Skip to content

Commit a4d33b1

Browse files
Add tests for ROX mode during Node Stage (kubernetes-sigs#1215)
* Add tests for resize during node stage * Add test for readonly capability * run hack/update-gofmt.sh * Update pkg/gce-pd-csi-driver/node_test.go Co-authored-by: Roman Bednář <[email protected]> * Update pkg/gce-pd-csi-driver/node_test.go Co-authored-by: Roman Bednář <[email protected]> * run hack/update-gofmt.sh --------- Co-authored-by: Roman Bednář <[email protected]>
1 parent 5ceccbf commit a4d33b1

File tree

5 files changed

+126
-25
lines changed

5 files changed

+126
-25
lines changed

docs/kubernetes/development.md

-3
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,6 @@ You may see errors during driver deployment.
102102

103103
### Sanity tests
104104

105-
> ***NOTE:*** Sanity tests are currently failing, tracked by
106-
> https://github.com/kubernetes-sigs/gcp-compute-persistent-disk-csi-driver/issues/990.
107-
108105
```
109106
./test/run-sanity.sh
110107
```

pkg/deviceutils/fake-device-utils.go

+10-4
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,15 @@ package deviceutils
1717
import "sigs.k8s.io/gcp-compute-persistent-disk-csi-driver/pkg/resizefs"
1818

1919
type fakeDeviceUtils struct {
20+
skipResize bool
2021
}
2122

2223
var _ DeviceUtils = &fakeDeviceUtils{}
2324

24-
func NewFakeDeviceUtils() *fakeDeviceUtils {
25-
return &fakeDeviceUtils{}
25+
func NewFakeDeviceUtils(skipResize bool) *fakeDeviceUtils {
26+
return &fakeDeviceUtils{
27+
skipResize: skipResize,
28+
}
2629
}
2730

2831
// Returns list of all /dev/disk/by-id/* paths for given PD.
@@ -41,6 +44,9 @@ func (_ *fakeDeviceUtils) DisableDevice(devicePath string) error {
4144
return nil
4245
}
4346

44-
func (_ *fakeDeviceUtils) Resize(resizer resizefs.Resizefs, devicePath string, deviceMountPath string) (bool, error) {
45-
return false, nil
47+
func (du *fakeDeviceUtils) Resize(resizer resizefs.Resizefs, devicePath string, deviceMountPath string) (bool, error) {
48+
if du.skipResize {
49+
return false, nil
50+
}
51+
return resizer.Resize(devicePath, deviceMountPath)
4652
}

pkg/gce-pd-csi-driver/node.go

+15-4
Original file line numberDiff line numberDiff line change
@@ -342,10 +342,12 @@ func (ns *GCENodeServer) NodeStageVolume(ctx context.Context, req *csi.NodeStage
342342

343343
// Part 4: Resize filesystem.
344344
// https://github.com/kubernetes/kubernetes/issues/94929
345-
resizer := resizefs.NewResizeFs(ns.Mounter)
346-
_, err = ns.DeviceUtils.Resize(resizer, devicePath, stagingTargetPath)
347-
if err != nil {
348-
return nil, status.Error(codes.Internal, fmt.Sprintf("error when resizing volume %s from device '%s' at path '%s': %v", volumeID, devicePath, stagingTargetPath, err.Error()))
345+
if !readonly {
346+
resizer := resizefs.NewResizeFs(ns.Mounter)
347+
_, err = ns.DeviceUtils.Resize(resizer, devicePath, stagingTargetPath)
348+
if err != nil {
349+
return nil, status.Error(codes.Internal, fmt.Sprintf("error when resizing volume %s from device '%s' at path '%s': %v", volumeID, devicePath, stagingTargetPath, err.Error()))
350+
}
349351
}
350352

351353
klog.V(4).Infof("NodeStageVolume succeeded on %v to %s", volumeID, stagingTargetPath)
@@ -505,6 +507,15 @@ func (ns *GCENodeServer) NodeExpandVolume(ctx context.Context, req *csi.NodeExpa
505507
klog.V(4).Infof("NodeExpandVolume succeeded on %v to %s, capability is block so this is a no-op", volumeID, volumePath)
506508
return &csi.NodeExpandVolumeResponse{}, nil
507509
}
510+
511+
readonly, err := getReadOnlyFromCapability(volumeCapability)
512+
if err != nil {
513+
return nil, status.Error(codes.Internal, fmt.Sprintf("failed to check if capability for volume %s is readonly: %v", volumeID, err))
514+
}
515+
if readonly {
516+
klog.V(4).Infof("NodeExpandVolume succeeded on %v to %s, capability access is readonly so this is a no-op", volumeID, volumePath)
517+
return &csi.NodeExpandVolumeResponse{}, nil
518+
}
508519
}
509520

510521
// TODO(#328): Use requested size in resize if provided

pkg/gce-pd-csi-driver/node_test.go

+100-13
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"io/ioutil"
2222
"os"
2323
"path/filepath"
24+
"strings"
2425
"testing"
2526

2627
"k8s.io/utils/exec"
@@ -40,11 +41,11 @@ const defaultTargetPath = "/mnt/test"
4041
const defaultStagingPath = "/staging"
4142

4243
func getTestGCEDriver(t *testing.T) *GCEDriver {
43-
return getCustomTestGCEDriver(t, mountmanager.NewFakeSafeMounter(), deviceutils.NewFakeDeviceUtils(), metadataservice.NewFakeService())
44+
return getCustomTestGCEDriver(t, mountmanager.NewFakeSafeMounter(), deviceutils.NewFakeDeviceUtils(false), metadataservice.NewFakeService())
4445
}
4546

4647
func getTestGCEDriverWithCustomMounter(t *testing.T, mounter *mount.SafeFormatAndMount) *GCEDriver {
47-
return getCustomTestGCEDriver(t, mounter, deviceutils.NewFakeDeviceUtils(), metadataservice.NewFakeService())
48+
return getCustomTestGCEDriver(t, mounter, deviceutils.NewFakeDeviceUtils(false), metadataservice.NewFakeService())
4849
}
4950

5051
func getCustomTestGCEDriver(t *testing.T, mounter *mount.SafeFormatAndMount, deviceUtils deviceutils.DeviceUtils, metaService metadataservice.MetadataService) *GCEDriver {
@@ -60,7 +61,7 @@ func getCustomTestGCEDriver(t *testing.T, mounter *mount.SafeFormatAndMount, dev
6061
func getTestBlockingGCEDriver(t *testing.T, readyToExecute chan chan struct{}) *GCEDriver {
6162
gceDriver := GetGCEDriver()
6263
mounter := mountmanager.NewFakeSafeBlockingMounter(readyToExecute)
63-
nodeServer := NewNodeServer(gceDriver, mounter, deviceutils.NewFakeDeviceUtils(), metadataservice.NewFakeService(), mountmanager.NewFakeStatter(mounter))
64+
nodeServer := NewNodeServer(gceDriver, mounter, deviceutils.NewFakeDeviceUtils(false), metadataservice.NewFakeService(), mountmanager.NewFakeStatter(mounter))
6465
err := gceDriver.SetupGCEDriver(driver, "test-vendor", nil, nil, nil, nodeServer)
6566
if err != nil {
6667
t.Fatalf("Failed to setup GCE Driver: %v", err)
@@ -381,26 +382,61 @@ func TestNodeStageVolume(t *testing.T) {
381382
stagingPath := filepath.Join(tempDir, defaultStagingPath)
382383

383384
testCases := []struct {
384-
name string
385-
req *csi.NodeStageVolumeRequest
386-
expErrCode codes.Code
385+
name string
386+
req *csi.NodeStageVolumeRequest
387+
deviceSize int
388+
blockExtSize int
389+
readonlyBit string
390+
expResize bool
391+
expErrCode codes.Code
387392
}{
388393
{
389-
name: "Valid request",
394+
name: "Valid request, no resize because block and filesystem sizes match",
390395
req: &csi.NodeStageVolumeRequest{
391396
VolumeId: volumeID,
392397
StagingTargetPath: stagingPath,
393398
VolumeCapability: stdVolCap,
394399
},
400+
deviceSize: 1,
401+
blockExtSize: 1,
402+
readonlyBit: "0",
403+
expResize: false,
395404
},
396405
{
397-
name: "Invalid request (Bad Access Mode)",
406+
name: "Valid request, no resize bc readonly",
398407
req: &csi.NodeStageVolumeRequest{
399408
VolumeId: volumeID,
400409
StagingTargetPath: stagingPath,
401-
VolumeCapability: createVolumeCapability(csi.VolumeCapability_AccessMode_UNKNOWN),
410+
VolumeCapability: stdVolCap,
402411
},
403-
expErrCode: codes.InvalidArgument,
412+
deviceSize: 1,
413+
blockExtSize: 1,
414+
readonlyBit: "1",
415+
expResize: false,
416+
},
417+
{
418+
name: "Valid request, resize bc size",
419+
req: &csi.NodeStageVolumeRequest{
420+
VolumeId: volumeID,
421+
StagingTargetPath: stagingPath,
422+
VolumeCapability: stdVolCap,
423+
},
424+
deviceSize: 5,
425+
blockExtSize: 1,
426+
readonlyBit: "0",
427+
expResize: true,
428+
},
429+
{
430+
name: "Valid request, no resize bc readonly capability",
431+
req: &csi.NodeStageVolumeRequest{
432+
VolumeId: volumeID,
433+
StagingTargetPath: stagingPath,
434+
VolumeCapability: createVolumeCapability(csi.VolumeCapability_AccessMode_MULTI_NODE_READER_ONLY),
435+
},
436+
deviceSize: 5,
437+
blockExtSize: 1,
438+
readonlyBit: "0",
439+
expResize: false,
404440
},
405441
{
406442
name: "Invalid request (Bad Access Mode)",
@@ -448,6 +484,7 @@ func TestNodeStageVolume(t *testing.T) {
448484
}
449485
for _, tc := range testCases {
450486
t.Logf("Test case: %s", tc.name)
487+
resizeCalled := false
451488
actionList := []testingexec.FakeCommandAction{
452489
makeFakeCmd(
453490
&testingexec.FakeCmd{
@@ -458,26 +495,40 @@ func TestNodeStageVolume(t *testing.T) {
458495
},
459496
},
460497
"blkid",
498+
strings.Split("-p -s TYPE -s PTTYPE -o export /dev/disk/fake-path", " ")...,
461499
),
462500
makeFakeCmd(
463501
&testingexec.FakeCmd{
464502
CombinedOutputScript: []testingexec.FakeAction{
465503
func() ([]byte, []byte, error) {
466-
return []byte("1"), nil, nil
504+
return []byte(""), nil, nil
505+
},
506+
},
507+
},
508+
"fsck",
509+
strings.Split("-a /dev/disk/fake-path", " ")...,
510+
),
511+
makeFakeCmd(
512+
&testingexec.FakeCmd{
513+
CombinedOutputScript: []testingexec.FakeAction{
514+
func() ([]byte, []byte, error) {
515+
return []byte(tc.readonlyBit), nil, nil
467516
},
468517
},
469518
},
470519
"blockdev",
520+
strings.Split("--getro /dev/disk/fake-path", " ")...,
471521
),
472522
makeFakeCmd(
473523
&testingexec.FakeCmd{
474524
CombinedOutputScript: []testingexec.FakeAction{
475525
func() ([]byte, []byte, error) {
476-
return []byte("1"), nil, nil
526+
return []byte(fmt.Sprintf("%d", tc.deviceSize)), nil, nil
477527
},
478528
},
479529
},
480530
"blockdev",
531+
strings.Split("--getsize64 /dev/disk/fake-path", " ")...,
481532
),
482533
makeFakeCmd(
483534
&testingexec.FakeCmd{
@@ -488,18 +539,48 @@ func TestNodeStageVolume(t *testing.T) {
488539
},
489540
},
490541
"blkid",
542+
strings.Split("-p -s TYPE -s PTTYPE -o export /dev/disk/fake-path", " ")...,
491543
),
492544
makeFakeCmd(
493545
&testingexec.FakeCmd{
494546
CombinedOutputScript: []testingexec.FakeAction{
495547
func() ([]byte, []byte, error) {
496-
return []byte(fmt.Sprintf("block size: 1\nblock count: 1")), nil, nil
548+
return []byte(fmt.Sprintf("block size: %d\nblock count: 1", tc.blockExtSize)), nil, nil
497549
},
498550
},
499551
},
500552
"dumpe2fs",
553+
strings.Split("-h /dev/disk/fake-path", " ")...,
501554
),
502555
}
556+
557+
if tc.expResize {
558+
actionList = append(actionList, []testingexec.FakeCommandAction{
559+
makeFakeCmd(
560+
&testingexec.FakeCmd{
561+
CombinedOutputScript: []testingexec.FakeAction{
562+
func() ([]byte, []byte, error) {
563+
return []byte(fmt.Sprintf("DEVNAME=/dev/sdb\nTYPE=ext4")), nil, nil
564+
},
565+
},
566+
},
567+
"blkid",
568+
strings.Split("-p -s TYPE -s PTTYPE -o export /dev/disk/fake-path", " ")...,
569+
),
570+
makeFakeCmd(
571+
&testingexec.FakeCmd{
572+
CombinedOutputScript: []testingexec.FakeAction{
573+
func() ([]byte, []byte, error) {
574+
resizeCalled = true
575+
return []byte(fmt.Sprintf("DEVNAME=/dev/sdb\nTYPE=ext4")), nil, nil
576+
},
577+
},
578+
},
579+
"resize2fs",
580+
strings.Split("/dev/disk/fake-path", " ")...,
581+
),
582+
}...)
583+
}
503584
mounter := mountmanager.NewFakeSafeMounterWithCustomExec(&testingexec.FakeExec{CommandScript: actionList})
504585
gceDriver := getTestGCEDriverWithCustomMounter(t, mounter)
505586
ns := gceDriver.ns
@@ -517,6 +598,12 @@ func TestNodeStageVolume(t *testing.T) {
517598
if tc.expErrCode != codes.OK {
518599
t.Fatalf("Expected error: %v, got no error", tc.expErrCode)
519600
}
601+
if tc.expResize == true && resizeCalled == false {
602+
t.Fatalf("Test did not call resize, but it was expected.")
603+
}
604+
if tc.expResize == false && resizeCalled == true {
605+
t.Fatalf("Test called resize, but it was not expected.")
606+
}
520607
}
521608
}
522609

test/sanity/sanity_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ func TestSanity(t *testing.T) {
6262
}
6363

6464
mounter := mountmanager.NewFakeSafeMounter()
65-
deviceUtils := deviceutils.NewFakeDeviceUtils()
65+
deviceUtils := deviceutils.NewFakeDeviceUtils(true)
6666

6767
//Initialize GCE Driver
6868
identityServer := driver.NewIdentityServer(gceDriver)

0 commit comments

Comments
 (0)