github.com/anth0d/nomad@v0.0.0-20221214183521-ae3a0a2cad06/command/agent/deployment_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/ci"
     9  	"github.com/hashicorp/nomad/nomad/mock"
    10  	"github.com/hashicorp/nomad/nomad/structs"
    11  	"github.com/stretchr/testify/assert"
    12  )
    13  
    14  func TestHTTP_DeploymentList(t *testing.T) {
    15  	ci.Parallel(t)
    16  	assert := assert.New(t)
    17  	httpTest(t, nil, func(s *TestAgent) {
    18  		// Directly manipulate the state
    19  		state := s.Agent.server.State()
    20  		d1 := mock.Deployment()
    21  		d2 := mock.Deployment()
    22  		assert.Nil(state.UpsertDeployment(999, d1), "UpsertDeployment")
    23  		assert.Nil(state.UpsertDeployment(1000, d2), "UpsertDeployment")
    24  
    25  		// Make the HTTP request
    26  		req, err := http.NewRequest("GET", "/v1/deployments", nil)
    27  		assert.Nil(err, "HTTP Request")
    28  		respW := httptest.NewRecorder()
    29  
    30  		// Make the request
    31  		obj, err := s.Server.DeploymentsRequest(respW, req)
    32  		assert.Nil(err, "Deployment Request")
    33  
    34  		// Check for the index
    35  		assert.NotZero(respW.Result().Header.Get("X-Nomad-Index"), "missing index")
    36  		assert.Equal("true", respW.Result().Header.Get("X-Nomad-KnownLeader"), "missing known leader")
    37  		assert.NotZero(respW.Result().Header.Get("X-Nomad-LastContact"), "missing last contact")
    38  
    39  		// Check the deployments
    40  		deploys := obj.([]*structs.Deployment)
    41  		assert.Len(deploys, 2, "Deployments")
    42  	})
    43  }
    44  
    45  func TestHTTP_DeploymentPrefixList(t *testing.T) {
    46  	ci.Parallel(t)
    47  	assert := assert.New(t)
    48  	httpTest(t, nil, func(s *TestAgent) {
    49  		// Directly manipulate the state
    50  		state := s.Agent.server.State()
    51  		d1 := mock.Deployment()
    52  		d1.ID = "aaabbbbb-e8f7-fd38-c855-ab94ceb89706"
    53  		d2 := mock.Deployment()
    54  		d2.ID = "aaabbbbb-e8f7-fd38-c855-ab94ceb89706"
    55  		assert.Nil(state.UpsertDeployment(999, d1), "UpsertDeployment")
    56  		assert.Nil(state.UpsertDeployment(1000, d2), "UpsertDeployment")
    57  
    58  		// Make the HTTP request
    59  		req, err := http.NewRequest("GET", "/v1/deployments?prefix=aaab", nil)
    60  		assert.Nil(err, "HTTP Request")
    61  		respW := httptest.NewRecorder()
    62  
    63  		// Make the request
    64  		obj, err := s.Server.DeploymentsRequest(respW, req)
    65  		assert.Nil(err, "Deployment Request")
    66  
    67  		// Check for the index
    68  		assert.NotZero(respW.Result().Header.Get("X-Nomad-Index"), "missing index")
    69  		assert.Equal("true", respW.Result().Header.Get("X-Nomad-KnownLeader"), "missing known leader")
    70  		assert.NotZero(respW.Result().Header.Get("X-Nomad-LastContact"), "missing last contact")
    71  
    72  		// Check the deployments
    73  		deploys := obj.([]*structs.Deployment)
    74  		assert.Len(deploys, 1, "Deployments")
    75  		assert.Equal(d1.ID, deploys[0].ID, "Wrong Deployment")
    76  	})
    77  }
    78  
    79  func TestHTTP_DeploymentAllocations(t *testing.T) {
    80  	ci.Parallel(t)
    81  	assert := assert.New(t)
    82  	httpTest(t, nil, func(s *TestAgent) {
    83  		// Directly manipulate the state
    84  		state := s.Agent.server.State()
    85  		j := mock.Job()
    86  		d := mock.Deployment()
    87  		d.JobID = j.ID
    88  		a1 := mock.Alloc()
    89  		a1.JobID = j.ID
    90  		a1.DeploymentID = d.ID
    91  
    92  		testEvent := structs.NewTaskEvent(structs.TaskSiblingFailed)
    93  		var events1 []*structs.TaskEvent
    94  		events1 = append(events1, testEvent)
    95  		taskState := &structs.TaskState{Events: events1}
    96  		a1.TaskStates = make(map[string]*structs.TaskState)
    97  		a1.TaskStates["test"] = taskState
    98  
    99  		a2 := mock.Alloc()
   100  		a2.JobID = j.ID
   101  		a2.DeploymentID = d.ID
   102  
   103  		// Create a test event
   104  		testEvent2 := structs.NewTaskEvent(structs.TaskSiblingFailed)
   105  		var events2 []*structs.TaskEvent
   106  		events2 = append(events2, testEvent2)
   107  		taskState2 := &structs.TaskState{Events: events2}
   108  		a2.TaskStates = make(map[string]*structs.TaskState)
   109  		a2.TaskStates["test"] = taskState2
   110  
   111  		assert.Nil(state.UpsertJob(structs.MsgTypeTestSetup, 998, j), "UpsertJob")
   112  		assert.Nil(state.UpsertDeployment(999, d), "UpsertDeployment")
   113  		assert.Nil(state.UpsertAllocs(structs.MsgTypeTestSetup, 1000, []*structs.Allocation{a1, a2}), "UpsertAllocs")
   114  
   115  		// Make the HTTP request
   116  		req, err := http.NewRequest("GET", "/v1/deployment/allocations/"+d.ID, nil)
   117  		assert.Nil(err, "HTTP Request")
   118  		respW := httptest.NewRecorder()
   119  
   120  		// Make the request
   121  		obj, err := s.Server.DeploymentSpecificRequest(respW, req)
   122  		assert.Nil(err, "DeploymentSpecificRequest")
   123  
   124  		// Check for the index
   125  		assert.NotZero(respW.Result().Header.Get("X-Nomad-Index"), "missing index")
   126  		assert.Equal("true", respW.Result().Header.Get("X-Nomad-KnownLeader"), "missing known leader")
   127  		assert.NotZero(respW.Result().Header.Get("X-Nomad-LastContact"), "missing last contact")
   128  
   129  		// Check the output
   130  		allocs := obj.([]*structs.AllocListStub)
   131  		assert.Len(allocs, 2, "Deployment Allocs")
   132  		expectedMsg := "Task's sibling failed"
   133  		displayMsg1 := allocs[0].TaskStates["test"].Events[0].DisplayMessage
   134  		assert.Equal(expectedMsg, displayMsg1, "DisplayMessage should be set")
   135  		displayMsg2 := allocs[0].TaskStates["test"].Events[0].DisplayMessage
   136  		assert.Equal(expectedMsg, displayMsg2, "DisplayMessage should be set")
   137  	})
   138  }
   139  
   140  func TestHTTP_DeploymentQuery(t *testing.T) {
   141  	ci.Parallel(t)
   142  	assert := assert.New(t)
   143  	httpTest(t, nil, func(s *TestAgent) {
   144  		// Directly manipulate the state
   145  		state := s.Agent.server.State()
   146  		d := mock.Deployment()
   147  		assert.Nil(state.UpsertDeployment(1000, d), "UpsertDeployment")
   148  
   149  		// Make the HTTP request
   150  		req, err := http.NewRequest("GET", "/v1/deployment/"+d.ID, nil)
   151  		assert.Nil(err, "HTTP Request")
   152  		respW := httptest.NewRecorder()
   153  
   154  		// Make the request
   155  		obj, err := s.Server.DeploymentSpecificRequest(respW, req)
   156  		assert.Nil(err, "Deployment Request")
   157  
   158  		// Check for the index
   159  		assert.NotZero(respW.Result().Header.Get("X-Nomad-Index"), "missing index")
   160  		assert.Equal("true", respW.Result().Header.Get("X-Nomad-KnownLeader"), "missing known leader")
   161  		assert.NotZero(respW.Result().Header.Get("X-Nomad-LastContact"), "missing last contact")
   162  
   163  		// Check the job
   164  		out := obj.(*structs.Deployment)
   165  		assert.Equal(d.ID, out.ID, "ID mismatch")
   166  	})
   167  }
   168  
   169  func TestHTTP_DeploymentPause(t *testing.T) {
   170  	ci.Parallel(t)
   171  	assert := assert.New(t)
   172  	httpTest(t, nil, func(s *TestAgent) {
   173  		// Directly manipulate the state
   174  		state := s.Agent.server.State()
   175  		j := mock.Job()
   176  		d := mock.Deployment()
   177  		d.JobID = j.ID
   178  		assert.Nil(state.UpsertJob(structs.MsgTypeTestSetup, 999, j), "UpsertJob")
   179  		assert.Nil(state.UpsertDeployment(1000, d), "UpsertDeployment")
   180  
   181  		// Create the pause request
   182  		args := structs.DeploymentPauseRequest{
   183  			DeploymentID: d.ID,
   184  			Pause:        false,
   185  			WriteRequest: structs.WriteRequest{
   186  				Region:    "global",
   187  				Namespace: structs.DefaultNamespace,
   188  			},
   189  		}
   190  		buf := encodeReq(args)
   191  
   192  		// Make the HTTP request
   193  		req, err := http.NewRequest("PUT", "/v1/deployment/pause/"+d.ID, buf)
   194  		assert.Nil(err, "HTTP Request")
   195  		respW := httptest.NewRecorder()
   196  
   197  		// Make the request
   198  		obj, err := s.Server.DeploymentSpecificRequest(respW, req)
   199  		assert.Nil(err, "Deployment Request")
   200  
   201  		// Check the response
   202  		resp := obj.(structs.DeploymentUpdateResponse)
   203  		assert.NotZero(resp.EvalID, "Expect Eval")
   204  		assert.NotZero(resp.EvalCreateIndex, "Expect Eval")
   205  		assert.NotZero(resp.DeploymentModifyIndex, "Expect Deployment to be Modified")
   206  		assert.NotZero(respW.Result().Header.Get("X-Nomad-Index"), "missing index")
   207  	})
   208  }
   209  
   210  func TestHTTP_DeploymentPromote(t *testing.T) {
   211  	ci.Parallel(t)
   212  	assert := assert.New(t)
   213  	httpTest(t, nil, func(s *TestAgent) {
   214  		// Directly manipulate the state
   215  		state := s.Agent.server.State()
   216  		j := mock.Job()
   217  		d := mock.Deployment()
   218  		d.JobID = j.ID
   219  		assert.Nil(state.UpsertJob(structs.MsgTypeTestSetup, 999, j), "UpsertJob")
   220  		assert.Nil(state.UpsertDeployment(1000, d), "UpsertDeployment")
   221  
   222  		// Create the pause request
   223  		args := structs.DeploymentPromoteRequest{
   224  			DeploymentID: d.ID,
   225  			All:          true,
   226  			WriteRequest: structs.WriteRequest{
   227  				Region:    "global",
   228  				Namespace: structs.DefaultNamespace,
   229  			},
   230  		}
   231  		buf := encodeReq(args)
   232  
   233  		// Make the HTTP request
   234  		req, err := http.NewRequest("PUT", "/v1/deployment/pause/"+d.ID, buf)
   235  		assert.Nil(err, "HTTP Request")
   236  		respW := httptest.NewRecorder()
   237  
   238  		// Make the request
   239  		obj, err := s.Server.DeploymentSpecificRequest(respW, req)
   240  		assert.Nil(err, "Deployment Request")
   241  
   242  		// Check the response
   243  		resp := obj.(structs.DeploymentUpdateResponse)
   244  		assert.NotZero(resp.EvalID, "Expect Eval")
   245  		assert.NotZero(resp.EvalCreateIndex, "Expect Eval")
   246  		assert.NotZero(resp.DeploymentModifyIndex, "Expect Deployment to be Modified")
   247  		assert.NotZero(respW.Result().Header.Get("X-Nomad-Index"), "missing index")
   248  	})
   249  }
   250  
   251  func TestHTTP_DeploymentAllocHealth(t *testing.T) {
   252  	ci.Parallel(t)
   253  	assert := assert.New(t)
   254  	httpTest(t, nil, func(s *TestAgent) {
   255  		// Directly manipulate the state
   256  		state := s.Agent.server.State()
   257  		j := mock.Job()
   258  		d := mock.Deployment()
   259  		d.JobID = j.ID
   260  		a := mock.Alloc()
   261  		a.JobID = j.ID
   262  		a.DeploymentID = d.ID
   263  		assert.Nil(state.UpsertJob(structs.MsgTypeTestSetup, 998, j), "UpsertJob")
   264  		assert.Nil(state.UpsertDeployment(999, d), "UpsertDeployment")
   265  		assert.Nil(state.UpsertAllocs(structs.MsgTypeTestSetup, 1000, []*structs.Allocation{a}), "UpsertAllocs")
   266  
   267  		// Create the pause request
   268  		args := structs.DeploymentAllocHealthRequest{
   269  			DeploymentID:         d.ID,
   270  			HealthyAllocationIDs: []string{a.ID},
   271  			WriteRequest: structs.WriteRequest{
   272  				Region:    "global",
   273  				Namespace: structs.DefaultNamespace,
   274  			},
   275  		}
   276  		buf := encodeReq(args)
   277  
   278  		// Make the HTTP request
   279  		req, err := http.NewRequest("PUT", "/v1/deployment/allocation-health/"+d.ID, buf)
   280  		assert.Nil(err, "HTTP Request")
   281  		respW := httptest.NewRecorder()
   282  
   283  		// Make the request
   284  		obj, err := s.Server.DeploymentSpecificRequest(respW, req)
   285  		assert.Nil(err, "Deployment Request")
   286  
   287  		// Check the response
   288  		resp := obj.(structs.DeploymentUpdateResponse)
   289  		assert.NotZero(resp.EvalID, "Expect Eval")
   290  		assert.NotZero(resp.EvalCreateIndex, "Expect Eval")
   291  		assert.NotZero(resp.DeploymentModifyIndex, "Expect Deployment to be Modified")
   292  		assert.NotZero(respW.Result().Header.Get("X-Nomad-Index"), "missing index")
   293  	})
   294  }
   295  
   296  func TestHTTP_DeploymentFail(t *testing.T) {
   297  	ci.Parallel(t)
   298  	assert := assert.New(t)
   299  	httpTest(t, nil, func(s *TestAgent) {
   300  		// Directly manipulate the state
   301  		state := s.Agent.server.State()
   302  		j := mock.Job()
   303  		d := mock.Deployment()
   304  		d.JobID = j.ID
   305  		assert.Nil(state.UpsertJob(structs.MsgTypeTestSetup, 998, j), "UpsertJob")
   306  		assert.Nil(state.UpsertDeployment(999, d), "UpsertDeployment")
   307  
   308  		// Make the HTTP request
   309  		req, err := http.NewRequest("PUT", "/v1/deployment/fail/"+d.ID, nil)
   310  		assert.Nil(err, "HTTP Request")
   311  		respW := httptest.NewRecorder()
   312  
   313  		// Make the request
   314  		obj, err := s.Server.DeploymentSpecificRequest(respW, req)
   315  		assert.Nil(err, "Deployment Request")
   316  
   317  		// Check the response
   318  		resp := obj.(structs.DeploymentUpdateResponse)
   319  		assert.NotZero(resp.EvalID, "Expect Eval")
   320  		assert.NotZero(resp.EvalCreateIndex, "Expect Eval")
   321  		assert.NotZero(resp.DeploymentModifyIndex, "Expect Deployment to be Modified")
   322  		assert.NotZero(respW.Result().Header.Get("X-Nomad-Index"), "missing index")
   323  	})
   324  }