@@ -25,6 +25,12 @@ func TestCalculateAutoStop(t *testing.T) {
25
25
26
26
now := time .Now ()
27
27
28
+ chicago , err := time .LoadLocation ("America/Chicago" )
29
+ require .NoError (t , err , "loading chicago time location" )
30
+
31
+ // pastDateNight is 9:45pm on a wednesday
32
+ pastDateNight := time .Date (2024 , 2 , 14 , 21 , 45 , 0 , 0 , chicago )
33
+
28
34
// Wednesday the 8th of February 2023 at midnight. This date was
29
35
// specifically chosen as it doesn't fall on a applicable week for both
30
36
// fortnightly and triweekly autostop requirements.
@@ -70,8 +76,12 @@ func TestCalculateAutoStop(t *testing.T) {
70
76
t .Log ("saturdayMidnightAfterDstOut" , saturdayMidnightAfterDstOut )
71
77
72
78
cases := []struct {
73
- name string
74
- now time.Time
79
+ name string
80
+ now time.Time
81
+
82
+ wsAutostart string
83
+ templateAutoStart schedule.TemplateAutostartRequirement
84
+
75
85
templateAllowAutostop bool
76
86
templateDefaultTTL time.Duration
77
87
templateAutostopRequirement schedule.TemplateAutostopRequirement
@@ -364,6 +374,115 @@ func TestCalculateAutoStop(t *testing.T) {
364
374
// expectedDeadline is copied from expectedMaxDeadline.
365
375
expectedMaxDeadline : dstOutQuietHoursExpectedTime ,
366
376
},
377
+ {
378
+ // A user expects this workspace to be online from 9am -> 9pm.
379
+ // So if a deadline is going to land in the middle of this range,
380
+ // we should bump it to the end.
381
+ // This is already done on `ActivityBumpWorkspace`, but that requires
382
+ // activity on the workspace.
383
+ name : "AutostopCrossAutostartBorder" ,
384
+ // Starting at 9:45pm, with the autostart at 9am.
385
+ now : pastDateNight ,
386
+ templateAllowAutostop : false ,
387
+ templateDefaultTTL : time .Hour * 12 ,
388
+ workspaceTTL : time .Hour * 12 ,
389
+ // At 9am every morning
390
+ wsAutostart : "CRON_TZ=America/Chicago 0 9 * * *" ,
391
+
392
+ // No quiet hours
393
+ templateAutoStart : schedule.TemplateAutostartRequirement {
394
+ // Just allow all days of the week
395
+ DaysOfWeek : 0b01111111 ,
396
+ },
397
+ templateAutostopRequirement : schedule.TemplateAutostopRequirement {},
398
+ userQuietHoursSchedule : "" ,
399
+
400
+ expectedDeadline : time .Date (pastDateNight .Year (), pastDateNight .Month (), pastDateNight .Day ()+ 1 , 21 , 0 , 0 , 0 , chicago ),
401
+ expectedMaxDeadline : time.Time {},
402
+ errContains : "" ,
403
+ },
404
+ {
405
+ // Same as AutostopCrossAutostartBorder, but just misses the autostart.
406
+ name : "AutostopCrossMissAutostartBorder" ,
407
+ // Starting at 8:45pm, with the autostart at 9am.
408
+ now : time .Date (pastDateNight .Year (), pastDateNight .Month (), pastDateNight .Day (), 20 , 30 , 0 , 0 , chicago ),
409
+ templateAllowAutostop : false ,
410
+ templateDefaultTTL : time .Hour * 12 ,
411
+ workspaceTTL : time .Hour * 12 ,
412
+ // At 9am every morning
413
+ wsAutostart : "CRON_TZ=America/Chicago 0 9 * * *" ,
414
+
415
+ // No quiet hours
416
+ templateAutoStart : schedule.TemplateAutostartRequirement {
417
+ // Just allow all days of the week
418
+ DaysOfWeek : 0b01111111 ,
419
+ },
420
+ templateAutostopRequirement : schedule.TemplateAutostopRequirement {},
421
+ userQuietHoursSchedule : "" ,
422
+
423
+ expectedDeadline : time .Date (pastDateNight .Year (), pastDateNight .Month (), pastDateNight .Day ()+ 1 , 8 , 30 , 0 , 0 , chicago ),
424
+ expectedMaxDeadline : time.Time {},
425
+ errContains : "" ,
426
+ },
427
+ {
428
+ // Same as AutostopCrossAutostartBorderMaxEarlyDeadline with max deadline to limit it.
429
+ // The autostop deadline is before the autostart threshold.
430
+ name : "AutostopCrossAutostartBorderMaxEarlyDeadline" ,
431
+ // Starting at 9:45pm, with the autostart at 9am.
432
+ now : pastDateNight ,
433
+ templateAllowAutostop : false ,
434
+ templateDefaultTTL : time .Hour * 12 ,
435
+ workspaceTTL : time .Hour * 12 ,
436
+ // At 9am every morning
437
+ wsAutostart : "CRON_TZ=America/Chicago 0 9 * * *" ,
438
+
439
+ // No quiet hours
440
+ templateAutoStart : schedule.TemplateAutostartRequirement {
441
+ // Just allow all days of the week
442
+ DaysOfWeek : 0b01111111 ,
443
+ },
444
+ templateAutostopRequirement : schedule.TemplateAutostopRequirement {
445
+ // Autostop every day
446
+ DaysOfWeek : 0b01111111 ,
447
+ Weeks : 0 ,
448
+ },
449
+ // 6am quiet hours
450
+ userQuietHoursSchedule : "CRON_TZ=America/Chicago 0 6 * * *" ,
451
+
452
+ expectedDeadline : time .Date (pastDateNight .Year (), pastDateNight .Month (), pastDateNight .Day ()+ 1 , 6 , 0 , 0 , 0 , chicago ),
453
+ expectedMaxDeadline : time .Date (pastDateNight .Year (), pastDateNight .Month (), pastDateNight .Day ()+ 1 , 6 , 0 , 0 , 0 , chicago ),
454
+ errContains : "" ,
455
+ },
456
+ {
457
+ // Same as AutostopCrossAutostartBorder with max deadline to limit it.
458
+ // The autostop deadline is after autostart threshold.
459
+ // So the deadline is > 12 hours, but stops at the max deadline.
460
+ name : "AutostopCrossAutostartBorderMaxDeadline" ,
461
+ // Starting at 9:45pm, with the autostart at 9am.
462
+ now : pastDateNight ,
463
+ templateAllowAutostop : false ,
464
+ templateDefaultTTL : time .Hour * 12 ,
465
+ workspaceTTL : time .Hour * 12 ,
466
+ // At 9am every morning
467
+ wsAutostart : "CRON_TZ=America/Chicago 0 9 * * *" ,
468
+
469
+ // No quiet hours
470
+ templateAutoStart : schedule.TemplateAutostartRequirement {
471
+ // Just allow all days of the week
472
+ DaysOfWeek : 0b01111111 ,
473
+ },
474
+ templateAutostopRequirement : schedule.TemplateAutostopRequirement {
475
+ // Autostop every day
476
+ DaysOfWeek : 0b01111111 ,
477
+ Weeks : 0 ,
478
+ },
479
+ // 11am quiet hours, yea this is werid case.
480
+ userQuietHoursSchedule : "CRON_TZ=America/Chicago 0 11 * * *" ,
481
+
482
+ expectedDeadline : time .Date (pastDateNight .Year (), pastDateNight .Month (), pastDateNight .Day ()+ 1 , 11 , 0 , 0 , 0 , chicago ),
483
+ expectedMaxDeadline : time .Date (pastDateNight .Year (), pastDateNight .Month (), pastDateNight .Day ()+ 1 , 11 , 0 , 0 , 0 , chicago ),
484
+ errContains : "" ,
485
+ },
367
486
}
368
487
369
488
for _ , c := range cases {
@@ -382,6 +501,7 @@ func TestCalculateAutoStop(t *testing.T) {
382
501
UserAutostopEnabled : c .templateAllowAutostop ,
383
502
DefaultTTL : c .templateDefaultTTL ,
384
503
AutostopRequirement : c .templateAutostopRequirement ,
504
+ AutostartRequirement : c .templateAutoStart ,
385
505
}, nil
386
506
},
387
507
}
@@ -433,11 +553,20 @@ func TestCalculateAutoStop(t *testing.T) {
433
553
Valid : true ,
434
554
}
435
555
}
556
+
557
+ autostart := sql.NullString {}
558
+ if c .wsAutostart != "" {
559
+ autostart = sql.NullString {
560
+ String : c .wsAutostart ,
561
+ Valid : true ,
562
+ }
563
+ }
436
564
workspace := dbgen .Workspace (t , db , database.Workspace {
437
- TemplateID : template .ID ,
438
- OrganizationID : org .ID ,
439
- OwnerID : user .ID ,
440
- Ttl : workspaceTTL ,
565
+ TemplateID : template .ID ,
566
+ OrganizationID : org .ID ,
567
+ OwnerID : user .ID ,
568
+ Ttl : workspaceTTL ,
569
+ AutostartSchedule : autostart ,
441
570
})
442
571
443
572
autostop , err := schedule .CalculateAutostop (ctx , schedule.CalculateAutostopParams {
@@ -446,6 +575,7 @@ func TestCalculateAutoStop(t *testing.T) {
446
575
UserQuietHoursScheduleStore : userQuietHoursScheduleStore ,
447
576
Now : c .now ,
448
577
Workspace : workspace ,
578
+ WorkspaceAutostart : c .wsAutostart ,
449
579
})
450
580
if c .errContains != "" {
451
581
require .Error (t , err )
0 commit comments