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  }