github.com/vmware/govmomi@v0.51.0/simulator/dvs_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  	"reflect"
    10  	"testing"
    11  
    12  	"github.com/vmware/govmomi/find"
    13  	"github.com/vmware/govmomi/object"
    14  	"github.com/vmware/govmomi/task"
    15  	"github.com/vmware/govmomi/vim25/types"
    16  )
    17  
    18  func TestDVS(t *testing.T) {
    19  	m := VPX()
    20  
    21  	defer m.Remove()
    22  
    23  	err := m.Create()
    24  	if err != nil {
    25  		t.Fatal(err)
    26  	}
    27  
    28  	ctx := context.Background()
    29  	c := m.Service.client()
    30  
    31  	finder := find.NewFinder(c, false)
    32  	dc, _ := finder.DatacenterList(ctx, "*")
    33  	finder.SetDatacenter(dc[0])
    34  	folders, _ := dc[0].Folders(ctx)
    35  	hosts, _ := finder.HostSystemList(ctx, "*/*")
    36  	vswitch := m.Map().Any("DistributedVirtualSwitch").(*DistributedVirtualSwitch)
    37  	dvs0 := object.NewDistributedVirtualSwitch(c, vswitch.Reference())
    38  
    39  	if len(vswitch.Summary.HostMember) == 0 {
    40  		t.Fatal("no host member")
    41  	}
    42  
    43  	for _, ref := range vswitch.Summary.HostMember {
    44  		host := m.Map().Get(ref).(*HostSystem)
    45  		if len(host.Network) == 0 {
    46  			t.Fatalf("%s.Network=%v", ref, host.Network)
    47  		}
    48  		parent := hostParent(m.Service.Context, &host.HostSystem)
    49  		if len(parent.Network) != len(host.Network) {
    50  			t.Fatalf("%s.Network=%v", parent.Reference(), parent.Network)
    51  		}
    52  	}
    53  
    54  	var spec types.DVSCreateSpec
    55  	spec.ConfigSpec = &types.VMwareDVSConfigSpec{}
    56  	spec.ConfigSpec.GetDVSConfigSpec().Name = "DVS1"
    57  
    58  	dtask, err := folders.NetworkFolder.CreateDVS(ctx, spec)
    59  	if err != nil {
    60  		t.Fatal(err)
    61  	}
    62  
    63  	info, err := dtask.WaitForResult(ctx, nil)
    64  	if err != nil {
    65  		t.Fatal(err)
    66  	}
    67  
    68  	dvs := object.NewDistributedVirtualSwitch(c, info.Result.(types.ManagedObjectReference))
    69  
    70  	config := &types.DVSConfigSpec{}
    71  
    72  	for _, host := range hosts {
    73  		config.Host = append(config.Host, types.DistributedVirtualSwitchHostMemberConfigSpec{
    74  			Host: host.Reference(),
    75  		})
    76  	}
    77  
    78  	tests := []struct {
    79  		op  types.ConfigSpecOperation
    80  		pg  string
    81  		err types.BaseMethodFault
    82  	}{
    83  		{types.ConfigSpecOperationAdd, "", nil},                               // Add == OK
    84  		{types.ConfigSpecOperationAdd, "", &types.AlreadyExists{}},            // Add == fail (AlreadyExists)
    85  		{types.ConfigSpecOperationEdit, "", &types.NotSupported{}},            // Edit == fail (NotSupported)
    86  		{types.ConfigSpecOperationRemove, "", nil},                            // Remove == OK
    87  		{types.ConfigSpecOperationAdd, "", nil},                               // Add == OK
    88  		{types.ConfigSpecOperationAdd, "DVPG0", nil},                          // Add PG == OK
    89  		{types.ConfigSpecOperationRemove, "", &types.ResourceInUse{}},         // Remove dvs0 == fail (ResourceInUse)
    90  		{types.ConfigSpecOperationRemove, "", nil},                            // Remove dvs1 == OK (no VMs attached)
    91  		{types.ConfigSpecOperationRemove, "", &types.ManagedObjectNotFound{}}, // Remove == fail (ManagedObjectNotFound)
    92  	}
    93  
    94  	for x, test := range tests {
    95  		dswitch := dvs
    96  
    97  		switch test.err.(type) {
    98  		case *types.ManagedObjectNotFound:
    99  			for i := range config.Host {
   100  				config.Host[i].Host.Value = "enoent"
   101  			}
   102  		case *types.ResourceInUse:
   103  			dswitch = dvs0
   104  		}
   105  
   106  		if test.pg == "" {
   107  			for i := range config.Host {
   108  				config.Host[i].Operation = string(test.op)
   109  			}
   110  
   111  			dtask, err = dswitch.Reconfigure(ctx, config)
   112  		} else {
   113  			switch test.op {
   114  			case types.ConfigSpecOperationAdd:
   115  				dtask, err = dswitch.AddPortgroup(ctx, []types.DVPortgroupConfigSpec{
   116  					{Name: test.pg, NumPorts: 1},
   117  				})
   118  			}
   119  		}
   120  
   121  		if err != nil {
   122  			t.Fatal(err)
   123  		}
   124  
   125  		err = dtask.Wait(ctx)
   126  
   127  		if test.err == nil {
   128  			if err != nil {
   129  				t.Fatalf("%d: %s", x, err)
   130  			}
   131  			continue
   132  		}
   133  
   134  		if err == nil {
   135  			t.Errorf("expected error in test %d", x)
   136  		}
   137  
   138  		if reflect.TypeOf(test.err) != reflect.TypeOf(err.(task.Error).Fault()) {
   139  			t.Errorf("expected %T fault in test %d", test.err, x)
   140  		}
   141  	}
   142  
   143  	ports, err := dvs.FetchDVPorts(ctx, nil)
   144  	if err != nil {
   145  		t.Fatal(err)
   146  	}
   147  	if len(ports) != 2 {
   148  		t.Fatalf("expected 2 ports in DVPorts; got %d", len(ports))
   149  	}
   150  
   151  	dtask, err = dvs.Destroy(ctx)
   152  	if err != nil {
   153  		t.Fatal(err)
   154  	}
   155  
   156  	err = dtask.Wait(ctx)
   157  	if err != nil {
   158  		t.Fatal(err)
   159  	}
   160  }
   161  
   162  func TestFetchDVPortsCriteria(t *testing.T) {
   163  	m := VPX()
   164  
   165  	defer m.Remove()
   166  
   167  	err := m.Create()
   168  	if err != nil {
   169  		t.Fatal(err)
   170  	}
   171  
   172  	ctx := context.Background()
   173  	c := m.Service.client()
   174  
   175  	finder := find.NewFinder(c, false)
   176  	dc, _ := finder.DatacenterList(ctx, "*")
   177  	finder.SetDatacenter(dc[0])
   178  	vswitch := m.Map().Any("DistributedVirtualSwitch").(*DistributedVirtualSwitch)
   179  	dvs0 := object.NewDistributedVirtualSwitch(c, vswitch.Reference())
   180  	pgs := vswitch.Portgroup
   181  	if len(pgs) != 2 {
   182  		t.Fatalf("expected 2 portgroups in DVS; got %d", len(pgs))
   183  	}
   184  
   185  	tests := []struct {
   186  		name     string
   187  		criteria *types.DistributedVirtualSwitchPortCriteria
   188  		expected []types.DistributedVirtualPort
   189  	}{
   190  		{
   191  			"empty criteria",
   192  			&types.DistributedVirtualSwitchPortCriteria{},
   193  			[]types.DistributedVirtualPort{
   194  				{PortgroupKey: pgs[0].Value, Key: "0"},
   195  				{PortgroupKey: pgs[1].Value, Key: "0"},
   196  			},
   197  		},
   198  		{
   199  			"inside PortgroupKeys",
   200  			&types.DistributedVirtualSwitchPortCriteria{
   201  				PortgroupKey: []string{pgs[0].Value},
   202  				Inside:       types.NewBool(true),
   203  			},
   204  			[]types.DistributedVirtualPort{
   205  				{PortgroupKey: pgs[0].Value, Key: "0"},
   206  			},
   207  		},
   208  		{
   209  			"outside PortgroupKeys",
   210  			&types.DistributedVirtualSwitchPortCriteria{
   211  				PortgroupKey: []string{pgs[0].Value},
   212  				Inside:       types.NewBool(false),
   213  			},
   214  			[]types.DistributedVirtualPort{
   215  				{PortgroupKey: pgs[1].Value, Key: "0"},
   216  			},
   217  		},
   218  		{
   219  			"PortKeys",
   220  			&types.DistributedVirtualSwitchPortCriteria{
   221  				PortKey: []string{"1"},
   222  			},
   223  			[]types.DistributedVirtualPort{},
   224  		},
   225  		{
   226  			"connected",
   227  			&types.DistributedVirtualSwitchPortCriteria{
   228  				Connected: types.NewBool(true),
   229  			},
   230  			[]types.DistributedVirtualPort{},
   231  		},
   232  		{
   233  			"not connected",
   234  			&types.DistributedVirtualSwitchPortCriteria{
   235  				Connected: types.NewBool(false),
   236  			},
   237  			[]types.DistributedVirtualPort{
   238  				{PortgroupKey: pgs[0].Value, Key: "0"},
   239  				{PortgroupKey: pgs[1].Value, Key: "0"},
   240  			},
   241  		},
   242  	}
   243  
   244  	for _, test := range tests {
   245  		t.Run(test.name, func(t *testing.T) {
   246  			actual, err := dvs0.FetchDVPorts(context.TODO(), test.criteria)
   247  
   248  			if err != nil {
   249  				t.Fatal(err)
   250  			}
   251  
   252  			if len(actual) != len(test.expected) {
   253  				t.Fatalf("expected %d ports; got %d", len(test.expected), len(actual))
   254  			}
   255  
   256  			for i, p := range actual {
   257  				if p.Key != test.expected[i].Key {
   258  					t.Errorf("ports[%d]: expected Key `%s`; got `%s`",
   259  						i, test.expected[i].Key, p.Key)
   260  				}
   261  
   262  				if p.PortgroupKey != test.expected[i].PortgroupKey {
   263  					t.Errorf("ports[%d]: expected PortgroupKey `%s`; got `%s`",
   264  						i, test.expected[i].PortgroupKey, p.PortgroupKey)
   265  				}
   266  			}
   267  		})
   268  	}
   269  }