@@ -331,6 +331,216 @@ func TestNodeStageVolume(t *testing.T) {
331
331
}
332
332
}
333
333
334
+ func TestNodeUnstageVolume (t * testing.T ) {
335
+ targetPath := "/test/path"
336
+ devicePath := "/dev/fake"
337
+
338
+ testCases := []struct {
339
+ name string
340
+ testFunc func (t * testing.T )
341
+ }{
342
+ {
343
+ name : "success normal" ,
344
+ testFunc : func (t * testing.T ) {
345
+ mockCtl := gomock .NewController (t )
346
+ defer mockCtl .Finish ()
347
+
348
+ mockMounter := mocks .NewMockMounter (mockCtl )
349
+ mockDevice := mocks .NewMockLinuxDevice (mockCtl )
350
+
351
+ powervsDriver := & nodeService {
352
+ mounter : mockMounter ,
353
+ volumeLocks : util .NewVolumeLocks (),
354
+ }
355
+
356
+ mockMounter .EXPECT ().GetDeviceName (gomock .Eq (targetPath )).Return (devicePath , 1 , nil )
357
+ mockMounter .EXPECT ().Unmount (gomock .Eq (targetPath )).Return (nil )
358
+ mockMounter .EXPECT ().IsMountPoint (gomock .Eq (targetPath )).Return (false , nil )
359
+
360
+ mockDevice .EXPECT ().GetMapper ().Return (devicePath )
361
+ mockDevice .EXPECT ().Populate (false ).Return (nil )
362
+ mockDevice .EXPECT ().DeleteDevice ().Return (nil )
363
+
364
+ req := & csi.NodeUnstageVolumeRequest {
365
+ StagingTargetPath : targetPath ,
366
+ VolumeId : volumeID ,
367
+ }
368
+
369
+ GetDeviceWWN = func (pathName string ) (string , error ) {
370
+ return "fakeWWN" , nil
371
+ }
372
+ // always use mocked device
373
+ NewDevice = func (wwn string ) device.LinuxDevice {
374
+ return mockDevice
375
+ }
376
+
377
+ _ , err := powervsDriver .NodeUnstageVolume (context .TODO (), req )
378
+ if err != nil {
379
+ t .Fatalf ("Expect no error but got: %v" , err )
380
+ }
381
+ },
382
+ },
383
+ {
384
+ name : "success no device mounted at target" ,
385
+ testFunc : func (t * testing.T ) {
386
+ mockCtl := gomock .NewController (t )
387
+ defer mockCtl .Finish ()
388
+
389
+ mockMounter := mocks .NewMockMounter (mockCtl )
390
+
391
+ powervsDriver := & nodeService {
392
+ mounter : mockMounter ,
393
+ volumeLocks : util .NewVolumeLocks (),
394
+ }
395
+ mockMounter .EXPECT ().GetDeviceName (gomock .Eq (targetPath )).Return (devicePath , 0 , nil )
396
+
397
+ req := & csi.NodeUnstageVolumeRequest {
398
+ StagingTargetPath : targetPath ,
399
+ VolumeId : volumeID ,
400
+ }
401
+ _ , err := powervsDriver .NodeUnstageVolume (context .TODO (), req )
402
+ if err != nil {
403
+ t .Fatalf ("Expect no error but got: %v" , err )
404
+ }
405
+ },
406
+ },
407
+ {
408
+ name : "success device mounted at multiple targets" ,
409
+ testFunc : func (t * testing.T ) {
410
+ mockCtl := gomock .NewController (t )
411
+ defer mockCtl .Finish ()
412
+
413
+ mockMounter := mocks .NewMockMounter (mockCtl )
414
+ mockDevice := mocks .NewMockLinuxDevice (mockCtl )
415
+
416
+ powervsDriver := & nodeService {
417
+ mounter : mockMounter ,
418
+ volumeLocks : util .NewVolumeLocks (),
419
+ }
420
+
421
+ mockMounter .EXPECT ().GetDeviceName (gomock .Eq (targetPath )).Return (devicePath , 2 , nil )
422
+ mockMounter .EXPECT ().Unmount (gomock .Eq (targetPath )).Return (nil )
423
+ mockMounter .EXPECT ().IsMountPoint (gomock .Eq (targetPath )).Return (false , nil )
424
+
425
+ mockDevice .EXPECT ().GetMapper ().Return (devicePath )
426
+ mockDevice .EXPECT ().Populate (false ).Return (nil )
427
+ mockDevice .EXPECT ().DeleteDevice ().Return (nil )
428
+
429
+ GetDeviceWWN = func (pathName string ) (string , error ) {
430
+ return "fakeWWN" , nil
431
+ }
432
+ // always use mocked device
433
+ NewDevice = func (wwn string ) device.LinuxDevice {
434
+ return mockDevice
435
+ }
436
+
437
+ req := & csi.NodeUnstageVolumeRequest {
438
+ StagingTargetPath : targetPath ,
439
+ VolumeId : volumeID ,
440
+ }
441
+
442
+ _ , err := powervsDriver .NodeUnstageVolume (context .TODO (), req )
443
+ if err != nil {
444
+ t .Fatalf ("Expect no error but got: %v" , err )
445
+ }
446
+ },
447
+ },
448
+ {
449
+ name : "fail no VolumeId" ,
450
+ testFunc : func (t * testing.T ) {
451
+ mockCtl := gomock .NewController (t )
452
+ defer mockCtl .Finish ()
453
+
454
+ mockMounter := mocks .NewMockMounter (mockCtl )
455
+
456
+ powervsDriver := & nodeService {
457
+ mounter : mockMounter ,
458
+ volumeLocks : util .NewVolumeLocks (),
459
+ }
460
+
461
+ req := & csi.NodeUnstageVolumeRequest {
462
+ StagingTargetPath : targetPath ,
463
+ }
464
+
465
+ _ , err := powervsDriver .NodeUnstageVolume (context .TODO (), req )
466
+ expectErr (t , err , codes .InvalidArgument )
467
+ },
468
+ },
469
+ {
470
+ name : "fail no StagingTargetPath" ,
471
+ testFunc : func (t * testing.T ) {
472
+ mockCtl := gomock .NewController (t )
473
+ defer mockCtl .Finish ()
474
+
475
+ mockMounter := mocks .NewMockMounter (mockCtl )
476
+
477
+ powervsDriver := & nodeService {
478
+ mounter : mockMounter ,
479
+ volumeLocks : util .NewVolumeLocks (),
480
+ }
481
+
482
+ req := & csi.NodeUnstageVolumeRequest {
483
+ VolumeId : volumeID ,
484
+ }
485
+ _ , err := powervsDriver .NodeUnstageVolume (context .TODO (), req )
486
+ expectErr (t , err , codes .InvalidArgument )
487
+ },
488
+ },
489
+ {
490
+ name : "fail GetDeviceName returns error" ,
491
+ testFunc : func (t * testing.T ) {
492
+ mockCtl := gomock .NewController (t )
493
+ defer mockCtl .Finish ()
494
+
495
+ mockMounter := mocks .NewMockMounter (mockCtl )
496
+
497
+ powervsDriver := & nodeService {
498
+ mounter : mockMounter ,
499
+ volumeLocks : util .NewVolumeLocks (),
500
+ }
501
+
502
+ mockMounter .EXPECT ().GetDeviceName (gomock .Eq (targetPath )).Return ("" , 0 , errors .New ("GetDeviceName faield" ))
503
+
504
+ req := & csi.NodeUnstageVolumeRequest {
505
+ StagingTargetPath : targetPath ,
506
+ VolumeId : volumeID ,
507
+ }
508
+
509
+ _ , err := powervsDriver .NodeUnstageVolume (context .TODO (), req )
510
+ expectErr (t , err , codes .Internal )
511
+ },
512
+ },
513
+ {
514
+ name : "fail if volume is already locked" ,
515
+ testFunc : func (t * testing.T ) {
516
+ mockCtl := gomock .NewController (t )
517
+ defer mockCtl .Finish ()
518
+
519
+ mockMounter := mocks .NewMockMounter (mockCtl )
520
+
521
+ powervsDriver := & nodeService {
522
+ mounter : mockMounter ,
523
+ volumeLocks : util .NewVolumeLocks (),
524
+ }
525
+
526
+ req := & csi.NodeUnstageVolumeRequest {
527
+ StagingTargetPath : targetPath ,
528
+ VolumeId : volumeID ,
529
+ }
530
+ powervsDriver .volumeLocks .TryAcquire (req .VolumeId )
531
+ defer powervsDriver .volumeLocks .Release (req .VolumeId )
532
+
533
+ _ , err := powervsDriver .NodeUnstageVolume (context .TODO (), req )
534
+ expectErr (t , err , codes .Aborted )
535
+ },
536
+ },
537
+ }
538
+
539
+ for _ , tc := range testCases {
540
+ t .Run (tc .name , tc .testFunc )
541
+ }
542
+ }
543
+
334
544
func TestNodeExpandVolume (t * testing.T ) {
335
545
mockCtl := gomock .NewController (t )
336
546
defer mockCtl .Finish ()
0 commit comments