detached 5f9aee7

test(runtime): keep the Xvfb displayfd read end open until cleanup

Closing it right after the first read made Xvfb's later displayfd write fail on a server reset ('Cannot write display number to fd 3'), killing the server under load. Reproduced on ubuntu:26.04 Xvfb 21.1.22 with CPU contention: 8/200 failures before, 0/200 after.
commit
5f9aee7852c50d4df9eaddf46f0ffa36d8527d47
author
brice · · 2026-10-22 09:35 UTC
parent
f2df270
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
checks
4/4
2 files · +6 -2
M conn_xserver_test.go +3 -1
@@ -31,7 +31,9 @@ func startXvfb(t *testing.T, authFile string) string {
3131 if err != nil {
3232 t.Fatal(err)
3333 }
34- defer r.Close()
34+ // Xvfb may write to -displayfd again (e.g. after a server reset); closing
35+ // the read end early makes that write fail and kills the server.
36+ t.Cleanup(func() { _ = r.Close() })
3537 cmd := exec.Command("Xvfb", "-displayfd", "3", "-screen", "0", "800x600x24", "-nolisten", "tcp", "-auth", authFile)
3638 cmd.ExtraFiles = []*os.File{w}
3739 var log bytes.Buffer
@@ -31,7 +31,9 @@ func startXvfb(t *testing.T, authFile string) string {
31 if err != nil {31 if err != nil {
32 t.Fatal(err)32 t.Fatal(err)
33 }33 }
34- defer r.Close()34+ // Xvfb may write to -displayfd again (e.g. after a server reset); closing
35+ // the read end early makes that write fail and kills the server.
36+ t.Cleanup(func() { _ = r.Close() })
35 cmd := exec.Command("Xvfb", "-displayfd", "3", "-screen", "0", "800x600x24", "-nolisten", "tcp", "-auth", authFile)37 cmd := exec.Command("Xvfb", "-displayfd", "3", "-screen", "0", "800x600x24", "-nolisten", "tcp", "-auth", authFile)
36 cmd.ExtraFiles = []*os.File{w}38 cmd.ExtraFiles = []*os.File{w}
37 var log bytes.Buffer39 var log bytes.Buffer
M internal/xtest/capture_test.go +3 -1
@@ -101,7 +101,9 @@ func TestCaptureRequests(t *testing.T) {
101101 if err != nil {
102102 t.Fatal(err)
103103 }
104- defer r.Close()
104+ // Xvfb writes to displayfd again after a server reset; keep the read end
105+ // open until the test ends so that write cannot kill the server.
106+ t.Cleanup(func() { _ = r.Close() })
105107 cmd := exec.Command("Xvfb", xvfbArgs()...)
106108 cmd.ExtraFiles = []*os.File{w}
107109 var log bytes.Buffer
@@ -101,7 +101,9 @@ func TestCaptureRequests(t *testing.T) {
101 if err != nil {101 if err != nil {
102 t.Fatal(err)102 t.Fatal(err)
103 }103 }
104- defer r.Close()104+ // Xvfb writes to displayfd again after a server reset; keep the read end
105+ // open until the test ends so that write cannot kill the server.
106+ t.Cleanup(func() { _ = r.Close() })
105 cmd := exec.Command("Xvfb", xvfbArgs()...)107 cmd := exec.Command("Xvfb", xvfbArgs()...)
106 cmd.ExtraFiles = []*os.File{w}108 cmd.ExtraFiles = []*os.File{w}
107 var log bytes.Buffer109 var log bytes.Buffer

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 1

Tags 1

↑↓ moveenter openesc close