github.com/kardianos/nomad@v0.1.3-0.20151022182107-b13df73ee850/command/agent/job_endpoint_test.go (about) 1 package agent 2 3 import ( 4 "net/http" 5 "net/http/httptest" 6 "testing" 7 8 "github.com/hashicorp/nomad/nomad/mock" 9 "github.com/hashicorp/nomad/nomad/structs" 10 ) 11 12 func TestHTTP_JobsList(t *testing.T) { 13 httpTest(t, nil, func(s *TestServer) { 14 for i := 0; i < 3; i++ { 15 // Create the job 16 job := mock.Job() 17 args := structs.JobRegisterRequest{ 18 Job: job, 19 WriteRequest: structs.WriteRequest{Region: "global"}, 20 } 21 var resp structs.JobRegisterResponse 22 if err := s.Agent.RPC("Job.Register", &args, &resp); err != nil { 23 t.Fatalf("err: %v", err) 24 } 25 } 26 27 // Make the HTTP request 28 req, err := http.NewRequest("GET", "/v1/jobs", nil) 29 if err != nil { 30 t.Fatalf("err: %v", err) 31 } 32 respW := httptest.NewRecorder() 33 34 // Make the request 35 obj, err := s.Server.JobsRequest(respW, req) 36 if err != nil { 37 t.Fatalf("err: %v", err) 38 } 39 40 // Check for the index 41 if respW.HeaderMap.Get("X-Nomad-Index") == "" { 42 t.Fatalf("missing index") 43 } 44 if respW.HeaderMap.Get("X-Nomad-KnownLeader") != "true" { 45 t.Fatalf("missing known leader") 46 } 47 if respW.HeaderMap.Get("X-Nomad-LastContact") == "" { 48 t.Fatalf("missing last contact") 49 } 50 51 // Check the job 52 j := obj.([]*structs.JobListStub) 53 if len(j) != 3 { 54 t.Fatalf("bad: %#v", j) 55 } 56 }) 57 } 58 59 func TestHTTP_JobsRegister(t *testing.T) { 60 httpTest(t, nil, func(s *TestServer) { 61 // Create the job 62 job := mock.Job() 63 args := structs.JobRegisterRequest{ 64 Job: job, 65 WriteRequest: structs.WriteRequest{Region: "global"}, 66 } 67 buf := encodeReq(args) 68 69 // Make the HTTP request 70 req, err := http.NewRequest("PUT", "/v1/jobs", buf) 71 if err != nil { 72 t.Fatalf("err: %v", err) 73 } 74 respW := httptest.NewRecorder() 75 76 // Make the request 77 obj, err := s.Server.JobsRequest(respW, req) 78 if err != nil { 79 t.Fatalf("err: %v", err) 80 } 81 82 // Check the response 83 dereg := obj.(structs.JobRegisterResponse) 84 if dereg.EvalID == "" { 85 t.Fatalf("bad: %v", dereg) 86 } 87 88 // Check for the index 89 if respW.HeaderMap.Get("X-Nomad-Index") == "" { 90 t.Fatalf("missing index") 91 } 92 93 // Check the job is registered 94 getReq := structs.JobSpecificRequest{ 95 JobID: job.ID, 96 QueryOptions: structs.QueryOptions{Region: "global"}, 97 } 98 var getResp structs.SingleJobResponse 99 if err := s.Agent.RPC("Job.GetJob", &getReq, &getResp); err != nil { 100 t.Fatalf("err: %v", err) 101 } 102 103 if getResp.Job == nil { 104 t.Fatalf("job does not exist") 105 } 106 }) 107 } 108 109 func TestHTTP_JobQuery(t *testing.T) { 110 httpTest(t, nil, func(s *TestServer) { 111 // Create the job 112 job := mock.Job() 113 args := structs.JobRegisterRequest{ 114 Job: job, 115 WriteRequest: structs.WriteRequest{Region: "global"}, 116 } 117 var resp structs.JobRegisterResponse 118 if err := s.Agent.RPC("Job.Register", &args, &resp); err != nil { 119 t.Fatalf("err: %v", err) 120 } 121 122 // Make the HTTP request 123 req, err := http.NewRequest("GET", "/v1/job/"+job.ID, nil) 124 if err != nil { 125 t.Fatalf("err: %v", err) 126 } 127 respW := httptest.NewRecorder() 128 129 // Make the request 130 obj, err := s.Server.JobSpecificRequest(respW, req) 131 if err != nil { 132 t.Fatalf("err: %v", err) 133 } 134 135 // Check for the index 136 if respW.HeaderMap.Get("X-Nomad-Index") == "" { 137 t.Fatalf("missing index") 138 } 139 if respW.HeaderMap.Get("X-Nomad-KnownLeader") != "true" { 140 t.Fatalf("missing known leader") 141 } 142 if respW.HeaderMap.Get("X-Nomad-LastContact") == "" { 143 t.Fatalf("missing last contact") 144 } 145 146 // Check the job 147 j := obj.(*structs.Job) 148 if j.ID != job.ID { 149 t.Fatalf("bad: %#v", j) 150 } 151 }) 152 } 153 154 func TestHTTP_JobUpdate(t *testing.T) { 155 httpTest(t, nil, func(s *TestServer) { 156 // Create the job 157 job := mock.Job() 158 args := structs.JobRegisterRequest{ 159 Job: job, 160 WriteRequest: structs.WriteRequest{Region: "global"}, 161 } 162 buf := encodeReq(args) 163 164 // Make the HTTP request 165 req, err := http.NewRequest("PUT", "/v1/job/"+job.ID, buf) 166 if err != nil { 167 t.Fatalf("err: %v", err) 168 } 169 respW := httptest.NewRecorder() 170 171 // Make the request 172 obj, err := s.Server.JobSpecificRequest(respW, req) 173 if err != nil { 174 t.Fatalf("err: %v", err) 175 } 176 177 // Check the response 178 dereg := obj.(structs.JobRegisterResponse) 179 if dereg.EvalID == "" { 180 t.Fatalf("bad: %v", dereg) 181 } 182 183 // Check for the index 184 if respW.HeaderMap.Get("X-Nomad-Index") == "" { 185 t.Fatalf("missing index") 186 } 187 188 // Check the job is registered 189 getReq := structs.JobSpecificRequest{ 190 JobID: job.ID, 191 QueryOptions: structs.QueryOptions{Region: "global"}, 192 } 193 var getResp structs.SingleJobResponse 194 if err := s.Agent.RPC("Job.GetJob", &getReq, &getResp); err != nil { 195 t.Fatalf("err: %v", err) 196 } 197 198 if getResp.Job == nil { 199 t.Fatalf("job does not exist") 200 } 201 }) 202 } 203 204 func TestHTTP_JobDelete(t *testing.T) { 205 httpTest(t, nil, func(s *TestServer) { 206 // Create the job 207 job := mock.Job() 208 args := structs.JobRegisterRequest{ 209 Job: job, 210 WriteRequest: structs.WriteRequest{Region: "global"}, 211 } 212 var resp structs.JobRegisterResponse 213 if err := s.Agent.RPC("Job.Register", &args, &resp); err != nil { 214 t.Fatalf("err: %v", err) 215 } 216 217 // Make the HTTP request 218 req, err := http.NewRequest("DELETE", "/v1/job/"+job.ID, nil) 219 if err != nil { 220 t.Fatalf("err: %v", err) 221 } 222 respW := httptest.NewRecorder() 223 224 // Make the request 225 obj, err := s.Server.JobSpecificRequest(respW, req) 226 if err != nil { 227 t.Fatalf("err: %v", err) 228 } 229 230 // Check the response 231 dereg := obj.(structs.JobDeregisterResponse) 232 if dereg.EvalID == "" { 233 t.Fatalf("bad: %v", dereg) 234 } 235 236 // Check for the index 237 if respW.HeaderMap.Get("X-Nomad-Index") == "" { 238 t.Fatalf("missing index") 239 } 240 241 // Check the job is gone 242 getReq := structs.JobSpecificRequest{ 243 JobID: job.ID, 244 QueryOptions: structs.QueryOptions{Region: "global"}, 245 } 246 var getResp structs.SingleJobResponse 247 if err := s.Agent.RPC("Job.GetJob", &getReq, &getResp); err != nil { 248 t.Fatalf("err: %v", err) 249 } 250 if getResp.Job != nil { 251 t.Fatalf("job still exists") 252 } 253 }) 254 } 255 256 func TestHTTP_JobForceEvaluate(t *testing.T) { 257 httpTest(t, nil, func(s *TestServer) { 258 // Create the job 259 job := mock.Job() 260 args := structs.JobRegisterRequest{ 261 Job: job, 262 WriteRequest: structs.WriteRequest{Region: "global"}, 263 } 264 var resp structs.JobRegisterResponse 265 if err := s.Agent.RPC("Job.Register", &args, &resp); err != nil { 266 t.Fatalf("err: %v", err) 267 } 268 269 // Make the HTTP request 270 req, err := http.NewRequest("POST", "/v1/job/"+job.ID+"/evaluate", nil) 271 if err != nil { 272 t.Fatalf("err: %v", err) 273 } 274 respW := httptest.NewRecorder() 275 276 // Make the request 277 obj, err := s.Server.JobSpecificRequest(respW, req) 278 if err != nil { 279 t.Fatalf("err: %v", err) 280 } 281 282 // Check the response 283 reg := obj.(structs.JobRegisterResponse) 284 if reg.EvalID == "" { 285 t.Fatalf("bad: %v", reg) 286 } 287 288 // Check for the index 289 if respW.HeaderMap.Get("X-Nomad-Index") == "" { 290 t.Fatalf("missing index") 291 } 292 }) 293 } 294 295 func TestHTTP_JobEvaluations(t *testing.T) { 296 httpTest(t, nil, func(s *TestServer) { 297 // Create the job 298 job := mock.Job() 299 args := structs.JobRegisterRequest{ 300 Job: job, 301 WriteRequest: structs.WriteRequest{Region: "global"}, 302 } 303 var resp structs.JobRegisterResponse 304 if err := s.Agent.RPC("Job.Register", &args, &resp); err != nil { 305 t.Fatalf("err: %v", err) 306 } 307 308 // Make the HTTP request 309 req, err := http.NewRequest("GET", "/v1/job/"+job.ID+"/evaluations", nil) 310 if err != nil { 311 t.Fatalf("err: %v", err) 312 } 313 respW := httptest.NewRecorder() 314 315 // Make the request 316 obj, err := s.Server.JobSpecificRequest(respW, req) 317 if err != nil { 318 t.Fatalf("err: %v", err) 319 } 320 321 // Check the response 322 evals := obj.([]*structs.Evaluation) 323 if len(evals) != 1 || evals[0].ID != resp.EvalID { 324 t.Fatalf("bad: %v", evals) 325 } 326 327 // Check for the index 328 if respW.HeaderMap.Get("X-Nomad-Index") == "" { 329 t.Fatalf("missing index") 330 } 331 if respW.HeaderMap.Get("X-Nomad-KnownLeader") != "true" { 332 t.Fatalf("missing known leader") 333 } 334 if respW.HeaderMap.Get("X-Nomad-LastContact") == "" { 335 t.Fatalf("missing last contact") 336 } 337 }) 338 } 339 340 func TestHTTP_JobAllocations(t *testing.T) { 341 httpTest(t, nil, func(s *TestServer) { 342 // Create the job 343 job := mock.Job() 344 args := structs.JobRegisterRequest{ 345 Job: job, 346 WriteRequest: structs.WriteRequest{Region: "global"}, 347 } 348 var resp structs.JobRegisterResponse 349 if err := s.Agent.RPC("Job.Register", &args, &resp); err != nil { 350 t.Fatalf("err: %v", err) 351 } 352 353 // Directly manipulate the state 354 state := s.Agent.server.State() 355 alloc1 := mock.Alloc() 356 alloc1.JobID = job.ID 357 err := state.UpsertAllocs(1000, []*structs.Allocation{alloc1}) 358 if err != nil { 359 t.Fatalf("err: %v", err) 360 } 361 362 // Make the HTTP request 363 req, err := http.NewRequest("GET", "/v1/job/"+job.ID+"/allocations", nil) 364 if err != nil { 365 t.Fatalf("err: %v", err) 366 } 367 respW := httptest.NewRecorder() 368 369 // Make the request 370 obj, err := s.Server.JobSpecificRequest(respW, req) 371 if err != nil { 372 t.Fatalf("err: %v", err) 373 } 374 375 // Check the response 376 allocs := obj.([]*structs.AllocListStub) 377 if len(allocs) != 1 && allocs[0].ID != alloc1.ID { 378 t.Fatalf("bad: %v", allocs) 379 } 380 381 // Check for the index 382 if respW.HeaderMap.Get("X-Nomad-Index") == "" { 383 t.Fatalf("missing index") 384 } 385 if respW.HeaderMap.Get("X-Nomad-KnownLeader") != "true" { 386 t.Fatalf("missing known leader") 387 } 388 if respW.HeaderMap.Get("X-Nomad-LastContact") == "" { 389 t.Fatalf("missing last contact") 390 } 391 }) 392 }