Skip to content

Commit 2928da4

Browse files
committed
e2e: add nvmeof GroupLock stress tests for concurrent operations
Add e2e tests to validate nvmeof NodeServer GroupLock implementation under concurrent NodeStage (Group A) and NodeUnstage (Group B) operations. The tests ensure no deadlock occurs when multiple PVCs and Pods are created and deleted simultaneously. New helper file (nvmeof_helper.go) provides reusable functions for concurrent PVC/Pod operations with proper error tracking. Two test cases cover: 1) sequential concurrent batches (create all, then delete all) 2) mixed operations with pre-created batch to guarantee continuous Group A/B switching.. Signed-off-by: gadi-didi <gadi.didi@ibm.com>
1 parent 96907dc commit 2928da4

2 files changed

Lines changed: 403 additions & 0 deletions

File tree

e2e/nvmeof.go

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ package e2e
1818

1919
import (
2020
"context"
21+
"fmt"
2122

2223
"github.com/onsi/ginkgo/v2"
2324
. "github.com/onsi/gomega"
@@ -189,5 +190,84 @@ var _ = ginkgo.Describe("nvmeof", func() {
189190
validateRBDImageCount(f, 0, nvmeofPool)
190191
validateOmapCount(f, 0, rbdType, nvmeofPool, volumesType)
191192
})
193+
194+
ginkgo.It("Test GroupLock: Concurrent Create/Delete PVCs and Pods", func() {
195+
// This test validates the GroupLock implementation in the NVMeoF NodeServer
196+
// by creating and deleting multiple PVCs and Pods concurrently.
197+
//
198+
// Test flow:
199+
// 1. Create 3 PVCs + Pods concurrently (triggers NodeStage -> Group A lock)
200+
// 2. Wait for all to be ready
201+
// 3. Delete all PVCs + Pods concurrently (triggers NodeUnstage -> Group B lock)
202+
// 4. Verify no timeouts/deadlocks
203+
// 5. Verify all operations succeed
204+
totalCount := 3
205+
206+
ginkgo.By("Creating multiple PVCs and Pods concurrently")
207+
createResult := createConcurrentPVCsAndApps(totalCount, pvcPath, appPath, f)
208+
209+
// Log any errors
210+
if createResult.HasErrors() {
211+
createResult.LogErrors()
212+
}
213+
214+
// Verify all creations succeeded
215+
Expect(createResult.failed).To(Equal(0),
216+
"Expected all %d create operations to succeed, but %d failed",
217+
totalCount, createResult.failed)
218+
219+
ginkgo.By("Validating backend RBD images were created")
220+
validateRBDImageCount(f, totalCount, nvmeofPool)
221+
validateOmapCount(f, totalCount, rbdType, nvmeofPool, volumesType)
222+
223+
ginkgo.By("Deleting multiple PVCs and Pods concurrently")
224+
deleteResult := deleteConcurrentPVCsAndApps(createResult, pvcPath, appPath, f)
225+
226+
// Log any errors
227+
if deleteResult.HasErrors() {
228+
deleteResult.LogErrors()
229+
}
230+
231+
// Verify all deletions succeeded
232+
Expect(deleteResult.failed).To(Equal(0),
233+
"Expected all %d delete operations to succeed, but %d failed",
234+
totalCount, deleteResult.failed)
235+
236+
ginkgo.By("Validating all backend RBD images were deleted")
237+
validateRBDImageCount(f, 0, nvmeofPool)
238+
validateOmapCount(f, 0, rbdType, nvmeofPool, volumesType)
239+
240+
framework.Logf("GroupLock test passed: %d concurrent create and %d concurrent delete operations completed successfully",
241+
totalCount, totalCount)
242+
})
243+
244+
ginkgo.It("Test GroupLock: Mixed Create/Delete with Rapid Switching", func() {
245+
// This test validates the GroupLock implementation under rapid switching
246+
// between Group A (NodeStage) and Group B (NodeUnstage) operations.
247+
//
248+
// Test flow:
249+
// 1. Create 5 PVCs + Pods (Group A)
250+
// 2. Concurrently start creating next 5 PVCs + Pods (Group A) while deleting previous 5 (Group B)
251+
// 3. Repeat for total of 15 PVCs + Pods with rapid switching between Group A and B
252+
//
253+
// This creates 15 total PVCs and forces rapid GroupLock switching,
254+
// simulating "real-world" scenarios for catching potential deadlocks/starvation.
255+
totalCount := 15
256+
batchSize := 5
257+
258+
ginkgo.By(fmt.Sprintf("Running mixed create/delete test: %d total PVCs in batches of %d",
259+
totalCount, batchSize))
260+
261+
err := mixedCreateDeletePVCsAndApps(totalCount, batchSize, pvcPath, appPath, f)
262+
Expect(err).ShouldNot(HaveOccurred(),
263+
"Mixed create/delete operations should complete without errors")
264+
265+
ginkgo.By("Validating all backend RBD images were cleaned up")
266+
validateRBDImageCount(f, 0, nvmeofPool)
267+
validateOmapCount(f, 0, rbdType, nvmeofPool, volumesType)
268+
269+
framework.Logf("GroupLock mixed test passed: %d PVCs created and deleted with rapid Group A/B switching",
270+
totalCount)
271+
})
192272
})
193273
})

0 commit comments

Comments
 (0)