Skip to content

Commit 8848cff

Browse files
committed
Added multi disk support tests
1 parent eb41bfe commit 8848cff

File tree

6 files changed

+393
-17
lines changed

6 files changed

+393
-17
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,7 @@ generate-e2e-templates-main: $(KUSTOMIZE) ## Generate test templates for the mai
374374
cp "$(RELEASE_DIR)/main/cluster-template-ignition.yaml" "$(E2E_GOVMOMI_TEMPLATE_DIR)/main/base/cluster-template-ignition.yaml"
375375
"$(KUSTOMIZE)" --load-restrictor LoadRestrictionsNone build "$(E2E_GOVMOMI_TEMPLATE_DIR)/main/base" > "$(E2E_GOVMOMI_TEMPLATE_DIR)/main/cluster-template.yaml"
376376
"$(KUSTOMIZE)" --load-restrictor LoadRestrictionsNone build "$(E2E_GOVMOMI_TEMPLATE_DIR)/main/hw-upgrade" > "$(E2E_GOVMOMI_TEMPLATE_DIR)/main/cluster-template-hw-upgrade.yaml"
377+
"$(KUSTOMIZE)" --load-restrictor LoadRestrictionsNone build "$(E2E_GOVMOMI_TEMPLATE_DIR)/main/multi-disk" > "$(E2E_GOVMOMI_TEMPLATE_DIR)/main/cluster-template-multi-disk.yaml"
377378
"$(KUSTOMIZE)" --load-restrictor LoadRestrictionsNone build "$(E2E_GOVMOMI_TEMPLATE_DIR)/main/storage-policy" > "$(E2E_GOVMOMI_TEMPLATE_DIR)/main/cluster-template-storage-policy.yaml"
378379
"$(KUSTOMIZE)" --load-restrictor LoadRestrictionsNone build "$(E2E_GOVMOMI_TEMPLATE_DIR)/main/conformance" > "$(E2E_GOVMOMI_TEMPLATE_DIR)/main/cluster-template-conformance.yaml"
379380
# Since CAPI uses different flavor names for KCP and MD remediation using MHC

pkg/services/govmomi/vcenter/clone_test.go

Lines changed: 260 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package vcenter
1919
import (
2020
ctx "context"
2121
"crypto/tls"
22+
"fmt"
2223
"testing"
2324

2425
"github.com/vmware/govmomi/object"
@@ -60,25 +61,30 @@ func TestGetDiskSpec(t *testing.T) {
6061
additionalCloneDiskSizes []int32
6162
name string
6263
disks object.VirtualDeviceList
64+
dataDisks []infrav1.VSphereDisk
65+
expectedDiskCount int
6366
err string
6467
}{
6568
{
66-
name: "Successfully clone template with correct disk requirements",
67-
disks: defaultDisks,
68-
cloneDiskSize: defaultSizeGiB,
69-
expectDevice: true,
69+
name: "Successfully clone template with correct disk requirements",
70+
disks: defaultDisks,
71+
cloneDiskSize: defaultSizeGiB,
72+
expectDevice: true,
73+
expectedDiskCount: 1,
7074
},
7175
{
72-
name: "Successfully clone template and increase disk requirements",
73-
disks: defaultDisks,
74-
cloneDiskSize: defaultSizeGiB + 1,
75-
expectDevice: true,
76+
name: "Successfully clone template and increase disk requirements",
77+
disks: defaultDisks,
78+
cloneDiskSize: defaultSizeGiB + 1,
79+
expectDevice: true,
80+
expectedDiskCount: 1,
7681
},
7782
{
78-
name: "Successfully clone template with no explicit disk requirements",
79-
disks: defaultDisks,
80-
cloneDiskSize: 0,
81-
expectDevice: true,
83+
name: "Successfully clone template with no explicit disk requirements",
84+
disks: defaultDisks,
85+
cloneDiskSize: 0,
86+
expectDevice: true,
87+
expectedDiskCount: 1,
8288
},
8389
{
8490
name: "Fail to clone template with lower disk requirements then on template",
@@ -98,6 +104,7 @@ func TestGetDiskSpec(t *testing.T) {
98104
cloneDiskSize: defaultSizeGiB + 1,
99105
additionalCloneDiskSizes: []int32{defaultSizeGiB + 1},
100106
expectDevice: true,
107+
expectedDiskCount: 2,
101108
},
102109
{
103110
name: "Fails to clone template and decrease second disk size",
@@ -114,32 +121,268 @@ func TestGetDiskSpec(t *testing.T) {
114121
cloneSpec := infrav1.VirtualMachineCloneSpec{
115122
DiskGiB: tc.cloneDiskSize,
116123
AdditionalDisksGiB: tc.additionalCloneDiskSizes,
124+
DataDisks: tc.dataDisks,
117125
}
118126
vsphereVM := &infrav1.VSphereVM{
119127
Spec: infrav1.VSphereVMSpec{
120128
VirtualMachineCloneSpec: cloneSpec,
121129
},
122130
}
123131
vmContext := &capvcontext.VMContext{VSphereVM: vsphereVM}
124-
devices, err := getDiskSpec(vmContext, tc.disks)
132+
deviceResults, err := getDiskSpec(vmContext, tc.disks)
125133
if (tc.err != "" && err == nil) || (tc.err == "" && err != nil) || (err != nil && tc.err != err.Error()) {
126134
t.Fatalf("Expected to get '%v' error from getDiskSpec, got: '%v'", tc.err, err)
127135
}
128-
if deviceFound := len(devices) != 0; tc.expectDevice != deviceFound {
129-
t.Fatalf("Expected to get a device: %v, but got: '%#v'", tc.expectDevice, devices)
136+
if deviceFound := len(deviceResults) != 0; tc.expectDevice != deviceFound {
137+
t.Fatalf("Expected to get a device: %v, but got: '%#v'", tc.expectDevice, deviceResults)
130138
}
131139
if tc.expectDevice {
132-
primaryDevice := devices[0]
140+
primaryDevice := deviceResults[0]
133141
validateDiskSpec(t, primaryDevice, tc.cloneDiskSize)
134142
if len(tc.additionalCloneDiskSizes) != 0 {
135-
secondaryDevice := devices[1]
143+
secondaryDevice := deviceResults[1]
136144
validateDiskSpec(t, secondaryDevice, tc.additionalCloneDiskSizes[0])
137145
}
146+
147+
// Check number of disks present
148+
if len(deviceResults) != tc.expectedDiskCount {
149+
t.Fatalf("Expected device count to be %v, but found %v", tc.expectedDiskCount, len(deviceResults))
150+
}
151+
}
152+
})
153+
}
154+
}
155+
156+
func TestCreateDiskSpec(t *testing.T) {
157+
model, session, server := initSimulator(t)
158+
t.Cleanup(model.Remove)
159+
t.Cleanup(server.Close)
160+
vm := simulator.Map.Any("VirtualMachine").(*simulator.VirtualMachine)
161+
machine := object.NewVirtualMachine(session.Client.Client, vm.Reference())
162+
163+
devices, err := machine.Device(ctx.TODO())
164+
if err != nil {
165+
t.Fatalf("Failed to obtain vm devices: %v", err)
166+
}
167+
defaultDisks := devices.SelectByType((*types.VirtualDisk)(nil))
168+
if len(defaultDisks) < 1 {
169+
t.Fatal("Unable to find attached disk for data disk testing")
170+
}
171+
172+
testCases := []struct {
173+
expectDevice bool
174+
cloneDiskSize int32
175+
additionalCloneDiskSizes []int32
176+
name string
177+
disks object.VirtualDeviceList
178+
dataDisks []infrav1.VSphereDisk
179+
expectedDiskCount int
180+
err string
181+
}{
182+
{
183+
name: "Successfully add data disk",
184+
disks: devices,
185+
dataDisks: []infrav1.VSphereDisk{
186+
{
187+
SizeGiB: 10,
188+
},
189+
},
190+
expectDevice: true,
191+
},
192+
{
193+
name: "Successfully add multiple data disks",
194+
disks: devices,
195+
dataDisks: []infrav1.VSphereDisk{
196+
{
197+
SizeGiB: 10,
198+
},
199+
{
200+
SizeGiB: 20,
201+
},
202+
},
203+
expectDevice: true,
204+
},
205+
{
206+
name: "Successfully add multiple data disks when template has multiple disks",
207+
disks: append(devices, defaultDisks...),
208+
dataDisks: []infrav1.VSphereDisk{
209+
{
210+
SizeGiB: 10,
211+
},
212+
{
213+
SizeGiB: 20,
214+
},
215+
},
216+
expectDevice: true,
217+
},
218+
}
219+
220+
for _, test := range testCases {
221+
tc := test
222+
t.Run(tc.name, func(t *testing.T) {
223+
deviceResults, err := createDataDisks(ctx.TODO(), tc.dataDisks, tc.disks)
224+
if (tc.err != "" && err == nil) || (tc.err == "" && err != nil) || (err != nil && tc.err != err.Error()) {
225+
t.Fatalf("Expected to get '%v' error from createDataDisks, got: '%v'", tc.err, err)
226+
}
227+
if deviceFound := len(deviceResults) != 0; tc.expectDevice != deviceFound {
228+
t.Fatalf("Expected to get a device: %v, but got: '%#v'", tc.expectDevice, deviceResults)
229+
}
230+
if tc.expectDevice {
231+
// Check number of disks present
232+
if len(deviceResults) != len(tc.dataDisks) {
233+
t.Fatalf("Expected device count to be %v, but found %v", tc.expectedDiskCount, len(deviceResults))
234+
}
235+
}
236+
})
237+
}
238+
}
239+
240+
func TestAddingDataDisks(t *testing.T) {
241+
model, session, server := initSimulator(t)
242+
t.Cleanup(model.Remove)
243+
t.Cleanup(server.Close)
244+
vm := simulator.Map.Any("VirtualMachine").(*simulator.VirtualMachine)
245+
machine := object.NewVirtualMachine(session.Client.Client, vm.Reference())
246+
247+
deviceList, err := machine.Device(ctx.TODO())
248+
if err != nil {
249+
t.Fatalf("Failed to obtain vm devices: %v", err)
250+
}
251+
252+
// Find primary disk and get controller
253+
disks := deviceList.SelectByType((*types.VirtualDisk)(nil))
254+
primaryDisk := disks[0].(*types.VirtualDisk)
255+
controller, ok := deviceList.FindByKey(primaryDisk.ControllerKey).(types.BaseVirtualController)
256+
if !ok {
257+
t.Fatalf("unable to get controller for test")
258+
}
259+
260+
testCases := []struct {
261+
name string
262+
devices object.VirtualDeviceList
263+
controller types.BaseVirtualController
264+
dataDisks []infrav1.VSphereDisk
265+
expectedUnitNumber []int
266+
err string
267+
}{
268+
{
269+
name: "Add data disk with 1 ova disk",
270+
devices: deviceList,
271+
controller: controller,
272+
dataDisks: createDataDiskDefinitions(1),
273+
expectedUnitNumber: []int{1},
274+
},
275+
{
276+
name: "Add data disk with 2 ova disk",
277+
devices: createAdditionalDisks(deviceList, controller, 1),
278+
controller: controller,
279+
dataDisks: createDataDiskDefinitions(1),
280+
expectedUnitNumber: []int{2},
281+
},
282+
{
283+
name: "Add multiple data disk with 1 ova disk",
284+
devices: deviceList,
285+
controller: controller,
286+
dataDisks: createDataDiskDefinitions(2),
287+
expectedUnitNumber: []int{1, 2},
288+
},
289+
{
290+
name: "Add too many data disks with 1 ova disk",
291+
devices: deviceList,
292+
controller: controller,
293+
dataDisks: createDataDiskDefinitions(30),
294+
err: "all unit numbers are already in-use",
295+
},
296+
{
297+
name: "Add data disk with no ova disk",
298+
devices: nil,
299+
controller: nil,
300+
dataDisks: createDataDiskDefinitions(1),
301+
err: "Invalid disk count: 0",
302+
},
303+
{
304+
name: "Add too many data disks with 1 ova disk",
305+
devices: deviceList,
306+
controller: controller,
307+
dataDisks: createDataDiskDefinitions(40),
308+
err: "all unit numbers are already in-use",
309+
},
310+
}
311+
312+
for _, test := range testCases {
313+
tc := test
314+
t.Run(tc.name, func(t *testing.T) {
315+
var funcError error
316+
317+
// Create the data disks
318+
newDisks, funcError := createDataDisks(ctx.TODO(), tc.dataDisks, tc.devices)
319+
if (tc.err != "" && funcError == nil) || (tc.err == "" && funcError != nil) || (funcError != nil && tc.err != funcError.Error()) {
320+
t.Fatalf("Expected to get '%v' error from assignUnitNumber, got: '%v'", tc.err, funcError)
321+
}
322+
323+
// Validate the configs of new data disks
324+
for index, disk := range newDisks {
325+
if funcError != nil {
326+
break
327+
}
328+
329+
unitNumber := *disk.GetVirtualDeviceConfigSpec().Device.GetVirtualDevice().UnitNumber
330+
if tc.err == "" && unitNumber != int32(tc.expectedUnitNumber[index]) {
331+
t.Fatalf("Expected to get unitNumber '%d' error from assignUnitNumber, got: '%d'", tc.expectedUnitNumber[index], unitNumber)
332+
}
138333
}
139334
})
140335
}
141336
}
142337

338+
func createAdditionalDisks(devices object.VirtualDeviceList, controller types.BaseVirtualController, numOfDisks int) object.VirtualDeviceList {
339+
deviceList := devices
340+
disks := devices.SelectByType((*types.VirtualDisk)(nil))
341+
primaryDisk := disks[0].(*types.VirtualDisk)
342+
343+
for i := 0; i < numOfDisks; i++ {
344+
newDevice := createVirtualDisk(primaryDisk.ControllerKey+1, controller, 10)
345+
newUnitNumber := *primaryDisk.UnitNumber + int32(i+1)
346+
newDevice.UnitNumber = &newUnitNumber
347+
deviceList = append(deviceList, newDevice)
348+
}
349+
return deviceList
350+
}
351+
352+
func createVirtualDisk(key int32, controller types.BaseVirtualController, diskSize int32) *types.VirtualDisk {
353+
dev := &types.VirtualDisk{
354+
VirtualDevice: types.VirtualDevice{
355+
Key: key,
356+
Backing: &types.VirtualDiskFlatVer2BackingInfo{
357+
DiskMode: string(types.VirtualDiskModePersistent),
358+
ThinProvisioned: types.NewBool(true),
359+
VirtualDeviceFileBackingInfo: types.VirtualDeviceFileBackingInfo{
360+
FileName: "",
361+
},
362+
},
363+
},
364+
CapacityInKB: int64(diskSize) * 1024 * 1024,
365+
}
366+
367+
if controller != nil {
368+
dev.VirtualDevice.ControllerKey = controller.GetVirtualController().Key
369+
}
370+
return dev
371+
}
372+
373+
func createDataDiskDefinitions(numOfDataDisks int) []infrav1.VSphereDisk {
374+
disks := []infrav1.VSphereDisk{}
375+
376+
for i := 0; i < numOfDataDisks; i++ {
377+
disk := infrav1.VSphereDisk{
378+
Name: fmt.Sprintf("disk_%d", i),
379+
SizeGiB: 10 * int32(i),
380+
}
381+
disks = append(disks, disk)
382+
}
383+
return disks
384+
}
385+
143386
func validateDiskSpec(t *testing.T, device types.BaseVirtualDeviceConfigSpec, cloneDiskSize int32) {
144387
t.Helper()
145388
disk := device.GetVirtualDeviceConfigSpec().Device.(*types.VirtualDisk)

test/e2e/config/vsphere.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,7 @@ providers:
173173
- sourcePath: "../../../test/e2e/data/infrastructure-vsphere-govmomi/main/cluster-template-ipam.yaml"
174174
- sourcePath: "../../../test/e2e/data/infrastructure-vsphere-govmomi/main/cluster-template-kcp-remediation.yaml"
175175
- sourcePath: "../../../test/e2e/data/infrastructure-vsphere-govmomi/main/cluster-template-md-remediation.yaml"
176+
- sourcePath: "../../../test/e2e/data/infrastructure-vsphere-govmomi/main/cluster-template-multi-disk.yaml"
176177
- sourcePath: "../../../test/e2e/data/infrastructure-vsphere-govmomi/main/cluster-template-node-drain.yaml"
177178
- sourcePath: "../../../test/e2e/data/infrastructure-vsphere-govmomi/main/cluster-template-ownerrefs-finalizers.yaml"
178179
- sourcePath: "../../../test/e2e/data/infrastructure-vsphere-govmomi/main/cluster-template-pci.yaml"
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
2+
kind: VSphereMachineTemplate
3+
metadata:
4+
name: '${CLUSTER_NAME}'
5+
namespace: '${NAMESPACE}'
6+
spec:
7+
template:
8+
spec:
9+
dataDisks:
10+
- name: "disk_1"
11+
sizeGiB: 10
12+
- name: "disk_2"
13+
sizeGiB: 20
14+
---
15+
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
16+
kind: VSphereMachineTemplate
17+
metadata:
18+
name: '${CLUSTER_NAME}-worker'
19+
namespace: '${NAMESPACE}'
20+
spec:
21+
template:
22+
spec:
23+
dataDisks:
24+
- name: "disk_1"
25+
sizeGiB: 20
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
apiVersion: kustomize.config.k8s.io/v1beta1
2+
kind: Kustomization
3+
resources:
4+
- ../base
5+
patchesStrategicMerge:
6+
- data-disks-patch.yaml

0 commit comments

Comments
 (0)