detached f569d8b

test(darwin): stabilize macos CI paths and prewarm

commit
f569d8b7f056a5834a43ec454aef47ea9046c0bb
author
brice · · 2026-07-16 18:58 UTC
parent
27e6e25
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
4 files · +52 -10
M internal/adapters/ipc/dial_test.go +2 -3
@@ -3,7 +3,6 @@ package ipc
33 import (
44 "context"
55 "errors"
6- "path/filepath"
76 "testing"
87 "time"
98
@@ -43,7 +42,7 @@ func TestDialContextCanceledOrExpired(t *testing.T) {
4342 ctx, cancel := tt.ctx()
4443 defer cancel()
4544
46- transport, err := DialContext(ctx, t.TempDir())
45+ transport, err := DialContext(ctx, shortSocketDir(t))
4746 if transport != nil {
4847 t.Fatal("DialContext returned a transport for a completed context")
4948 }
@@ -55,7 +54,7 @@ func TestDialContextCanceledOrExpired(t *testing.T) {
5554 }
5655
5756 func TestDialContextPreservesOptions(t *testing.T) {
58- dir := filepath.Join(t.TempDir(), "vev")
57+ dir := shortSocketDir(t, "vev")
5958 listener, err := Listen(dir)
6059 if err != nil {
6160 t.Fatalf("Listen: %v", err)
@@ -3,7 +3,6 @@ package ipc
3 import (3 import (
4 "context"4 "context"
5 "errors"5 "errors"
6- "path/filepath"
7 "testing"6 "testing"
8 "time"7 "time"
9 8
@@ -43,7 +42,7 @@ func TestDialContextCanceledOrExpired(t *testing.T) {
43 ctx, cancel := tt.ctx()42 ctx, cancel := tt.ctx()
44 defer cancel()43 defer cancel()
45 44
46- transport, err := DialContext(ctx, t.TempDir())45+ transport, err := DialContext(ctx, shortSocketDir(t))
47 if transport != nil {46 if transport != nil {
48 t.Fatal("DialContext returned a transport for a completed context")47 t.Fatal("DialContext returned a transport for a completed context")
49 }48 }
@@ -55,7 +54,7 @@ func TestDialContextCanceledOrExpired(t *testing.T) {
55 }54 }
56 55
57 func TestDialContextPreservesOptions(t *testing.T) {56 func TestDialContextPreservesOptions(t *testing.T) {
58- dir := filepath.Join(t.TempDir(), "vev")57+ dir := shortSocketDir(t, "vev")
59 listener, err := Listen(dir)58 listener, err := Listen(dir)
60 if err != nil {59 if err != nil {
61 t.Fatalf("Listen: %v", err)60 t.Fatalf("Listen: %v", err)
M internal/adapters/ipc/listener_test.go +5 -6
@@ -13,7 +13,7 @@ import (
1313 )
1414
1515 func TestListenAcceptRoundTrip(t *testing.T) {
16- dir := filepath.Join(t.TempDir(), "vev")
16+ dir := shortSocketDir(t, "vev")
1717
1818 ln, err := Listen(dir)
1919 if err != nil {
@@ -65,8 +65,7 @@ func TestListenAcceptRoundTrip(t *testing.T) {
6565 }
6666
6767 func TestListenMkdirsSocketDir(t *testing.T) {
68- base := t.TempDir()
69- dir := filepath.Join(base, "nested", "socketdir")
68+ dir := shortSocketDir(t, "nested", "socketdir")
7069
7170 ln, err := Listen(dir)
7271 if err != nil {
@@ -87,7 +86,7 @@ func TestListenMkdirsSocketDir(t *testing.T) {
8786 }
8887
8988 func TestListenRejectsHostileSocketDir(t *testing.T) {
90- dir := filepath.Join(t.TempDir(), "socketdir")
89+ dir := shortSocketDir(t, "socketdir")
9190 if err := os.MkdirAll(dir, 0o777); err != nil {
9291 t.Fatalf("mkdir hostile socket dir: %v", err)
9392 }
@@ -106,7 +105,7 @@ func TestListenRejectsHostileSocketDir(t *testing.T) {
106105 }
107106
108107 func TestListenStaleSocketCleanedUp(t *testing.T) {
109- dir := filepath.Join(t.TempDir(), "vev")
108+ dir := shortSocketDir(t, "vev")
110109 if err := os.Mkdir(dir, 0o700); err != nil {
111110 t.Fatalf("mkdir safe socket dir: %v", err)
112111 }
@@ -140,7 +139,7 @@ func TestListenStaleSocketCleanedUp(t *testing.T) {
140139 }
141140
142141 func TestListenLiveDaemonRejected(t *testing.T) {
143- dir := filepath.Join(t.TempDir(), "vev")
142+ dir := shortSocketDir(t, "vev")
144143
145144 first, err := Listen(dir)
146145 if err != nil {
@@ -13,7 +13,7 @@ import (
13 )13 )
14 14
15 func TestListenAcceptRoundTrip(t *testing.T) {15 func TestListenAcceptRoundTrip(t *testing.T) {
16- dir := filepath.Join(t.TempDir(), "vev")16+ dir := shortSocketDir(t, "vev")
17 17
18 ln, err := Listen(dir)18 ln, err := Listen(dir)
19 if err != nil {19 if err != nil {
@@ -65,8 +65,7 @@ func TestListenAcceptRoundTrip(t *testing.T) {
65 }65 }
66 66
67 func TestListenMkdirsSocketDir(t *testing.T) {67 func TestListenMkdirsSocketDir(t *testing.T) {
68- base := t.TempDir()68+ dir := shortSocketDir(t, "nested", "socketdir")
69- dir := filepath.Join(base, "nested", "socketdir")
70 69
71 ln, err := Listen(dir)70 ln, err := Listen(dir)
72 if err != nil {71 if err != nil {
@@ -87,7 +86,7 @@ func TestListenMkdirsSocketDir(t *testing.T) {
87 }86 }
88 87
89 func TestListenRejectsHostileSocketDir(t *testing.T) {88 func TestListenRejectsHostileSocketDir(t *testing.T) {
90- dir := filepath.Join(t.TempDir(), "socketdir")89+ dir := shortSocketDir(t, "socketdir")
91 if err := os.MkdirAll(dir, 0o777); err != nil {90 if err := os.MkdirAll(dir, 0o777); err != nil {
92 t.Fatalf("mkdir hostile socket dir: %v", err)91 t.Fatalf("mkdir hostile socket dir: %v", err)
93 }92 }
@@ -106,7 +105,7 @@ func TestListenRejectsHostileSocketDir(t *testing.T) {
106 }105 }
107 106
108 func TestListenStaleSocketCleanedUp(t *testing.T) {107 func TestListenStaleSocketCleanedUp(t *testing.T) {
109- dir := filepath.Join(t.TempDir(), "vev")108+ dir := shortSocketDir(t, "vev")
110 if err := os.Mkdir(dir, 0o700); err != nil {109 if err := os.Mkdir(dir, 0o700); err != nil {
111 t.Fatalf("mkdir safe socket dir: %v", err)110 t.Fatalf("mkdir safe socket dir: %v", err)
112 }111 }
@@ -140,7 +139,7 @@ func TestListenStaleSocketCleanedUp(t *testing.T) {
140 }139 }
141 140
142 func TestListenLiveDaemonRejected(t *testing.T) {141 func TestListenLiveDaemonRejected(t *testing.T) {
143- dir := filepath.Join(t.TempDir(), "vev")142+ dir := shortSocketDir(t, "vev")
144 143
145 first, err := Listen(dir)144 first, err := Listen(dir)
146 if err != nil {145 if err != nil {
A internal/adapters/ipc/test_helpers_test.go +35 -0
@@ -0,0 +1,35 @@
1+package ipc
2+
3+import (
4+ "os"
5+ "path/filepath"
6+ "testing"
7+)
8+
9+const darwinUnixSocketPathMax = 103
10+
11+func shortSocketDir(t *testing.T, nested ...string) string {
12+ t.Helper()
13+
14+ root, err := os.MkdirTemp("/tmp", "v")
15+ if err != nil {
16+ t.Fatalf("create short socket test root: %v", err)
17+ }
18+ t.Cleanup(func() {
19+ if err := os.RemoveAll(root); err != nil {
20+ t.Errorf("remove short socket test root %q: %v", root, err)
21+ }
22+ })
23+
24+ dir := filepath.Join(append([]string{root}, nested...)...)
25+ assertDarwinSafeSocketPath(t, filepath.Join(dir, "daemon.sock"))
26+ return dir
27+}
28+
29+func assertDarwinSafeSocketPath(t *testing.T, path string) {
30+ t.Helper()
31+
32+ if len(path) >= darwinUnixSocketPathMax {
33+ t.Fatalf("test socket path %q is %d bytes; must be shorter than Darwin's %d-byte AF_UNIX pathname maximum", path, len(path), darwinUnixSocketPathMax)
34+ }
35+}
@@ -0,0 +1,35 @@
1+package ipc
2+
3+import (
4+ "os"
5+ "path/filepath"
6+ "testing"
7+)
8+
9+const darwinUnixSocketPathMax = 103
10+
11+func shortSocketDir(t *testing.T, nested ...string) string {
12+ t.Helper()
13+
14+ root, err := os.MkdirTemp("/tmp", "v")
15+ if err != nil {
16+ t.Fatalf("create short socket test root: %v", err)
17+ }
18+ t.Cleanup(func() {
19+ if err := os.RemoveAll(root); err != nil {
20+ t.Errorf("remove short socket test root %q: %v", root, err)
21+ }
22+ })
23+
24+ dir := filepath.Join(append([]string{root}, nested...)...)
25+ assertDarwinSafeSocketPath(t, filepath.Join(dir, "daemon.sock"))
26+ return dir
27+}
28+
29+func assertDarwinSafeSocketPath(t *testing.T, path string) {
30+ t.Helper()
31+
32+ if len(path) >= darwinUnixSocketPathMax {
33+ t.Fatalf("test socket path %q is %d bytes; must be shorter than Darwin's %d-byte AF_UNIX pathname maximum", path, len(path), darwinUnixSocketPathMax)
34+ }
35+}
M internal/usecase/daemon/picker_test.go +10 -1
@@ -857,9 +857,13 @@ func TestResumeStoppedAndSwitchInheritsTerminalEnv(t *testing.T) {
857857 },
858858 ).Twice()
859859 floating := newQuietPTY()
860+ floatingOpened := make(chan struct{})
860861 f.EXPECT().Open(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.MatchedBy(func(got domain.Size) bool {
861862 return got != normalSize && got.Valid()
862- })).Return(floating, nil).Once()
863+ })).RunAndReturn(func(context.Context, string, []string, []string, string, domain.Size) (ports.PTY, error) {
864+ close(floatingOpened)
865+ return floating, nil
866+ }).Once()
863867 d := newTestDaemon(t, f, stubClock{})
864868 d.stopped["old"] = stoppedSession{name: "old", cwd: t.TempDir(), createdAt: 1}
865869 tr := portsmocks.NewMockTransport(t)
@@ -877,6 +881,11 @@ func TestResumeStoppedAndSwitchInheritsTerminalEnv(t *testing.T) {
877881 require.Contains(t, opens[1], "TERM=xterm-direct")
878882 require.Contains(t, opens[1], "COLORTERM=truecolor")
879883 require.Contains(t, opens[1], "TERM_PROGRAM=vev")
884+ select {
885+ case <-floatingOpened:
886+ case <-time.After(time.Second):
887+ t.Fatal("floating prewarm PTY was not opened")
888+ }
880889 _ = d.killSession(got, ports.ReasonSessionKilled, false)
881890 release1()
882891 release2()
@@ -857,9 +857,13 @@ func TestResumeStoppedAndSwitchInheritsTerminalEnv(t *testing.T) {
857 },857 },
858 ).Twice()858 ).Twice()
859 floating := newQuietPTY()859 floating := newQuietPTY()
860+ floatingOpened := make(chan struct{})
860 f.EXPECT().Open(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.MatchedBy(func(got domain.Size) bool {861 f.EXPECT().Open(mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.MatchedBy(func(got domain.Size) bool {
861 return got != normalSize && got.Valid()862 return got != normalSize && got.Valid()
862- })).Return(floating, nil).Once()863+ })).RunAndReturn(func(context.Context, string, []string, []string, string, domain.Size) (ports.PTY, error) {
864+ close(floatingOpened)
865+ return floating, nil
866+ }).Once()
863 d := newTestDaemon(t, f, stubClock{})867 d := newTestDaemon(t, f, stubClock{})
864 d.stopped["old"] = stoppedSession{name: "old", cwd: t.TempDir(), createdAt: 1}868 d.stopped["old"] = stoppedSession{name: "old", cwd: t.TempDir(), createdAt: 1}
865 tr := portsmocks.NewMockTransport(t)869 tr := portsmocks.NewMockTransport(t)
@@ -877,6 +881,11 @@ func TestResumeStoppedAndSwitchInheritsTerminalEnv(t *testing.T) {
877 require.Contains(t, opens[1], "TERM=xterm-direct")881 require.Contains(t, opens[1], "TERM=xterm-direct")
878 require.Contains(t, opens[1], "COLORTERM=truecolor")882 require.Contains(t, opens[1], "COLORTERM=truecolor")
879 require.Contains(t, opens[1], "TERM_PROGRAM=vev")883 require.Contains(t, opens[1], "TERM_PROGRAM=vev")
884+ select {
885+ case <-floatingOpened:
886+ case <-time.After(time.Second):
887+ t.Fatal("floating prewarm PTY was not opened")
888+ }
880 _ = d.killSession(got, ports.ReasonSessionKilled, false)889 _ = d.killSession(got, ports.ReasonSessionKilled, false)
881 release1()890 release1()
882 release2()891 release2()

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 12

Tags 11

↑↓ moveenter openesc close