@@ -69,6 +69,83 @@ func TestCoreScheduler_EvalGC(t *testing.T) {
69
69
}
70
70
}
71
71
72
+ func TestCoreScheduler_EvalGC_Partial (t * testing.T ) {
73
+ s1 := testServer (t , nil )
74
+ defer s1 .Shutdown ()
75
+ testutil .WaitForLeader (t , s1 .RPC )
76
+
77
+ // Insert "dead" eval
78
+ state := s1 .fsm .State ()
79
+ eval := mock .Eval ()
80
+ eval .Status = structs .EvalStatusComplete
81
+ err := state .UpsertEvals (1000 , []* structs.Evaluation {eval })
82
+ if err != nil {
83
+ t .Fatalf ("err: %v" , err )
84
+ }
85
+
86
+ // Insert "dead" alloc
87
+ alloc := mock .Alloc ()
88
+ alloc .EvalID = eval .ID
89
+ alloc .DesiredStatus = structs .AllocDesiredStatusFailed
90
+ err = state .UpsertAllocs (1001 , []* structs.Allocation {alloc })
91
+ if err != nil {
92
+ t .Fatalf ("err: %v" , err )
93
+ }
94
+
95
+ // Insert "running" alloc
96
+ alloc2 := mock .Alloc ()
97
+ alloc2 .EvalID = eval .ID
98
+ err = state .UpsertAllocs (1002 , []* structs.Allocation {alloc2 })
99
+ if err != nil {
100
+ t .Fatalf ("err: %v" , err )
101
+ }
102
+
103
+ // Update the time tables to make this work
104
+ tt := s1 .fsm .TimeTable ()
105
+ tt .Witness (2000 , time .Now ().UTC ().Add (- 1 * s1 .config .EvalGCThreshold ))
106
+
107
+ // Create a core scheduler
108
+ snap , err := state .Snapshot ()
109
+ if err != nil {
110
+ t .Fatalf ("err: %v" , err )
111
+ }
112
+ core := NewCoreScheduler (s1 , snap )
113
+
114
+ // Attempt the GC
115
+ gc := s1 .coreJobEval (structs .CoreJobEvalGC )
116
+ gc .ModifyIndex = 2000
117
+ err = core .Process (gc )
118
+ if err != nil {
119
+ t .Fatalf ("err: %v" , err )
120
+ }
121
+
122
+ // Should not be gone
123
+ out , err := state .EvalByID (eval .ID )
124
+ if err != nil {
125
+ t .Fatalf ("err: %v" , err )
126
+ }
127
+ if out == nil {
128
+ t .Fatalf ("bad: %v" , out )
129
+ }
130
+
131
+ outA , err := state .AllocByID (alloc2 .ID )
132
+ if err != nil {
133
+ t .Fatalf ("err: %v" , err )
134
+ }
135
+ if outA == nil {
136
+ t .Fatalf ("bad: %v" , outA )
137
+ }
138
+
139
+ // Should be gone
140
+ outB , err := state .AllocByID (alloc .ID )
141
+ if err != nil {
142
+ t .Fatalf ("err: %v" , err )
143
+ }
144
+ if outB != nil {
145
+ t .Fatalf ("bad: %v" , outB )
146
+ }
147
+ }
148
+
72
149
func TestCoreScheduler_EvalGC_Batch_NoAllocs (t * testing.T ) {
73
150
s1 := testServer (t , nil )
74
151
defer s1 .Shutdown ()
@@ -334,6 +411,108 @@ func TestCoreScheduler_NodeGC(t *testing.T) {
334
411
}
335
412
}
336
413
414
+ func TestCoreScheduler_NodeGC_TerminalAllocs (t * testing.T ) {
415
+ s1 := testServer (t , nil )
416
+ defer s1 .Shutdown ()
417
+ testutil .WaitForLeader (t , s1 .RPC )
418
+
419
+ // Insert "dead" node
420
+ state := s1 .fsm .State ()
421
+ node := mock .Node ()
422
+ node .Status = structs .NodeStatusDown
423
+ err := state .UpsertNode (1000 , node )
424
+ if err != nil {
425
+ t .Fatalf ("err: %v" , err )
426
+ }
427
+
428
+ // Insert a terminal alloc on that node
429
+ alloc := mock .Alloc ()
430
+ alloc .DesiredStatus = structs .AllocDesiredStatusStop
431
+ if err := state .UpsertAllocs (1001 , []* structs.Allocation {alloc }); err != nil {
432
+ t .Fatalf ("err: %v" , err )
433
+ }
434
+
435
+ // Update the time tables to make this work
436
+ tt := s1 .fsm .TimeTable ()
437
+ tt .Witness (2000 , time .Now ().UTC ().Add (- 1 * s1 .config .NodeGCThreshold ))
438
+
439
+ // Create a core scheduler
440
+ snap , err := state .Snapshot ()
441
+ if err != nil {
442
+ t .Fatalf ("err: %v" , err )
443
+ }
444
+ core := NewCoreScheduler (s1 , snap )
445
+
446
+ // Attempt the GC
447
+ gc := s1 .coreJobEval (structs .CoreJobNodeGC )
448
+ gc .ModifyIndex = 2000
449
+ err = core .Process (gc )
450
+ if err != nil {
451
+ t .Fatalf ("err: %v" , err )
452
+ }
453
+
454
+ // Should be gone
455
+ out , err := state .NodeByID (node .ID )
456
+ if err != nil {
457
+ t .Fatalf ("err: %v" , err )
458
+ }
459
+ if out != nil {
460
+ t .Fatalf ("bad: %v" , out )
461
+ }
462
+ }
463
+
464
+ func TestCoreScheduler_NodeGC_RunningAllocs (t * testing.T ) {
465
+ s1 := testServer (t , nil )
466
+ defer s1 .Shutdown ()
467
+ testutil .WaitForLeader (t , s1 .RPC )
468
+
469
+ // Insert "dead" node
470
+ state := s1 .fsm .State ()
471
+ node := mock .Node ()
472
+ node .Status = structs .NodeStatusDown
473
+ err := state .UpsertNode (1000 , node )
474
+ if err != nil {
475
+ t .Fatalf ("err: %v" , err )
476
+ }
477
+
478
+ // Insert a running alloc on that node
479
+ alloc := mock .Alloc ()
480
+ alloc .NodeID = node .ID
481
+ alloc .DesiredStatus = structs .AllocDesiredStatusRun
482
+ alloc .ClientStatus = structs .AllocClientStatusRunning
483
+ if err := state .UpsertAllocs (1001 , []* structs.Allocation {alloc }); err != nil {
484
+ t .Fatalf ("err: %v" , err )
485
+ }
486
+
487
+ // Update the time tables to make this work
488
+ tt := s1 .fsm .TimeTable ()
489
+ tt .Witness (2000 , time .Now ().UTC ().Add (- 1 * s1 .config .NodeGCThreshold ))
490
+
491
+ // Create a core scheduler
492
+ snap , err := state .Snapshot ()
493
+ if err != nil {
494
+ t .Fatalf ("err: %v" , err )
495
+ }
496
+ core := NewCoreScheduler (s1 , snap )
497
+
498
+ // Attempt the GC
499
+ gc := s1 .coreJobEval (structs .CoreJobNodeGC )
500
+ gc .ModifyIndex = 2000
501
+ err = core .Process (gc )
502
+ if err != nil {
503
+ t .Fatalf ("err: %v" , err )
504
+ }
505
+
506
+ // Should still be here
507
+ out , err := state .NodeByID (node .ID )
508
+ if err != nil {
509
+ t .Fatalf ("err: %v" , err )
510
+ }
511
+ if out == nil {
512
+ t .Fatalf ("bad: %v" , out )
513
+ }
514
+ }
515
+
337
516
func TestCoreScheduler_NodeGC_Force (t * testing.T ) {
338
517
s1 := testServer (t , nil )
339
518
defer s1 .Shutdown ()
0 commit comments