@@ -18,6 +18,7 @@ package csi
18
18
19
19
import (
20
20
"context"
21
+ "errors"
21
22
"fmt"
22
23
"os"
23
24
"path/filepath"
@@ -282,6 +283,54 @@ func TestBlockMapperSetupDevice(t *testing.T) {
282
283
}
283
284
}
284
285
286
+ func TestBlockMapperSetupDeviceError (t * testing.T ) {
287
+ defer featuregatetesting .SetFeatureGateDuringTest (t , utilfeature .DefaultFeatureGate , features .CSIBlockVolume , true )()
288
+
289
+ plug , tmpDir := newTestPlugin (t , nil )
290
+ defer os .RemoveAll (tmpDir )
291
+
292
+ csiMapper , _ , pv , err := prepareBlockMapperTest (plug , "test-pv" , t )
293
+ if err != nil {
294
+ t .Fatalf ("Failed to make a new Mapper: %v" , err )
295
+ }
296
+
297
+ pvName := pv .GetName ()
298
+ nodeName := string (plug .host .GetNodeName ())
299
+
300
+ csiMapper .csiClient = setupClient (t , true )
301
+ fClient := csiMapper .csiClient .(* fakeCsiDriverClient )
302
+ fClient .nodeClient .SetNextError (errors .New ("mock final error" ))
303
+
304
+ attachID := getAttachmentName (csiMapper .volumeID , string (csiMapper .driverName ), string (nodeName ))
305
+ attachment := makeTestAttachment (attachID , nodeName , pvName )
306
+ attachment .Status .Attached = true
307
+ _ , err = csiMapper .k8s .StorageV1 ().VolumeAttachments ().Create (context .TODO (), attachment , metav1.CreateOptions {})
308
+ if err != nil {
309
+ t .Fatalf ("failed to setup VolumeAttachment: %v" , err )
310
+ }
311
+ t .Log ("created attachement " , attachID )
312
+
313
+ err = csiMapper .SetUpDevice ()
314
+ if err == nil {
315
+ t .Fatal ("mapper unexpectedly succeeded" )
316
+ }
317
+
318
+ // Check that all directories have been cleaned
319
+ // Check that all metadata / staging / publish directories were deleted
320
+ dataDir := getVolumeDeviceDataDir (pv .ObjectMeta .Name , plug .host )
321
+ if _ , err := os .Stat (dataDir ); err == nil {
322
+ t .Errorf ("volume publish data directory %s was not deleted" , dataDir )
323
+ }
324
+ devDir := getVolumeDeviceDataDir (pv .ObjectMeta .Name , plug .host )
325
+ if _ , err := os .Stat (devDir ); err == nil {
326
+ t .Errorf ("volume publish device directory %s was not deleted" , devDir )
327
+ }
328
+ stagingPath := csiMapper .getStagingPath ()
329
+ if _ , err := os .Stat (stagingPath ); err == nil {
330
+ t .Errorf ("volume staging path %s was not deleted" , stagingPath )
331
+ }
332
+ }
333
+
285
334
func TestBlockMapperMapPodDevice (t * testing.T ) {
286
335
defer featuregatetesting .SetFeatureGateDuringTest (t , utilfeature .DefaultFeatureGate , features .CSIBlockVolume , true )()
287
336
@@ -430,3 +479,124 @@ func TestBlockMapperTearDownDevice(t *testing.T) {
430
479
t .Error ("csi server may not have received NodeUnstageVolume call" )
431
480
}
432
481
}
482
+
483
+ func TestVolumeSetupTeardown (t * testing.T ) {
484
+ defer featuregatetesting .SetFeatureGateDuringTest (t , utilfeature .DefaultFeatureGate , features .CSIBlockVolume , true )()
485
+
486
+ plug , tmpDir := newTestPlugin (t , nil )
487
+ defer os .RemoveAll (tmpDir )
488
+
489
+ csiMapper , spec , pv , err := prepareBlockMapperTest (plug , "test-pv" , t )
490
+ if err != nil {
491
+ t .Fatalf ("Failed to make a new Mapper: %v" , err )
492
+ }
493
+
494
+ pvName := pv .GetName ()
495
+ nodeName := string (plug .host .GetNodeName ())
496
+
497
+ csiMapper .csiClient = setupClient (t , true )
498
+
499
+ attachID := getAttachmentName (csiMapper .volumeID , string (csiMapper .driverName ), string (nodeName ))
500
+ attachment := makeTestAttachment (attachID , nodeName , pvName )
501
+ attachment .Status .Attached = true
502
+ _ , err = csiMapper .k8s .StorageV1 ().VolumeAttachments ().Create (context .TODO (), attachment , metav1.CreateOptions {})
503
+ if err != nil {
504
+ t .Fatalf ("failed to setup VolumeAttachment: %v" , err )
505
+ }
506
+ t .Log ("created attachement " , attachID )
507
+
508
+ // SetupDevice
509
+ err = csiMapper .SetUpDevice ()
510
+ if err != nil {
511
+ t .Fatalf ("mapper failed to SetupDevice: %v" , err )
512
+ }
513
+ // Check if NodeStageVolume staged to the right path
514
+ stagingPath := csiMapper .getStagingPath ()
515
+ svols := csiMapper .csiClient .(* fakeCsiDriverClient ).nodeClient .GetNodeStagedVolumes ()
516
+ svol , ok := svols [csiMapper .volumeID ]
517
+ if ! ok {
518
+ t .Error ("csi server may not have received NodeStageVolume call" )
519
+ }
520
+ if svol .Path != stagingPath {
521
+ t .Errorf ("csi server expected device path %s, got %s" , stagingPath , svol .Path )
522
+ }
523
+
524
+ // MapPodDevice
525
+ path , err := csiMapper .MapPodDevice ()
526
+ if err != nil {
527
+ t .Fatalf ("mapper failed to GetGlobalMapPath: %v" , err )
528
+ }
529
+ pvols := csiMapper .csiClient .(* fakeCsiDriverClient ).nodeClient .GetNodePublishedVolumes ()
530
+ pvol , ok := pvols [csiMapper .volumeID ]
531
+ if ! ok {
532
+ t .Error ("csi server may not have received NodePublishVolume call" )
533
+ }
534
+ publishPath := csiMapper .getPublishPath ()
535
+ if pvol .Path != publishPath {
536
+ t .Errorf ("csi server expected path %s, got %s" , publishPath , pvol .Path )
537
+ }
538
+ if path != publishPath {
539
+ t .Errorf ("csi server expected path %s, but MapPodDevice returned %s" , publishPath , path )
540
+ }
541
+
542
+ unmapper , err := plug .NewBlockVolumeUnmapper (pv .ObjectMeta .Name , testPodUID )
543
+ if err != nil {
544
+ t .Fatalf ("failed to make a new Unmapper: %v" , err )
545
+ }
546
+
547
+ csiUnmapper := unmapper .(* csiBlockMapper )
548
+ csiUnmapper .csiClient = csiMapper .csiClient
549
+
550
+ globalMapPath , err := csiUnmapper .GetGlobalMapPath (spec )
551
+ if err != nil {
552
+ t .Fatalf ("unmapper failed to GetGlobalMapPath: %v" , err )
553
+ }
554
+
555
+ // UnmapDevice
556
+ err = csiUnmapper .UnmapPodDevice ()
557
+ if err != nil {
558
+ t .Errorf ("unmapper failed to call UnmapPodDevice: %v" , err )
559
+ }
560
+
561
+ // GenerateUnmapDeviceFunc uses "" as pod UUID, it is global operation over all pods that used the volume
562
+ unmapper , err = plug .NewBlockVolumeUnmapper (pv .ObjectMeta .Name , "" )
563
+ if err != nil {
564
+ t .Fatalf ("failed to make a new Unmapper: %v" , err )
565
+ }
566
+ csiUnmapper = unmapper .(* csiBlockMapper )
567
+ csiUnmapper .csiClient = csiMapper .csiClient
568
+
569
+ // TearDownDevice
570
+ err = csiUnmapper .TearDownDevice (globalMapPath , "/dev/test" )
571
+ if err != nil {
572
+ t .Fatal (err )
573
+ }
574
+ pubs := csiUnmapper .csiClient .(* fakeCsiDriverClient ).nodeClient .GetNodePublishedVolumes ()
575
+ if _ , ok := pubs [csiUnmapper .volumeID ]; ok {
576
+ t .Error ("csi server may not have received NodeUnpublishVolume call" )
577
+ }
578
+ vols := csiUnmapper .csiClient .(* fakeCsiDriverClient ).nodeClient .GetNodeStagedVolumes ()
579
+ if _ , ok := vols [csiUnmapper .volumeID ]; ok {
580
+ t .Error ("csi server may not have received NodeUnstageVolume call" )
581
+ }
582
+
583
+ // Check that all metadata / staging / publish directories were deleted
584
+ dataDir := getVolumeDeviceDataDir (pv .ObjectMeta .Name , plug .host )
585
+ if _ , err := os .Stat (dataDir ); err == nil {
586
+ t .Errorf ("volume publish data directory %s was not deleted" , dataDir )
587
+ }
588
+ devDir := getVolumeDeviceDataDir (pv .ObjectMeta .Name , plug .host )
589
+ if _ , err := os .Stat (devDir ); err == nil {
590
+ t .Errorf ("volume publish device directory %s was not deleted" , devDir )
591
+ }
592
+ if _ , err := os .Stat (publishPath ); err == nil {
593
+ t .Errorf ("volume publish path %s was not deleted" , publishPath )
594
+ }
595
+ publishDir := filepath .Dir (publishPath )
596
+ if _ , err := os .Stat (publishDir ); err == nil {
597
+ t .Errorf ("volume publish parent directory %s was not deleted" , publishDir )
598
+ }
599
+ if _ , err := os .Stat (stagingPath ); err == nil {
600
+ t .Errorf ("volume staging path %s was not deleted" , stagingPath )
601
+ }
602
+ }
0 commit comments