@@ -37,6 +37,8 @@ import (
37
37
"google.golang.org/api/iterator"
38
38
kmspb "google.golang.org/genproto/googleapis/cloud/kms/v1"
39
39
fieldmask "google.golang.org/genproto/protobuf/field_mask"
40
+ "google.golang.org/grpc/codes"
41
+ "google.golang.org/grpc/status"
40
42
)
41
43
42
44
const (
@@ -159,6 +161,147 @@ var _ = Describe("GCE PD CSI Driver", func() {
159
161
}()
160
162
})
161
163
164
+ It ("Should fail validation if the same disk with different capabilities is staged/published to the same path" , func () {
165
+ testContext := getRandomTestContext ()
166
+
167
+ p , z , _ := testContext .Instance .GetIdentity ()
168
+ client := testContext .Client
169
+ instance := testContext .Instance
170
+
171
+ // Setup: Create Disk A
172
+ volNameA , volIDA := createAndValidateUniqueZonalDisk (client , p , z )
173
+ defer func () {
174
+ // Delete Disk
175
+ err := client .DeleteVolume (volIDA )
176
+ Expect (err ).To (BeNil (), "DeleteVolume failed" )
177
+
178
+ // Validate Disk Deleted
179
+ _ , err = computeService .Disks .Get (p , z , volNameA ).Do ()
180
+ Expect (gce .IsGCEError (err , "notFound" )).To (BeTrue (), "Expected disk to not be found" )
181
+ }()
182
+
183
+ // Setup: Attach Disk A
184
+ err := client .ControllerPublishVolume (volIDA , instance .GetNodeID ())
185
+ Expect (err ).To (BeNil (), "ControllerPublishVolume failed with error for disk %v on node %v: %v" , volIDA , instance .GetNodeID ())
186
+ defer func () {
187
+ // Detach Disk
188
+ err = client .ControllerUnpublishVolume (volIDA , instance .GetNodeID ())
189
+ if err != nil {
190
+ klog .Errorf ("Failed to detach disk: %v" , err )
191
+ }
192
+ }()
193
+
194
+ // Setup: Create Disk B
195
+ volNameB , volIDB := createAndValidateUniqueZonalDisk (client , p , z )
196
+ defer func () {
197
+ // Delete Disk
198
+ err := client .DeleteVolume (volIDB )
199
+ Expect (err ).To (BeNil (), "DeleteVolume failed" )
200
+
201
+ // Validate Disk Deleted
202
+ _ , err = computeService .Disks .Get (p , z , volNameB ).Do ()
203
+ Expect (gce .IsGCEError (err , "notFound" )).To (BeTrue (), "Expected disk to not be found" )
204
+ }()
205
+
206
+ // Setup: Attach Disk B
207
+ err = client .ControllerPublishVolume (volIDB , instance .GetNodeID ())
208
+ Expect (err ).To (BeNil (), "ControllerPublishVolume failed with error for disk %v on node %v: %v" , volIDB , instance .GetNodeID ())
209
+ defer func () {
210
+ // Detach Disk
211
+ err = client .ControllerUnpublishVolume (volIDB , instance .GetNodeID ())
212
+ if err != nil {
213
+ klog .Errorf ("Failed to detach disk: %v" , err )
214
+ }
215
+ }()
216
+
217
+ // Setup: Stage Disk A
218
+ stageDirA := filepath .Join ("/tmp/" , volNameA , "stage" )
219
+ err = client .NodeStageExt4Volume (volIDA , stageDirA )
220
+ Expect (err ).To (BeNil (), "failed to stage volume" )
221
+
222
+ // Assert: Stage to same location with different fstype should fail
223
+ err = client .NodeStageVolume (volIDA , stageDirA , & csi.VolumeCapability {
224
+ AccessType : & csi.VolumeCapability_Mount {
225
+ Mount : & csi.VolumeCapability_MountVolume {
226
+ FsType : "xfs" ,
227
+ },
228
+ },
229
+ AccessMode : & csi.VolumeCapability_AccessMode {
230
+ Mode : csi .VolumeCapability_AccessMode_SINGLE_NODE_WRITER ,
231
+ },
232
+ })
233
+ e , ok := status .FromError (err )
234
+ Expect (ok ).To (BeTrue (), "Could not get error type from err" , err )
235
+ Expect (e .Code ()).To (Equal (codes .AlreadyExists ), "Volume staged with different fs type should result in already exists error" )
236
+
237
+ // Assert: Stage to same location with same fstype should work
238
+ err = client .NodeStageVolume (volIDA , stageDirA , & csi.VolumeCapability {
239
+ AccessType : & csi.VolumeCapability_Mount {
240
+ Mount : & csi.VolumeCapability_MountVolume {
241
+ FsType : "ext4" ,
242
+ },
243
+ },
244
+ AccessMode : & csi.VolumeCapability_AccessMode {
245
+ Mode : csi .VolumeCapability_AccessMode_SINGLE_NODE_WRITER ,
246
+ },
247
+ })
248
+ Expect (err ).To (BeNil (), "Staged volume to same location with same fs type should work" )
249
+
250
+ // Assert: Stage volume using block to location with fs type already should always work
251
+ err = client .NodeStageBlockVolume (volIDA , stageDirA )
252
+ Expect (err ).To (BeNil (), "Staged volume of block type should always work" )
253
+
254
+ defer func () {
255
+ // Unstage Disk
256
+ err = client .NodeUnstageVolume (volIDA , stageDirA )
257
+ if err != nil {
258
+ klog .Errorf ("Failed to unstage volume: %v" , err )
259
+ }
260
+ fp := filepath .Join ("/tmp/" , volNameA )
261
+ err = testutils .RmAll (instance , fp )
262
+ if err != nil {
263
+ klog .Errorf ("Failed to rm file path %s: %v" , fp , err )
264
+ }
265
+ }()
266
+
267
+ // Assert: Stage Disk B to Disk A position and fail even both as EXT4
268
+ err = client .NodeStageExt4Volume (volIDB , stageDirA )
269
+ e , ok = status .FromError (err )
270
+ Expect (ok ).To (BeTrue (), "Could not get error type from err" , err )
271
+ Expect (e .Code ()).To (Equal (codes .AlreadyExists ), "Volume B staged with same fs type to Volume A staging path should result in already exists error" )
272
+
273
+ // Setup: Stage Disk B with EXT3
274
+ stageDirB := filepath .Join ("/tmp/" , volNameB , "stage" )
275
+ err = client .NodeStageVolume (volIDB , stageDirB , & csi.VolumeCapability {
276
+ AccessType : & csi.VolumeCapability_Mount {
277
+ Mount : & csi.VolumeCapability_MountVolume {
278
+ FsType : "ext3" ,
279
+ },
280
+ },
281
+ AccessMode : & csi.VolumeCapability_AccessMode {
282
+ Mode : csi .VolumeCapability_AccessMode_SINGLE_NODE_WRITER ,
283
+ },
284
+ })
285
+ Expect (err ).To (BeNil (), "failed to stage volume" )
286
+
287
+ // Setup: Publish A to publishDirA
288
+ publishDirA := filepath .Join ("/tmp/" , volNameA , "mount" )
289
+ err = client .NodePublishVolume (volIDA , stageDirA , publishDirA )
290
+ Expect (err ).To (BeNil (), "failed to publish volume" )
291
+ defer func () {
292
+ err = client .NodeUnpublishVolume (volIDA , publishDirA )
293
+ Expect (err ).To (BeNil (), "failed to unpublish volume" )
294
+ }()
295
+ // Assert: Publish A to publishDirA with block which already has an fs should work
296
+ err = client .NodePublishBlockVolume (volIDA , stageDirA , publishDirA )
297
+ Expect (err ).To (BeNil (), "publish block volume to an the existing location with fstype should work" )
298
+
299
+ // Assert: Publish B to publishDirA should fail because disks are different
300
+ err = client .NodePublishBlockVolume (volIDB , stageDirB , publishDirA )
301
+ Expect (ok ).To (BeTrue (), "Could not get error type from err" , err )
302
+ Expect (e .Code ()).To (Equal (codes .AlreadyExists ), "Volume B staged with same fs type to Volume A staging path should result in already exists error" )
303
+ })
304
+
162
305
It ("Should create disks in correct zones when topology is specified" , func () {
163
306
Expect (testContexts ).ToNot (BeEmpty ())
164
307
testContext := getRandomTestContext ()
0 commit comments