Files
notarius/internal/framework/pipeline/evidence_preparation_test.go

99 lines
4.0 KiB
Go

package pipeline
import (
"context"
"reflect"
"strings"
"testing"
"gitea.maximumdirect.net/eric/notarius/internal/core/source"
"gitea.maximumdirect.net/eric/notarius/internal/framework/contracts"
)
type testEvidenceOutput struct {
policy EvidenceContextPolicy
}
func (output testEvidenceOutput) Key() string { return "output" }
func (output testEvidenceOutput) Encode(context.Context, contracts.OutputRequest) (contracts.OutputResult, error) {
return contracts.OutputResult{}, nil
}
func (output testEvidenceOutput) EvidenceContextPolicy() EvidenceContextPolicy {
return cloneEvidenceContextPolicy(output.policy)
}
func TestPrepareEvidencePlanSelectsActiveLanesAndOwnsPolicy(t *testing.T) {
registries, _ := constructionRegistries(t, nil, nil)
registries.ArtifactEvidence = NewArtifactEvidenceRegistry()
registerTestEvidenceOutput(t, &registries, EvidenceContextPolicy{Enabled: true, WindowUnits: 2, LaneIDs: []string{"artifact", "inactive"}})
if err := RegisterArtifactEvidence(registries.ArtifactEvidence, "test/notes", func(codecNotes) []source.SourceRef { return nil }); err != nil {
t.Fatal(err)
}
profile := constructionProfile()
profile.Output.Options = map[string]any{"known": true}
resolved, err := ResolvePipeline(profile, ResolveOptions{}, registries.catalog())
if err != nil {
t.Fatal(err)
}
prepared, err := Prepare(resolved, registries, ModuleDependencies{})
if err != nil {
t.Fatalf("Prepare() error = %v, want nil", err)
}
if prepared.evidencePlan == nil || !reflect.DeepEqual(prepared.evidencePlan.policy.LaneIDs, []string{"artifact", "inactive"}) {
t.Fatalf("evidence plan = %#v, want complete configured policy", prepared.evidencePlan)
}
if got := prepared.evidencePlan.lanes; len(got) != 1 || got[0].laneID != "artifact" {
t.Fatalf("active evidence lanes = %#v, want artifact only", got)
}
prepared.evidencePlan.policy.LaneIDs[0] = "mutated"
if policy := prepared.output.(EvidenceContextPolicyProvider).EvidenceContextPolicy(); policy.LaneIDs[0] != "artifact" {
t.Fatalf("prepared plan mutated provider policy: %#v", policy)
}
}
func TestPrepareEvidencePlanRejectsMissingAndMismatchedCapabilities(t *testing.T) {
for _, test := range []struct {
name string
configure func(*Registries)
want string
}{
{name: "missing registry", configure: func(registries *Registries) { registries.ArtifactEvidence = nil }, want: "artifact evidence registry"},
{name: "unsupported kind", configure: func(registries *Registries) {}, want: "artifact evidence \"test/notes\" is not registered"},
{name: "mismatched type", configure: func(registries *Registries) {
if err := RegisterArtifactEvidence(registries.ArtifactEvidence, "test/notes", func(codecScore) []source.SourceRef { return nil }); err != nil {
t.Fatal(err)
}
}, want: "requires Go type"},
} {
t.Run(test.name, func(t *testing.T) {
registries, _ := constructionRegistries(t, nil, nil)
registries.ArtifactEvidence = NewArtifactEvidenceRegistry()
registerTestEvidenceOutput(t, &registries, EvidenceContextPolicy{Enabled: true, LaneIDs: []string{"artifact"}})
test.configure(&registries)
profile := constructionProfile()
profile.Output.Options = map[string]any{"known": true}
resolved, err := ResolvePipeline(profile, ResolveOptions{}, registries.catalog())
if err != nil {
t.Fatal(err)
}
_, err = Prepare(resolved, registries, ModuleDependencies{})
if err == nil || !strings.Contains(err.Error(), test.want) {
t.Fatalf("Prepare() error = %v, want %q", err, test.want)
}
})
}
}
func registerTestEvidenceOutput(t *testing.T, registries *Registries, policy EvidenceContextPolicy) {
t.Helper()
registry := NewOutputEncoderRegistry()
if err := registry.RegisterBuilderWithSpec(defaultModuleSpec("output", StageOutput), func(options map[string]any) error {
return RejectUnknownOptions(options, "known")
}, func(BuildRequest) (contracts.OutputEncoder, error) {
return testEvidenceOutput{policy: cloneEvidenceContextPolicy(policy)}, nil
}); err != nil {
t.Fatal(err)
}
registries.Outputs = registry
}