@@ -18,13 +18,18 @@ package controller
1818
1919import (
2020 "fmt"
21+ "strconv"
2122 "testing"
2223 "time"
2324
2425 csi "github.com/container-storage-interface/spec/lib/go/csi/v0"
2526 "github.com/golang/mock/gomock"
2627 "github.com/kubernetes-csi/csi-test/driver"
28+ "github.com/kubernetes-incubator/external-storage/lib/controller"
2729 "google.golang.org/grpc"
30+ "k8s.io/api/core/v1"
31+ "k8s.io/apimachinery/pkg/api/resource"
32+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2833)
2934
3035const (
@@ -384,3 +389,94 @@ func TestGetDriverName(t *testing.T) {
384389 }
385390 }
386391}
392+
393+ func TestCreateDriverReturnsInvalidCapacityDuringProvision (t * testing.T ) {
394+ // Set up mocks
395+ var requestedBytes int64 = 100
396+ mockController , driver , identityServer , controllerServer , csiConn , err := createMockServer (t )
397+ if err != nil {
398+ t .Fatal (err )
399+ }
400+ defer mockController .Finish ()
401+ defer driver .Stop ()
402+
403+ csiProvisioner := NewCSIProvisioner (nil , driver .Address (), 5 * time .Second , "test-provisioner" , "test" , 5 , csiConn .conn )
404+
405+ // Requested PVC with requestedBytes storage
406+ opts := controller.VolumeOptions {
407+ PersistentVolumeReclaimPolicy : v1 .PersistentVolumeReclaimDelete ,
408+ PVName : "test-name" ,
409+ PVC : createFakePVC (requestedBytes ),
410+ Parameters : map [string ]string {},
411+ }
412+
413+ // Drivers CreateVolume response with lower capacity bytes than request
414+ out := & csi.CreateVolumeResponse {
415+ Volume : & csi.Volume {
416+ CapacityBytes : requestedBytes - 1 ,
417+ Id : "test-volume-id" ,
418+ },
419+ }
420+
421+ // Set up Mocks
422+ provisionMockServerSetupExpectations (identityServer , controllerServer )
423+ controllerServer .EXPECT ().CreateVolume (gomock .Any (), gomock .Any ()).Return (out , nil ).Times (1 )
424+ // Since capacity returned by driver is invalid, we expect the provision call to clean up the volume
425+ controllerServer .EXPECT ().DeleteVolume (gomock .Any (), & csi.DeleteVolumeRequest {
426+ VolumeId : "test-volume-id" ,
427+ }).Return (& csi.DeleteVolumeResponse {}, nil ).Times (1 )
428+
429+ // Call provision
430+ _ , err = csiProvisioner .Provision (opts )
431+ if err == nil {
432+ t .Errorf ("Provision did not cause an error when one was expected" )
433+ return
434+ }
435+ t .Logf ("Provision encountered an error: %v, expected: create volume capacity less than requested capacity" , err )
436+ }
437+
438+ func provisionMockServerSetupExpectations (identityServer * driver.MockIdentityServer , controllerServer * driver.MockControllerServer ) {
439+ identityServer .EXPECT ().GetPluginCapabilities (gomock .Any (), gomock .Any ()).Return (& csi.GetPluginCapabilitiesResponse {
440+ Capabilities : []* csi.PluginCapability {
441+ & csi.PluginCapability {
442+ Type : & csi.PluginCapability_Service_ {
443+ Service : & csi.PluginCapability_Service {
444+ Type : csi .PluginCapability_Service_CONTROLLER_SERVICE ,
445+ },
446+ },
447+ },
448+ },
449+ }, nil ).Times (1 )
450+ controllerServer .EXPECT ().ControllerGetCapabilities (gomock .Any (), gomock .Any ()).Return (& csi.ControllerGetCapabilitiesResponse {
451+ Capabilities : []* csi.ControllerServiceCapability {
452+ & csi.ControllerServiceCapability {
453+ Type : & csi.ControllerServiceCapability_Rpc {
454+ Rpc : & csi.ControllerServiceCapability_RPC {
455+ Type : csi .ControllerServiceCapability_RPC_CREATE_DELETE_VOLUME ,
456+ },
457+ },
458+ },
459+ },
460+ }, nil ).Times (1 )
461+ identityServer .EXPECT ().GetPluginInfo (gomock .Any (), gomock .Any ()).Return (& csi.GetPluginInfoResponse {
462+ Name : "test-driver" ,
463+ VendorVersion : "test-vendor" ,
464+ }, nil ).Times (1 )
465+ }
466+
467+ // Minimal PVC required for tests to function
468+ func createFakePVC (requestBytes int64 ) * v1.PersistentVolumeClaim {
469+ return & v1.PersistentVolumeClaim {
470+ ObjectMeta : metav1.ObjectMeta {
471+ UID : "testid" ,
472+ },
473+ Spec : v1.PersistentVolumeClaimSpec {
474+ Selector : nil , // Provisioner doesn't support selector
475+ Resources : v1.ResourceRequirements {
476+ Requests : v1.ResourceList {
477+ v1 .ResourceName (v1 .ResourceStorage ): resource .MustParse (strconv .FormatInt (requestBytes , 10 )),
478+ },
479+ },
480+ },
481+ }
482+ }
0 commit comments