Test inherited configuration resolution
This commit is contained in:
@@ -79,6 +79,8 @@ or replace the final suite in Stage 5.
|
|||||||
|
|
||||||
## Stage 2 — Verify Inherited Configuration, Defaults, and Credentials
|
## Stage 2 — Verify Inherited Configuration, Defaults, and Credentials
|
||||||
|
|
||||||
|
**Completion:** Complete.
|
||||||
|
|
||||||
**Primary files:** `internal/core/config/config_test.go`; change
|
**Primary files:** `internal/core/config/config_test.go`; change
|
||||||
`internal/core/config/config.go` only if these checks expose an integration defect.
|
`internal/core/config/config.go` only if these checks expose an integration defect.
|
||||||
|
|
||||||
|
|||||||
@@ -137,9 +137,167 @@ func TestSurvivingCredentials(t *testing.T) {
|
|||||||
if err != nil || loaded.Config.Backends["other"].Credential != nil {
|
if err != nil || loaded.Config.Backends["other"].Credential != nil {
|
||||||
t.Fatalf("null credential: %+v %v", loaded, err)
|
t.Fatalf("null credential: %+v %v", loaded, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inherited := `version: 2
|
||||||
|
backends:
|
||||||
|
parent:
|
||||||
|
endpoint: https://parent.invalid/v1
|
||||||
|
credential: BASE_SECRET
|
||||||
|
local:
|
||||||
|
extends: parent
|
||||||
|
credential: null
|
||||||
|
llm:
|
||||||
|
proposal_profile: proposal
|
||||||
|
`
|
||||||
|
if _, err := loadText(inherited, ""); err == nil {
|
||||||
|
t.Fatal("null child credential removed the unselected parent's surviving reference")
|
||||||
|
}
|
||||||
|
t.Setenv("BASE_SECRET", "synthetic-parent-secret")
|
||||||
|
loaded, err = loadText(strings.Replace(inherited, " credential: null\n", "", 1), "")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if got := loaded.Config.Backends["local"].Credential.Value(); got != "synthetic-parent-secret" {
|
||||||
|
t.Fatalf("inherited secret: %q", got)
|
||||||
|
}
|
||||||
|
if got := loaded.Metadata().IsExplicit(ck.Keys("backends", "local", "credential")); !got {
|
||||||
|
t.Fatal("inherited credential is not explicit")
|
||||||
|
}
|
||||||
|
var inheritedEffective bytes.Buffer
|
||||||
|
if err := loaded.WriteEffective(&inheritedEffective); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if strings.Contains(inheritedEffective.String(), "synthetic-parent-secret") {
|
||||||
|
t.Fatal("effective output leaked an inherited secret")
|
||||||
|
}
|
||||||
|
loaded, err = loadText(inherited, "")
|
||||||
|
if err != nil || loaded.Config.Backends["local"].Credential != nil {
|
||||||
|
t.Fatalf("child null credential: %+v %v", loaded, err)
|
||||||
|
}
|
||||||
|
if got := loaded.Config.Backends["parent"].Credential.Value(); got != "synthetic-parent-secret" {
|
||||||
|
t.Fatalf("parent credential after child null: %q", got)
|
||||||
|
}
|
||||||
|
|
||||||
t.Setenv("AUDITA_MODEL", "legacy-model")
|
t.Setenv("AUDITA_MODEL", "legacy-model")
|
||||||
loaded, err = loadText(base, "")
|
loaded, err = loadText(base, "")
|
||||||
if err != nil || loaded.Config.LLM.ProposalProfile != "proposal" {
|
if err != nil || loaded.Config.LLM.ProposalProfile != "proposal" {
|
||||||
t.Fatalf("legacy environment affected loading: %+v %v", loaded, err)
|
t.Fatalf("legacy environment affected loading: %+v %v", loaded, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestSiblingInheritancePreservesBackendSettings(t *testing.T) {
|
||||||
|
text := `version: 2
|
||||||
|
backends:
|
||||||
|
base:
|
||||||
|
endpoint: https://base.invalid/v1
|
||||||
|
concurrency: 3
|
||||||
|
queue_capacity: 0
|
||||||
|
local:
|
||||||
|
extends: base
|
||||||
|
llm:
|
||||||
|
proposal_profile: proposal
|
||||||
|
`
|
||||||
|
loaded, err := loadText(text, "")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
backend := loaded.Config.Backends["local"]
|
||||||
|
if backend.Endpoint != "https://base.invalid/v1" || backend.Concurrency != 3 || backend.QueueCapacity != 0 {
|
||||||
|
t.Fatalf("inherited backend settings: %+v", backend)
|
||||||
|
}
|
||||||
|
for _, path := range []ck.Path{
|
||||||
|
ck.Keys("backends", "local", "endpoint"),
|
||||||
|
ck.Keys("backends", "local", "concurrency"),
|
||||||
|
ck.Keys("backends", "local", "queue_capacity"),
|
||||||
|
} {
|
||||||
|
if !loaded.Metadata().IsExplicit(path) {
|
||||||
|
t.Errorf("inherited field %s is not explicit", path.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
overridden, err := loadText(strings.Replace(text, " extends: base\n", " extends: base\n concurrency: 2\n", 1), "")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if got := overridden.Config.Backends["local"].Concurrency; got != 2 {
|
||||||
|
t.Fatalf("child concurrency override: %d", got)
|
||||||
|
}
|
||||||
|
if got := overridden.Config.Backends["local"].QueueCapacity; got != 0 {
|
||||||
|
t.Fatalf("inherited zero queue capacity: %d", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSiblingInheritanceUsesSelectedOverlay(t *testing.T) {
|
||||||
|
dir := t.TempDir()
|
||||||
|
if err := os.Mkdir(filepath.Join(dir, "overlays"), 0700); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
main := filepath.Join(dir, "config.yml")
|
||||||
|
text := `version: 2
|
||||||
|
backends:
|
||||||
|
base:
|
||||||
|
endpoint: https://base.invalid/v1
|
||||||
|
concurrency: 3
|
||||||
|
queue_capacity: 0
|
||||||
|
local:
|
||||||
|
extends: base
|
||||||
|
concurrency: 2
|
||||||
|
llm:
|
||||||
|
proposal_profile: proposal
|
||||||
|
`
|
||||||
|
if err := os.WriteFile(main, []byte(text), 0600); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err := os.WriteFile(filepath.Join(dir, "overlays", "testing.yml"), []byte("backends:\n base:\n endpoint: https://overlay.invalid/v1\n concurrency: 4\n"), 0600); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
loaded, err := Load(ck.File(main), "testing")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
child := loaded.Config.Backends["local"]
|
||||||
|
if child.Endpoint != "https://overlay.invalid/v1" || child.Concurrency != 2 || child.QueueCapacity != 0 {
|
||||||
|
t.Fatalf("overlay inheritance and child override: %+v", child)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSiblingInheritanceDoesNotBypassBackendValidation(t *testing.T) {
|
||||||
|
for _, tc := range []struct {
|
||||||
|
name string
|
||||||
|
text string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "invalid inherited parent setting",
|
||||||
|
text: `version: 2
|
||||||
|
backends:
|
||||||
|
base:
|
||||||
|
endpoint: https://base.invalid/v1
|
||||||
|
concurrency: 0
|
||||||
|
local:
|
||||||
|
extends: base
|
||||||
|
llm:
|
||||||
|
proposal_profile: proposal
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "invalid child override",
|
||||||
|
text: `version: 2
|
||||||
|
backends:
|
||||||
|
base:
|
||||||
|
endpoint: https://base.invalid/v1
|
||||||
|
concurrency: 3
|
||||||
|
local:
|
||||||
|
extends: base
|
||||||
|
concurrency: 0
|
||||||
|
llm:
|
||||||
|
proposal_profile: proposal
|
||||||
|
`,
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
if _, err := loadText(tc.text, ""); err == nil {
|
||||||
|
t.Fatal("invalid backend concurrency accepted")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user