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 }