From 33c896f6ff3a08acc33c8ab705ac64cb7b45b5b0 Mon Sep 17 00:00:00 2001 From: Grant Griffiths Date: Sun, 22 Dec 2019 22:49:33 -0800 Subject: [PATCH] Update common controller tests after split controller Signed-off-by: Grant Griffiths --- pkg/common-controller/framework_test.go | 353 +++++++++--------- pkg/common-controller/snapshot_create_test.go | 274 ++++++-------- pkg/common-controller/snapshot_delete_test.go | 58 +-- .../snapshot_finalizer_test.go | 32 +- pkg/common-controller/snapshot_update_test.go | 77 ++-- pkg/common-controller/snapshotclass_test.go | 92 +++++ 6 files changed, 470 insertions(+), 416 deletions(-) create mode 100644 pkg/common-controller/snapshotclass_test.go diff --git a/pkg/common-controller/framework_test.go b/pkg/common-controller/framework_test.go index 1aaf51ee7..e4b141a59 100644 --- a/pkg/common-controller/framework_test.go +++ b/pkg/common-controller/framework_test.go @@ -17,7 +17,6 @@ limitations under the License. package common_controller import ( - "context" "errors" "fmt" "reflect" @@ -105,12 +104,6 @@ type controllerTest struct { expectedEvents []string // Errors to produce on matching action errors []reactorError - // List of expected CSI Create snapshot calls - expectedCreateCalls []createCall - // List of expected CSI Delete snapshot calls - expectedDeleteCalls []deleteCall - // List of expected CSI list snapshot calls - expectedListCalls []listCall // Function to call as the test. test testCall expectSuccess bool @@ -151,6 +144,7 @@ type snapshotReactor struct { claims map[string]*v1.PersistentVolumeClaim contents map[string]*crdv1.VolumeSnapshotContent snapshots map[string]*crdv1.VolumeSnapshot + snapshotClasses map[string]*crdv1.VolumeSnapshotClass changedObjects []interface{} changedSinceLastSync int ctrl *csiSnapshotCommonController @@ -171,6 +165,7 @@ type reactorError struct { } func withSnapshotFinalizer(snapshot *crdv1.VolumeSnapshot) *crdv1.VolumeSnapshot { + snapshot.ObjectMeta.Finalizers = append(snapshot.ObjectMeta.Finalizers, utils.VolumeSnapshotContentFinalizer) snapshot.ObjectMeta.Finalizers = append(snapshot.ObjectMeta.Finalizers, utils.VolumeSnapshotAsSourceFinalizer) snapshot.ObjectMeta.Finalizers = append(snapshot.ObjectMeta.Finalizers, utils.VolumeSnapshotBoundFinalizer) return snapshot @@ -712,6 +707,7 @@ func newSnapshotReactor(kubeClient *kubefake.Clientset, client *fake.Clientset, storageClasses: make(map[string]*storagev1.StorageClass), volumes: make(map[string]*v1.PersistentVolume), claims: make(map[string]*v1.PersistentVolumeClaim), + snapshotClasses: make(map[string]*crdv1.VolumeSnapshotClass), contents: make(map[string]*crdv1.VolumeSnapshotContent), snapshots: make(map[string]*crdv1.VolumeSnapshot), ctrl: ctrl, @@ -723,10 +719,13 @@ func newSnapshotReactor(kubeClient *kubefake.Clientset, client *fake.Clientset, client.AddReactor("create", "volumesnapshotcontents", reactor.React) client.AddReactor("update", "volumesnapshotcontents", reactor.React) client.AddReactor("update", "volumesnapshots", reactor.React) + client.AddReactor("update", "volumesnapshotclasses", reactor.React) client.AddReactor("get", "volumesnapshotcontents", reactor.React) client.AddReactor("get", "volumesnapshots", reactor.React) + client.AddReactor("get", "volumesnapshotclasses", reactor.React) client.AddReactor("delete", "volumesnapshotcontents", reactor.React) client.AddReactor("delete", "volumesnapshots", reactor.React) + client.AddReactor("delete", "volumesnapshotclasses", reactor.React) kubeClient.AddReactor("get", "persistentvolumeclaims", reactor.React) kubeClient.AddReactor("update", "persistentvolumeclaims", reactor.React) kubeClient.AddReactor("get", "persistentvolumes", reactor.React) @@ -746,14 +745,6 @@ func newTestController(kubeClient kubernetes.Interface, clientset clientset.Inte coreFactory := coreinformers.NewSharedInformerFactory(kubeClient, utils.NoResyncPeriodFunc()) - // Construct controller - //fakeSnapshot := &fakeSnapshotter{ - // t: t, - // listCalls: test.expectedListCalls, - // createCalls: test.expectedCreateCalls, - // deleteCalls: test.expectedDeleteCalls, - //} - ctrl := NewCSISnapshotCommonController( clientset, kubeClient, @@ -770,6 +761,8 @@ func newTestController(kubeClient kubernetes.Interface, clientset clientset.Inte ctrl.snapshotListerSynced = alwaysReady ctrl.classListerSynced = alwaysReady ctrl.pvcListerSynced = alwaysReady + ctrl.createSnapshotContentInterval = time.Millisecond * 5 + ctrl.createSnapshotContentRetryCount = 3 return ctrl, nil } @@ -870,7 +863,7 @@ func newContentWithUnmatchDriverArray(contentName, boundToSnapshotUID, boundToSn func newSnapshot( snapshotName, snapshotUID, pvcName, targetContentName, snapshotClassName, boundContentName string, readyToUse *bool, creationTime *metav1.Time, restoreSize *resource.Quantity, - err *crdv1.VolumeSnapshotError, nilStatus bool) *crdv1.VolumeSnapshot { + err *crdv1.VolumeSnapshotError, nilStatus bool, withFinalizer bool) *crdv1.VolumeSnapshot { snapshot := crdv1.VolumeSnapshot{ ObjectMeta: metav1.ObjectMeta{ Name: snapshotName, @@ -897,7 +890,9 @@ func newSnapshot( snapshot.Status.BoundVolumeSnapshotContentName = &boundContentName } - snapshot.Spec.VolumeSnapshotClassName = &snapshotClassName + if snapshotClassName != "" { + snapshot.Spec.VolumeSnapshotClassName = &snapshotClassName + } if pvcName != "" { snapshot.Spec.Source = crdv1.VolumeSnapshotSource{ @@ -908,15 +903,42 @@ func newSnapshot( VolumeSnapshotContentName: &targetContentName, } } - return withSnapshotFinalizer(&snapshot) + if withFinalizer { + return withSnapshotFinalizer(&snapshot) + } + return &snapshot } func newSnapshotArray( snapshotName, snapshotUID, pvcName, targetContentName, snapshotClassName, boundContentName string, readyToUse *bool, creationTime *metav1.Time, restoreSize *resource.Quantity, - err *crdv1.VolumeSnapshotError, nilStatus bool) []*crdv1.VolumeSnapshot { + err *crdv1.VolumeSnapshotError, nilStatus bool, withFinalizer bool) []*crdv1.VolumeSnapshot { return []*crdv1.VolumeSnapshot{ - newSnapshot(snapshotName, snapshotUID, pvcName, targetContentName, snapshotClassName, boundContentName, readyToUse, creationTime, restoreSize, err, nilStatus), + newSnapshot(snapshotName, snapshotUID, pvcName, targetContentName, snapshotClassName, boundContentName, readyToUse, creationTime, restoreSize, err, nilStatus, withFinalizer), + } +} + +func newSnapshotClass(snapshotClassName, snapshotClassUID, driverName string, isDefaultClass bool) *crdv1.VolumeSnapshotClass { + sc := &crdv1.VolumeSnapshotClass{ + ObjectMeta: metav1.ObjectMeta{ + Name: snapshotClassName, + Namespace: testNamespace, + UID: types.UID(snapshotClassUID), + ResourceVersion: "1", + SelfLink: "/apis/snapshot.storage.k8s.io/v1beta1/namespaces/" + testNamespace + "/volumesnapshotclasses/" + snapshotClassName, + }, + Driver: driverName, + } + if isDefaultClass { + sc.Annotations = make(map[string]string) + sc.Annotations[utils.IsDefaultSnapshotClassAnnotation] = "true" + } + return sc +} + +func newSnapshotClassArray(snapshotClassName, snapshotClassUID, driverName string, isDefaultClass bool) []*crdv1.VolumeSnapshotClass { + return []*crdv1.VolumeSnapshotClass{ + newSnapshotClass(snapshotClassName, snapshotClassUID, driverName, isDefaultClass), } } @@ -1056,6 +1078,19 @@ func testRemovePVCFinalizer(ctrl *csiSnapshotCommonController, reactor *snapshot return ctrl.checkandRemovePVCFinalizer(test.initialSnapshots[0]) } +func testAddSnapshotFinalizer(ctrl *csiSnapshotCommonController, reactor *snapshotReactor, test controllerTest) error { + return ctrl.addSnapshotFinalizer(test.initialSnapshots[0], true, true) +} + +func testRemoveSnapshotFinalizer(ctrl *csiSnapshotCommonController, reactor *snapshotReactor, test controllerTest) error { + return ctrl.removeSnapshotFinalizer(test.initialSnapshots[0], true, true) +} + +func testUpdateSnapshotClass(ctrl *csiSnapshotCommonController, reactor *snapshotReactor, test controllerTest) error { + _, err := ctrl.checkAndUpdateSnapshotClass(test.initialSnapshots[0]) + return err +} + var ( classEmpty string classGold = "gold" @@ -1109,7 +1144,6 @@ func evaluateTestResults(ctrl *csiSnapshotCommonController, reactor *snapshotRea // Evaluate results if err := reactor.checkSnapshots(test.expectedSnapshots); err != nil { t.Errorf("Test %q: %v", test.name, err) - } if err := reactor.checkContents(test.expectedContents); err != nil { t.Errorf("Test %q: %v", test.name, err) @@ -1190,8 +1224,8 @@ func runSyncTests(t *testing.T, tests []controllerTest, snapshotClasses []*crdv1 } } -// This tests ensurePVCFinalizer and checkandRemovePVCFinalizer -func runPVCFinalizerTests(t *testing.T, tests []controllerTest, snapshotClasses []*crdv1.VolumeSnapshotClass) { +// This tests that finalizers are added or removed from a PVC or Snapshot +func runFinalizerTests(t *testing.T, tests []controllerTest, snapshotClasses []*crdv1.VolumeSnapshotClass) { snapshotscheme.AddToScheme(scheme.Scheme) for _, test := range tests { klog.V(4).Infof("starting test %q", test.name) @@ -1245,15 +1279,16 @@ func runPVCFinalizerTests(t *testing.T, tests []controllerTest, snapshotClasses t.Errorf("Test %q failed: %v", test.name, err) } - // Verify PVCFinalizer tests results - evaluatePVCFinalizerTests(ctrl, reactor, test, t) + // Verify Finalizer tests results + evaluateFinalizerTests(ctrl, reactor, test, t) } } -// Evaluate PVCFinalizer tests results -func evaluatePVCFinalizerTests(ctrl *csiSnapshotCommonController, reactor *snapshotReactor, test controllerTest, t *testing.T) { +// Evaluate Finalizer tests results +func evaluateFinalizerTests(ctrl *csiSnapshotCommonController, reactor *snapshotReactor, test controllerTest, t *testing.T) { // Evaluate results bHasPVCFinalizer := false + bHasSnapshotFinalizer := false name := sysruntime.FuncForPC(reflect.ValueOf(test.test).Pointer()).Name() index := strings.LastIndex(name, ".") if index == -1 { @@ -1262,36 +1297,132 @@ func evaluatePVCFinalizerTests(ctrl *csiSnapshotCommonController, reactor *snaps } names := []rune(name) funcName := string(names[index+1 : len(name)]) - klog.V(4).Infof("test %q: PVCFinalizer test func name: [%s]", test.name, funcName) - - if funcName == "testAddPVCFinalizer" { - for _, pvc := range reactor.claims { - if test.initialClaims[0].Name == pvc.Name { - if !slice.ContainsString(test.initialClaims[0].ObjectMeta.Finalizers, utils.PVCFinalizer, nil) && slice.ContainsString(pvc.ObjectMeta.Finalizers, utils.PVCFinalizer, nil) { - klog.V(4).Infof("test %q succeeded. PVCFinalizer is added to PVC %s", test.name, pvc.Name) - bHasPVCFinalizer = true + klog.V(4).Infof("test %q: Finalizer test func name: [%s]", test.name, funcName) + + if strings.Contains(funcName, "PVCFinalizer") { + if funcName == "testAddPVCFinalizer" { + for _, pvc := range reactor.claims { + if test.initialClaims[0].Name == pvc.Name { + if !slice.ContainsString(test.initialClaims[0].ObjectMeta.Finalizers, utils.PVCFinalizer, nil) && slice.ContainsString(pvc.ObjectMeta.Finalizers, utils.PVCFinalizer, nil) { + klog.V(4).Infof("test %q succeeded. PVCFinalizer is added to PVC %s", test.name, pvc.Name) + bHasPVCFinalizer = true + } + break } - break + } + if test.expectSuccess && !bHasPVCFinalizer { + t.Errorf("Test %q: failed to add finalizer to PVC %s", test.name, test.initialClaims[0].Name) } } - if test.expectSuccess && !bHasPVCFinalizer { - t.Errorf("Test %q: failed to add finalizer to PVC %s", test.name, test.initialClaims[0].Name) + bHasPVCFinalizer = true + if funcName == "testRemovePVCFinalizer" { + for _, pvc := range reactor.claims { + if test.initialClaims[0].Name == pvc.Name { + if slice.ContainsString(test.initialClaims[0].ObjectMeta.Finalizers, utils.PVCFinalizer, nil) && !slice.ContainsString(pvc.ObjectMeta.Finalizers, utils.PVCFinalizer, nil) { + klog.V(4).Infof("test %q succeeded. PVCFinalizer is removed from PVC %s", test.name, pvc.Name) + bHasPVCFinalizer = false + } + break + } + } + if test.expectSuccess && bHasPVCFinalizer { + t.Errorf("Test %q: failed to remove finalizer from PVC %s", test.name, test.initialClaims[0].Name) + } } - } - bHasPVCFinalizer = true - if funcName == "testRemovePVCFinalizer" { - for _, pvc := range reactor.claims { - if test.initialClaims[0].Name == pvc.Name { - if slice.ContainsString(test.initialClaims[0].ObjectMeta.Finalizers, utils.PVCFinalizer, nil) && !slice.ContainsString(pvc.ObjectMeta.Finalizers, utils.PVCFinalizer, nil) { - klog.V(4).Infof("test %q succeeded. PVCFinalizer is removed from PVC %s", test.name, pvc.Name) - bHasPVCFinalizer = false + } else { + if funcName == "testAddSnapshotFinalizer" { + for _, snapshot := range reactor.snapshots { + if test.initialSnapshots[0].Name == snapshot.Name { + if !slice.ContainsString(test.initialSnapshots[0].ObjectMeta.Finalizers, utils.VolumeSnapshotBoundFinalizer, nil) && slice.ContainsString(snapshot.ObjectMeta.Finalizers, utils.VolumeSnapshotBoundFinalizer, nil) && + !slice.ContainsString(test.initialSnapshots[0].ObjectMeta.Finalizers, utils.VolumeSnapshotAsSourceFinalizer, nil) && slice.ContainsString(snapshot.ObjectMeta.Finalizers, utils.VolumeSnapshotAsSourceFinalizer, nil) { + klog.V(4).Infof("test %q succeeded. Finalizers are added to snapshot %s", test.name, snapshot.Name) + bHasSnapshotFinalizer = true + } + break + } + } + if test.expectSuccess && !bHasSnapshotFinalizer { + t.Errorf("Test %q: failed to add finalizer to Snapshot %s", test.name, test.initialSnapshots[0].Name) + } + } + bHasSnapshotFinalizer = true + if funcName == "testRemoveSnapshotFinalizer" { + for _, snapshot := range reactor.snapshots { + if test.initialSnapshots[0].Name == snapshot.Name { + if slice.ContainsString(test.initialSnapshots[0].ObjectMeta.Finalizers, utils.VolumeSnapshotBoundFinalizer, nil) && !slice.ContainsString(snapshot.ObjectMeta.Finalizers, utils.VolumeSnapshotBoundFinalizer, nil) && + slice.ContainsString(test.initialSnapshots[0].ObjectMeta.Finalizers, utils.VolumeSnapshotAsSourceFinalizer, nil) && !slice.ContainsString(snapshot.ObjectMeta.Finalizers, utils.VolumeSnapshotAsSourceFinalizer, nil) { + klog.V(4).Infof("test %q succeeded. SnapshotFinalizer is removed from Snapshot %s", test.name, snapshot.Name) + bHasSnapshotFinalizer = false + } + break } - break } + if test.expectSuccess && bHasSnapshotFinalizer { + t.Errorf("Test %q: failed to remove finalizer from snapshot %s", test.name, test.initialSnapshots[0].Name) + } + } + } +} + +// This tests that a snapshotclass is updated or not +func runUpdateSnapshotClassTests(t *testing.T, tests []controllerTest, snapshotClasses []*crdv1.VolumeSnapshotClass) { + snapshotscheme.AddToScheme(scheme.Scheme) + for _, test := range tests { + klog.V(4).Infof("starting test %q", test.name) + + // Initialize the controller + kubeClient := &kubefake.Clientset{} + client := &fake.Clientset{} + + ctrl, err := newTestController(kubeClient, client, nil, t, test) + if err != nil { + t.Fatalf("Test %q construct test controller failed: %v", test.name, err) + } + + reactor := newSnapshotReactor(kubeClient, client, ctrl, nil, nil, test.errors) + for _, snapshot := range test.initialSnapshots { + ctrl.snapshotStore.Add(snapshot) + reactor.snapshots[snapshot.Name] = snapshot + } + for _, content := range test.initialContents { + ctrl.contentStore.Add(content) + reactor.contents[content.Name] = content + } + + pvcIndexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{}) + for _, claim := range test.initialClaims { + reactor.claims[claim.Name] = claim + pvcIndexer.Add(claim) + } + ctrl.pvcLister = corelisters.NewPersistentVolumeClaimLister(pvcIndexer) + + for _, volume := range test.initialVolumes { + reactor.volumes[volume.Name] = volume + } + for _, storageClass := range test.initialStorageClasses { + reactor.storageClasses[storageClass.Name] = storageClass } - if test.expectSuccess && bHasPVCFinalizer { - t.Errorf("Test %q: failed to remove finalizer from PVC %s", test.name, test.initialClaims[0].Name) + for _, secret := range test.initialSecrets { + reactor.secrets[secret.Name] = secret + } + + // Inject classes into controller via a custom lister. + indexer := cache.NewIndexer(cache.MetaNamespaceKeyFunc, cache.Indexers{}) + for _, class := range snapshotClasses { + indexer.Add(class) + reactor.snapshotClasses[class.Name] = class + + } + ctrl.classLister = storagelisters.NewVolumeSnapshotClassLister(indexer) + + // Run the tested functions + err = test.test(ctrl, reactor, test) + if test.expectSuccess && err != nil { + t.Errorf("Test %q failed: %v", test.name, err) } + + // Verify UpdateSnapshotClass tests results + evaluateTestResults(ctrl, reactor, test, t) } } @@ -1341,127 +1472,3 @@ func emptyDataSecretAnnotations() map[string]string { utils.AnnDeletionSecretRefNamespace: "default", } } - -type listCall struct { - snapshotID string - // information to return - readyToUse bool - createTime time.Time - size int64 - err error -} - -type deleteCall struct { - snapshotID string - secrets map[string]string - err error -} - -type createCall struct { - // expected request parameter - snapshotName string - volume *v1.PersistentVolume - parameters map[string]string - secrets map[string]string - // information to return - driverName string - snapshotId string - creationTime time.Time - size int64 - readyToUse bool - err error -} - -// Fake SnapShotter implementation that check that Attach/Detach is called -// with the right parameters and it returns proper error code and metadata. -type fakeSnapshotter struct { - createCalls []createCall - createCallCounter int - deleteCalls []deleteCall - deleteCallCounter int - listCalls []listCall - listCallCounter int - t *testing.T -} - -func (f *fakeSnapshotter) CreateSnapshot(ctx context.Context, snapshotName string, volume *v1.PersistentVolume, parameters map[string]string, snapshotterCredentials map[string]string) (string, string, time.Time, int64, bool, error) { - if f.createCallCounter >= len(f.createCalls) { - f.t.Errorf("Unexpected CSI Create Snapshot call: snapshotName=%s, volume=%v, index: %d, calls: %+v", snapshotName, volume.Name, f.createCallCounter, f.createCalls) - return "", "", time.Time{}, 0, false, fmt.Errorf("unexpected call") - } - call := f.createCalls[f.createCallCounter] - f.createCallCounter++ - - var err error - if call.snapshotName != snapshotName { - f.t.Errorf("Wrong CSI Create Snapshot call: snapshotName=%s, volume=%s, expected snapshotName: %s", snapshotName, volume.Name, call.snapshotName) - err = fmt.Errorf("unexpected create snapshot call") - } - - if !reflect.DeepEqual(call.volume, volume) { - f.t.Errorf("Wrong CSI Create Snapshot call: snapshotName=%s, volume=%s, diff %s", snapshotName, volume.Name, diff.ObjectDiff(call.volume, volume)) - err = fmt.Errorf("unexpected create snapshot call") - } - - if !reflect.DeepEqual(call.parameters, parameters) { - f.t.Errorf("Wrong CSI Create Snapshot call: snapshotName=%s, volume=%s, expected parameters %+v, got %+v", snapshotName, volume.Name, call.parameters, parameters) - err = fmt.Errorf("unexpected create snapshot call") - } - - if !reflect.DeepEqual(call.secrets, snapshotterCredentials) { - f.t.Errorf("Wrong CSI Create Snapshot call: snapshotName=%s, volume=%s, expected secrets %+v, got %+v", snapshotName, volume.Name, call.secrets, snapshotterCredentials) - err = fmt.Errorf("unexpected create snapshot call") - } - - if err != nil { - return "", "", time.Time{}, 0, false, fmt.Errorf("unexpected call") - } - return call.driverName, call.snapshotId, call.creationTime, call.size, call.readyToUse, call.err -} - -func (f *fakeSnapshotter) DeleteSnapshot(ctx context.Context, snapshotID string, snapshotterCredentials map[string]string) error { - if f.deleteCallCounter >= len(f.deleteCalls) { - f.t.Errorf("Unexpected CSI Delete Snapshot call: snapshotID=%s, index: %d, calls: %+v", snapshotID, f.createCallCounter, f.createCalls) - return fmt.Errorf("unexpected DeleteSnapshot call") - } - call := f.deleteCalls[f.deleteCallCounter] - f.deleteCallCounter++ - - var err error - if call.snapshotID != snapshotID { - f.t.Errorf("Wrong CSI Create Snapshot call: snapshotID=%s, expected snapshotID: %s", snapshotID, call.snapshotID) - err = fmt.Errorf("unexpected Delete snapshot call") - } - - //if !reflect.DeepEqual(call.secrets, snapshotterCredentials) { - // f.t.Errorf("Wrong CSI Delete Snapshot call: snapshotID=%s, expected secrets %+v, got %+v", snapshotID, call.secrets, snapshotterCredentials) - // err = fmt.Errorf("unexpected Delete Snapshot call") - //} - - if err != nil { - return fmt.Errorf("unexpected call") - } - - return call.err -} - -func (f *fakeSnapshotter) GetSnapshotStatus(ctx context.Context, snapshotID string) (bool, time.Time, int64, error) { - if f.listCallCounter >= len(f.listCalls) { - f.t.Errorf("Unexpected CSI list Snapshot call: snapshotID=%s, index: %d, calls: %+v", snapshotID, f.createCallCounter, f.createCalls) - return false, time.Time{}, 0, fmt.Errorf("unexpected call") - } - call := f.listCalls[f.listCallCounter] - f.listCallCounter++ - - var err error - if call.snapshotID != snapshotID { - f.t.Errorf("Wrong CSI List Snapshot call: snapshotID=%s, expected snapshotID: %s", snapshotID, call.snapshotID) - err = fmt.Errorf("unexpected List snapshot call") - } - - if err != nil { - return false, time.Time{}, 0, fmt.Errorf("unexpected call") - } - - return call.readyToUse, call.createTime, call.size, call.err -} diff --git a/pkg/common-controller/snapshot_create_test.go b/pkg/common-controller/snapshot_create_test.go index 799de7f60..ffaa370a2 100644 --- a/pkg/common-controller/snapshot_create_test.go +++ b/pkg/common-controller/snapshot_create_test.go @@ -17,7 +17,7 @@ limitations under the License. package common_controller import ( - //"errors" + "errors" "testing" "time" @@ -44,7 +44,7 @@ var sameDriverStorageClass = &storage.StorageClass{ Kind: "StorageClass", }, ObjectMeta: metav1.ObjectMeta{ - Name: "sameDriver", + Name: sameDriver, }, Provisioner: mockDriverName, Parameters: class1Parameters, @@ -55,7 +55,7 @@ var diffDriverStorageClass = &storage.StorageClass{ Kind: "StorageClass", }, ObjectMeta: metav1.ObjectMeta{ - Name: "diffDriver", + Name: diffDriver, }, Provisioner: mockDriverName, Parameters: class1Parameters, @@ -66,62 +66,35 @@ var diffDriverStorageClass = &storage.StorageClass{ // 2. Call the SyncSnapshot *once*. // 3. Compare resulting contents with expected contents. func TestCreateSnapshotSync(t *testing.T) { - tests := []controllerTest{ { name: "6-1 - successful create snapshot with snapshot class gold", initialContents: nocontents, expectedContents: newContentArrayNoStatus("snapcontent-snapuid6-1", "snapuid6-1", "snap6-1", "sid6-1", classGold, "", "pv-handle6-1", deletionPolicy, nil, nil, false, false), - initialSnapshots: newSnapshotArray("snap6-1", "snapuid6-1", "claim6-1", "", classGold, "", &False, nil, nil, nil, false), - expectedSnapshots: newSnapshotArray("snap6-1", "snapuid6-1", "claim6-1", "", classGold, "snapcontent-snapuid6-1", &False, nil, nil, nil, false), + initialSnapshots: newSnapshotArray("snap6-1", "snapuid6-1", "claim6-1", "", classGold, "", &False, nil, nil, nil, false, true), + expectedSnapshots: newSnapshotArray("snap6-1", "snapuid6-1", "claim6-1", "", classGold, "snapcontent-snapuid6-1", &False, nil, nil, nil, false, true), initialClaims: newClaimArray("claim6-1", "pvc-uid6-1", "1Gi", "volume6-1", v1.ClaimBound, &classEmpty), initialVolumes: newVolumeArray("volume6-1", "pv-uid6-1", "pv-handle6-1", "1Gi", "pvc-uid6-1", "claim6-1", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty), - /*expectedCreateCalls: []createCall{ - { - snapshotName: "snapshot-snapuid6-1", - volume: newVolume("volume6-1", "pv-uid6-1", "pv-handle6-1", "1Gi", "pvc-uid6-1", "claim6-1", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty), - parameters: map[string]string{"param1": "value1"}, - // information to return - driverName: mockDriverName, - size: defaultSize, - snapshotId: "sid6-1", - creationTime: timeNow, - readyToUse: True, - }, - },*/ - errors: noerrors, - test: testSyncSnapshot, + errors: noerrors, + test: testSyncSnapshot, }, { name: "6-2 - successful create snapshot with snapshot class silver", initialContents: nocontents, expectedContents: newContentArrayNoStatus("snapcontent-snapuid6-2", "snapuid6-2", "snap6-2", "sid6-2", classSilver, "", "pv-handle6-2", deletionPolicy, nil, nil, false, false), - initialSnapshots: newSnapshotArray("snap6-2", "snapuid6-2", "claim6-2", "", classSilver, "", &False, nil, nil, nil, false), - expectedSnapshots: newSnapshotArray("snap6-2", "snapuid6-2", "claim6-2", "", classSilver, "snapcontent-snapuid6-2", &False, nil, nil, nil, false), + initialSnapshots: newSnapshotArray("snap6-2", "snapuid6-2", "claim6-2", "", classSilver, "", &False, nil, nil, nil, false, true), + expectedSnapshots: newSnapshotArray("snap6-2", "snapuid6-2", "claim6-2", "", classSilver, "snapcontent-snapuid6-2", &False, nil, nil, nil, false, true), initialClaims: newClaimArray("claim6-2", "pvc-uid6-2", "1Gi", "volume6-2", v1.ClaimBound, &classEmpty), initialVolumes: newVolumeArray("volume6-2", "pv-uid6-2", "pv-handle6-2", "1Gi", "pvc-uid6-2", "claim6-2", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty), - /*expectedCreateCalls: []createCall{ - { - snapshotName: "snapshot-snapuid6-2", - volume: newVolume("volume6-2", "pv-uid6-2", "pv-handle6-2", "1Gi", "pvc-uid6-2", "claim6-2", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty), - parameters: map[string]string{"param2": "value2"}, - // information to return - driverName: mockDriverName, - size: defaultSize, - snapshotId: "sid6-2", - creationTime: timeNow, - readyToUse: True, - }, - },*/ - errors: noerrors, - test: testSyncSnapshot, + errors: noerrors, + test: testSyncSnapshot, }, { name: "7-1 - fail to create snapshot with non-existing snapshot class", initialContents: nocontents, expectedContents: nocontents, - initialSnapshots: newSnapshotArray("snap7-1", "snapuid7-1", "claim7-1", "", classNonExisting, "", &False, nil, nil, nil, false), - expectedSnapshots: newSnapshotArray("snap7-1", "snapuid7-1", "claim7-1", "", classNonExisting, "", &False, nil, nil, newVolumeError("Failed to create snapshot content with error failed to get input parameters to create snapshot snap7-1: \"failed to retrieve snapshot class non-existing from the informer: \\\"volumesnapshotclass.snapshot.storage.k8s.io \\\\\\\"non-existing\\\\\\\" not found\\\"\""), false), + initialSnapshots: newSnapshotArray("snap7-1", "snapuid7-1", "claim7-1", "", classNonExisting, "", &False, nil, nil, nil, false, true), + expectedSnapshots: newSnapshotArray("snap7-1", "snapuid7-1", "claim7-1", "", classNonExisting, "", &False, nil, nil, newVolumeError("Failed to create snapshot content with error failed to get input parameters to create snapshot snap7-1: \"failed to retrieve snapshot class non-existing from the informer: \\\"volumesnapshotclass.snapshot.storage.k8s.io \\\\\\\"non-existing\\\\\\\" not found\\\"\""), false, true), initialClaims: newClaimArray("claim7-1", "pvc-uid7-1", "1Gi", "volume7-1", v1.ClaimBound, &classEmpty), initialVolumes: newVolumeArray("volume7-1", "pv-uid7-1", "pv-handle7-1", "1Gi", "pvc-uid7-1", "claim7-1", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty), expectedEvents: []string{"Warning SnapshotContentCreationFailed"}, @@ -129,24 +102,30 @@ func TestCreateSnapshotSync(t *testing.T) { expectSuccess: false, test: testSyncSnapshot, }, - /*{ - name: "7-2 - fail to create snapshot with snapshot class invalid-secret-class", - initialContents: nocontents, - expectedContents: nocontents, - initialSnapshots: newSnapshotArray("snap7-2", "snapuid7-2", "claim7-2", "", invalidSecretClass, "", &False, nil, nil, nil), - expectedSnapshots: newSnapshotArray("snap7-2", "snapuid7-2", "claim7-2", "", invalidSecretClass, "", &False, nil, nil, newVolumeError("Failed to create snapshot: failed to get input parameters to create snapshot snap7-2: \"failed to get name and namespace template from params: either name and namespace for Snapshotter secrets specified, Both must be specified\"")), - initialClaims: newClaimArray("claim7-2", "pvc-uid7-2", "1Gi", "volume7-2", v1.ClaimBound, &classEmpty), - initialVolumes: newVolumeArray("volume7-2", "pv-uid7-2", "pv-handle7-2", "1Gi", "pvc-uid7-2", "claim7-2", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty), - expectedEvents: []string{"Warning SnapshotCreationFailed"}, - errors: noerrors, - test: testSyncSnapshot, - },*/ + { + name: "7-2 - fail to update snapshot reports warning event", + initialContents: newContentArrayWithReadyToUse("snapcontent-snapuid7-2", "snapuid7-2", "snap7-2", "sid7-2", classGold, "sid7-2", "pv-handle7-2", deletionPolicy, nil, nil, &True, false), + expectedContents: newContentArrayWithReadyToUse("snapcontent-snapuid7-2", "snapuid7-2", "snap7-2", "sid7-2", classGold, "sid7-2", "pv-handle7-2", deletionPolicy, nil, nil, &True, false), + initialSnapshots: newSnapshotArray("snap7-2", "snapuid7-2", "claim7-2", "", classGold, "snapcontent-snapuid7-2", &False, nil, nil, nil, false, true), + expectedSnapshots: newSnapshotArray("snap7-2", "snapuid7-2", "claim7-2", "", classGold, "snapcontent-snapuid7-2", &False, nil, nil, newVolumeError("Snapshot status update failed, snapshot controller failed to update default/snap7-2 on API server: mock update error"), false, true), + initialClaims: newClaimArray("claim7-2", "pvc-uid7-2", "1Gi", "volume7-2", v1.ClaimBound, &classGold), + initialVolumes: newVolumeArray("volume7-2", "pv-uid7-2", "pv-handle7-2", "1Gi", "pvc-uid7-2", "claim7-2", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classGold), + expectedEvents: []string{"Warning SnapshotStatusUpdateFailed"}, + errors: []reactorError{ + // Inject error to the forth client.VolumesnapshotV1beta1().VolumeSnapshots().Update call. + // All other calls will succeed. + {"update", "volumesnapshots", errors.New("mock update error")}, + {"update", "volumesnapshots", errors.New("mock update error")}, + {"update", "volumesnapshots", errors.New("mock update error")}, + }, test: testSyncSnapshot, + }, + /*{ name: "7-3 - fail to create snapshot without snapshot class ", initialContents: nocontents, expectedContents: nocontents, - initialSnapshots: newSnapshotArray("snap7-3", "snapuid7-3", "claim7-3", "", "", "", &False, nil, nil, nil, false), - expectedSnapshots: newSnapshotArray("snap7-3", "snapuid7-3", "claim7-3", "", "", "", &False, nil, nil, newVolumeError("Failed to create snapshot content with error failed to get input parameters to create snapshot snap7-3: \"failed to retrieve snapshot class from the informer: \\\"volumesnapshotclass.snapshot.storage.k8s.io \\\\\\\"\\\\\\\" not found\\\"\""), false), + initialSnapshots: newSnapshotArray("snap7-3", "snapuid7-3", "claim7-3", "", "", "", &False, nil, nil, nil, false, true), + expectedSnapshots: newSnapshotArray("snap7-3", "snapuid7-3", "claim7-3", "", "", "", &False, nil, nil, newVolumeError("Failed to create snapshot content with error failed to get input parameters to create snapshot snap7-3: \"failed to retrieve snapshot class from the informer: \\\"volumesnapshotclass.snapshot.storage.k8s.io \\\\\\\"\\\\\\\" not found\\\"\""), false, true), initialClaims: newClaimArray("claim7-3", "pvc-uid7-3", "1Gi", "volume7-3", v1.ClaimBound, &classEmpty), initialVolumes: newVolumeArray("volume7-3", "pv-uid7-3", "pv-handle7-3", "1Gi", "pvc-uid7-3", "claim7-3", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty), initialStorageClasses: []*storage.StorageClass{diffDriverStorageClass}, @@ -154,37 +133,38 @@ func TestCreateSnapshotSync(t *testing.T) { errors: noerrors, expectSuccess: false, test: testSyncSnapshot, - }, - /*{ + },*/ + { name: "7-4 - fail create snapshot with no-existing claim", initialContents: nocontents, expectedContents: nocontents, - initialSnapshots: newSnapshotArray("snap7-4", "snapuid7-4", "claim7-4", "", classGold, "", &False, nil, nil, nil, false), - expectedSnapshots: newSnapshotArray("snap7-4", "snapuid7-4", "claim7-4", "", classGold, "", &False, nil, nil, newVolumeError("Failed to create snapshot content with error failed to get input parameters to create snapshot snap7-4: \"failed to retrieve PVC claim7-4 from the lister: \\\"persistentvolumeclaim \\\\\\\"claim7-4\\\\\\\" not found\\\"\""), false), + initialSnapshots: newSnapshotArray("snap7-4", "snapuid7-4", "claim7-4", "", classGold, "", &False, nil, nil, nil, false, true), + expectedSnapshots: newSnapshotArray("snap7-4", "snapuid7-4", "claim7-4", "", classGold, "", &False, nil, nil, newVolumeError("Failed to create snapshot content with error snapshot controller failed to update snap7-4 on API server: cannot get claim from snapshot"), false, true), initialVolumes: newVolumeArray("volume7-4", "pv-uid7-4", "pv-handle7-4", "1Gi", "pvc-uid7-4", "claim7-4", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty), expectedEvents: []string{"Warning SnapshotContentCreationFailed"}, errors: noerrors, expectSuccess: false, test: testSyncSnapshot, - },*/ + }, { name: "7-5 - fail create snapshot with no-existing volume", initialContents: nocontents, expectedContents: nocontents, - initialSnapshots: newSnapshotArray("snap7-5", "snapuid7-5", "claim7-5", "", classGold, "", &False, nil, nil, nil, false), - expectedSnapshots: newSnapshotArray("snap7-5", "snapuid7-5", "claim7-5", "", classGold, "", &False, nil, nil, newVolumeError("Failed to create snapshot content with error failed to get input parameters to create snapshot snap7-5: \"failed to retrieve PV volume7-5 from the API server: \\\"cannot find volume volume7-5\\\"\""), false), + initialSnapshots: newSnapshotArray("snap7-5", "snapuid7-5", "claim7-5", "", classGold, "", &False, nil, nil, nil, false, true), + expectedSnapshots: newSnapshotArray("snap7-5", "snapuid7-5", "claim7-5", "", classGold, "", &False, nil, nil, newVolumeError("Failed to create snapshot content with error failed to get input parameters to create snapshot snap7-5: \"failed to retrieve PV volume7-5 from the API server: \\\"cannot find volume volume7-5\\\"\""), false, true), initialClaims: newClaimArray("claim7-5", "pvc-uid7-5", "1Gi", "volume7-5", v1.ClaimBound, &classEmpty), expectedEvents: []string{"Warning SnapshotContentCreationFailed"}, errors: noerrors, expectSuccess: false, test: testSyncSnapshot, }, + { name: "7-6 - fail create snapshot with claim that is not yet bound", initialContents: nocontents, expectedContents: nocontents, - initialSnapshots: newSnapshotArray("snap7-6", "snapuid7-6", "claim7-6", "", classGold, "", &False, nil, nil, nil, false), - expectedSnapshots: newSnapshotArray("snap7-6", "snapuid7-6", "claim7-6", "", classGold, "", &False, nil, nil, newVolumeError("Failed to create snapshot content with error failed to get input parameters to create snapshot snap7-6: \"the PVC claim7-6 is not yet bound to a PV, will not attempt to take a snapshot\""), false), + initialSnapshots: newSnapshotArray("snap7-6", "snapuid7-6", "claim7-6", "", classGold, "", &False, nil, nil, nil, false, true), + expectedSnapshots: newSnapshotArray("snap7-6", "snapuid7-6", "claim7-6", "", classGold, "", &False, nil, nil, newVolumeError("Failed to create snapshot content with error failed to get input parameters to create snapshot snap7-6: \"the PVC claim7-6 is not yet bound to a PV, will not attempt to take a snapshot\""), false, true), initialClaims: newClaimArray("claim7-6", "pvc-uid7-6", "1Gi", "", v1.ClaimPending, &classEmpty), expectedEvents: []string{"Warning SnapshotContentCreationFailed"}, errors: noerrors, @@ -192,104 +172,82 @@ func TestCreateSnapshotSync(t *testing.T) { test: testSyncSnapshot, }, /*{ - name: "7-7 - fail create snapshot due to csi driver error", - initialContents: nocontents, - expectedContents: nocontents, - initialSnapshots: newSnapshotArray("snap7-7", "snapuid7-7", "claim7-7", "", classGold, "", &False, nil, nil, nil), - expectedSnapshots: newSnapshotArray("snap7-7", "snapuid7-7", "claim7-7", "", classGold, "", &False, nil, nil, newVolumeError("Failed to create snapshot content with error failed to take snapshot of the volume, volume7-7: \"mock create snapshot error\"")), - initialClaims: newClaimArray("claim7-7", "pvc-uid7-7", "1Gi", "volume7-7", v1.ClaimBound, &classEmpty), - initialVolumes: newVolumeArray("volume7-7", "pv-uid7-7", "pv-handle7-7", "1Gi", "pvc-uid7-7", "claim7-7", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty), - expectedCreateCalls: []createCall{ - { - snapshotName: "snapshot-snapuid7-7", - volume: newVolume("volume7-7", "pv-uid7-7", "pv-handle7-7", "1Gi", "pvc-uid7-7", "claim7-7", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty), - parameters: map[string]string{"param1": "value1"}, - // information to return - err: errors.New("mock create snapshot error"), + name: "7-8 - fail create snapshot due to cannot update snapshot status", + initialContents: nocontents, + expectedContents: nocontents, + initialSnapshots: newSnapshotArray("snap7-8", "snapuid7-8", "claim7-8", "", classGold, "", &False, nil, nil, nil), + expectedSnapshots: newSnapshotArray("snap7-8", "snapuid7-8", "claim7-8", "", classGold, "", &False, nil, nil, newVolumeError("Failed to create snapshot: snapshot controller failed to update default/snap7-8 on API server: mock update error")), + initialClaims: newClaimArray("claim7-8", "pvc-uid7-8", "1Gi", "volume7-8", v1.ClaimBound, &classEmpty), + initialVolumes: newVolumeArray("volume7-8", "pv-uid7-8", "pv-handle7-8", "1Gi", "pvc-uid7-8", "claim7-8", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty), + expectedCreateCalls: []createCall{ + { + snapshotName: "snapshot-snapuid7-8", + volume: newVolume("volume7-8", "pv-uid7-8", "pv-handle7-8", "1Gi", "pvc-uid7-8", "claim7-8", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty), + parameters: map[string]string{"param1": "value1"}, + // information to return + driverName: mockDriverName, + size: defaultSize, + snapshotId: "sid7-8", + creationTime: timeNow, + readyToUse: True, + }, }, - }, - errors: noerrors, - expectSuccess: false, - expectedEvents: []string{"Warning SnapshotContentCreationFailed"}, - test: testSyncSnapshot, - },*/ - /*{ - name: "7-8 - fail create snapshot due to cannot update snapshot status", - initialContents: nocontents, - expectedContents: nocontents, - initialSnapshots: newSnapshotArray("snap7-8", "snapuid7-8", "claim7-8", "", classGold, "", &False, nil, nil, nil), - expectedSnapshots: newSnapshotArray("snap7-8", "snapuid7-8", "claim7-8", "", classGold, "", &False, nil, nil, newVolumeError("Failed to create snapshot: snapshot controller failed to update default/snap7-8 on API server: mock update error")), - initialClaims: newClaimArray("claim7-8", "pvc-uid7-8", "1Gi", "volume7-8", v1.ClaimBound, &classEmpty), - initialVolumes: newVolumeArray("volume7-8", "pv-uid7-8", "pv-handle7-8", "1Gi", "pvc-uid7-8", "claim7-8", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty), - /*expectedCreateCalls: []createCall{ - { - snapshotName: "snapshot-snapuid7-8", - volume: newVolume("volume7-8", "pv-uid7-8", "pv-handle7-8", "1Gi", "pvc-uid7-8", "claim7-8", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty), - parameters: map[string]string{"param1": "value1"}, - // information to return - driverName: mockDriverName, - size: defaultSize, - snapshotId: "sid7-8", - creationTime: timeNow, - readyToUse: True, - }, - },*/ - /*errors: []reactorError{ - // Inject error to the forth client.VolumesnapshotV1beta1().VolumeSnapshots().Update call. - // All other calls will succeed. - {"update", "volumesnapshots", errors.New("mock update error")}, - {"update", "volumesnapshots", errors.New("mock update error")}, - {"update", "volumesnapshots", errors.New("mock update error")}, - }, - expectedEvents: []string{"Warning SnapshotContentCreationFailed"}, + /*errors: []reactorError{ + // Inject error to the forth client.VolumesnapshotV1beta1().VolumeSnapshots().Update call. + // All other calls will succeed. + {"update", "volumesnapshots", errors.New("mock update error")}, + {"update", "volumesnapshots", errors.New("mock update error")}, + {"update", "volumesnapshots", errors.New("mock update error")}, + }, + expectedEvents: []string{"Warning SnapshotContentCreationFailed"}, - expectSuccess: false, - test: testSyncSnapshot, - },*/ - /*{ - // TODO(xiangqian): this test case needs to be revisited the scenario - // of VolumeSnapshotContent saving failure. Since there will be no content object - // in API server, it could potentially cause leaking issue - name: "7-9 - fail create snapshot due to cannot save snapshot content", - initialContents: nocontents, - expectedContents: nocontents, - initialSnapshots: newSnapshotArray("snap7-9", "snapuid7-9", "claim7-9", "", classGold, "", &False, nil, nil, nil), - expectedSnapshots: newSnapshotArray("snap7-9", "snapuid7-9", "claim7-9", "", classGold, "snapcontent-snapuid7-9", &True, metaTimeNowUnix, getSize(defaultSize), nil), - initialClaims: newClaimArray("claim7-9", "pvc-uid7-9", "1Gi", "volume7-9", v1.ClaimBound, &classEmpty), - initialVolumes: newVolumeArray("volume7-9", "pv-uid7-9", "pv-handle7-9", "1Gi", "pvc-uid7-9", "claim7-9", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty), - expectedCreateCalls: []createCall{ - { - snapshotName: "snapshot-snapuid7-9", - volume: newVolume("volume7-9", "pv-uid7-9", "pv-handle7-9", "1Gi", "pvc-uid7-9", "claim7-9", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty), - parameters: map[string]string{"param1": "value1"}, - // information to return - driverName: mockDriverName, - size: defaultSize, - snapshotId: "sid7-9", - creationTime: timeNow, - readyToUse: True, + expectSuccess: false, + test: testSyncSnapshot, }, - }, - errors: []reactorError{ - {"create", "volumesnapshotcontents", errors.New("mock create error")}, - {"create", "volumesnapshotcontents", errors.New("mock create error")}, - {"create", "volumesnapshotcontents", errors.New("mock create error")}, - }, - expectedEvents: []string{"Warning CreateSnapshotContentFailed"}, - test: testSyncSnapshot, - }, - { - name: "7-10 - fail create snapshot with secret not found", - initialContents: nocontents, - expectedContents: nocontents, - initialSnapshots: newSnapshotArray("snap7-10", "snapuid7-10", "claim7-10", "", validSecretClass, "", &False, nil, nil, nil), - expectedSnapshots: newSnapshotArray("snap7-10", "snapuid7-10", "claim7-10", "", validSecretClass, "", &False, nil, nil, newVolumeError("Failed to create snapshot: error getting secret secret in namespace default: cannot find secret secret")), - initialClaims: newClaimArray("claim7-10", "pvc-uid7-10", "1Gi", "volume7-10", v1.ClaimBound, &classEmpty), - initialVolumes: newVolumeArray("volume7-10", "pv-uid7-10", "pv-handle7-10", "1Gi", "pvc-uid7-10", "claim7-10", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty), - initialSecrets: []*v1.Secret{}, // no initial secret created - errors: noerrors, - test: testSyncSnapshot, - },*/ + /*{ + // TODO(xiangqian): this test case needs to be revisited the scenario + // of VolumeSnapshotContent saving failure. Since there will be no content object + // in API server, it could potentially cause leaking issue + name: "7-9 - fail create snapshot due to cannot save snapshot content", + initialContents: nocontents, + expectedContents: nocontents, + initialSnapshots: newSnapshotArray("snap7-9", "snapuid7-9", "claim7-9", "", classGold, "", &False, nil, nil, nil), + expectedSnapshots: newSnapshotArray("snap7-9", "snapuid7-9", "claim7-9", "", classGold, "snapcontent-snapuid7-9", &True, metaTimeNowUnix, getSize(defaultSize), nil), + initialClaims: newClaimArray("claim7-9", "pvc-uid7-9", "1Gi", "volume7-9", v1.ClaimBound, &classEmpty), + initialVolumes: newVolumeArray("volume7-9", "pv-uid7-9", "pv-handle7-9", "1Gi", "pvc-uid7-9", "claim7-9", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty), + expectedCreateCalls: []createCall{ + { + snapshotName: "snapshot-snapuid7-9", + volume: newVolume("volume7-9", "pv-uid7-9", "pv-handle7-9", "1Gi", "pvc-uid7-9", "claim7-9", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty), + parameters: map[string]string{"param1": "value1"}, + // information to return + driverName: mockDriverName, + size: defaultSize, + snapshotId: "sid7-9", + creationTime: timeNow, + readyToUse: True, + }, + }, + errors: []reactorError{ + {"create", "volumesnapshotcontents", errors.New("mock create error")}, + {"create", "volumesnapshotcontents", errors.New("mock create error")}, + {"create", "volumesnapshotcontents", errors.New("mock create error")}, + }, + expectedEvents: []string{"Warning CreateSnapshotContentFailed"}, + test: testSyncSnapshot, + }, + { + name: "7-10 - fail create snapshot with secret not found", + initialContents: nocontents, + expectedContents: nocontents, + initialSnapshots: newSnapshotArray("snap7-10", "snapuid7-10", "claim7-10", "", validSecretClass, "", &False, nil, nil, nil, false, true), + expectedSnapshots: newSnapshotArray("snap7-10", "snapuid7-10", "claim7-10", "", validSecretClass, "", &False, nil, nil, newVolumeError("Failed to create snapshot: error getting secret secret in namespace default: cannot find secret secret"), false, true), + initialClaims: newClaimArray("claim7-10", "pvc-uid7-10", "1Gi", "volume7-10", v1.ClaimBound, &classEmpty), + initialVolumes: newVolumeArray("volume7-10", "pv-uid7-10", "pv-handle7-10", "1Gi", "pvc-uid7-10", "claim7-10", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty), + initialSecrets: []*v1.Secret{}, // no initial secret created + errors: noerrors, + test: testSyncSnapshot, + },*/ } runSyncTests(t, tests, snapshotClasses) } diff --git a/pkg/common-controller/snapshot_delete_test.go b/pkg/common-controller/snapshot_delete_test.go index 32f273f65..ca2ea2e6f 100644 --- a/pkg/common-controller/snapshot_delete_test.go +++ b/pkg/common-controller/snapshot_delete_test.go @@ -169,29 +169,29 @@ func TestDeleteSync(t *testing.T) { initialSecrets: []*v1.Secret{secret()}, //expectedDeleteCalls: []deleteCall{{"sid1-3", map[string]string{"foo": "bar"}, nil}}, test: testSyncContent, - }, - /*{ - name: "1-4 - fail delete with snapshot class that has invalid secret parameter", - initialContents: newContentArray("content1-4", "sid1-4", "snapuid1-4", "snap1-4", &deletePolicy, nil, nil, true), - expectedContents: newContentArray("content1-4", "sid1-4", "snapuid1-4", "snap1-4", &deletePolicy, nil, nil, true), - initialSnapshots: nosnapshots, - expectedSnapshots: nosnapshots, - expectedEvents: noevents, - errors: noerrors, - test: testSyncContent, - },*/ - /*{ - name: "1-5 - csi driver delete snapshot returns error", - initialContents: newContentArray("content1-5", "sid1-5", "snap1-5", "sid1-5", validSecretClass, "", "", deletionPolicy, nil, nil, true), - expectedContents: newContentArray("content1-5", "sid1-5", "snap1-5", "sid1-5", validSecretClass, "", "", deletionPolicy, nil, nil, true), - initialSnapshots: nosnapshots, - expectedSnapshots: nosnapshots, - initialSecrets: []*v1.Secret{secret()}, - expectedDeleteCalls: []deleteCall{{"sid1-5", map[string]string{"foo": "bar"}, errors.New("mock csi driver delete error")}}, - expectedEvents: []string{"Warning SnapshotDeleteError"}, - errors: noerrors, - test: testSyncContent, - },*/ + }, /* + { + name: "1-4 - fail delete with snapshot class that has invalid secret parameter", + initialContents: newContentArray("content1-4", "sid1-4", "snapuid1-4", "snap1-4", &deletePolicy, nil, nil, true), + expectedContents: newContentArray("content1-4", "sid1-4", "snapuid1-4", "snap1-4", &deletePolicy, nil, nil, true), + initialSnapshots: nosnapshots, + expectedSnapshots: nosnapshots, + expectedEvents: noevents, + errors: noerrors, + test: testSyncContent, + }, + { + name: "1-5 - csi driver delete snapshot returns error", + initialContents: newContentArray("content1-5", "sid1-5", "snap1-5", "sid1-5", validSecretClass, "", "", deletionPolicy, nil, nil, true), + expectedContents: newContentArray("content1-5", "sid1-5", "snap1-5", "sid1-5", validSecretClass, "", "", deletionPolicy, nil, nil, true), + initialSnapshots: nosnapshots, + expectedSnapshots: nosnapshots, + initialSecrets: []*v1.Secret{secret()}, + expectedDeleteCalls: []deleteCall{{"sid1-5", map[string]string{"foo": "bar"}, errors.New("mock csi driver delete error")}}, + expectedEvents: []string{"Warning SnapshotDeleteError"}, + errors: noerrors, + test: testSyncContent, + },*/ /*{ name: "1-6 - api server delete content returns error", initialContents: newContentArray("content1-6", "sid1-6", "snap1-6", "sid1-6", validSecretClass, "", "", deletionPolicy, nil, nil, true), @@ -214,8 +214,8 @@ func TestDeleteSync(t *testing.T) { name: "1-7 - prebound content is deleted while the snapshot exists", initialContents: newContentArray("content1-7", "sid1-7", "snap1-7", "sid1-7", emptySecretClass, "", "", deletionPolicy, nil, nil, true), expectedContents: newContentArray("content1-7", "sid1-7", "snap1-7", "sid1-7", emptySecretClass, "", "", deletionPolicy, nil, nil, true), - initialSnapshots: newSnapshotArray("snap1-7", "snapuid1-7-x", "claim1-7", "", validSecretClass, "", &False, nil, nil, nil, false), - expectedSnapshots: newSnapshotArray("snap1-7", "snapuid1-7-x", "claim1-7", "", validSecretClass, "", &False, nil, nil, nil, false), + initialSnapshots: newSnapshotArray("snap1-7", "snapuid1-7-x", "claim1-7", "", validSecretClass, "", &False, nil, nil, nil, false, true), + expectedSnapshots: newSnapshotArray("snap1-7", "snapuid1-7-x", "claim1-7", "", validSecretClass, "", &False, nil, nil, nil, false, true), initialSecrets: []*v1.Secret{secret()}, //expectedDeleteCalls: []deleteCall{{"sid1-7", map[string]string{"foo": "bar"}, nil}}, expectedEvents: noevents, @@ -255,8 +255,8 @@ func TestDeleteSync(t *testing.T) { name: "1-10 - will not delete content with retain policy set which is bound to a snapshot incorrectly", initialContents: newContentArray("content1-10", "snapuid1-10-x", "snap1-10", "sid1-10", validSecretClass, "", "", retainPolicy, nil, nil, true), expectedContents: newContentArray("content1-10", "snapuid1-10-x", "snap1-10", "sid1-10", validSecretClass, "", "", retainPolicy, nil, nil, true), - initialSnapshots: newSnapshotArray("snap1-10", "snapuid1-10", "claim1-10", "", validSecretClass, "content1-10", &False, nil, nil, nil, false), - expectedSnapshots: newSnapshotArray("snap1-10", "snapuid1-10", "claim1-10", "", validSecretClass, "content1-10", &False, nil, nil, nil, false), + initialSnapshots: newSnapshotArray("snap1-10", "snapuid1-10", "claim1-10", "", validSecretClass, "content1-10", &False, nil, nil, nil, false, true), + expectedSnapshots: newSnapshotArray("snap1-10", "snapuid1-10", "claim1-10", "", validSecretClass, "content1-10", &False, nil, nil, nil, false, true), expectedEvents: noevents, initialSecrets: []*v1.Secret{secret()}, errors: noerrors, @@ -266,8 +266,8 @@ func TestDeleteSync(t *testing.T) { name: "1-11 - content will not be deleted if it is bound to a snapshot correctly, snapsht uid is not specified", initialContents: newContentArray("content1-11", "", "snap1-11", "sid1-11", validSecretClass, "", "", deletePolicy, nil, nil, true), expectedContents: newContentArray("content1-11", "", "snap1-11", "sid1-11", validSecretClass, "", "", deletePolicy, nil, nil, true), - initialSnapshots: newSnapshotArray("snap1-11", "snapuid1-11", "claim1-11", "", validSecretClass, "content1-11", &False, nil, nil, nil, false), - expectedSnapshots: newSnapshotArray("snap1-11", "snapuid1-11", "claim1-11", "", validSecretClass, "content1-11", &False, nil, nil, nil, false), + initialSnapshots: newSnapshotArray("snap1-11", "snapuid1-11", "claim1-11", "", validSecretClass, "content1-11", &False, nil, nil, nil, false, true), + expectedSnapshots: newSnapshotArray("snap1-11", "snapuid1-11", "claim1-11", "", validSecretClass, "content1-11", &False, nil, nil, nil, false, true), expectedEvents: noevents, initialSecrets: []*v1.Secret{secret()}, errors: noerrors, diff --git a/pkg/common-controller/snapshot_finalizer_test.go b/pkg/common-controller/snapshot_finalizer_test.go index 049262fdf..6265c26cb 100644 --- a/pkg/common-controller/snapshot_finalizer_test.go +++ b/pkg/common-controller/snapshot_finalizer_test.go @@ -22,46 +22,60 @@ import ( v1 "k8s.io/api/core/v1" ) -// Test single call to ensurePVCFinalizer and checkandRemovePVCFinalizer, -// expecting PVCFinalizer to be added or removed -func TestPVCFinalizer(t *testing.T) { +// Test single call to ensurePVCFinalizer, checkandRemovePVCFinalizer, addSnapshotFinalizer, removeSnapshotFinalizer +// expecting finalizers to be added or removed +func TestSnapshotFinalizer(t *testing.T) { tests := []controllerTest{ { name: "1-1 - successful add PVC finalizer", - initialSnapshots: newSnapshotArray("snap6-2", "snapuid6-2", "claim6-2", "", classSilver, "", &False, nil, nil, nil, false), + initialSnapshots: newSnapshotArray("snap6-2", "snapuid6-2", "claim6-2", "", classSilver, "", &False, nil, nil, nil, false, true), initialClaims: newClaimArray("claim6-2", "pvc-uid6-2", "1Gi", "volume6-2", v1.ClaimBound, &classEmpty), test: testAddPVCFinalizer, expectSuccess: true, }, { name: "1-2 - won't add PVC finalizer; already added", - initialSnapshots: newSnapshotArray("snap6-2", "snapuid6-2", "claim6-2", "", classSilver, "", &False, nil, nil, nil, false), + initialSnapshots: newSnapshotArray("snap6-2", "snapuid6-2", "claim6-2", "", classSilver, "", &False, nil, nil, nil, false, true), initialClaims: newClaimArrayFinalizer("claim6-2", "pvc-uid6-2", "1Gi", "volume6-2", v1.ClaimBound, &classEmpty), test: testAddPVCFinalizer, expectSuccess: false, }, { name: "1-3 - successful remove PVC finalizer", - initialSnapshots: newSnapshotArray("snap6-2", "snapuid6-2", "claim6-2", "", classSilver, "", &False, nil, nil, nil, false), + initialSnapshots: newSnapshotArray("snap6-2", "snapuid6-2", "claim6-2", "", classSilver, "", &False, nil, nil, nil, false, true), initialClaims: newClaimArrayFinalizer("claim6-2", "pvc-uid6-2", "1Gi", "volume6-2", v1.ClaimBound, &classEmpty), test: testRemovePVCFinalizer, expectSuccess: true, }, { name: "1-4 - won't remove PVC finalizer; already removed", - initialSnapshots: newSnapshotArray("snap6-2", "snapuid6-2", "claim6-2", "", classSilver, "", &False, nil, nil, nil, false), + initialSnapshots: newSnapshotArray("snap6-2", "snapuid6-2", "claim6-2", "", classSilver, "", &False, nil, nil, nil, false, true), initialClaims: newClaimArray("claim6-2", "pvc-uid6-2", "1Gi", "volume6-2", v1.ClaimBound, &classEmpty), test: testRemovePVCFinalizer, expectSuccess: false, }, { name: "1-5 - won't remove PVC finalizer; PVC in-use", - initialSnapshots: newSnapshotArray("snap6-2", "snapuid6-2", "claim6-2", "", classSilver, "", &False, nil, nil, nil, false), + initialSnapshots: newSnapshotArray("snap6-2", "snapuid6-2", "claim6-2", "", classSilver, "", &False, nil, nil, nil, false, true), initialClaims: newClaimArray("claim6-2", "pvc-uid6-2", "1Gi", "volume6-2", v1.ClaimBound, &classEmpty), test: testRemovePVCFinalizer, expectSuccess: false, }, + { + name: "2-1 - successful add Snapshot finalizer", + initialSnapshots: newSnapshotArray("snap6-2", "snapuid6-2", "claim6-2", "", classSilver, "", &False, nil, nil, nil, false, false), + initialClaims: newClaimArray("claim6-2", "pvc-uid6-2", "1Gi", "volume6-2", v1.ClaimBound, &classEmpty), + test: testAddSnapshotFinalizer, + expectSuccess: true, + }, + { + name: "2-1 - successful remove Snapshot finalizer", + initialSnapshots: newSnapshotArray("snap6-2", "snapuid6-2", "claim6-2", "", classSilver, "", &False, nil, nil, nil, false, true), + initialClaims: newClaimArray("claim6-2", "pvc-uid6-2", "1Gi", "volume6-2", v1.ClaimBound, &classEmpty), + test: testRemoveSnapshotFinalizer, + expectSuccess: true, + }, } - runPVCFinalizerTests(t, tests, snapshotClasses) + runFinalizerTests(t, tests, snapshotClasses) } diff --git a/pkg/common-controller/snapshot_update_test.go b/pkg/common-controller/snapshot_update_test.go index f3a2faea6..78d0dceea 100644 --- a/pkg/common-controller/snapshot_update_test.go +++ b/pkg/common-controller/snapshot_update_test.go @@ -48,8 +48,8 @@ func TestSync(t *testing.T) { name: "2-1 - snapshot is bound to a non-existing content", initialContents: nocontents, expectedContents: nocontents, - initialSnapshots: newSnapshotArray("snap2-1", "snapuid2-1", "claim2-1", "", validSecretClass, "content2-1", &True, nil, nil, nil, false), - expectedSnapshots: newSnapshotArray("snap2-1", "snapuid2-1", "claim2-1", "", validSecretClass, "content2-1", &False, nil, nil, newVolumeError("VolumeSnapshotContent is missing"), false), + initialSnapshots: newSnapshotArray("snap2-1", "snapuid2-1", "claim2-1", "", validSecretClass, "content2-1", &True, nil, nil, nil, false, true), + expectedSnapshots: newSnapshotArray("snap2-1", "snapuid2-1", "claim2-1", "", validSecretClass, "content2-1", &False, nil, nil, newVolumeError("VolumeSnapshotContent is missing"), false, true), expectedEvents: []string{"Warning SnapshotContentMissing"}, errors: noerrors, test: testSyncSnapshot, @@ -68,8 +68,8 @@ func TestSync(t *testing.T) { name: "2-3 - success bind snapshot and content but not ready, no status changed", initialContents: newContentArray("content2-3", "snapuid2-3", "snap2-3", "sid2-3", validSecretClass, "", "", deletionPolicy, nil, nil, false), expectedContents: newContentArrayWithReadyToUse("content2-3", "snapuid2-3", "snap2-3", "sid2-3", validSecretClass, "", "", deletionPolicy, &timeNowStamp, nil, &True, false), - initialSnapshots: newSnapshotArray("snap2-3", "snapuid2-3", "claim2-3", "", validSecretClass, "content2-3", &False, metaTimeNow, nil, nil, false), - expectedSnapshots: newSnapshotArray("snap2-3", "snapuid2-3", "claim2-3", "", validSecretClass, "content2-3", &True, metaTimeNow, nil, nil, false), + initialSnapshots: newSnapshotArray("snap2-3", "snapuid2-3", "claim2-3", "", validSecretClass, "content2-3", &False, metaTimeNow, nil, nil, false, true), + expectedSnapshots: newSnapshotArray("snap2-3", "snapuid2-3", "claim2-3", "", validSecretClass, "content2-3", &True, metaTimeNow, nil, nil, false, true), initialClaims: newClaimArray("claim2-3", "pvc-uid2-3", "1Gi", "volume2-3", v1.ClaimBound, &classEmpty), initialVolumes: newVolumeArray("volume2-3", "pv-uid2-3", "pv-handle2-3", "1Gi", "pvc-uid2-3", "claim2-3", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty), initialSecrets: []*v1.Secret{secret()}, @@ -95,8 +95,8 @@ func TestSync(t *testing.T) { name: "2-4 - noop", initialContents: newContentArray("content2-4", "snapuid2-4", "snap2-4", "sid2-4", validSecretClass, "", "", deletionPolicy, nil, nil, false), expectedContents: newContentArray("content2-4", "snapuid2-4", "snap2-4", "sid2-4", validSecretClass, "", "", deletionPolicy, nil, nil, false), - initialSnapshots: newSnapshotArray("snap2-4", "snapuid2-4", "claim2-4", "", validSecretClass, "content2-4", &True, metaTimeNow, nil, nil, false), - expectedSnapshots: newSnapshotArray("snap2-4", "snapuid2-4", "claim2-4", "", validSecretClass, "content2-4", &True, metaTimeNow, nil, nil, false), + initialSnapshots: newSnapshotArray("snap2-4", "snapuid2-4", "claim2-4", "", validSecretClass, "content2-4", &True, metaTimeNow, nil, nil, false, true), + expectedSnapshots: newSnapshotArray("snap2-4", "snapuid2-4", "claim2-4", "", validSecretClass, "content2-4", &True, metaTimeNow, nil, nil, false, true), errors: noerrors, test: testSyncSnapshot, }, @@ -104,8 +104,8 @@ func TestSync(t *testing.T) { name: "2-5 - snapshot and content bound, status ready false -> true", initialContents: newContentArrayWithReadyToUse("content2-5", "snapuid2-5", "snap2-5", "sid2-5", validSecretClass, "", "", deletionPolicy, &timeNowStamp, nil, &False, false), expectedContents: newContentArrayWithReadyToUse("content2-5", "snapuid2-5", "snap2-5", "sid2-5", validSecretClass, "", "", deletionPolicy, &timeNowStamp, nil, &False, false), - initialSnapshots: newSnapshotArray("snap2-5", "snapuid2-5", "claim2-5", "", validSecretClass, "content2-5", &False, metaTimeNow, nil, nil, false), - expectedSnapshots: newSnapshotArray("snap2-5", "snapuid2-5", "claim2-5", "", validSecretClass, "content2-5", &False, metaTimeNow, nil, nil, false), + initialSnapshots: newSnapshotArray("snap2-5", "snapuid2-5", "claim2-5", "", validSecretClass, "content2-5", &False, metaTimeNow, nil, nil, false, true), + expectedSnapshots: newSnapshotArray("snap2-5", "snapuid2-5", "claim2-5", "", validSecretClass, "content2-5", &False, metaTimeNow, nil, nil, false, true), initialClaims: newClaimArray("claim2-5", "pvc-uid2-5", "1Gi", "volume2-5", v1.ClaimBound, &classEmpty), initialVolumes: newVolumeArray("volume2-5", "pv-uid2-5", "pv-handle2-5", "1Gi", "pvc-uid2-5", "claim2-5", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty), initialSecrets: []*v1.Secret{secret()}, @@ -130,17 +130,10 @@ func TestSync(t *testing.T) { name: "2-6 - snapshot bound to prebound content correctly, status ready false -> true, ref.UID '' -> 'snapuid2-6'", initialContents: newContentArrayWithReadyToUse("content2-6", "snapuid2-6", "snap2-6", "sid2-6", validSecretClass, "", "", deletionPolicy, &timeNowStamp, nil, &False, false), expectedContents: newContentArrayWithReadyToUse("content2-6", "snapuid2-6", "snap2-6", "sid2-6", validSecretClass, "", "", deletionPolicy, &timeNowStamp, nil, &False, false), - initialSnapshots: newSnapshotArray("snap2-6", "snapuid2-6", "", "content2-6", validSecretClass, "content2-6", &False, metaTimeNow, nil, nil, false), - expectedSnapshots: newSnapshotArray("snap2-6", "snapuid2-6", "", "content2-6", validSecretClass, "content2-6", &False, metaTimeNow, nil, nil, false), - expectedListCalls: []listCall{ - { - size: defaultSize, - snapshotID: "sid2-6", - readyToUse: true, - }, - }, - errors: noerrors, - test: testSyncSnapshot, + initialSnapshots: newSnapshotArray("snap2-6", "snapuid2-6", "", "content2-6", validSecretClass, "content2-6", &False, metaTimeNow, nil, nil, false, true), + expectedSnapshots: newSnapshotArray("snap2-6", "snapuid2-6", "", "content2-6", validSecretClass, "content2-6", &False, metaTimeNow, nil, nil, false, true), + errors: noerrors, + test: testSyncSnapshot, }, /*{ name: "2-7 - snapshot and content bound, csi driver get status error", @@ -200,8 +193,8 @@ func TestSync(t *testing.T) { name: "2-9 - fail on status update as there is not pvc provided", initialContents: newContentArray("content2-9", "snapuid2-9", "snap2-9", "sid2-9", validSecretClass, "", "", deletionPolicy, nil, nil, false), expectedContents: newContentArray("content2-9", "snapuid2-9", "snap2-9", "sid2-9", validSecretClass, "", "", deletionPolicy, nil, nil, false), - initialSnapshots: newSnapshotArray("snap2-9", "snapuid2-9", "claim2-9", "", validSecretClass, "", &False, nil, nil, nil, false), - expectedSnapshots: newSnapshotArray("snap2-9", "snapuid2-9", "claim2-9", "", validSecretClass, "content2-9", &True, nil, nil, nil, false), + initialSnapshots: newSnapshotArray("snap2-9", "snapuid2-9", "claim2-9", "", validSecretClass, "", &False, nil, nil, nil, false, true), + expectedSnapshots: newSnapshotArray("snap2-9", "snapuid2-9", "claim2-9", "", validSecretClass, "content2-9", &True, nil, nil, nil, false, true), //expectedSnapshots: newSnapshotArray("snap2-9", "snapuid2-9", "claim2-9", "", validSecretClass, "content2-9", &False, nil, nil, newVolumeError("Failed to check and update snapshot: failed to get input parameters to create snapshot snap2-9: \"failed to retrieve PVC claim2-9 from the lister: \\\"persistentvolumeclaim \\\\\\\"claim2-9\\\\\\\" not found\\\"\"")), errors: noerrors, test: testSyncSnapshot, @@ -210,8 +203,8 @@ func TestSync(t *testing.T) { name: "2-10 - do not bind when snapshot and content not match", initialContents: newContentArray("content2-10", "snapuid2-10-x", "snap2-10", "sid2-10", validSecretClass, "", "", deletionPolicy, nil, nil, false), expectedContents: newContentArray("content2-10", "snapuid2-10-x", "snap2-10", "sid2-10", validSecretClass, "", "", deletionPolicy, nil, nil, false), - initialSnapshots: newSnapshotArray("snap2-10", "snapuid2-10", "claim2-10", "", validSecretClass, "", &False, nil, nil, newVolumeError("mock driver error"), false), - expectedSnapshots: newSnapshotArray("snap2-10", "snapuid2-10", "claim2-10", "", validSecretClass, "", &False, nil, nil, newVolumeError("mock driver error"), false), + initialSnapshots: newSnapshotArray("snap2-10", "snapuid2-10", "claim2-10", "", validSecretClass, "", &False, nil, nil, newVolumeError("mock driver error"), false, true), + expectedSnapshots: newSnapshotArray("snap2-10", "snapuid2-10", "claim2-10", "", validSecretClass, "", &False, nil, nil, newVolumeError("mock driver error"), false, true), errors: noerrors, test: testSyncSnapshot, }, @@ -219,8 +212,8 @@ func TestSync(t *testing.T) { name: "3-1 - ready snapshot lost reference to VolumeSnapshotContent", initialContents: nocontents, expectedContents: nocontents, - initialSnapshots: newSnapshotArray("snap3-1", "snapuid3-1", "claim3-1", "", validSecretClass, "content3-1", &True, metaTimeNow, nil, nil, false), - expectedSnapshots: newSnapshotArray("snap3-1", "snapuid3-1", "claim3-1", "", validSecretClass, "content3-1", &False, metaTimeNow, nil, newVolumeError("VolumeSnapshotContent is missing"), false), + initialSnapshots: newSnapshotArray("snap3-1", "snapuid3-1", "claim3-1", "", validSecretClass, "content3-1", &True, metaTimeNow, nil, nil, false, true), + expectedSnapshots: newSnapshotArray("snap3-1", "snapuid3-1", "claim3-1", "", validSecretClass, "content3-1", &False, metaTimeNow, nil, newVolumeError("VolumeSnapshotContent is missing"), false, true), errors: noerrors, expectedEvents: []string{"Warning SnapshotContentMissing"}, test: testSyncSnapshot, @@ -229,8 +222,8 @@ func TestSync(t *testing.T) { name: "3-2 - ready snapshot bound to none-exist content", initialContents: nocontents, expectedContents: nocontents, - initialSnapshots: newSnapshotArray("snap3-2", "snapuid3-2", "claim3-2", "", validSecretClass, "content3-2", &True, metaTimeNow, nil, nil, false), - expectedSnapshots: newSnapshotArray("snap3-2", "snapuid3-2", "claim3-2", "", validSecretClass, "content3-2", &False, metaTimeNow, nil, newVolumeError("VolumeSnapshotContent is missing"), false), + initialSnapshots: newSnapshotArray("snap3-2", "snapuid3-2", "claim3-2", "", validSecretClass, "content3-2", &True, metaTimeNow, nil, nil, false, true), + expectedSnapshots: newSnapshotArray("snap3-2", "snapuid3-2", "claim3-2", "", validSecretClass, "content3-2", &False, metaTimeNow, nil, newVolumeError("VolumeSnapshotContent is missing"), false, true), errors: noerrors, expectedEvents: []string{"Warning SnapshotContentMissing"}, test: testSyncSnapshot, @@ -239,8 +232,8 @@ func TestSync(t *testing.T) { name: "3-3 - ready snapshot(everything is well, do nothing)", initialContents: newContentArray("content3-3", "snapuid3-3", "snap3-3", "sid3-3", validSecretClass, "", "", deletionPolicy, nil, nil, false), expectedContents: newContentArray("content3-3", "snapuid3-3", "snap3-3", "sid3-3", validSecretClass, "", "", deletionPolicy, nil, nil, false), - initialSnapshots: newSnapshotArray("snap3-3", "snapuid3-3", "claim3-3", "", validSecretClass, "content3-3", &True, metaTimeNow, nil, nil, false), - expectedSnapshots: newSnapshotArray("snap3-3", "snapuid3-3", "claim3-3", "", validSecretClass, "content3-3", &True, metaTimeNow, nil, nil, false), + initialSnapshots: newSnapshotArray("snap3-3", "snapuid3-3", "claim3-3", "", validSecretClass, "content3-3", &True, metaTimeNow, nil, nil, false, true), + expectedSnapshots: newSnapshotArray("snap3-3", "snapuid3-3", "claim3-3", "", validSecretClass, "content3-3", &True, metaTimeNow, nil, nil, false, true), errors: noerrors, test: testSyncSnapshot, }, @@ -248,27 +241,17 @@ func TestSync(t *testing.T) { name: "3-4 - ready snapshot misbound to VolumeSnapshotContent", initialContents: newContentArray("content3-4", "snapuid3-4-x", "snap3-4", "sid3-4", validSecretClass, "", "", deletionPolicy, nil, nil, false), expectedContents: newContentArray("content3-4", "snapuid3-4-x", "snap3-4", "sid3-4", validSecretClass, "", "", deletionPolicy, nil, nil, false), - initialSnapshots: newSnapshotArray("snap3-4", "snapuid3-4", "claim3-4", "", validSecretClass, "content3-4", &True, metaTimeNow, nil, nil, false), - expectedSnapshots: newSnapshotArray("snap3-4", "snapuid3-4", "claim3-4", "", validSecretClass, "content3-4", &False, metaTimeNow, nil, newVolumeError("VolumeSnapshotContent is not bound to the VolumeSnapshot correctly"), false), + initialSnapshots: newSnapshotArray("snap3-4", "snapuid3-4", "claim3-4", "", validSecretClass, "content3-4", &True, metaTimeNow, nil, nil, false, true), + expectedSnapshots: newSnapshotArray("snap3-4", "snapuid3-4", "claim3-4", "", validSecretClass, "content3-4", &False, metaTimeNow, nil, newVolumeError("VolumeSnapshotContent is not bound to the VolumeSnapshot correctly"), false, true), errors: noerrors, test: testSyncSnapshot, }, - /*{ - name: "3-5 - snapshot bound to content in which the driver does not match", - initialContents: newContentWithUnmatchDriverArray("content3-5", "snapuid3-5", "snap3-5", "sid3-5", validSecretClass, "", "", deletionPolicy, nil, nil, false), - expectedContents: nocontents, - initialSnapshots: newSnapshotArray("snap3-5", "snapuid3-5", "claim3-5", "", validSecretClass, "content3-5", &False, metaTimeNow, nil, nil), - expectedSnapshots: newSnapshotArray("snap3-5", "snapuid3-5", "claim3-5", "", validSecretClass, "content3-5", &False, metaTimeNow, nil, newVolumeError("VolumeSnapshotContent is missing")), - expectedEvents: []string{"Warning SnapshotContentMissing"}, - errors: noerrors, - test: testSyncSnapshotError, - },*/ { name: "4-1 - content bound to snapshot, snapshot status missing and rebuilt", initialContents: newContentArrayWithReadyToUse("content2-5", "snapuid2-5", "snap2-5", "sid2-5", validSecretClass, "", "", deletionPolicy, nil, &size, &True, false), expectedContents: newContentArrayWithReadyToUse("content2-5", "snapuid2-5", "snap2-5", "sid2-5", validSecretClass, "", "", deletionPolicy, nil, &size, &True, false), - initialSnapshots: newSnapshotArray("snap2-5", "snapuid2-5", "claim2-5", "", validSecretClass, "", &False, nil, nil, nil, true), - expectedSnapshots: newSnapshotArray("snap2-5", "snapuid2-5", "claim2-5", "", validSecretClass, "content2-5", &True, nil, getSize(1), nil, false), + initialSnapshots: newSnapshotArray("snap2-5", "snapuid2-5", "claim2-5", "", validSecretClass, "", &False, nil, nil, nil, true, true), + expectedSnapshots: newSnapshotArray("snap2-5", "snapuid2-5", "claim2-5", "", validSecretClass, "content2-5", &True, nil, getSize(1), nil, false, true), initialClaims: newClaimArray("claim2-5", "pvc-uid2-5", "1Gi", "volume2-5", v1.ClaimBound, &classEmpty), initialVolumes: newVolumeArray("volume2-5", "pv-uid2-5", "pv-handle2-5", "1Gi", "pvc-uid2-5", "claim2-5", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty), initialSecrets: []*v1.Secret{secret()}, @@ -279,8 +262,8 @@ func TestSync(t *testing.T) { name: "4-2 - snapshot and content bound, ReadyToUse in snapshot status missing and rebuilt", initialContents: newContentArrayWithReadyToUse("content2-5", "snapuid2-5", "snap2-5", "sid2-5", validSecretClass, "", "", deletionPolicy, nil, nil, &True, false), expectedContents: newContentArrayWithReadyToUse("content2-5", "snapuid2-5", "snap2-5", "sid2-5", validSecretClass, "", "", deletionPolicy, nil, nil, &True, false), - initialSnapshots: newSnapshotArray("snap2-5", "snapuid2-5", "claim2-5", "", validSecretClass, "content2-5", &False, nil, nil, nil, false), - expectedSnapshots: newSnapshotArray("snap2-5", "snapuid2-5", "claim2-5", "", validSecretClass, "content2-5", &True, nil, nil, nil, false), + initialSnapshots: newSnapshotArray("snap2-5", "snapuid2-5", "claim2-5", "", validSecretClass, "content2-5", &False, nil, nil, nil, false, true), + expectedSnapshots: newSnapshotArray("snap2-5", "snapuid2-5", "claim2-5", "", validSecretClass, "content2-5", &True, nil, nil, nil, false, true), initialClaims: newClaimArray("claim2-5", "pvc-uid2-5", "1Gi", "volume2-5", v1.ClaimBound, &classEmpty), initialVolumes: newVolumeArray("volume2-5", "pv-uid2-5", "pv-handle2-5", "1Gi", "pvc-uid2-5", "claim2-5", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty), initialSecrets: []*v1.Secret{secret()}, @@ -291,8 +274,8 @@ func TestSync(t *testing.T) { name: "4-3 - content bound to snapshot, fields in snapshot status missing and rebuilt", initialContents: newContentArrayWithReadyToUse("content2-5", "snapuid2-5", "snap2-5", "sid2-5", validSecretClass, "", "", deletionPolicy, nil, &size, &True, false), expectedContents: newContentArrayWithReadyToUse("content2-5", "snapuid2-5", "snap2-5", "sid2-5", validSecretClass, "", "", deletionPolicy, nil, &size, &True, false), - initialSnapshots: newSnapshotArray("snap2-5", "snapuid2-5", "claim2-5", "", validSecretClass, "", &False, nil, nil, nil, false), - expectedSnapshots: newSnapshotArray("snap2-5", "snapuid2-5", "claim2-5", "", validSecretClass, "content2-5", &True, nil, getSize(1), nil, false), + initialSnapshots: newSnapshotArray("snap2-5", "snapuid2-5", "claim2-5", "", validSecretClass, "", &False, nil, nil, nil, false, true), + expectedSnapshots: newSnapshotArray("snap2-5", "snapuid2-5", "claim2-5", "", validSecretClass, "content2-5", &True, nil, getSize(1), nil, false, true), initialClaims: newClaimArray("claim2-5", "pvc-uid2-5", "1Gi", "volume2-5", v1.ClaimBound, &classEmpty), initialVolumes: newVolumeArray("volume2-5", "pv-uid2-5", "pv-handle2-5", "1Gi", "pvc-uid2-5", "claim2-5", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty), initialSecrets: []*v1.Secret{secret()}, diff --git a/pkg/common-controller/snapshotclass_test.go b/pkg/common-controller/snapshotclass_test.go new file mode 100644 index 000000000..65a64da9d --- /dev/null +++ b/pkg/common-controller/snapshotclass_test.go @@ -0,0 +1,92 @@ +/* +Copyright 2018 The Kubernetes Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package common_controller + +import ( + "errors" + + v1 "k8s.io/api/core/v1" + storage "k8s.io/api/storage/v1" + + "testing" +) + +// Test single call to checkAndUpdateSnapshotClass. +// 1. Fill in the controller with initial data +// 2. Call the tested function checkAndUpdateSnapshotClass via +// controllerTest.testCall *once*. +// 3. Compare resulting snapshotclass. +func TestUpdateSnapshotClass(t *testing.T) { + tests := []controllerTest{ + { + // defualt snapshot class name should be set + name: "1-1 - default snapshot class name should be set", + initialContents: nocontents, + initialSnapshots: newSnapshotArray("snap1-1", "snapuid1-1", "claim1-1", "content1-1", "", "content1-1", &True, nil, nil, nil, false, true), + expectedSnapshots: newSnapshotArray("snap1-1", "snapuid1-1", "claim1-1", "content1-1", defaultClass, "content1-1", &True, nil, nil, nil, false, true), + initialClaims: newClaimArray("claim1-1", "pvc-uid1-1", "1Gi", "volume1-1", v1.ClaimBound, &sameDriver), + initialVolumes: newVolumeArray("volume1-1", "pv-uid1-1", "pv-handle1-1", "1Gi", "pvc-uid1-1", "claim1-1", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty), + initialStorageClasses: []*storage.StorageClass{sameDriverStorageClass}, + expectedEvents: noevents, + errors: noerrors, + test: testUpdateSnapshotClass, + }, + { + // snapshot class name already set + name: "1-2 - snapshot class name already set", + initialContents: nocontents, + initialSnapshots: newSnapshotArray("snap1-1", "snapuid1-1", "claim1-1", "content1-1", defaultClass, "content1-1", &True, nil, nil, nil, false, true), + expectedSnapshots: newSnapshotArray("snap1-1", "snapuid1-1", "claim1-1", "content1-1", defaultClass, "content1-1", &True, nil, nil, nil, false, true), + initialClaims: newClaimArray("claim1-1", "pvc-uid1-1", "1Gi", "volume1-1", v1.ClaimBound, &sameDriver), + initialVolumes: newVolumeArray("volume1-1", "pv-uid1-1", "pv-handle1-1", "1Gi", "pvc-uid1-1", "claim1-1", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty), + initialStorageClasses: []*storage.StorageClass{sameDriverStorageClass}, + expectedEvents: noevents, + errors: noerrors, + test: testUpdateSnapshotClass, + }, + { + // default snapshot class not found + name: "1-3 - snapshot class name not found", + initialContents: nocontents, + initialSnapshots: newSnapshotArray("snap1-1", "snapuid1-1", "claim1-1", "content1-1", "missing-class", "content1-1", &True, nil, nil, nil, false, true), + expectedSnapshots: newSnapshotArray("snap1-1", "snapuid1-1", "claim1-1", "content1-1", "missing-class", "content1-1", &False, nil, nil, newVolumeError("Failed to get snapshot class with error failed to retrieve snapshot class missing-class from the informer: \"volumesnapshotclass.snapshot.storage.k8s.io \\\"missing-class\\\" not found\""), false, true), + initialClaims: newClaimArray("claim1-1", "pvc-uid1-1", "1Gi", "volume1-1", v1.ClaimBound, &sameDriver), + initialVolumes: newVolumeArray("volume1-1", "pv-uid1-1", "pv-handle1-1", "1Gi", "pvc-uid1-1", "claim1-1", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty), + initialStorageClasses: []*storage.StorageClass{sameDriverStorageClass}, + expectedEvents: []string{"Warning GetSnapshotClassFailed"}, + errors: noerrors, + test: testUpdateSnapshotClass, + }, + { + // failed to get snapshot class from name + name: "1-4 - snapshot update with default class name failed because storageclass not found", + initialContents: nocontents, + initialSnapshots: newSnapshotArray("snap1-1", "snapuid1-1", "claim1-1", "content1-1", "", "content1-1", &True, nil, nil, nil, false, true), + expectedSnapshots: newSnapshotArray("snap1-1", "snapuid1-1", "claim1-1", "content1-1", "", "content1-1", &False, nil, nil, newVolumeError("Failed to set default snapshot class with error mock update error"), false, true), + initialClaims: newClaimArray("claim1-1", "pvc-uid1-1", "1Gi", "volume1-1", v1.ClaimBound, &sameDriver), + initialVolumes: newVolumeArray("volume1-1", "pv-uid1-1", "pv-handle1-1", "1Gi", "pvc-uid1-1", "claim1-1", v1.VolumeBound, v1.PersistentVolumeReclaimDelete, classEmpty), + initialStorageClasses: []*storage.StorageClass{sameDriverStorageClass}, + expectedEvents: []string{"Warning SetDefaultSnapshotClassFailed"}, + errors: []reactorError{ + {"get", "storageclasses", errors.New("mock update error")}, + }, + test: testUpdateSnapshotClass, + }, + } + + runUpdateSnapshotClassTests(t, tests, snapshotClasses) +}