Skip to content

test: add unit tests for plugin payload attribute validation - #581

Open
arpitjain099 wants to merge 1 commit into
notaryproject:mainfrom
arpitjain099:test/payload-descriptor-validation
Open

test: add unit tests for plugin payload attribute validation#581
arpitjain099 wants to merge 1 commit into
notaryproject:mainfrom
arpitjain099:test/payload-descriptor-validation

Conversation

@arpitjain099

Copy link
Copy Markdown

What this does

Adds unit tests for the plugin payload attribute validation that #178 introduced. As noted in #194, those checks shipped without unit coverage because they were hard to exercise through the full signing flow without refactoring business logic. This PR tests the two helper functions directly instead, so no production code changes are needed.

Closes #194

Tests added

In a new signer/payload_test.go:

TestIsPayloadDescriptorValid is table-driven and covers a plugin returning the same subject descriptor it was given (valid), appending an annotation (valid), and the tamper cases that the function exists to catch: a changed digest, a changed size, a changed mediaType, and an existing annotation being overridden. These map to the spec requirement that a plugin must not alter the payload subject during signing.

TestAreUnknownAttributesAdded covers a payload where every key is an allowed descriptor field (nothing reported), an unknown attribute injected inside the targetArtifact descriptor, an unknown attribute added at the payload top level, and both at once. This matches the rule from the plugin signing workflow that no extra top-level attributes may be added to the subject.

Verification

  • go test ./signer/... passes; statement coverage of isPayloadDescriptorValid and areUnknownAttributesAdded goes from 0 percent to full.
  • gofmt -l and go vet ./signer/... are clean.
  • I confirmed the tests are real by temporarily weakening each function (dropping the descriptor equality check, and returning no unknown attributes); the relevant subtests failed, then passed again once the code was restored. The diff in this PR touches only the new test file.

Adds table-driven coverage for the payload descriptor checks introduced
in notaryproject#178, which previously had no unit tests (tracked in notaryproject#194).

isPayloadDescriptorValid is exercised for a matching descriptor, an
appended annotation, and rejection on a tampered digest, size, or
mediaType, plus rejection when a plugin overrides an existing
annotation. areUnknownAttributesAdded is exercised for the all-known
case and for unknown attributes added inside the descriptor and at the
payload top level.

Coverage of both functions goes from 0 percent to full statement
coverage. No production code changes.

Signed-off-by: Arpit Jain <arpitjain099@gmail.com>
Copilot AI review requested due to automatic review settings June 3, 2026 00:37

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds unit tests for payload validation logic in the signer package to detect descriptor tampering and unexpected JSON fields during envelope generation.

Changes:

  • Introduces TestIsPayloadDescriptorValid covering allowed vs. rejected descriptor mutations.
  • Introduces TestAreUnknownAttributesAdded covering detection of unknown JSON attributes at multiple levels.
  • Adds a shared baseDescriptor() helper to reduce duplication across cases.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread signer/payload_test.go
Comment on lines +93 to +99
for name, tc := range tests {
t.Run(name, func(t *testing.T) {
if got := isPayloadDescriptorValid(original, tc.newDesc); got != tc.want {
t.Fatalf("isPayloadDescriptorValid() = %v, want %v", got, tc.want)
}
})
}
Comment thread signer/payload_test.go
Comment on lines +129 to +139
for name, tc := range tests {
t.Run(name, func(t *testing.T) {
got := areUnknownAttributesAdded([]byte(tc.content))
sort.Strings(got)
want := append([]string{}, tc.want...)
sort.Strings(want)
if !reflect.DeepEqual(got, want) {
t.Fatalf("areUnknownAttributesAdded() = %+q, want %+q", got, want)
}
})
}
Comment thread signer/payload_test.go
}
}

func TestAreUnknownAttributesAdded(t *testing.T) {
@github-actions

Copy link
Copy Markdown

This PR is stale because it has been opened for 45 days with no activity. Remove stale label or comment. Otherwise, it will be closed in 30 days.

@github-actions github-actions Bot added the Stale label Jul 18, 2026
@arpitjain099

Copy link
Copy Markdown
Author

Still relevant, and the stale label caught me out rather than the change being abandoned. Going through Copilot's three points:

On rebinding tc := tc in the two table loops: this module is go 1.23.0, and Go 1.22 changed range variables to be per-iteration, so the rebinding is a no-op on any toolchain that can build this repo. grep -r 'tc := tc' also finds nothing in the tree, so adding it here would be the only instance and would read as cargo cult. Happy to add it if the project would rather keep the older idiom for consistency with t.Parallel() use elsewhere, but I would rather not add a line that does nothing.

On the TestAreUnknownAttributesAdded name: that one is fair. The function returns the slice of unknown keys rather than a bool, so the name promises the wrong shape. I can rename it to TestAreUnknownAttributesAdded_ReportsUnknownAttributes.

The tests themselves cover areUnknownAttributesAdded over the empty, exact-match, extra-key and missing-key cases, which is the validation path a plugin response goes through. Let me know if you want the rename pushed and I will do it, or if you would rather this be closed.

@github-actions github-actions Bot removed the Stale label Aug 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Unit test payload attribute validation

2 participants