Skip to content

Commit dcfcc61

Browse files
committed
Random / parallel testing
This patch updates VM Op to run its unit/integration tests in a random order, in parallel (using as many processes as there are CPUs). This change reduces the time to test one of the larger packages, ./pkg/providers/vsphere, from 502s to only 88s. The randomization also ensures both the production code and test code is reslient and more decomposed. Finally, if there is a need to maintain ordering, because VM Op uses Ginkgo v2, the Ordered decorator may be utilized. There are examples of this in the code-base already, such as in ./pkg/exit/exit_test.go. Just search the project for `Ordered,` to find such examples, ex.: `grep -r 'Ordered,' * `.
1 parent 5acdb66 commit dcfcc61

File tree

12 files changed

+114
-57
lines changed

12 files changed

+114
-57
lines changed

controllers/virtualmachine/storagepolicyusage/storagepolicyusage_controller_unit_test.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,8 @@ func unitTestsReconcileSPUForVM() {
448448
)
449449

450450
BeforeEach(func() {
451+
vm1 = nil
452+
vm2 = nil
451453
withObjects = nil
452454
withFuncs = interceptor.Funcs{}
453455
inNamespace = namespace
@@ -1010,6 +1012,11 @@ func unitTestsReconcileSPUForVMSnapshot() {
10101012
withObjects = nil
10111013
inNamespace = namespace
10121014
inName = name
1015+
vm1 = nil
1016+
vm2 = nil
1017+
vmSnapshot1 = nil
1018+
vmSnapshot2 = nil
1019+
10131020
})
10141021

10151022
JustBeforeEach(func() {

controllers/virtualmachineclass/virtualmachineclass_controller_intg_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ func intgTestsReconcile() {
4444
vmClass = &vmopv1.VirtualMachineClass{
4545
ObjectMeta: metav1.ObjectMeta{
4646
Name: "small",
47-
Namespace: "default",
47+
Namespace: ctx.Namespace,
4848
},
4949
Spec: vmopv1.VirtualMachineClassSpec{
5050
Hardware: vmopv1.VirtualMachineClassHardware{

controllers/virtualmachinesnapshot/virtualmachinesnapshot_controller_intg_test.go

Lines changed: 49 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,6 @@ func intgTestsReconcile() {
9292
Expect(vcSimCtx).ToNot(BeNil())
9393

9494
vcSimCtx.BeforeEach()
95-
96-
snapshotObjKey = types.NamespacedName{
97-
Name: vmSnapshot.Name,
98-
Namespace: vmSnapshot.Namespace,
99-
}
10095
})
10196

10297
AfterEach(func() {
@@ -108,13 +103,17 @@ func intgTestsReconcile() {
108103
BeforeEach(func() {
109104
initEnvFn = func(ctx *builder.IntegrationTestContextForVCSim) {
110105
By("create vm in k8s")
111-
vm = builder.DummyBasicVirtualMachine("dummy-vm", vcSimCtx.NSInfo.Namespace)
112-
Expect(vcSimCtx.Client.Create(ctx, vm)).To(Succeed())
106+
vm = builder.DummyBasicVirtualMachine("dummy-vm", ctx.NSInfo.Namespace)
107+
Expect(ctx.Client.Create(ctx, vm)).To(Succeed())
113108
vm.Status.UniqueID = uniqueVMID
114-
Expect(vcSimCtx.Client.Status().Update(ctx, vm)).To(Succeed())
109+
Expect(ctx.Client.Status().Update(ctx, vm)).To(Succeed())
115110
By("create snapshot in k8s")
116-
vmSnapshot = builder.DummyVirtualMachineSnapshot(vcSimCtx.NSInfo.Namespace, "snap-1", vm.Name)
117-
Expect(vcSimCtx.Client.Create(ctx, vmSnapshot.DeepCopy())).To(Succeed())
111+
vmSnapshot = builder.DummyVirtualMachineSnapshot(ctx.NSInfo.Namespace, "snap-1", vm.Name)
112+
snapshotObjKey = types.NamespacedName{
113+
Name: vmSnapshot.Name,
114+
Namespace: vmSnapshot.Namespace,
115+
}
116+
Expect(ctx.Client.Create(ctx, vmSnapshot.DeepCopy())).To(Succeed())
118117
}
119118
})
120119

@@ -139,13 +138,17 @@ func intgTestsReconcile() {
139138
BeforeEach(func() {
140139
initEnvFn = func(ctx *builder.IntegrationTestContextForVCSim) {
141140
By("create vm in k8s")
142-
vm = builder.DummyBasicVirtualMachine("dummy-vm", vcSimCtx.NSInfo.Namespace)
143-
Expect(vcSimCtx.Client.Create(ctx, vm)).To(Succeed())
141+
vm = builder.DummyBasicVirtualMachine("dummy-vm", ctx.NSInfo.Namespace)
142+
Expect(ctx.Client.Create(ctx, vm)).To(Succeed())
144143
vm.Status.UniqueID = uniqueVMID
145-
Expect(vcSimCtx.Client.Status().Update(ctx, vm)).To(Succeed())
144+
Expect(ctx.Client.Status().Update(ctx, vm)).To(Succeed())
146145
By("create snapshot in k8s")
147-
vmSnapshot = builder.DummyVirtualMachineSnapshot(vcSimCtx.NSInfo.Namespace, "snap-1", vm.Name)
148-
Expect(vcSimCtx.Client.Create(ctx, vmSnapshot.DeepCopy())).To(Succeed())
146+
vmSnapshot = builder.DummyVirtualMachineSnapshot(ctx.NSInfo.Namespace, "snap-1", vm.Name)
147+
snapshotObjKey = types.NamespacedName{
148+
Name: vmSnapshot.Name,
149+
Namespace: vmSnapshot.Namespace,
150+
}
151+
Expect(ctx.Client.Create(ctx, vmSnapshot.DeepCopy())).To(Succeed())
149152
}
150153
})
151154
JustBeforeEach(func() {
@@ -158,7 +161,7 @@ func intgTestsReconcile() {
158161
It("returns success, and set the csi volume sync annotation to requested", func() {
159162
Eventually(func(g Gomega) {
160163
vmSnapshotObj := &vmopv1.VirtualMachineSnapshot{}
161-
Expect(vcSimCtx.Client.Get(ctx, snapshotObjKey, vmSnapshotObj)).To(Succeed())
164+
g.Expect(vcSimCtx.Client.Get(ctx, snapshotObjKey, vmSnapshotObj)).To(Succeed())
162165
g.Expect(vmSnapshotObj.Annotations[constants.CSIVSphereVolumeSyncAnnotationKey]).
163166
To(Equal(constants.CSIVSphereVolumeSyncAnnotationValueRequested))
164167
g.Expect(conditions.IsFalse(vmSnapshotObj,
@@ -201,13 +204,17 @@ func intgTestsReconcile() {
201204
BeforeEach(func() {
202205
initEnvFn = func(ctx *builder.IntegrationTestContextForVCSim) {
203206
By("create vm and snapshot in k8s")
204-
vm = builder.DummyBasicVirtualMachine("dummy-vm", vcSimCtx.NSInfo.Namespace)
205-
vmSnapshot = builder.DummyVirtualMachineSnapshot(vcSimCtx.NSInfo.Namespace, "snap-1", vm.Name)
206-
Expect(vcSimCtx.Client.Create(ctx, vmSnapshot.DeepCopy())).To(Succeed())
207-
Expect(vcSimCtx.Client.Create(ctx, vm)).To(Succeed())
207+
vm = builder.DummyBasicVirtualMachine("dummy-vm", ctx.NSInfo.Namespace)
208+
vmSnapshot = builder.DummyVirtualMachineSnapshot(ctx.NSInfo.Namespace, "snap-1", vm.Name)
209+
snapshotObjKey = types.NamespacedName{
210+
Name: vmSnapshot.Name,
211+
Namespace: vmSnapshot.Namespace,
212+
}
213+
Expect(ctx.Client.Create(ctx, vmSnapshot.DeepCopy())).To(Succeed())
214+
Expect(ctx.Client.Create(ctx, vm)).To(Succeed())
208215
vm.Status.UniqueID = uniqueVMID
209216
vm.Status.CurrentSnapshot = newManagedSnapshotRefWithSnapshotName(vmSnapshot.Name)
210-
Expect(vcSimCtx.Client.Status().Update(ctx, vm)).To(Succeed())
217+
Expect(ctx.Client.Status().Update(ctx, vm)).To(Succeed())
211218
}
212219

213220
provider.Lock()
@@ -311,8 +318,12 @@ func intgTestsReconcile() {
311318
BeforeEach(func() {
312319
initEnvFn = func(ctx *builder.IntegrationTestContextForVCSim) {
313320
By("only create snapshot in k8s")
314-
vmSnapshot = builder.DummyVirtualMachineSnapshot(vcSimCtx.NSInfo.Namespace, "snap-1", vm.Name)
315-
Expect(vcSimCtx.Client.Create(ctx, vmSnapshot.DeepCopy())).To(Succeed())
321+
vmSnapshot = builder.DummyVirtualMachineSnapshot(ctx.NSInfo.Namespace, "snap-1", vm.Name)
322+
snapshotObjKey = types.NamespacedName{
323+
Name: vmSnapshot.Name,
324+
Namespace: vmSnapshot.Namespace,
325+
}
326+
Expect(ctx.Client.Create(ctx, vmSnapshot.DeepCopy())).To(Succeed())
316327
}
317328
})
318329
It("snapshot is deleted", func() {
@@ -335,15 +346,19 @@ func intgTestsReconcile() {
335346
BeforeEach(func() {
336347
initEnvFn = func(ctx *builder.IntegrationTestContextForVCSim) {
337348
By("create vm and snapshot in k8s")
338-
vm = builder.DummyBasicVirtualMachine("dummy-vm", vcSimCtx.NSInfo.Namespace)
339-
vmSnapshot = builder.DummyVirtualMachineSnapshot(vcSimCtx.NSInfo.Namespace, "snap-1", vm.Name)
349+
vm = builder.DummyBasicVirtualMachine("dummy-vm", ctx.NSInfo.Namespace)
350+
vmSnapshot = builder.DummyVirtualMachineSnapshot(ctx.NSInfo.Namespace, "snap-1", vm.Name)
351+
snapshotObjKey = types.NamespacedName{
352+
Name: vmSnapshot.Name,
353+
Namespace: vmSnapshot.Namespace,
354+
}
340355
By("set snapshot's vmref to nil")
341356
vmSnapshot.Spec.VMRef = nil
342-
Expect(vcSimCtx.Client.Create(ctx, vmSnapshot.DeepCopy())).To(Succeed())
343-
Expect(vcSimCtx.Client.Create(ctx, vm)).To(Succeed())
357+
Expect(ctx.Client.Create(ctx, vmSnapshot.DeepCopy())).To(Succeed())
358+
Expect(ctx.Client.Create(ctx, vm)).To(Succeed())
344359
vm.Status.UniqueID = uniqueVMID
345360
vm.Status.CurrentSnapshot = newManagedSnapshotRefWithSnapshotName(vmSnapshot.Name)
346-
Expect(vcSimCtx.Client.Status().Update(ctx, vm)).To(Succeed())
361+
Expect(ctx.Client.Status().Update(ctx, vm)).To(Succeed())
347362

348363
vmObjKey := types.NamespacedName{Name: vm.Name, Namespace: vm.Namespace}
349364
Eventually(func(g Gomega) {
@@ -412,18 +427,18 @@ func intgTestsReconcile() {
412427
vmSnapshotL3Node1 = builder.DummyVirtualMachineSnapshot(ctx.NSInfo.Namespace, vmSnapshotL3Node1Name, vm.Name)
413428
vmSnapshotL3Node2 = builder.DummyVirtualMachineSnapshot(ctx.NSInfo.Namespace, vmSnapshotL3Node2Name, vm.Name)
414429

415-
Expect(vcSimCtx.Client.Create(ctx, vm)).To(Succeed())
430+
Expect(ctx.Client.Create(ctx, vm)).To(Succeed())
416431
// Update the current snapshot after creation. Otherwise will run into "failed to get informer from cache"
417432
vm.Status.UniqueID = uniqueVMID
418433
// Update the root snapshots
419434
vm.Status.RootSnapshots = []vmopv1.VirtualMachineSnapshotReference{*newManagedSnapshotRefWithSnapshotName(vmSnapshotL1.Name)}
420-
Expect(vcSimCtx.Client.Status().Update(ctx, vm)).To(Succeed())
435+
Expect(ctx.Client.Status().Update(ctx, vm)).To(Succeed())
421436

422437
// // Create the object here so that it can be customized in each BeforeEach
423-
Expect(vcSimCtx.Client.Create(ctx, vmSnapshotL1)).To(Succeed())
424-
Expect(vcSimCtx.Client.Create(ctx, vmSnapshotL2)).To(Succeed())
425-
Expect(vcSimCtx.Client.Create(ctx, vmSnapshotL3Node1.DeepCopy())).To(Succeed())
426-
Expect(vcSimCtx.Client.Create(ctx, vmSnapshotL3Node2.DeepCopy())).To(Succeed())
438+
Expect(ctx.Client.Create(ctx, vmSnapshotL1)).To(Succeed())
439+
Expect(ctx.Client.Create(ctx, vmSnapshotL2)).To(Succeed())
440+
Expect(ctx.Client.Create(ctx, vmSnapshotL3Node1.DeepCopy())).To(Succeed())
441+
Expect(ctx.Client.Create(ctx, vmSnapshotL3Node2.DeepCopy())).To(Succeed())
427442
// Mark the snapshot as ready so that they won't update CurrentSnapshot
428443
markVMSnapshotReady(vcSimCtx, vmSnapshotL1)
429444
markVMSnapshotReady(vcSimCtx, vmSnapshotL2)

hack/test.sh

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,18 @@ set -x
1313
# script is located.
1414
cd "$(dirname "${BASH_SOURCE[0]}")/.."
1515

16-
GO_TEST_FLAGS+=("-v") # verbose
17-
GO_TEST_FLAGS+=("-r") # recursive
18-
GO_TEST_FLAGS+=("--race") # check for possible races
19-
GO_TEST_FLAGS+=("--keep-going") # do not fail on the first error
16+
GO_TEST_FLAGS+=("-p") # parallel
17+
GO_TEST_FLAGS+=("-r") # recursive
18+
GO_TEST_FLAGS+=("-v") # verbose
19+
GO_TEST_FLAGS+=("--race") # check for possible races
20+
GO_TEST_FLAGS+=("--keep-going") # do not fail on the first error
21+
GO_TEST_FLAGS+=("--randomize-all") # random order
22+
GO_TEST_FLAGS+=("--force-newlines") # always print empty line after test cases
23+
24+
# Use the GitHub output option if the tests are run as part of a GitHub action.
25+
if [ -n "${GITHUB_RUN_ID:-}" ]; then
26+
GO_TEST_FLAGS+=("--github-output")
27+
fi
2028

2129
# Only run tests that match given labels if LABEL_FILTER is non-empty.
2230
if [ -n "${LABEL_FILTER:-}" ]; then

pkg/builder/auth_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -81,15 +81,15 @@ var _ = DescribeTable("IsPrivilegedAccount",
8181
),
8282
)
8383

84-
var _ = Describe("VerifyWebhookRequest", func() {
84+
var _ = Describe("VerifyWebhookRequest", Serial, func() {
8585
BeforeEach(func() {
8686
dir := filepath.Dir(caFilePath)
8787
Expect(os.MkdirAll(dir, 0755)).To(Succeed())
8888
Expect(os.WriteFile(caFilePath, []byte(sampleCert), 0644)).To(Succeed())
8989
})
9090

9191
AfterEach(func() {
92-
Expect(os.Remove(caFilePath)).To(Succeed())
92+
Expect(os.RemoveAll(caFilePath)).To(Succeed())
9393
Expect(os.RemoveAll("/tmp/k8s-webhook-server")).To(Succeed())
9494
})
9595

pkg/builder/mutating_webhook_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import (
2828
pkgctxfake "github.com/vmware-tanzu/vm-operator/pkg/context/fake"
2929
)
3030

31-
var _ = Describe("NewMutatingWebhook", func() {
31+
var _ = Describe("NewMutatingWebhook", Serial, func() {
3232

3333
var (
3434
err error
@@ -135,7 +135,7 @@ var _ = Describe("NewMutatingWebhook", func() {
135135
})
136136

137137
AfterEach(func() {
138-
err := os.Remove(caFilePath)
138+
err := os.RemoveAll(caFilePath)
139139
Expect(err).NotTo(HaveOccurred())
140140

141141
err = os.RemoveAll("/tmp/k8s-webhook-server")

pkg/builder/validating_webhook_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import (
2929
pkgctxfake "github.com/vmware-tanzu/vm-operator/pkg/context/fake"
3030
)
3131

32-
var _ = Describe("NewValidatingWebhook", func() {
32+
var _ = Describe("NewValidatingWebhook", Serial, func() {
3333

3434
var (
3535
err error
@@ -153,7 +153,7 @@ var _ = Describe("NewValidatingWebhook", func() {
153153
})
154154

155155
AfterEach(func() {
156-
err := os.Remove(caFilePath)
156+
err := os.RemoveAll(caFilePath)
157157
Expect(err).NotTo(HaveOccurred())
158158

159159
err = os.RemoveAll("/tmp/k8s-webhook-server")

pkg/providers/vsphere/session/session_vm_update_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ var _ = Describe("Update ConfigSpec", func() {
232232
var vmSpec vmopv1.VirtualMachineSpec
233233

234234
BeforeEach(func() {
235+
vmSpec = vmopv1.VirtualMachineSpec{}
235236
config.ChangeTrackingEnabled = nil
236237
})
237238

pkg/providers/vsphere/virtualmachine/cdrom_test.go

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,14 +1089,14 @@ func cdromTests() {
10891089
Context("UpdateConfigSpecCdromDeviceConnection", func() {
10901090

10911091
var (
1092-
ctx *builder.TestContextForVCSim
1093-
vmCtx pkgctx.VirtualMachineContext
1094-
restClient *rest.Client
1095-
k8sClient ctrlclient.Client
1096-
configInfo *vimtypes.VirtualMachineConfigInfo
1097-
configSpec *vimtypes.VirtualMachineConfigSpec
1098-
1099-
updateErr error
1092+
ctx *builder.TestContextForVCSim
1093+
vmCtx pkgctx.VirtualMachineContext
1094+
restClient *rest.Client
1095+
k8sClient ctrlclient.Client
1096+
configInfo *vimtypes.VirtualMachineConfigInfo
1097+
configSpec *vimtypes.VirtualMachineConfigSpec
1098+
k8sInitObjs []ctrlclient.Object
1099+
updateErr error
11001100
)
11011101

11021102
BeforeEach(func() {
@@ -1118,16 +1118,16 @@ func cdromTests() {
11181118
})
11191119

11201120
JustBeforeEach(func() {
1121+
k8sClient = builder.NewFakeClient(k8sInitObjs...)
11211122
updateErr = virtualmachine.UpdateConfigSpecCdromDeviceConnection(vmCtx, restClient, k8sClient, configInfo, configSpec)
11221123
})
11231124

11241125
Context("Happy Path (no error occurs)", func() {
11251126

11261127
BeforeEach(func() {
11271128
// Create a fake K8s client with both namespace & cluster scope ISO type images and their content library item objects.
1128-
k8sInitObjs := builder.DummyImageAndItemObjectsForCdromBacking(vmiName, ns, vmiKind, vmiFileName, ctx.ContentLibraryIsoItemID, true, true, resource.MustParse("100Mi"), true, true, imgregv1a1.ContentLibraryItemTypeIso)
1129+
k8sInitObjs = builder.DummyImageAndItemObjectsForCdromBacking(vmiName, ns, vmiKind, vmiFileName, ctx.ContentLibraryIsoItemID, true, true, resource.MustParse("100Mi"), true, true, imgregv1a1.ContentLibraryItemTypeIso)
11291130
k8sInitObjs = append(k8sInitObjs, builder.DummyImageAndItemObjectsForCdromBacking(cvmiName, "", cvmiKind, cvmiFileName, ctx.ContentLibraryIsoItemID, true, true, resource.MustParse("100Mi"), true, true, imgregv1a1.ContentLibraryItemTypeIso)...)
1130-
k8sClient = builder.NewFakeClient(k8sInitObjs...)
11311131
})
11321132

11331133
When("VM.Spec.Cdrom has no changes", func() {

pkg/providers/vsphere/virtualmachine/virtualmachine_suite_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ func vcSimTests() {
1919
Describe("Publish", Label(testlabels.VCSim), publishTests)
2020
Describe("Backup", Label(testlabels.VCSim), backupTests)
2121
Describe("GuestInfo", Label(testlabels.VCSim), guestInfoTests)
22-
Describe("CD-ROM", Label(testlabels.VCSim), cdromTests)
22+
Describe("CD-ROM", Serial, Label(testlabels.VCSim), cdromTests)
2323
Describe("Snapshot", Label(testlabels.VCSim), snapShotTests)
2424
Describe("ExtraConfig", Label(testlabels.VCSim), extraConfigTests)
2525
}

0 commit comments

Comments
 (0)