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