Add validator chain provenance
This commit is contained in:
@@ -110,6 +110,78 @@ func TestResolvePipelineAppliesDefaults(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolvePipelineRecordsValidatorChains(t *testing.T) {
|
||||
catalog := newProfileCatalog(t)
|
||||
if err := catalog.ValidatorChains.Register(ValidatorChainMapping{
|
||||
Stage: StageExtract,
|
||||
Module: "event-extractor",
|
||||
Validators: []ModuleBinding{Binding("grounded")},
|
||||
}); err != nil {
|
||||
t.Fatalf("register validator chain: %v", err)
|
||||
}
|
||||
|
||||
resolved, err := ResolvePipeline(PipelineProfile{
|
||||
ID: "validated",
|
||||
Input: Binding("text"),
|
||||
Artifacts: map[string]ArtifactLaneProfile{
|
||||
"events": {Extract: Binding("event-extractor")},
|
||||
},
|
||||
}, ResolveOptions{}, catalog)
|
||||
if err != nil {
|
||||
t.Fatalf("ResolvePipeline() error = %v, want nil", err)
|
||||
}
|
||||
|
||||
if len(resolved.ValidatorChains) != 4 {
|
||||
t.Fatalf("len(ValidatorChains) = %d, want chunk plus lane extract/merge/normalize", len(resolved.ValidatorChains))
|
||||
}
|
||||
extractChain := findResolvedValidatorChain(resolved.ValidatorChains, StageExtract, "events", "event-extractor")
|
||||
if extractChain == nil {
|
||||
t.Fatal("extract validator chain not found")
|
||||
}
|
||||
if len(extractChain.Validators) != 1 {
|
||||
t.Fatalf("extract validators = %#v, want one validator", extractChain.Validators)
|
||||
}
|
||||
if extractChain.Validators[0].Binding.Module != "grounded" {
|
||||
t.Fatalf("extract validator key = %q, want grounded", extractChain.Validators[0].Binding.Module)
|
||||
}
|
||||
if extractChain.Validators[0].ExecutionClass != contracts.ExecutionClassDeterministic {
|
||||
t.Fatalf("extract validator execution class = %q, want deterministic", extractChain.Validators[0].ExecutionClass)
|
||||
}
|
||||
|
||||
chunkChain := findResolvedValidatorChain(resolved.ValidatorChains, StageChunk, "", DefaultChunkModule)
|
||||
if chunkChain == nil {
|
||||
t.Fatal("chunk validator chain not found")
|
||||
}
|
||||
if len(chunkChain.Validators) != 0 {
|
||||
t.Fatalf("chunk validators = %#v, want explicit empty chain", chunkChain.Validators)
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolvePipelineRejectsUnknownDefaultValidator(t *testing.T) {
|
||||
catalog := newProfileCatalog(t)
|
||||
if err := catalog.ValidatorChains.Register(ValidatorChainMapping{
|
||||
Stage: StageNormalize,
|
||||
Module: DefaultNormalizeModule,
|
||||
Validators: []ModuleBinding{Binding("missing-validator")},
|
||||
}); err != nil {
|
||||
t.Fatalf("register validator chain: %v", err)
|
||||
}
|
||||
|
||||
_, err := ResolvePipeline(PipelineProfile{
|
||||
ID: "invalid-chain",
|
||||
Input: Binding("text"),
|
||||
Artifacts: map[string]ArtifactLaneProfile{
|
||||
"events": {Extract: Binding("event-extractor")},
|
||||
},
|
||||
}, ResolveOptions{}, catalog)
|
||||
if err == nil {
|
||||
t.Fatal("ResolvePipeline() error = nil, want unknown validator error")
|
||||
}
|
||||
if !strings.Contains(err.Error(), "missing-validator") {
|
||||
t.Fatalf("ResolvePipeline() error = %q, want missing validator context", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolvePipelineSelectsOnlyRequestedLanes(t *testing.T) {
|
||||
profile := multiLaneProfile()
|
||||
resolved, err := ResolvePipeline(profile, ResolveOptions{Only: []string{" summaries ", "events", "summaries"}}, newProfileCatalog(t))
|
||||
@@ -955,6 +1027,15 @@ func assertBindingSource(t *testing.T, bindings []ReferenceBinding, slotName str
|
||||
t.Fatalf("binding %q not found in %#v", slotName, bindings)
|
||||
}
|
||||
|
||||
func findResolvedValidatorChain(chains []ResolvedValidatorChain, stage ModuleStage, laneID string, module string) *ResolvedValidatorChain {
|
||||
for i := range chains {
|
||||
if chains[i].Stage == stage && chains[i].LaneID == laneID && chains[i].ModuleKey == module {
|
||||
return &chains[i]
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func newProfileCatalog(t *testing.T) ModuleCatalog {
|
||||
t.Helper()
|
||||
|
||||
@@ -994,13 +1075,14 @@ func newProfileCatalogWithOverrides(t *testing.T, overrides ...ModuleSpec) Modul
|
||||
|
||||
func emptyProfileCatalog() ModuleCatalog {
|
||||
return ModuleCatalog{
|
||||
Inputs: NewInputAdapterRegistry(),
|
||||
Chunkers: NewChunkerRegistry(),
|
||||
Extractors: NewExtractorRegistry(),
|
||||
Mergers: NewMergerRegistry(),
|
||||
Normalizers: NewNormalizerRegistry(),
|
||||
Validators: NewValidatorRegistry(),
|
||||
Outputs: NewOutputEncoderRegistry(),
|
||||
Inputs: NewInputAdapterRegistry(),
|
||||
Chunkers: NewChunkerRegistry(),
|
||||
Extractors: NewExtractorRegistry(),
|
||||
Mergers: NewMergerRegistry(),
|
||||
Normalizers: NewNormalizerRegistry(),
|
||||
Validators: NewValidatorRegistry(),
|
||||
ValidatorChains: NewValidatorChainRegistry(),
|
||||
Outputs: NewOutputEncoderRegistry(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1043,7 +1125,8 @@ func registerProfileSpecs(t *testing.T, catalog ModuleCatalog, specs ...ModuleSp
|
||||
t.Fatalf("register normalizer spec %#v: %v", spec, err)
|
||||
}
|
||||
case StageValidate:
|
||||
if err := catalog.Validators.RegisterWithSpec(spec, profileValidatorConstructor(spec.Key)); err != nil {
|
||||
validatorSpec := ValidatorSpec{Key: spec.Key, ExecutionClass: contracts.ExecutionClassDeterministic}
|
||||
if err := catalog.Validators.RegisterWithSpec(validatorSpec, profileValidatorConstructor(spec.Key)); err != nil {
|
||||
t.Fatalf("register validator spec %#v: %v", spec, err)
|
||||
}
|
||||
case StageOutput:
|
||||
|
||||
Reference in New Issue
Block a user