github.com/vmware/govmomi@v0.51.0/object/virtual_device_list_test.go (about) 1 // © Broadcom. All Rights Reserved. 2 // The term “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 3 // SPDX-License-Identifier: Apache-2.0 4 5 package object 6 7 import ( 8 "math/rand" 9 "reflect" 10 "testing" 11 12 "github.com/vmware/govmomi/vim25/types" 13 ) 14 15 func intPtrValue(val int32) *int32 { 16 return &val 17 } 18 19 var devices = VirtualDeviceList([]types.BaseVirtualDevice{ 20 &types.VirtualIDEController{ 21 VirtualController: types.VirtualController{ 22 VirtualDevice: types.VirtualDevice{ 23 DynamicData: types.DynamicData{}, 24 Key: 200, 25 DeviceInfo: &types.Description{ 26 DynamicData: types.DynamicData{}, 27 Label: "IDE 0", 28 Summary: "IDE 0", 29 }, 30 Backing: nil, 31 Connectable: (*types.VirtualDeviceConnectInfo)(nil), 32 SlotInfo: nil, 33 ControllerKey: 0, 34 UnitNumber: intPtrValue(0), 35 }, 36 BusNumber: 0, 37 Device: []int32{3001, 3000}, 38 }, 39 }, 40 &types.VirtualIDEController{ 41 VirtualController: types.VirtualController{ 42 VirtualDevice: types.VirtualDevice{ 43 DynamicData: types.DynamicData{}, 44 Key: 201, 45 DeviceInfo: &types.Description{ 46 DynamicData: types.DynamicData{}, 47 Label: "IDE 1", 48 Summary: "IDE 1", 49 }, 50 Backing: nil, 51 Connectable: (*types.VirtualDeviceConnectInfo)(nil), 52 SlotInfo: nil, 53 ControllerKey: 0, 54 UnitNumber: intPtrValue(0), 55 }, 56 BusNumber: 1, 57 Device: []int32{3002}, 58 }, 59 }, 60 &types.VirtualPS2Controller{ 61 VirtualController: types.VirtualController{ 62 VirtualDevice: types.VirtualDevice{ 63 DynamicData: types.DynamicData{}, 64 Key: 300, 65 DeviceInfo: &types.Description{ 66 DynamicData: types.DynamicData{}, 67 Label: "PS2 controller 0", 68 Summary: "PS2 controller 0", 69 }, 70 Backing: nil, 71 Connectable: (*types.VirtualDeviceConnectInfo)(nil), 72 SlotInfo: nil, 73 ControllerKey: 0, 74 UnitNumber: intPtrValue(0), 75 }, 76 BusNumber: 0, 77 Device: []int32{600, 700}, 78 }, 79 }, 80 &types.VirtualPCIController{ 81 VirtualController: types.VirtualController{ 82 VirtualDevice: types.VirtualDevice{ 83 DynamicData: types.DynamicData{}, 84 Key: 100, 85 DeviceInfo: &types.Description{ 86 DynamicData: types.DynamicData{}, 87 Label: "PCI controller 0", 88 Summary: "PCI controller 0", 89 }, 90 Backing: nil, 91 Connectable: (*types.VirtualDeviceConnectInfo)(nil), 92 SlotInfo: nil, 93 ControllerKey: 0, 94 UnitNumber: intPtrValue(0), 95 }, 96 BusNumber: 0, 97 Device: []int32{500, 12000, 1000, 4000}, 98 }, 99 }, 100 &types.VirtualSIOController{ 101 VirtualController: types.VirtualController{ 102 VirtualDevice: types.VirtualDevice{ 103 DynamicData: types.DynamicData{}, 104 Key: 400, 105 DeviceInfo: &types.Description{ 106 DynamicData: types.DynamicData{}, 107 Label: "SIO controller 0", 108 Summary: "SIO controller 0", 109 }, 110 Backing: nil, 111 Connectable: (*types.VirtualDeviceConnectInfo)(nil), 112 SlotInfo: nil, 113 ControllerKey: 0, 114 UnitNumber: intPtrValue(0), 115 }, 116 BusNumber: 0, 117 Device: []int32{9000}, 118 }, 119 }, 120 &types.VirtualKeyboard{ 121 VirtualDevice: types.VirtualDevice{ 122 DynamicData: types.DynamicData{}, 123 Key: 600, 124 DeviceInfo: &types.Description{ 125 DynamicData: types.DynamicData{}, 126 Label: "Keyboard ", 127 Summary: "Keyboard", 128 }, 129 Backing: nil, 130 Connectable: (*types.VirtualDeviceConnectInfo)(nil), 131 SlotInfo: nil, 132 ControllerKey: 300, 133 UnitNumber: intPtrValue(0), 134 }, 135 }, 136 &types.VirtualPointingDevice{ 137 VirtualDevice: types.VirtualDevice{ 138 DynamicData: types.DynamicData{}, 139 Key: 700, 140 DeviceInfo: &types.Description{ 141 DynamicData: types.DynamicData{}, 142 Label: "Pointing device", 143 Summary: "Pointing device; Device", 144 }, 145 Backing: &types.VirtualPointingDeviceDeviceBackingInfo{ 146 VirtualDeviceDeviceBackingInfo: types.VirtualDeviceDeviceBackingInfo{}, 147 HostPointingDevice: "autodetect", 148 }, 149 Connectable: (*types.VirtualDeviceConnectInfo)(nil), 150 SlotInfo: nil, 151 ControllerKey: 300, 152 UnitNumber: intPtrValue(1), 153 }, 154 }, 155 &types.VirtualMachineVideoCard{ 156 VirtualDevice: types.VirtualDevice{ 157 DynamicData: types.DynamicData{}, 158 Key: 500, 159 DeviceInfo: &types.Description{ 160 DynamicData: types.DynamicData{}, 161 Label: "Video card ", 162 Summary: "Video card", 163 }, 164 Backing: nil, 165 Connectable: (*types.VirtualDeviceConnectInfo)(nil), 166 SlotInfo: nil, 167 ControllerKey: 100, 168 UnitNumber: intPtrValue(0), 169 }, 170 VideoRamSizeInKB: 4096, 171 NumDisplays: 1, 172 UseAutoDetect: types.NewBool(false), 173 Enable3DSupport: types.NewBool(false), 174 Use3dRenderer: "automatic", 175 }, 176 &types.VirtualMachineVMCIDevice{ 177 VirtualDevice: types.VirtualDevice{ 178 DynamicData: types.DynamicData{}, 179 Key: 12000, 180 DeviceInfo: &types.Description{ 181 DynamicData: types.DynamicData{}, 182 Label: "VMCI device", 183 Summary: "Device on the virtual machine PCI bus that provides support for the virtual machine communication interface", 184 }, 185 Backing: nil, 186 Connectable: (*types.VirtualDeviceConnectInfo)(nil), 187 SlotInfo: &types.VirtualDevicePciBusSlotInfo{ 188 VirtualDeviceBusSlotInfo: types.VirtualDeviceBusSlotInfo{}, 189 PciSlotNumber: 33, 190 }, 191 ControllerKey: 100, 192 UnitNumber: intPtrValue(17), 193 }, 194 Id: 1754519335, 195 AllowUnrestrictedCommunication: types.NewBool(false), 196 }, 197 &types.VirtualLsiLogicController{ 198 VirtualSCSIController: types.VirtualSCSIController{ 199 VirtualController: types.VirtualController{ 200 VirtualDevice: types.VirtualDevice{ 201 DynamicData: types.DynamicData{}, 202 Key: 1000, 203 DeviceInfo: &types.Description{ 204 DynamicData: types.DynamicData{}, 205 Label: "SCSI controller 0", 206 Summary: "LSI Logic", 207 }, 208 Backing: nil, 209 Connectable: (*types.VirtualDeviceConnectInfo)(nil), 210 SlotInfo: nil, 211 ControllerKey: 100, 212 UnitNumber: intPtrValue(3), 213 }, 214 BusNumber: 0, 215 Device: nil, 216 }, 217 HotAddRemove: types.NewBool(true), 218 SharedBus: "noSharing", 219 ScsiCtlrUnitNumber: 7, 220 }, 221 }, 222 &types.VirtualCdrom{ 223 VirtualDevice: types.VirtualDevice{ 224 DynamicData: types.DynamicData{}, 225 Key: 3001, 226 DeviceInfo: &types.Description{ 227 DynamicData: types.DynamicData{}, 228 Label: "CD/DVD drive 1", 229 Summary: "ISO [datastore1] ttylinux-pc_i486-16.1.iso", 230 }, 231 Backing: &types.VirtualCdromIsoBackingInfo{ 232 VirtualDeviceFileBackingInfo: types.VirtualDeviceFileBackingInfo{ 233 VirtualDeviceBackingInfo: types.VirtualDeviceBackingInfo{}, 234 FileName: "[datastore1] foo.iso", 235 Datastore: &types.ManagedObjectReference{Type: "Datastore", Value: "53fe43cc-75dc5110-3643-000c2918dc41"}, 236 BackingObjectId: "", 237 }, 238 }, 239 Connectable: &types.VirtualDeviceConnectInfo{ 240 DynamicData: types.DynamicData{}, 241 StartConnected: true, 242 AllowGuestControl: true, 243 Connected: false, 244 Status: "untried", 245 }, 246 SlotInfo: nil, 247 ControllerKey: 200, 248 UnitNumber: intPtrValue(1), 249 }, 250 }, 251 &types.VirtualDisk{ 252 VirtualDevice: types.VirtualDevice{ 253 DynamicData: types.DynamicData{}, 254 Key: 3000, 255 DeviceInfo: &types.Description{ 256 DynamicData: types.DynamicData{}, 257 Label: "Hard disk 1", 258 Summary: "30,720 KB", 259 }, 260 Backing: &types.VirtualDiskFlatVer2BackingInfo{ 261 VirtualDeviceFileBackingInfo: types.VirtualDeviceFileBackingInfo{ 262 VirtualDeviceBackingInfo: types.VirtualDeviceBackingInfo{}, 263 FileName: "[datastore1] bar/bar.vmdk", 264 Datastore: &types.ManagedObjectReference{Type: "Datastore", Value: "53fe43cc-75dc5110-3643-000c2918dc41"}, 265 BackingObjectId: "3-3000-0", 266 }, 267 DiskMode: "persistent", 268 Split: types.NewBool(false), 269 WriteThrough: types.NewBool(false), 270 ThinProvisioned: types.NewBool(false), 271 EagerlyScrub: types.NewBool(true), 272 Uuid: "6000C296-d0af-1209-1975-10c98eae10e4", 273 ContentId: "d46395062e2d1b1790985bdec573b211", 274 ChangeId: "", 275 Parent: &types.VirtualDiskFlatVer2BackingInfo{ 276 VirtualDeviceFileBackingInfo: types.VirtualDeviceFileBackingInfo{ 277 VirtualDeviceBackingInfo: types.VirtualDeviceBackingInfo{}, 278 FileName: "[datastore1] ttylinux.vmdk", 279 Datastore: &types.ManagedObjectReference{Type: "Datastore", Value: "53fe43cc-75dc5110-3643-000c2918dc41"}, 280 BackingObjectId: "3-3000-1", 281 }, 282 DiskMode: "persistent", 283 Split: types.NewBool(false), 284 WriteThrough: types.NewBool(false), 285 ThinProvisioned: types.NewBool(false), 286 EagerlyScrub: types.NewBool(true), 287 Uuid: "6000C296-d0af-1209-1975-10c98eae10e4", 288 ContentId: "1c2dad9e1662219e962a620c6d238a7c", 289 ChangeId: "", 290 Parent: (*types.VirtualDiskFlatVer2BackingInfo)(nil), 291 DeltaDiskFormat: "", 292 DigestEnabled: types.NewBool(false), 293 DeltaGrainSize: 0, 294 }, 295 DeltaDiskFormat: "redoLogFormat", 296 DigestEnabled: types.NewBool(false), 297 DeltaGrainSize: 0, 298 }, 299 Connectable: (*types.VirtualDeviceConnectInfo)(nil), 300 SlotInfo: nil, 301 ControllerKey: 200, 302 UnitNumber: intPtrValue(0), 303 }, 304 CapacityInKB: 30720, 305 CapacityInBytes: 31457280, 306 Shares: &types.SharesInfo{ 307 DynamicData: types.DynamicData{}, 308 Shares: 1000, 309 Level: "normal", 310 }, 311 StorageIOAllocation: &types.StorageIOAllocationInfo{ 312 DynamicData: types.DynamicData{}, 313 Limit: types.NewInt64(-1), 314 Shares: &types.SharesInfo{ 315 DynamicData: types.DynamicData{}, 316 Shares: 1000, 317 Level: "normal", 318 }, 319 Reservation: types.NewInt32(0), 320 }, 321 DiskObjectId: "3-3000", 322 VFlashCacheConfigInfo: (*types.VirtualDiskVFlashCacheConfigInfo)(nil), 323 }, 324 &types.VirtualDisk{ 325 VirtualDevice: types.VirtualDevice{ 326 DynamicData: types.DynamicData{}, 327 Key: 3002, 328 DeviceInfo: &types.Description{ 329 DynamicData: types.DynamicData{}, 330 Label: "Hard disk 2", 331 Summary: "10,000,000 KB", 332 }, 333 Backing: &types.VirtualDiskFlatVer2BackingInfo{ 334 VirtualDeviceFileBackingInfo: types.VirtualDeviceFileBackingInfo{ 335 VirtualDeviceBackingInfo: types.VirtualDeviceBackingInfo{}, 336 FileName: "[datastore1] bar/disk-201-0.vmdk", 337 Datastore: &types.ManagedObjectReference{Type: "Datastore", Value: "53fe43cc-75dc5110-3643-000c2918dc41"}, 338 BackingObjectId: "3-3002-0", 339 }, 340 DiskMode: "persistent", 341 Split: types.NewBool(false), 342 WriteThrough: types.NewBool(false), 343 ThinProvisioned: types.NewBool(true), 344 EagerlyScrub: types.NewBool(false), 345 Uuid: "6000C293-fde5-4457-5118-dd267ea992a7", 346 ContentId: "90399989b9d520eed6793ab0fffffffe", 347 ChangeId: "", 348 Parent: (*types.VirtualDiskFlatVer2BackingInfo)(nil), 349 DeltaDiskFormat: "", 350 DigestEnabled: types.NewBool(false), 351 DeltaGrainSize: 0, 352 }, 353 Connectable: (*types.VirtualDeviceConnectInfo)(nil), 354 SlotInfo: nil, 355 ControllerKey: 201, 356 UnitNumber: intPtrValue(0), 357 }, 358 CapacityInKB: 10000000, 359 CapacityInBytes: 10240000000, 360 Shares: &types.SharesInfo{ 361 DynamicData: types.DynamicData{}, 362 Shares: 1000, 363 Level: "normal", 364 }, 365 StorageIOAllocation: &types.StorageIOAllocationInfo{ 366 DynamicData: types.DynamicData{}, 367 Limit: types.NewInt64(-1), 368 Shares: &types.SharesInfo{ 369 DynamicData: types.DynamicData{}, 370 Shares: 1000, 371 Level: "normal", 372 }, 373 Reservation: types.NewInt32(0), 374 }, 375 DiskObjectId: "3-3002", 376 VFlashCacheConfigInfo: (*types.VirtualDiskVFlashCacheConfigInfo)(nil), 377 }, 378 &types.VirtualE1000{ 379 VirtualEthernetCard: types.VirtualEthernetCard{ 380 VirtualDevice: types.VirtualDevice{ 381 DynamicData: types.DynamicData{}, 382 Key: 4000, 383 DeviceInfo: &types.Description{ 384 DynamicData: types.DynamicData{}, 385 Label: "Network adapter 1", 386 Summary: "VM Network", 387 }, 388 Backing: &types.VirtualEthernetCardNetworkBackingInfo{ 389 VirtualDeviceDeviceBackingInfo: types.VirtualDeviceDeviceBackingInfo{ 390 VirtualDeviceBackingInfo: types.VirtualDeviceBackingInfo{}, 391 DeviceName: "VM Network", 392 UseAutoDetect: types.NewBool(false), 393 }, 394 Network: &types.ManagedObjectReference{Type: "Network", Value: "HaNetwork-VM Network"}, 395 InPassthroughMode: types.NewBool(false), 396 }, 397 Connectable: &types.VirtualDeviceConnectInfo{ 398 DynamicData: types.DynamicData{}, 399 StartConnected: true, 400 AllowGuestControl: true, 401 Connected: false, 402 Status: "untried", 403 }, 404 SlotInfo: &types.VirtualDevicePciBusSlotInfo{ 405 VirtualDeviceBusSlotInfo: types.VirtualDeviceBusSlotInfo{}, 406 PciSlotNumber: 32, 407 }, 408 ControllerKey: 100, 409 UnitNumber: intPtrValue(7), 410 }, 411 AddressType: "generated", 412 MacAddress: "00:0c:29:93:d7:27", 413 WakeOnLanEnabled: types.NewBool(true), 414 }, 415 }, 416 &types.VirtualSerialPort{ 417 VirtualDevice: types.VirtualDevice{ 418 DynamicData: types.DynamicData{}, 419 Key: 9000, 420 DeviceInfo: &types.Description{ 421 DynamicData: types.DynamicData{}, 422 Label: "Serial port 1", 423 Summary: "Remote localhost:0", 424 }, 425 Backing: &types.VirtualSerialPortURIBackingInfo{ 426 VirtualDeviceURIBackingInfo: types.VirtualDeviceURIBackingInfo{ 427 VirtualDeviceBackingInfo: types.VirtualDeviceBackingInfo{}, 428 ServiceURI: "localhost:0", 429 Direction: "client", 430 ProxyURI: "", 431 }, 432 }, 433 Connectable: &types.VirtualDeviceConnectInfo{ 434 DynamicData: types.DynamicData{}, 435 StartConnected: true, 436 AllowGuestControl: true, 437 Connected: false, 438 Status: "untried", 439 }, 440 SlotInfo: nil, 441 ControllerKey: 400, 442 UnitNumber: intPtrValue(0), 443 }, 444 YieldOnPoll: true, 445 }, 446 &types.VirtualPCIPassthrough{ 447 VirtualDevice: types.VirtualDevice{ 448 Key: 13000, 449 DeviceInfo: &types.Description{ 450 Label: "PCI device 0", 451 Summary: "NVIDIA GRID vGPU grid_v100-4q", 452 }, 453 Backing: &types.VirtualPCIPassthroughVmiopBackingInfo{ 454 VirtualPCIPassthroughPluginBackingInfo: types.VirtualPCIPassthroughPluginBackingInfo{}, 455 Vgpu: "grid_v100-4q", 456 MigrateSupported: (*bool)(nil), 457 }, 458 Connectable: (*types.VirtualDeviceConnectInfo)(nil), 459 SlotInfo: &types.VirtualDevicePciBusSlotInfo{ 460 VirtualDeviceBusSlotInfo: types.VirtualDeviceBusSlotInfo{}, 461 PciSlotNumber: 33, 462 }, 463 ControllerKey: 100, 464 UnitNumber: types.NewInt32(18), 465 }, 466 }, 467 &types.VirtualPCIPassthrough{ 468 VirtualDevice: types.VirtualDevice{ 469 Key: 14000, 470 DeviceInfo: &types.Description{ 471 Label: "PCI device 1", 472 Summary: "NVIDIA GPU", 473 }, 474 Backing: &types.VirtualPCIPassthroughDynamicBackingInfo{ 475 AllowedDevice: []types.VirtualPCIPassthroughAllowedDevice{{ 476 VendorId: int32(111), 477 DeviceId: int32(222), 478 }}, 479 CustomLabel: "mygpu", 480 }, 481 Connectable: (*types.VirtualDeviceConnectInfo)(nil), 482 SlotInfo: &types.VirtualDevicePciBusSlotInfo{ 483 VirtualDeviceBusSlotInfo: types.VirtualDeviceBusSlotInfo{}, 484 PciSlotNumber: 34, 485 }, 486 ControllerKey: 100, 487 UnitNumber: types.NewInt32(19), 488 }, 489 }, 490 }) 491 492 func TestSelectByType(t *testing.T) { 493 tests := []struct { 494 dtype types.BaseVirtualDevice 495 expect int 496 }{ 497 { 498 (*types.VirtualCdrom)(nil), 499 1, 500 }, 501 { 502 (*types.VirtualEthernetCard)(nil), 503 1, 504 }, 505 { 506 (*types.VirtualDisk)(nil), 507 2, 508 }, 509 { 510 (*types.VirtualController)(nil), 511 6, 512 }, 513 { 514 (*types.VirtualIDEController)(nil), 515 2, 516 }, 517 { 518 (*types.VirtualSCSIController)(nil), 519 1, 520 }, 521 { 522 (*types.VirtualLsiLogicController)(nil), 523 1, 524 }, 525 { 526 (*types.ParaVirtualSCSIController)(nil), 527 0, 528 }, 529 } 530 531 for _, test := range tests { 532 d := devices.SelectByType(test.dtype) 533 534 if len(d) != test.expect { 535 t.Errorf("%#v has %d", test.dtype, len(devices)) 536 } 537 } 538 } 539 540 func TestSelectByBackingInfo(t *testing.T) { 541 tests := []types.BaseVirtualDeviceBackingInfo{ 542 &types.VirtualEthernetCardNetworkBackingInfo{ 543 VirtualDeviceDeviceBackingInfo: types.VirtualDeviceDeviceBackingInfo{ 544 DeviceName: "VM Network", 545 }, 546 }, 547 &types.VirtualDiskFlatVer2BackingInfo{ 548 VirtualDeviceFileBackingInfo: types.VirtualDeviceFileBackingInfo{ 549 FileName: "[datastore1] bar/bar.vmdk", 550 }, 551 }, 552 &types.VirtualDiskFlatVer2BackingInfo{ 553 Parent: &types.VirtualDiskFlatVer2BackingInfo{ 554 VirtualDeviceFileBackingInfo: types.VirtualDeviceFileBackingInfo{ 555 FileName: "[datastore1] ttylinux.vmdk", 556 }, 557 }, 558 }, 559 &types.VirtualCdromIsoBackingInfo{ 560 VirtualDeviceFileBackingInfo: types.VirtualDeviceFileBackingInfo{ 561 VirtualDeviceBackingInfo: types.VirtualDeviceBackingInfo{}, 562 FileName: "[datastore1] foo.iso", 563 }, 564 }, 565 (*types.VirtualCdromIsoBackingInfo)(nil), 566 &types.VirtualSerialPortURIBackingInfo{ 567 VirtualDeviceURIBackingInfo: types.VirtualDeviceURIBackingInfo{ 568 VirtualDeviceBackingInfo: types.VirtualDeviceBackingInfo{}, 569 ServiceURI: "localhost:0", 570 Direction: "client", 571 ProxyURI: "", 572 }, 573 }, 574 (*types.VirtualSerialPortURIBackingInfo)(nil), 575 &types.VirtualPCIPassthroughVmiopBackingInfo{ 576 Vgpu: "grid_v100-4q", 577 }, 578 (*types.VirtualPCIPassthroughVmiopBackingInfo)(nil), 579 (*types.VirtualPCIPassthroughDynamicBackingInfo)(nil), 580 &types.VirtualPCIPassthroughDynamicBackingInfo{ 581 CustomLabel: "mygpu", 582 }, 583 &types.VirtualPCIPassthroughDynamicBackingInfo{ 584 AllowedDevice: []types.VirtualPCIPassthroughAllowedDevice{{ 585 VendorId: int32(111), 586 DeviceId: int32(222), 587 }}, 588 }, 589 } 590 591 for _, test := range tests { 592 l := devices.SelectByBackingInfo(test) 593 594 if len(l) != 1 { 595 t.Errorf("Expected 1, got %d: %#v", len(l), test) 596 } 597 } 598 599 // test selecting by backing type 600 tests = []types.BaseVirtualDeviceBackingInfo{ 601 (*types.VirtualDiskFlatVer2BackingInfo)(nil), 602 } 603 604 for _, test := range tests { 605 l := devices.SelectByBackingInfo(test) 606 607 if len(l) != 2 { 608 t.Errorf("Expected 2, got %d: %#v", len(l), test) 609 } 610 } 611 } 612 613 func TestFind(t *testing.T) { 614 for _, device := range devices { 615 name := devices.Name(device) 616 d := devices.Find(name) 617 if name != devices.Name(d) { 618 t.Errorf("expected name: %s, got: %s", name, devices.Name(d)) 619 } 620 } 621 622 d := devices.Find("enoent") 623 if d != nil { 624 t.Errorf("unexpected: %#v", d) 625 } 626 } 627 628 func TestFindController(t *testing.T) { 629 for _, name := range []string{"", "ide-200"} { 630 _, err := devices.FindIDEController(name) 631 if err != nil { 632 t.Error(err) 633 } 634 } 635 636 for _, name := range []string{"", "lsilogic-1000"} { 637 _, err := devices.FindSCSIController(name) 638 if err != nil { 639 t.Error(err) 640 } 641 } 642 643 fns := []func() error{ 644 func() error { 645 _, err := devices.FindIDEController("lsilogic-1000") 646 return err 647 }, 648 func() error { 649 _, err := devices.FindSCSIController("ide-200") 650 return err 651 }, 652 } 653 654 for _, f := range fns { 655 err := f() 656 if err == nil { 657 t.Error("should fail") 658 } 659 } 660 } 661 662 func TestPickController(t *testing.T) { 663 list := devices 664 665 tests := []struct { 666 ctype types.BaseVirtualController 667 key int32 668 unit int32 669 }{ 670 { 671 (*types.VirtualIDEController)(nil), 201, 1, 672 }, 673 { 674 (*types.VirtualSCSIController)(nil), 1000, 0, 675 }, 676 { 677 (*types.VirtualSCSIController)(nil), 1000, 1, 678 }, 679 } 680 681 for _, test := range tests { 682 c := list.PickController(test.ctype).GetVirtualController() 683 684 key := c.Key 685 if key != test.key { 686 t.Errorf("expected controller key: %d, got: %d\n", test.key, key) 687 } 688 689 unit := list.newUnitNumber(c, 0) 690 if unit != test.unit { 691 t.Errorf("expected unit number: %d, got: %d\n", test.unit, unit) 692 } 693 694 dev := &types.VirtualDevice{ 695 Key: int32(rand.Int()), 696 UnitNumber: new(int32), 697 ControllerKey: key, 698 } 699 *dev.UnitNumber = unit 700 701 list = append(list, dev) 702 c.Device = append(c.Device, dev.Key) 703 } 704 705 if list.PickController((*types.VirtualIDEController)(nil)) != nil { 706 t.Error("should be nil") 707 } 708 709 if list.PickController((*types.VirtualSCSIController)(nil)) == nil { 710 t.Errorf("should not be nil") 711 } 712 } 713 714 func TestAssignController(t *testing.T) { 715 scsi, _ := devices.CreateSCSIController("scsi") 716 disk := &types.VirtualDisk{ 717 CapacityInBytes: 512 * 1024, 718 VirtualDevice: types.VirtualDevice{ 719 Backing: new(types.VirtualDiskFlatVer2BackingInfo), // Leave fields empty to test defaults 720 }, 721 } 722 723 devices := VirtualDeviceList([]types.BaseVirtualDevice{scsi}) 724 devices.AssignController(disk, scsi.(*types.VirtualLsiLogicController)) 725 726 if disk.ControllerKey != scsi.GetVirtualDevice().Key { 727 t.Errorf("expected controller key: %d, got: %d\n", scsi.GetVirtualDevice().Key, disk.ControllerKey) 728 } 729 730 // if disk does not have device key, AssignController gives a random negative key to the disk 731 // so that it will not collide with existing device keys 732 if disk.Key >= 0 { 733 t.Errorf("device key %d should be negative", disk.Key) 734 } 735 736 // AssignController should add the disk to the controller's device list. 737 cd := scsi.(*types.VirtualLsiLogicController).Device[0] 738 if cd != disk.Key { 739 t.Errorf("expected controller device key: %d, got: %d\n", disk.Key, cd) 740 } 741 } 742 743 func TestCreateSCSIController(t *testing.T) { 744 for _, l := range []VirtualDeviceList{SCSIControllerTypes(), devices} { 745 _, err := l.CreateSCSIController("enoent") 746 if err == nil { 747 t.Error("should fail") 748 } 749 750 for _, name := range []string{"", "scsi", "pvscsi", "buslogic", "lsilogic", "lsilogic-sas"} { 751 _, err = l.CreateSCSIController(name) 752 if err != nil { 753 t.Error(err) 754 } 755 } 756 } 757 } 758 759 func TestCreateSATAController(t *testing.T) { 760 l := VirtualDeviceList{} 761 for _, i := range sataBusNumbers { 762 c, err := l.CreateSATAController() 763 if err != nil { 764 t.Error(err) 765 } 766 if j := c.(types.BaseVirtualController).GetVirtualController().BusNumber; j != int32(i) { 767 t.Errorf("expected bus number: %d, got: %d", i, j) 768 } 769 l = append(l, c) 770 } 771 772 if _, err := l.CreateSATAController(); err == nil { 773 t.Error("should fail") 774 } 775 } 776 777 func TestCreateEthernetCard(t *testing.T) { 778 _, err := EthernetCardTypes().CreateEthernetCard("enoent", nil) 779 if err == nil { 780 t.Error("should fail") 781 } 782 783 for _, name := range []string{"", "e1000", "e1000e", "vmxnet2", "vmxnet3", "pcnet32", "sriov"} { 784 c, err := EthernetCardTypes().CreateEthernetCard(name, nil) 785 if err != nil { 786 t.Error(err) 787 } 788 789 if key := c.GetVirtualDevice().Key; key >= 0 { 790 t.Errorf("device key %d should be negative", key) 791 } 792 } 793 } 794 795 func TestCdrom(t *testing.T) { 796 c, err := devices.FindCdrom("") 797 if err != nil { 798 t.Error(err) 799 } 800 801 d := devices.Find(devices.Name(c)) 802 803 if c.Key != d.GetVirtualDevice().Key { 804 t.Error("device key mismatch") 805 } 806 807 for _, name := range []string{"enoent", "ide-200"} { 808 _, err = devices.FindCdrom(name) 809 if err == nil { 810 t.Errorf("FindCdrom(%s) should fail", name) 811 } 812 } 813 814 _, err = devices.Select(func(device types.BaseVirtualDevice) bool { 815 if _, ok := device.(*types.VirtualCdrom); ok { 816 return false 817 } 818 return true 819 }).FindCdrom("") 820 821 if err == nil { 822 t.Error("FindCdrom('') should fail") 823 } 824 } 825 826 func TestSerialPort(t *testing.T) { 827 device, err := devices.CreateSerialPort() 828 if err != nil { 829 t.Error(err) 830 } 831 devices.ConnectSerialPort(device, "telnet://:33233", false, "") 832 } 833 834 func TestPrimaryMacAddress(t *testing.T) { 835 expect := "00:0c:29:93:d7:27" 836 mac := devices.PrimaryMacAddress() 837 if expect != mac { 838 t.Errorf("expected: %s, got: %s", expect, mac) 839 } 840 } 841 842 func TestBootOrder(t *testing.T) { 843 o := []string{DeviceTypeEthernet, DeviceTypeCdrom, DeviceTypeFloppy, DeviceTypeDisk} 844 list := devices 845 846 n := 4 // 1 ethernet, 1 cdrom, 2 disk 847 order := list.BootOrder(o) 848 if len(order) != n { 849 t.Errorf("expected %d boot devices, got: %d", n, len(order)) 850 } 851 852 list = list.SelectBootOrder(order) 853 if len(list) != n { 854 t.Errorf("expected %d boot devices, got: %d", n, len(list)) 855 } 856 857 // test lookup by name 858 var names []string 859 for _, x := range list { 860 names = append(names, list.Name(x)) 861 } 862 863 order = list.BootOrder(names) 864 if len(order) != n { 865 t.Errorf("expected %d boot devices, got: %d", n, len(order)) 866 } 867 868 if !reflect.DeepEqual(list, list.SelectBootOrder(order)) { 869 t.Error("boot order mismatch") 870 } 871 872 // remove disks 873 list = list.Select(func(device types.BaseVirtualDevice) bool { 874 if _, ok := device.(*types.VirtualDisk); ok { 875 return false 876 } 877 return true 878 }) 879 880 n = 2 // 1 ethernet, 1 cdrom 881 order = list.BootOrder(o) 882 if len(order) != n { 883 t.Errorf("expected %d boot devices, got: %d", n, len(order)) 884 } 885 886 if !reflect.DeepEqual(list, list.SelectBootOrder(order)) { 887 t.Error("boot order mismatch") 888 } 889 890 if len(list.BootOrder([]string{DeviceTypeDisk})) != 0 { 891 t.Error("expected 0 disks") 892 } 893 894 if len(list.BootOrder([]string{DeviceTypeNone})) != 1 { 895 t.Error("expected 1") 896 } 897 } 898 899 func TestName(t *testing.T) { 900 tests := []struct { 901 device types.BaseVirtualDevice 902 expect string 903 }{ 904 { 905 &types.VirtualCdrom{}, 906 "cdrom-0", 907 }, 908 { 909 &types.VirtualDisk{}, 910 "disk-0-0", 911 }, 912 { 913 &types.VirtualFloppy{}, 914 "floppy-0", 915 }, 916 { 917 &types.VirtualIDEController{}, 918 "ide-0", 919 }, 920 { 921 &types.VirtualMachineVideoCard{}, 922 "video-0", 923 }, 924 { 925 &types.VirtualPointingDevice{}, 926 "pointing-0", 927 }, 928 { 929 &types.ParaVirtualSCSIController{}, 930 "pvscsi-0", 931 }, 932 { 933 &types.VirtualSerialPort{}, 934 "serialport-0", 935 }, 936 { 937 &types.VirtualE1000{ 938 VirtualEthernetCard: types.VirtualEthernetCard{ 939 VirtualDevice: types.VirtualDevice{ 940 UnitNumber: intPtrValue(7), 941 }, 942 }, 943 }, 944 "ethernet-0", 945 }, 946 } 947 948 for _, test := range tests { 949 name := devices.Name(test.device) 950 if name != test.expect { 951 t.Errorf("expected: %s, got: %s", test.expect, name) 952 } 953 } 954 } 955 956 func TestChildDisk(t *testing.T) { 957 disks := devices.SelectByType((*types.VirtualDisk)(nil)) 958 959 for _, disk := range disks { 960 child := disks.ChildDisk(disk.(*types.VirtualDisk)) 961 name := child.Backing.(*types.VirtualDiskFlatVer2BackingInfo).VirtualDeviceFileBackingInfo.FileName 962 963 p := new(DatastorePath) 964 p.FromString(name) 965 966 if p.Datastore != "datastore1" { 967 t.Fatal(p.Datastore) 968 } 969 970 if p.Path != "" { 971 t.Fatal(p.Path) 972 } 973 } 974 }