github.com/vmware/govmomi@v0.43.0/simulator/resource_pool_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 "reflect" 22 "testing" 23 24 "github.com/google/uuid" 25 26 "github.com/vmware/govmomi/find" 27 "github.com/vmware/govmomi/object" 28 "github.com/vmware/govmomi/property" 29 "github.com/vmware/govmomi/simulator/esx" 30 "github.com/vmware/govmomi/vim25/mo" 31 "github.com/vmware/govmomi/vim25/soap" 32 "github.com/vmware/govmomi/vim25/types" 33 ) 34 35 func TestResourcePool(t *testing.T) { 36 ctx := context.Background() 37 38 m := &Model{ 39 ServiceContent: esx.ServiceContent, 40 RootFolder: esx.RootFolder, 41 } 42 43 err := m.Create() 44 if err != nil { 45 t.Fatal(err) 46 } 47 48 c := m.Service.client 49 50 finder := find.NewFinder(c, false) 51 finder.SetDatacenter(object.NewDatacenter(c, esx.Datacenter.Reference())) 52 53 spec := types.DefaultResourceConfigSpec() 54 55 parent := object.NewResourcePool(c, esx.ResourcePool.Self) 56 57 spec.CpuAllocation.Reservation = nil 58 // missing required field (Reservation) for create 59 _, err = parent.Create(ctx, "fail", spec) 60 if err == nil { 61 t.Error("expected error") 62 } 63 spec = types.DefaultResourceConfigSpec() 64 65 // can't destroy a root pool 66 task, err := parent.Destroy(ctx) 67 if err != nil { 68 t.Fatal(err) 69 } 70 if err = task.Wait(ctx); err == nil { 71 t.Fatal("expected error destroying a root pool") 72 } 73 74 // create a child pool 75 childName := uuid.New().String() 76 77 child, err := parent.Create(ctx, childName, spec) 78 if err != nil { 79 t.Fatal(err) 80 } 81 82 if child.Reference() == esx.ResourcePool.Self { 83 t.Error("expected new pool Self reference") 84 } 85 86 *spec.CpuAllocation.Reservation = -1 87 // invalid field value (Reservation) for update 88 err = child.UpdateConfig(ctx, "", &spec) 89 if err == nil { 90 t.Error("expected error") 91 } 92 93 // valid config update 94 *spec.CpuAllocation.Reservation = 10 95 err = child.UpdateConfig(ctx, "", &spec) 96 if err != nil { 97 t.Error(err) 98 } 99 100 var p mo.ResourcePool 101 err = child.Properties(ctx, child.Reference(), []string{"config.cpuAllocation"}, &p) 102 if err != nil { 103 t.Error(err) 104 } 105 106 if *p.Config.CpuAllocation.Reservation != 10 { 107 t.Error("config not updated") 108 } 109 110 // duplicate name 111 _, err = parent.Create(ctx, childName, spec) 112 if err == nil { 113 t.Error("expected error") 114 } 115 116 // create a grandchild pool 117 grandChildName := uuid.New().String() 118 _, err = child.Create(ctx, grandChildName, spec) 119 if err != nil { 120 t.Fatal(err) 121 } 122 123 // create sibling (of the grand child) pool 124 siblingName := uuid.New().String() 125 _, err = child.Create(ctx, siblingName, spec) 126 if err != nil { 127 t.Fatal(err) 128 } 129 130 // finder should return the 2 grand children 131 pools, err := finder.ResourcePoolList(ctx, "*/Resources/"+childName+"/*") 132 if err != nil { 133 t.Fatal(err) 134 } 135 if len(pools) != 2 { 136 t.Fatalf("len(pools) == %d", len(pools)) 137 } 138 139 // destroy the child 140 task, err = child.Destroy(ctx) 141 if err != nil { 142 t.Fatal(err) 143 } 144 err = task.Wait(ctx) 145 if err != nil { 146 t.Fatal(err) 147 } 148 149 // finder should error not found after destroying the child 150 _, err = finder.ResourcePoolList(ctx, "*/Resources/"+childName+"/*") 151 if err == nil { 152 t.Fatal("expected not found error") 153 } 154 155 // since the child was destroyed, grand child pools should now be children of the root pool 156 pools, err = finder.ResourcePoolList(ctx, "*/Resources/*") 157 if err != nil { 158 t.Fatal(err) 159 } 160 161 if len(pools) != 2 { 162 t.Fatalf("len(pools) == %d", len(pools)) 163 } 164 } 165 166 func TestCreateVAppESX(t *testing.T) { 167 ctx := context.Background() 168 169 m := ESX() 170 m.Datastore = 0 171 m.Machine = 0 172 173 err := m.Create() 174 if err != nil { 175 t.Fatal(err) 176 } 177 178 c := m.Service.client 179 180 parent := object.NewResourcePool(c, esx.ResourcePool.Self) 181 182 rspec := types.DefaultResourceConfigSpec() 183 vspec := NewVAppConfigSpec() 184 185 _, err = parent.CreateVApp(ctx, "myapp", rspec, vspec, nil) 186 if err == nil { 187 t.Fatal("expected error") 188 } 189 190 fault := soap.ToSoapFault(err).Detail.Fault 191 192 if reflect.TypeOf(fault) != reflect.TypeOf(&types.MethodDisabled{}) { 193 t.Errorf("fault=%#v", fault) 194 } 195 } 196 197 func TestCreateVAppVPX(t *testing.T) { 198 ctx := context.Background() 199 200 m := VPX() 201 202 err := m.Create() 203 if err != nil { 204 t.Fatal(err) 205 } 206 207 defer m.Remove() 208 209 c := m.Service.client 210 211 pool := Map.Any("ResourcePool") 212 parent := object.NewResourcePool(c, pool.Reference()) 213 rspec := types.DefaultResourceConfigSpec() 214 vspec := NewVAppConfigSpec() 215 216 vapp, err := parent.CreateVApp(ctx, "myapp", rspec, vspec, nil) 217 if err != nil { 218 t.Fatal(err) 219 } 220 221 _, err = parent.CreateVApp(ctx, "myapp", rspec, vspec, nil) 222 if err == nil { 223 t.Error("expected error") 224 } 225 226 spec := types.VirtualMachineConfigSpec{ 227 GuestId: string(types.VirtualMachineGuestOsIdentifierOtherGuest), 228 Files: &types.VirtualMachineFileInfo{ 229 VmPathName: "[LocalDS_0]", 230 }, 231 } 232 233 for _, fail := range []bool{true, false} { 234 task, cerr := vapp.CreateChildVM(ctx, spec, nil) 235 if cerr != nil { 236 t.Fatal(err) 237 } 238 239 cerr = task.Wait(ctx) 240 if fail { 241 if cerr == nil { 242 t.Error("expected error") 243 } 244 } else { 245 if cerr != nil { 246 t.Error(err) 247 } 248 } 249 250 spec.Name = "test" 251 } 252 253 si := object.NewSearchIndex(c) 254 vm, err := si.FindChild(ctx, vapp, spec.Name) 255 if err != nil { 256 t.Fatal(err) 257 } 258 259 if vm == nil { 260 t.Errorf("FindChild(%s)==nil", spec.Name) 261 } 262 263 ref := Map.Get(Map.getEntityDatacenter(pool).VmFolder).Reference() 264 folder, err := object.NewFolder(c, ref).CreateFolder(ctx, "myapp-clone") 265 if err != nil { 266 t.Fatal(err) 267 } 268 269 cspec := types.VAppCloneSpec{ 270 VmFolder: types.NewReference(folder.Reference()), 271 } 272 273 task, err := vapp.Clone(ctx, "myapp-clone", parent.Reference(), cspec) 274 if err != nil { 275 t.Fatal(err) 276 } 277 278 res, err := task.WaitForResult(ctx, nil) 279 if err != nil { 280 t.Fatal(err) 281 } 282 283 var apps []mo.VirtualApp 284 refs := []types.ManagedObjectReference{vapp.Reference(), res.Result.(types.ManagedObjectReference)} 285 err = property.DefaultCollector(c).Retrieve(ctx, refs, []string{"vm"}, &apps) 286 if err != nil { 287 t.Fatal(err) 288 } 289 290 if len(apps) != 2 { 291 t.Errorf("apps=%d", len(apps)) 292 } 293 294 for _, app := range apps { 295 if len(app.Vm) != 1 { 296 t.Errorf("app %s vm=%d", app.Reference(), len(app.Vm)) 297 } 298 } 299 300 task, err = vapp.Destroy(ctx) 301 if err != nil { 302 t.Fatal(err) 303 } 304 305 err = task.Wait(ctx) 306 if err != nil { 307 t.Fatal(err) 308 } 309 } 310 311 func TestResourcePoolValidation(t *testing.T) { 312 tests := []func() bool{ 313 func() bool { 314 return allResourceFieldsSet(&types.ResourceAllocationInfo{}) 315 }, 316 func() bool { 317 spec := types.DefaultResourceConfigSpec() 318 spec.CpuAllocation.Limit = nil 319 return allResourceFieldsSet(&spec.CpuAllocation) 320 }, 321 func() bool { 322 spec := types.DefaultResourceConfigSpec() 323 spec.CpuAllocation.Reservation = nil 324 return allResourceFieldsSet(&spec.CpuAllocation) 325 }, 326 func() bool { 327 spec := types.DefaultResourceConfigSpec() 328 spec.CpuAllocation.ExpandableReservation = nil 329 return allResourceFieldsSet(&spec.CpuAllocation) 330 }, 331 func() bool { 332 spec := types.DefaultResourceConfigSpec() 333 spec.CpuAllocation.Shares = nil 334 return allResourceFieldsSet(&spec.CpuAllocation) 335 }, 336 func() bool { 337 spec := types.DefaultResourceConfigSpec() 338 spec.CpuAllocation.Reservation = types.NewInt64(-1) 339 return allResourceFieldsValid(&spec.CpuAllocation) 340 }, 341 func() bool { 342 spec := types.DefaultResourceConfigSpec() 343 spec.CpuAllocation.Limit = types.NewInt64(-100) 344 return allResourceFieldsValid(&spec.CpuAllocation) 345 }, 346 func() bool { 347 spec := types.DefaultResourceConfigSpec() 348 shares := spec.CpuAllocation.Shares 349 shares.Level = types.SharesLevelCustom 350 shares.Shares = -1 351 return allResourceFieldsValid(&spec.CpuAllocation) 352 }, 353 } 354 355 for i, test := range tests { 356 ok := test() 357 if ok { 358 t.Errorf("%d: expected false", i) 359 } 360 } 361 }