fix(auth): harden unified diagnostic execution

This commit is contained in:
2026-08-17 16:39:54 +02:00
parent 3ed00ff086
commit 30ee9433dc
20 changed files with 1034 additions and 57 deletions
+18 -9
View File
@@ -155,27 +155,36 @@ func RunWithProbe(ctx context.Context, installation config.Installation, runner
status, statusAvailable, servicesCheck := serviceStatus(ctx, installation, runner, secretValues)
coreRunning := false
coreHealthy := false
if statusAvailable {
var err error
coreRunning, err = service.CoreRunning(status)
if err != nil {
var runningErr, healthyErr error
coreRunning, runningErr = service.CoreRunning(status)
coreHealthy, healthyErr = service.CoreHealthy(status)
if runningErr != nil || healthyErr != nil {
coreRunning = false
coreHealthy = false
}
}
if !configReady || !coreRunning {
add("authentication", StatusSkipped, "core is unavailable")
} else if !coreHealthy {
add("authentication", StatusFailed, "core is running but unhealthy")
} else if authenticationCheck(ctx, installation, runner, secretValues) {
add("authentication", StatusPassed, "container-local authentication diagnostics passed")
} else {
add("authentication", StatusFailed, "container-local authentication diagnostics failed")
}
add(servicesCheck.Name, servicesCheck.Status, servicesCheck.Detail)
if !coreRunning {
add("core-http", StatusSkipped, "core is not running")
add("frontend-http", StatusSkipped, "core is not running")
add("workspace-registry", StatusSkipped, "core is not running")
add("workflow", StatusSkipped, "core is not running")
add("pi", StatusSkipped, "core is not running")
if !coreHealthy || servicesCheck.Status != StatusPassed {
detail := "required services are not healthy"
if !coreRunning {
detail = "core is not running"
}
add("core-http", StatusSkipped, detail)
add("frontend-http", StatusSkipped, detail)
add("workspace-registry", StatusSkipped, detail)
add("workflow", StatusSkipped, detail)
add("pi", StatusSkipped, detail)
return finalize(report), nil
}
+62
View File
@@ -60,6 +60,43 @@ func TestRunSkipsContainerDiagnosticsWhenCoreIsStopped(t *testing.T) {
}
}
func TestRunFailsAuthenticationWithoutExecWhenCoreIsRunningButUnhealthy(t *testing.T) {
installation := doctorInstallation(t, "")
runner := &doctorRunner{services: unhealthyCoreServices}
report, err := Run(context.Background(), installation, runner)
if err != nil {
t.Fatal(err)
}
if report.OK || checkStatus(report, "authentication") != StatusFailed {
t.Fatalf("Run() report = %#v, want deterministic failed authentication", report)
}
assertChecklist(t, report, []string{"descriptor", "files", "docker", "compose", "configuration", "authentication", "services", "core-http", "frontend-http", "workspace-registry", "workflow", "pi"})
if strings.Contains(strings.Join(runner.calls, "\n"), " exec -T ") {
t.Fatalf("Run() invoked exec -T while core was unhealthy: %v", runner.calls)
}
if detail := checkDetail(report, "authentication"); detail != "core is running but unhealthy" {
t.Fatalf("authentication detail = %q, want deterministic unhealthy detail", detail)
}
}
func TestRunExecutesOnlyAuthenticationWhenCoreIsHealthyButAnotherServiceIsUnhealthy(t *testing.T) {
installation := doctorInstallation(t, "")
runner := &doctorRunner{services: unhealthyFrontendServices}
report, err := Run(context.Background(), installation, runner)
if err != nil {
t.Fatal(err)
}
if checkStatus(report, "authentication") != StatusPassed || checkStatus(report, "services") != StatusFailed {
t.Fatalf("Run() report = %#v, want auth passed before failed services", report)
}
calls := strings.Join(runner.calls, "\n")
if strings.Count(calls, " exec -T ") != 1 || !strings.Contains(calls, "exec -T core node dist/auth/diagnostic-command.js --json") {
t.Fatalf("Run() calls = %s, want only the healthy-core authentication exec", calls)
}
}
// Catches host-Python diagnostics or omission of workflow/Pi checks once core is healthy.
func TestRunUsesOnlyContainerLocalWorkflowAndPiDiagnosticsWhenCoreRuns(t *testing.T) {
installation := doctorInstallation(t, "")
@@ -240,6 +277,15 @@ func checkStatus(report Report, name string) string {
return ""
}
func checkDetail(report Report, name string) string {
for _, check := range report.Checks {
if check.Name == name {
return check.Detail
}
}
return ""
}
func reportText(report Report) string {
parts := make([]string, 0, len(report.Checks))
for _, check := range report.Checks {
@@ -273,3 +319,19 @@ const stoppedServices = `[
{"Service":"core","State":"exited","Health":""},
{"Service":"frontend","State":"running","Health":"healthy"}
]`
const unhealthyCoreServices = `[
{"Service":"core","State":"running","Health":"unhealthy"},
{"Service":"frontend","State":"running","Health":"healthy"},
{"Service":"qdrant","State":"running","Health":"healthy"},
{"Service":"embedding","State":"running","Health":"healthy"},
{"Service":"embedding-model-init","State":"exited","ExitCode":0}
]`
const unhealthyFrontendServices = `[
{"Service":"core","State":"running","Health":"healthy"},
{"Service":"frontend","State":"running","Health":"unhealthy"},
{"Service":"qdrant","State":"running","Health":"healthy"},
{"Service":"embedding","State":"running","Health":"healthy"},
{"Service":"embedding-model-init","State":"exited","ExitCode":0}
]`