package engine import ( "bytes" "reflect" "testing" ) func TestMetadataHistoricalPaths(t *testing.T) { t.Parallel() result, err := testLoad[map[string]any](Bytes("base", []byte("retired: {child: 1}\nshape: {'0': base}\n'a/b~': {'': 2}\n")), Options[map[string]any]{ Overrides: []Override{ {Path: Keys("retired"), Value: nil, Flag: "--retired"}, {Path: Keys("shape"), Value: []any{"replacement"}, Flag: "--shape"}, }, }) if err != nil { t.Fatal(err) } metadata := result.Metadata() paths := metadata.HistoricalPaths() var got []string for _, path := range paths { got = append(got, path.String()) if len(metadata.History(path)) == 0 { t.Fatalf("enumerated path %s has no history", path) } } want := []string{"", "/a~1b~0", "/a~1b~0/", "/retired", "/retired/child", "/shape", "/shape/0"} if !reflect.DeepEqual(got, want) { t.Fatalf("historical paths = %v, want %v", got, want) } if _, ok := metadata.Lookup(paths[4]); ok { t.Fatal("removed descendant remains effective") } if _, ok := metadata.Lookup(paths[6]); !ok { t.Fatal("enumerated numeric path cannot query the new sequence shape") } // Returned slices and nested paths must not alias retained metadata. paths[1].segments[0].key = "mutated" paths[2] = Keys("replacement") if again := metadata.HistoricalPaths(); again[1].String() != want[1] || again[2].String() != want[2] { t.Fatal("enumeration returned aliased paths") } if len((Metadata{}).HistoricalPaths()) != 0 { t.Fatal("zero metadata contains paths") } } func TestHistoricalPathsExposeHiddenBaseOwnershipWithoutResolvingBaseSecrets(t *testing.T) { t.Setenv("CONFIGKIT_HISTORY_UNUSED_PROD_KEY", "") t.Setenv("CONFIGKIT_HISTORY_TEST_KEY", "synthetic-test-key") type config struct { Credential *Secret `yaml:"credential"` Definitions map[string]map[string]string `yaml:"definitions"` } for _, credential := range []string{"CONFIGKIT_HISTORY_TEST_KEY", "null"} { t.Run(credential, func(t *testing.T) { dir := t.TempDir() root := writeImportFile(t, dir, "main.yml", "configkit:\n imports: [{path: first.yml}, {path: second.yml}]\ncredential: CONFIGKIT_HISTORY_UNUSED_PROD_KEY\n") writeImportFile(t, dir, "first.yml", "definitions: {recap: {prompt: recap}}\n") writeImportFile(t, dir, "second.yml", "definitions: {recap: {output: recap.md}}\n") writeImportFile(t, dir, "overlays/testing.yml", "definitions: null\ncredential: "+credential+"\n") result, err := testLoad[config](File(root), Options[config]{Imports: true, Overlay: "testing"}) if err != nil { t.Fatal(err) } metadata := result.Metadata() found := false for _, path := range metadata.HistoricalPaths() { if path.String() != "/definitions/recap" { continue } found = true owners := map[string]bool{} for _, change := range metadata.History(path) { if change.Origin.Layer == LayerBase { for _, location := range change.Origin.Locations { owners[location.SourceID] = true } } } if len(owners) != 2 { t.Fatalf("hidden declaration owners = %v", owners) } } if !found { t.Fatal("hidden base declaration was not discoverable") } }) } } func TestMetadataQueriesReturnDetachedRecords(t *testing.T) { t.Parallel() path := Keys("service", "workers") metadata := Metadata{ effectivePaths: map[string]Path{path.String(): path}, historicalPaths: map[string][]Path{path.String(): {path}}, fields: map[string]FieldInfo{ path.String(): { Explicit: true, Origin: Origin{ Layer: LayerBase, Locations: []Location{{SourceID: "source-1", Line: 2, Column: 3}}, }, }, }, history: map[string][]Change{ path.String(): {{ Path: path, Origin: Origin{Layer: LayerResolution, Locations: []Location{{SourceID: "source-1"}}}, Previous: []Origin{{Layer: LayerDefault, Locations: []Location{{SourceID: "default"}}}}, Reasons: []string{"bounded worker count"}, Dependencies: []Path{Keys("limits")}, }}, }, } info, ok := metadata.Lookup(path) if !ok || !info.Explicit || !metadata.IsExplicit(path) { t.Fatalf("Lookup() = %#v, %v", info, ok) } info.Origin.Locations[0].SourceID = "mutated" again, _ := metadata.Lookup(path) if again.Origin.Locations[0].SourceID != "source-1" { t.Fatal("Lookup returned aliased locations") } history := metadata.History(path) history[0].Reasons[0] = "mutated" history[0].Previous[0].Locations[0].SourceID = "mutated" history[0].Dependencies[0].segments[0].key = "mutated" againHistory := metadata.History(path) if againHistory[0].Reasons[0] != "bounded worker count" || againHistory[0].Previous[0].Locations[0].SourceID != "default" || againHistory[0].Dependencies[0].String() != "/limits" { t.Fatal("History returned aliased nested records") } missing := Keys("missing") if _, ok := metadata.Lookup(missing); ok || metadata.IsExplicit(missing) || metadata.History(missing) != nil { t.Fatal("unknown path produced metadata") } if _, ok := metadata.Lookup(Path{}.Index(-1)); ok { t.Fatal("invalid path produced metadata") } } func TestResolutionInputKeepsDetachedEntryMetadata(t *testing.T) { t.Parallel() type configuration struct { Default string `yaml:"default"` Items []string `yaml:"items"` Values map[string]string `yaml:"values"` Nullable *string `yaml:"nullable"` } schema := mustSchemaFor[configuration](t) document := parseDocumentForDecode(t, "items: [first]\nvalues: {'0': key, 'a/b~': escaped}\nnullable: null\n") decoded, issues := decodeConfiguration(schema, reflect.ValueOf(configuration{Default: "retained"}), document) if len(issues) != 0 { t.Fatalf("decode issues = %#v", issues) } metadata := metadataFromDecoded(decoded) input := newResolutionInput(metadata, decoded.final, []SourceInfo{{ ID: "source-1", Label: "decode.yml", Layer: LayerBase, ImportedFrom: &Location{SourceID: "parent", Line: 1, Column: 1}, }}) parsedItem, err := ParsePath("/items/0") if err != nil { t.Fatal(err) } parsedKey, err := ParsePath("/values/0") if err != nil { t.Fatal(err) } for _, path := range []Path{Path{}, Keys("default"), Keys("nullable"), parsedItem, parsedKey, Keys("values", "a/b~")} { if _, ok := input.lookup(path); !ok { t.Fatalf("entry path %s is missing", path) } } defaultInfo, _ := input.lookup(Keys("default")) nullInfo, _ := input.lookup(Keys("nullable")) if defaultInfo.Explicit || !nullInfo.Explicit || !nullInfo.Null { t.Fatalf("default = %#v, nullable = %#v", defaultInfo, nullInfo) } for _, path := range []Path{ Keys("default", "child"), Keys("items", "0"), Keys("values").Index(0), Keys("items").Index(1), } { if _, ok := input.lookup(path); ok { t.Fatalf("entry lookup accepted %s", path) } } item, _ := input.lookup(parsedItem) item.Origin.Locations[0].SourceID = "mutated" source, ok := input.source("source-1") if !ok { t.Fatal("source is missing") } source.ImportedFrom.SourceID = "mutated" configurationAtEntry := decoded.value.Interface().(configuration) resolved := runResolution(&configurationAtEntry, func(value *configuration, resolution *Resolution) error { value.Items[0] = "normalized" resolution.Record(Keys("items"), ChangeNormalization, "normalized item") return nil }, schema, decoded, document, input) if len(resolved.diagnostics) != 0 { t.Fatalf("resolution diagnostics = %#v", resolved.diagnostics) } applyResolutionMetadata(&metadata, resolved) metadata.effectivePaths = effectivePathIndex(resolved.final) again, ok := input.lookup(parsedItem) if !ok || again.Origin.Locations[0].SourceID != "source-1" || again.Origin.Operation != "" { t.Fatalf("entry metadata changed after resolution = %#v, %v", again, ok) } againSource, ok := input.source("source-1") if !ok || againSource.ImportedFrom == nil || againSource.ImportedFrom.SourceID != "parent" { t.Fatalf("entry source changed = %#v, %v", againSource, ok) } if _, ok := input.source(""); ok { t.Fatal("empty source identity resolved") } } func TestQueriesRespectActualHistoricalAndEffectiveContainers(t *testing.T) { result, err := testLoad[map[string]any](Bytes("base", []byte("items: [1]\nm: {'0': 2}\nx: 3\nretired: {child: 4}\n")), Options[map[string]any]{Overrides: []Override{{Path: Keys("retired"), Value: "removed", Flag: "--retired"}}}) if err != nil { t.Fatal(err) } for _, path := range []Path{Keys("items", "0"), Keys("m").Index(0), Keys("x", "missing"), Keys("items").Index(8)} { if _, ok := result.Metadata().Lookup(path); ok { t.Fatalf("invalid lookup %s", path) } if result.Metadata().History(path) != nil { t.Fatalf("invalid history %s", path) } if _, ok := result.Explain(path); ok { t.Fatalf("invalid explanation %s", path) } var out bytes.Buffer if err := result.WriteExplanation(&out, path); err == nil || out.Len() != 0 { t.Fatalf("invalid path wrote output: %s", path) } } for _, pointer := range []string{"/items/0", "/m/0"} { path, _ := ParsePath(pointer) if _, ok := result.Metadata().Lookup(path); !ok { t.Fatal("parsed path lost lookup") } if _, ok := result.Explain(path); !ok { t.Fatal("parsed path lost explanation") } } retired := Keys("retired", "child") if _, ok := result.Metadata().Lookup(retired); ok { t.Fatal("removed path remains effective") } if len(result.Metadata().History(retired)) == 0 { t.Fatal("removed history missing") } x, ok := result.Explain(retired) if !ok || x.Effective.Present || len(x.History) == 0 { t.Fatal("removed explanation missing") } }