Skip to content

Commit 4bc420d

Browse files
authored
test: Fix data race in loadtest/reconnectingpty (coder#5431)
1 parent 25ebeba commit 4bc420d

File tree

1 file changed

+22
-1
lines changed
  • loadtest/reconnectingpty

1 file changed

+22
-1
lines changed

loadtest/reconnectingpty/run.go

+22-1
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,8 @@ func (r *Runner) Run(ctx context.Context, _ string, logs io.Writer) error {
8383
}
8484

8585
copyCtx, copyCancel := context.WithTimeout(ctx, time.Duration(copyTimeout))
86+
defer copyCancel()
8687
matched, err := copyContext(copyCtx, copyOutput, conn, r.cfg.ExpectOutput)
87-
copyCancel()
8888
if r.cfg.ExpectTimeout {
8989
if err == nil {
9090
return xerrors.Errorf("expected timeout, but the command exited successfully")
@@ -107,11 +107,27 @@ func copyContext(ctx context.Context, dst io.Writer, src io.Reader, expectOutput
107107
copyErr = make(chan error)
108108
matched = expectOutput == ""
109109
)
110+
111+
// Guard goroutine for loop body to ensure reading `matched` is safe on
112+
// context cancellation and that `dst` won't be written to after we
113+
// return from this function.
114+
processing := make(chan struct{}, 1)
115+
processing <- struct{}{}
116+
110117
go func() {
118+
defer close(processing)
111119
defer close(copyErr)
112120

113121
scanner := bufio.NewScanner(src)
114122
for scanner.Scan() {
123+
select {
124+
case <-processing:
125+
default:
126+
}
127+
if ctx.Err() != nil {
128+
return
129+
}
130+
115131
if expectOutput != "" && strings.Contains(scanner.Text(), expectOutput) {
116132
matched = true
117133
}
@@ -121,6 +137,7 @@ func copyContext(ctx context.Context, dst io.Writer, src io.Reader, expectOutput
121137
copyErr <- xerrors.Errorf("write to logs: %w", err)
122138
return
123139
}
140+
processing <- struct{}{}
124141
}
125142
if scanner.Err() != nil {
126143
copyErr <- xerrors.Errorf("read from reconnecting PTY: %w", scanner.Err())
@@ -130,6 +147,10 @@ func copyContext(ctx context.Context, dst io.Writer, src io.Reader, expectOutput
130147

131148
select {
132149
case <-ctx.Done():
150+
select {
151+
case <-processing:
152+
case <-copyErr:
153+
}
133154
return matched, ctx.Err()
134155
case err := <-copyErr:
135156
return matched, err

0 commit comments

Comments
 (0)