From 8175ed87d03c669ea430e63ae91c4e04f2d98c9e Mon Sep 17 00:00:00 2001 From: Eric Rakestraw Date: Sat, 3 Oct 2026 17:23:28 +0000 Subject: [PATCH] Verify inherited backend runtime integration --- cmd/audita/main_integration_test.go | 78 +++++++++++++++++++ docs/roadmap/implementation.md | 2 + .../framework/llm/adapter_capacity_test.go | 6 +- 3 files changed, 85 insertions(+), 1 deletion(-) diff --git a/cmd/audita/main_integration_test.go b/cmd/audita/main_integration_test.go index 7c703a7..cafd9cb 100644 --- a/cmd/audita/main_integration_test.go +++ b/cmd/audita/main_integration_test.go @@ -293,6 +293,25 @@ func (f processFixture) run(t *testing.T, includeOutput bool, extra ...string) ( return code, stdout.String(), stderr.String() } +func (f processFixture) runConfigView(t *testing.T, view string) (int, string, string) { + t.Helper() + command := exec.Command(os.Args[0], "-test.run=^TestProcessSubprocessHelper$", "--", "config", "print-effective", "--config", f.config, "--view", view) + command.Dir = f.dir + command.Env = append(os.Environ(), "AUDITA_HELPER_PROCESS=1", "AUDITA_TEST_PROVIDER_KEY="+f.provider.secret) + var stdout, stderr bytes.Buffer + command.Stdout, command.Stderr = &stdout, &stderr + err := command.Run() + code := 0 + if err != nil { + if exit, ok := err.(*exec.ExitError); ok { + code = exit.ExitCode() + } else { + t.Fatal(err) + } + } + return code, stdout.String(), stderr.String() +} + func (f processFixture) errors(t *testing.T) reporting.ErrorsDocument { t.Helper() raw, err := os.ReadFile(filepath.Join(f.dir, "errors.yml")) @@ -840,6 +859,21 @@ func TestSubprocessReportingAndDebugSelections(t *testing.T) { {false, false}, {false, true}, {true, false}, {true, true}, } { f := newProcessFixture(t, "normal", "[grammar]") + if selection.reporting && selection.debug { + original, err := os.ReadFile(f.config) + if err != nil { + t.Fatal(err) + } + old := fmt.Sprintf("backends:\n local:\n endpoint: %s/v1\n credential: AUDITA_TEST_PROVIDER_KEY", f.server.URL) + inherited := fmt.Sprintf("backends:\n local-base:\n endpoint: %s/v1\n credential: AUDITA_TEST_PROVIDER_KEY\n concurrency: 2\n queue_capacity: 0\n local:\n extends: local-base\n concurrency: 1", f.server.URL) + updated := strings.Replace(string(original), old, inherited, 1) + if updated == string(original) { + t.Fatal("process fixture backend configuration was not found") + } + if err := os.WriteFile(f.config, []byte(updated), 0600); err != nil { + t.Fatal(err) + } + } reportDir := filepath.Join(f.dir, "missing") extra := []string{"--reporting=false", "--report-dir", reportDir} if selection.reporting { @@ -882,6 +916,31 @@ func TestSubprocessReportingAndDebugSelections(t *testing.T) { t.Fatal(err) } } + if selection.reporting { + effective, err := os.ReadFile(filepath.Join(dirs[0], "effective-config.redacted.yaml")) + if err != nil { + t.Fatal(err) + } + if !strings.Contains(string(effective), f.server.URL+"/v1") || !strings.Contains(string(effective), "concurrency: 1") || !strings.Contains(string(effective), "queue_capacity: 0") || strings.Contains(string(effective), f.provider.secret) { + t.Fatalf("effective inherited settings: %s", effective) + } + origins, err := os.ReadFile(filepath.Join(dirs[0], "config-origins.yaml")) + if err != nil { + t.Fatal(err) + } + for _, want := range []string{"from: /backends/local-base/endpoint", "to: /backends/local/endpoint", "reference: /backends/local/extends"} { + if !strings.Contains(string(origins), want) { + t.Fatalf("configuration origins missing %q: %s", want, origins) + } + } + if strings.Contains(string(origins), f.provider.secret) { + t.Fatal("configuration origins exposed the resolved inherited credential") + } + code, explain, stderr := f.runConfigView(t, "explain") + if code != 0 || stderr != "" || !strings.Contains(explain, "from: /backends/local-base/endpoint") || strings.Contains(explain, f.provider.secret) { + t.Fatalf("inheritance explanation: code=%d stdout=%s stderr=%s", code, explain, stderr) + } + } } } } @@ -1051,6 +1110,25 @@ func TestSubprocessInvalidInputLeavesFailedReports(t *testing.T) { } } +func TestSubprocessMissingInheritanceParentFailsBeforeProviderDispatch(t *testing.T) { + f := newProcessFixture(t, "normal", "[grammar]") + original, err := os.ReadFile(f.config) + if err != nil { + t.Fatal(err) + } + updated := strings.Replace(string(original), " local:\n endpoint:", " local:\n extends: missing\n endpoint:", 1) + if updated == string(original) { + t.Fatal("process fixture backend configuration was not found") + } + if err := os.WriteFile(f.config, []byte(updated), 0600); err != nil { + t.Fatal(err) + } + code, stdout, stderr := f.run(t, true) + if code != 2 || stdout != "" || f.provider.callCount() != 0 || !strings.Contains(stderr, "referenced sibling does not exist") { + t.Fatalf("missing parent handling: code=%d stdout=%q stderr=%q provider calls=%d", code, stdout, stderr, f.provider.callCount()) + } +} + func TestSubprocessInvalidInputWritesFailedReportsToSelectedDirectory(t *testing.T) { f := newProcessFixture(t, "normal", "[grammar]") if err := os.WriteFile(f.transcript, []byte("not JSON"), 0600); err != nil { diff --git a/docs/roadmap/implementation.md b/docs/roadmap/implementation.md index 8d2abc1..1a6e67b 100644 --- a/docs/roadmap/implementation.md +++ b/docs/roadmap/implementation.md @@ -158,6 +158,8 @@ Review emitted fields and affected documentation, then commit the inspection uni ## Stage 4 — Verify CLI Failures and Runtime Use of Inherited Backends +**Completion:** Complete. + **Primary files:** `internal/framework/llm/adapter_capacity_test.go`, `internal/cli/config_input_test.go`, and `cmd/audita/main_integration_test.go`. Touch production wiring only to fix a diff --git a/internal/framework/llm/adapter_capacity_test.go b/internal/framework/llm/adapter_capacity_test.go index 6ac5bc2..69b4010 100644 --- a/internal/framework/llm/adapter_capacity_test.go +++ b/internal/framework/llm/adapter_capacity_test.go @@ -23,9 +23,13 @@ import ( ) func TestRolesShareBackendCapacityAndReleaseAfterCancellation(t *testing.T) { + t.Setenv("INHERITED_TEST_KEY", "synthetic-inherited-runtime-secret") entered := make(chan struct{}, 3) release := make(chan struct{}) server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if got := r.Header.Get("Authorization"); got != "Bearer synthetic-inherited-runtime-secret" { + t.Errorf("inherited credential header: %q", got) + } entered <- struct{}{} <-release content, _ := json.Marshal(`{"corrections":[]}`) @@ -37,7 +41,7 @@ func TestRolesShareBackendCapacityAndReleaseAfterCancellation(t *testing.T) { t.Fatal(err) } main := filepath.Join(dir, "config.yml") - body := fmt.Sprintf("version: 2\nbackends:\n shared:\n endpoint: %s/v1\n concurrency: 1\n queue_capacity: 0\nllm:\n proposal_profile: proposal\n validation_profile: validation\n transient_retries: 0\n repair_attempts: 0\n", server.URL) + body := fmt.Sprintf("version: 2\nbackends:\n shared-base:\n endpoint: %s/v1\n credential: INHERITED_TEST_KEY\n concurrency: 1\n queue_capacity: 0\n shared:\n extends: shared-base\nllm:\n proposal_profile: proposal\n validation_profile: validation\n transient_retries: 0\n repair_attempts: 0\n", server.URL) if err := os.WriteFile(main, []byte(body), 0600); err != nil { t.Fatal(err) }