Execute ordered pipeline steps with barriers

This commit is contained in:
2026-07-21 21:19:00 +00:00
parent f846f252c0
commit afb7ed3cf1
15 changed files with 365 additions and 97 deletions

View File

@@ -67,11 +67,71 @@ func TestPrepareConstructsEverythingInStableOrder(t *testing.T) {
if !reflect.DeepEqual(built, want) {
t.Fatalf("construction order = %#v, want %#v", built, want)
}
if prepared.Input.Module != "input" || prepared.Chunk.Module != "chunk" || prepared.Output.Module != "output" || len(prepared.ArtifactLanes) != 1 {
if prepared.Input.Module != "input" || prepared.Chunk.Module != "chunk" || prepared.Output.Module != "output" || len(prepared.Steps) != 1 || len(prepared.Steps[0].ArtifactLanes) != 1 {
t.Fatalf("PreparedPipeline = %#v, want explicit resolved components", prepared)
}
}
func TestPrepareBuildsEveryOrderedStepBeforeExecution(t *testing.T) {
var built []string
registries, input := constructionRegistries(t, &built, nil)
profile := constructionProfile()
lane := profile.Artifacts["artifact"]
profile.Artifacts = nil
profile.Steps = []PipelineStepProfile{
{ID: "first", Artifacts: map[string]ArtifactLaneProfile{"first-artifact": lane}},
{ID: "second", Artifacts: map[string]ArtifactLaneProfile{"second-artifact": lane}},
}
resolved, err := ResolvePipeline(profile, ResolveOptions{}, registries.catalog())
if err != nil {
t.Fatalf("ResolvePipeline() error = %v, want nil", err)
}
prepared, err := Prepare(resolved, registries, ModuleDependencies{})
if err != nil {
t.Fatalf("Prepare() error = %v, want nil", err)
}
want := []string{
"input", "chunk", "validator",
"extract", "validator", "merge", "validator", "normalize", "validator",
"extract", "validator", "merge", "validator", "normalize", "validator",
"output",
}
if !reflect.DeepEqual(built, want) {
t.Fatalf("construction order = %#v, want %#v", built, want)
}
if len(prepared.Steps) != 2 || len(prepared.Steps[0].lanes) != 1 || len(prepared.Steps[1].lanes) != 1 {
t.Fatalf("prepared steps = %#v, want two constructed steps", prepared.Steps)
}
if len(input.requests) != 0 {
t.Fatalf("input Parse calls = %d, want zero during preparation", len(input.requests))
}
}
func TestPrepareRetainsGeneratedSelectorsWithoutReferenceBytes(t *testing.T) {
var built []string
registries, _ := constructionRegistries(t, &built, nil)
resolved, err := ResolvePipeline(constructionProfile(), ResolveOptions{}, registries.catalog())
if err != nil {
t.Fatalf("ResolvePipeline() error = %v, want nil", err)
}
resolved.Steps[0].ArtifactLanes[0].ExtractReferences.Bindings = []ReferenceBinding{{
Stage: StageExtract,
LaneID: "artifact",
SlotName: "generated",
Artifact: &ArtifactReference{Step: "producer", Lane: "artifact"},
}}
prepared, err := Prepare(resolved, registries, ModuleDependencies{})
if err != nil {
t.Fatalf("Prepare() error = %v, want nil", err)
}
if len(prepared.Steps[0].ArtifactLanes[0].Resolved.ExtractReferences.ReferenceSet.Slots) != 0 {
t.Fatalf("prepared generated reference set = %#v, want no reference bytes", prepared.Steps[0].ArtifactLanes[0].Resolved.ExtractReferences.ReferenceSet)
}
if len(built) == 0 {
t.Fatal("constructed modules = empty, want preparation to construct the selected components")
}
}
func TestPreparedCheckpointFingerprintsCollectEveryComponentInStableScopeOrder(t *testing.T) {
provider := func(value string) checkpointFingerprintTestProvider {
return checkpointFingerprintTestProvider{{Name: "identity", Value: value}}
@@ -90,6 +150,7 @@ func TestPreparedCheckpointFingerprintsCollectEveryComponentInStableScopeOrder(t
chunk: provider("chunk-validator"),
}}},
output: provider("output"),
Steps: []PreparedPipelineStep{{ID: "default"}},
}
lane := preparedLaneExecutor{
resolved: ResolvedArtifactLane{
@@ -107,7 +168,7 @@ func TestPreparedCheckpointFingerprintsCollectEveryComponentInStableScopeOrder(t
mergeValidators: fingerprintTestValidatorChain("merge-validator", provider("merge-validator")),
normalizeValidators: fingerprintTestValidatorChain("normalize-validator", provider("normalize-validator")),
}
prepared.lanes = []preparedLaneExecutor{lane}
prepared.Steps[0].lanes = []preparedLaneExecutor{lane}
first, err := collectPreparedCheckpointFingerprints(prepared)
if err != nil {
@@ -279,7 +340,7 @@ func TestPrepareDeliversTargetReferencesAsIndependentBuildInputs(t *testing.T) {
t.Fatalf("resolved extract references = %q, want original content", got)
}
_, err = prepared.lanes[0].typed.extract(context.Background(), prepared.lanes[0].typed.extractor, contracts.TypedExtractionRequest{
_, err = prepared.Steps[0].lanes[0].typed.extract(context.Background(), prepared.Steps[0].lanes[0].typed.extractor, contracts.TypedExtractionRequest{
References: CloneReferenceSet(resolved.Steps[0].ArtifactLanes[0].ExtractReferences.ReferenceSet),
})
if err != nil {