on main help sign in
fix(server): correct socket location test on macOS

Co-Authored-By: Charm Crush <crush@charm.land>

commit4abf2066b1d432685e90a9b297d13153bbe3b1da authorChristian Rocha <christian@rocha.is> dateMon 8 Jun 2026, 09:59 (4 months ago) parent2922de8
4 files changed+21−12
internal/cmd/root.go+1−1 internal/server/net_other.go+1−1 internal/server/proto.go+9−4 internal/server/socket_test.go+10−6
internal/cmd/root.go+1−1
@@ -437,7 +437,7 @@ func ensureServer(cmd *cobra.Command, hostURL *url.URL) error {
437437 // we detect it with a short DialTimeout and remove the
438438 // orphaned file so the normal spawn path can run.
439439 if hostURL.Scheme == "unix" {
440− conn, dialErr := net.DialTimeout(
440+ conn, dialErr := net.DialTimeout( //nolint:noctx
441441 hostURL.Scheme, hostURL.Host, 200*time.Millisecond,
442442 )
443443 if dialErr == nil {
internal/server/net_other.go+1−1
@@ -32,7 +32,7 @@ func listen(network, address string) (net.Listener, bool, error) {
3232 var removedStale bool
3333 if network == "unix" && address != "" {
3434 if _, err := os.Stat(address); err == nil {
35− conn, dialErr := net.DialTimeout(network, address, staleSocketDialTimeout)
35+ conn, dialErr := net.DialTimeout(network, address, staleSocketDialTimeout) //nolint:noctx
3636 if dialErr == nil {
3737 // A live server owns the socket. Fall through to
3838 // net.Listen so the caller sees the standard
internal/server/proto.go+9−4
@@ -261,16 +261,21 @@ func (c *controllerV1) handleGetWorkspaceEvents(w http.ResponseWriter, r *http.R
261261 if !ok {
262262 return
263263 }
264− if err := c.backend.AttachClient(id, clientID); err != nil {
264+ // Subscribe to the event broker BEFORE attaching the client.
265+ // AttachClient bumps the stream count that observers use to
266+ // detect a live subscriber; subscribing first guarantees that
267+ // once a client appears attached, any published event is
268+ // delivered rather than dropped on a not-yet-registered stream.
269+ events, err := c.backend.SubscribeEvents(r.Context(), id)
270+ if err != nil {
265271 c.handleError(w, r, err)
266272 return
267273 }
268− defer c.backend.DetachClient(id, clientID)
269− events, err := c.backend.SubscribeEvents(r.Context(), id)
270− if err != nil {
274+ if err := c.backend.AttachClient(id, clientID); err != nil {
271275 c.handleError(w, r, err)
272276 return
273277 }
278+ defer c.backend.DetachClient(id, clientID)
274279
275280 w.Header().Set("Content-Type", "text/event-stream")
276281 w.Header().Set("Cache-Control", "no-cache")
internal/server/socket_test.go+10−6
@@ -71,8 +71,12 @@ func TestDefaultHost_XDGRuntimeDir(t *testing.T) {
7171 path := strings.TrimPrefix(host, "unix://")
7272
7373 // The composed path may exceed maxUnixSocketPathLen and fall back
74− // to /tmp; only assert containment when it did not.
75− if len(filepath.Join(dir, "crush.sock")) <= maxUnixSocketPathLen {
74+ // to /tmp; only assert containment when it did not. Recompose the
75+ // path under dir (rather than checking the returned path length,
76+ // which is short again after a /tmp fallback) to decide whether a
77+ // fallback happened. The socket is named crush-<uid>.sock.
78+ composed := filepath.Join(dir, filepath.Base(path))
79+ if len(composed) <= maxUnixSocketPathLen {
7680 require.True(t, strings.HasPrefix(path, dir),
7781 "socket path %q should live under %q", path, dir)
7882 }
@@ -104,7 +108,7 @@ func TestDefaultHost_FallbackTemp(t *testing.T) {
104108// it. A leftover file is best-effort removed via t.Cleanup.
105109func staleSocketPath(t *testing.T, path string) {
106110 t.Helper()
107− ln, err := net.Listen("unix", path)
111+ ln, err := net.Listen("unix", path) //nolint:noctx
108112 require.NoError(t, err)
109113 ul, ok := ln.(*net.UnixListener)
110114 require.True(t, ok, "expected *net.UnixListener, got %T", ln)
@@ -112,7 +116,7 @@ func staleSocketPath(t *testing.T, path string) {
112116 require.NoError(t, ul.Close())
113117
114118 // Verify it is actually stale: dialing should fail.
115− conn, dialErr := net.DialTimeout("unix", path, 200*time.Millisecond)
119+ conn, dialErr := net.DialTimeout("unix", path, 200*time.Millisecond) //nolint:noctx
116120 if dialErr == nil {
117121 conn.Close()
118122 t.Fatalf("expected stale socket at %q to refuse connections", path)
@@ -150,7 +154,7 @@ func TestListen_LiveSocketNotRemoved(t *testing.T) {
150154 dir := t.TempDir()
151155 path := filepath.Join(dir, "s.sock")
152156
153− ln1, err := net.Listen("unix", path)
157+ ln1, err := net.Listen("unix", path) //nolint:noctx
154158 require.NoError(t, err)
155159
156160 // Drain accepts so the listener stays alive and responsive without
@@ -183,7 +187,7 @@ func TestListen_LiveSocketNotRemoved(t *testing.T) {
183187 // The live socket file must still be on disk and dialable.
184188 _, statErr := os.Stat(path)
185189 require.NoError(t, statErr, "live socket file should still exist")
186− conn, dialErr := net.DialTimeout("unix", path, 200*time.Millisecond)
190+ conn, dialErr := net.DialTimeout("unix", path, 200*time.Millisecond) //nolint:noctx
187191 require.NoError(t, dialErr, "live socket should still accept dials")
188192 _ = conn.Close()
189193}