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  }