github.com/ryanslade/nomad@v0.2.4-0.20160128061903-fc95782f2089/nomad/core_sched_test.go (about) 1 package nomad 2 3 import ( 4 "testing" 5 "time" 6 7 "github.com/hashicorp/nomad/nomad/mock" 8 "github.com/hashicorp/nomad/nomad/structs" 9 "github.com/hashicorp/nomad/testutil" 10 ) 11 12 func TestCoreScheduler_EvalGC(t *testing.T) { 13 s1 := testServer(t, nil) 14 defer s1.Shutdown() 15 testutil.WaitForLeader(t, s1.RPC) 16 17 // Insert "dead" eval 18 state := s1.fsm.State() 19 eval := mock.Eval() 20 eval.Status = structs.EvalStatusFailed 21 err := state.UpsertEvals(1000, []*structs.Evaluation{eval}) 22 if err != nil { 23 t.Fatalf("err: %v", err) 24 } 25 26 // Insert "dead" alloc 27 alloc := mock.Alloc() 28 alloc.EvalID = eval.ID 29 alloc.DesiredStatus = structs.AllocDesiredStatusFailed 30 err = state.UpsertAllocs(1001, []*structs.Allocation{alloc}) 31 if err != nil { 32 t.Fatalf("err: %v", err) 33 } 34 35 // Update the time tables to make this work 36 tt := s1.fsm.TimeTable() 37 tt.Witness(2000, time.Now().UTC().Add(-1*s1.config.EvalGCThreshold)) 38 39 // Create a core scheduler 40 snap, err := state.Snapshot() 41 if err != nil { 42 t.Fatalf("err: %v", err) 43 } 44 core := NewCoreScheduler(s1, snap) 45 46 // Attempt the GC 47 gc := s1.coreJobEval(structs.CoreJobEvalGC) 48 gc.ModifyIndex = 2000 49 err = core.Process(gc) 50 if err != nil { 51 t.Fatalf("err: %v", err) 52 } 53 54 // Should be gone 55 out, err := state.EvalByID(eval.ID) 56 if err != nil { 57 t.Fatalf("err: %v", err) 58 } 59 if out != nil { 60 t.Fatalf("bad: %v", out) 61 } 62 63 outA, err := state.AllocByID(alloc.ID) 64 if err != nil { 65 t.Fatalf("err: %v", err) 66 } 67 if outA != nil { 68 t.Fatalf("bad: %v", outA) 69 } 70 } 71 72 func TestCoreScheduler_NodeGC(t *testing.T) { 73 s1 := testServer(t, nil) 74 defer s1.Shutdown() 75 testutil.WaitForLeader(t, s1.RPC) 76 77 // Insert "dead" node 78 state := s1.fsm.State() 79 node := mock.Node() 80 node.Status = structs.NodeStatusDown 81 err := state.UpsertNode(1000, node) 82 if err != nil { 83 t.Fatalf("err: %v", err) 84 } 85 86 // Update the time tables to make this work 87 tt := s1.fsm.TimeTable() 88 tt.Witness(2000, time.Now().UTC().Add(-1*s1.config.NodeGCThreshold)) 89 90 // Create a core scheduler 91 snap, err := state.Snapshot() 92 if err != nil { 93 t.Fatalf("err: %v", err) 94 } 95 core := NewCoreScheduler(s1, snap) 96 97 // Attempt the GC 98 gc := s1.coreJobEval(structs.CoreJobNodeGC) 99 gc.ModifyIndex = 2000 100 err = core.Process(gc) 101 if err != nil { 102 t.Fatalf("err: %v", err) 103 } 104 105 // Should be gone 106 out, err := state.NodeByID(node.ID) 107 if err != nil { 108 t.Fatalf("err: %v", err) 109 } 110 if out != nil { 111 t.Fatalf("bad: %v", out) 112 } 113 } 114 115 func TestCoreScheduler_JobGC(t *testing.T) { 116 tests := []struct { 117 test, evalStatus, allocStatus string 118 shouldExist bool 119 }{ 120 { 121 test: "Terminal", 122 evalStatus: structs.EvalStatusFailed, 123 allocStatus: structs.AllocDesiredStatusFailed, 124 shouldExist: false, 125 }, 126 { 127 test: "Has Alloc", 128 evalStatus: structs.EvalStatusFailed, 129 allocStatus: structs.AllocDesiredStatusRun, 130 shouldExist: true, 131 }, 132 { 133 test: "Has Eval", 134 evalStatus: structs.EvalStatusPending, 135 allocStatus: structs.AllocDesiredStatusFailed, 136 shouldExist: true, 137 }, 138 } 139 140 for _, test := range tests { 141 s1 := testServer(t, nil) 142 defer s1.Shutdown() 143 testutil.WaitForLeader(t, s1.RPC) 144 145 // Insert job. 146 state := s1.fsm.State() 147 job := mock.Job() 148 job.GC = true 149 err := state.UpsertJob(1000, job) 150 if err != nil { 151 t.Fatalf("test(%s) err: %v", test.test, err) 152 } 153 154 // Insert eval 155 eval := mock.Eval() 156 eval.JobID = job.ID 157 eval.Status = test.evalStatus 158 err = state.UpsertEvals(1001, []*structs.Evaluation{eval}) 159 if err != nil { 160 t.Fatalf("test(%s) err: %v", test.test, err) 161 } 162 163 // Insert alloc 164 alloc := mock.Alloc() 165 alloc.JobID = job.ID 166 alloc.EvalID = eval.ID 167 alloc.DesiredStatus = test.allocStatus 168 err = state.UpsertAllocs(1002, []*structs.Allocation{alloc}) 169 if err != nil { 170 t.Fatalf("test(%s) err: %v", test.test, err) 171 } 172 173 // Update the time tables to make this work 174 tt := s1.fsm.TimeTable() 175 tt.Witness(2000, time.Now().UTC().Add(-1*s1.config.JobGCThreshold)) 176 177 // Create a core scheduler 178 snap, err := state.Snapshot() 179 if err != nil { 180 t.Fatalf("test(%s) err: %v", test.test, err) 181 } 182 core := NewCoreScheduler(s1, snap) 183 184 // Attempt the GC 185 gc := s1.coreJobEval(structs.CoreJobJobGC) 186 gc.ModifyIndex = 2000 187 err = core.Process(gc) 188 if err != nil { 189 t.Fatalf("test(%s) err: %v", test.test, err) 190 } 191 192 // Should still exist 193 out, err := state.JobByID(job.ID) 194 if err != nil { 195 t.Fatalf("test(%s) err: %v", test.test, err) 196 } 197 if (test.shouldExist && out == nil) || (!test.shouldExist && out != nil) { 198 t.Fatalf("test(%s) bad: %v", test.test, out) 199 } 200 201 outE, err := state.EvalByID(eval.ID) 202 if err != nil { 203 t.Fatalf("test(%s) err: %v", test.test, err) 204 } 205 if (test.shouldExist && outE == nil) || (!test.shouldExist && outE != nil) { 206 t.Fatalf("test(%s) bad: %v", test.test, out) 207 } 208 209 outA, err := state.AllocByID(alloc.ID) 210 if err != nil { 211 t.Fatalf("test(%s) err: %v", test.test, err) 212 } 213 if (test.shouldExist && outA == nil) || (!test.shouldExist && outA != nil) { 214 t.Fatalf("test(%s) bad: %v", test.test, outA) 215 } 216 } 217 }