on main help sign in
fix(server): correct socket location test on macOS
4abf206Christian Rocha
internal/cmd/root.go+1−1
@@ -437,7 +437,7 @@ func ensureServer(cmd *cobra.Command, hostURL *url.URL) error {
437 // we detect it with a short DialTimeout and remove the
437 // we detect it with a short DialTimeout and remove the
438 // orphaned file so the normal spawn path can run.
438 // orphaned file so the normal spawn path can run.
439 if hostURL.Scheme == "unix" {
439 if hostURL.Scheme == "unix" {
440− conn, dialErr := net.DialTimeout(
440+ conn, dialErr := net.DialTimeout( //nolint:noctx
441 hostURL.Scheme, hostURL.Host, 200*time.Millisecond,
441 hostURL.Scheme, hostURL.Host, 200*time.Millisecond,
442 )
442 )
443 if dialErr == nil {
443 if dialErr == nil {
internal/server/net_other.go+1−1
@@ -32,7 +32,7 @@ func listen(network, address string) (net.Listener, bool, error) {
32 var removedStale bool
32 var removedStale bool
33 if network == "unix" && address != "" {
33 if network == "unix" && address != "" {
34 if _, err := os.Stat(address); err == nil {
34 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
36 if dialErr == nil {
36 if dialErr == nil {
37 // A live server owns the socket. Fall through to
37 // A live server owns the socket. Fall through to
38 // net.Listen so the caller sees the standard
38 // 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
261 if !ok {
261 if !ok {
262 return
262 return
263 }
263 }
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 {
265 c.handleError(w, r, err)
271 c.handleError(w, r, err)
266 return
272 return
267 }
273 }
268− defer c.backend.DetachClient(id, clientID)
274+ if err := c.backend.AttachClient(id, clientID); err != nil {
269− events, err := c.backend.SubscribeEvents(r.Context(), id)
270− if err != nil {
271 c.handleError(w, r, err)
275 c.handleError(w, r, err)
272 return
276 return
273 }
277 }
278+ defer c.backend.DetachClient(id, clientID)
274
279
275 w.Header().Set("Content-Type", "text/event-stream")
280 w.Header().Set("Content-Type", "text/event-stream")
276 w.Header().Set("Cache-Control", "no-cache")
281 w.Header().Set("Cache-Control", "no-cache")
internal/server/socket_test.go+10−6
@@ -71,8 +71,12 @@ func TestDefaultHost_XDGRuntimeDir(t *testing.T) {
71 path := strings.TrimPrefix(host, "unix://")
71 path := strings.TrimPrefix(host, "unix://")
72
72
73 // The composed path may exceed maxUnixSocketPathLen and fall back
73 // The composed path may exceed maxUnixSocketPathLen and fall back
74− // to /tmp; only assert containment when it did not.
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))
75− if len(filepath.Join(dir, "crush.sock")) <= maxUnixSocketPathLen {
79+ if len(composed) <= maxUnixSocketPathLen {
76 require.True(t, strings.HasPrefix(path, dir),
80 require.True(t, strings.HasPrefix(path, dir),
77 "socket path %q should live under %q", path, dir)
81 "socket path %q should live under %q", path, dir)
78 }
82 }
@@ -104,7 +108,7 @@ func TestDefaultHost_FallbackTemp(t *testing.T) {
104// it. A leftover file is best-effort removed via t.Cleanup.
108// it. A leftover file is best-effort removed via t.Cleanup.
105func staleSocketPath(t *testing.T, path string) {
109func staleSocketPath(t *testing.T, path string) {
106 t.Helper()
110 t.Helper()
107− ln, err := net.Listen("unix", path)
111+ ln, err := net.Listen("unix", path) //nolint:noctx
108 require.NoError(t, err)
112 require.NoError(t, err)
109 ul, ok := ln.(*net.UnixListener)
113 ul, ok := ln.(*net.UnixListener)
110 require.True(t, ok, "expected *net.UnixListener, got %T", ln)
114 require.True(t, ok, "expected *net.UnixListener, got %T", ln)
@@ -112,7 +116,7 @@ func staleSocketPath(t *testing.T, path string) {
112 require.NoError(t, ul.Close())
116 require.NoError(t, ul.Close())
113
117
114 // Verify it is actually stale: dialing should fail.
118 // 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
116 if dialErr == nil {
120 if dialErr == nil {
117 conn.Close()
121 conn.Close()
118 t.Fatalf("expected stale socket at %q to refuse connections", path)
122 t.Fatalf("expected stale socket at %q to refuse connections", path)
@@ -150,7 +154,7 @@ func TestListen_LiveSocketNotRemoved(t *testing.T) {
150 dir := t.TempDir()
154 dir := t.TempDir()
151 path := filepath.Join(dir, "s.sock")
155 path := filepath.Join(dir, "s.sock")
152
156
153− ln1, err := net.Listen("unix", path)
157+ ln1, err := net.Listen("unix", path) //nolint:noctx
154 require.NoError(t, err)
158 require.NoError(t, err)
155
159
156 // Drain accepts so the listener stays alive and responsive without
160 // Drain accepts so the listener stays alive and responsive without
@@ -183,7 +187,7 @@ func TestListen_LiveSocketNotRemoved(t *testing.T) {
183 // The live socket file must still be on disk and dialable.
187 // The live socket file must still be on disk and dialable.
184 _, statErr := os.Stat(path)
188 _, statErr := os.Stat(path)
185 require.NoError(t, statErr, "live socket file should still exist")
189 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
187 require.NoError(t, dialErr, "live socket should still accept dials")
191 require.NoError(t, dialErr, "live socket should still accept dials")
188 _ = conn.Close()
192 _ = conn.Close()
189}
193}