github.com/jrxfive/nomad@v0.6.1-0.20170802162750-1fef470e89bf/nomad/system_endpoint_test.go (about) 1 package nomad 2 3 import ( 4 "fmt" 5 "reflect" 6 "testing" 7 8 memdb "github.com/hashicorp/go-memdb" 9 "github.com/hashicorp/net-rpc-msgpackrpc" 10 "github.com/hashicorp/nomad/nomad/mock" 11 "github.com/hashicorp/nomad/nomad/structs" 12 "github.com/hashicorp/nomad/testutil" 13 ) 14 15 func TestSystemEndpoint_GarbageCollect(t *testing.T) { 16 t.Parallel() 17 s1 := testServer(t, nil) 18 defer s1.Shutdown() 19 codec := rpcClient(t, s1) 20 testutil.WaitForLeader(t, s1.RPC) 21 22 // Insert a job that can be GC'd 23 state := s1.fsm.State() 24 job := mock.Job() 25 job.Type = structs.JobTypeBatch 26 job.Stop = true 27 if err := state.UpsertJob(1000, job); err != nil { 28 t.Fatalf("UpsertJob() failed: %v", err) 29 } 30 31 eval := mock.Eval() 32 eval.Status = structs.EvalStatusComplete 33 eval.JobID = job.ID 34 if err := state.UpsertEvals(1001, []*structs.Evaluation{eval}); err != nil { 35 t.Fatalf("UpsertEvals() failed: %v", err) 36 } 37 38 // Make the GC request 39 req := &structs.GenericRequest{ 40 QueryOptions: structs.QueryOptions{ 41 Region: "global", 42 }, 43 } 44 var resp structs.GenericResponse 45 if err := msgpackrpc.CallWithCodec(codec, "System.GarbageCollect", req, &resp); err != nil { 46 t.Fatalf("expect err") 47 } 48 49 testutil.WaitForResult(func() (bool, error) { 50 // Check if the job has been GC'd 51 ws := memdb.NewWatchSet() 52 exist, err := state.JobByID(ws, job.ID) 53 if err != nil { 54 return false, err 55 } 56 if exist != nil { 57 return false, fmt.Errorf("job %+v wasn't garbage collected", job) 58 } 59 return true, nil 60 }, func(err error) { 61 t.Fatalf("err: %s", err) 62 }) 63 } 64 65 func TestSystemEndpoint_ReconcileSummaries(t *testing.T) { 66 t.Parallel() 67 s1 := testServer(t, nil) 68 defer s1.Shutdown() 69 codec := rpcClient(t, s1) 70 testutil.WaitForLeader(t, s1.RPC) 71 72 // Insert a job that can be GC'd 73 state := s1.fsm.State() 74 s1.fsm.State() 75 job := mock.Job() 76 if err := state.UpsertJob(1000, job); err != nil { 77 t.Fatalf("UpsertJob() failed: %v", err) 78 } 79 80 // Delete the job summary 81 state.DeleteJobSummary(1001, job.ID) 82 83 // Make the GC request 84 req := &structs.GenericRequest{ 85 QueryOptions: structs.QueryOptions{ 86 Region: "global", 87 }, 88 } 89 var resp structs.GenericResponse 90 if err := msgpackrpc.CallWithCodec(codec, "System.ReconcileJobSummaries", req, &resp); err != nil { 91 t.Fatalf("expect err: %v", err) 92 } 93 94 testutil.WaitForResult(func() (bool, error) { 95 // Check if Nomad has reconciled the summary for the job 96 ws := memdb.NewWatchSet() 97 summary, err := state.JobSummaryByID(ws, job.ID) 98 if err != nil { 99 return false, err 100 } 101 if summary.CreateIndex == 0 || summary.ModifyIndex == 0 { 102 t.Fatalf("create index: %v, modify index: %v", summary.CreateIndex, summary.ModifyIndex) 103 } 104 105 // setting the modifyindex and createindex of the expected summary to 106 // the output so that we can do deep equal 107 expectedSummary := structs.JobSummary{ 108 JobID: job.ID, 109 Summary: map[string]structs.TaskGroupSummary{ 110 "web": structs.TaskGroupSummary{ 111 Queued: 10, 112 }, 113 }, 114 ModifyIndex: summary.ModifyIndex, 115 CreateIndex: summary.CreateIndex, 116 } 117 if !reflect.DeepEqual(&expectedSummary, summary) { 118 return false, fmt.Errorf("expected: %v, actual: %v", expectedSummary, summary) 119 } 120 return true, nil 121 }, func(err error) { 122 t.Fatalf("err: %s", err) 123 }) 124 }