-
Notifications
You must be signed in to change notification settings - Fork 111
Expand file tree
/
Copy pathpty_socket_test.go
More file actions
105 lines (95 loc) · 5.06 KB
/
Copy pathpty_socket_test.go
File metadata and controls
105 lines (95 loc) · 5.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
//go:build !windows
// +build !windows
package tmux
import (
"context"
"reflect"
"testing"
)
// These tests guard the #687 follow-up socket-isolation-at-attach fix
// (v1.7.55). They assert that every command assembly path in pty.go reads
// Session.SocketName via the factory, not via raw exec.Command. A regression
// here is exactly the bug @jcordasco found in v1.7.50: the CLI wrote the
// session's socket name to SQLite, the lifecycle paths honored it on
// start/stop, but Attach / AttachReadOnly / Resize / AttachWindow /
// StreamOutput still built their tmux argv by hand and connected to the
// user's default server — silently defeating the whole feature.
// TestSession_AttachCmd_WithSocket_PrependsDashL: the headline regression.
// Before v1.7.55, pty.go:142 used exec.CommandContext(ctx, "tmux",
// "attach-session", "-t", s.Name) and produced argv[1]="attach-session"
// when a socket was configured. This test fails until the command is built
// via s.tmuxCmdContext, which inserts -L <socket> before the subcommand.
func TestSession_AttachCmd_WithSocket_PrependsDashL(t *testing.T) {
s := &Session{Name: "agentdeck_iso_abc", SocketName: "agentdeck"}
cmd := s.attachCmd(context.Background())
wantArgs := []string{"tmux", "-L", "agentdeck", "-u", "attach-session", "-t", s.Name}
if !reflect.DeepEqual(cmd.Args, wantArgs) {
t.Fatalf("attach must route through tmuxCmdContext so -L lands before subcommand\n got: %v\n want: %v", cmd.Args, wantArgs)
}
}
// TestSession_AttachCmd_EmptySocket_NoDashL: opt-in contract. No config means
// no -L; the required UTF-8 flag is independent of socket isolation.
func TestSession_AttachCmd_EmptySocket_NoDashL(t *testing.T) {
s := &Session{Name: "agentdeck_default_abc"}
cmd := s.attachCmd(context.Background())
wantArgs := []string{"tmux", "-u", "attach-session", "-t", s.Name}
if !reflect.DeepEqual(cmd.Args, wantArgs) {
t.Fatalf("empty SocketName must produce attach argv without -L\n got: %v\n want: %v", cmd.Args, wantArgs)
}
}
// TestSession_AttachReadOnlyCmd_WithSocket_PrependsDashL: read-only attach
// was the SECOND bypass in pty.go (AttachReadOnly, pre-fix line 406). Web
// terminal handler + scripted inspect calls use it — same isolation failure
// mode as interactive attach.
func TestSession_AttachReadOnlyCmd_WithSocket_PrependsDashL(t *testing.T) {
s := &Session{Name: "agentdeck_ro_abc", SocketName: "agentdeck"}
cmd := s.attachReadOnlyCmd(context.Background())
wantArgs := []string{"tmux", "-L", "agentdeck", "-u", "attach-session", "-r", "-t", s.Name}
if !reflect.DeepEqual(cmd.Args, wantArgs) {
t.Fatalf("read-only attach must include -L <socket>\n got: %v\n want: %v", cmd.Args, wantArgs)
}
}
// TestSession_ResizeCmd_WithSocket_PrependsDashL: Resize() called resize-window
// without -L. With isolation on, the user's default server either had no
// such session (silent no-op) or had a stale one (resized the wrong pane).
func TestSession_ResizeCmd_WithSocket_PrependsDashL(t *testing.T) {
s := &Session{Name: "agentdeck_rsz_abc", SocketName: "agentdeck"}
cmd := s.resizeCmd(80, 24)
wantArgs := []string{"tmux", "-L", "agentdeck", "resize-window", "-t", s.Name, "-x", "80", "-y", "24"}
if !reflect.DeepEqual(cmd.Args, wantArgs) {
t.Fatalf("resize must carry -L <socket>\n got: %v\n want: %v", cmd.Args, wantArgs)
}
}
// TestSession_AttachWindowSelectCmd_WithSocket_PrependsDashL: AttachWindow's
// pre-attach select-window step used its own raw exec.Command — so selecting
// window 2 of an isolated session silently targeted a default-server session
// with the same name (or failed).
func TestSession_AttachWindowSelectCmd_WithSocket_PrependsDashL(t *testing.T) {
s := &Session{Name: "agentdeck_win_abc", SocketName: "agentdeck"}
cmd := s.selectWindowCmd(2)
wantArgs := []string{"tmux", "-L", "agentdeck", "select-window", "-t", "agentdeck_win_abc:2"}
if !reflect.DeepEqual(cmd.Args, wantArgs) {
t.Fatalf("select-window must carry -L <socket>\n got: %v\n want: %v", cmd.Args, wantArgs)
}
}
// TestSession_StreamOutputCmd_WithSocket_PrependsDashL: StreamOutput's
// pipe-pane start ran on the wrong server when isolation was on, causing
// the caller to receive no bytes at all.
func TestSession_StreamOutputCmd_WithSocket_PrependsDashL(t *testing.T) {
s := &Session{Name: "agentdeck_stream_abc", SocketName: "agentdeck"}
cmd := s.pipePaneStartCmd(context.Background())
wantArgs := []string{"tmux", "-L", "agentdeck", "pipe-pane", "-t", s.Name, "-o", "cat"}
if !reflect.DeepEqual(cmd.Args, wantArgs) {
t.Fatalf("pipe-pane start must carry -L <socket>\n got: %v\n want: %v", cmd.Args, wantArgs)
}
}
// TestSession_StreamOutputStopCmd_WithSocket_PrependsDashL: and the symmetric
// pipe-pane stop that runs during context cancellation.
func TestSession_StreamOutputStopCmd_WithSocket_PrependsDashL(t *testing.T) {
s := &Session{Name: "agentdeck_stream_abc", SocketName: "agentdeck"}
cmd := s.pipePaneStopCmd()
wantArgs := []string{"tmux", "-L", "agentdeck", "pipe-pane", "-t", s.Name}
if !reflect.DeepEqual(cmd.Args, wantArgs) {
t.Fatalf("pipe-pane stop must carry -L <socket>\n got: %v\n want: %v", cmd.Args, wantArgs)
}
}