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 }