Skip to content

Commit 074ec28

Browse files
authored
test(agent/agentssh): fix test race and improve Windows compat (#17271)
Fixes coder/internal#558
1 parent 59c5bc9 commit 074ec28

File tree

3 files changed

+21
-6
lines changed

3 files changed

+21
-6
lines changed

agent/agentssh/agentssh.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -1060,8 +1060,10 @@ func (s *Server) Close() error {
10601060
// Guard against multiple calls to Close and
10611061
// accepting new connections during close.
10621062
if s.closing != nil {
1063+
closing := s.closing
10631064
s.mu.Unlock()
1064-
return xerrors.New("server is closing")
1065+
<-closing
1066+
return xerrors.New("server is closed")
10651067
}
10661068
s.closing = make(chan struct{})
10671069

agent/agentssh/agentssh_test.go

+11-2
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,9 @@ func TestNewServer_CloseActiveConnections(t *testing.T) {
153153
logger := slogtest.Make(t, &slogtest.Options{IgnoreErrors: true}).Leveled(slog.LevelDebug)
154154
s, err := agentssh.NewServer(ctx, logger, prometheus.NewRegistry(), afero.NewMemMapFs(), agentexec.DefaultExecer, nil)
155155
require.NoError(t, err)
156-
defer s.Close()
156+
t.Cleanup(func() {
157+
_ = s.Close()
158+
})
157159
err = s.UpdateHostSigner(42)
158160
assert.NoError(t, err)
159161

@@ -190,10 +192,17 @@ func TestNewServer_CloseActiveConnections(t *testing.T) {
190192
}
191193
// The 60 seconds here is intended to be longer than the
192194
// test. The shutdown should propagate.
193-
err = sess.Start("/bin/bash -c 'trap \"sleep 60\" SIGTERM; sleep 60'")
195+
if runtime.GOOS == "windows" {
196+
// Best effort to at least partially test this in Windows.
197+
err = sess.Start("echo start\"ed\" && sleep 60")
198+
} else {
199+
err = sess.Start("/bin/bash -c 'trap \"sleep 60\" SIGTERM; echo start\"ed\"; sleep 60'")
200+
}
194201
assert.NoError(t, err)
195202

203+
pty.ExpectMatchContext(ctx, "started")
196204
close(ch)
205+
197206
err = sess.Wait()
198207
assert.Error(t, err)
199208
}(waitConns[i])

agent/agentssh/exec_windows.go

+7-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package agentssh
22

33
import (
44
"context"
5-
"os"
65
"os/exec"
76
"syscall"
87

@@ -15,7 +14,12 @@ func cmdSysProcAttr() *syscall.SysProcAttr {
1514

1615
func cmdCancel(ctx context.Context, logger slog.Logger, cmd *exec.Cmd) func() error {
1716
return func() error {
18-
logger.Debug(ctx, "cmdCancel: sending interrupt to process", slog.F("pid", cmd.Process.Pid))
19-
return cmd.Process.Signal(os.Interrupt)
17+
logger.Debug(ctx, "cmdCancel: killing process", slog.F("pid", cmd.Process.Pid))
18+
// Windows doesn't support sending signals to process groups, so we
19+
// have to kill the process directly. In the future, we may want to
20+
// implement a more sophisticated solution for process groups on
21+
// Windows, but for now, this is a simple way to ensure that the
22+
// process is terminated when the context is cancelled.
23+
return cmd.Process.Kill()
2024
}
2125
}

0 commit comments

Comments
 (0)