Audit source version lifecycle agreement

This commit is contained in:
2026-10-15 16:17:21 +00:00
parent 43c994a32a
commit b0550af6a3
2 changed files with 135 additions and 2 deletions

View File

@@ -1,6 +1,7 @@
package configkit_test
import (
"bytes"
"errors"
"os"
"path/filepath"
@@ -418,3 +419,114 @@ func TestFacadeSourceVersionEvidencePreservesAbsenceAndNull(t *testing.T) {
t.Fatalf("null declaration evidence = %#v", null)
}
}
func TestFacadeSourceVersionLifecycleKeepsConsumedHeadersOutOfPayloadHistory(t *testing.T) {
type serviceConfig struct {
Version uint64 `yaml:"version"`
Count int `yaml:"count"`
Enabled bool `yaml:"enabled"`
Nullable *string `yaml:"nullable"`
Revision string `yaml:"revision"`
Defaulted string `yaml:"defaulted"`
Resolved string `yaml:"resolved"`
Credential configkit.Secret `yaml:"credential"`
}
type configuration struct {
Service serviceConfig `yaml:"service"`
}
t.Setenv("CONFIGKIT_LIFECYCLE_SECRET", "lifecycle-secret-value")
var checked []configkit.Version
var validationCalls int
definition := configkit.Definition[configuration]{
Defaults: func() configuration {
return configuration{Service: serviceConfig{Defaulted: "from defaults"}}
},
Version: &configkit.VersionRule{
Path: configkit.Keys("version"),
Check: func(version configkit.Version, _ *configkit.Validation) error {
checked = append(checked, version)
return nil
},
},
Resolve: func(current *configuration, resolution *configkit.Resolution) error {
current.Service.Resolved = "resolved once"
resolution.Record(configkit.Keys("service", "resolved"), configkit.ChangeNormalization, "derive resolved value")
return nil
},
Validate: func(current *configuration, validation *configkit.Validation) {
validationCalls++
if current.Service.Version != 9007199254740993 || current.Service.Count != 0 || current.Service.Enabled ||
current.Service.Nullable != nil || current.Service.Revision != "ordinary-payload" || current.Service.Defaulted != "from defaults" ||
current.Service.Resolved != "resolved once" || current.Service.Credential.Value() != "lifecycle-secret-value" {
validation.Error(configkit.Keys("service"), "assembled values did not survive source declaration processing")
}
},
}
load := func(header string) *configkit.Result[configuration] {
t.Helper()
result, err := configkit.LoadLayered(configkit.Input{
Source: configkit.Bytes("main", []byte("version: 9007199254740993\n")), Destination: configkit.Keys("service"),
}, configkit.LayeredOptions[configuration]{
Definition: definition, SourceVersionMode: configkit.SourceVersionModeIfPresent,
Underlays: []configkit.Underlay{{Inputs: []configkit.Input{{
Source: configkit.Bytes("underlay", []byte("version: "+header+"\ncount: 0\nenabled: false\nnullable: null\nrevision: ordinary-payload\ncredential: CONFIGKIT_LIFECYCLE_SECRET\n")),
Destination: configkit.Keys("service"),
}}}},
})
if err != nil || result == nil {
var failure *configkit.LoadError
var diagnostics []configkit.Diagnostic
if errors.As(err, &failure) {
diagnostics = failure.Diagnostics()
}
t.Fatalf("LoadLayered(%q) = %#v, %v; diagnostics %#v", header, result, err, diagnostics)
}
return result
}
first := load("underlay-release-a")
second := load("underlay-release-b")
if len(checked) != 4 || checked[0].Text != "9007199254740993" || checked[1].Text != "underlay-release-a" ||
checked[2].Text != "9007199254740993" || checked[3].Text != "underlay-release-b" {
t.Fatalf("source declarations checked = %#v", checked)
}
if validationCalls != 2 || first.Config.Service != second.Config.Service {
t.Fatalf("final configs or validation count = %#v, %#v, %d", first.Config, second.Config, validationCalls)
}
if differences, err := configkit.Diff(first, second); err != nil || len(differences) != 0 {
t.Fatalf("different consumed declarations created effective differences: %#v, %v", differences, err)
}
var firstEffective, secondEffective bytes.Buffer
if err := first.WriteEffective(&firstEffective); err != nil {
t.Fatal(err)
}
if err := second.WriteEffective(&secondEffective); err != nil {
t.Fatal(err)
}
if firstEffective.String() != secondEffective.String() || strings.Contains(firstEffective.String(), "underlay-release") {
t.Fatalf("consumed declarations affected effective rendering:\n%s\n%s", firstEffective.String(), secondEffective.String())
}
sourcesA, sourcesB := first.Sources(), second.Sources()
if len(sourcesA) != 2 || len(sourcesB) != 2 || sourcesA[1].VersionCheck == nil || sourcesB[1].VersionCheck == nil ||
sourcesA[1].VersionCheck.Version.Text != "underlay-release-a" || sourcesB[1].VersionCheck.Version.Text != "underlay-release-b" {
t.Fatalf("sanitized evidence did not retain distinct accepted declarations: %#v / %#v", sourcesA, sourcesB)
}
versionExplanation, found := first.Explain(configkit.Keys("service", "version"))
if !found {
t.Fatal("retained main version missing from effective explanation")
}
underlayID := sourcesA[1].ID
for _, location := range versionExplanation.Origin.Locations {
if location.SourceID == underlayID {
t.Fatalf("consumed underlay declaration entered effective origin: %#v", versionExplanation.Origin)
}
}
for _, change := range versionExplanation.History {
for _, location := range change.Origin.Locations {
if location.SourceID == underlayID {
t.Fatalf("consumed underlay declaration entered effective history: %#v", versionExplanation.History)
}
}
}
}