1package main
2
3import (
4 "errors"
5 "strings"
6 "testing"
7
8 "github.com/bnema/vev/internal/ports"
9)
10
11func TestBoundedStderrRetainsAtMostDiagnosticLimit(t *testing.T) {
12 stderr := &boundedStderr{}
13 input := strings.Repeat("x", commandStderrLimit+1)
14
15 written, err := stderr.Write([]byte(input))
16
17 if err != nil {
18 t.Fatal(err)
19 }
20 if written != len(input) {
21 t.Fatalf("written = %d, want %d", written, len(input))
22 }
23 if stderr.Len() != commandStderrLimit {
24 t.Fatalf("stderr length = %d, want %d", stderr.Len(), commandStderrLimit)
25 }
26 if !strings.Contains(stderr.String(), "[stderr truncated]") {
27 t.Fatalf("stderr = %q, want truncation marker", stderr.String())
28 }
29}
30
31func TestCommandErrorWithStderr(t *testing.T) {
32 cause := errors.New("command failed")
33 if got := commandErrorWithStderr(cause, " daemon could not start\n"); !errors.Is(got, cause) || !strings.Contains(got.Error(), "stderr: daemon could not start") {
34 t.Fatalf("command error = %v", got)
35 }
36 if got := commandErrorWithStderr(cause, "\n"); got != cause {
37 t.Fatalf("empty stderr error = %v, want original error", got)
38 }
39}
40
41func TestRunCapturedCommandIncludesStderr(t *testing.T) {
42 err := runCapturedCommand(t.Context(), "sh", "-c", "printf 'command diagnostics\\n' >&2; exit 1")
43 if err == nil || !strings.Contains(err.Error(), "stderr: command diagnostics") {
44 t.Fatalf("command error = %v", err)
45 }
46}
47
48func TestAssertNoDirectHandoffProcessesInitialFramesAndRetainsOutput(t *testing.T) {
49 tr := &harnessTransport{
50 probe: &visualProbe{},
51 frames: make(chan harnessFrame, 2),
52 }
53 tr.frames <- harnessFrame{frame: ports.Frame{Type: ports.MsgOutput}}
54 tr.frames <- harnessFrame{frame: ports.Frame{Type: ports.MsgAttachTarget}}
55
56 if err := assertNoDirectHandoff(tr); err == nil {
57 t.Fatal("direct handoff was not rejected")
58 }
59 if len(tr.queued) != 1 || tr.queued[0].frame.Type != ports.MsgOutput {
60 t.Fatalf("queued frames = %#v, want one retained output", tr.queued)
61 }
62 if tr.probe.unexpectedHandoffs != 1 {
63 t.Fatalf("unexpected handoffs = %d, want 1", tr.probe.unexpectedHandoffs)
64 }
65}