@@ -16,6 +16,7 @@ import (
16
16
"github.com/coder/coder/codersdk"
17
17
18
18
"github.com/google/uuid"
19
+ "github.com/stretchr/testify/assert"
19
20
"github.com/stretchr/testify/require"
20
21
)
21
22
@@ -49,12 +50,8 @@ func TestExecutorAutostartOK(t *testing.T) {
49
50
close (tickCh )
50
51
}()
51
52
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 )
58
55
}
59
56
60
57
func TestExecutorAutostartTemplateUpdated (t * testing.T ) {
@@ -99,11 +96,8 @@ func TestExecutorAutostartTemplateUpdated(t *testing.T) {
99
96
}()
100
97
101
98
// 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 )
103
100
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" )
107
101
require .Equal (t , workspace .LatestBuild .TemplateVersionID , ws .LatestBuild .TemplateVersionID , "expected workspace build to be using the old template version" )
108
102
}
109
103
@@ -139,10 +133,7 @@ func TestExecutorAutostartAlreadyRunning(t *testing.T) {
139
133
}()
140
134
141
135
// 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 )
146
137
}
147
138
148
139
func TestExecutorAutostartNotEnabled (t * testing.T ) {
@@ -173,10 +164,7 @@ func TestExecutorAutostartNotEnabled(t *testing.T) {
173
164
}()
174
165
175
166
// 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 )
180
168
}
181
169
182
170
func TestExecutorAutostopOK (t * testing.T ) {
@@ -202,11 +190,7 @@ func TestExecutorAutostopOK(t *testing.T) {
202
190
}()
203
191
204
192
// 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 )
210
194
}
211
195
212
196
func TestExecutorAutostopExtend (t * testing.T ) {
@@ -228,8 +212,9 @@ func TestExecutorAutostopExtend(t *testing.T) {
228
212
require .NotZero (t , originalDeadline )
229
213
230
214
// Given: we extend the workspace deadline
215
+ newDeadline := originalDeadline .Add (30 * time .Minute )
231
216
err := client .PutExtendWorkspace (ctx , workspace .ID , codersdk.PutExtendWorkspaceRequest {
232
- Deadline : originalDeadline . Add ( 30 * time . Minute ) ,
217
+ Deadline : newDeadline ,
233
218
})
234
219
require .NoError (t , err , "extend workspace deadline" )
235
220
@@ -238,24 +223,17 @@ func TestExecutorAutostopExtend(t *testing.T) {
238
223
tickCh <- originalDeadline .Add (time .Minute )
239
224
}()
240
225
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 )
246
228
247
229
// When: the autobuild executor ticks after the *new* deadline:
248
230
go func () {
249
- tickCh <- ws . LatestBuild . Deadline .Add (time .Minute )
231
+ tickCh <- newDeadline .Add (time .Minute )
250
232
close (tickCh )
251
233
}()
252
234
253
235
// 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 )
259
237
}
260
238
261
239
func TestExecutorAutostopAlreadyStopped (t * testing.T ) {
@@ -282,11 +260,8 @@ func TestExecutorAutostopAlreadyStopped(t *testing.T) {
282
260
close (tickCh )
283
261
}()
284
262
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 )
290
265
}
291
266
292
267
func TestExecutorAutostopNotEnabled (t * testing.T ) {
@@ -317,10 +292,7 @@ func TestExecutorAutostopNotEnabled(t *testing.T) {
317
292
}()
318
293
319
294
// 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 )
324
296
}
325
297
326
298
func TestExecutorWorkspaceDeleted (t * testing.T ) {
@@ -355,10 +327,7 @@ func TestExecutorWorkspaceDeleted(t *testing.T) {
355
327
}()
356
328
357
329
// 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 )
362
331
}
363
332
364
333
func TestExecutorWorkspaceAutostartTooEarly (t * testing.T ) {
@@ -394,10 +363,7 @@ func TestExecutorWorkspaceAutostartTooEarly(t *testing.T) {
394
363
}()
395
364
396
365
// 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 )
401
367
}
402
368
403
369
func TestExecutorWorkspaceAutostopBeforeDeadline (t * testing.T ) {
@@ -420,10 +386,7 @@ func TestExecutorWorkspaceAutostopBeforeDeadline(t *testing.T) {
420
386
}()
421
387
422
388
// 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 )
427
390
}
428
391
429
392
func TestExecutorWorkspaceAutostopNoWaitChangedMyMind (t * testing.T ) {
@@ -451,11 +414,7 @@ func TestExecutorWorkspaceAutostopNoWaitChangedMyMind(t *testing.T) {
451
414
}()
452
415
453
416
// 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 )
459
418
}
460
419
461
420
func TestExecutorAutostartMultipleOK (t * testing.T ) {
@@ -492,23 +451,21 @@ func TestExecutorAutostartMultipleOK(t *testing.T) {
492
451
close (tickCh2 )
493
452
}()
494
453
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
+
497
457
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" )
501
458
builds , err := client .WorkspaceBuilds (ctx , codersdk.WorkspaceBuildsRequest {WorkspaceID : ws .ID })
502
459
require .NoError (t , err , "fetch list of workspace builds from primary" )
503
460
// 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
+ }
512
469
}
513
470
514
471
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)
555
512
return ws
556
513
}
557
514
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
+
558
543
func TestMain (m * testing.M ) {
559
544
goleak .VerifyTestMain (m )
560
545
}
0 commit comments