package cli import ( "bytes" "context" "os" "path/filepath" "strings" "testing" ) func writeRuntimeErrorConfig(t *testing.T, operatorDocument string) string { t.Helper() dir := t.TempDir() profiles := filepath.Join(dir, "profiles") if err := os.Mkdir(profiles, 0700); err != nil { t.Fatal(err) } main := filepath.Join(dir, "config.yml") configText := "version: 2\nprofiles_dir: profiles\nbackends:\n offline:\n endpoint: http://127.0.0.1:1/v1\n credential: AUDITA_TEST_PROVIDER_KEY\nllm:\n proposal_profile: proposal\n" if err := os.WriteFile(main, []byte(configText), 0600); err != nil { t.Fatal(err) } if err := os.WriteFile(filepath.Join(profiles, "operator.yml"), []byte(operatorDocument), 0600); err != nil { t.Fatal(err) } return main } func TestConfigCommandsClassifyOperatorPromptErrorsAsInputErrors(t *testing.T) { t.Setenv("AUDITA_TEST_PROVIDER_KEY", "synthetic-cli-redaction-secret") definitions := map[string]string{ "malformed operator YAML": "profiles:\n proposal: [\n", "invalid operator template": "profiles:\n proposal:\n backend: offline\n model: local-model\nprompts:\n modules.grammar.proposal:\n v1:\n messages:\n - role: user\n content: '{{'\n", "missing operator message resource": "profiles:\n proposal:\n backend: offline\n model: local-model\nprompts:\n modules.grammar.proposal:\n v1:\n messages:\n - role: user\n content_file: missing-instruction.md\n", } commands := []struct { name string args []string }{ {name: "validate", args: []string{"config", "validate"}}, {name: "print effective", args: []string{"config", "print-effective", "--view", "profiles"}}, } for definition, document := range definitions { for _, command := range commands { t.Run(definition+"/"+command.name, func(t *testing.T) { main := writeRuntimeErrorConfig(t, document) args := append(append([]string(nil), command.args...), "--config", main) var stdout, stderr bytes.Buffer if code := Run(context.Background(), args, &stdout, &stderr); code != 2 { t.Fatalf("exit=%d, stdout=%q, stderr=%q", code, stdout.String(), stderr.String()) } if strings.Contains(stderr.String(), "synthetic-cli-redaction-secret") { t.Fatalf("configured secret leaked: %q", stderr.String()) } }) } } } func TestConfigCommandsKeepCallerCancellationAsRuntimeExit(t *testing.T) { t.Setenv("AUDITA_TEST_PROVIDER_KEY", "synthetic-cli-redaction-secret") main := writeRuntimeErrorConfig(t, "profiles:\n proposal:\n backend: offline\n model: local-model\n") commands := [][]string{ {"config", "validate", "--config", main}, {"config", "print-effective", "--config", main, "--view", "profiles"}, } for _, args := range commands { ctx, cancel := context.WithCancel(context.Background()) cancel() var stdout, stderr bytes.Buffer if code := Run(ctx, args, &stdout, &stderr); code != 1 { t.Fatalf("args=%v exit=%d, stdout=%q, stderr=%q", args, code, stdout.String(), stderr.String()) } } }