Skip to content

Commit b1def1c

Browse files
authored
Merge pull request #91 from darkowlzz/provision-test
Add controller provision tests
2 parents e8dcc7f + 23529d8 commit b1def1c

File tree

1 file changed

+284
-0
lines changed

1 file changed

+284
-0
lines changed

pkg/controller/controller_test.go

Lines changed: 284 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ limitations under the License.
1717
package controller
1818

1919
import (
20+
"errors"
2021
"fmt"
2122
"reflect"
2223
"strconv"
@@ -31,6 +32,8 @@ import (
3132
"k8s.io/api/core/v1"
3233
"k8s.io/apimachinery/pkg/api/resource"
3334
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
35+
"k8s.io/client-go/kubernetes"
36+
fakeclientset "k8s.io/client-go/kubernetes/fake"
3437
)
3538

3639
const (
@@ -647,3 +650,284 @@ func TestGetSecretReference(t *testing.T) {
647650
})
648651
}
649652
}
653+
654+
func TestProvision(t *testing.T) {
655+
var requestedBytes int64 = 100
656+
657+
type pvSpec struct {
658+
Name string
659+
ReclaimPolicy v1.PersistentVolumeReclaimPolicy
660+
AccessModes []v1.PersistentVolumeAccessMode
661+
Capacity v1.ResourceList
662+
CSIPVS *v1.CSIPersistentVolumeSource
663+
}
664+
665+
testcases := map[string]struct {
666+
volOpts controller.VolumeOptions
667+
notNilSelector bool
668+
driverNotReady bool
669+
makeVolumeNameErr bool
670+
getSecretRefErr bool
671+
getCredentialsErr bool
672+
volWithLessCap bool
673+
expectedPVSpec *pvSpec
674+
withSecretRefs bool
675+
expectErr bool
676+
}{
677+
"normal provision": {
678+
volOpts: controller.VolumeOptions{
679+
PersistentVolumeReclaimPolicy: v1.PersistentVolumeReclaimDelete,
680+
PVName: "test-name",
681+
PVC: createFakePVC(requestedBytes),
682+
Parameters: map[string]string{
683+
"fstype": "ext3",
684+
},
685+
},
686+
expectedPVSpec: &pvSpec{
687+
Name: "test-testi",
688+
ReclaimPolicy: v1.PersistentVolumeReclaimDelete,
689+
Capacity: v1.ResourceList{
690+
v1.ResourceName(v1.ResourceStorage): bytesToGiQuantity(requestedBytes),
691+
},
692+
CSIPVS: &v1.CSIPersistentVolumeSource{
693+
Driver: "test-driver",
694+
VolumeHandle: "test-volume-id",
695+
FSType: "ext3",
696+
VolumeAttributes: map[string]string{
697+
"storage.kubernetes.io/csiProvisionerIdentity": "test-provisioner",
698+
},
699+
},
700+
},
701+
},
702+
"provision with access modes": {
703+
volOpts: controller.VolumeOptions{
704+
PersistentVolumeReclaimPolicy: v1.PersistentVolumeReclaimDelete,
705+
PVName: "test-name",
706+
PVC: &v1.PersistentVolumeClaim{
707+
ObjectMeta: metav1.ObjectMeta{
708+
UID: "testid",
709+
},
710+
Spec: v1.PersistentVolumeClaimSpec{
711+
Selector: nil,
712+
Resources: v1.ResourceRequirements{
713+
Requests: v1.ResourceList{
714+
v1.ResourceName(v1.ResourceStorage): resource.MustParse(strconv.FormatInt(requestedBytes, 10)),
715+
},
716+
},
717+
AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce},
718+
},
719+
},
720+
Parameters: map[string]string{},
721+
},
722+
expectedPVSpec: &pvSpec{
723+
Name: "test-testi",
724+
ReclaimPolicy: v1.PersistentVolumeReclaimDelete,
725+
AccessModes: []v1.PersistentVolumeAccessMode{v1.ReadWriteOnce},
726+
Capacity: v1.ResourceList{
727+
v1.ResourceName(v1.ResourceStorage): bytesToGiQuantity(requestedBytes),
728+
},
729+
CSIPVS: &v1.CSIPersistentVolumeSource{
730+
Driver: "test-driver",
731+
VolumeHandle: "test-volume-id",
732+
FSType: "ext4",
733+
VolumeAttributes: map[string]string{
734+
"storage.kubernetes.io/csiProvisionerIdentity": "test-provisioner",
735+
},
736+
},
737+
},
738+
},
739+
"provision with secrets": {
740+
volOpts: controller.VolumeOptions{
741+
PVName: "test-name",
742+
PVC: createFakePVC(requestedBytes),
743+
Parameters: map[string]string{},
744+
},
745+
withSecretRefs: true,
746+
expectedPVSpec: &pvSpec{
747+
Name: "test-testi",
748+
Capacity: v1.ResourceList{
749+
v1.ResourceName(v1.ResourceStorage): bytesToGiQuantity(requestedBytes),
750+
},
751+
CSIPVS: &v1.CSIPersistentVolumeSource{
752+
Driver: "test-driver",
753+
VolumeHandle: "test-volume-id",
754+
FSType: "ext4",
755+
VolumeAttributes: map[string]string{
756+
"storage.kubernetes.io/csiProvisionerIdentity": "test-provisioner",
757+
},
758+
ControllerPublishSecretRef: &v1.SecretReference{
759+
Name: "ctrlpublishsecret",
760+
Namespace: "default",
761+
},
762+
NodeStageSecretRef: &v1.SecretReference{
763+
Name: "nodestagesecret",
764+
Namespace: "default",
765+
},
766+
NodePublishSecretRef: &v1.SecretReference{
767+
Name: "nodepublishsecret",
768+
Namespace: "default",
769+
},
770+
},
771+
},
772+
},
773+
"fail to get secret reference": {
774+
volOpts: controller.VolumeOptions{
775+
PVName: "test-name",
776+
PVC: createFakePVC(requestedBytes),
777+
Parameters: map[string]string{},
778+
},
779+
getSecretRefErr: true,
780+
expectErr: true,
781+
},
782+
"fail not nil selector": {
783+
volOpts: controller.VolumeOptions{
784+
PVName: "test-name",
785+
PVC: createFakePVC(requestedBytes),
786+
},
787+
notNilSelector: true,
788+
expectErr: true,
789+
},
790+
"fail driver not ready": {
791+
volOpts: controller.VolumeOptions{
792+
PVName: "test-name",
793+
PVC: createFakePVC(requestedBytes),
794+
},
795+
driverNotReady: true,
796+
expectErr: true,
797+
},
798+
"fail to make volume name": {
799+
volOpts: controller.VolumeOptions{
800+
PVName: "test-name",
801+
PVC: createFakePVC(requestedBytes),
802+
},
803+
makeVolumeNameErr: true,
804+
expectErr: true,
805+
},
806+
"fail to get credentials": {
807+
volOpts: controller.VolumeOptions{
808+
PVName: "test-name",
809+
PVC: createFakePVC(requestedBytes),
810+
Parameters: map[string]string{},
811+
},
812+
getCredentialsErr: true,
813+
expectErr: true,
814+
},
815+
"fail vol with less capacity": {
816+
volOpts: controller.VolumeOptions{
817+
PVName: "test-name",
818+
PVC: createFakePVC(requestedBytes),
819+
Parameters: map[string]string{},
820+
},
821+
volWithLessCap: true,
822+
expectErr: true,
823+
},
824+
}
825+
826+
mockController, driver, identityServer, controllerServer, csiConn, err := createMockServer(t)
827+
if err != nil {
828+
t.Fatal(err)
829+
}
830+
defer mockController.Finish()
831+
defer driver.Stop()
832+
833+
for k, tc := range testcases {
834+
var clientSet kubernetes.Interface
835+
836+
if tc.withSecretRefs {
837+
clientSet = fakeclientset.NewSimpleClientset(&v1.Secret{
838+
ObjectMeta: metav1.ObjectMeta{
839+
Name: "ctrlpublishsecret",
840+
Namespace: "default",
841+
},
842+
}, &v1.Secret{
843+
ObjectMeta: metav1.ObjectMeta{
844+
Name: "nodestagesecret",
845+
Namespace: "default",
846+
},
847+
}, &v1.Secret{
848+
ObjectMeta: metav1.ObjectMeta{
849+
Name: "nodepublishsecret",
850+
Namespace: "default",
851+
},
852+
})
853+
} else {
854+
clientSet = fakeclientset.NewSimpleClientset()
855+
}
856+
857+
csiProvisioner := NewCSIProvisioner(clientSet, driver.Address(), 5*time.Second, "test-provisioner", "test", 5, csiConn.conn)
858+
859+
out := &csi.CreateVolumeResponse{
860+
Volume: &csi.Volume{
861+
CapacityBytes: requestedBytes,
862+
Id: "test-volume-id",
863+
},
864+
}
865+
866+
if tc.withSecretRefs {
867+
tc.volOpts.Parameters[controllerPublishSecretNameKey] = "ctrlpublishsecret"
868+
tc.volOpts.Parameters[controllerPublishSecretNamespaceKey] = "default"
869+
tc.volOpts.Parameters[nodeStageSecretNameKey] = "nodestagesecret"
870+
tc.volOpts.Parameters[nodeStageSecretNamespaceKey] = "default"
871+
tc.volOpts.Parameters[nodePublishSecretNameKey] = "nodepublishsecret"
872+
tc.volOpts.Parameters[nodePublishSecretNamespaceKey] = "default"
873+
}
874+
875+
if tc.notNilSelector {
876+
tc.volOpts.PVC.Spec.Selector = &metav1.LabelSelector{}
877+
} else if tc.driverNotReady {
878+
identityServer.EXPECT().GetPluginCapabilities(gomock.Any(), gomock.Any()).Return(nil, errors.New("driver not ready")).Times(1)
879+
} else if tc.makeVolumeNameErr {
880+
tc.volOpts.PVC.ObjectMeta.UID = ""
881+
provisionMockServerSetupExpectations(identityServer, controllerServer)
882+
} else if tc.getSecretRefErr {
883+
tc.volOpts.Parameters[provisionerSecretNameKey] = ""
884+
provisionMockServerSetupExpectations(identityServer, controllerServer)
885+
} else if tc.getCredentialsErr {
886+
tc.volOpts.Parameters[provisionerSecretNameKey] = "secretx"
887+
tc.volOpts.Parameters[provisionerSecretNamespaceKey] = "default"
888+
provisionMockServerSetupExpectations(identityServer, controllerServer)
889+
} else if tc.volWithLessCap {
890+
out.Volume.CapacityBytes = int64(80)
891+
provisionMockServerSetupExpectations(identityServer, controllerServer)
892+
controllerServer.EXPECT().CreateVolume(gomock.Any(), gomock.Any()).Return(out, nil).Times(1)
893+
controllerServer.EXPECT().DeleteVolume(gomock.Any(), gomock.Any()).Return(&csi.DeleteVolumeResponse{}, nil).Times(1)
894+
} else {
895+
// Setup regular mock call expectations.
896+
provisionMockServerSetupExpectations(identityServer, controllerServer)
897+
controllerServer.EXPECT().CreateVolume(gomock.Any(), gomock.Any()).Return(out, nil).Times(1)
898+
}
899+
900+
pv, err := csiProvisioner.Provision(tc.volOpts)
901+
if tc.expectErr && err == nil {
902+
t.Errorf("test %q: Expected error, got none", k)
903+
}
904+
if !tc.expectErr && err != nil {
905+
t.Errorf("test %q: got error: %v", k, err)
906+
}
907+
908+
if tc.expectedPVSpec != nil {
909+
if pv.Name != tc.expectedPVSpec.Name {
910+
t.Errorf("test %q: expected PV name: %q, got: %q", k, tc.expectedPVSpec.Name, pv.Name)
911+
}
912+
913+
if pv.Spec.PersistentVolumeReclaimPolicy != tc.expectedPVSpec.ReclaimPolicy {
914+
t.Errorf("test %q: expected reclaim policy: %v, got: %v", k, tc.expectedPVSpec.ReclaimPolicy, pv.Spec.PersistentVolumeReclaimPolicy)
915+
}
916+
917+
if !reflect.DeepEqual(pv.Spec.AccessModes, tc.expectedPVSpec.AccessModes) {
918+
t.Errorf("test %q: expected access modes: %v, got: %v", k, tc.expectedPVSpec.AccessModes, pv.Spec.AccessModes)
919+
}
920+
921+
if !reflect.DeepEqual(pv.Spec.Capacity, tc.expectedPVSpec.Capacity) {
922+
t.Errorf("test %q: expected capacity: %v, got: %v", k, tc.expectedPVSpec.Capacity, pv.Spec.Capacity)
923+
}
924+
925+
if tc.expectedPVSpec.CSIPVS != nil {
926+
if !reflect.DeepEqual(pv.Spec.PersistentVolumeSource.CSI, tc.expectedPVSpec.CSIPVS) {
927+
t.Errorf("test %q: expected PV: %v, got: %v", k, tc.expectedPVSpec.CSIPVS, pv.Spec.PersistentVolumeSource.CSI)
928+
}
929+
}
930+
931+
}
932+
}
933+
}

0 commit comments

Comments
 (0)