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  }