Skip to content

Commit ac3c530

Browse files
authored
fix(cli/clitest): race between Start/StartWithWaiter cleanup order (#7232)
1 parent 745868f commit ac3c530

File tree

2 files changed

+29
-7
lines changed

2 files changed

+29
-7
lines changed

cli/clitest/clitest.go

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,20 +133,23 @@ func Start(t *testing.T, inv *clibase.Invocation) {
133133
t.Helper()
134134

135135
closeCh := make(chan struct{})
136+
// StartWithWaiter adds its own `t.Cleanup`, so we need to be sure it's added
137+
// before ours.
138+
waiter := StartWithWaiter(t, inv)
139+
t.Cleanup(func() {
140+
<-closeCh
141+
})
142+
136143
go func() {
137144
defer close(closeCh)
138-
err := StartWithWaiter(t, inv).Wait()
145+
err := waiter.Wait()
139146
switch {
140147
case errors.Is(err, context.Canceled):
141148
return
142149
default:
143150
assert.NoError(t, err)
144151
}
145152
}()
146-
147-
t.Cleanup(func() {
148-
<-closeCh
149-
})
150153
}
151154

152155
// Run runs the command and asserts that there is no error.

cli/templatecreate_test.go

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ package cli_test
22

33
import (
44
"bytes"
5+
"context"
56
"os"
67
"testing"
78

9+
"github.com/stretchr/testify/assert"
810
"github.com/stretchr/testify/require"
911

1012
"github.com/coder/coder/cli/clitest"
@@ -13,6 +15,7 @@ import (
1315
"github.com/coder/coder/provisioner/echo"
1416
"github.com/coder/coder/provisionersdk/proto"
1517
"github.com/coder/coder/pty/ptytest"
18+
"github.com/coder/coder/testutil"
1619
)
1720

1821
var provisionCompleteWithAgent = []*proto.Provision_Response{
@@ -290,11 +293,23 @@ func TestTemplateCreate(t *testing.T) {
290293
removeTmpDirUntilSuccessAfterTest(t, tempDir)
291294
variablesFile, _ := os.CreateTemp(tempDir, "variables*.yaml")
292295
_, _ = variablesFile.WriteString(`second_variable: foobar`)
296+
297+
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort)
298+
defer cancel()
299+
293300
inv, root := clitest.New(t, "templates", "create", "my-template", "--directory", source, "--test.provisioner", string(database.ProvisionerTypeEcho), "--variables-file", variablesFile.Name())
294301
clitest.SetupConfig(t, client, root)
302+
inv = inv.WithContext(ctx)
295303
pty := ptytest.New(t).Attach(inv)
296304

297-
clitest.Start(t, inv)
305+
// We expect the cli to return an error, so we have to handle it
306+
// ourselves.
307+
go func() {
308+
cancel()
309+
err := inv.Run()
310+
assert.Error(t, err)
311+
}()
312+
298313
matches := []struct {
299314
match string
300315
write string
@@ -307,6 +322,8 @@ func TestTemplateCreate(t *testing.T) {
307322
pty.WriteLine(m.write)
308323
}
309324
}
325+
326+
<-ctx.Done()
310327
})
311328

312329
t.Run("WithVariablesFileWithTheRequiredValue", func(t *testing.T) {
@@ -390,7 +407,9 @@ func TestTemplateCreate(t *testing.T) {
390407
}
391408
for _, m := range matches {
392409
pty.ExpectMatch(m.match)
393-
pty.WriteLine(m.write)
410+
if len(m.write) > 0 {
411+
pty.WriteLine(m.write)
412+
}
394413
}
395414
})
396415
}

0 commit comments

Comments
 (0)