Skip to content

Commit 864d5cb

Browse files
committed
Add testcase for defaultfstype provisioner conditions:
There are 4 combinations added here: StorageClass set + default set StorageClass unset + default set StorageClass set + default unset StorageClass unset + default unset Signed-off-by: Humble Chirammal <[email protected]>
1 parent fa371e7 commit 864d5cb

File tree

2 files changed

+237
-12
lines changed

2 files changed

+237
-12
lines changed

cmd/csi-provisioner/csi-provisioner.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ var (
7171
metricsAddress = flag.String("metrics-address", "", "The TCP network address where the prometheus metrics endpoint will listen (example: `:8080`). The default is empty string, which means metrics endpoint is disabled.")
7272
metricsPath = flag.String("metrics-path", "/metrics", "The HTTP path where prometheus metrics will be exposed. Default is `/metrics`.")
7373

74-
defaultFSType = flag.String("default-fstype", "", "Specify the filesystem type of the volume. If not specified, external-provisioner will not set any default filesystem type.")
74+
defaultFSType = flag.String("default-fstype", "", "The default filesystem type of the volume to provision when fstype is unspecified in the StorageClass. If the default is not set and fstype is unset in the StorageClass, then no fstype will be set")
7575

7676
featureGates map[string]bool
7777
provisionController *controller.ProvisionController

pkg/controller/controller_test.go

Lines changed: 236 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,6 @@ import (
2929

3030
"github.com/container-storage-interface/spec/lib/go/csi"
3131
"github.com/golang/mock/gomock"
32-
"github.com/kubernetes-csi/csi-lib-utils/connection"
33-
"github.com/kubernetes-csi/csi-lib-utils/metrics"
34-
"github.com/kubernetes-csi/csi-lib-utils/rpc"
35-
"github.com/kubernetes-csi/csi-test/driver"
36-
"github.com/kubernetes-csi/external-provisioner/pkg/features"
37-
crdv1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1beta1"
38-
"github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned/fake"
3932
"google.golang.org/grpc"
4033
"google.golang.org/grpc/codes"
4134
"google.golang.org/grpc/status"
@@ -53,6 +46,14 @@ import (
5346
csitrans "k8s.io/csi-translation-lib"
5447
"k8s.io/klog"
5548
"sigs.k8s.io/sig-storage-lib-external-provisioner/v5/controller"
49+
50+
"github.com/kubernetes-csi/csi-lib-utils/connection"
51+
"github.com/kubernetes-csi/csi-lib-utils/metrics"
52+
"github.com/kubernetes-csi/csi-lib-utils/rpc"
53+
"github.com/kubernetes-csi/csi-test/driver"
54+
"github.com/kubernetes-csi/external-provisioner/pkg/features"
55+
crdv1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1beta1"
56+
"github.com/kubernetes-csi/external-snapshotter/pkg/client/clientset/versioned/fake"
5657
)
5758

5859
func init() {
@@ -814,6 +815,19 @@ type provisioningTestcase struct {
814815
skipCreateVolume bool
815816
}
816817

818+
type provisioningFSTypeTestcase struct {
819+
volOpts controller.ProvisionOptions
820+
821+
expectedPVSpec *pvSpec
822+
clientSetObjects []runtime.Object
823+
createVolumeError error
824+
expectErr bool
825+
expectState controller.ProvisioningState
826+
expectCreateVolDo interface{}
827+
828+
skipDefaultFSType bool
829+
}
830+
817831
type pvSpec struct {
818832
Name string
819833
ReclaimPolicy v1.PersistentVolumeReclaimPolicy
@@ -836,6 +850,7 @@ func getDefaultStorageClassSecretParameters() map[string]string {
836850
nodePublishSecretNamespaceKey: defaultSecretNsName,
837851
prefixedControllerExpandSecretNameKey: "controllerexpandsecret",
838852
prefixedControllerExpandSecretNamespaceKey: defaultSecretNsName,
853+
// "fstype": "ext4",
839854
}
840855
}
841856

@@ -865,6 +880,135 @@ func getDefaultSecretObjects() []runtime.Object {
865880
}
866881
}
867882

883+
func TestFSTypeProvision(t *testing.T) {
884+
var requestedBytes int64 = 100
885+
deletePolicy := v1.PersistentVolumeReclaimDelete
886+
testcases := map[string]provisioningFSTypeTestcase{
887+
"fstype not set/'nil' in SC to provision": {
888+
volOpts: controller.ProvisionOptions{
889+
StorageClass: &storagev1.StorageClass{
890+
ReclaimPolicy: &deletePolicy,
891+
Parameters: map[string]string{
892+
// We deliberately skip fsType in sc param
893+
// "fstype": "",
894+
},
895+
},
896+
PVName: "test-name",
897+
PVC: createFakePVC(requestedBytes),
898+
},
899+
expectedPVSpec: &pvSpec{
900+
Name: "test-testi",
901+
ReclaimPolicy: v1.PersistentVolumeReclaimDelete,
902+
Capacity: v1.ResourceList{
903+
v1.ResourceName(v1.ResourceStorage): bytesToGiQuantity(requestedBytes),
904+
},
905+
CSIPVS: &v1.CSIPersistentVolumeSource{
906+
Driver: "test-driver",
907+
VolumeHandle: "test-volume-id",
908+
FSType: "ext4",
909+
VolumeAttributes: map[string]string{
910+
"storage.kubernetes.io/csiProvisionerIdentity": "test-provisioner",
911+
},
912+
},
913+
},
914+
expectState: controller.ProvisioningFinished,
915+
},
916+
"Other fstype(ex:'xfs') set in SC": {
917+
volOpts: controller.ProvisionOptions{
918+
StorageClass: &storagev1.StorageClass{
919+
ReclaimPolicy: &deletePolicy,
920+
Parameters: map[string]string{
921+
"fstype": "xfs",
922+
},
923+
},
924+
PVName: "test-name",
925+
PVC: createFakePVC(requestedBytes),
926+
},
927+
expectedPVSpec: &pvSpec{
928+
Name: "test-testi",
929+
ReclaimPolicy: v1.PersistentVolumeReclaimDelete,
930+
Capacity: v1.ResourceList{
931+
v1.ResourceName(v1.ResourceStorage): bytesToGiQuantity(requestedBytes),
932+
},
933+
CSIPVS: &v1.CSIPersistentVolumeSource{
934+
Driver: "test-driver",
935+
VolumeHandle: "test-volume-id",
936+
FSType: "xfs",
937+
VolumeAttributes: map[string]string{
938+
"storage.kubernetes.io/csiProvisionerIdentity": "test-provisioner",
939+
},
940+
},
941+
},
942+
expectState: controller.ProvisioningFinished,
943+
},
944+
945+
"fstype not set/Nil in SC and defaultFSType arg unset for provisioner": {
946+
volOpts: controller.ProvisionOptions{
947+
StorageClass: &storagev1.StorageClass{
948+
ReclaimPolicy: &deletePolicy,
949+
Parameters: map[string]string{
950+
// We deliberately skip fsType in sc param
951+
// "fstype": "xfs",
952+
},
953+
},
954+
PVName: "test-name",
955+
PVC: createFakePVC(requestedBytes),
956+
},
957+
skipDefaultFSType: true,
958+
expectedPVSpec: &pvSpec{
959+
Name: "test-testi",
960+
ReclaimPolicy: v1.PersistentVolumeReclaimDelete,
961+
Capacity: v1.ResourceList{
962+
v1.ResourceName(v1.ResourceStorage): bytesToGiQuantity(requestedBytes),
963+
},
964+
CSIPVS: &v1.CSIPersistentVolumeSource{
965+
Driver: "test-driver",
966+
VolumeHandle: "test-volume-id",
967+
FSType: "",
968+
VolumeAttributes: map[string]string{
969+
"storage.kubernetes.io/csiProvisionerIdentity": "test-provisioner",
970+
},
971+
},
972+
},
973+
expectState: controller.ProvisioningFinished,
974+
},
975+
976+
"fstype set in SC and defaultFSType arg unset for provisioner": {
977+
volOpts: controller.ProvisionOptions{
978+
StorageClass: &storagev1.StorageClass{
979+
ReclaimPolicy: &deletePolicy,
980+
Parameters: map[string]string{
981+
"fstype": "xfs",
982+
},
983+
},
984+
PVName: "test-name",
985+
PVC: createFakePVC(requestedBytes),
986+
},
987+
skipDefaultFSType: true,
988+
expectedPVSpec: &pvSpec{
989+
Name: "test-testi",
990+
ReclaimPolicy: v1.PersistentVolumeReclaimDelete,
991+
Capacity: v1.ResourceList{
992+
v1.ResourceName(v1.ResourceStorage): bytesToGiQuantity(requestedBytes),
993+
},
994+
CSIPVS: &v1.CSIPersistentVolumeSource{
995+
Driver: "test-driver",
996+
VolumeHandle: "test-volume-id",
997+
FSType: "xfs",
998+
VolumeAttributes: map[string]string{
999+
"storage.kubernetes.io/csiProvisionerIdentity": "test-provisioner",
1000+
},
1001+
},
1002+
},
1003+
expectState: controller.ProvisioningFinished,
1004+
},
1005+
}
1006+
1007+
for k, tc := range testcases {
1008+
runFSTypeProvisionTest(t, k, tc, requestedBytes, driverName, "" /* no migration */)
1009+
}
1010+
}
1011+
8681012
func TestProvision(t *testing.T) {
8691013
var requestedBytes int64 = 100
8701014
deletePolicy := v1.PersistentVolumeReclaimDelete
@@ -1251,6 +1395,7 @@ func TestProvision(t *testing.T) {
12511395
Parameters: map[string]string{
12521396
prefixedDefaultSecretNameKey: "default-secret",
12531397
prefixedDefaultSecretNamespaceKey: "default-ns",
1398+
"fstype": "ext4",
12541399
},
12551400
},
12561401
PVName: "test-name",
@@ -1302,6 +1447,7 @@ func TestProvision(t *testing.T) {
13021447
Parameters: map[string]string{
13031448
prefixedDefaultSecretNameKey: "${pvc.name}",
13041449
prefixedDefaultSecretNamespaceKey: "default-ns",
1450+
"fstype": "ext4",
13051451
},
13061452
},
13071453
PVName: "test-name",
@@ -1693,10 +1839,90 @@ func newSnapshot(name, className, boundToContent, snapshotUID, claimName string,
16931839

16941840
return &snapshot
16951841
}
1842+
func runFSTypeProvisionTest(t *testing.T, k string, tc provisioningFSTypeTestcase, requestedBytes int64, provisionDriverName, supportsMigrationFromInTreePluginName string) {
1843+
t.Logf("Running test: %v", k)
1844+
myDefaultfsType := "ext4"
1845+
tmpdir := tempDir(t)
1846+
defer os.RemoveAll(tmpdir)
1847+
mockController, driver, _, controllerServer, csiConn, err := createMockServer(t, tmpdir)
1848+
if err != nil {
1849+
t.Fatal(err)
1850+
}
1851+
defer mockController.Finish()
1852+
defer driver.Stop()
1853+
1854+
clientSet := fakeclientset.NewSimpleClientset(tc.clientSetObjects...)
1855+
1856+
pluginCaps, controllerCaps := provisionCapabilities()
1857+
1858+
if tc.skipDefaultFSType {
1859+
myDefaultfsType = ""
1860+
}
1861+
csiProvisioner := NewCSIProvisioner(clientSet, 5*time.Second, "test-provisioner", "test", 5, csiConn.conn,
1862+
nil, provisionDriverName, pluginCaps, controllerCaps, supportsMigrationFromInTreePluginName, false, csitrans.New(), nil, nil, nil, nil, nil, false, myDefaultfsType)
1863+
out := &csi.CreateVolumeResponse{
1864+
Volume: &csi.Volume{
1865+
CapacityBytes: requestedBytes,
1866+
VolumeId: "test-volume-id",
1867+
},
1868+
}
1869+
1870+
// Setup regular mock call expectations.
1871+
if !tc.expectErr {
1872+
controllerServer.EXPECT().CreateVolume(gomock.Any(), gomock.Any()).Return(out, tc.createVolumeError).Times(1)
1873+
}
1874+
1875+
pv, state, err := csiProvisioner.(controller.ProvisionerExt).ProvisionExt(tc.volOpts)
1876+
if tc.expectErr && err == nil {
1877+
t.Errorf("test %q: Expected error, got none", k)
1878+
}
1879+
if !tc.expectErr && err != nil {
1880+
t.Fatalf("test %q: got error: %v", k, err)
1881+
}
1882+
1883+
if tc.expectState == "" {
1884+
tc.expectState = controller.ProvisioningFinished
1885+
}
1886+
if tc.expectState != state {
1887+
t.Errorf("test %q: expected ProvisioningState %s, got %s", k, tc.expectState, state)
1888+
}
1889+
1890+
if tc.expectedPVSpec != nil {
1891+
if pv.Name != tc.expectedPVSpec.Name {
1892+
t.Errorf("test %q: expected PV name: %q, got: %q", k, tc.expectedPVSpec.Name, pv.Name)
1893+
}
1894+
1895+
if pv.Spec.PersistentVolumeReclaimPolicy != tc.expectedPVSpec.ReclaimPolicy {
1896+
t.Errorf("test %q: expected reclaim policy: %v, got: %v", k, tc.expectedPVSpec.ReclaimPolicy, pv.Spec.PersistentVolumeReclaimPolicy)
1897+
}
1898+
1899+
if !reflect.DeepEqual(pv.Spec.AccessModes, tc.expectedPVSpec.AccessModes) {
1900+
t.Errorf("test %q: expected access modes: %v, got: %v", k, tc.expectedPVSpec.AccessModes, pv.Spec.AccessModes)
1901+
}
1902+
1903+
if !reflect.DeepEqual(pv.Spec.VolumeMode, tc.expectedPVSpec.VolumeMode) {
1904+
t.Errorf("test %q: expected volumeMode: %v, got: %v", k, tc.expectedPVSpec.VolumeMode, pv.Spec.VolumeMode)
1905+
}
1906+
1907+
if !reflect.DeepEqual(pv.Spec.Capacity, tc.expectedPVSpec.Capacity) {
1908+
t.Errorf("test %q: expected capacity: %v, got: %v", k, tc.expectedPVSpec.Capacity, pv.Spec.Capacity)
1909+
}
1910+
1911+
if !reflect.DeepEqual(pv.Spec.MountOptions, tc.expectedPVSpec.MountOptions) {
1912+
t.Errorf("test %q: expected mount options: %v, got: %v", k, tc.expectedPVSpec.MountOptions, pv.Spec.MountOptions)
1913+
}
1914+
1915+
if tc.expectedPVSpec.CSIPVS != nil {
1916+
if !reflect.DeepEqual(pv.Spec.PersistentVolumeSource.CSI, tc.expectedPVSpec.CSIPVS) {
1917+
t.Errorf("test %q: expected PV: %v, got: %v", k, tc.expectedPVSpec.CSIPVS, pv.Spec.PersistentVolumeSource.CSI)
1918+
}
1919+
}
1920+
1921+
}
1922+
}
16961923

16971924
func runProvisionTest(t *testing.T, k string, tc provisioningTestcase, requestedBytes int64, provisionDriverName, supportsMigrationFromInTreePluginName string) {
16981925
t.Logf("Running test: %v", k)
1699-
17001926
tmpdir := tempDir(t)
17011927
defer os.RemoveAll(tmpdir)
17021928
mockController, driver, _, controllerServer, csiConn, err := createMockServer(t, tmpdir)
@@ -1707,7 +1933,6 @@ func runProvisionTest(t *testing.T, k string, tc provisioningTestcase, requested
17071933
defer driver.Stop()
17081934

17091935
clientSet := fakeclientset.NewSimpleClientset(tc.clientSetObjects...)
1710-
17111936
pluginCaps, controllerCaps := provisionCapabilities()
17121937
csiProvisioner := NewCSIProvisioner(clientSet, 5*time.Second, "test-provisioner", "test", 5, csiConn.conn,
17131938
nil, provisionDriverName, pluginCaps, controllerCaps, supportsMigrationFromInTreePluginName, false, csitrans.New(), nil, nil, nil, nil, nil, tc.withExtraMetadata, defaultfsType)
@@ -1871,7 +2096,7 @@ func TestProvisionFromSnapshot(t *testing.T) {
18712096
volOpts: controller.ProvisionOptions{
18722097
StorageClass: &storagev1.StorageClass{
18732098
ReclaimPolicy: &deletePolicy,
1874-
Parameters: map[string]string{},
2099+
Parameters: map[string]string{"fstype": "ext4"},
18752100
Provisioner: "test-driver",
18762101
},
18772102
PVName: "test-name",
@@ -3142,7 +3367,7 @@ func generatePVCForProvisionFromPVC(srcNamespace, srcName, scName string, reques
31423367
provisionRequest := controller.ProvisionOptions{
31433368
StorageClass: &storagev1.StorageClass{
31443369
ReclaimPolicy: &deletePolicy,
3145-
Parameters: map[string]string{},
3370+
Parameters: map[string]string{"fstype": "ext4"},
31463371
Provisioner: driverName,
31473372
},
31483373
PVName: "new-pv-name",

0 commit comments

Comments
 (0)