github.com/vmware/govmomi@v0.43.0/simulator/finder_test.go (about) 1 /* 2 Copyright (c) 2017-2023 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 "errors" 22 "fmt" 23 "reflect" 24 "testing" 25 26 "github.com/vmware/govmomi" 27 "github.com/vmware/govmomi/find" 28 "github.com/vmware/govmomi/object" 29 "github.com/vmware/govmomi/vim25" 30 "github.com/vmware/govmomi/vim25/types" 31 ) 32 33 func TestFinderVPX(t *testing.T) { 34 ctx := context.Background() 35 36 m := VPX() 37 m.Datacenter = 3 38 m.Folder = 2 39 m.Pool = 1 40 41 defer m.Remove() 42 43 err := m.Create() 44 if err != nil { 45 t.Fatal(err) 46 } 47 48 s := m.Service.NewServer() 49 defer s.Close() 50 51 client, err := govmomi.NewClient(ctx, s.URL, true) 52 if err != nil { 53 t.Fatal(err) 54 } 55 56 finder := find.NewFinder(client.Client, false) 57 dc, _ := finder.Datacenter(ctx, "/F0/DC1") 58 finder.SetDatacenter(dc) 59 60 tests := []struct { 61 kind string 62 path string 63 expect int 64 }{ 65 {"ManagedObjectList", "./*", 4}, // /F0/DC1/{vm,host,network,datastore} 66 {"ManagedObjectListChildren", ".", 4}, // "" 67 {"ManagedObjectList", "/", 1}, 68 {"ManagedObjectList", "/*", m.Datacenter - m.Folder + m.Folder}, 69 {"ManagedObjectList", "/DC0", 1}, 70 {"ManagedObjectList", "/F[01]", 2}, 71 {"ManagedObjectListChildren", "/*", m.Datacenter + 3}, 72 {"ManagedObjectListChildren", "/*/*", 19}, 73 {"ManagedObjectListChildren", "/*/*/*", 31}, 74 {"FolderList", "/*", m.Folder}, 75 {"DatacenterList", "/F0/*", 1}, 76 {"DatacenterList", "/DC0", 1}, 77 {"VirtualMachineList", "/DC0/vm/*", (m.Host + m.Cluster) * m.Machine}, 78 {"VirtualMachineList", "F0/DC1_C0_RP1_VM0", 1}, 79 {"VirtualMachineList", "./DC1_C0_RP1_VM0", 0}, 80 {"VirtualMachineList", "DC1_C0_RP1_VM0", 1}, // find . -type VirtualMachine -name DC1_C0_RP0_VM0 81 {"VirtualAppList", "/DC0/vm/*", 0}, 82 {"DatastoreList", "/DC0/datastore/*", m.Datastore}, 83 {"DatastoreList", "./*", 0}, 84 {"DatastoreList", "./F0/*", m.Datastore}, 85 {"DatastoreList", "/F*/*/datastore/F*/*", m.Datastore * m.Folder}, 86 {"DatastoreList", "/F0/DC1/datastore/F0/LocalDS_0", m.Datastore}, 87 {"DatastoreList", "/F0/DC1/datastore/F0/*", m.Datastore}, 88 {"DatastoreList", "/F1/DC2/datastore/F1/*", m.Datastore}, 89 {"DatastoreList", "./LocalDS_0", 0}, 90 {"DatastoreList", "LocalDS_0", 1}, // find . -type Datastore -name LocalDS_0 91 {"DatastoreClusterList", "/DC0/datastore/*", 0}, 92 {"ComputeResourceList", "/DC0/host/*", m.Host + m.Cluster}, 93 {"ClusterComputeResourceList", "/DC0/host/*", m.Cluster}, 94 {"HostSystemList", "/DC0/host/*", m.Host + m.ClusterHost}, 95 {"HostSystemList", "/F0/DC1/host/F0/*", m.Host + m.ClusterHost}, 96 {"HostSystemList", "DC1_H0", 1}, // find . -type HostSystem -name DC1_H0 97 {"ComputeResourceList", "DC1_H0", 1}, // find . -type ComputeResource -name DC1_H0 98 {"ClusterComputeResourceList", "DC1_C0", 1}, // find . -type ClusterComputeResource -name DC1_H0 99 {"NetworkList", "/DC0/network/*", 3 + m.Portgroup}, // VM Network + DSwitch + DSwitch-Uplinks + m.Portgroup 100 {"NetworkList", "./*", 1}, 101 {"NetworkList", "/F0/DC1/network/VM Network", 1}, 102 {"NetworkList", "/F0/DC1/network/F0/*", 2 + m.Portgroup}, 103 {"NetworkList", "./F0/DC1_DVPG0", 1}, 104 {"NetworkList", "./F0/DC1_DVPG0", 1}, 105 {"NetworkList", "DC1_DVPG0", 1}, // find . -type Network -name DC1_DVPG0 106 {"ResourcePoolList", "/F0/DC1/host/F0/*", m.Host + m.Cluster}, 107 {"ResourcePoolList", "/F0/DC1/host/F0/*/*", m.Host + m.Cluster}, 108 {"ResourcePoolList", "/DC0/host/*", m.Host + m.Cluster}, 109 {"ResourcePoolList", "/DC0/host/*/*", m.Host + m.Cluster}, 110 {"ResourcePoolList", "/DC0/host/DC0_H0/Resources", 1}, 111 {"ResourcePoolList", "/F1/DC2/host/F1/DC2_C0/Resources", 1}, 112 {"ResourcePoolList", "Resources", m.Host + m.Cluster}, // find . -type ResourcePool -name Resources 113 {"ResourcePoolList", "/F1/DC2/...", m.Pool + m.Host + 1}, // find $path -type ResourcePool 114 {"ResourcePoolList", "/F1/DC2/host/...", m.Pool + m.Host + 1}, // find $path -type ResourcePool 115 {"ResourcePoolList", "/F1/DC2/host/F1/...", m.Pool + m.Host + 1}, // find $path -type ResourcePool 116 {"ResourcePoolList", "/F1/DC2/host/F1/DC2_C0/...", m.Pool + 1}, // find $path -type ResourcePool 117 {"ResourcePoolList", "/F1/DC2/host/F1/DC2_C0/Resources/...", m.Pool}, // find $path -type ResourcePool 118 {"ResourcePoolList", "F0/DC1_C0", 1}, 119 {"ResourcePoolList", "DC1_C0_RP1", 1}, // find . -type ResourcePool -name DC1_C0_RP1 120 {"", "", 0}, // unset Datacenter 121 {"DatacenterList", "*", m.Datacenter}, // find . -type Datacenter 122 {"DatacenterList", "./...", m.Datacenter}, // find . -type Datacenter 123 {"DatacenterList", "DC2", 1}, // find . -type Datacenter -name DC2 124 {"DatacenterList", "/*", m.Datacenter - m.Folder}, 125 {"DatacenterList", "/*/*", m.Folder}, 126 {"DatastoreList", "/F1/DC2/datastore/F1/LocalDS_0", 1}, 127 {"VirtualMachineList", "DC1_C0_RP1_VM0", 0}, // TODO: recurse all Datacenters? 128 } 129 130 f := reflect.ValueOf(finder) 131 c := reflect.ValueOf(ctx) 132 133 for i, test := range tests { 134 if test.kind == "" { 135 finder.SetDatacenter(nil) 136 continue 137 } 138 139 err = nil 140 141 arg := []reflect.Value{c, reflect.ValueOf(test.path)} 142 res := f.MethodByName(test.kind).Call(arg) 143 144 rval := res[0] 145 rerr := res[1] 146 147 if rval.Len() != test.expect { 148 msg := fmt.Sprintf("expected %d, got %d", test.expect, rval.Len()) 149 if !rerr.IsNil() { 150 msg += fmt.Sprintf(" (%s)", rerr.Interface()) 151 } 152 err = errors.New(msg) 153 154 if !rval.IsNil() { 155 for j := 0; j < rval.Len(); j++ { 156 t.Logf("%s\n", rval.Index(j).Interface()) 157 } 158 } 159 } else if !rerr.IsNil() { 160 if test.expect != 0 { 161 err = rerr.Interface().(error) 162 } 163 } 164 165 if err != nil { 166 t.Errorf("%d) %s(%s): %s", i, test.kind, test.path, err) 167 } 168 } 169 } 170 171 func TestFinderESX(t *testing.T) { 172 ctx := context.Background() 173 174 m := ESX() 175 176 defer m.Remove() 177 178 err := m.Create() 179 if err != nil { 180 t.Fatal(err) 181 } 182 183 s := m.Service.NewServer() 184 defer s.Close() 185 186 client, err := govmomi.NewClient(ctx, s.URL, true) 187 if err != nil { 188 t.Fatal(err) 189 } 190 191 finder := find.NewFinder(client.Client, false) 192 193 dc, err := finder.DefaultDatacenter(ctx) 194 if err != nil { 195 t.Fatal(err) 196 } 197 198 finder.SetDatacenter(dc) 199 200 f := reflect.ValueOf(finder) 201 c := reflect.ValueOf(ctx) 202 203 tests := []string{"Folder", "Datastore", "ComputeResource", "HostSystem", "Datastore", "Network"} 204 205 for _, test := range tests { 206 res := f.MethodByName("Default" + test).Call([]reflect.Value{c}) 207 if !res[1].IsNil() { 208 t.Fatalf("%s: %s", test, res[1].Interface()) 209 } 210 211 // test find by moref 212 ref := res[0].Interface().(object.Reference).Reference() 213 o, err := finder.Element(ctx, ref) 214 if err != nil { 215 t.Fatal(err) 216 } 217 218 if o.Object.Reference() != ref { 219 t.Errorf("%s", ref) 220 } 221 } 222 } 223 224 func TestFinderDefaultHostVPX(t *testing.T) { 225 ctx := context.Background() 226 227 m := VPX() 228 m.Folder = 1 229 230 defer m.Remove() 231 232 err := m.Create() 233 if err != nil { 234 t.Fatal(err) 235 } 236 237 s := m.Service.NewServer() 238 defer s.Close() 239 240 client, err := govmomi.NewClient(ctx, s.URL, true) 241 if err != nil { 242 t.Fatal(err) 243 } 244 245 finder := find.NewFinder(client.Client, false) 246 dc, _ := finder.Datacenter(ctx, "/F0/DC0") 247 finder.SetDatacenter(dc) 248 249 hostf, _ := finder.Folder(ctx, dc.InventoryPath+"/host/F0") 250 251 folders, err := dc.Folders(ctx) 252 if err != nil { 253 t.Fatal(err) 254 } 255 256 f, err := folders.HostFolder.CreateFolder(ctx, "MyHosts") 257 if err != nil { 258 t.Fatal(err) 259 } 260 261 // 2-levels (MyHosts/F0) deep under the DC host folder: /F0/DC0/host/MyHosts/F0/DC0_C0/DC0_C0_H0 262 task, _ := f.MoveInto(ctx, []types.ManagedObjectReference{hostf.Reference()}) 263 if err = task.Wait(ctx); err != nil { 264 t.Fatal(err) 265 } 266 267 _, err = finder.HostSystemOrDefault(ctx, "") 268 if err == nil { 269 t.Fatal("expected error") 270 } 271 272 _, ok := err.(*find.DefaultMultipleFoundError) 273 if !ok { 274 t.Errorf("unexpected error type=%T", err) 275 } 276 } 277 278 func TestFinderDestroyedParentResourcePool(t *testing.T) { 279 Test(func(ctx context.Context, c *vim25.Client) { 280 finder := find.NewFinder(c) 281 282 rp, err := finder.ResourcePool(ctx, "/DC0/host/DC0_C0/Resources") 283 if err != nil { 284 t.Fatal(err) 285 } 286 287 foo, err := rp.Create(ctx, "foo", types.DefaultResourceConfigSpec()) 288 if err != nil { 289 t.Fatal(err) 290 } 291 292 bar, err := foo.Create(ctx, "bar", types.DefaultResourceConfigSpec()) 293 if err != nil { 294 t.Fatal(err) 295 } 296 297 task, err := foo.Destroy(ctx) 298 if err != nil { 299 t.Fatal(err) 300 } 301 if err := task.WaitEx(ctx); err != nil { 302 t.Fatal(err) 303 } 304 305 if _, err := finder.Element(ctx, bar.Reference()); err != nil { 306 t.Fatal(err) 307 } 308 }) 309 }