github.com/vmware/govmomi@v0.37.2/object/virtual_device_list_test.go (about)

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