From e2438aee3530e8ab27ac2505cd61ebea06dbf47c Mon Sep 17 00:00:00 2001 From: Armon Dadgar Date: Sun, 6 Sep 2015 12:32:22 -0700 Subject: [PATCH] http/job: complete the job endpoints --- command/agent/job_endpoint.go | 43 ++++++++- command/agent/job_endpoint_test.go | 146 +++++++++++++++++++++++++++++ 2 files changed, 186 insertions(+), 3 deletions(-) diff --git a/command/agent/job_endpoint.go b/command/agent/job_endpoint.go index f1551dc04..cdbb6ac7e 100644 --- a/command/agent/job_endpoint.go +++ b/command/agent/job_endpoint.go @@ -19,7 +19,18 @@ func (s *HTTPServer) JobsRequest(resp http.ResponseWriter, req *http.Request) (i } func (s *HTTPServer) jobListRequest(resp http.ResponseWriter, req *http.Request) (interface{}, error) { - return nil, nil + args := structs.JobListRequest{} + if s.parse(resp, req, &args.Region, &args.QueryOptions) { + return nil, nil + } + + var out structs.JobListResponse + if err := s.agent.RPC("Job.List", &args, &out); err != nil { + return nil, err + } + + setMeta(resp, &out.QueryMeta) + return out.Jobs, nil } func (s *HTTPServer) JobSpecificRequest(resp http.ResponseWriter, req *http.Request) (interface{}, error) { @@ -62,7 +73,20 @@ func (s *HTTPServer) jobAllocations(resp http.ResponseWriter, req *http.Request, if req.Method != "GET" { return nil, CodedError(405, ErrInvalidMethod) } - return nil, nil + args := structs.JobSpecificRequest{ + JobID: jobName, + } + if s.parse(resp, req, &args.Region, &args.QueryOptions) { + return nil, nil + } + + var out structs.JobAllocationsResponse + if err := s.agent.RPC("Job.Allocations", &args, &out); err != nil { + return nil, err + } + + setMeta(resp, &out.QueryMeta) + return out.Allocations, nil } func (s *HTTPServer) jobEvaluations(resp http.ResponseWriter, req *http.Request, @@ -70,7 +94,20 @@ func (s *HTTPServer) jobEvaluations(resp http.ResponseWriter, req *http.Request, if req.Method != "GET" { return nil, CodedError(405, ErrInvalidMethod) } - return nil, nil + args := structs.JobSpecificRequest{ + JobID: jobName, + } + if s.parse(resp, req, &args.Region, &args.QueryOptions) { + return nil, nil + } + + var out structs.JobEvaluationsResponse + if err := s.agent.RPC("Job.Evaluations", &args, &out); err != nil { + return nil, err + } + + setMeta(resp, &out.QueryMeta) + return out.Evaluations, nil } func (s *HTTPServer) jobCRUD(resp http.ResponseWriter, req *http.Request, diff --git a/command/agent/job_endpoint_test.go b/command/agent/job_endpoint_test.go index 83c487351..9ab18a6be 100644 --- a/command/agent/job_endpoint_test.go +++ b/command/agent/job_endpoint_test.go @@ -9,6 +9,53 @@ import ( "github.com/hashicorp/nomad/nomad/structs" ) +func TestHTTP_JobsList(t *testing.T) { + httpTest(t, nil, func(s *TestServer) { + for i := 0; i < 3; i++ { + // Create the job + job := mock.Job() + args := structs.JobRegisterRequest{ + Job: job, + WriteRequest: structs.WriteRequest{Region: "region1"}, + } + var resp structs.JobRegisterResponse + if err := s.Agent.RPC("Job.Register", &args, &resp); err != nil { + t.Fatalf("err: %v", err) + } + } + + // Make the HTTP request + req, err := http.NewRequest("GET", "/v1/jobs", nil) + if err != nil { + t.Fatalf("err: %v", err) + } + respW := httptest.NewRecorder() + + // Make the request + obj, err := s.Server.JobsRequest(respW, req) + if err != nil { + t.Fatalf("err: %v", err) + } + + // Check for the index + if respW.HeaderMap.Get("X-Nomad-Index") == "" { + t.Fatalf("missing index") + } + if respW.HeaderMap.Get("X-Nomad-KnownLeader") != "true" { + t.Fatalf("missing known leader") + } + if respW.HeaderMap.Get("X-Nomad-LastContact") == "" { + t.Fatalf("missing last contact") + } + + // Check the job + j := obj.([]*structs.JobListStub) + if len(j) != 3 { + t.Fatalf("bad: %#v", j) + } + }) +} + func TestHTTP_JobsRegister(t *testing.T) { httpTest(t, nil, func(s *TestServer) { // Create the job @@ -244,3 +291,102 @@ func TestHTTP_JobForceEvaluate(t *testing.T) { } }) } + +func TestHTTP_JobAllocations(t *testing.T) { + httpTest(t, nil, func(s *TestServer) { + // Create the job + job := mock.Job() + args := structs.JobRegisterRequest{ + Job: job, + WriteRequest: structs.WriteRequest{Region: "region1"}, + } + var resp structs.JobRegisterResponse + if err := s.Agent.RPC("Job.Register", &args, &resp); err != nil { + t.Fatalf("err: %v", err) + } + + // Make the HTTP request + req, err := http.NewRequest("GET", "/v1/job/"+job.ID+"/evaluations", nil) + if err != nil { + t.Fatalf("err: %v", err) + } + respW := httptest.NewRecorder() + + // Make the request + obj, err := s.Server.JobSpecificRequest(respW, req) + if err != nil { + t.Fatalf("err: %v", err) + } + + // Check the response + evals := obj.([]*structs.Evaluation) + if len(evals) != 1 || evals[0].ID != resp.EvalID { + t.Fatalf("bad: %v", evals) + } + + // Check for the index + if respW.HeaderMap.Get("X-Nomad-Index") == "" { + t.Fatalf("missing index") + } + if respW.HeaderMap.Get("X-Nomad-KnownLeader") != "true" { + t.Fatalf("missing known leader") + } + if respW.HeaderMap.Get("X-Nomad-LastContact") == "" { + t.Fatalf("missing last contact") + } + }) +} + +func TestHTTP_JobEvaluations(t *testing.T) { + httpTest(t, nil, func(s *TestServer) { + // Create the job + job := mock.Job() + args := structs.JobRegisterRequest{ + Job: job, + WriteRequest: structs.WriteRequest{Region: "region1"}, + } + var resp structs.JobRegisterResponse + if err := s.Agent.RPC("Job.Register", &args, &resp); err != nil { + t.Fatalf("err: %v", err) + } + + // Directly manipulate the state + state := s.Agent.server.State() + alloc1 := mock.Alloc() + alloc1.JobID = job.ID + err := state.UpdateAllocations(1000, []*structs.Allocation{alloc1}) + if err != nil { + t.Fatalf("err: %v", err) + } + + // Make the HTTP request + req, err := http.NewRequest("GET", "/v1/job/"+job.ID+"/allocations", nil) + if err != nil { + t.Fatalf("err: %v", err) + } + respW := httptest.NewRecorder() + + // Make the request + obj, err := s.Server.JobSpecificRequest(respW, req) + if err != nil { + t.Fatalf("err: %v", err) + } + + // Check the response + allocs := obj.([]*structs.Allocation) + if len(allocs) != 1 && allocs[0].ID != alloc1.ID { + t.Fatalf("bad: %v", allocs) + } + + // Check for the index + if respW.HeaderMap.Get("X-Nomad-Index") == "" { + t.Fatalf("missing index") + } + if respW.HeaderMap.Get("X-Nomad-KnownLeader") != "true" { + t.Fatalf("missing known leader") + } + if respW.HeaderMap.Get("X-Nomad-LastContact") == "" { + t.Fatalf("missing last contact") + } + }) +}