github.com/vmware/govmomi@v0.51.0/simulator/view_manager_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 simulator 6 7 import ( 8 "context" 9 "log" 10 "sync" 11 "testing" 12 13 "github.com/vmware/govmomi/vim25" 14 15 "github.com/vmware/govmomi" 16 "github.com/vmware/govmomi/object" 17 "github.com/vmware/govmomi/property" 18 "github.com/vmware/govmomi/view" 19 "github.com/vmware/govmomi/vim25/mo" 20 "github.com/vmware/govmomi/vim25/types" 21 ) 22 23 func TestContainerViewVPX(t *testing.T) { 24 ctx := context.Background() 25 26 m := VPX() 27 m.Datacenter = 3 28 m.Folder = 2 29 m.Pool = 1 30 m.App = 1 31 m.Pod = 1 32 33 defer m.Remove() 34 35 err := m.Create() 36 if err != nil { 37 t.Fatal(err) 38 } 39 40 s := m.Service.NewServer() 41 defer s.Close() 42 43 c, err := govmomi.NewClient(ctx, s.URL, true) 44 if err != nil { 45 t.Fatal(err) 46 } 47 48 v := view.NewManager(c.Client) 49 root := c.Client.ServiceContent.RootFolder 50 51 // test container type validation 52 _, err = v.CreateContainerView(ctx, v.Reference(), nil, false) 53 if err == nil { 54 t.Fatal("expected error") 55 } 56 57 // test container value validation 58 _, err = v.CreateContainerView(ctx, types.ManagedObjectReference{Value: "enoent"}, nil, false) 59 if err == nil { 60 t.Fatal("expected error") 61 } 62 63 // test types validation 64 _, err = v.CreateContainerView(ctx, root, []string{"enoent"}, false) 65 if err == nil { 66 t.Fatal("expected error") 67 } 68 69 vapp := object.NewVirtualApp(c.Client, m.Map().Any("VirtualApp").Reference()) 70 71 count := m.Count() 72 73 tests := []struct { 74 root types.ManagedObjectReference 75 recurse bool 76 kinds []string 77 expect int 78 }{ 79 {root, false, nil, m.Datacenter - m.Folder + m.Folder}, 80 {root, true, nil, count.total - 1}, // not including the root Folder 81 {root, true, []string{"ManagedEntity"}, count.total - 1}, // not including the root Folder 82 {root, true, []string{"Folder"}, count.Folder + count.Pod - 1}, // not including the root Folder 83 {root, false, []string{"HostSystem"}, 0}, 84 {root, true, []string{"HostSystem"}, count.Host}, 85 {root, false, []string{"Datacenter"}, m.Datacenter - m.Folder}, 86 {root, true, []string{"Datacenter"}, count.Datacenter}, 87 {root, true, []string{"Datastore"}, count.Datastore}, 88 {root, true, []string{"VirtualMachine"}, count.Machine}, 89 {root, true, []string{"ResourcePool"}, count.Pool + count.App}, 90 {root, true, []string{"VirtualApp"}, count.App}, 91 {vapp.Reference(), true, []string{"VirtualMachine"}, m.Machine}, 92 {root, true, []string{"ClusterComputeResource"}, count.Cluster}, 93 {root, true, []string{"ComputeResource"}, (m.Cluster + m.Host) * m.Datacenter}, 94 {root, true, []string{"DistributedVirtualSwitch"}, count.Datacenter}, 95 {root, true, []string{"DistributedVirtualPortgroup"}, count.Portgroup}, 96 {root, true, []string{"Network"}, count.Portgroup + m.Datacenter}, 97 {root, true, []string{"OpaqueNetwork"}, 0}, 98 {root, true, []string{"StoragePod"}, m.Pod * m.Datacenter}, 99 } 100 101 pc := property.DefaultCollector(c.Client) 102 103 for i, test := range tests { 104 cv, err := v.CreateContainerView(ctx, test.root, test.kinds, test.recurse) 105 if err != nil { 106 t.Fatal(err) 107 } 108 109 var mcv mo.ContainerView 110 err = pc.RetrieveOne(ctx, cv.Reference(), nil, &mcv) 111 if err != nil { 112 t.Fatal(err) 113 } 114 115 n := len(mcv.View) 116 117 if n != test.expect { 118 t.Errorf("%d: %d != %d", i, n, test.expect) 119 } 120 121 err = cv.Destroy(ctx) 122 if err != nil { 123 t.Fatal(err) 124 } 125 } 126 } 127 128 func TestViewManager_CreateContainerView(t *testing.T) { 129 m := VPX() 130 m.Datacenter = 10 // smaller numbers than this sometimes fail to trigger the DATA RACE 131 m.Datastore = 10 132 err := m.Run(func(ctx context.Context, client *vim25.Client) (err error) { 133 manager := view.NewManager(client) 134 datacenterView, err := manager.CreateContainerView(ctx, client.ServiceContent.RootFolder, []string{"Datacenter"}, true) 135 if err != nil { 136 return err 137 } 138 defer datacenterView.Destroy(ctx) 139 var datacenterList []mo.Datacenter 140 err = datacenterView.Retrieve(ctx, []string{"Datacenter"}, []string{"name", "datastoreFolder"}, &datacenterList) 141 if err != nil { 142 return err 143 } 144 var getDataStores = func(dc mo.Datacenter) (dsNames []string, err error) { 145 dataStoreView, err := manager.CreateContainerView(ctx, dc.DatastoreFolder, []string{"Datastore"}, true) 146 if err != nil { 147 return dsNames, err 148 } 149 defer dataStoreView.Destroy(ctx) 150 var dsList []mo.Datastore 151 err = dataStoreView.Retrieve(ctx, []string{"Datastore"}, []string{"name"}, &dsList) 152 if err != nil { 153 return dsNames, err 154 } 155 for _, ds := range dsList { 156 dsNames = append(dsNames, ds.Name) 157 } 158 return dsNames, err 159 } 160 wg := &sync.WaitGroup{} 161 mtx := sync.Mutex{} 162 var datastores [][]string 163 wg.Add(len(datacenterList)) 164 for _, dc := range datacenterList { 165 go func(ref mo.Datacenter) { 166 defer wg.Done() 167 ds, err := getDataStores(ref) 168 if err != nil { 169 return 170 } 171 mtx.Lock() 172 datastores = append(datastores, ds) 173 mtx.Unlock() 174 }(dc) 175 } 176 wg.Wait() 177 if len(datastores) != m.Datacenter { 178 t.Errorf("Invalid number of datacenters: %d", len(datastores)) 179 } else { 180 if len(datastores[0]) != m.Datastore { 181 t.Errorf("Invalid number of datastores per datacenter: %d", len(datastores[0])) 182 } 183 } 184 return nil 185 }) 186 if err != nil { 187 t.Errorf("Failed to run simulation: %s", err.Error()) 188 } 189 } 190 191 func TestListViewModify(t *testing.T) { 192 Test(func(ctx context.Context, c *vim25.Client) { 193 list, err := view.NewManager(c).CreateListView(ctx, nil) 194 if err != nil { 195 log.Fatal(err) 196 } 197 198 defer list.Destroy(ctx) 199 200 add := []types.ManagedObjectReference{ 201 c.ServiceContent.RootFolder, 202 {Type: "Folder", Value: "invalid"}, 203 } 204 205 refs, err := list.Add(ctx, add) 206 if err != nil { 207 log.Fatal(err) 208 } 209 210 if len(refs) != 1 { 211 t.Errorf("unresolved refs=%s", refs) 212 } 213 214 refs, err = list.Remove(ctx, add) 215 if err != nil { 216 log.Fatal(err) 217 } 218 219 if len(refs) != 0 { 220 t.Errorf("unresolved refs=%s", refs) 221 } 222 }) 223 }