Verify integer version provenance and protections
This commit is contained in:
104
explain_test.go
104
explain_test.go
@@ -366,6 +366,110 @@ func TestExplanationReconcilesDefaultsAfterInputReplacement(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestIntegerVersionInspectionRetainsInputAndReconcilesTypedValue(t *testing.T) {
|
||||
type config struct {
|
||||
Version string `yaml:"version"`
|
||||
}
|
||||
rule := &VersionRule{Path: Keys("version"), Check: func(version Version, _ *Validation) error {
|
||||
if version.Text != "4" {
|
||||
t.Errorf("version = %#v", version)
|
||||
}
|
||||
return nil
|
||||
}}
|
||||
options := Options[config]{Definition: Definition[config]{
|
||||
Defaults: func() config { return config{Version: "4"} },
|
||||
Version: rule,
|
||||
}}
|
||||
first, err := Load(Bytes("version.yml", []byte("version: 4\n")), options)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
second, err := Load(Bytes("version.yml", []byte("version: 4\n")), options)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if first.Config.Version != "4" || second.Config.Version != "4" {
|
||||
t.Fatalf("configurations = %#v / %#v", first.Config, second.Config)
|
||||
}
|
||||
inputVersion, inputOK := documentAtPath(first.applications[0].value, Keys("version"))
|
||||
finalVersion, finalOK := documentAtPath(first.final, Keys("version"))
|
||||
if !inputOK || inputVersion.Kind != document.Number || inputVersion.Text != "4" ||
|
||||
!finalOK || finalVersion.Kind != document.String || finalVersion.Text != "4" {
|
||||
t.Fatalf("input/final = %#v / %#v", inputVersion, finalVersion)
|
||||
}
|
||||
|
||||
info, ok := first.Metadata().Lookup(Keys("version"))
|
||||
if !ok || !info.Explicit || info.Null || info.Origin.Layer != LayerBase || len(info.Origin.Locations) != 1 ||
|
||||
info.Origin.Locations[0].SourceID != "source-1" || info.Origin.Locations[0].Line != 1 {
|
||||
t.Fatalf("version metadata = %#v, %v", info, ok)
|
||||
}
|
||||
explanation, ok := first.Explain(Keys("version"))
|
||||
if !ok || explanation.Effective.YAML != "'4'\n" {
|
||||
t.Fatalf("version explanation = %#v, %v", explanation, ok)
|
||||
}
|
||||
foundInput, foundDecoding := false, false
|
||||
for _, change := range explanation.History {
|
||||
if change.After.YAML == "4\n" && change.Origin.Layer == LayerBase {
|
||||
foundInput = true
|
||||
}
|
||||
if change.Before.YAML == "4\n" && change.After.YAML == "'4'\n" && change.Origin.Operation == ChangeDecoding {
|
||||
foundDecoding = true
|
||||
}
|
||||
if change.Origin.Layer == LayerResolution {
|
||||
t.Fatalf("conversion recorded as resolution: %#v", change)
|
||||
}
|
||||
}
|
||||
if !foundInput || !foundDecoding {
|
||||
t.Fatalf("version history = %#v", explanation.History)
|
||||
}
|
||||
paths := first.Metadata().HistoricalPaths()
|
||||
foundPath := false
|
||||
for _, path := range paths {
|
||||
if path.String() == "/version" {
|
||||
foundPath = true
|
||||
}
|
||||
}
|
||||
if !foundPath || len(first.Metadata().History(Keys("version"))) < 2 {
|
||||
t.Fatalf("historical version paths/history = %#v / %#v", paths, first.Metadata().History(Keys("version")))
|
||||
}
|
||||
|
||||
var effective strings.Builder
|
||||
if err := first.WriteEffective(&effective); err != nil || effective.String() != "version: '4'\n" {
|
||||
t.Fatalf("effective output = %q, %v", effective.String(), err)
|
||||
}
|
||||
first.Config.Version = "mutated"
|
||||
effective.Reset()
|
||||
if err := first.WriteEffective(&effective); err != nil || effective.String() != "version: '4'\n" || second.Config.Version != "4" {
|
||||
t.Fatalf("detached results = %q / %#v, %v", effective.String(), second.Config, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSensitiveIntegerVersionStaysRedactedWithoutSecretLookup(t *testing.T) {
|
||||
type config struct {
|
||||
Version string `yaml:"version"`
|
||||
}
|
||||
lookups := 0
|
||||
result, err := loadWithSecretLookup(Bytes("version.yml", []byte("version: 987654321\n")), func(string) (string, bool) {
|
||||
lookups++
|
||||
return "CREDENTIAL_CANARY", true
|
||||
}, Options[config]{Definition: Definition[config]{
|
||||
Version: &VersionRule{Path: Keys("version"), Check: func(Version, *Validation) error { return nil }},
|
||||
Secret: func(path Path) bool { return path.String() == "/version" },
|
||||
}})
|
||||
if err != nil || result.Config.Version != "987654321" || lookups != 0 {
|
||||
t.Fatalf("result = %#v, lookups = %d, err = %v", result, lookups, err)
|
||||
}
|
||||
var effective strings.Builder
|
||||
if err := result.WriteEffective(&effective); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
explanation, ok := result.Explain(Keys("version"))
|
||||
formatted := effective.String() + fmt.Sprintf("%#v %#v", explanation, result.Metadata().History(Keys("version")))
|
||||
if !ok || !explanation.Effective.Redacted || strings.Contains(formatted, "987654321") || strings.Contains(formatted, "CREDENTIAL_CANARY") {
|
||||
t.Fatalf("sensitive inspection = %q / %#v", effective.String(), explanation)
|
||||
}
|
||||
}
|
||||
|
||||
func TestExplanationReplaysResolutionAdditionsAndOverlappingIntent(t *testing.T) {
|
||||
type cfg struct {
|
||||
M map[string]any `yaml:"m"`
|
||||
|
||||
Reference in New Issue
Block a user