Skip to content

Commit ecad573

Browse files
committed
Treat list volume tokens as opaque
When listing volumes using pagination we must treat the "next_token" field as opaque data and not make assumptions about what's in it. This patch removes tests that assume tokens are integers and that they represent the number of volumes that have been listed, replacing one of them with one to check that pagination works as expected when new volumes are created and old ones deleted between page requests. This closes issue 204
1 parent 65a7181 commit ecad573

File tree

1 file changed

+62
-56
lines changed

1 file changed

+62
-56
lines changed

pkg/sanity/controller.go

Lines changed: 62 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -197,32 +197,7 @@ var _ = DescribeSanity("Controller Service", func(sc *SanityContext) {
197197
Expect(serverError.Code()).To(Equal(codes.Aborted))
198198
})
199199

200-
It("should fail when the starting_token is greater than total number of vols", func() {
201-
// Get total number of volumes.
202-
vols, err := c.ListVolumes(
203-
context.Background(),
204-
&csi.ListVolumesRequest{})
205-
Expect(err).NotTo(HaveOccurred())
206-
Expect(vols).NotTo(BeNil())
207-
208-
totalVols := len(vols.GetEntries())
209-
210-
// Send starting_token that is greater than the total number of volumes.
211-
vols, err = c.ListVolumes(
212-
context.Background(),
213-
&csi.ListVolumesRequest{
214-
StartingToken: strconv.Itoa(totalVols + 5),
215-
},
216-
)
217-
Expect(err).To(HaveOccurred())
218-
Expect(vols).To(BeNil())
219-
220-
serverError, ok := status.FromError(err)
221-
Expect(ok).To(BeTrue())
222-
Expect(serverError.Code()).To(Equal(codes.Aborted))
223-
})
224-
225-
It("check the presence of new volumes in the volume list", func() {
200+
It("check the presence of new volumes and absence of deleted ones in the volume list", func() {
226201
// List Volumes before creating new volume.
227202
vols, err := c.ListVolumes(
228203
context.Background(),
@@ -284,17 +259,14 @@ var _ = DescribeSanity("Controller Service", func(sc *SanityContext) {
284259
Expect(len(vols.GetEntries())).To(Equal(totalVols))
285260
})
286261

287-
It("should return next token when a limited number of entries are requested", func() {
262+
It("pagination should detect volumes added between pages and accept tokens when the last volume from a page is deleted", func() {
288263
// minVolCount is the minimum number of volumes expected to exist,
289264
// based on which paginated volume listing is performed.
290-
minVolCount := 5
265+
minVolCount := 3
291266
// maxEntried is the maximum entries in list volume request.
292267
maxEntries := 2
293-
// currentTotalVols is the total number of volumes at a given time. It
294-
// is used to verify that all the volumes have been listed.
295-
currentTotalVols := 0
296-
// newVols to keep a record of the newly created volume names and ids.
297-
newVols := map[string]string{}
268+
// existing_vols to keep a record of the volumes that should exist
269+
existing_vols := map[string]bool{}
298270

299271
// Get the number of existing volumes.
300272
vols, err := c.ListVolumes(
@@ -304,14 +276,17 @@ var _ = DescribeSanity("Controller Service", func(sc *SanityContext) {
304276
Expect(vols).NotTo(BeNil())
305277

306278
initialTotalVols := len(vols.GetEntries())
307-
currentTotalVols = initialTotalVols
308279

309-
// Ensure minimum minVolCount volumes exist.
310-
if initialTotalVols < minVolCount {
280+
for _, vol := range vols.GetEntries() {
281+
existing_vols[vol.Volume.VolumeId] = true
282+
}
311283

284+
if minVolCount <= initialTotalVols {
285+
minVolCount = initialTotalVols
286+
} else {
287+
// Ensure minimum minVolCount volumes exist.
312288
By("creating required new volumes")
313-
requiredVols := minVolCount - initialTotalVols
314-
for i := 1; i <= requiredVols; i++ {
289+
for i := initialTotalVols; i < minVolCount; i++ {
315290
name := "sanity" + strconv.Itoa(i)
316291
req := &csi.CreateVolumeRequest{
317292
Name: name,
@@ -331,12 +306,10 @@ var _ = DescribeSanity("Controller Service", func(sc *SanityContext) {
331306
vol, err := c.CreateVolume(context.Background(), req)
332307
Expect(err).NotTo(HaveOccurred())
333308
Expect(vol).NotTo(BeNil())
334-
cl.RegisterVolume(name, VolumeInfo{VolumeID: vol.Volume.VolumeId})
335-
newVols[name] = vol.Volume.VolumeId
309+
// Register the volume so it's automatically cleaned
310+
cl.RegisterVolume(vol.Volume.VolumeId, VolumeInfo{VolumeID: vol.Volume.VolumeId})
311+
existing_vols[vol.Volume.VolumeId] = true
336312
}
337-
338-
// Update the current total vols count.
339-
currentTotalVols += requiredVols
340313
}
341314

342315
// Request list volumes with max entries maxEntries.
@@ -347,25 +320,58 @@ var _ = DescribeSanity("Controller Service", func(sc *SanityContext) {
347320
})
348321
Expect(err).NotTo(HaveOccurred())
349322
Expect(vols).NotTo(BeNil())
323+
Expect(len(vols.GetEntries())).To(Equal(maxEntries))
350324

351325
nextToken := vols.GetNextToken()
352326

353-
Expect(nextToken).To(Equal(strconv.Itoa(maxEntries)))
354-
Expect(len(vols.GetEntries())).To(Equal(maxEntries))
327+
By("removing all listed volumes")
328+
for _, vol := range vols.GetEntries() {
329+
Expect(existing_vols[vol.Volume.VolumeId]).To(BeTrue())
330+
delReq := &csi.DeleteVolumeRequest{
331+
VolumeId: vol.Volume.VolumeId,
332+
Secrets: sc.Secrets.DeleteVolumeSecret,
333+
}
355334

356-
if initialTotalVols < minVolCount {
335+
_, err := c.DeleteVolume(context.Background(), delReq)
336+
Expect(err).NotTo(HaveOccurred())
337+
vol_id := vol.Volume.VolumeId
338+
existing_vols[vol_id] = false
339+
cl.UnregisterVolume(vol_id)
340+
}
357341

358-
By("cleaning up deleting the volumes")
359-
for name, volID := range newVols {
360-
delReq := &csi.DeleteVolumeRequest{
361-
VolumeId: volID,
362-
Secrets: sc.Secrets.DeleteVolumeSecret,
363-
}
342+
By("creating a new volume")
343+
req := &csi.CreateVolumeRequest{
344+
Name: "new-addition",
345+
VolumeCapabilities: []*csi.VolumeCapability{
346+
{
347+
AccessType: &csi.VolumeCapability_Mount{
348+
Mount: &csi.VolumeCapability_MountVolume{},
349+
},
350+
AccessMode: &csi.VolumeCapability_AccessMode{
351+
Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER,
352+
},
353+
},
354+
},
355+
Secrets: sc.Secrets.CreateVolumeSecret,
356+
}
357+
vol, err := c.CreateVolume(context.Background(), req)
358+
Expect(err).NotTo(HaveOccurred())
359+
Expect(vol).NotTo(BeNil())
360+
Expect(vol.Volume).NotTo(BeNil())
361+
existing_vols[vol.Volume.VolumeId] = true
364362

365-
_, err := c.DeleteVolume(context.Background(), delReq)
366-
Expect(err).NotTo(HaveOccurred())
367-
cl.UnregisterVolume(name)
368-
}
363+
vols, err = c.ListVolumes(
364+
context.Background(),
365+
&csi.ListVolumesRequest{
366+
StartingToken: nextToken,
367+
})
368+
Expect(err).NotTo(HaveOccurred())
369+
Expect(vols).NotTo(BeNil())
370+
expected_num_volumes := minVolCount - maxEntries + 1
371+
Expect(len(vols.GetEntries())).To(Equal(expected_num_volumes))
372+
for _, vol := range vols.GetEntries() {
373+
Expect(existing_vols[vol.Volume.VolumeId]).To(BeTrue())
374+
existing_vols[vol.Volume.VolumeId] = false
369375
}
370376
})
371377
})

0 commit comments

Comments
 (0)