Skip to content

Commit 0053871

Browse files
committed
feat(test): add e2e device removal test
1 parent 0e39823 commit 0053871

File tree

3 files changed

+87
-1
lines changed

3 files changed

+87
-1
lines changed

test/e2e/aws_disk_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ func (m *AWSDiskManager) createAndAttachAWSVolumesForNode(ctx context.Context, n
148148
return fmt.Errorf("failed to create and attach aws Disks for Node %s with %v: %w",
149149
nodeEntry.Node, createInput, err)
150150
}
151-
log.Info("creating volume", "size", volume.Size, "id", volume.VolumeId)
151+
log.Info("creating volume", "size", volume.Size, "id", volume.VolumeId, "path", diskName)
152152
volumes[i] = volume
153153
volumeIDs = append(volumeIDs, volume.VolumeId)
154154
}

test/e2e/lvm_cluster_test.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,4 +90,54 @@ func lvmClusterTest() {
9090
VerifyLVMSSetup(ctx, cluster)
9191
})
9292
})
93+
94+
Describe("Device Removal", Serial, func() {
95+
It("should remove devices from volume group successfully", func(ctx SpecContext) {
96+
// Configure cluster with multiple devices for removal testing
97+
cluster.Spec.Storage.DeviceClasses[0].DeviceSelector = &v1alpha1.DeviceSelector{
98+
Paths: []v1alpha1.DevicePath{"/dev/sdg", "/dev/sdh"},
99+
}
100+
101+
By("Creating cluster with multiple devices")
102+
CreateResource(ctx, cluster)
103+
VerifyLVMSSetup(ctx, cluster)
104+
105+
By("Removing one device from the volume group")
106+
// Update cluster to remove /dev/sdi
107+
cluster.Spec.Storage.DeviceClasses[0].DeviceSelector.Paths = []v1alpha1.DevicePath{
108+
"/dev/sdg",
109+
}
110+
111+
err := crClient.Update(ctx, cluster)
112+
Expect(err).NotTo(HaveOccurred())
113+
114+
By("Verifying device removal completed successfully")
115+
Eventually(func(ctx SpecContext) bool {
116+
return validateDeviceRemovalSuccess(ctx, cluster, 1)
117+
}, 5*timeout, interval).WithContext(ctx).Should(BeTrue())
118+
})
119+
120+
It("should handle optional device removal", func(ctx SpecContext) {
121+
// Configure cluster with both required and optional devices
122+
cluster.Spec.Storage.DeviceClasses[0].DeviceSelector = &v1alpha1.DeviceSelector{
123+
Paths: []v1alpha1.DevicePath{"/dev/sdh"},
124+
OptionalPaths: []v1alpha1.DevicePath{"/dev/sdl", "/dev/sdm"},
125+
}
126+
127+
By("Creating cluster with required and optional devices")
128+
CreateResource(ctx, cluster)
129+
VerifyLVMSSetup(ctx, cluster)
130+
131+
By("Removing optional devices")
132+
cluster.Spec.Storage.DeviceClasses[0].DeviceSelector.OptionalPaths = []v1alpha1.DevicePath{}
133+
134+
err := crClient.Update(ctx, cluster)
135+
Expect(err).NotTo(HaveOccurred(), "Should allow removal of optional devices")
136+
137+
By("Verifying cluster remains Ready with required device only")
138+
Eventually(func(ctx SpecContext) bool {
139+
return validateClusterReady(ctx, cluster)
140+
}, timeout, interval).WithContext(ctx).Should(BeTrue())
141+
})
142+
})
93143
}

test/e2e/validation_test.go

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,3 +369,39 @@ func GenericGetItemsFromList(list client.ObjectList) ([]client.Object, error) {
369369

370370
return result, nil
371371
}
372+
373+
func validateDeviceRemovalSuccess(ctx context.Context, cluster *v1alpha1.LVMCluster, expectedDeviceCount int) bool {
374+
vgStatus := getVGStatusForCluster(ctx, cluster)
375+
return len(vgStatus.Devices) == expectedDeviceCount && vgStatus.Status == v1alpha1.VGStatusReady
376+
}
377+
378+
func validateClusterReady(ctx context.Context, cluster *v1alpha1.LVMCluster) bool {
379+
vgStatus := getVGStatusForCluster(ctx, cluster)
380+
return vgStatus.Status == v1alpha1.VGStatusReady
381+
}
382+
383+
func getVGStatusForCluster(ctx context.Context, cluster *v1alpha1.LVMCluster) v1alpha1.VGStatus {
384+
currentCluster := &v1alpha1.LVMCluster{}
385+
err := crClient.Get(ctx, client.ObjectKeyFromObject(cluster), currentCluster)
386+
if err != nil {
387+
return v1alpha1.VGStatus{}
388+
}
389+
390+
if len(currentCluster.Status.DeviceClassStatuses) == 0 {
391+
return v1alpha1.VGStatus{}
392+
}
393+
394+
// Find the first device class (usually "vg1")
395+
for _, deviceClassStatus := range currentCluster.Status.DeviceClassStatuses {
396+
if len(deviceClassStatus.NodeStatus) > 0 {
397+
// Return status from the first node with VG status
398+
for _, nodeStatus := range deviceClassStatus.NodeStatus {
399+
if nodeStatus.Name == lvmVolumeGroupName {
400+
return nodeStatus.VGStatus
401+
}
402+
}
403+
}
404+
}
405+
406+
return v1alpha1.VGStatus{}
407+
}

0 commit comments

Comments
 (0)