github.com/adityamillind98/nomad@v0.11.8/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 msgpackrpc "github.com/hashicorp/net-rpc-msgpackrpc" 10 "github.com/hashicorp/nomad/acl" 11 "github.com/hashicorp/nomad/nomad/mock" 12 "github.com/hashicorp/nomad/nomad/structs" 13 "github.com/hashicorp/nomad/testutil" 14 "github.com/stretchr/testify/assert" 15 ) 16 17 func TestSystemEndpoint_GarbageCollect(t *testing.T) { 18 t.Parallel() 19 20 s1, cleanupS1 := TestServer(t, nil) 21 defer cleanupS1() 22 codec := rpcClient(t, s1) 23 testutil.WaitForLeader(t, s1.RPC) 24 25 // Insert a job that can be GC'd 26 state := s1.fsm.State() 27 job := mock.Job() 28 job.Type = structs.JobTypeBatch 29 job.Stop = true 30 if err := state.UpsertJob(1000, job); err != nil { 31 t.Fatalf("UpsertJob() failed: %v", err) 32 } 33 34 eval := mock.Eval() 35 eval.Status = structs.EvalStatusComplete 36 eval.JobID = job.ID 37 if err := state.UpsertEvals(1001, []*structs.Evaluation{eval}); err != nil { 38 t.Fatalf("UpsertEvals() failed: %v", err) 39 } 40 41 // Make the GC request 42 req := &structs.GenericRequest{ 43 QueryOptions: structs.QueryOptions{ 44 Region: "global", 45 }, 46 } 47 var resp structs.GenericResponse 48 if err := msgpackrpc.CallWithCodec(codec, "System.GarbageCollect", req, &resp); err != nil { 49 t.Fatalf("expect err") 50 } 51 52 testutil.WaitForResult(func() (bool, error) { 53 // Check if the job has been GC'd 54 ws := memdb.NewWatchSet() 55 exist, err := state.JobByID(ws, job.Namespace, job.ID) 56 if err != nil { 57 return false, err 58 } 59 if exist != nil { 60 return false, fmt.Errorf("job %+v wasn't garbage collected", job) 61 } 62 return true, nil 63 }, func(err error) { 64 t.Fatalf("err: %s", err) 65 }) 66 } 67 68 func TestSystemEndpoint_GarbageCollect_ACL(t *testing.T) { 69 t.Parallel() 70 71 s1, root, cleanupS1 := TestACLServer(t, nil) 72 defer cleanupS1() 73 codec := rpcClient(t, s1) 74 assert := assert.New(t) 75 testutil.WaitForLeader(t, s1.RPC) 76 state := s1.fsm.State() 77 78 // Create ACL tokens 79 invalidToken := mock.CreatePolicyAndToken(t, state, 1001, "test-invalid", mock.NodePolicy(acl.PolicyWrite)) 80 81 // Make the GC request 82 req := &structs.GenericRequest{ 83 QueryOptions: structs.QueryOptions{ 84 Region: "global", 85 }, 86 } 87 88 // Try without a token and expect failure 89 { 90 var resp structs.GenericResponse 91 err := msgpackrpc.CallWithCodec(codec, "System.GarbageCollect", req, &resp) 92 assert.NotNil(err) 93 assert.Contains(err.Error(), structs.ErrPermissionDenied.Error()) 94 } 95 96 // Try with an invalid token and expect failure 97 { 98 req.AuthToken = invalidToken.SecretID 99 var resp structs.GenericResponse 100 err := msgpackrpc.CallWithCodec(codec, "System.GarbageCollect", req, &resp) 101 assert.NotNil(err) 102 assert.Contains(err.Error(), structs.ErrPermissionDenied.Error()) 103 } 104 105 // Try with a management token 106 { 107 req.AuthToken = root.SecretID 108 var resp structs.GenericResponse 109 assert.Nil(msgpackrpc.CallWithCodec(codec, "System.GarbageCollect", req, &resp)) 110 } 111 } 112 113 func TestSystemEndpoint_ReconcileSummaries(t *testing.T) { 114 t.Parallel() 115 116 s1, cleanupS1 := TestServer(t, nil) 117 defer cleanupS1() 118 codec := rpcClient(t, s1) 119 testutil.WaitForLeader(t, s1.RPC) 120 121 // Insert a job that can be GC'd 122 state := s1.fsm.State() 123 s1.fsm.State() 124 job := mock.Job() 125 if err := state.UpsertJob(1000, job); err != nil { 126 t.Fatalf("UpsertJob() failed: %v", err) 127 } 128 129 // Delete the job summary 130 state.DeleteJobSummary(1001, job.Namespace, job.ID) 131 132 // Make the GC request 133 req := &structs.GenericRequest{ 134 QueryOptions: structs.QueryOptions{ 135 Region: "global", 136 }, 137 } 138 var resp structs.GenericResponse 139 if err := msgpackrpc.CallWithCodec(codec, "System.ReconcileJobSummaries", req, &resp); err != nil { 140 t.Fatalf("expect err: %v", err) 141 } 142 143 testutil.WaitForResult(func() (bool, error) { 144 // Check if Nomad has reconciled the summary for the job 145 ws := memdb.NewWatchSet() 146 summary, err := state.JobSummaryByID(ws, job.Namespace, job.ID) 147 if err != nil { 148 return false, err 149 } 150 if summary.CreateIndex == 0 || summary.ModifyIndex == 0 { 151 t.Fatalf("create index: %v, modify index: %v", summary.CreateIndex, summary.ModifyIndex) 152 } 153 154 // setting the modifyindex and createindex of the expected summary to 155 // the output so that we can do deep equal 156 expectedSummary := structs.JobSummary{ 157 JobID: job.ID, 158 Namespace: job.Namespace, 159 Summary: map[string]structs.TaskGroupSummary{ 160 "web": { 161 Queued: 10, 162 }, 163 }, 164 ModifyIndex: summary.ModifyIndex, 165 CreateIndex: summary.CreateIndex, 166 } 167 if !reflect.DeepEqual(&expectedSummary, summary) { 168 return false, fmt.Errorf("expected: %v, actual: %v", expectedSummary, summary) 169 } 170 return true, nil 171 }, func(err error) { 172 t.Fatalf("err: %s", err) 173 }) 174 } 175 176 func TestSystemEndpoint_ReconcileJobSummaries_ACL(t *testing.T) { 177 t.Parallel() 178 179 s1, root, cleanupS1 := TestACLServer(t, nil) 180 defer cleanupS1() 181 codec := rpcClient(t, s1) 182 assert := assert.New(t) 183 testutil.WaitForLeader(t, s1.RPC) 184 state := s1.fsm.State() 185 186 // Create ACL tokens 187 invalidToken := mock.CreatePolicyAndToken(t, state, 1001, "test-invalid", mock.NodePolicy(acl.PolicyWrite)) 188 189 // Make the request 190 req := &structs.GenericRequest{ 191 QueryOptions: structs.QueryOptions{ 192 Region: "global", 193 }, 194 } 195 196 // Try without a token and expect failure 197 { 198 var resp structs.GenericResponse 199 err := msgpackrpc.CallWithCodec(codec, "System.ReconcileJobSummaries", req, &resp) 200 assert.NotNil(err) 201 assert.Contains(err.Error(), structs.ErrPermissionDenied.Error()) 202 } 203 204 // Try with an invalid token and expect failure 205 { 206 req.AuthToken = invalidToken.SecretID 207 var resp structs.GenericResponse 208 err := msgpackrpc.CallWithCodec(codec, "System.ReconcileJobSummaries", req, &resp) 209 assert.NotNil(err) 210 assert.Contains(err.Error(), structs.ErrPermissionDenied.Error()) 211 } 212 213 // Try with a management token 214 { 215 req.AuthToken = root.SecretID 216 var resp structs.GenericResponse 217 assert.Nil(msgpackrpc.CallWithCodec(codec, "System.ReconcileJobSummaries", req, &resp)) 218 } 219 }