github.com/vmware/govmomi@v0.37.2/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  }