on main help sign in
fix(backend): fix data race in tests using captureDebugLogs
a1e4a7cChristian Rocha
internal/backend/backend_test.go+23−4
@@ -642,17 +642,36 @@ func protoWS(path, dataDir, clientID string) proto.Workspace {
642 return proto.Workspace{Path: path, DataDir: dataDir, ClientID: clientID}
642 return proto.Workspace{Path: path, DataDir: dataDir, ClientID: clientID}
643}
643}
644
644
645+// syncBuffer is a thread-safe buffer that can be safely read and written
646+// from multiple goroutines.
647+type syncBuffer struct {
648+ mu sync.Mutex
649+ buf bytes.Buffer
650+}
651+
652+func (sb *syncBuffer) Write(p []byte) (n int, err error) {
653+ sb.mu.Lock()
654+ defer sb.mu.Unlock()
655+ return sb.buf.Write(p)
656+}
657+
658+func (sb *syncBuffer) String() string {
659+ sb.mu.Lock()
660+ defer sb.mu.Unlock()
661+ return sb.buf.String()
662+}
663+
645// captureDebugLogs installs a buffer-backed slog handler at Debug
664// captureDebugLogs installs a buffer-backed slog handler at Debug
646// level for the duration of the test, returning the buffer. The
665// level for the duration of the test, returning the buffer. The
647// previous default handler is restored via t.Cleanup.
666// previous default handler is restored via t.Cleanup.
648−func captureDebugLogs(t *testing.T) *bytes.Buffer {
667+func captureDebugLogs(t *testing.T) *syncBuffer {
649 t.Helper()
668 t.Helper()
650− var buf bytes.Buffer
669+ var sb syncBuffer
651 prev := slog.Default()
670 prev := slog.Default()
652− handler := slog.NewTextHandler(&buf, &slog.HandlerOptions{Level: slog.LevelDebug})
671+ handler := slog.NewTextHandler(&sb, &slog.HandlerOptions{Level: slog.LevelDebug})
653 slog.SetDefault(slog.New(handler))
672 slog.SetDefault(slog.New(handler))
654 t.Cleanup(func() { slog.SetDefault(prev) })
673 t.Cleanup(func() { slog.SetDefault(prev) })
655− return &buf
674+ return &sb
656}
675}
657
676
658// xdgIsolated points HOME and XDG_* variables at fresh tempdirs so
677// xdgIsolated points HOME and XDG_* variables at fresh tempdirs so