Skip to content

Commit c304696

Browse files
committed
chore: executor_test: break out some test helpers, attempt to speed up test execution
1 parent ff542af commit c304696

File tree

1 file changed

+59
-74
lines changed

1 file changed

+59
-74
lines changed

coderd/autobuild/executor/lifecycle_executor_test.go

+59-74
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import (
1616
"github.com/coder/coder/codersdk"
1717

1818
"github.com/google/uuid"
19+
"github.com/stretchr/testify/assert"
1920
"github.com/stretchr/testify/require"
2021
)
2122

@@ -49,12 +50,8 @@ func TestExecutorAutostartOK(t *testing.T) {
4950
close(tickCh)
5051
}()
5152

52-
// Then: the workspace should be started
53-
<-time.After(5 * time.Second)
54-
ws := mustWorkspace(t, client, workspace.ID)
55-
require.NotEqual(t, workspace.LatestBuild.ID, ws.LatestBuild.ID, "expected a workspace build to occur")
56-
require.Equal(t, codersdk.ProvisionerJobSucceeded, ws.LatestBuild.Job.Status, "expected provisioner job to have succeeded")
57-
require.Equal(t, codersdk.WorkspaceTransitionStart, ws.LatestBuild.Transition, "expected latest transition to be start")
53+
// Then: the workspace should eventually be started
54+
assertLatestTransitionWithEventualBuild(t, client, workspace, codersdk.WorkspaceTransitionStart)
5855
}
5956

6057
func TestExecutorAutostartTemplateUpdated(t *testing.T) {
@@ -99,11 +96,8 @@ func TestExecutorAutostartTemplateUpdated(t *testing.T) {
9996
}()
10097

10198
// Then: the workspace should be started using the previous template version, and not the updated version.
102-
<-time.After(5 * time.Second)
99+
assertLatestTransitionWithEventualBuild(t, client, workspace, codersdk.WorkspaceTransitionStart)
103100
ws := mustWorkspace(t, client, workspace.ID)
104-
require.NotEqual(t, workspace.LatestBuild.ID, ws.LatestBuild.ID, "expected a workspace build to occur")
105-
require.Equal(t, codersdk.ProvisionerJobSucceeded, ws.LatestBuild.Job.Status, "expected provisioner job to have succeeded")
106-
require.Equal(t, codersdk.WorkspaceTransitionStart, ws.LatestBuild.Transition, "expected latest transition to be start")
107101
require.Equal(t, workspace.LatestBuild.TemplateVersionID, ws.LatestBuild.TemplateVersionID, "expected workspace build to be using the old template version")
108102
}
109103

@@ -139,10 +133,7 @@ func TestExecutorAutostartAlreadyRunning(t *testing.T) {
139133
}()
140134

141135
// Then: the workspace should not be started.
142-
<-time.After(5 * time.Second)
143-
ws := mustWorkspace(t, client, workspace.ID)
144-
require.Equal(t, workspace.LatestBuild.ID, ws.LatestBuild.ID, "expected no further workspace builds to occur")
145-
require.Equal(t, codersdk.WorkspaceTransitionStart, ws.LatestBuild.Transition, "expected workspace to be running")
136+
assertLatestTransitionWithNoEventualBuild(t, client, workspace, codersdk.WorkspaceTransitionStop)
146137
}
147138

148139
func TestExecutorAutostartNotEnabled(t *testing.T) {
@@ -173,10 +164,7 @@ func TestExecutorAutostartNotEnabled(t *testing.T) {
173164
}()
174165

175166
// Then: the workspace should not be started.
176-
<-time.After(5 * time.Second)
177-
ws := mustWorkspace(t, client, workspace.ID)
178-
require.Equal(t, workspace.LatestBuild.ID, ws.LatestBuild.ID, "expected no further workspace builds to occur")
179-
require.NotEqual(t, database.WorkspaceTransitionStart, ws.LatestBuild.Transition, "expected workspace not to be running")
167+
assertLatestTransitionWithNoEventualBuild(t, client, workspace, codersdk.WorkspaceTransitionStop)
180168
}
181169

182170
func TestExecutorAutostopOK(t *testing.T) {
@@ -202,11 +190,7 @@ func TestExecutorAutostopOK(t *testing.T) {
202190
}()
203191

204192
// Then: the workspace should be stopped
205-
<-time.After(5 * time.Second)
206-
ws := mustWorkspace(t, client, workspace.ID)
207-
require.NotEqual(t, workspace.LatestBuild.ID, ws.LatestBuild.ID, "expected a workspace build to occur")
208-
require.Equal(t, codersdk.ProvisionerJobSucceeded, ws.LatestBuild.Job.Status, "expected provisioner job to have succeeded")
209-
require.Equal(t, codersdk.WorkspaceTransitionStop, ws.LatestBuild.Transition, "expected workspace not to be running")
193+
assertLatestTransitionWithEventualBuild(t, client, workspace, codersdk.WorkspaceTransitionStop)
210194
}
211195

212196
func TestExecutorAutostopExtend(t *testing.T) {
@@ -228,8 +212,9 @@ func TestExecutorAutostopExtend(t *testing.T) {
228212
require.NotZero(t, originalDeadline)
229213

230214
// Given: we extend the workspace deadline
215+
newDeadline := originalDeadline.Add(30 * time.Minute)
231216
err := client.PutExtendWorkspace(ctx, workspace.ID, codersdk.PutExtendWorkspaceRequest{
232-
Deadline: originalDeadline.Add(30 * time.Minute),
217+
Deadline: newDeadline,
233218
})
234219
require.NoError(t, err, "extend workspace deadline")
235220

@@ -238,24 +223,17 @@ func TestExecutorAutostopExtend(t *testing.T) {
238223
tickCh <- originalDeadline.Add(time.Minute)
239224
}()
240225

241-
// Then: nothing should happen
242-
<-time.After(5 * time.Second)
243-
ws := mustWorkspace(t, client, workspace.ID)
244-
require.Equal(t, workspace.LatestBuild.ID, ws.LatestBuild.ID, "expected no further workspace builds to occur")
245-
require.Equal(t, codersdk.WorkspaceTransitionStart, ws.LatestBuild.Transition, "expected workspace to be running")
226+
// Then: nothing should happen and the workspace should stay running
227+
assertLatestTransitionWithNoEventualBuild(t, client, workspace, codersdk.WorkspaceTransitionStart)
246228

247229
// When: the autobuild executor ticks after the *new* deadline:
248230
go func() {
249-
tickCh <- ws.LatestBuild.Deadline.Add(time.Minute)
231+
tickCh <- newDeadline.Add(time.Minute)
250232
close(tickCh)
251233
}()
252234

253235
// Then: the workspace should be stopped
254-
<-time.After(5 * time.Second)
255-
ws = mustWorkspace(t, client, workspace.ID)
256-
require.NotEqual(t, workspace.LatestBuild.ID, ws.LatestBuild.ID, "expected a workspace build to occur")
257-
require.Equal(t, codersdk.ProvisionerJobSucceeded, ws.LatestBuild.Job.Status, "expected provisioner job to have succeeded")
258-
require.Equal(t, codersdk.WorkspaceTransitionStop, ws.LatestBuild.Transition, "expected workspace not to be running")
236+
assertLatestTransitionWithEventualBuild(t, client, workspace, codersdk.WorkspaceTransitionStop)
259237
}
260238

261239
func TestExecutorAutostopAlreadyStopped(t *testing.T) {
@@ -282,11 +260,8 @@ func TestExecutorAutostopAlreadyStopped(t *testing.T) {
282260
close(tickCh)
283261
}()
284262

285-
// Then: the workspace should not be stopped.
286-
<-time.After(5 * time.Second)
287-
ws := mustWorkspace(t, client, workspace.ID)
288-
require.Equal(t, codersdk.WorkspaceTransitionStop, ws.LatestBuild.Transition, "expected workspace not to be running")
289-
require.Equal(t, workspace.LatestBuild.ID, ws.LatestBuild.ID, "expected no further workspace builds to occur")
263+
// Then: the workspace should remain stopped and no build should happen.
264+
assertLatestTransitionWithNoEventualBuild(t, client, workspace, codersdk.WorkspaceTransitionStop)
290265
}
291266

292267
func TestExecutorAutostopNotEnabled(t *testing.T) {
@@ -317,10 +292,7 @@ func TestExecutorAutostopNotEnabled(t *testing.T) {
317292
}()
318293

319294
// Then: the workspace should not be stopped.
320-
<-time.After(5 * time.Second)
321-
ws := mustWorkspace(t, client, workspace.ID)
322-
require.Equal(t, workspace.LatestBuild.ID, ws.LatestBuild.ID, "expected no further workspace builds to occur")
323-
require.Equal(t, codersdk.WorkspaceTransitionStart, ws.LatestBuild.Transition, "expected workspace to be running")
295+
assertLatestTransitionWithNoEventualBuild(t, client, workspace, codersdk.WorkspaceTransitionStart)
324296
}
325297

326298
func TestExecutorWorkspaceDeleted(t *testing.T) {
@@ -355,10 +327,7 @@ func TestExecutorWorkspaceDeleted(t *testing.T) {
355327
}()
356328

357329
// Then: nothing should happen
358-
<-time.After(5 * time.Second)
359-
ws := mustWorkspace(t, client, workspace.ID)
360-
require.Equal(t, workspace.LatestBuild.ID, ws.LatestBuild.ID, "expected no further workspace builds to occur")
361-
require.Equal(t, codersdk.WorkspaceTransitionDelete, ws.LatestBuild.Transition, "expected workspace to be deleted")
330+
assertLatestTransitionWithNoEventualBuild(t, client, workspace, codersdk.WorkspaceTransitionDelete)
362331
}
363332

364333
func TestExecutorWorkspaceAutostartTooEarly(t *testing.T) {
@@ -394,10 +363,7 @@ func TestExecutorWorkspaceAutostartTooEarly(t *testing.T) {
394363
}()
395364

396365
// Then: nothing should happen
397-
<-time.After(5 * time.Second)
398-
ws := mustWorkspace(t, client, workspace.ID)
399-
require.Equal(t, workspace.LatestBuild.ID, ws.LatestBuild.ID, "expected no further workspace builds to occur")
400-
require.Equal(t, codersdk.WorkspaceTransitionStart, ws.LatestBuild.Transition, "expected workspace to be running")
366+
assertLatestTransitionWithNoEventualBuild(t, client, workspace, codersdk.WorkspaceTransitionStart)
401367
}
402368

403369
func TestExecutorWorkspaceAutostopBeforeDeadline(t *testing.T) {
@@ -420,10 +386,7 @@ func TestExecutorWorkspaceAutostopBeforeDeadline(t *testing.T) {
420386
}()
421387

422388
// Then: nothing should happen
423-
<-time.After(5 * time.Second)
424-
ws := mustWorkspace(t, client, workspace.ID)
425-
require.Equal(t, workspace.LatestBuild.ID, ws.LatestBuild.ID, "expected no further workspace builds to occur")
426-
require.Equal(t, codersdk.WorkspaceTransitionStart, ws.LatestBuild.Transition, "expected workspace to be running")
389+
assertLatestTransitionWithNoEventualBuild(t, client, workspace, codersdk.WorkspaceTransitionStart)
427390
}
428391

429392
func TestExecutorWorkspaceAutostopNoWaitChangedMyMind(t *testing.T) {
@@ -451,11 +414,7 @@ func TestExecutorWorkspaceAutostopNoWaitChangedMyMind(t *testing.T) {
451414
}()
452415

453416
// Then: the workspace should still stop - sorry!
454-
<-time.After(5 * time.Second)
455-
ws := mustWorkspace(t, client, workspace.ID)
456-
require.NotEqual(t, workspace.LatestBuild.ID, ws.LatestBuild.ID, "expected a workspace build to occur")
457-
require.Equal(t, codersdk.ProvisionerJobSucceeded, ws.LatestBuild.Job.Status, "expected provisioner job to have succeeded")
458-
require.Equal(t, codersdk.WorkspaceTransitionStop, ws.LatestBuild.Transition, "expected workspace not to be running")
417+
assertLatestTransitionWithEventualBuild(t, client, workspace, codersdk.WorkspaceTransitionStop)
459418
}
460419

461420
func TestExecutorAutostartMultipleOK(t *testing.T) {
@@ -492,23 +451,21 @@ func TestExecutorAutostartMultipleOK(t *testing.T) {
492451
close(tickCh2)
493452
}()
494453

495-
// Then: the workspace should be started
496-
<-time.After(5 * time.Second)
454+
// Then: the workspace should eventually be started
455+
assertLatestTransitionWithEventualBuild(t, client, workspace, codersdk.WorkspaceTransitionStart)
456+
497457
ws := mustWorkspace(t, client, workspace.ID)
498-
require.NotEqual(t, workspace.LatestBuild.ID, ws.LatestBuild.ID, "expected a workspace build to occur")
499-
require.Equal(t, codersdk.ProvisionerJobSucceeded, ws.LatestBuild.Job.Status, "expected provisioner job to have succeeded")
500-
require.Equal(t, codersdk.WorkspaceTransitionStart, ws.LatestBuild.Transition, "expected latest transition to be start")
501458
builds, err := client.WorkspaceBuilds(ctx, codersdk.WorkspaceBuildsRequest{WorkspaceID: ws.ID})
502459
require.NoError(t, err, "fetch list of workspace builds from primary")
503460
// One build to start, one stop transition, and one autostart. No more.
504-
require.Equal(t, codersdk.WorkspaceTransitionStart, builds[0].Transition)
505-
require.Equal(t, codersdk.WorkspaceTransitionStop, builds[1].Transition)
506-
require.Equal(t, codersdk.WorkspaceTransitionStart, builds[2].Transition)
507-
require.Len(t, builds, 3, "unexpected number of builds for workspace from primary")
508-
509-
// Builds are returned most recent first.
510-
require.True(t, builds[0].CreatedAt.After(builds[1].CreatedAt))
511-
require.True(t, builds[1].CreatedAt.After(builds[2].CreatedAt))
461+
if assert.Len(t, builds, 3, "unexpected number of builds for workspace from primary") {
462+
assert.Equal(t, codersdk.WorkspaceTransitionStart, builds[0].Transition)
463+
assert.Equal(t, codersdk.WorkspaceTransitionStop, builds[1].Transition)
464+
assert.Equal(t, codersdk.WorkspaceTransitionStart, builds[2].Transition)
465+
// Builds are returned most recent first.
466+
require.True(t, builds[0].CreatedAt.After(builds[1].CreatedAt))
467+
require.True(t, builds[1].CreatedAt.After(builds[2].CreatedAt))
468+
}
512469
}
513470

514471
func mustProvisionWorkspace(t *testing.T, client *codersdk.Client, mut ...func(*codersdk.CreateWorkspaceRequest)) codersdk.Workspace {
@@ -555,6 +512,34 @@ func mustWorkspace(t *testing.T, client *codersdk.Client, workspaceID uuid.UUID)
555512
return ws
556513
}
557514

515+
func assertLatestTransitionWithEventualBuild(t *testing.T, client *codersdk.Client, workspace codersdk.Workspace, expected codersdk.WorkspaceTransition) {
516+
assert.Eventually(t, func() bool {
517+
ws := mustWorkspace(t, client, workspace.ID)
518+
if ws.LatestBuild.ID == workspace.LatestBuild.ID {
519+
return false
520+
}
521+
if ws.LatestBuild.Job.Status != codersdk.ProvisionerJobSucceeded {
522+
return false
523+
}
524+
// At this point a build has happened. Is it what we want?
525+
return assert.Equal(t, expected, ws.LatestBuild.Transition)
526+
}, 5*time.Second, 25*time.Millisecond)
527+
}
528+
529+
func assertLatestTransitionWithNoEventualBuild(t *testing.T, client *codersdk.Client, workspace codersdk.Workspace, expected codersdk.WorkspaceTransition) {
530+
assert.Never(t, func() bool {
531+
ws := mustWorkspace(t, client, workspace.ID)
532+
if ws.LatestBuild.ID == workspace.LatestBuild.ID {
533+
return false
534+
}
535+
if ws.LatestBuild.Job.Status != codersdk.ProvisionerJobSucceeded {
536+
return false
537+
}
538+
// At this point a build should not have happened. Is the state still as expected?
539+
return assert.Equal(t, expected, ws.LatestBuild.Transition)
540+
}, 5*time.Second, 25*time.Millisecond)
541+
}
542+
558543
func TestMain(m *testing.M) {
559544
goleak.VerifyTestMain(m)
560545
}

0 commit comments

Comments
 (0)