github.com/akamai/AkamaiOPEN-edgegrid-golang/v8@v8.1.0/pkg/cloudlets/loadbalancer_test.go (about) 1 package cloudlets 2 3 import ( 4 "context" 5 "errors" 6 "io/ioutil" 7 "net/http" 8 "net/http/httptest" 9 "testing" 10 11 "github.com/stretchr/testify/assert" 12 "github.com/stretchr/testify/require" 13 ) 14 15 func TestListOrigins(t *testing.T) { 16 tests := map[string]struct { 17 originType ListOriginsRequest 18 responseStatus int 19 responseBody string 20 expectedPath string 21 expectedResponse []OriginResponse 22 withError func(*testing.T, error) 23 }{ 24 "200 OK": { 25 originType: ListOriginsRequest{}, 26 responseStatus: http.StatusOK, 27 responseBody: `[ 28 { 29 30 "hostname": "", 31 "description": "ALB1", 32 "originId": "alb1", 33 "type": "APPLICATION_LOAD_BALANCER", 34 "akamaized": false 35 }, 36 { 37 "hostname": "", 38 "description": "", 39 "originId": "alb2", 40 "type": "APPLICATION_LOAD_BALANCER", 41 "akamaized": false 42 }, 43 { 44 "hostname": "dc1.foo.com", 45 "description": "", 46 "originId": "dc1", 47 "type": "CUSTOMER", 48 "akamaized": false 49 }, 50 { 51 52 "hostname": "dc2.foo.com", 53 "description": "", 54 "originId": "dc2", 55 "type": "CUSTOMER", 56 "akamaized": true 57 }, 58 { 59 "hostname": "download.akamai.com/12345", 60 "description": "", 61 "originId": "ns1", 62 "type": "NETSTORAGE", 63 "akamaized": true 64 }, 65 { 66 67 "hostname": "download.akamai.com/12345", 68 "description": "", 69 "originId": "ns2", 70 "type": "NETSTORAGE", 71 "akamaized": true 72 } 73 ]`, 74 expectedPath: "/cloudlets/api/v2/origins", 75 expectedResponse: []OriginResponse{ 76 { 77 Hostname: "", 78 Origin: Origin{ 79 OriginID: "alb1", 80 Description: "ALB1", 81 Type: "APPLICATION_LOAD_BALANCER", 82 Akamaized: false, 83 }, 84 }, 85 { 86 Hostname: "", 87 Origin: Origin{ 88 Description: "", 89 OriginID: "alb2", 90 Type: "APPLICATION_LOAD_BALANCER", 91 Akamaized: false, 92 }, 93 }, 94 { 95 Hostname: "dc1.foo.com", 96 Origin: Origin{ 97 Description: "", 98 OriginID: "dc1", 99 Type: "CUSTOMER", 100 Akamaized: false, 101 }, 102 }, 103 { 104 Hostname: "dc2.foo.com", 105 Origin: Origin{ 106 Description: "", 107 OriginID: "dc2", 108 Type: "CUSTOMER", 109 Akamaized: true, 110 }, 111 }, 112 { 113 Hostname: "download.akamai.com/12345", 114 Origin: Origin{ 115 Description: "", 116 OriginID: "ns1", 117 Type: "NETSTORAGE", 118 Akamaized: true, 119 }, 120 }, 121 { 122 Hostname: "download.akamai.com/12345", 123 Origin: Origin{ 124 Description: "", 125 OriginID: "ns2", 126 Type: "NETSTORAGE", 127 Akamaized: true, 128 }, 129 }, 130 }, 131 }, 132 "200 ok with param": { 133 originType: ListOriginsRequest{Type: OriginTypeCustomer}, 134 responseStatus: http.StatusOK, 135 responseBody: `[ 136 { 137 "hostname": "dc1.foo.com", 138 "description": "", 139 "originId": "dc1", 140 "type": "CUSTOMER", 141 "akamaized": false 142 }, 143 { 144 145 "hostname": "dc2.foo.com", 146 "description": "", 147 "originId": "dc2", 148 "type": "CUSTOMER", 149 "akamaized": true 150 } 151 ]`, 152 expectedPath: "/cloudlets/api/v2/origins?type=CUSTOMER", 153 expectedResponse: []OriginResponse{ 154 { 155 Hostname: "dc1.foo.com", 156 Origin: Origin{ 157 Description: "", 158 OriginID: "dc1", 159 Type: "CUSTOMER", 160 Akamaized: false, 161 }, 162 }, 163 { 164 Hostname: "dc2.foo.com", 165 Origin: Origin{ 166 Description: "", 167 OriginID: "dc2", 168 Type: "CUSTOMER", 169 Akamaized: true, 170 }, 171 }, 172 }, 173 }, 174 "500 internal server error": { 175 originType: ListOriginsRequest{}, 176 responseStatus: http.StatusInternalServerError, 177 responseBody: `{ 178 "type": "internal_error", 179 "title": "Internal Server Error", 180 "detail": "Error making request", 181 "status": 500 182 }`, 183 expectedPath: "/cloudlets/api/v2/origins", 184 withError: func(t *testing.T, err error) { 185 want := &Error{ 186 Type: "internal_error", 187 Title: "Internal Server Error", 188 Detail: "Error making request", 189 StatusCode: http.StatusInternalServerError, 190 } 191 assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err) 192 }, 193 }, 194 } 195 196 for name, test := range tests { 197 t.Run(name, func(t *testing.T) { 198 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 199 assert.Equal(t, test.expectedPath, r.URL.String()) 200 assert.Equal(t, http.MethodGet, r.Method) 201 w.WriteHeader(test.responseStatus) 202 _, err := w.Write([]byte(test.responseBody)) 203 assert.NoError(t, err) 204 })) 205 client := mockAPIClient(t, mockServer) 206 result, err := client.ListOrigins(context.Background(), test.originType) 207 if test.withError != nil { 208 test.withError(t, err) 209 return 210 } 211 require.NoError(t, err) 212 assert.Equal(t, test.expectedResponse, result) 213 }) 214 } 215 } 216 217 func TestGetOrigin(t *testing.T) { 218 tests := map[string]struct { 219 originID string 220 responseStatus int 221 responseBody string 222 expectedPath string 223 expectedResponse *Origin 224 withError func(*testing.T, error) 225 }{ 226 "200 OK": { 227 originID: "alb1", 228 responseStatus: http.StatusOK, 229 responseBody: `{ 230 "description": "ALB1", 231 "originId": "alb1", 232 "type": "APPLICATION_LOAD_BALANCER", 233 "checksum": "abcdefg1111hijklmn22222fff76yae3" 234 }`, 235 expectedPath: "/cloudlets/api/v2/origins/alb1", 236 expectedResponse: &Origin{ 237 Description: "ALB1", 238 OriginID: "alb1", 239 Type: OriginTypeApplicationLoadBalancer, 240 Checksum: "abcdefg1111hijklmn22222fff76yae3", 241 }, 242 }, 243 "500 internal server error": { 244 originID: "ALB1", 245 responseStatus: http.StatusInternalServerError, 246 responseBody: `{ 247 "type": "internal_error", 248 "title": "Internal Server Error", 249 "detail": "Error making request", 250 "status": 500 251 }`, 252 expectedPath: "/cloudlets/api/v2/origins/ALB1", 253 withError: func(t *testing.T, err error) { 254 want := &Error{ 255 Type: "internal_error", 256 Title: "Internal Server Error", 257 Detail: "Error making request", 258 StatusCode: http.StatusInternalServerError, 259 } 260 assert.True(t, errors.Is(err, want), "want: %s; got: %s", want, err) 261 }, 262 }, 263 } 264 265 for name, test := range tests { 266 t.Run(name, func(t *testing.T) { 267 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 268 assert.Equal(t, test.expectedPath, r.URL.String()) 269 assert.Equal(t, http.MethodGet, r.Method) 270 w.WriteHeader(test.responseStatus) 271 _, err := w.Write([]byte(test.responseBody)) 272 assert.NoError(t, err) 273 })) 274 client := mockAPIClient(t, mockServer) 275 result, err := client.GetOrigin(context.Background(), GetOriginRequest{OriginID: test.originID}) 276 if test.withError != nil { 277 test.withError(t, err) 278 return 279 } 280 require.NoError(t, err) 281 assert.Equal(t, test.expectedResponse, result) 282 }) 283 } 284 } 285 286 func TestCreateOrigin(t *testing.T) { 287 tests := map[string]struct { 288 request CreateOriginRequest 289 expectedRequestBody string 290 responseStatus int 291 responseBody string 292 expectedPath string 293 expectedResponse *Origin 294 withError error 295 }{ 296 "201 created": { 297 request: CreateOriginRequest{ 298 OriginID: "first", 299 Description: Description{"create first Origin"}, 300 }, 301 expectedRequestBody: `{"originId":"first","description":"create first Origin"}`, 302 responseStatus: http.StatusCreated, 303 responseBody: `{ 304 "originId": "first", 305 "akamaized": true, 306 "checksum": "9c0fc1f3e9ea7eb2e090f2bf53709e45", 307 "description": "create first Origin", 308 "type": "APPLICATION_LOAD_BALANCER" 309 }`, 310 expectedPath: "/cloudlets/api/v2/origins", 311 expectedResponse: &Origin{ 312 OriginID: "first", 313 Description: "create first Origin", 314 Akamaized: true, 315 Type: OriginTypeApplicationLoadBalancer, 316 Checksum: "9c0fc1f3e9ea7eb2e090f2bf53709e45", 317 }, 318 }, 319 "500 internal server error": { 320 request: CreateOriginRequest{ 321 OriginID: "second", 322 Description: Description{"create second Origin"}, 323 }, 324 responseStatus: http.StatusInternalServerError, 325 responseBody: ` 326 { 327 "type": "internal_error", 328 "title": "Internal Server Error", 329 "detail": "Error creating enrollment", 330 "status": 500 331 }`, 332 expectedPath: "/cloudlets/api/v2/origins", 333 withError: &Error{ 334 Type: "internal_error", 335 Title: "Internal Server Error", 336 Detail: "Error creating enrollment", 337 StatusCode: http.StatusInternalServerError, 338 }, 339 expectedResponse: &Origin{ 340 OriginID: "first", 341 Description: "create first Origin", 342 Akamaized: false, 343 Type: OriginTypeApplicationLoadBalancer, 344 Checksum: "9c0fc1f3e9ea7eb2e090f2bf53709e45", 345 }, 346 }, 347 "validation error": { 348 request: CreateOriginRequest{}, 349 withError: ErrStructValidation, 350 }, 351 } 352 353 for name, test := range tests { 354 t.Run(name, func(t *testing.T) { 355 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 356 assert.Equal(t, test.expectedPath, r.URL.String()) 357 assert.Equal(t, http.MethodPost, r.Method) 358 w.WriteHeader(test.responseStatus) 359 _, err := w.Write([]byte(test.responseBody)) 360 assert.NoError(t, err) 361 362 if len(test.expectedRequestBody) > 0 { 363 body, err := ioutil.ReadAll(r.Body) 364 require.NoError(t, err) 365 assert.Equal(t, test.expectedRequestBody, string(body)) 366 } 367 })) 368 client := mockAPIClient(t, mockServer) 369 result, err := client.CreateOrigin(context.Background(), test.request) 370 if test.withError != nil { 371 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 372 return 373 } 374 require.NoError(t, err) 375 assert.Equal(t, test.expectedResponse, result) 376 }) 377 } 378 } 379 380 func TestCreateOriginValidation(t *testing.T) { 381 tests := map[string]struct { 382 request CreateOriginRequest 383 withError error 384 }{ 385 "validation error - OriginID exceeds max length, which is 63": { 386 request: CreateOriginRequest{ 387 OriginID: "ExceedMaxLenghtExceedMaxLenghtExceedMaxLenghtExceedMaxLenghtExce", 388 }, 389 withError: ErrStructValidation, 390 }, 391 "validation error - OriginID value less than min, which is 2": { 392 request: CreateOriginRequest{ 393 OriginID: "E", 394 }, 395 withError: ErrStructValidation, 396 }, 397 "validation error - Description exceeds max length, which is 255": { 398 request: CreateOriginRequest{ 399 OriginID: "first", 400 Description: Description{ 401 "Test for creating APPLICATION_LOAD_BALANCER origin type, Test for creating APPLICATION_LOAD_BALANCER origin type, Test for creating APPLICATION_LOAD_BALANCER origin type, Test for creating APPLICATION_LOAD_BALANCER origin type,Test for creating exceed valu", 402 }, 403 }, 404 withError: ErrStructValidation, 405 }, 406 } 407 for name, test := range tests { 408 t.Run(name, func(t *testing.T) { 409 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})) 410 client := mockAPIClient(t, mockServer) 411 _, err := client.CreateOrigin(context.Background(), test.request) 412 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 413 }) 414 } 415 } 416 417 func TestUpdateOrigin(t *testing.T) { 418 tests := map[string]struct { 419 request UpdateOriginRequest 420 expectedRequestBody string 421 responseStatus int 422 responseBody string 423 expectedPath string 424 expectedResponse *Origin 425 withError error 426 }{ 427 "200 updated": { 428 request: UpdateOriginRequest{ 429 OriginID: "first", 430 Description: Description{"update first Origin"}, 431 }, 432 expectedRequestBody: `{"description":"update first Origin"}`, 433 responseStatus: http.StatusOK, 434 responseBody: `{ 435 "originId": "first", 436 "akamaized": true, 437 "checksum": "9c0fc1f3e9ea7eb2e090f2bf53709e45", 438 "description": "update first Origin", 439 "type": "APPLICATION_LOAD_BALANCER" 440 }`, 441 expectedPath: "/cloudlets/api/v2/origins/first", 442 expectedResponse: &Origin{ 443 OriginID: "first", 444 Description: "update first Origin", 445 Akamaized: true, 446 Type: OriginTypeApplicationLoadBalancer, 447 Checksum: "9c0fc1f3e9ea7eb2e090f2bf53709e45", 448 }, 449 }, 450 "500 internal server error": { 451 request: UpdateOriginRequest{ 452 OriginID: "second", 453 Description: Description{"create second Origin"}, 454 }, 455 responseStatus: http.StatusInternalServerError, 456 responseBody: ` 457 { 458 "type": "internal_error", 459 "title": "Internal Server Error", 460 "detail": "Error creating enrollment", 461 "status": 500 462 }`, 463 expectedPath: "/cloudlets/api/v2/origins/second", 464 withError: &Error{ 465 Type: "internal_error", 466 Title: "Internal Server Error", 467 Detail: "Error creating enrollment", 468 StatusCode: http.StatusInternalServerError, 469 }, 470 expectedResponse: &Origin{ 471 OriginID: "second", 472 Description: "update first Origin", 473 Akamaized: false, 474 Type: OriginTypeApplicationLoadBalancer, 475 Checksum: "9c0fc1f3e9ea7eb2e090f2bf53709e45", 476 }, 477 }, 478 "validation error": { 479 request: UpdateOriginRequest{}, 480 withError: ErrStructValidation, 481 }, 482 } 483 for name, test := range tests { 484 t.Run(name, func(t *testing.T) { 485 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 486 assert.Equal(t, test.expectedPath, r.URL.String()) 487 assert.Equal(t, http.MethodPut, r.Method) 488 w.WriteHeader(test.responseStatus) 489 _, err := w.Write([]byte(test.responseBody)) 490 assert.NoError(t, err) 491 492 if len(test.expectedRequestBody) > 0 { 493 body, err := ioutil.ReadAll(r.Body) 494 require.NoError(t, err) 495 assert.Equal(t, test.expectedRequestBody, string(body)) 496 } 497 })) 498 client := mockAPIClient(t, mockServer) 499 result, err := client.UpdateOrigin(context.Background(), test.request) 500 if test.withError != nil { 501 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 502 return 503 } 504 require.NoError(t, err) 505 assert.Equal(t, test.expectedResponse, result) 506 }) 507 } 508 } 509 510 func TestUpdateOriginValidation(t *testing.T) { 511 tests := map[string]struct { 512 request UpdateOriginRequest 513 withError error 514 }{ 515 "validation error - OriginID exceeds max length, which is 63": { 516 request: UpdateOriginRequest{ 517 OriginID: "ExceedMaxLenghtExceedMaxLenghtExceedMaxLenghtExceedMaxLenghtExce", 518 }, 519 withError: ErrStructValidation, 520 }, 521 "validation error - OriginID value less than min, which is 2": { 522 request: UpdateOriginRequest{ 523 OriginID: "E", 524 }, 525 withError: ErrStructValidation, 526 }, 527 "validation error - Description exceeds max length, which is 255": { 528 request: UpdateOriginRequest{ 529 OriginID: "first", 530 Description: Description{ 531 "Test for creating APPLICATION_LOAD_BALANCER origin type, Test for creating APPLICATION_LOAD_BALANCER origin type, Test for creating APPLICATION_LOAD_BALANCER origin type, Test for creating APPLICATION_LOAD_BALANCER origin type,Test for creating exceed valu", 532 }, 533 }, 534 withError: ErrStructValidation, 535 }, 536 } 537 for name, test := range tests { 538 t.Run(name, func(t *testing.T) { 539 mockServer := httptest.NewTLSServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {})) 540 client := mockAPIClient(t, mockServer) 541 _, err := client.UpdateOrigin(context.Background(), test.request) 542 assert.True(t, errors.Is(err, test.withError), "want: %s; got: %s", test.withError, err) 543 }) 544 } 545 }