feat: manage embedded pi with thothctl
This commit is contained in:
@@ -347,6 +347,59 @@ func TestRunPreservesChildExitCodes(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestRunPiStatusUsesImageBundledPi(t *testing.T) {
|
||||
fixture := newCLIFixture(t, "THT_LLM_URL=https://llm.example.invalid\n")
|
||||
fixture.setEnvironment(t)
|
||||
|
||||
var stdout, stderr bytes.Buffer
|
||||
exitCode := run(context.Background(), []string{"--installation", fixture.installationPath, "pi", "status"}, &stdout, &stderr)
|
||||
|
||||
if exitCode != 0 {
|
||||
t.Fatalf("run() exit code = %d, stderr = %s", exitCode, stderr.String())
|
||||
}
|
||||
if stdout.String() != "Pi version: 0.80.3\n" {
|
||||
t.Errorf("stdout = %q, want image-bundled Pi version", stdout.String())
|
||||
}
|
||||
assertInvocationContains(t, fixture.invocations(t), "exec", "-T", "core", "pi", "--version")
|
||||
}
|
||||
|
||||
func TestRunPiUpdateRequiresExplicitConfirmationWithoutInvokingDocker(t *testing.T) {
|
||||
fixture := newCLIFixture(t, "THT_LLM_URL=https://llm.example.invalid\n")
|
||||
fixture.setEnvironment(t)
|
||||
|
||||
var stdout, stderr bytes.Buffer
|
||||
exitCode := run(context.Background(), []string{"--installation", fixture.installationPath, "pi", "update", "--version", "0.81.0"}, &stdout, &stderr)
|
||||
|
||||
if exitCode != 2 {
|
||||
t.Errorf("run() exit code = %d, want 2", exitCode)
|
||||
}
|
||||
if !strings.Contains(stderr.String(), "requires --yes") {
|
||||
t.Errorf("stderr = %q, want explicit confirmation guidance", stderr.String())
|
||||
}
|
||||
assertDockerNotInvoked(t, fixture)
|
||||
}
|
||||
|
||||
func TestRunPiStatusPreservesDockerExitCodeAndRedactsDiagnostics(t *testing.T) {
|
||||
fixture := newCLIFixture(t, "PI_TOKEN_FILE=%s\n")
|
||||
secretPath := filepath.Join(fixture.root, "pi-secret")
|
||||
if err := os.WriteFile(secretPath, []byte("pi-status-secret"), 0o600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
fixture.setEnvironment(t, secretPath)
|
||||
t.Setenv("THOTHCTL_FAKE_FAIL_ON", "version")
|
||||
t.Setenv("THOTHCTL_FAKE_FAILURE", "pi-status-secret")
|
||||
|
||||
var stdout, stderr bytes.Buffer
|
||||
exitCode := run(context.Background(), []string{"--installation", fixture.installationPath, "pi", "status"}, &stdout, &stderr)
|
||||
|
||||
if exitCode != 41 {
|
||||
t.Errorf("run() exit code = %d, want 41", exitCode)
|
||||
}
|
||||
if strings.Contains(stdout.String()+stderr.String(), "pi-status-secret") {
|
||||
t.Errorf("Pi status exposed a secret: stdout=%q stderr=%q", stdout.String(), stderr.String())
|
||||
}
|
||||
}
|
||||
|
||||
type cliFixture struct {
|
||||
root string
|
||||
installationPath string
|
||||
@@ -392,8 +445,9 @@ func newCLIFixture(t *testing.T, envTemplate string) cliFixture {
|
||||
printf '%s\n' "$@" >> "$THOTHCTL_FAKE_ARGS"
|
||||
printf '%s\n' -- >> "$THOTHCTL_FAKE_ARGS"
|
||||
case " $* " in
|
||||
*" config --format json "*) printf '%s\n' '{"volumes":{"settings":{}}}' ;;
|
||||
*" config --format json "*) printf '%s\n' '{"volumes":{"settings":{}},"services":{"core":{"image":"thothii-core:local","environment":{"THT_LLM_URL":"https://llm.example.invalid"}}}}' ;;
|
||||
*" ps --format json "*) printf '%s\n' '[{"Service":"core","State":"running","Health":"healthy"},{"Service":"frontend","State":"running","Health":"healthy"}]' ;;
|
||||
*" pi --version "*) printf '%s\n' '0.80.3' ;;
|
||||
*" logs "*) printf '%s\n' "$THOTHCTL_FAKE_LOG" ;;
|
||||
esac
|
||||
if [ "${THOTHCTL_FAKE_FAIL_ON:-}" = "version" ]; then
|
||||
@@ -458,3 +512,18 @@ func assertDockerNotInvoked(t *testing.T, fixture cliFixture) {
|
||||
t.Errorf("Docker was invoked: stat error = %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func assertInvocationContains(t *testing.T, invocations [][]string, want ...string) {
|
||||
t.Helper()
|
||||
for _, invocation := range invocations {
|
||||
for start := range invocation {
|
||||
if len(invocation)-start < len(want) {
|
||||
continue
|
||||
}
|
||||
if strings.Join(invocation[start:start+len(want)], "\x00") == strings.Join(want, "\x00") {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
t.Fatalf("invocations = %#v, want %#v", invocations, want)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user