Skip to content

Commit cde5ccf

Browse files
committed
extend code coverage
1 parent fc5b620 commit cde5ccf

File tree

1 file changed

+244
-1
lines changed

1 file changed

+244
-1
lines changed

cmd/validate/vsa_test.go

Lines changed: 244 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2389,6 +2389,249 @@ func TestCreateErrorResult(t *testing.T) {
23892389
assert.Equal(t, component.Name, result.ComponentName)
23902390
assert.Equal(t, component.ContainerImage, result.ImageRef)
23912391
assert.Equal(t, err, result.Error)
2392-
assert.Nil(t, result.Result)
2392+
2393+
// Result should be created from error for proper display
2394+
assert.NotNil(t, result.Result)
2395+
assert.False(t, result.Result.Passed)
2396+
assert.Equal(t, "test error", result.Result.Message)
2397+
assert.False(t, result.Result.SignatureVerified)
2398+
assert.Equal(t, "retrieval_failed", result.Result.ReasonCode)
2399+
23932400
assert.Nil(t, result.FallbackResult)
23942401
}
2402+
2403+
// TestCreateValidationResultFromError tests the createValidationResultFromError helper function
2404+
func TestCreateValidationResultFromError(t *testing.T) {
2405+
tests := []struct {
2406+
name string
2407+
err error
2408+
wantNil bool
2409+
wantReason string
2410+
wantMsg string
2411+
}{
2412+
{
2413+
name: "nil error",
2414+
err: nil,
2415+
wantNil: true,
2416+
wantReason: "",
2417+
wantMsg: "",
2418+
},
2419+
{
2420+
name: "timeout error",
2421+
err: errors.New("exceeded allowed execution time of 5m0s"),
2422+
wantNil: false,
2423+
wantReason: "retrieval_failed",
2424+
wantMsg: "exceeded allowed execution time of 5m0s",
2425+
},
2426+
{
2427+
name: "timeout error variant",
2428+
err: errors.New("timeout occurred"),
2429+
wantNil: false,
2430+
wantReason: "retrieval_failed",
2431+
wantMsg: "timeout occurred",
2432+
},
2433+
{
2434+
name: "no entries found error",
2435+
err: errors.New("no entries found in Rekor"),
2436+
wantNil: false,
2437+
wantReason: "no_vsa",
2438+
wantMsg: "no entries found in Rekor",
2439+
},
2440+
{
2441+
name: "not found error",
2442+
err: errors.New("VSA not found"),
2443+
wantNil: false,
2444+
wantReason: "no_vsa",
2445+
wantMsg: "VSA not found",
2446+
},
2447+
{
2448+
name: "signature error",
2449+
err: errors.New("signature verification failed"),
2450+
wantNil: false,
2451+
wantReason: "retrieval_failed",
2452+
wantMsg: "signature verification failed",
2453+
},
2454+
{
2455+
name: "generic error",
2456+
err: errors.New("generic error message"),
2457+
wantNil: false,
2458+
wantReason: "retrieval_failed",
2459+
wantMsg: "generic error message",
2460+
},
2461+
}
2462+
2463+
for _, tt := range tests {
2464+
t.Run(tt.name, func(t *testing.T) {
2465+
result := createValidationResultFromError(tt.err)
2466+
2467+
if tt.wantNil {
2468+
assert.Nil(t, result)
2469+
} else {
2470+
assert.NotNil(t, result)
2471+
assert.False(t, result.Passed)
2472+
assert.Equal(t, tt.wantMsg, result.Message)
2473+
assert.False(t, result.SignatureVerified)
2474+
assert.Equal(t, tt.wantReason, result.ReasonCode)
2475+
assert.Empty(t, result.PredicateOutcome)
2476+
}
2477+
})
2478+
}
2479+
}
2480+
2481+
// TestAggregateAllSectionsData_ErrorHandling tests the error handling path in aggregateAllSectionsData
2482+
func TestAggregateAllSectionsData_ErrorHandling(t *testing.T) {
2483+
tests := []struct {
2484+
name string
2485+
results []vsa.ComponentResult
2486+
wantVSAFailed int
2487+
wantVSAStatus string
2488+
wantSigStatus string
2489+
wantFallback bool
2490+
}{
2491+
{
2492+
name: "error with no result",
2493+
results: []vsa.ComponentResult{
2494+
{
2495+
ComponentName: "test-component",
2496+
ImageRef: "registry.com/image@sha256:12345678",
2497+
Error: errors.New("VSA validation failed: timeout"),
2498+
Result: nil,
2499+
},
2500+
},
2501+
wantVSAFailed: 1,
2502+
wantVSAStatus: "FAILED(reason=unknown)", // extractReasonFromMessage doesn't match "timeout" exactly
2503+
wantSigStatus: "NOT VERIFIED",
2504+
wantFallback: false,
2505+
},
2506+
{
2507+
name: "error with result",
2508+
results: []vsa.ComponentResult{
2509+
{
2510+
ComponentName: "test-component",
2511+
ImageRef: "registry.com/image@sha256:12345678",
2512+
Error: errors.New("VSA validation failed"),
2513+
Result: &vsa.ValidationResult{
2514+
Passed: false,
2515+
Message: "timeout",
2516+
SignatureVerified: false,
2517+
ReasonCode: "retrieval_failed",
2518+
},
2519+
},
2520+
},
2521+
wantVSAFailed: 1,
2522+
wantVSAStatus: "FAILED(reason=retrieval failed)", // Uses ReasonCode which maps to "retrieval failed"
2523+
wantSigStatus: "NOT VERIFIED",
2524+
wantFallback: false,
2525+
},
2526+
{
2527+
name: "error with fallback result",
2528+
results: []vsa.ComponentResult{
2529+
{
2530+
ComponentName: "test-component",
2531+
ImageRef: "registry.com/image@sha256:12345678",
2532+
Error: nil,
2533+
Result: &vsa.ValidationResult{
2534+
Passed: false,
2535+
Message: "no VSA found",
2536+
SignatureVerified: false,
2537+
ReasonCode: "no_vsa",
2538+
},
2539+
FallbackResult: &validate_utils.Result{
2540+
Component: applicationsnapshot.Component{
2541+
SnapshotComponent: app.SnapshotComponent{
2542+
Name: "test-component",
2543+
},
2544+
Success: true,
2545+
},
2546+
},
2547+
},
2548+
},
2549+
wantVSAFailed: 1,
2550+
wantVSAStatus: "FAILED(reason=no vsa)",
2551+
wantSigStatus: "NOT VERIFIED",
2552+
wantFallback: true,
2553+
},
2554+
{
2555+
name: "mixed results",
2556+
results: []vsa.ComponentResult{
2557+
{
2558+
ComponentName: "component-1",
2559+
ImageRef: "registry.com/image1@sha256:11111111",
2560+
Error: errors.New("timeout"),
2561+
Result: nil,
2562+
},
2563+
{
2564+
ComponentName: "component-2",
2565+
ImageRef: "registry.com/image2@sha256:22222222",
2566+
Error: nil,
2567+
Result: &vsa.ValidationResult{
2568+
Passed: true,
2569+
SignatureVerified: true,
2570+
},
2571+
},
2572+
},
2573+
wantVSAFailed: 1,
2574+
wantVSAStatus: "FAILED(reason=unknown)", // extractReasonFromMessage doesn't match "timeout" exactly // First component
2575+
wantSigStatus: "NOT VERIFIED", // Should be NOT VERIFIED due to first component
2576+
wantFallback: false,
2577+
},
2578+
}
2579+
2580+
for _, tt := range tests {
2581+
t.Run(tt.name, func(t *testing.T) {
2582+
data := aggregateAllSectionsData(tt.results)
2583+
2584+
assert.Equal(t, len(tt.results), data.TotalImages)
2585+
assert.Equal(t, tt.wantVSAFailed, data.VSAFailed)
2586+
assert.Equal(t, tt.wantSigStatus, data.SignatureStatus)
2587+
assert.Equal(t, tt.wantFallback, data.FallbackUsed)
2588+
2589+
if len(data.ImageStatuses) > 0 {
2590+
// Check first image status
2591+
assert.Contains(t, data.ImageStatuses[0].VSAStatus, "FAILED")
2592+
if tt.wantVSAStatus != "" {
2593+
assert.Equal(t, tt.wantVSAStatus, data.ImageStatuses[0].VSAStatus)
2594+
}
2595+
}
2596+
})
2597+
}
2598+
}
2599+
2600+
// TestProcessSnapshotComponentWithWorkerContext_ErrorHandling tests error handling with fallback
2601+
// This test verifies that when VSA validation fails, a ValidationResult is created from the error
2602+
// and fallback is checked before returning the error
2603+
func TestProcessSnapshotComponentWithWorkerContext_ErrorHandling(t *testing.T) {
2604+
ctx := context.Background()
2605+
2606+
// Create a component with valid image reference
2607+
component := app.SnapshotComponent{
2608+
Name: "test-component",
2609+
ContainerImage: "registry.com/image@sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef",
2610+
}
2611+
2612+
// Create data with fallback enabled
2613+
// Note: We don't set a retriever, so performVSAValidation will fail when trying to validate
2614+
// This tests the error handling path where an error occurs during VSA validation
2615+
data := &validateVSAData{
2616+
fallbackToImageValidation: true,
2617+
policySpec: ecapi.EnterpriseContractPolicySpec{},
2618+
effectiveTime: "now",
2619+
retriever: nil, // No retriever - will cause error in performVSAValidation
2620+
}
2621+
2622+
// Test with fallback enabled but no worker context
2623+
// This will fail at performVSAValidation due to nil retriever, but should create a ValidationResult
2624+
result := processSnapshotComponentWithWorkerContext(ctx, component, data, nil)
2625+
2626+
// Should have error and result set (even though validation failed)
2627+
// Note: This test may hit different error paths depending on initialization
2628+
// The key is that if there's an error, a ValidationResult should be created
2629+
if result.Error != nil {
2630+
// If error occurs, ValidationResult should be created for display
2631+
if result.Result != nil {
2632+
assert.False(t, result.Result.Passed)
2633+
}
2634+
// Error message may vary (VSA validation failed, fallback context not initialized, etc.)
2635+
assert.NotEmpty(t, result.Error.Error())
2636+
}
2637+
}

0 commit comments

Comments
 (0)