Host detail v2: full pipeline + per-stage logs + WoL diagnostics
CI / Lint + build + test (push) Has been cancelled
CI / Lint + build + test (push) Has been cancelled
Pipeline now always renders all 13 nodes (3 pre-stage + 9 stage +
Completed), synthesising ghosts from run state when stage rows
aren't seeded yet. Makes a WaitingWoL host show the full timeline
ahead of it instead of just 4 dots.
Agent tags each log line with its stage; logs.Hub fans out to both
log-{runID} and log-{runID}-{stage} SSE events so the detail page
can show per-stage tabs with a pure-CSS radio-sibling switch. Flat
run log prepends [stage] so grep still works.
Dispatcher writes picked/sent-WoL/heartbeat lines into the per-run
log — the operator opens the detail page, sees WaitingWoL stuck,
and reads exactly what the dispatcher did and why nothing's
progressing, instead of having to tail journalctl on the LXC.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
package orchestrator
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"vetting/internal/events"
|
||||
"vetting/internal/logs"
|
||||
)
|
||||
|
||||
// TestDispatcher_RunLogWritesToHub verifies the plumbing between the
|
||||
// dispatcher and the per-run log hub: runLog must persist to the on-disk
|
||||
// file so the detail page's replay + SSE fan-out see the same
|
||||
// pre-stage diagnostics (picked / sent WoL / heartbeat).
|
||||
func TestDispatcher_RunLogWritesToHub(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
ev := events.NewHub()
|
||||
lh, err := logs.NewHub(dir, ev)
|
||||
if err != nil {
|
||||
t.Fatalf("NewHub: %v", err)
|
||||
}
|
||||
defer lh.Close()
|
||||
|
||||
d := &Dispatcher{Logs: lh}
|
||||
d.runLog(7, "info", "dispatcher: sent WoL packet to aa:bb:cc:dd:ee:ff via 10.0.0.255:9")
|
||||
|
||||
body, err := os.ReadFile(filepath.Join(dir, "run-7.log"))
|
||||
if err != nil {
|
||||
t.Fatalf("read run log: %v", err)
|
||||
}
|
||||
if !strings.Contains(string(body), "dispatcher: sent WoL packet") {
|
||||
t.Fatalf("run log missing dispatcher line: %q", body)
|
||||
}
|
||||
if !strings.Contains(string(body), "INFO") {
|
||||
t.Fatalf("run log missing level: %q", body)
|
||||
}
|
||||
}
|
||||
|
||||
// TestDispatcher_RunLogNilHubDoesNotPanic: tests construct Dispatcher
|
||||
// directly without a hub. runLog must degrade to stderr rather than
|
||||
// panicking so the dispatcher loop stays alive.
|
||||
func TestDispatcher_RunLogNilHubDoesNotPanic(t *testing.T) {
|
||||
d := &Dispatcher{}
|
||||
d.runLog(1, "info", "fallback path")
|
||||
}
|
||||
Reference in New Issue
Block a user