Skip to content

Commit 34d1ee3

Browse files
authored
Merge pull request #80 from darkowlzz/ctrl-list-vols-starting-token
sanity: Add ListVolumes test to check starting token and next token
2 parents 7e4a8e2 + 5b9ef0c commit 34d1ee3

File tree

2 files changed

+185
-7
lines changed

2 files changed

+185
-7
lines changed

mock/service/controller.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ func (s *service) ListVolumes(
316316
i, err := strconv.ParseUint(v, 10, 32)
317317
if err != nil {
318318
return nil, status.Errorf(
319-
codes.InvalidArgument,
319+
codes.Aborted,
320320
"startingToken=%d !< int32=%d",
321321
startingToken, math.MaxUint32)
322322
}
@@ -325,7 +325,7 @@ func (s *service) ListVolumes(
325325

326326
if startingToken > ulenVols {
327327
return nil, status.Errorf(
328-
codes.InvalidArgument,
328+
codes.Aborted,
329329
"startingToken=%d > len(vols)=%d",
330330
startingToken, ulenVols)
331331
}

pkg/sanity/controller.go

+183-5
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,13 @@ package sanity
1919
import (
2020
"context"
2121
"fmt"
22+
"strconv"
2223

2324
"google.golang.org/grpc/codes"
2425
"google.golang.org/grpc/status"
2526

2627
"github.com/container-storage-interface/spec/lib/go/csi"
2728

28-
"strconv"
29-
3029
. "github.com/onsi/ginkgo"
3130
. "github.com/onsi/gomega"
3231
)
@@ -171,10 +170,189 @@ var _ = DescribeSanity("Controller Service", func(sc *SanityContext) {
171170
}
172171
})
173172

174-
// TODO: Add test to test for tokens
173+
It("should fail when an invalid starting_token is passed", func() {
174+
vols, err := c.ListVolumes(
175+
context.Background(),
176+
&csi.ListVolumesRequest{
177+
StartingToken: "invalid-token",
178+
},
179+
)
180+
Expect(err).To(HaveOccurred())
181+
Expect(vols).To(BeNil())
182+
183+
serverError, ok := status.FromError(err)
184+
Expect(ok).To(BeTrue())
185+
Expect(serverError.Code()).To(Equal(codes.Aborted))
186+
})
187+
188+
It("should fail when the starting_token is greater than total number of vols", func() {
189+
// Get total number of volumes.
190+
vols, err := c.ListVolumes(
191+
context.Background(),
192+
&csi.ListVolumesRequest{})
193+
Expect(err).NotTo(HaveOccurred())
194+
Expect(vols).NotTo(BeNil())
195+
196+
totalVols := len(vols.GetEntries())
197+
198+
// Send starting_token that is greater than the total number of volumes.
199+
vols, err = c.ListVolumes(
200+
context.Background(),
201+
&csi.ListVolumesRequest{
202+
StartingToken: strconv.Itoa(totalVols + 5),
203+
},
204+
)
205+
Expect(err).To(HaveOccurred())
206+
Expect(vols).To(BeNil())
207+
208+
serverError, ok := status.FromError(err)
209+
Expect(ok).To(BeTrue())
210+
Expect(serverError.Code()).To(Equal(codes.Aborted))
211+
})
212+
213+
It("check the presence of new volumes in the volume list", func() {
214+
// List Volumes before creating new volume.
215+
vols, err := c.ListVolumes(
216+
context.Background(),
217+
&csi.ListVolumesRequest{})
218+
Expect(err).NotTo(HaveOccurred())
219+
Expect(vols).NotTo(BeNil())
220+
221+
totalVols := len(vols.GetEntries())
222+
223+
By("creating a volume")
224+
name := "sanity"
225+
226+
// Create a new volume.
227+
req := &csi.CreateVolumeRequest{
228+
Name: name,
229+
VolumeCapabilities: []*csi.VolumeCapability{
230+
{
231+
AccessType: &csi.VolumeCapability_Mount{
232+
Mount: &csi.VolumeCapability_MountVolume{},
233+
},
234+
AccessMode: &csi.VolumeCapability_AccessMode{
235+
Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER,
236+
},
237+
},
238+
},
239+
Secrets: sc.Secrets.CreateVolumeSecret,
240+
}
175241

176-
// TODO: Add test which checks list of volume is there when created,
177-
// and not there when deleted.
242+
vol, err := c.CreateVolume(context.Background(), req)
243+
Expect(err).NotTo(HaveOccurred())
244+
Expect(vol).NotTo(BeNil())
245+
Expect(vol.GetVolume()).NotTo(BeNil())
246+
Expect(vol.GetVolume().GetVolumeId()).NotTo(BeEmpty())
247+
248+
// List volumes and check for the newly created volume.
249+
vols, err = c.ListVolumes(
250+
context.Background(),
251+
&csi.ListVolumesRequest{})
252+
Expect(err).NotTo(HaveOccurred())
253+
Expect(vols).NotTo(BeNil())
254+
Expect(len(vols.GetEntries())).To(Equal(totalVols + 1))
255+
256+
By("cleaning up deleting the volume")
257+
258+
delReq := &csi.DeleteVolumeRequest{
259+
VolumeId: vol.GetVolume().GetVolumeId(),
260+
Secrets: sc.Secrets.DeleteVolumeSecret,
261+
}
262+
263+
_, err = c.DeleteVolume(context.Background(), delReq)
264+
Expect(err).NotTo(HaveOccurred())
265+
266+
// List volumes and check if the deleted volume exists in the volume list.
267+
vols, err = c.ListVolumes(
268+
context.Background(),
269+
&csi.ListVolumesRequest{})
270+
Expect(err).NotTo(HaveOccurred())
271+
Expect(vols).NotTo(BeNil())
272+
Expect(len(vols.GetEntries())).To(Equal(totalVols))
273+
})
274+
275+
It("should return next token when a limited number of entries are requested", func() {
276+
// minVolCount is the minimum number of volumes expected to exist,
277+
// based on which paginated volume listing is performed.
278+
minVolCount := 5
279+
// maxEntried is the maximum entries in list volume request.
280+
maxEntries := 2
281+
// currentTotalVols is the total number of volumes at a given time. It
282+
// is used to verify that all the volumes have been listed.
283+
currentTotalVols := 0
284+
// newVolIDs to keep a record of the newly created volume ids.
285+
var newVolIDs []string
286+
287+
// Get the number of existing volumes.
288+
vols, err := c.ListVolumes(
289+
context.Background(),
290+
&csi.ListVolumesRequest{})
291+
Expect(err).NotTo(HaveOccurred())
292+
Expect(vols).NotTo(BeNil())
293+
294+
initialTotalVols := len(vols.GetEntries())
295+
currentTotalVols = initialTotalVols
296+
297+
// Ensure minimum minVolCount volumes exist.
298+
if initialTotalVols < minVolCount {
299+
300+
By("creating required new volumes")
301+
requiredVols := minVolCount - initialTotalVols
302+
name := "sanity"
303+
for i := 1; i <= requiredVols; i++ {
304+
req := &csi.CreateVolumeRequest{
305+
Name: name + strconv.Itoa(i),
306+
VolumeCapabilities: []*csi.VolumeCapability{
307+
{
308+
AccessType: &csi.VolumeCapability_Mount{
309+
Mount: &csi.VolumeCapability_MountVolume{},
310+
},
311+
AccessMode: &csi.VolumeCapability_AccessMode{
312+
Mode: csi.VolumeCapability_AccessMode_SINGLE_NODE_WRITER,
313+
},
314+
},
315+
},
316+
Secrets: sc.Secrets.CreateVolumeSecret,
317+
}
318+
319+
vol, err := c.CreateVolume(context.Background(), req)
320+
Expect(err).NotTo(HaveOccurred())
321+
Expect(vol).NotTo(BeNil())
322+
}
323+
324+
// Update the current total vols count.
325+
currentTotalVols += requiredVols
326+
}
327+
328+
// Request list volumes with max entries maxEntries.
329+
vols, err = c.ListVolumes(
330+
context.Background(),
331+
&csi.ListVolumesRequest{
332+
MaxEntries: int32(maxEntries),
333+
})
334+
Expect(err).NotTo(HaveOccurred())
335+
Expect(vols).NotTo(BeNil())
336+
337+
nextToken := vols.GetNextToken()
338+
339+
Expect(nextToken).To(Equal(strconv.Itoa(maxEntries)))
340+
Expect(len(vols.GetEntries())).To(Equal(maxEntries))
341+
342+
if initialTotalVols < minVolCount {
343+
344+
By("cleaning up deleting the volumes")
345+
for _, volID := range newVolIDs {
346+
delReq := &csi.DeleteVolumeRequest{
347+
VolumeId: volID,
348+
Secrets: sc.Secrets.DeleteVolumeSecret,
349+
}
350+
351+
_, err := c.DeleteVolume(context.Background(), delReq)
352+
Expect(err).NotTo(HaveOccurred())
353+
}
354+
}
355+
})
178356
})
179357

180358
Describe("CreateVolume", func() {

0 commit comments

Comments
 (0)