github.com/vnpaycloud-console/gophercloud/v2@v2.0.5/openstack/compute/v2/servers/testing/requests_test.go (about) 1 package testing 2 3 import ( 4 "context" 5 "encoding/base64" 6 "encoding/json" 7 "net/http" 8 "testing" 9 10 "github.com/vnpaycloud-console/gophercloud/v2/openstack/compute/v2/servers" 11 "github.com/vnpaycloud-console/gophercloud/v2/pagination" 12 th "github.com/vnpaycloud-console/gophercloud/v2/testhelper" 13 "github.com/vnpaycloud-console/gophercloud/v2/testhelper/client" 14 ) 15 16 func TestListServers(t *testing.T) { 17 th.SetupHTTP() 18 defer th.TeardownHTTP() 19 HandleServerListSuccessfully(t) 20 21 pages := 0 22 err := servers.List(client.ServiceClient(), servers.ListOpts{}).EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { 23 pages++ 24 25 actual, err := servers.ExtractServers(page) 26 if err != nil { 27 return false, err 28 } 29 30 if len(actual) != 3 { 31 t.Fatalf("Expected 3 servers, got %d", len(actual)) 32 } 33 th.CheckDeepEquals(t, ServerHerp, actual[0]) 34 th.CheckDeepEquals(t, ServerDerp, actual[1]) 35 th.CheckDeepEquals(t, ServerMerp, actual[2]) 36 37 return true, nil 38 }) 39 40 th.AssertNoErr(t, err) 41 42 if pages != 1 { 43 t.Errorf("Expected 1 page, saw %d", pages) 44 } 45 } 46 47 func TestListAllServers(t *testing.T) { 48 th.SetupHTTP() 49 defer th.TeardownHTTP() 50 HandleServerListSimpleSuccessfully(t) 51 52 allPages, err := servers.ListSimple(client.ServiceClient(), servers.ListOpts{}).AllPages(context.TODO()) 53 th.AssertNoErr(t, err) 54 actual, err := servers.ExtractServers(allPages) 55 th.AssertNoErr(t, err) 56 th.CheckDeepEquals(t, ServerHerp, actual[0]) 57 th.CheckDeepEquals(t, ServerDerp, actual[1]) 58 } 59 60 func TestListAllServersWithExtensions(t *testing.T) { 61 th.SetupHTTP() 62 defer th.TeardownHTTP() 63 HandleServerListSuccessfully(t) 64 65 allPages, err := servers.List(client.ServiceClient(), servers.ListOpts{}).AllPages(context.TODO()) 66 th.AssertNoErr(t, err) 67 68 var actual []servers.Server 69 err = servers.ExtractServersInto(allPages, &actual) 70 th.AssertNoErr(t, err) 71 th.AssertEquals(t, 3, len(actual)) 72 th.AssertEquals(t, "nova", actual[0].AvailabilityZone) 73 th.AssertEquals(t, "RUNNING", actual[0].PowerState.String()) 74 th.AssertEquals(t, "", actual[0].TaskState) 75 th.AssertEquals(t, "active", actual[0].VmState) 76 th.AssertEquals(t, servers.Manual, actual[0].DiskConfig) 77 } 78 79 func TestCreateServer(t *testing.T) { 80 th.SetupHTTP() 81 defer th.TeardownHTTP() 82 HandleServerCreationSuccessfully(t, SingleServerBody) 83 84 actual, err := servers.Create(context.TODO(), client.ServiceClient(), servers.CreateOpts{ 85 Name: "derp", 86 ImageRef: "f90f6034-2570-4974-8351-6b49732ef2eb", 87 FlavorRef: "1", 88 }, nil).Extract() 89 th.AssertNoErr(t, err) 90 91 th.CheckDeepEquals(t, ServerDerp, *actual) 92 } 93 94 func TestCreateServerNoNetwork(t *testing.T) { 95 th.SetupHTTP() 96 defer th.TeardownHTTP() 97 HandleServerNoNetworkCreationSuccessfully(t, SingleServerBody) 98 99 actual, err := servers.Create(context.TODO(), client.ServiceClient(), servers.CreateOpts{ 100 Name: "derp", 101 ImageRef: "f90f6034-2570-4974-8351-6b49732ef2eb", 102 FlavorRef: "1", 103 Networks: "none", 104 }, nil).Extract() 105 th.AssertNoErr(t, err) 106 107 th.CheckDeepEquals(t, ServerDerp, *actual) 108 } 109 110 func TestCreateServers(t *testing.T) { 111 th.SetupHTTP() 112 defer th.TeardownHTTP() 113 HandleServersCreationSuccessfully(t, SingleServerBody) 114 115 actual, err := servers.Create(context.TODO(), client.ServiceClient(), servers.CreateOpts{ 116 Name: "derp", 117 ImageRef: "f90f6034-2570-4974-8351-6b49732ef2eb", 118 FlavorRef: "1", 119 Min: 3, 120 Max: 3, 121 }, nil).Extract() 122 th.AssertNoErr(t, err) 123 124 th.CheckDeepEquals(t, ServerDerp, *actual) 125 } 126 127 func TestCreateServerWithCustomField(t *testing.T) { 128 th.SetupHTTP() 129 defer th.TeardownHTTP() 130 HandleServerCreationWithCustomFieldSuccessfully(t, SingleServerBody) 131 132 actual, err := servers.Create(context.TODO(), client.ServiceClient(), CreateOptsWithCustomField{ 133 CreateOpts: servers.CreateOpts{ 134 Name: "derp", 135 ImageRef: "f90f6034-2570-4974-8351-6b49732ef2eb", 136 FlavorRef: "1", 137 }, 138 Foo: "bar", 139 }, nil).Extract() 140 th.AssertNoErr(t, err) 141 142 th.CheckDeepEquals(t, ServerDerp, *actual) 143 } 144 145 func TestCreateServerWithMetadata(t *testing.T) { 146 th.SetupHTTP() 147 defer th.TeardownHTTP() 148 HandleServerCreationWithMetadata(t, SingleServerBody) 149 150 actual, err := servers.Create(context.TODO(), client.ServiceClient(), servers.CreateOpts{ 151 Name: "derp", 152 ImageRef: "f90f6034-2570-4974-8351-6b49732ef2eb", 153 FlavorRef: "1", 154 Metadata: map[string]string{ 155 "abc": "def", 156 }, 157 }, nil).Extract() 158 th.AssertNoErr(t, err) 159 160 th.CheckDeepEquals(t, ServerDerp, *actual) 161 } 162 163 func TestCreateServerWithUserdataString(t *testing.T) { 164 th.SetupHTTP() 165 defer th.TeardownHTTP() 166 HandleServerCreationWithUserdata(t, SingleServerBody) 167 168 actual, err := servers.Create(context.TODO(), client.ServiceClient(), servers.CreateOpts{ 169 Name: "derp", 170 ImageRef: "f90f6034-2570-4974-8351-6b49732ef2eb", 171 FlavorRef: "1", 172 UserData: []byte("userdata string"), 173 }, nil).Extract() 174 th.AssertNoErr(t, err) 175 176 th.CheckDeepEquals(t, ServerDerp, *actual) 177 } 178 179 func TestCreateServerWithUserdataEncoded(t *testing.T) { 180 th.SetupHTTP() 181 defer th.TeardownHTTP() 182 HandleServerCreationWithUserdata(t, SingleServerBody) 183 184 encoded := base64.StdEncoding.EncodeToString([]byte("userdata string")) 185 186 actual, err := servers.Create(context.TODO(), client.ServiceClient(), servers.CreateOpts{ 187 Name: "derp", 188 ImageRef: "f90f6034-2570-4974-8351-6b49732ef2eb", 189 FlavorRef: "1", 190 UserData: []byte(encoded), 191 }, nil).Extract() 192 th.AssertNoErr(t, err) 193 194 th.CheckDeepEquals(t, ServerDerp, *actual) 195 } 196 197 func TestCreateServerWithHostname(t *testing.T) { 198 th.SetupHTTP() 199 defer th.TeardownHTTP() 200 HandleServerCreationWithHostname(t, SingleServerBody) 201 202 actual, err := servers.Create(context.TODO(), client.ServiceClient(), servers.CreateOpts{ 203 Name: "derp", 204 ImageRef: "f90f6034-2570-4974-8351-6b49732ef2eb", 205 FlavorRef: "1", 206 Hostname: "derp.local", 207 }, nil).Extract() 208 th.AssertNoErr(t, err) 209 210 th.CheckDeepEquals(t, ServerDerp, *actual) 211 } 212 213 func TestCreateServerWithDiskConfig(t *testing.T) { 214 opts := servers.CreateOpts{ 215 Name: "createdserver", 216 ImageRef: "asdfasdfasdf", 217 FlavorRef: "performance1-1", 218 DiskConfig: servers.Manual, 219 } 220 expected := ` 221 { 222 "server": { 223 "name": "createdserver", 224 "imageRef": "asdfasdfasdf", 225 "flavorRef": "performance1-1", 226 "OS-DCF:diskConfig": "MANUAL" 227 } 228 } 229 ` 230 231 actual, err := opts.ToServerCreateMap() 232 th.AssertNoErr(t, err) 233 th.CheckJSONEquals(t, expected, actual) 234 } 235 236 func TestCreateServerWithBFVBootFromNewVolume(t *testing.T) { 237 opts := servers.CreateOpts{ 238 Name: "createdserver", 239 FlavorRef: "performance1-1", 240 BlockDevice: []servers.BlockDevice{ 241 { 242 UUID: "123456", 243 SourceType: servers.SourceImage, 244 DestinationType: servers.DestinationVolume, 245 VolumeSize: 10, 246 DeleteOnTermination: true, 247 }, 248 }, 249 } 250 expected := ` 251 { 252 "server": { 253 "name":"createdserver", 254 "flavorRef":"performance1-1", 255 "imageRef":"", 256 "block_device_mapping_v2":[ 257 { 258 "uuid":"123456", 259 "source_type":"image", 260 "destination_type":"volume", 261 "boot_index": 0, 262 "delete_on_termination": true, 263 "volume_size": 10 264 } 265 ] 266 } 267 } 268 ` 269 270 actual, err := opts.ToServerCreateMap() 271 th.AssertNoErr(t, err) 272 th.CheckJSONEquals(t, expected, actual) 273 } 274 275 func TestCreateServerWithBFVBootFromExistingVolume(t *testing.T) { 276 opts := servers.CreateOpts{ 277 Name: "createdserver", 278 FlavorRef: "performance1-1", 279 BlockDevice: []servers.BlockDevice{ 280 { 281 UUID: "123456", 282 SourceType: servers.SourceVolume, 283 DestinationType: servers.DestinationVolume, 284 DeleteOnTermination: true, 285 }, 286 }, 287 } 288 expected := ` 289 { 290 "server": { 291 "name":"createdserver", 292 "flavorRef":"performance1-1", 293 "imageRef":"", 294 "block_device_mapping_v2":[ 295 { 296 "uuid":"123456", 297 "source_type":"volume", 298 "destination_type":"volume", 299 "boot_index": 0, 300 "delete_on_termination": true 301 } 302 ] 303 } 304 } 305 ` 306 307 actual, err := opts.ToServerCreateMap() 308 th.AssertNoErr(t, err) 309 th.CheckJSONEquals(t, expected, actual) 310 } 311 312 func TestCreateServerWithBFVBootFromImage(t *testing.T) { 313 var ImageRequest = servers.CreateOpts{ 314 Name: "createdserver", 315 FlavorRef: "performance1-1", 316 ImageRef: "asdfasdfasdf", 317 BlockDevice: []servers.BlockDevice{ 318 { 319 BootIndex: 0, 320 DeleteOnTermination: true, 321 DestinationType: servers.DestinationLocal, 322 SourceType: servers.SourceImage, 323 UUID: "asdfasdfasdf", 324 }, 325 }, 326 } 327 const ExpectedImageRequest = ` 328 { 329 "server": { 330 "name": "createdserver", 331 "imageRef": "asdfasdfasdf", 332 "flavorRef": "performance1-1", 333 "block_device_mapping_v2":[ 334 { 335 "boot_index": 0, 336 "delete_on_termination": true, 337 "destination_type":"local", 338 "source_type":"image", 339 "uuid":"asdfasdfasdf" 340 } 341 ] 342 } 343 } 344 ` 345 346 actual, err := ImageRequest.ToServerCreateMap() 347 th.AssertNoErr(t, err) 348 th.CheckJSONEquals(t, ExpectedImageRequest, actual) 349 } 350 351 func TestCreateServerWithBFVCreateMultiEphemeralOpts(t *testing.T) { 352 var MultiEphemeralRequest = servers.CreateOpts{ 353 Name: "createdserver", 354 FlavorRef: "performance1-1", 355 ImageRef: "asdfasdfasdf", 356 BlockDevice: []servers.BlockDevice{ 357 { 358 BootIndex: 0, 359 DeleteOnTermination: true, 360 DestinationType: servers.DestinationLocal, 361 SourceType: servers.SourceImage, 362 UUID: "asdfasdfasdf", 363 }, 364 { 365 BootIndex: -1, 366 DeleteOnTermination: true, 367 DestinationType: servers.DestinationLocal, 368 GuestFormat: "ext4", 369 SourceType: servers.SourceBlank, 370 VolumeSize: 1, 371 }, 372 { 373 BootIndex: -1, 374 DeleteOnTermination: true, 375 DestinationType: servers.DestinationLocal, 376 GuestFormat: "ext4", 377 SourceType: servers.SourceBlank, 378 VolumeSize: 1, 379 }, 380 }, 381 } 382 const ExpectedMultiEphemeralRequest = ` 383 { 384 "server": { 385 "name": "createdserver", 386 "imageRef": "asdfasdfasdf", 387 "flavorRef": "performance1-1", 388 "block_device_mapping_v2":[ 389 { 390 "boot_index": 0, 391 "delete_on_termination": true, 392 "destination_type":"local", 393 "source_type":"image", 394 "uuid":"asdfasdfasdf" 395 }, 396 { 397 "boot_index": -1, 398 "delete_on_termination": true, 399 "destination_type":"local", 400 "guest_format":"ext4", 401 "source_type":"blank", 402 "volume_size": 1 403 }, 404 { 405 "boot_index": -1, 406 "delete_on_termination": true, 407 "destination_type":"local", 408 "guest_format":"ext4", 409 "source_type":"blank", 410 "volume_size": 1 411 } 412 ] 413 } 414 } 415 ` 416 417 actual, err := MultiEphemeralRequest.ToServerCreateMap() 418 th.AssertNoErr(t, err) 419 th.CheckJSONEquals(t, ExpectedMultiEphemeralRequest, actual) 420 } 421 422 func TestCreateServerWithBFVAttachNewVolume(t *testing.T) { 423 opts := servers.CreateOpts{ 424 Name: "createdserver", 425 FlavorRef: "performance1-1", 426 ImageRef: "asdfasdfasdf", 427 BlockDevice: []servers.BlockDevice{ 428 { 429 BootIndex: 0, 430 DeleteOnTermination: true, 431 DestinationType: servers.DestinationLocal, 432 SourceType: servers.SourceImage, 433 UUID: "asdfasdfasdf", 434 }, 435 { 436 BootIndex: 1, 437 DeleteOnTermination: true, 438 DestinationType: servers.DestinationVolume, 439 SourceType: servers.SourceBlank, 440 VolumeSize: 1, 441 DeviceType: "disk", 442 DiskBus: "scsi", 443 }, 444 }, 445 } 446 expected := ` 447 { 448 "server": { 449 "name": "createdserver", 450 "imageRef": "asdfasdfasdf", 451 "flavorRef": "performance1-1", 452 "block_device_mapping_v2":[ 453 { 454 "boot_index": 0, 455 "delete_on_termination": true, 456 "destination_type":"local", 457 "source_type":"image", 458 "uuid":"asdfasdfasdf" 459 }, 460 { 461 "boot_index": 1, 462 "delete_on_termination": true, 463 "destination_type":"volume", 464 "source_type":"blank", 465 "volume_size": 1, 466 "device_type": "disk", 467 "disk_bus": "scsi" 468 } 469 ] 470 } 471 } 472 ` 473 474 actual, err := opts.ToServerCreateMap() 475 th.AssertNoErr(t, err) 476 th.CheckJSONEquals(t, expected, actual) 477 } 478 479 func TestCreateServerWithBFVAttachExistingVolume(t *testing.T) { 480 opts := servers.CreateOpts{ 481 Name: "createdserver", 482 FlavorRef: "performance1-1", 483 ImageRef: "asdfasdfasdf", 484 BlockDevice: []servers.BlockDevice{ 485 { 486 BootIndex: 0, 487 DeleteOnTermination: true, 488 DestinationType: servers.DestinationLocal, 489 SourceType: servers.SourceImage, 490 UUID: "asdfasdfasdf", 491 }, 492 { 493 BootIndex: 1, 494 DeleteOnTermination: true, 495 DestinationType: servers.DestinationVolume, 496 SourceType: servers.SourceVolume, 497 UUID: "123456", 498 VolumeSize: 1, 499 }, 500 }, 501 } 502 expected := ` 503 { 504 "server": { 505 "name": "createdserver", 506 "imageRef": "asdfasdfasdf", 507 "flavorRef": "performance1-1", 508 "block_device_mapping_v2":[ 509 { 510 "boot_index": 0, 511 "delete_on_termination": true, 512 "destination_type":"local", 513 "source_type":"image", 514 "uuid":"asdfasdfasdf" 515 }, 516 { 517 "boot_index": 1, 518 "delete_on_termination": true, 519 "destination_type":"volume", 520 "source_type":"volume", 521 "uuid":"123456", 522 "volume_size": 1 523 } 524 ] 525 } 526 } 527 ` 528 529 actual, err := opts.ToServerCreateMap() 530 th.AssertNoErr(t, err) 531 th.CheckJSONEquals(t, expected, actual) 532 } 533 534 func TestCreateServerWithBFVBootFromNewVolumeType(t *testing.T) { 535 var NewVolumeTypeRequest = servers.CreateOpts{ 536 Name: "createdserver", 537 FlavorRef: "performance1-1", 538 BlockDevice: []servers.BlockDevice{ 539 { 540 UUID: "123456", 541 SourceType: servers.SourceImage, 542 DestinationType: servers.DestinationVolume, 543 VolumeSize: 10, 544 DeleteOnTermination: true, 545 VolumeType: "ssd", 546 }, 547 }, 548 } 549 const ExpectedNewVolumeTypeRequest = ` 550 { 551 "server": { 552 "name":"createdserver", 553 "flavorRef":"performance1-1", 554 "imageRef":"", 555 "block_device_mapping_v2":[ 556 { 557 "uuid":"123456", 558 "source_type":"image", 559 "destination_type":"volume", 560 "boot_index": 0, 561 "delete_on_termination": true, 562 "volume_size": 10, 563 "volume_type": "ssd" 564 } 565 ] 566 } 567 } 568 ` 569 570 actual, err := NewVolumeTypeRequest.ToServerCreateMap() 571 th.AssertNoErr(t, err) 572 th.CheckJSONEquals(t, ExpectedNewVolumeTypeRequest, actual) 573 } 574 575 func TestCreateServerWithBFVAttachExistingVolumeWithTag(t *testing.T) { 576 var ImageAndExistingVolumeWithTagRequest = servers.CreateOpts{ 577 Name: "createdserver", 578 FlavorRef: "performance1-1", 579 ImageRef: "asdfasdfasdf", 580 BlockDevice: []servers.BlockDevice{ 581 { 582 BootIndex: 0, 583 DeleteOnTermination: true, 584 DestinationType: servers.DestinationLocal, 585 SourceType: servers.SourceImage, 586 UUID: "asdfasdfasdf", 587 }, 588 { 589 BootIndex: -1, 590 DeleteOnTermination: true, 591 DestinationType: servers.DestinationVolume, 592 SourceType: servers.SourceVolume, 593 Tag: "volume-tag", 594 UUID: "123456", 595 VolumeSize: 1, 596 }, 597 }, 598 } 599 const ExpectedImageAndExistingVolumeWithTagRequest = ` 600 { 601 "server": { 602 "name": "createdserver", 603 "imageRef": "asdfasdfasdf", 604 "flavorRef": "performance1-1", 605 "block_device_mapping_v2":[ 606 { 607 "boot_index": 0, 608 "delete_on_termination": true, 609 "destination_type":"local", 610 "source_type":"image", 611 "uuid":"asdfasdfasdf" 612 }, 613 { 614 "boot_index": -1, 615 "delete_on_termination": true, 616 "destination_type":"volume", 617 "source_type":"volume", 618 "tag": "volume-tag", 619 "uuid":"123456", 620 "volume_size": 1 621 } 622 ] 623 } 624 } 625 ` 626 627 actual, err := ImageAndExistingVolumeWithTagRequest.ToServerCreateMap() 628 th.AssertNoErr(t, err) 629 th.CheckJSONEquals(t, ExpectedImageAndExistingVolumeWithTagRequest, actual) 630 } 631 632 func TestCreateSchedulerHints(t *testing.T) { 633 opts := servers.SchedulerHintOpts{ 634 Group: "101aed42-22d9-4a3e-9ba1-21103b0d1aba", 635 DifferentHost: []string{ 636 "a0cf03a5-d921-4877-bb5c-86d26cf818e1", 637 "8c19174f-4220-44f0-824a-cd1eeef10287", 638 }, 639 SameHost: []string{ 640 "a0cf03a5-d921-4877-bb5c-86d26cf818e1", 641 "8c19174f-4220-44f0-824a-cd1eeef10287", 642 }, 643 Query: []any{"=", "$free_ram_mb", "1024"}, 644 TargetCell: "foobar", 645 DifferentCell: []string{ 646 "bazbar", 647 "barbaz", 648 }, 649 BuildNearHostIP: "192.168.1.1/24", 650 AdditionalProperties: map[string]any{"reservation": "a0cf03a5-d921-4877-bb5c-86d26cf818e1"}, 651 } 652 653 expected := ` 654 { 655 "os:scheduler_hints": { 656 "group": "101aed42-22d9-4a3e-9ba1-21103b0d1aba", 657 "different_host": [ 658 "a0cf03a5-d921-4877-bb5c-86d26cf818e1", 659 "8c19174f-4220-44f0-824a-cd1eeef10287" 660 ], 661 "same_host": [ 662 "a0cf03a5-d921-4877-bb5c-86d26cf818e1", 663 "8c19174f-4220-44f0-824a-cd1eeef10287" 664 ], 665 "query": "[\"=\",\"$free_ram_mb\",\"1024\"]", 666 "target_cell": "foobar", 667 "different_cell": [ 668 "bazbar", 669 "barbaz" 670 ], 671 "build_near_host_ip": "192.168.1.1", 672 "cidr": "/24", 673 "reservation": "a0cf03a5-d921-4877-bb5c-86d26cf818e1" 674 } 675 } 676 ` 677 actual, err := opts.ToSchedulerHintsMap() 678 th.AssertNoErr(t, err) 679 th.CheckJSONEquals(t, expected, actual) 680 } 681 682 func TestCreateComplexSchedulerHints(t *testing.T) { 683 opts := servers.SchedulerHintOpts{ 684 Group: "101aed42-22d9-4a3e-9ba1-21103b0d1aba", 685 DifferentHost: []string{ 686 "a0cf03a5-d921-4877-bb5c-86d26cf818e1", 687 "8c19174f-4220-44f0-824a-cd1eeef10287", 688 }, 689 SameHost: []string{ 690 "a0cf03a5-d921-4877-bb5c-86d26cf818e1", 691 "8c19174f-4220-44f0-824a-cd1eeef10287", 692 }, 693 Query: []any{"and", []string{"=", "$free_ram_mb", "1024"}, []string{"=", "$free_disk_mb", "204800"}}, 694 TargetCell: "foobar", 695 DifferentCell: []string{ 696 "bazbar", 697 "barbaz", 698 }, 699 BuildNearHostIP: "192.168.1.1/24", 700 AdditionalProperties: map[string]any{"reservation": "a0cf03a5-d921-4877-bb5c-86d26cf818e1"}, 701 } 702 703 expected := ` 704 { 705 "os:scheduler_hints": { 706 "group": "101aed42-22d9-4a3e-9ba1-21103b0d1aba", 707 "different_host": [ 708 "a0cf03a5-d921-4877-bb5c-86d26cf818e1", 709 "8c19174f-4220-44f0-824a-cd1eeef10287" 710 ], 711 "same_host": [ 712 "a0cf03a5-d921-4877-bb5c-86d26cf818e1", 713 "8c19174f-4220-44f0-824a-cd1eeef10287" 714 ], 715 "query": "[\"and\",[\"=\",\"$free_ram_mb\",\"1024\"],[\"=\",\"$free_disk_mb\",\"204800\"]]", 716 "target_cell": "foobar", 717 "different_cell": [ 718 "bazbar", 719 "barbaz" 720 ], 721 "build_near_host_ip": "192.168.1.1", 722 "cidr": "/24", 723 "reservation": "a0cf03a5-d921-4877-bb5c-86d26cf818e1" 724 } 725 } 726 ` 727 actual, err := opts.ToSchedulerHintsMap() 728 th.AssertNoErr(t, err) 729 th.CheckJSONEquals(t, expected, actual) 730 } 731 732 func TestDeleteServer(t *testing.T) { 733 th.SetupHTTP() 734 defer th.TeardownHTTP() 735 HandleServerDeletionSuccessfully(t) 736 737 res := servers.Delete(context.TODO(), client.ServiceClient(), "asdfasdfasdf") 738 th.AssertNoErr(t, res.Err) 739 } 740 741 func TestForceDeleteServer(t *testing.T) { 742 th.SetupHTTP() 743 defer th.TeardownHTTP() 744 HandleServerForceDeletionSuccessfully(t) 745 746 res := servers.ForceDelete(context.TODO(), client.ServiceClient(), "asdfasdfasdf") 747 th.AssertNoErr(t, res.Err) 748 } 749 750 func TestGetServer(t *testing.T) { 751 th.SetupHTTP() 752 defer th.TeardownHTTP() 753 HandleServerGetSuccessfully(t) 754 755 client := client.ServiceClient() 756 actual, err := servers.Get(context.TODO(), client, "1234asdf").Extract() 757 if err != nil { 758 t.Fatalf("Unexpected Get error: %v", err) 759 } 760 761 th.CheckDeepEquals(t, ServerDerp, *actual) 762 } 763 764 func TestGetFaultyServer(t *testing.T) { 765 th.SetupHTTP() 766 defer th.TeardownHTTP() 767 HandleServerGetFaultSuccessfully(t) 768 769 client := client.ServiceClient() 770 actual, err := servers.Get(context.TODO(), client, "1234asdf").Extract() 771 if err != nil { 772 t.Fatalf("Unexpected Get error: %v", err) 773 } 774 775 FaultyServer := ServerDerp 776 FaultyServer.Fault = DerpFault 777 FaultyServer.Locked = nil 778 th.CheckDeepEquals(t, FaultyServer, *actual) 779 } 780 781 func TestGetServerWithExtensions(t *testing.T) { 782 th.SetupHTTP() 783 defer th.TeardownHTTP() 784 HandleServerGetSuccessfully(t) 785 786 var s struct { 787 servers.Server 788 } 789 790 client := client.ServiceClient() 791 err := servers.Get(context.TODO(), client, "1234asdf").ExtractInto(&s) 792 th.AssertNoErr(t, err) 793 th.AssertEquals(t, "nova", s.AvailabilityZone) 794 th.AssertEquals(t, "RUNNING", s.PowerState.String()) 795 th.AssertEquals(t, "", s.TaskState) 796 th.AssertEquals(t, "active", s.VmState) 797 th.AssertEquals(t, servers.Manual, s.DiskConfig) 798 799 err = servers.Get(context.TODO(), client, "1234asdf").ExtractInto(s) 800 if err == nil { 801 t.Errorf("Expected error when providing non-pointer struct") 802 } 803 } 804 805 func TestUpdateServer(t *testing.T) { 806 th.SetupHTTP() 807 defer th.TeardownHTTP() 808 HandleServerUpdateSuccessfully(t) 809 810 client := client.ServiceClient() 811 actual, err := servers.Update(context.TODO(), client, "1234asdf", servers.UpdateOpts{Name: "new-name"}).Extract() 812 if err != nil { 813 t.Fatalf("Unexpected Update error: %v", err) 814 } 815 816 th.CheckDeepEquals(t, ServerDerp, *actual) 817 } 818 819 func TestChangeServerAdminPassword(t *testing.T) { 820 th.SetupHTTP() 821 defer th.TeardownHTTP() 822 HandleAdminPasswordChangeSuccessfully(t) 823 824 res := servers.ChangeAdminPassword(context.TODO(), client.ServiceClient(), "1234asdf", "new-password") 825 th.AssertNoErr(t, res.Err) 826 } 827 828 func TestShowConsoleOutput(t *testing.T) { 829 th.SetupHTTP() 830 defer th.TeardownHTTP() 831 HandleShowConsoleOutputSuccessfully(t, ConsoleOutputBody) 832 833 outputOpts := &servers.ShowConsoleOutputOpts{ 834 Length: 50, 835 } 836 actual, err := servers.ShowConsoleOutput(context.TODO(), client.ServiceClient(), "1234asdf", outputOpts).Extract() 837 838 th.AssertNoErr(t, err) 839 th.AssertByteArrayEquals(t, []byte(ConsoleOutput), []byte(actual)) 840 } 841 842 func TestGetPassword(t *testing.T) { 843 th.SetupHTTP() 844 defer th.TeardownHTTP() 845 HandlePasswordGetSuccessfully(t) 846 847 res := servers.GetPassword(context.TODO(), client.ServiceClient(), "1234asdf") 848 th.AssertNoErr(t, res.Err) 849 } 850 851 func TestRebootServer(t *testing.T) { 852 th.SetupHTTP() 853 defer th.TeardownHTTP() 854 HandleRebootSuccessfully(t) 855 856 res := servers.Reboot(context.TODO(), client.ServiceClient(), "1234asdf", servers.RebootOpts{ 857 Type: servers.SoftReboot, 858 }) 859 th.AssertNoErr(t, res.Err) 860 } 861 862 func TestRebuildServer(t *testing.T) { 863 th.SetupHTTP() 864 defer th.TeardownHTTP() 865 HandleRebuildSuccessfully(t, SingleServerBody) 866 867 opts := servers.RebuildOpts{ 868 Name: "new-name", 869 AdminPass: "swordfish", 870 ImageRef: "f90f6034-2570-4974-8351-6b49732ef2eb", 871 AccessIPv4: "1.2.3.4", 872 } 873 874 actual, err := servers.Rebuild(context.TODO(), client.ServiceClient(), "1234asdf", opts).Extract() 875 th.AssertNoErr(t, err) 876 877 th.CheckDeepEquals(t, ServerDerp, *actual) 878 } 879 880 func TestRebuildServerWithDiskConfig(t *testing.T) { 881 opts := servers.RebuildOpts{ 882 Name: "rebuiltserver", 883 AdminPass: "swordfish", 884 ImageRef: "asdfasdfasdf", 885 DiskConfig: servers.Auto, 886 } 887 expected := ` 888 { 889 "rebuild": { 890 "name": "rebuiltserver", 891 "imageRef": "asdfasdfasdf", 892 "adminPass": "swordfish", 893 "OS-DCF:diskConfig": "AUTO" 894 } 895 } 896 ` 897 898 actual, err := opts.ToServerRebuildMap() 899 th.AssertNoErr(t, err) 900 th.CheckJSONEquals(t, expected, actual) 901 } 902 903 func TestResizeServer(t *testing.T) { 904 th.SetupHTTP() 905 defer th.TeardownHTTP() 906 907 th.Mux.HandleFunc("/servers/1234asdf/action", func(w http.ResponseWriter, r *http.Request) { 908 th.TestMethod(t, r, "POST") 909 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 910 th.TestJSONRequest(t, r, `{ "resize": { "flavorRef": "2" } }`) 911 912 w.WriteHeader(http.StatusAccepted) 913 }) 914 915 res := servers.Resize(context.TODO(), client.ServiceClient(), "1234asdf", servers.ResizeOpts{FlavorRef: "2"}) 916 th.AssertNoErr(t, res.Err) 917 } 918 919 func TestResizeServerWithDiskConfig(t *testing.T) { 920 opts := servers.ResizeOpts{ 921 FlavorRef: "performance1-8", 922 DiskConfig: servers.Auto, 923 } 924 expected := ` 925 { 926 "resize": { 927 "flavorRef": "performance1-8", 928 "OS-DCF:diskConfig": "AUTO" 929 } 930 } 931 ` 932 933 actual, err := opts.ToServerResizeMap() 934 th.AssertNoErr(t, err) 935 th.CheckJSONEquals(t, expected, actual) 936 } 937 938 func TestConfirmResize(t *testing.T) { 939 th.SetupHTTP() 940 defer th.TeardownHTTP() 941 942 th.Mux.HandleFunc("/servers/1234asdf/action", func(w http.ResponseWriter, r *http.Request) { 943 th.TestMethod(t, r, "POST") 944 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 945 th.TestJSONRequest(t, r, `{ "confirmResize": null }`) 946 947 w.WriteHeader(http.StatusNoContent) 948 }) 949 950 res := servers.ConfirmResize(context.TODO(), client.ServiceClient(), "1234asdf") 951 th.AssertNoErr(t, res.Err) 952 } 953 954 func TestRevertResize(t *testing.T) { 955 th.SetupHTTP() 956 defer th.TeardownHTTP() 957 958 th.Mux.HandleFunc("/servers/1234asdf/action", func(w http.ResponseWriter, r *http.Request) { 959 th.TestMethod(t, r, "POST") 960 th.TestHeader(t, r, "X-Auth-Token", client.TokenID) 961 th.TestJSONRequest(t, r, `{ "revertResize": null }`) 962 963 w.WriteHeader(http.StatusAccepted) 964 }) 965 966 res := servers.RevertResize(context.TODO(), client.ServiceClient(), "1234asdf") 967 th.AssertNoErr(t, res.Err) 968 } 969 970 func TestGetMetadatum(t *testing.T) { 971 th.SetupHTTP() 972 defer th.TeardownHTTP() 973 974 HandleMetadatumGetSuccessfully(t) 975 976 expected := map[string]string{"foo": "bar"} 977 actual, err := servers.Metadatum(context.TODO(), client.ServiceClient(), "1234asdf", "foo").Extract() 978 th.AssertNoErr(t, err) 979 th.AssertDeepEquals(t, expected, actual) 980 } 981 982 func TestCreateMetadatum(t *testing.T) { 983 th.SetupHTTP() 984 defer th.TeardownHTTP() 985 986 HandleMetadatumCreateSuccessfully(t) 987 988 expected := map[string]string{"foo": "bar"} 989 actual, err := servers.CreateMetadatum(context.TODO(), client.ServiceClient(), "1234asdf", servers.MetadatumOpts{"foo": "bar"}).Extract() 990 th.AssertNoErr(t, err) 991 th.AssertDeepEquals(t, expected, actual) 992 } 993 994 func TestDeleteMetadatum(t *testing.T) { 995 th.SetupHTTP() 996 defer th.TeardownHTTP() 997 998 HandleMetadatumDeleteSuccessfully(t) 999 1000 err := servers.DeleteMetadatum(context.TODO(), client.ServiceClient(), "1234asdf", "foo").ExtractErr() 1001 th.AssertNoErr(t, err) 1002 } 1003 1004 func TestGetMetadata(t *testing.T) { 1005 th.SetupHTTP() 1006 defer th.TeardownHTTP() 1007 1008 HandleMetadataGetSuccessfully(t) 1009 1010 expected := map[string]string{"foo": "bar", "this": "that"} 1011 actual, err := servers.Metadata(context.TODO(), client.ServiceClient(), "1234asdf").Extract() 1012 th.AssertNoErr(t, err) 1013 th.AssertDeepEquals(t, expected, actual) 1014 } 1015 1016 func TestResetMetadata(t *testing.T) { 1017 th.SetupHTTP() 1018 defer th.TeardownHTTP() 1019 1020 HandleMetadataResetSuccessfully(t) 1021 1022 expected := map[string]string{"foo": "bar", "this": "that"} 1023 actual, err := servers.ResetMetadata(context.TODO(), client.ServiceClient(), "1234asdf", servers.MetadataOpts{ 1024 "foo": "bar", 1025 "this": "that", 1026 }).Extract() 1027 th.AssertNoErr(t, err) 1028 th.AssertDeepEquals(t, expected, actual) 1029 } 1030 1031 func TestUpdateMetadata(t *testing.T) { 1032 th.SetupHTTP() 1033 defer th.TeardownHTTP() 1034 1035 HandleMetadataUpdateSuccessfully(t) 1036 1037 expected := map[string]string{"foo": "baz", "this": "those"} 1038 actual, err := servers.UpdateMetadata(context.TODO(), client.ServiceClient(), "1234asdf", servers.MetadataOpts{ 1039 "foo": "baz", 1040 "this": "those", 1041 }).Extract() 1042 th.AssertNoErr(t, err) 1043 th.AssertDeepEquals(t, expected, actual) 1044 } 1045 1046 func TestListAddresses(t *testing.T) { 1047 th.SetupHTTP() 1048 defer th.TeardownHTTP() 1049 HandleAddressListSuccessfully(t) 1050 1051 expected := ListAddressesExpected 1052 pages := 0 1053 err := servers.ListAddresses(client.ServiceClient(), "asdfasdfasdf").EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { 1054 pages++ 1055 1056 actual, err := servers.ExtractAddresses(page) 1057 th.AssertNoErr(t, err) 1058 1059 if len(actual) != 2 { 1060 t.Fatalf("Expected 2 networks, got %d", len(actual)) 1061 } 1062 th.CheckDeepEquals(t, expected, actual) 1063 1064 return true, nil 1065 }) 1066 th.AssertNoErr(t, err) 1067 th.CheckEquals(t, 1, pages) 1068 } 1069 1070 func TestListAddressesByNetwork(t *testing.T) { 1071 th.SetupHTTP() 1072 defer th.TeardownHTTP() 1073 HandleNetworkAddressListSuccessfully(t) 1074 1075 expected := ListNetworkAddressesExpected 1076 pages := 0 1077 err := servers.ListAddressesByNetwork(client.ServiceClient(), "asdfasdfasdf", "public").EachPage(context.TODO(), func(_ context.Context, page pagination.Page) (bool, error) { 1078 pages++ 1079 1080 actual, err := servers.ExtractNetworkAddresses(page) 1081 th.AssertNoErr(t, err) 1082 1083 if len(actual) != 2 { 1084 t.Fatalf("Expected 2 addresses, got %d", len(actual)) 1085 } 1086 th.CheckDeepEquals(t, expected, actual) 1087 1088 return true, nil 1089 }) 1090 th.AssertNoErr(t, err) 1091 th.CheckEquals(t, 1, pages) 1092 } 1093 1094 func TestCreateServerImage(t *testing.T) { 1095 th.SetupHTTP() 1096 defer th.TeardownHTTP() 1097 HandleCreateServerImageSuccessfully(t) 1098 1099 _, err := servers.CreateImage(context.TODO(), client.ServiceClient(), "serverimage", servers.CreateImageOpts{Name: "test"}).ExtractImageID() 1100 th.AssertNoErr(t, err) 1101 } 1102 1103 func TestMarshalPersonality(t *testing.T) { 1104 name := "/etc/test" 1105 contents := []byte("asdfasdf") 1106 1107 personality := servers.Personality{ 1108 &servers.File{ 1109 Path: name, 1110 Contents: contents, 1111 }, 1112 } 1113 1114 data, err := json.Marshal(personality) 1115 if err != nil { 1116 t.Fatal(err) 1117 } 1118 1119 var actual []map[string]string 1120 err = json.Unmarshal(data, &actual) 1121 if err != nil { 1122 t.Fatal(err) 1123 } 1124 1125 if len(actual) != 1 { 1126 t.Fatal("expected personality length 1") 1127 } 1128 1129 if actual[0]["path"] != name { 1130 t.Fatal("file path incorrect") 1131 } 1132 1133 if actual[0]["contents"] != base64.StdEncoding.EncodeToString(contents) { 1134 t.Fatal("file contents incorrect") 1135 } 1136 } 1137 1138 func TestCreateServerWithTags(t *testing.T) { 1139 th.SetupHTTP() 1140 defer th.TeardownHTTP() 1141 HandleServerWithTagsCreationSuccessfully(t) 1142 1143 c := client.ServiceClient() 1144 c.Microversion = "2.52" 1145 1146 tags := []string{"foo", "bar"} 1147 ServerDerpTags := ServerDerp 1148 ServerDerpTags.Tags = &tags 1149 ServerDerpTags.Locked = nil 1150 1151 createOpts := servers.CreateOpts{ 1152 Name: "derp", 1153 ImageRef: "f90f6034-2570-4974-8351-6b49732ef2eb", 1154 FlavorRef: "1", 1155 Tags: tags, 1156 } 1157 res := servers.Create(context.TODO(), c, createOpts, nil) 1158 th.AssertNoErr(t, res.Err) 1159 actualServer, err := res.Extract() 1160 th.AssertNoErr(t, err) 1161 th.CheckDeepEquals(t, ServerDerpTags, *actualServer) 1162 } 1163 1164 func TestCreateServerWithHypervisorHostname(t *testing.T) { 1165 opts := servers.CreateOpts{ 1166 Name: "createdserver", 1167 FlavorRef: "performance1-1", 1168 ImageRef: "asdfasdfasdf", 1169 HypervisorHostname: "test-hypervisor", 1170 } 1171 expected := ` 1172 { 1173 "server": { 1174 "name":"createdserver", 1175 "flavorRef":"performance1-1", 1176 "imageRef":"asdfasdfasdf", 1177 "hypervisor_hostname":"test-hypervisor" 1178 } 1179 } 1180 ` 1181 actual, err := opts.ToServerCreateMap() 1182 th.AssertNoErr(t, err) 1183 th.CheckJSONEquals(t, expected, actual) 1184 }