@@ -68,6 +68,7 @@ func TestNodeStageVolume_Success(t *testing.T) {
6868 miscsi .EXPECT ().Login (ctx , target ).Return (nil )
6969 miscsi .EXPECT ().GetDevice (ctx , target ).Return ("/dev/sdb" , nil )
7070 miscsi .EXPECT ().WaitForDevice (ctx , "/dev/sdb" , 30 * time .Second ).Return (nil )
71+ mmount .EXPECT ().IsMounted ("/tmp/staging" ).Return (false , nil )
7172 mmount .EXPECT ().FormatAndMountDevice (ctx , "/dev/sdb" , "/tmp/staging" , "ext4" , nil ).Return (nil )
7273
7374 resp , err := svc .NodeStageVolume (ctx , req )
@@ -112,6 +113,7 @@ func TestNodeStageVolume_AlreadyLoggedIn(t *testing.T) {
112113 miscsi .EXPECT ().IsLoggedIn (ctx , target ).Return (true , nil )
113114 miscsi .EXPECT ().GetDevice (ctx , target ).Return ("/dev/sdb" , nil )
114115 miscsi .EXPECT ().WaitForDevice (ctx , "/dev/sdb" , 30 * time .Second ).Return (nil )
116+ mmount .EXPECT ().IsMounted ("/tmp/staging" ).Return (false , nil )
115117 mmount .EXPECT ().FormatAndMountDevice (ctx , "/dev/sdb" , "/tmp/staging" , "xfs" , nil ).Return (nil )
116118
117119 resp , err := svc .NodeStageVolume (ctx , req )
@@ -120,6 +122,51 @@ func TestNodeStageVolume_AlreadyLoggedIn(t *testing.T) {
120122 g .Expect (resp ).NotTo (BeNil ())
121123}
122124
125+ func TestNodeStageVolume_AlreadyStaged (t * testing.T ) {
126+ g := NewGomegaWithT (t )
127+ ctrl := gomock .NewController (t )
128+ defer ctrl .Finish ()
129+
130+ svc , miscsi , mmount := newTestNode (ctrl )
131+ ctx := context .Background ()
132+
133+ req := & csi.NodeStageVolumeRequest {
134+ VolumeId : "vol-1" ,
135+ StagingTargetPath : "/tmp/staging" ,
136+ PublishContext : map [string ]string {
137+ "target-iqn" : "iqn.2024-01.com.example:target" ,
138+ "ip-address" : "192.168.1.100" ,
139+ "username" : "testuser" ,
140+ "password" : "testpass" ,
141+ },
142+ VolumeCapability : & csi.VolumeCapability {
143+ AccessType : & csi.VolumeCapability_Mount {
144+ Mount : & csi.VolumeCapability_MountVolume {
145+ FsType : "ext4" ,
146+ },
147+ },
148+ },
149+ }
150+
151+ target := & iscsi.TargetInfo {
152+ Portal : "192.168.1.100:3260" ,
153+ IQN : "iqn.2024-01.com.example:target" ,
154+ Username : "testuser" ,
155+ Password : "testpass" ,
156+ }
157+
158+ miscsi .EXPECT ().IsLoggedIn (ctx , target ).Return (true , nil )
159+ miscsi .EXPECT ().GetDevice (ctx , target ).Return ("/dev/sdb" , nil )
160+ miscsi .EXPECT ().WaitForDevice (ctx , "/dev/sdb" , 30 * time .Second ).Return (nil )
161+ mmount .EXPECT ().IsMounted ("/tmp/staging" ).Return (true , nil )
162+ // FormatAndMountDevice must NOT be called for an already-staged volume
163+
164+ resp , err := svc .NodeStageVolume (ctx , req )
165+
166+ g .Expect (err ).To (BeNil ())
167+ g .Expect (resp ).NotTo (BeNil ())
168+ }
169+
123170func TestNodeStageVolume_MissingTargetIQN (t * testing.T ) {
124171 g := NewGomegaWithT (t )
125172 ctrl := gomock .NewController (t )
@@ -355,6 +402,31 @@ func TestNodePublishVolume_AlreadyMounted(t *testing.T) {
355402 g .Expect (resp ).NotTo (BeNil ())
356403}
357404
405+ func TestNodePublishVolume_BindMountFails (t * testing.T ) {
406+ g := NewGomegaWithT (t )
407+ ctrl := gomock .NewController (t )
408+ defer ctrl .Finish ()
409+
410+ svc , _ , mmount := newTestNode (ctrl )
411+ ctx := context .Background ()
412+
413+ req := & csi.NodePublishVolumeRequest {
414+ VolumeId : "vol-1" ,
415+ TargetPath : "/tmp/target" ,
416+ StagingTargetPath : "/tmp/staging" ,
417+ }
418+
419+ mmount .EXPECT ().IsMounted ("/tmp/target" ).Return (false , nil )
420+ mmount .EXPECT ().BindMount (ctx , "/tmp/staging" , "/tmp/target" , []string {}).
421+ Return (errors .New ("already mounted" ))
422+
423+ resp , err := svc .NodePublishVolume (ctx , req )
424+
425+ g .Expect (err ).NotTo (BeNil ())
426+ g .Expect (resp ).To (BeNil ())
427+ g .Expect (status .Code (err )).To (Equal (codes .Internal ))
428+ }
429+
358430func TestNodeUnpublishVolume_Success (t * testing.T ) {
359431 g := NewGomegaWithT (t )
360432 ctrl := gomock .NewController (t )
0 commit comments