Clarify pipeline composition envelope handling
This commit is contained in:
@@ -9,6 +9,82 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestSplitPipelineCompositionEnvelopePreservesInputAndDeclarationOrder(t *testing.T) {
|
||||
document, err := parseCompositionBytes("pipeline.yml", []byte(`composition:
|
||||
imports: [first.yml, second.yml]
|
||||
default_profile: production
|
||||
profiles:
|
||||
production:
|
||||
overlay: production.yml
|
||||
testing:
|
||||
overlay: testing.yml
|
||||
workspace:
|
||||
root: /srv/narratio
|
||||
`))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
originalRoot := cloneCompositionNode(document.root)
|
||||
originalSources := append([]string(nil), document.sources...)
|
||||
|
||||
body, envelope, err := splitPipelineCompositionEnvelope(document)
|
||||
if err != nil {
|
||||
t.Fatalf("splitPipelineCompositionEnvelope() error = %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(document.root, originalRoot) || !reflect.DeepEqual(document.sources, originalSources) {
|
||||
t.Fatalf("splitPipelineCompositionEnvelope() mutated its input")
|
||||
}
|
||||
if compositionFieldIndex(body.root.fields, "composition") >= 0 {
|
||||
t.Fatalf("pipeline body still contains composition envelope")
|
||||
}
|
||||
if compositionFieldIndex(body.root.fields, "workspace") < 0 {
|
||||
t.Fatalf("pipeline body lost ordinary root fields")
|
||||
}
|
||||
if want := []string{"first.yml", "second.yml"}; !reflect.DeepEqual(envelope.imports, want) {
|
||||
t.Fatalf("imports = %#v, want %#v", envelope.imports, want)
|
||||
}
|
||||
if len(envelope.profiles) != 2 || envelope.profiles[0].name != "production" || envelope.profiles[1].name != "testing" {
|
||||
t.Fatalf("profiles = %#v, want declaration order", envelope.profiles)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSplitPipelineCompositionEnvelopeRejectsMalformedShapesWithoutMutation(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
yaml string
|
||||
want string
|
||||
}{
|
||||
{name: "envelope", yaml: "composition: []\n", want: "expected a mapping"},
|
||||
{name: "imports mapping", yaml: "composition:\n imports: {}\n", want: "expected a list"},
|
||||
{name: "import value", yaml: "composition:\n imports: [1]\n", want: "expected a string path"},
|
||||
{name: "default profile", yaml: "composition:\n default_profile: {}\n", want: "expected a string profile name"},
|
||||
{name: "profiles sequence", yaml: "composition:\n profiles: []\n", want: "expected a mapping"},
|
||||
{name: "empty profiles", yaml: "composition:\n profiles: {}\n", want: "at least one named profile"},
|
||||
{name: "profile declaration", yaml: "composition:\n profiles:\n production: production.yml\n", want: "expected a mapping"},
|
||||
{name: "invalid profile name", yaml: "composition:\n profiles:\n ' production ':\n overlay: production.yml\n", want: "surrounding whitespace"},
|
||||
{name: "unknown field", yaml: "composition:\n unexpected: true\n", want: "unknown composition field"},
|
||||
{name: "unknown default", yaml: "composition:\n default_profile: testing\n profiles:\n production:\n overlay: production.yml\n", want: "does not name a declared profile"},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
document, err := parseCompositionBytes("pipeline.yml", []byte(test.yaml))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
originalRoot := cloneCompositionNode(document.root)
|
||||
|
||||
_, _, err = splitPipelineCompositionEnvelope(document)
|
||||
if err == nil || !strings.Contains(err.Error(), test.want) {
|
||||
t.Fatalf("splitPipelineCompositionEnvelope() error = %v, want containing %q", err, test.want)
|
||||
}
|
||||
if !reflect.DeepEqual(document.root, originalRoot) {
|
||||
t.Fatalf("splitPipelineCompositionEnvelope() mutated invalid input")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadPipelineCompositionImportsDisjointFieldsAndTracksOwnership(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
rootPath := writePipelineSource(t, dir, "pipeline.yml", `composition:
|
||||
|
||||
Reference in New Issue
Block a user