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