Skip to content

Commit 454bb13

Browse files
authored
Merge pull request #3028 from cuipinghuo/vsa-acceptance-enhance
test: add VSA upload error handling acceptance tests
2 parents 35d54fd + e802bdf commit 454bb13

File tree

4 files changed

+133
-0
lines changed

4 files changed

+133
-0
lines changed

acceptance/cli/cli.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -824,13 +824,29 @@ func createTrackBundleFile(ctx context.Context, name string, content *godog.DocS
824824
return createGenericFile(ctx, name, content)
825825
}
826826

827+
// theLogOutputShouldContain checks if the log output (stderr) contains the expected text
828+
func theLogOutputShouldContain(ctx context.Context, expected string) error {
829+
status, err := ecStatusFrom(ctx)
830+
if err != nil {
831+
return err
832+
}
833+
834+
stderr := status.stderr.String()
835+
if !strings.Contains(stderr, expected) {
836+
return fmt.Errorf("expected log output to contain:\n%s\nbut stderr was:\n%s", expected, stderr)
837+
}
838+
839+
return nil
840+
}
841+
827842
// AddStepsTo adds Gherkin steps to the godog ScenarioContext
828843
func AddStepsTo(sc *godog.ScenarioContext) {
829844
sc.Step(`^ec command is run with "(.+)"$`, ecCommandIsRunWith)
830845
sc.Step(`^the exit status should be (\d+)$`, theExitStatusIs)
831846
sc.Step(`^the standard output should contain$`, theStandardOutputShouldContain)
832847
sc.Step(`^the standard output should match baseline file "(.+)"$`, theStandardOutputShouldMatchBaseline)
833848
sc.Step(`^the standard error should contain$`, theStandardErrorShouldContain)
849+
sc.Step(`^the log output should contain "([^"]*)"$`, theLogOutputShouldContain)
834850
sc.Step(`^the environment variable is set "([^"]*)"$`, theEnvironmentVarilableIsSet)
835851
sc.Step(`^the output should match the snapshot$`, matchSnapshot)
836852
sc.Step(`^the "([^"]*)" file should match the snapshot$`, matchFileSnapshot)

acceptance/rekor/rekor.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,18 @@ func IsRunning(ctx context.Context) bool {
357357
return testenv.HasState[rekorState](ctx)
358358
}
359359

360+
// rekorUploadShouldFail creates WireMock stubs that simulate Rekor upload failures
361+
func rekorUploadShouldFail(ctx context.Context) error {
362+
// Create a stub that returns a 500 Internal Server Error for VSA upload requests
363+
return wiremock.StubFor(ctx, wiremock.Post(wiremock.URLPathEqualTo("/api/v1/log/entries")).
364+
WillReturnResponse(wiremock.NewResponse().
365+
WithStatus(500).
366+
WithHeaders(map[string]string{
367+
"Content-Type": "application/json",
368+
}).
369+
WithBody(`{"message":"Internal server error"}`)))
370+
}
371+
360372
// AddStepsTo adds Gherkin steps to the godog ScenarioContext
361373
func AddStepsTo(sc *godog.ScenarioContext) {
362374
sc.Step(`^stub rekord running$`, stubRekordRunning)
@@ -366,6 +378,7 @@ func AddStepsTo(sc *godog.ScenarioContext) {
366378
sc.Step(`^VSA should be uploaded to Rekor successfully$`, vsaShouldBeUploadedToRekor)
367379
sc.Step(`^VSA index search should return no results$`, stubVSAIndexSearch)
368380
sc.Step(`^VSA index search should return valid VSA$`, stubVSAIndexSearchWithResult)
381+
sc.Step(`^Rekor upload should fail$`, rekorUploadShouldFail)
369382
}
370383

371384
// expectVSAUploadToRekor creates WireMock stubs to expect VSA upload requests to Rekor

features/__snapshots__/vsa.snap

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -307,3 +307,55 @@ time="${TIMESTAMP}" level=warning msg="invalid storage config 'invalid-backend@s
307307
[VSA generation with multiple storage backends:stderr - 1]
308308

309309
---
310+
311+
[VSA generation without upload backends shows warning:stdout - 1]
312+
{
313+
"success": true,
314+
"components": [
315+
{
316+
"name": "Unnamed",
317+
"containerImage": "${REGISTRY}/acceptance/vsa-no-upload-image@sha256:${REGISTRY_acceptance/vsa-no-upload-image:latest_DIGEST}",
318+
"source": {},
319+
"success": true,
320+
"signatures": [
321+
{
322+
"keyid": "",
323+
"sig": "${IMAGE_SIGNATURE_acceptance/vsa-no-upload-image}"
324+
}
325+
],
326+
"attestations": [
327+
{
328+
"type": "https://in-toto.io/Statement/v0.1",
329+
"predicateType": "https://slsa.dev/provenance/v0.2",
330+
"predicateBuildType": "https://tekton.dev/attestations/chains/pipelinerun@v2",
331+
"signatures": [
332+
{
333+
"keyid": "",
334+
"sig": "${ATTESTATION_SIGNATURE_acceptance/vsa-no-upload-image}"
335+
}
336+
]
337+
}
338+
]
339+
}
340+
],
341+
"key": "${vsa-no-upload_PUBLIC_KEY_JSON}",
342+
"policy": {
343+
"sources": [
344+
{
345+
"policy": [
346+
"git::${GITHOST}/git/vsa-no-upload-policy.git?ref=${LATEST_COMMIT}"
347+
]
348+
}
349+
],
350+
"rekorUrl": "${REKOR}",
351+
"publicKey": "${vsa-no-upload_PUBLIC_KEY}"
352+
},
353+
"ec-version": "${EC_VERSION}",
354+
"effective-time": "${TIMESTAMP}"
355+
}
356+
---
357+
358+
[VSA generation without upload backends shows warning:stderr - 1]
359+
time="${TIMESTAMP}" level=error msg="[VSA] VSA files generated but not uploaded (no --vsa-upload backends specified)"
360+
361+
---

features/vsa.feature

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,3 +171,55 @@ Feature: VSA generation and storage
171171
When ec command is run with "validate image --image ${REGISTRY}/acceptance/vsa-existing-image@sha256:${REGISTRY_acceptance/vsa-existing-image:latest_DIGEST} --policy acceptance/vsa-existing-ec-policy --public-key ${vsa-existing_PUBLIC_KEY} --rekor-url ${REKOR} --vsa-expiration 24h --output json"
172172
Then the exit status should be 0
173173
Then the output should match the snapshot
174+
175+
Scenario: VSA generation without upload backends shows warning
176+
Given a key pair named "vsa-no-upload"
177+
Given an image named "acceptance/vsa-no-upload-image"
178+
Given a valid image signature of "acceptance/vsa-no-upload-image" image signed by the "vsa-no-upload" key
179+
Given a valid Rekor entry for image signature of "acceptance/vsa-no-upload-image"
180+
Given a valid attestation of "acceptance/vsa-no-upload-image" signed by the "vsa-no-upload" key
181+
Given a valid Rekor entry for attestation of "acceptance/vsa-no-upload-image"
182+
Given a git repository named "vsa-no-upload-policy" with
183+
| main.rego | examples/happy_day.rego |
184+
Given policy configuration named "vsa-no-upload-ec-policy" with specification
185+
"""
186+
{
187+
"sources": [
188+
{
189+
"policy": [
190+
"git::https://${GITHOST}/git/vsa-no-upload-policy.git"
191+
]
192+
}
193+
]
194+
}
195+
"""
196+
When ec command is run with "validate image --image ${REGISTRY}/acceptance/vsa-no-upload-image --policy acceptance/vsa-no-upload-ec-policy --public-key ${vsa-no-upload_PUBLIC_KEY} --rekor-url ${REKOR} --vsa --vsa-signing-key ${vsa-no-upload_PRIVATE_KEY} --vsa-expiration 0 --output json"
197+
Then the exit status should be 0
198+
Then the output should match the snapshot
199+
And the log output should contain "[VSA] VSA files generated but not uploaded (no --vsa-upload backends specified)"
200+
201+
Scenario: VSA upload failure handling
202+
Given a key pair named "vsa-upload-fail"
203+
Given an image named "acceptance/vsa-upload-fail-image"
204+
Given a valid image signature of "acceptance/vsa-upload-fail-image" image signed by the "vsa-upload-fail" key
205+
Given a valid Rekor entry for image signature of "acceptance/vsa-upload-fail-image"
206+
Given a valid attestation of "acceptance/vsa-upload-fail-image" signed by the "vsa-upload-fail" key
207+
Given a valid Rekor entry for attestation of "acceptance/vsa-upload-fail-image"
208+
Given a git repository named "vsa-upload-fail-policy" with
209+
| main.rego | examples/happy_day.rego |
210+
Given policy configuration named "vsa-upload-fail-ec-policy" with specification
211+
"""
212+
{
213+
"sources": [
214+
{
215+
"policy": [
216+
"git::https://${GITHOST}/git/vsa-upload-fail-policy.git"
217+
]
218+
}
219+
]
220+
}
221+
"""
222+
Given Rekor upload should fail
223+
When ec command is run with "validate image --image ${REGISTRY}/acceptance/vsa-upload-fail-image --policy acceptance/vsa-upload-fail-ec-policy --public-key ${vsa-upload-fail_PUBLIC_KEY} --rekor-url ${REKOR} --vsa --vsa-signing-key ${vsa-upload-fail_PRIVATE_KEY} --vsa-upload rekor@${REKOR} --vsa-expiration 0 --output json"
224+
Then the exit status should be 0
225+
And the log output should contain "[VSA] Failed to upload in-toto 0.0.2 entry"

0 commit comments

Comments
 (0)