Verify relative imports through the application lifecycle

This commit is contained in:
2026-10-14 17:39:28 +00:00
parent 6458dbd3aa
commit a20ba0af27
2 changed files with 224 additions and 1 deletions

View File

@@ -0,0 +1,211 @@
package engine
import (
"bytes"
"fmt"
"reflect"
"strings"
"testing"
)
func TestRelativeImportsFeedFinalInheritanceAndInspectionLifecycle(t *testing.T) {
t.Parallel()
type entry struct {
Extends string `yaml:"extends"`
Label string `yaml:"label"`
Token *Secret `yaml:"token" configkit:"secret"`
Dynamic string `yaml:"dynamic"`
Derived string `yaml:"derived"`
Height int `yaml:"height"`
}
type configuration struct {
Catalog struct {
Entries map[string]entry `yaml:"entries"`
} `yaml:"catalog"`
}
load := func(dynamic string) *testResult[configuration] {
t.Helper()
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "entry.yml", `configkit:
imports:
- path: parent.yml
destination: [entries]
- path: child.yml
destination: [entries]
`)
writeImportFile(t, directory, "parent.yml", `parent:
label: lower
token: PARENT_TOKEN
height: 1
`)
writeImportFile(t, directory, "child.yml", fmt.Sprintf(`child:
extends: parent
label: child
dynamic: %s
height: 9
`, dynamic))
var defaultsCalls, resolveCalls, validateCalls int
secretPaths := make(map[string]bool)
lookupCalls := make(map[string]int)
request := loadRequest[configuration]{
main: loadInput{
source: Bytes("main", []byte("parent: {label: final, height: 4}\n")),
destination: Keys("catalog", "entries"),
},
underlays: []loadGroup{{inputs: []loadInput{{
source: File(mainPath), imports: true, destination: Keys("catalog"),
}}}},
definition: Definition[configuration]{
Defaults: func() configuration {
defaultsCalls++
var defaults configuration
defaults.Catalog.Entries = map[string]entry{"fallback": {Label: "default"}}
return defaults
},
Resolve: func(config *configuration, resolution *Resolution) error {
resolveCalls++
child := config.Catalog.Entries["child"]
child.Derived = child.Label + ":" + child.Dynamic + ":" + fmt.Sprint(child.Height)
config.Catalog.Entries["child"] = child
resolution.Record(Keys("catalog", "entries", "child", "derived"), ChangeNormalization, "derive final child summary", Keys("catalog", "entries", "child", "label"), Keys("catalog", "entries", "child", "dynamic"), Keys("catalog", "entries", "child", "height"))
return nil
},
Validate: func(config *configuration, validation *Validation) {
validateCalls++
parent := config.Catalog.Entries["parent"]
child := config.Catalog.Entries["child"]
if parent.Label != "final" || parent.Height != 4 || child.Label != "child" || child.Height != 9 || child.Derived != child.Label+":"+child.Dynamic+":9" || child.Token == nil || !child.Token.IsResolved() || child.Token.Value() != "parent-secret-canary" {
validation.Error(Keys("catalog", "entries", "child"), "final imported configuration was not available to validation")
}
},
Secret: func(path Path) bool {
secretPaths[path.String()] = true
return path.String() == "/catalog/entries/child/dynamic"
},
},
}
loaded, err := loadGroupedWithSecretLookup(request, testSecretBinding(), func(name string) (string, bool) {
lookupCalls[name]++
if name == "PARENT_TOKEN" {
return "parent-secret-canary", true
}
return "", false
})
if err != nil {
if loadError, ok := err.(*LoadError); ok {
t.Fatalf("relative import lifecycle diagnostics: %#v", loadError.Diagnostics())
}
t.Fatalf("relative import lifecycle: %v", err)
}
if defaultsCalls != 1 || resolveCalls != 1 || validateCalls != 1 || lookupCalls["PARENT_TOKEN"] != 1 {
t.Fatalf("lifecycle calls defaults=%d resolve=%d validate=%d lookups=%#v", defaultsCalls, resolveCalls, validateCalls, lookupCalls)
}
if !secretPaths["/catalog/entries/child/dynamic"] {
t.Fatalf("secret classifier did not see effective paths: %#v", secretPaths)
}
return testLoaded(loaded)
}
left := load("LEFT-DYNAMIC-CANARY")
child := left.Config.Catalog.Entries["child"]
if child.Extends != "" || child.Label != "child" || child.Height != 9 || child.Derived != "child:LEFT-DYNAMIC-CANARY:9" || child.Token == nil || child.Token.Value() != "parent-secret-canary" {
t.Fatalf("resolved imported child = %#v", child)
}
if left.Config.Catalog.Entries["parent"].Label != "final" || left.Config.Catalog.Entries["parent"].Height != 4 || left.Config.Catalog.Entries["fallback"].Label != "default" {
t.Fatalf("final parent/default shape = %#v", left.Config.Catalog.Entries)
}
childTokenPath := Keys("catalog", "entries", "child", "token")
childToken, found := left.Inspection.Explain(childTokenPath)
childTokenInfo, tokenInfoFound := left.Inspection.Metadata().Lookup(childTokenPath)
if !found || !tokenInfoFound || !childToken.Effective.Redacted || strings.Contains(childToken.Effective.YAML, "parent-secret-canary") || len(childTokenInfo.Origin.Inheritance) != 1 {
t.Fatalf("inherited field explanation = %#v, %v", childToken, found)
}
var explanation bytes.Buffer
if err := left.Inspection.WriteExplanation(&explanation, childTokenPath); err != nil || strings.Contains(explanation.String(), "parent-secret-canary") || strings.Contains(explanation.String(), "LEFT-DYNAMIC-CANARY") {
t.Fatalf("safe explanation = %q, %v", explanation.String(), err)
}
labelHistory := left.Inspection.Metadata().History(Keys("catalog", "entries", "parent", "label"))
if len(labelHistory) < 2 {
t.Fatalf("parent label history omitted replaced contribution: %#v", labelHistory)
}
derived, found := left.Inspection.Explain(Keys("catalog", "entries", "child", "derived"))
if !found || !derived.Effective.Redacted || strings.Contains(derived.Effective.YAML, "LEFT-DYNAMIC-CANARY") || len(derived.History) == 0 || derived.History[len(derived.History)-1].Origin.Operation != ChangeNormalization {
t.Fatalf("recorded derived field explanation = %#v, %v", derived, found)
}
right := load("RIGHT-DYNAMIC-CANARY")
differences, err := Diff(left.Inspection, right.Inspection)
if err != nil {
t.Fatal(err)
}
seen := make(map[string]bool)
for _, difference := range differences {
path := difference.Path.String()
seen[path] = true
if !difference.Left.Redacted || !difference.Right.Redacted || !difference.HiddenChanged || strings.Contains(difference.Left.YAML+difference.Right.YAML, "DYNAMIC-CANARY") || strings.Contains(difference.Left.YAML+difference.Right.YAML, "parent-secret-canary") {
t.Errorf("sensitive difference at %s = %#v", path, difference)
}
}
for _, path := range []string{"/catalog/entries/child/dynamic", "/catalog/entries/child/derived"} {
if !seen[path] {
t.Errorf("missing inherited/derived difference at %s: %#v", path, differences)
}
}
}
func TestRelativeImportMatchesWrappedPlacementAndSafeDiff(t *testing.T) {
t.Parallel()
load := func(relativeImport bool, value string) *testResult[map[string]any] {
t.Helper()
input := Input{Source: NoSource()}
options := LayeredOptions[map[string]any]{}
if relativeImport {
directory := t.TempDir()
mainPath := writeImportFile(t, directory, "main.yml", `configkit:
imports:
- path: fragment.yml
destination: [application]
`)
writeImportFile(t, directory, "fragment.yml", "field: "+value+"\n")
options.Underlays = []Underlay{{Inputs: []Input{{Source: File(mainPath), Imports: true}}}}
} else {
options.Underlays = []Underlay{{Inputs: []Input{{Source: Bytes("wrapped", []byte("application: {field: "+value+"}\n"))}}}}
}
loaded, err := LoadLayered(input, testSecretBinding(), options)
if err != nil {
t.Fatalf("LoadLayered: %v", err)
}
return testLoaded(loaded)
}
relativeBefore := load(true, "before")
relativeAfter := load(true, "after")
wrappedBefore := load(false, "before")
wrappedAfter := load(false, "after")
for _, pair := range [][2]*testResult[map[string]any]{{relativeBefore, wrappedBefore}, {relativeAfter, wrappedAfter}} {
if !reflect.DeepEqual(pair[0].Config, pair[1].Config) {
t.Fatalf("relative and wrapped configurations differ: %#v vs %#v", pair[0].Config, pair[1].Config)
}
for _, result := range pair {
if info, ok := result.Metadata().Lookup(Keys("application", "field")); !ok || !info.Explicit {
t.Fatalf("effective field presence = %#v, %v", info, ok)
}
}
}
relativeDiff, err := Diff(relativeBefore.Inspection, relativeAfter.Inspection)
if err != nil {
t.Fatal(err)
}
wrappedDiff, err := Diff(wrappedBefore.Inspection, wrappedAfter.Inspection)
if err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(relativeDiff, wrappedDiff) {
t.Fatalf("relative safe diff = %#v, wrapped safe diff = %#v", relativeDiff, wrappedDiff)
}
}