package main import ( "errors" "testing" "time" "git.piksar.eu/piotr/groundstation/internal/display" ) type recordingCanvas struct { width, height int lines []string clears, flushes int } func (c *recordingCanvas) Size() (int, int) { return c.width, c.height } func (c *recordingCanvas) Clear() { c.clears++ } func (c *recordingCanvas) Text(_, _ int, message string) { c.lines = append(c.lines, message) } func (c *recordingCanvas) Flush() { c.flushes++ } func TestBuildTargetBuildsIndependentVitureLayers(t *testing.T) { layers, err := buildTarget("x11") if err != nil { t.Fatal(err) } if len(layers) != 2 { t.Fatalf("layers=%d want the fallback canvas and the OSD overlay", len(layers)) } canvas, osd := layers[0], layers[1] if canvas.Name != "fallback-canvas" || osd.Name != "osd-overlay" { t.Fatalf("layer names %q/%q want fallback-canvas/osd-overlay", canvas.Name, osd.Name) } canvasOpener, ok := canvas.Opener.(display.X11Opener) if !ok { t.Fatalf("canvas opener %T must be the X11 target", canvas.Opener) } if canvasOpener.Role != display.RoleBelow { t.Fatalf("canvas layer role %v must stay below video", canvasOpener.Role) } osdOpener, ok := osd.Opener.(display.X11Opener) if !ok { t.Fatalf("OSD opener %T must be the X11 target", osd.Opener) } if osdOpener.Role != display.RoleAbove { t.Fatalf("OSD layer role %v must stay above video", osdOpener.Role) } // Both layers must share one presence signal so the video lifecycle // observed by either session drives both templates. if canvasOpener.Video == nil || osdOpener.Video == nil || canvasOpener.Video != osdOpener.Video { t.Fatal("layers must share one video presence signal") } // The canvas layer keeps the target-specific fallback template with the // exact fallback text. canvasSurface := &recordingCanvas{width: 800, height: 600} canvas.Template.Draw(canvasSurface) if len(canvasSurface.lines) != 1 || canvasSurface.lines[0] != "Brak połączenia WFB" { t.Fatalf("canvas lines=%q want the exact fallback text", canvasSurface.lines) } // The OSD layer is the OSD surface, never the fallback. osdSurface := &recordingCanvas{width: 800, height: 600} osd.Template.Draw(osdSurface) if len(osdSurface.lines) != 0 { t.Fatalf("OSD lines=%q want none: the overlay must not duplicate the fallback", osdSurface.lines) } // Video presence hides the fallback on the canvas layer only. canvasOpener.Video.SetActive(true) canvasSurface.lines = nil canvas.Template.Draw(canvasSurface) if len(canvasSurface.lines) != 0 { t.Fatalf("canvas lines=%q must disappear while video is present", canvasSurface.lines) } canvasOpener.Video.SetActive(false) } func TestBuildTargetRejectsUnknownTarget(t *testing.T) { if _, err := buildTarget("hdmi-mirror"); err == nil { t.Fatal("unknown target must fail") } } func TestFormatDiagnosticRendersStructuredFields(t *testing.T) { got := formatDiagnostic(display.Diagnostic{ Target: "x11", Layer: "fallback-canvas", Event: display.EventOpenFailed, Err: errors.New("connect X11: refused"), RetryDelay: 500 * time.Millisecond, }) want := `target=x11 layer=fallback-canvas event=open_failed error="connect X11: refused" retry_delay=500ms` if got != want { t.Fatalf("formatDiagnostic=%q want %q", got, want) } } func TestWireDiagnosticsTagsEveryLayerWithItsName(t *testing.T) { layers, err := buildTarget("x11") if err != nil { t.Fatal(err) } wireDiagnostics("x11", layers) for _, layer := range layers { if layer.Options.Target != "x11" { t.Fatalf("layer %q target=%q want x11", layer.Name, layer.Options.Target) } if layer.Options.Layer != layer.Name { t.Fatalf("layer %q diagnostic layer=%q", layer.Name, layer.Options.Layer) } if layer.Options.Diagnostic == nil { t.Fatalf("layer %q must carry the reconnect diagnostic hook", layer.Name) } } // The shared hook must be safe to call from any layer goroutine. layers[0].Options.Diagnostic(display.Diagnostic{Target: "x11", Layer: layers[0].Name}) }