Skip to content

Commit 51dd1fd

Browse files
mafredrijohnstcn
andauthored
fix: Remove use of require in require.Eventually in tests (coder#3110)
* fix: Remove use of `require` in `require.Eventually` in tests Because require uses `t.FailNow()` and `require.Eventually` runs the function in a goroutine, which is not allowed. * feat: Add ruleguard for require.Eventually Co-authored-by: Cian Johnston <cian@coder.com>
1 parent 3bb7605 commit 51dd1fd

10 files changed

+74
-46
lines changed

agent/agent_test.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,9 @@ func TestAgent(t *testing.T) {
224224
if runtime.GOOS == "windows" {
225225
// Windows uses UTF16! 🪟🪟🪟
226226
content, _, err = transform.Bytes(unicode.UTF16(unicode.LittleEndian, unicode.UseBOM).NewDecoder(), content)
227-
require.NoError(t, err)
227+
if !assert.NoError(t, err) {
228+
return false
229+
}
228230
}
229231
gotContent = string(content)
230232
return true

cli/resetpassword_test.go

+7-9
Original file line numberDiff line numberDiff line change
@@ -44,17 +44,15 @@ func TestResetPassword(t *testing.T) {
4444
err = serverCmd.ExecuteContext(ctx)
4545
assert.ErrorIs(t, err, context.Canceled)
4646
}()
47-
var client *codersdk.Client
47+
var rawURL string
4848
require.Eventually(t, func() bool {
49-
rawURL, err := cfg.URL().Read()
50-
if err != nil {
51-
return false
52-
}
53-
accessURL, err := url.Parse(rawURL)
54-
require.NoError(t, err)
55-
client = codersdk.New(accessURL)
56-
return true
49+
rawURL, err = cfg.URL().Read()
50+
return err == nil && rawURL != ""
5751
}, 15*time.Second, 25*time.Millisecond)
52+
accessURL, err := url.Parse(rawURL)
53+
require.NoError(t, err)
54+
client := codersdk.New(accessURL)
55+
5856
_, err = client.CreateFirstUser(ctx, codersdk.CreateFirstUserRequest{
5957
Email: email,
6058
Username: username,

cli/server_test.go

+7-9
Original file line numberDiff line numberDiff line change
@@ -50,17 +50,15 @@ func TestServer(t *testing.T) {
5050
go func() {
5151
errC <- root.ExecuteContext(ctx)
5252
}()
53-
var client *codersdk.Client
53+
var rawURL string
5454
require.Eventually(t, func() bool {
55-
rawURL, err := cfg.URL().Read()
56-
if err != nil {
57-
return false
58-
}
59-
accessURL, err := url.Parse(rawURL)
60-
assert.NoError(t, err)
61-
client = codersdk.New(accessURL)
62-
return true
55+
rawURL, err = cfg.URL().Read()
56+
return err == nil && rawURL != ""
6357
}, time.Minute, 50*time.Millisecond)
58+
accessURL, err := url.Parse(rawURL)
59+
require.NoError(t, err)
60+
client := codersdk.New(accessURL)
61+
6462
_, err = client.CreateFirstUser(ctx, codersdk.CreateFirstUserRequest{
6563
Email: "some@one.com",
6664
Username: "example",

coderd/coderd_test.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,7 @@ func TestAuthorizeAllEndpoints(t *testing.T) {
153153
// so we wait for it to occur.
154154
require.Eventually(t, func() bool {
155155
provisionerds, err := client.ProvisionerDaemons(ctx)
156-
require.NoError(t, err)
157-
return len(provisionerds) > 0
156+
return assert.NoError(t, err) && len(provisionerds) > 0
158157
}, time.Second*10, time.Second)
159158

160159
provisionerds, err := client.ProvisionerDaemons(ctx)

coderd/coderdtest/coderdtest.go

+15-6
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,8 @@ func CreateWorkspaceBuild(
353353
t *testing.T,
354354
client *codersdk.Client,
355355
workspace codersdk.Workspace,
356-
transition database.WorkspaceTransition) codersdk.WorkspaceBuild {
356+
transition database.WorkspaceTransition,
357+
) codersdk.WorkspaceBuild {
357358
req := codersdk.CreateWorkspaceBuildRequest{
358359
Transition: codersdk.WorkspaceTransition(transition),
359360
}
@@ -397,36 +398,44 @@ func UpdateTemplateVersion(t *testing.T, client *codersdk.Client, organizationID
397398

398399
// AwaitTemplateImportJob awaits for an import job to reach completed status.
399400
func AwaitTemplateVersionJob(t *testing.T, client *codersdk.Client, version uuid.UUID) codersdk.TemplateVersion {
401+
t.Helper()
402+
400403
t.Logf("waiting for template version job %s", version)
401404
var templateVersion codersdk.TemplateVersion
402405
require.Eventually(t, func() bool {
403406
var err error
404407
templateVersion, err = client.TemplateVersion(context.Background(), version)
405-
require.NoError(t, err)
406-
return templateVersion.Job.CompletedAt != nil
408+
return assert.NoError(t, err) && templateVersion.Job.CompletedAt != nil
407409
}, 5*time.Second, 25*time.Millisecond)
408410
return templateVersion
409411
}
410412

411413
// AwaitWorkspaceBuildJob waits for a workspace provision job to reach completed status.
412414
func AwaitWorkspaceBuildJob(t *testing.T, client *codersdk.Client, build uuid.UUID) codersdk.WorkspaceBuild {
415+
t.Helper()
416+
417+
t.Logf("waiting for workspace build job %s", build)
413418
var workspaceBuild codersdk.WorkspaceBuild
414419
require.Eventually(t, func() bool {
415420
var err error
416421
workspaceBuild, err = client.WorkspaceBuild(context.Background(), build)
417-
require.NoError(t, err)
418-
return workspaceBuild.Job.CompletedAt != nil
422+
return assert.NoError(t, err) && workspaceBuild.Job.CompletedAt != nil
419423
}, 5*time.Second, 25*time.Millisecond)
420424
return workspaceBuild
421425
}
422426

423427
// AwaitWorkspaceAgents waits for all resources with agents to be connected.
424428
func AwaitWorkspaceAgents(t *testing.T, client *codersdk.Client, build uuid.UUID) []codersdk.WorkspaceResource {
429+
t.Helper()
430+
431+
t.Logf("waiting for workspace agents (build %s)", build)
425432
var resources []codersdk.WorkspaceResource
426433
require.Eventually(t, func() bool {
427434
var err error
428435
resources, err = client.WorkspaceResourcesByBuild(context.Background(), build)
429-
require.NoError(t, err)
436+
if !assert.NoError(t, err) {
437+
return false
438+
}
430439
for _, resource := range resources {
431440
for _, agent := range resource.Agents {
432441
if agent.Status != codersdk.WorkspaceAgentConnected {

coderd/devtunnel/tunnel_test.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,9 @@ func TestTunnel(t *testing.T) {
7878

7979
require.Eventually(t, func() bool {
8080
res, err := fTunServer.requestHTTP()
81-
require.NoError(t, err)
81+
if !assert.NoError(t, err) {
82+
return false
83+
}
8284
defer res.Body.Close()
8385
_, _ = io.Copy(io.Discard, res.Body)
8486

coderd/provisionerdaemons_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"testing"
88
"time"
99

10+
"github.com/stretchr/testify/assert"
1011
"github.com/stretchr/testify/require"
1112

1213
"github.com/coder/coder/coderd/coderdtest"
@@ -39,8 +40,7 @@ func TestProvisionerDaemons(t *testing.T) {
3940
require.Eventually(t, func() bool {
4041
var err error
4142
version, err = client.TemplateVersion(context.Background(), version.ID)
42-
require.NoError(t, err)
43-
return version.Job.Error != ""
43+
return assert.NoError(t, err) && version.Job.Error != ""
4444
}, 5*time.Second, 25*time.Millisecond)
4545
})
4646
}

coderd/templateversions_test.go

+20-10
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,9 @@ func TestPatchCancelTemplateVersion(t *testing.T) {
115115
require.Eventually(t, func() bool {
116116
var err error
117117
version, err = client.TemplateVersion(context.Background(), version.ID)
118-
require.NoError(t, err)
118+
if !assert.NoError(t, err) {
119+
return false
120+
}
119121
t.Logf("Status: %s", version.Job.Status)
120122
return version.Job.Status == codersdk.ProvisionerJobRunning
121123
}, 5*time.Second, 25*time.Millisecond)
@@ -148,7 +150,9 @@ func TestPatchCancelTemplateVersion(t *testing.T) {
148150
require.Eventually(t, func() bool {
149151
var err error
150152
version, err = client.TemplateVersion(context.Background(), version.ID)
151-
require.NoError(t, err)
153+
if !assert.NoError(t, err) {
154+
return false
155+
}
152156
t.Logf("Status: %s", version.Job.Status)
153157
return version.Job.Status == codersdk.ProvisionerJobRunning
154158
}, 5*time.Second, 25*time.Millisecond)
@@ -536,9 +540,7 @@ func TestTemplateVersionDryRun(t *testing.T) {
536540
// Wait for the job to complete
537541
require.Eventually(t, func() bool {
538542
job, err := client.TemplateVersionDryRun(ctx, version.ID, job.ID)
539-
assert.NoError(t, err)
540-
541-
return job.Status == codersdk.ProvisionerJobSucceeded
543+
return assert.NoError(t, err) && job.Status == codersdk.ProvisionerJobSucceeded
542544
}, 5*time.Second, 25*time.Millisecond)
543545

544546
<-logsDone
@@ -588,7 +590,8 @@ func TestTemplateVersionDryRun(t *testing.T) {
588590
{
589591
Type: &proto.Provision_Response_Log{
590592
Log: &proto.Log{},
591-
}},
593+
},
594+
},
592595
{
593596
Type: &proto.Provision_Response_Complete{
594597
Complete: &proto.Provision_Complete{},
@@ -609,7 +612,9 @@ func TestTemplateVersionDryRun(t *testing.T) {
609612

610613
require.Eventually(t, func() bool {
611614
job, err := client.TemplateVersionDryRun(context.Background(), version.ID, job.ID)
612-
assert.NoError(t, err)
615+
if !assert.NoError(t, err) {
616+
return false
617+
}
613618

614619
t.Logf("Status: %s", job.Status)
615620
return job.Status == codersdk.ProvisionerJobPending
@@ -620,7 +625,9 @@ func TestTemplateVersionDryRun(t *testing.T) {
620625

621626
require.Eventually(t, func() bool {
622627
job, err := client.TemplateVersionDryRun(context.Background(), version.ID, job.ID)
623-
assert.NoError(t, err)
628+
if !assert.NoError(t, err) {
629+
return false
630+
}
624631

625632
t.Logf("Status: %s", job.Status)
626633
return job.Status == codersdk.ProvisionerJobCanceling
@@ -642,7 +649,9 @@ func TestTemplateVersionDryRun(t *testing.T) {
642649

643650
require.Eventually(t, func() bool {
644651
job, err := client.TemplateVersionDryRun(context.Background(), version.ID, job.ID)
645-
assert.NoError(t, err)
652+
if !assert.NoError(t, err) {
653+
return false
654+
}
646655

647656
t.Logf("Status: %s", job.Status)
648657
return job.Status == codersdk.ProvisionerJobSucceeded
@@ -666,7 +675,8 @@ func TestTemplateVersionDryRun(t *testing.T) {
666675
{
667676
Type: &proto.Provision_Response_Log{
668677
Log: &proto.Log{},
669-
}},
678+
},
679+
},
670680
{
671681
Type: &proto.Provision_Response_Complete{
672682
Complete: &proto.Provision_Complete{},

coderd/workspacebuilds_test.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -221,8 +221,7 @@ func TestPatchCancelWorkspaceBuild(t *testing.T) {
221221
require.Eventually(t, func() bool {
222222
var err error
223223
build, err = client.WorkspaceBuild(context.Background(), workspace.LatestBuild.ID)
224-
require.NoError(t, err)
225-
return build.Job.Status == codersdk.ProvisionerJobRunning
224+
return assert.NoError(t, err) && build.Job.Status == codersdk.ProvisionerJobRunning
226225
}, 5*time.Second, 25*time.Millisecond)
227226
err := client.CancelWorkspaceBuild(context.Background(), build.ID)
228227
require.NoError(t, err)

scripts/rules.go

+15-4
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,17 @@ func doNotCallTFailNowInsideGoroutine(m dsl.Matcher) {
5959
Where(m["require"].Text == "require").
6060
Report("Do not call functions that may call t.FailNow in a goroutine, as this can cause data races (see testing.go:834)")
6161

62+
// require.Eventually runs the function in a goroutine.
63+
m.Match(`
64+
require.Eventually(t, func() bool {
65+
$*_
66+
$require.$_($*_)
67+
$*_
68+
}, $*_)`).
69+
At(m["require"]).
70+
Where(m["require"].Text == "require").
71+
Report("Do not call functions that may call t.FailNow in a goroutine, as this can cause data races (see testing.go:834)")
72+
6273
m.Match(`
6374
go func($*_){
6475
$*_
@@ -90,10 +101,10 @@ func InTx(m dsl.Matcher) {
90101
At(m["f"]).
91102
Report("Do not use the database directly within the InTx closure. Use '$y' instead of '$x'.")
92103

93-
//When using a tx closure, ensure that if you pass the db to another
94-
//function inside the closure, it is the tx.
95-
//This will miss more complex cases such as passing the db as apart
96-
//of another struct.
104+
// When using a tx closure, ensure that if you pass the db to another
105+
// function inside the closure, it is the tx.
106+
// This will miss more complex cases such as passing the db as apart
107+
// of another struct.
97108
m.Match(`
98109
$x.InTx(func($y database.Store) error {
99110
$*_

0 commit comments

Comments
 (0)