@@ -25,7 +25,11 @@ import (
2525 "strings"
2626 "time"
2727
28+ "github.com/googlecloudplatform/gcs-fuse-csi-driver/pkg/util"
29+ "github.com/googlecloudplatform/gcs-fuse-csi-driver/pkg/webhook"
2830 "github.com/onsi/ginkgo/v2"
31+ "github.com/onsi/gomega"
32+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2933 utilerrors "k8s.io/apimachinery/pkg/util/errors"
3034 "k8s.io/klog/v2"
3135 "k8s.io/kubernetes/test/e2e/framework"
@@ -87,8 +91,16 @@ func (t *gcsFuseCSIMultiVolumeTestSuite) DefineTests(driver storageframework.Tes
8791 }
8892
8993 l .volumeResourceList = []* storageframework.VolumeResource {}
90- for range volumeNumber {
91- l .volumeResourceList = append (l .volumeResourceList , specs .CreateVolumeResource (ctx , driver , l .config , pattern , e2evolume.SizeRange {}))
94+ for i := range volumeNumber {
95+ suffix := ""
96+ if len (configPrefix ) > 0 && configPrefix [0 ] == specs .BucketWithTwoUniqueVolSuffixPrefix {
97+ if i == 0 {
98+ suffix = ":rwx"
99+ } else if i == 1 {
100+ suffix = ":rox"
101+ }
102+ }
103+ l .volumeResourceList = append (l .volumeResourceList , specs .CreateVolumeResource (ctx , driver , l .config , pattern , e2evolume.SizeRange {}, suffix ))
92104 }
93105 }
94106
@@ -396,4 +408,60 @@ func (t *gcsFuseCSIMultiVolumeTestSuite) DefineTests(driver storageframework.Tes
396408
397409 testOnePodMultipleBuckets ()
398410 })
411+
412+ // This tests mounting two volumes via a unique suffix using shared mount as seen in https://docs.cloud.google.com/kubernetes-engine/docs/how-to/cloud-storage-fuse-csi-driver-pv#mount-same-bucket-different-pv.
413+ ginkgo .It ("[shared-mount] should access the same bucket via different PV's with unique volumeHandles from different Pods on the same node" , func () {
414+ if pattern .VolType != storageframework .PreprovisionedPV {
415+ e2eskipper .Skipf ("skip for volume type %v" , pattern .VolType )
416+ }
417+
418+ init (2 , specs .BucketWithTwoUniqueVolSuffixPrefix )
419+ l .volumeResourceList [1 ].VolSource .PersistentVolumeClaim .ReadOnly = true
420+ defer cleanup ()
421+
422+ // 1. Deploy Pod 1 (ReadWriteMany).
423+ ginkgo .By ("Configuring the first pod (ReadWriteMany)" )
424+ tPod1 := specs .NewTestPod (f .ClientSet , f .Namespace )
425+ tPod1 .SetupVolume (l .volumeResourceList [0 ], volumeName , mountPath , false /* readOnly */ )
426+
427+ ginkgo .By ("Deploying the first pod" )
428+ tPod1 .Create (ctx )
429+ defer tPod1 .Cleanup (ctx )
430+
431+ ginkgo .By ("Checking that the first pod is running" )
432+ tPod1 .WaitForRunning (ctx )
433+ nodeName := tPod1 .GetNode ()
434+
435+ // 2. Deploy Pod 2 (ReadOnlyMany) on the same node.
436+ ginkgo .By ("Configuring the second pod (ReadOnlyMany) on the same node" )
437+ tPod2 := specs .NewTestPod (f .ClientSet , f .Namespace )
438+ tPod2 .SetupVolume (l .volumeResourceList [1 ], volumeName , mountPath , true /* readOnly */ )
439+ tPod2 .SetNodeAffinity (nodeName , true /* sameNode */ )
440+
441+ ginkgo .By ("Deploying the second pod" )
442+ tPod2 .Create (ctx )
443+ defer tPod2 .Cleanup (ctx )
444+
445+ ginkgo .By ("Checking that the second pod is running" )
446+ tPod2 .WaitForRunning (ctx )
447+
448+ // 3. Verify distinct Mounter Pods exist for each volumeHandle in our ns.
449+ ginkgo .By ("Verifying distinct Mounter Pods exist for each volumeHandle" )
450+ mounterPods , err := f .ClientSet .CoreV1 ().Pods (f .Namespace .Name ).List (ctx , metav1.ListOptions {
451+ LabelSelector : fmt .Sprintf ("%s=%s" , webhook .SharedMountLabel , util .TrueStr ),
452+ })
453+ framework .ExpectNoError (err , "failed to list mounter pods" )
454+ gomega .Expect (mounterPods .Items ).To (gomega .HaveLen (2 ), "expected 2 distinct Mounter Pods for unique volumeHandles" )
455+
456+ // 4. Verify Pod 1 (RWX) operations.
457+ ginkgo .By ("Verifying RWX pod read and write operations" )
458+ tPod1 .VerifyExecInPodSucceed (f , specs .TesterContainerName , fmt .Sprintf ("mount | grep %v | grep rw," , mountPath ))
459+ tPod1 .VerifyExecInPodSucceed (f , specs .TesterContainerName , fmt .Sprintf ("echo 'hello world rwx' > %v/data-rwx && grep 'hello world rwx' %v/data-rwx" , mountPath , mountPath ))
460+
461+ // 5. Verify Pod 2 (ROX) operations and access mode enforcement.
462+ ginkgo .By ("Verifying ROX pod read operation and write restriction enforcement" )
463+ tPod2 .VerifyExecInPodSucceed (f , specs .TesterContainerName , fmt .Sprintf ("mount | grep %v | grep ro," , mountPath ))
464+ tPod2 .VerifyExecInPodSucceed (f , specs .TesterContainerName , fmt .Sprintf ("grep 'hello world rwx' %v/data-rwx" , mountPath ))
465+ tPod2 .VerifyExecInPodFail (f , specs .TesterContainerName , fmt .Sprintf ("echo 'hello world rox' > %v/data-rox" , mountPath ), 1 )
466+ })
399467}
0 commit comments