github.com/vmware/govmomi@v0.43.0/simulator/cluster_compute_resource_test.go (about) 1 /* 2 Copyright (c) 2017 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 simulator 18 19 import ( 20 "context" 21 "path" 22 "strings" 23 "testing" 24 25 "github.com/stretchr/testify/require" 26 27 "github.com/vmware/govmomi" 28 "github.com/vmware/govmomi/find" 29 "github.com/vmware/govmomi/object" 30 "github.com/vmware/govmomi/simulator/esx" 31 "github.com/vmware/govmomi/simulator/vpx" 32 "github.com/vmware/govmomi/vim25" 33 "github.com/vmware/govmomi/vim25/types" 34 ) 35 36 func TestClusterESX(t *testing.T) { 37 content := esx.ServiceContent 38 s := New(NewServiceInstance(SpoofContext(), content, esx.RootFolder)) 39 40 ts := s.NewServer() 41 defer ts.Close() 42 43 ctx := context.Background() 44 c, err := govmomi.NewClient(ctx, ts.URL, true) 45 if err != nil { 46 t.Fatal(err) 47 } 48 49 dc := object.NewDatacenter(c.Client, esx.Datacenter.Reference()) 50 51 folders, err := dc.Folders(ctx) 52 if err != nil { 53 t.Fatal(err) 54 } 55 56 _, err = folders.HostFolder.CreateCluster(ctx, "cluster1", types.ClusterConfigSpecEx{}) 57 if err == nil { 58 t.Fatal("expected error") 59 } 60 } 61 62 func TestClusterVC(t *testing.T) { 63 content := vpx.ServiceContent 64 s := New(NewServiceInstance(SpoofContext(), content, vpx.RootFolder)) 65 66 ts := s.NewServer() 67 defer ts.Close() 68 69 ctx := context.Background() 70 c, err := govmomi.NewClient(ctx, ts.URL, true) 71 if err != nil { 72 t.Fatal(err) 73 } 74 75 f := object.NewRootFolder(c.Client) 76 77 dc, err := f.CreateDatacenter(ctx, "foo") 78 if err != nil { 79 t.Error(err) 80 } 81 82 folders, err := dc.Folders(ctx) 83 if err != nil { 84 t.Fatal(err) 85 } 86 87 cluster, err := folders.HostFolder.CreateCluster(ctx, "cluster1", types.ClusterConfigSpecEx{}) 88 if err != nil { 89 t.Fatal(err) 90 } 91 92 // Enable DRS and HA for the cluster 93 clusterSpec := types.ClusterConfigSpecEx{ 94 DrsConfig: &types.ClusterDrsConfigInfo{ 95 Enabled: types.NewBool(true), 96 DefaultVmBehavior: types.DrsBehaviorFullyAutomated, // Set DRS to fully automated 97 }, 98 DasConfig: &types.ClusterDasConfigInfo{ 99 Enabled: types.NewBool(true), 100 }, 101 } 102 103 task, err := cluster.Reconfigure(ctx, &clusterSpec, true) 104 require.NoError(t, err) 105 err = task.Wait(ctx) 106 require.NoError(t, err) 107 108 // Check if DRS and HA is set 109 110 finder := find.NewFinder(c.Client, false).SetDatacenter(dc) 111 pathname := path.Join(dc.InventoryPath, "host", "cluster1") 112 clusterComputeResource, err := finder.ClusterComputeResource(ctx, pathname) 113 require.NoError(t, err) 114 clusterComputeInfo, err := clusterComputeResource.Configuration(ctx) 115 require.NoError(t, err) 116 require.NotNil(t, clusterComputeInfo.DrsConfig.Enabled) 117 require.NotNil(t, clusterComputeInfo.DasConfig.Enabled) 118 require.True(t, *clusterComputeInfo.DrsConfig.Enabled) 119 require.True(t, *clusterComputeInfo.DasConfig.Enabled) 120 require.True(t, clusterComputeInfo.DrsConfig.DefaultVmBehavior == types.DrsBehaviorFullyAutomated) 121 _, err = folders.HostFolder.CreateCluster(ctx, "cluster1", types.ClusterConfigSpecEx{}) 122 if err == nil { 123 t.Error("expected DuplicateName error") 124 } 125 126 spec := types.HostConnectSpec{} 127 128 for _, fail := range []bool{true, false} { 129 task, err := cluster.AddHost(ctx, spec, true, nil, nil) 130 if err != nil { 131 t.Fatal(err) 132 } 133 134 _, err = task.WaitForResult(ctx, nil) 135 136 if fail { 137 if err == nil { 138 t.Error("expected error") 139 } 140 spec.HostName = "localhost" 141 } else { 142 if err != nil { 143 t.Error(err) 144 } 145 } 146 } 147 } 148 149 func TestPlaceVmReconfigure(t *testing.T) { 150 tests := []struct { 151 name string 152 configSpec *types.VirtualMachineConfigSpec 153 placementType types.PlacementSpecPlacementType 154 expectedErr string 155 }{ 156 { 157 "unsupported placement type", 158 nil, 159 types.PlacementSpecPlacementType("unsupported"), 160 "NotSupported", 161 }, 162 { 163 "create", 164 nil, 165 types.PlacementSpecPlacementTypeCreate, 166 "", 167 }, 168 { 169 "reconfigure with nil config spec", 170 nil, 171 types.PlacementSpecPlacementTypeReconfigure, 172 "InvalidArgument", 173 }, 174 { 175 "reconfigure with an empty config spec", 176 &types.VirtualMachineConfigSpec{}, 177 types.PlacementSpecPlacementTypeReconfigure, 178 "", 179 }, 180 } 181 182 for _, test := range tests { 183 test := test // assign to local var since loop var is reused 184 Test(func(ctx context.Context, c *vim25.Client) { 185 // Test env setup. 186 finder := find.NewFinder(c, true) 187 datacenter, err := finder.DefaultDatacenter(ctx) 188 if err != nil { 189 t.Fatalf("failed to get default datacenter: %v", err) 190 } 191 finder.SetDatacenter(datacenter) 192 vmMoRef := Map.Any("VirtualMachine").(*VirtualMachine).Reference() 193 clusterMoRef := Map.Any("ClusterComputeResource").(*ClusterComputeResource).Reference() 194 clusterObj := object.NewClusterComputeResource(c, clusterMoRef) 195 196 // PlaceVm. 197 placementSpec := types.PlacementSpec{ 198 Vm: &vmMoRef, 199 ConfigSpec: test.configSpec, 200 PlacementType: string(test.placementType), 201 } 202 _, err = clusterObj.PlaceVm(ctx, placementSpec) 203 if err != nil && !strings.Contains(err.Error(), test.expectedErr) { 204 t.Fatalf("expected error %q, got %v", test.expectedErr, err) 205 } 206 }) 207 } 208 } 209 210 func TestPlaceVmRelocate(t *testing.T) { 211 Test(func(ctx context.Context, c *vim25.Client) { 212 // Test env setup. 213 finder := find.NewFinder(c, true) 214 datacenter, err := finder.DefaultDatacenter(ctx) 215 if err != nil { 216 t.Fatalf("failed to get default datacenter: %v", err) 217 } 218 finder.SetDatacenter(datacenter) 219 220 vmMoRef := Map.Any("VirtualMachine").(*VirtualMachine).Reference() 221 hostMoRef := Map.Any("HostSystem").(*HostSystem).Reference() 222 dsMoRef := Map.Any("Datastore").(*Datastore).Reference() 223 224 tests := []struct { 225 name string 226 relocateSpec *types.VirtualMachineRelocateSpec 227 vmMoRef *types.ManagedObjectReference 228 expectedErr string 229 }{ 230 { 231 "relocate without a spec", 232 nil, 233 &vmMoRef, 234 "", 235 }, 236 { 237 "relocate with an empty spec", 238 &types.VirtualMachineRelocateSpec{}, 239 &vmMoRef, 240 "", 241 }, 242 { 243 "relocate without a vm in spec", 244 &types.VirtualMachineRelocateSpec{ 245 Host: &hostMoRef, 246 }, 247 nil, 248 "InvalidArgument", 249 }, 250 { 251 "relocate with a non-existing vm in spec", 252 &types.VirtualMachineRelocateSpec{ 253 Host: &hostMoRef, 254 }, 255 &types.ManagedObjectReference{ 256 Type: "VirtualMachine", 257 Value: "fake-vm-999", 258 }, 259 "InvalidArgument", 260 }, 261 { 262 "relocate with a diskId in spec.dick that does not exist in the vm", 263 &types.VirtualMachineRelocateSpec{ 264 Host: &hostMoRef, 265 Disk: []types.VirtualMachineRelocateSpecDiskLocator{ 266 { 267 DiskId: 1, 268 Datastore: dsMoRef, 269 }, 270 }, 271 }, 272 &vmMoRef, 273 "InvalidArgument", 274 }, 275 { 276 "relocate with a non-existing datastore in spec.disk", 277 &types.VirtualMachineRelocateSpec{ 278 Host: &hostMoRef, 279 Disk: []types.VirtualMachineRelocateSpecDiskLocator{ 280 { 281 DiskId: 204, // The default diskId in simulator. 282 Datastore: types.ManagedObjectReference{ 283 Type: "Datastore", 284 Value: "fake-datastore-999", 285 }, 286 }, 287 }, 288 }, 289 &vmMoRef, 290 "InvalidArgument", 291 }, 292 { 293 "relocate with a valid spec.disk", 294 &types.VirtualMachineRelocateSpec{ 295 Host: &hostMoRef, 296 Disk: []types.VirtualMachineRelocateSpecDiskLocator{ 297 { 298 DiskId: 204, // The default diskId in simulator. 299 Datastore: dsMoRef, 300 }, 301 }, 302 }, 303 &vmMoRef, 304 "", 305 }, 306 { 307 "relocate with a valid host in spec", 308 &types.VirtualMachineRelocateSpec{ 309 Host: &hostMoRef, 310 }, 311 &vmMoRef, 312 "", 313 }, 314 { 315 "relocate with a non-existing host in spec", 316 &types.VirtualMachineRelocateSpec{ 317 Host: &types.ManagedObjectReference{ 318 Type: "HostSystem", 319 Value: "fake-host-999", 320 }, 321 }, 322 &vmMoRef, 323 "ManagedObjectNotFound", 324 }, 325 { 326 "relocate with a non-existing datastore in spec", 327 &types.VirtualMachineRelocateSpec{ 328 Datastore: &types.ManagedObjectReference{ 329 Type: "Datastore", 330 Value: "fake-datastore-999", 331 }, 332 }, 333 &vmMoRef, 334 "ManagedObjectNotFound", 335 }, 336 { 337 "relocate with a non-existing resource pool in spec", 338 &types.VirtualMachineRelocateSpec{ 339 Pool: &types.ManagedObjectReference{ 340 Type: "ResourcePool", 341 Value: "fake-resource-pool-999", 342 }, 343 }, 344 &vmMoRef, 345 "ManagedObjectNotFound", 346 }, 347 } 348 349 for _, test := range tests { 350 test := test // assign to local var since loop var is reused 351 // PlaceVm. 352 placementSpec := types.PlacementSpec{ 353 Vm: test.vmMoRef, 354 RelocateSpec: test.relocateSpec, 355 PlacementType: string(types.PlacementSpecPlacementTypeRelocate), 356 } 357 358 clusterMoRef := Map.Any("ClusterComputeResource").(*ClusterComputeResource).Reference() 359 clusterObj := object.NewClusterComputeResource(c, clusterMoRef) 360 _, err = clusterObj.PlaceVm(ctx, placementSpec) 361 if err == nil && test.expectedErr != "" { 362 t.Fatalf("expected error %q, got nil", test.expectedErr) 363 } else if err != nil && !strings.Contains(err.Error(), test.expectedErr) { 364 t.Fatalf("expected error %q, got %v", test.expectedErr, err) 365 } 366 } 367 }) 368 }