Add sidecar-controller unit tests
Signed-off-by: Grant Griffiths <grant@portworx.com>
This commit is contained in:
47
pkg/sidecar-controller/content_create_test.go
Normal file
47
pkg/sidecar-controller/content_create_test.go
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2019 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 sidecar_controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSyncContent(t *testing.T) {
|
||||||
|
var tests []controllerTest
|
||||||
|
|
||||||
|
tests = append(tests, controllerTest{
|
||||||
|
name: "Basic content create ready to use",
|
||||||
|
initialContents: newContentArrayWithReadyToUse("content1-1", "snapuid1-1", "snap1-1", "sid1-1", defaultClass, "", "", retainPolicy, nil, &defaultSize, &False, true),
|
||||||
|
expectedContents: newContentArrayWithReadyToUse("content1-1", "snapuid1-1", "snap1-1", "sid1-1", defaultClass, "", "", retainPolicy, nil, &defaultSize, &True, true),
|
||||||
|
expectedEvents: noevents,
|
||||||
|
expectedCreateCalls: []createCall{
|
||||||
|
{
|
||||||
|
snapshotName: "snapshot-snapuid1-1",
|
||||||
|
driverName: mockDriverName,
|
||||||
|
snapshotId: "snapuid1-1",
|
||||||
|
creationTime: timeNow,
|
||||||
|
readyToUse: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectedListCalls: []listCall{{"sid1-1", true, time.Now(), 1, nil}},
|
||||||
|
errors: noerrors,
|
||||||
|
test: testSyncContent,
|
||||||
|
})
|
||||||
|
|
||||||
|
runSyncContentTests(t, tests, snapshotClasses)
|
||||||
|
}
|
1025
pkg/sidecar-controller/framework_test.go
Normal file
1025
pkg/sidecar-controller/framework_test.go
Normal file
File diff suppressed because it is too large
Load Diff
91
pkg/sidecar-controller/snapshot_controller_test.go
Normal file
91
pkg/sidecar-controller/snapshot_controller_test.go
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2019 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 sidecar_controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
crdv1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1beta1"
|
||||||
|
"github.com/kubernetes-csi/external-snapshotter/pkg/utils"
|
||||||
|
"k8s.io/client-go/tools/cache"
|
||||||
|
)
|
||||||
|
|
||||||
|
var deletionPolicy = crdv1.VolumeSnapshotContentDelete
|
||||||
|
|
||||||
|
func storeVersion(t *testing.T, prefix string, c cache.Store, version string, expectedReturn bool) {
|
||||||
|
content := newContent("contentName", "snapuid1-1", "snap1-1", "sid1-1", classGold, "", "pv-handle-1-1", deletionPolicy, nil, nil, false, nil)
|
||||||
|
content.ResourceVersion = version
|
||||||
|
ret, err := utils.StoreObjectUpdate(c, content, "content")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("%s: expected storeObjectUpdate to succeed, got: %v", prefix, err)
|
||||||
|
}
|
||||||
|
if expectedReturn != ret {
|
||||||
|
t.Errorf("%s: expected storeObjectUpdate to return %v, got: %v", prefix, expectedReturn, ret)
|
||||||
|
}
|
||||||
|
|
||||||
|
// find the stored version
|
||||||
|
|
||||||
|
contentObj, found, err := c.GetByKey("contentName")
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("expected content 'contentName' in the cache, got error instead: %v", err)
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
t.Errorf("expected content 'contentName' in the cache but it was not found")
|
||||||
|
}
|
||||||
|
content, ok := contentObj.(*crdv1.VolumeSnapshotContent)
|
||||||
|
if !ok {
|
||||||
|
t.Errorf("expected content in the cache, got different object instead: %#v", contentObj)
|
||||||
|
}
|
||||||
|
|
||||||
|
if ret {
|
||||||
|
if content.ResourceVersion != version {
|
||||||
|
t.Errorf("expected content with version %s in the cache, got %s instead", version, content.ResourceVersion)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if content.ResourceVersion == version {
|
||||||
|
t.Errorf("expected content with version other than %s in the cache, got %s instead", version, content.ResourceVersion)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestControllerCache tests func storeObjectUpdate()
|
||||||
|
func TestControllerCache(t *testing.T) {
|
||||||
|
// Cache under test
|
||||||
|
c := cache.NewStore(cache.DeletionHandlingMetaNamespaceKeyFunc)
|
||||||
|
|
||||||
|
// Store new PV
|
||||||
|
storeVersion(t, "Step1", c, "1", true)
|
||||||
|
// Store the same PV
|
||||||
|
storeVersion(t, "Step2", c, "1", true)
|
||||||
|
// Store newer PV
|
||||||
|
storeVersion(t, "Step3", c, "2", true)
|
||||||
|
// Store older PV - simulating old "PV updated" event or periodic sync with
|
||||||
|
// old data
|
||||||
|
storeVersion(t, "Step4", c, "1", false)
|
||||||
|
// Store newer PV - test integer parsing ("2" > "10" as string,
|
||||||
|
// while 2 < 10 as integers)
|
||||||
|
storeVersion(t, "Step5", c, "10", true)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestControllerCacheParsingError(t *testing.T) {
|
||||||
|
c := cache.NewStore(cache.DeletionHandlingMetaNamespaceKeyFunc)
|
||||||
|
// There must be something in the cache to compare with
|
||||||
|
storeVersion(t, "Step1", c, "1", true)
|
||||||
|
content := newContent("contentName", "snapuid1-1", "snap1-1", "sid1-1", classGold, "", "pv-handle-1-1", deletionPolicy, nil, nil, false, nil)
|
||||||
|
content.ResourceVersion = "xxx"
|
||||||
|
_, err := utils.StoreObjectUpdate(c, content, "content")
|
||||||
|
if err == nil {
|
||||||
|
t.Errorf("Expected parsing error, got nil instead")
|
||||||
|
}
|
||||||
|
}
|
440
pkg/sidecar-controller/snapshot_delete_test.go
Normal file
440
pkg/sidecar-controller/snapshot_delete_test.go
Normal file
@@ -0,0 +1,440 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2019 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 sidecar_controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
crdv1 "github.com/kubernetes-csi/external-snapshotter/pkg/apis/volumesnapshot/v1beta1"
|
||||||
|
"github.com/kubernetes-csi/external-snapshotter/pkg/utils"
|
||||||
|
"k8s.io/api/core/v1"
|
||||||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
|
)
|
||||||
|
|
||||||
|
var defaultSize int64 = 1000
|
||||||
|
var emptySize int64 = 0
|
||||||
|
var deletePolicy = crdv1.VolumeSnapshotContentDelete
|
||||||
|
var retainPolicy = crdv1.VolumeSnapshotContentRetain
|
||||||
|
var timeNow = time.Now()
|
||||||
|
var timeNowMetav1 = metav1.Now()
|
||||||
|
var False = false
|
||||||
|
var True = true
|
||||||
|
|
||||||
|
var class1Parameters = map[string]string{
|
||||||
|
"param1": "value1",
|
||||||
|
}
|
||||||
|
|
||||||
|
var class2Parameters = map[string]string{
|
||||||
|
"param2": "value2",
|
||||||
|
}
|
||||||
|
|
||||||
|
var class3Parameters = map[string]string{
|
||||||
|
"param3": "value3",
|
||||||
|
utils.AnnDeletionSecretRefName: "name",
|
||||||
|
}
|
||||||
|
|
||||||
|
var class4Parameters = map[string]string{
|
||||||
|
utils.AnnDeletionSecretRefName: "emptysecret",
|
||||||
|
utils.AnnDeletionSecretRefNamespace: "default",
|
||||||
|
}
|
||||||
|
|
||||||
|
var class5Parameters = map[string]string{
|
||||||
|
utils.AnnDeletionSecretRefName: "secret",
|
||||||
|
utils.AnnDeletionSecretRefNamespace: "default",
|
||||||
|
}
|
||||||
|
|
||||||
|
var snapshotClasses = []*crdv1.VolumeSnapshotClass{
|
||||||
|
{
|
||||||
|
TypeMeta: metav1.TypeMeta{
|
||||||
|
Kind: "VolumeSnapshotClass",
|
||||||
|
},
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: classGold,
|
||||||
|
},
|
||||||
|
Driver: mockDriverName,
|
||||||
|
Parameters: class1Parameters,
|
||||||
|
DeletionPolicy: crdv1.VolumeSnapshotContentDelete,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
TypeMeta: metav1.TypeMeta{
|
||||||
|
Kind: "VolumeSnapshotClass",
|
||||||
|
},
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: classSilver,
|
||||||
|
},
|
||||||
|
Driver: mockDriverName,
|
||||||
|
Parameters: class2Parameters,
|
||||||
|
DeletionPolicy: crdv1.VolumeSnapshotContentDelete,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
TypeMeta: metav1.TypeMeta{
|
||||||
|
Kind: "VolumeSnapshotClass",
|
||||||
|
},
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: emptySecretClass,
|
||||||
|
},
|
||||||
|
Driver: mockDriverName,
|
||||||
|
Parameters: class4Parameters,
|
||||||
|
DeletionPolicy: crdv1.VolumeSnapshotContentDelete,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
TypeMeta: metav1.TypeMeta{
|
||||||
|
Kind: "VolumeSnapshotClass",
|
||||||
|
},
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: invalidSecretClass,
|
||||||
|
},
|
||||||
|
Driver: mockDriverName,
|
||||||
|
Parameters: class3Parameters,
|
||||||
|
DeletionPolicy: crdv1.VolumeSnapshotContentDelete,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
TypeMeta: metav1.TypeMeta{
|
||||||
|
Kind: "VolumeSnapshotClass",
|
||||||
|
},
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: validSecretClass,
|
||||||
|
},
|
||||||
|
Driver: mockDriverName,
|
||||||
|
Parameters: class5Parameters,
|
||||||
|
DeletionPolicy: crdv1.VolumeSnapshotContentDelete,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
TypeMeta: metav1.TypeMeta{
|
||||||
|
Kind: "VolumeSnapshotClass",
|
||||||
|
},
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: defaultClass,
|
||||||
|
Annotations: map[string]string{utils.IsDefaultSnapshotClassAnnotation: "true"},
|
||||||
|
},
|
||||||
|
Driver: mockDriverName,
|
||||||
|
DeletionPolicy: crdv1.VolumeSnapshotContentDelete,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
// Test single call to syncContent, expecting deleting to happen.
|
||||||
|
// 1. Fill in the controller with initial data
|
||||||
|
// 2. Call the syncContent *once*.
|
||||||
|
// 3. Compare resulting contents with expected contents.
|
||||||
|
func TestDeleteSync(t *testing.T) {
|
||||||
|
|
||||||
|
tests := []controllerTest{
|
||||||
|
{
|
||||||
|
name: "1-1 - content non-nil DeletionTimestamp with delete policy will delete snapshot",
|
||||||
|
initialContents: newContentArrayWithDeletionTimestamp("content1-1", "snapuid1-1", "snap1-1", "sid1-1", classGold, "", "snap1-1-volumehandle", deletionPolicy, nil, nil, true, &timeNowMetav1),
|
||||||
|
expectedContents: newContentArrayWithDeletionTimestamp("content1-1", "snapuid1-1", "snap1-1", "sid1-1", classGold, "", "snap1-1-volumehandle", deletionPolicy, nil, nil, false, &timeNowMetav1),
|
||||||
|
expectedEvents: noevents,
|
||||||
|
errors: noerrors,
|
||||||
|
initialSecrets: []*v1.Secret{secret()},
|
||||||
|
expectedCreateCalls: []createCall{
|
||||||
|
{
|
||||||
|
snapshotName: "snapshot-snapuid1-1",
|
||||||
|
volumeHandle: "snap1-1-volumehandle",
|
||||||
|
parameters: map[string]string{"param1": "value1"},
|
||||||
|
driverName: mockDriverName,
|
||||||
|
size: defaultSize,
|
||||||
|
snapshotId: "snapuid1-1-deleted",
|
||||||
|
creationTime: timeNow,
|
||||||
|
readyToUse: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectedListCalls: []listCall{{"sid1-1", true, time.Now(), 1, nil}},
|
||||||
|
expectedDeleteCalls: []deleteCall{{"sid1-1", nil, nil}},
|
||||||
|
test: testSyncContent,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "1-2 - content non-nil DeletionTimestamp with retain policy will not delete snapshot",
|
||||||
|
initialContents: newContentArrayWithDeletionTimestamp("content1-2", "snapuid1-2", "snap1-2", "sid1-2", classGold, "", "snap1-2-volumehandle", retainPolicy, nil, nil, true, &timeNowMetav1),
|
||||||
|
expectedContents: newContentArrayWithDeletionTimestamp("content1-2", "snapuid1-2", "snap1-2", "sid1-2", classGold, "", "snap1-2-volumehandle", retainPolicy, nil, nil, false, &timeNowMetav1),
|
||||||
|
expectedEvents: noevents,
|
||||||
|
errors: noerrors,
|
||||||
|
expectedCreateCalls: []createCall{
|
||||||
|
{
|
||||||
|
snapshotName: "snapshot-snapuid1-2",
|
||||||
|
volumeHandle: "snap1-2-volumehandle",
|
||||||
|
parameters: map[string]string{"param1": "value1"},
|
||||||
|
driverName: mockDriverName,
|
||||||
|
size: defaultSize,
|
||||||
|
snapshotId: "snapuid1-2-deleted",
|
||||||
|
creationTime: timeNow,
|
||||||
|
readyToUse: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectedListCalls: []listCall{{"sid1-2", true, time.Now(), 1, nil}},
|
||||||
|
expectedDeleteCalls: []deleteCall{{"sid1-2", nil, nil}},
|
||||||
|
test: testSyncContent,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "1-3 - delete snapshot error should result in an event",
|
||||||
|
initialContents: newContentArrayWithDeletionTimestamp("content1-3", "snapuid1-3", "snap1-3", "sid1-3", validSecretClass, "", "snap1-3-volumehandle", deletePolicy, nil, nil, true, &timeNowMetav1),
|
||||||
|
expectedContents: newContentArrayWithDeletionTimestamp("content1-3", "snapuid1-3", "snap1-3", "sid1-3", validSecretClass, "", "snap1-3-volumehandle", deletePolicy, nil, nil, false, &timeNowMetav1),
|
||||||
|
errors: noerrors,
|
||||||
|
expectedCreateCalls: []createCall{
|
||||||
|
{
|
||||||
|
snapshotName: "snapshot-snapuid1-3",
|
||||||
|
volumeHandle: "snap1-3-volumehandle",
|
||||||
|
parameters: map[string]string{"foo": "bar"},
|
||||||
|
driverName: mockDriverName,
|
||||||
|
size: defaultSize,
|
||||||
|
snapshotId: "snapuid1-3-deleted",
|
||||||
|
creationTime: timeNow,
|
||||||
|
readyToUse: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectedDeleteCalls: []deleteCall{{"sid1-3", nil, fmt.Errorf("mock csi driver delete error")}},
|
||||||
|
expectedEvents: []string{"Warning SnapshotDeleteError"},
|
||||||
|
expectedListCalls: []listCall{{"sid1-3", true, time.Now(), 1, nil}},
|
||||||
|
test: testSyncContent,
|
||||||
|
},
|
||||||
|
/*{
|
||||||
|
name: "1-4 - create snapshot error should result in an event",
|
||||||
|
initialContents: newContentArrayWithDeletionTimestamp("content1-4", "snapuid1-4", "snap1-4", "sid1-4", classGold, "", "snap1-4-volumehandle", deletePolicy, nil, nil, true, nil),
|
||||||
|
//expectedContents: newContentArrayWithDeletionTimestamp("content1-4", "snapuid1-4", "snap1-4", "sid1-4", classGold, "", "snap1-4-volumehandle", deletePolicy, nil, nil, true, nil),
|
||||||
|
errors: []reactorError{},
|
||||||
|
expectedCreateCalls: []createCall{
|
||||||
|
{
|
||||||
|
snapshotName: "snapshot-snapuid1-4",
|
||||||
|
volumeHandle: "snap1-4-volumehandle",
|
||||||
|
parameters: map[string]string{"param1": "value1"},
|
||||||
|
err: fmt.Errorf("Create failed"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
//expectedDeleteCalls: []deleteCall{{"sid1-4", nil, nil}},
|
||||||
|
expectedListCalls: []listCall{{"sid1-4", true, time.Now(), 1, nil}},
|
||||||
|
expectedEvents: []string{"Warning SnapshotContentCheckandUpdateFailed Failed to check and update snapshot content: Create failed"},
|
||||||
|
test: testSyncContent,
|
||||||
|
},*/
|
||||||
|
/*{
|
||||||
|
name: "2-1 - content with empty snapshot class will not be deleted if it is bound to a non-exist snapshot but it does not have a snapshot uid specified",
|
||||||
|
initialContents: newContentArray("content2-1", "", "snap2-1", "sid2-1", "", "", "", deletionPolicy, nil, nil, true),
|
||||||
|
expectedContents: newContentArray("content2-1", "", "snap2-1", "sid2-1", "", "", "", deletionPolicy, nil, nil, true),
|
||||||
|
expectedEvents: noevents,
|
||||||
|
errors: noerrors,
|
||||||
|
expectedDeleteCalls: []deleteCall{{"sid2-1", nil, nil}},
|
||||||
|
test: testSyncContent,
|
||||||
|
},*/
|
||||||
|
/*{
|
||||||
|
name: "1-2 - successful delete with snapshot class that has empty secret parameter",
|
||||||
|
initialContents: newContentArray("content1-2", "sid1-2", "snap1-2", "sid1-2", emptySecretClass, "", "volumeHandle", deletionPolicy, nil, nil, true),
|
||||||
|
expectedContents: nocontents,
|
||||||
|
initialSnapshots: nosnapshots,
|
||||||
|
expectedSnapshots: nosnapshots,
|
||||||
|
initialSecrets: []*v1.Secret{emptySecret()},
|
||||||
|
expectedEvents: noevents,
|
||||||
|
errors: noerrors,
|
||||||
|
expectedDeleteCalls: []deleteCall{{"sid1-2", map[string]string{}, nil}},
|
||||||
|
test: testSyncContent,
|
||||||
|
},*/
|
||||||
|
/*{
|
||||||
|
name: "1-3 - content non-nil DeletionTimestamp with delete policy will delete snapshot",
|
||||||
|
initialContents: newContentArrayWithDeletionTimestamp("content1-3", "snapuid1-1", "snap1-1", "sid1-3", classGold, "", "snap1-3-volumehandle", deletionPolicy, nil, nil, true, &timeNowMetav1),
|
||||||
|
expectedContents: newContentArrayWithDeletionTimestamp("content1-3", "snapuid1-1", "snap1-1", "sid1-3", classGold, "", "snap1-3-volumehandle", deletionPolicy, nil, nil, false, &timeNowMetav1),
|
||||||
|
initialSnapshots: newSnapshotArray("snap1-3", "snapuid1-3", "claim1-3", "", validSecretClass, "", &False, nil, nil, nil),
|
||||||
|
expectedSnapshots: newSnapshotArray("snap1-3", "snapuid1-3", "claim1-3", "", validSecretClass, "", &False, nil, nil, nil),
|
||||||
|
expectedEvents: noevents,
|
||||||
|
errors: noerrors,
|
||||||
|
initialSecrets: []*v1.Secret{secret()},
|
||||||
|
expectedCreateCalls: []createCall{
|
||||||
|
{
|
||||||
|
snapshotName: "snapshot-snapuid1-1",
|
||||||
|
volumeHandle: "snap1-1-volumehandle",
|
||||||
|
parameters: map[string]string{"param1": "value1"},
|
||||||
|
driverName: mockDriverName,
|
||||||
|
size: defaultSize,
|
||||||
|
snapshotId: "snapuid1-1-deleted",
|
||||||
|
creationTime: timeNow,
|
||||||
|
readyToUse: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectedListCalls: []listCall{{"sid1-1", true, time.Now(), 1, nil}},
|
||||||
|
expectedDeleteCalls: []deleteCall{{"sid1-1", nil, nil}},
|
||||||
|
test: testSyncContent,
|
||||||
|
},*/
|
||||||
|
|
||||||
|
/* name: "1-3 - successful delete with snapshot class that has valid secret parameter",
|
||||||
|
initialContents: newContentArray("content1-3", "sid1-3", "snap1-3", "sid1-3", validSecretClass, "", "snap1-3-volumehandle", deletionPolicy, nil, nil, true),
|
||||||
|
expectedContents: newContentArray("content1-3", "sid1-3", "snap1-3", "sid1-3", validSecretClass, "", "snap1-3-volumehandle", deletionPolicy, nil, nil, false),
|
||||||
|
initialSnapshots: newSnapshotArray("snapshot-snapuid1-3", "snapuid1-3", "claim1-3", "", validSecretClass, "", &False, nil, nil, nil),
|
||||||
|
expectedSnapshots: newSnapshotArray("snapshot-snapuid1-3", "snapuid1-3", "claim1-3", "", validSecretClass, "", &False, nil, nil, nil),
|
||||||
|
expectedEvents: noevents,
|
||||||
|
errors: noerrors,
|
||||||
|
initialSecrets: []*v1.Secret{secret()},
|
||||||
|
expectedCreateCalls: []createCall{
|
||||||
|
{
|
||||||
|
snapshotName: "snap1-3",
|
||||||
|
volumeHandle: "snap1-3-volumehandle",
|
||||||
|
parameters: map[string]string{"param1": "value1"},
|
||||||
|
driverName: mockDriverName,
|
||||||
|
size: defaultSize,
|
||||||
|
snapshotId: "sid1-3",
|
||||||
|
creationTime: timeNow,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectedListCalls: []listCall{{"sid1-3", true, time.Now(), 1, nil}},
|
||||||
|
expectedDeleteCalls: []deleteCall{{"sid1-3", map[string]string{"param1": "value1"}, nil}},
|
||||||
|
test: testSyncContent,
|
||||||
|
},
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
name: "1-4 - fail delete with snapshot class that has invalid secret parameter",
|
||||||
|
initialContents: newContentArrayWithDeletionTimestamp("content1-1", "snapuid1-1", "snap1-1", "sid1-1", "invalid", "", "snap1-1-volumehandle", deletionPolicy, nil, nil, true, &timeNowMetav1),
|
||||||
|
expectedContents: newContentArrayWithDeletionTimestamp("content1-1", "snapuid1-1", "snap1-1", "sid1-1", "invalid", "", "snap1-1-volumehandle", deletionPolicy, nil, nil, false, &timeNowMetav1),
|
||||||
|
expectedEvents: noevents,
|
||||||
|
errors: noerrors,
|
||||||
|
test: testSyncContent,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "1-5 - csi driver delete snapshot returns error",
|
||||||
|
initialContents: newContentArrayWithDeletionTimestamp("content1-5", "sid1-5", "snap1-5", "sid1-5", validSecretClass, "", "", deletionPolicy, nil, &defaultSize, true, &timeNowMetav1),
|
||||||
|
expectedContents: newContentArrayWithDeletionTimestamp("content1-5", "sid1-5", "snap1-5", "sid1-5", validSecretClass, "", "", deletionPolicy, nil, &defaultSize, false, &timeNowMetav1),
|
||||||
|
expectedListCalls: []listCall{{"sid1-5", true, time.Now(), 1000, nil}},
|
||||||
|
expectedDeleteCalls: []deleteCall{{"sid1-5", nil, 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", classGold, "", "", deletionPolicy, nil, nil, true),
|
||||||
|
//expectedContents: newContentArray("content1-6", "sid1-6", "snap1-6", "sid1-6", classGold, "", "", deletionPolicy, nil, nil, true),
|
||||||
|
expectedDeleteCalls: []deleteCall{{"sid1-6", map[string]string{"foo": "bar"}, nil}},
|
||||||
|
expectedListCalls: []listCall{{"sid1-6", false, time.Now(), 0, nil}},
|
||||||
|
expectedEvents: []string{"Warning SnapshotContentObjectDeleteError"},
|
||||||
|
errors: []reactorError{
|
||||||
|
// Inject error to the first client.VolumesnapshotV1beta1().VolumeSnapshotContents().Delete call.
|
||||||
|
// All other calls will succeed.
|
||||||
|
{"delete", "volumesnapshotcontents", errors.New("mock delete error")},
|
||||||
|
},
|
||||||
|
test: testSyncContent,
|
||||||
|
},*/
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
// delete success - snapshot that the content was pointing to was deleted, and another
|
||||||
|
// with the same name created.
|
||||||
|
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: nocontents,
|
||||||
|
initialSecrets: []*v1.Secret{secret()},
|
||||||
|
expectedDeleteCalls: []deleteCall{{"sid1-7", map[string]string{"foo": "bar"}, nil}},
|
||||||
|
expectedEvents: noevents,
|
||||||
|
errors: noerrors,
|
||||||
|
test: testSyncContent,
|
||||||
|
},*/
|
||||||
|
{
|
||||||
|
// delete success(?) - content is deleted before doDelete() starts
|
||||||
|
name: "1-8 - content is deleted before deleting",
|
||||||
|
initialContents: newContentArray("content1-8", "sid1-8", "snap1-8", "sid1-8", classGold, "", "", deletionPolicy, nil, nil, true),
|
||||||
|
expectedContents: nocontents,
|
||||||
|
expectedListCalls: []listCall{{"sid1-8", false, time.Now(), 0, nil}},
|
||||||
|
expectedDeleteCalls: []deleteCall{{"sid1-8", map[string]string{"foo": "bar"}, nil}},
|
||||||
|
expectedEvents: noevents,
|
||||||
|
errors: noerrors,
|
||||||
|
test: wrapTestWithInjectedOperation(testSyncContent, func(ctrl *csiSnapshotSideCarController, reactor *snapshotReactor) {
|
||||||
|
// Delete the volume before delete operation starts
|
||||||
|
reactor.lock.Lock()
|
||||||
|
delete(reactor.contents, "content1-8")
|
||||||
|
reactor.lock.Unlock()
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
/*{
|
||||||
|
name: "1-9 - content will not be deleted if it is bound to a snapshot correctly, snapshot uid is specified",
|
||||||
|
expectedContents: newContentArrayWithDeletionTimestamp("content1-9", "snapuid1-9", "snap1-9", "sid1-9", classGold, "", "snap1-9-volumehandle", retainPolicy, nil, nil, false, &timeNowMetav1),
|
||||||
|
initialContents: newContentArrayWithDeletionTimestamp("content1-9", "snapuid1-9", "snap1-9", "sid1-9", classGold, "", "snap1-9-volumehandle", retainPolicy, nil, nil, false, &timeNowMetav1),
|
||||||
|
expectedEvents: noevents,
|
||||||
|
expectedListCalls: []listCall{{"sid1-9", true, time.Now(), 0, nil}},
|
||||||
|
initialSecrets: []*v1.Secret{secret()},
|
||||||
|
errors: noerrors,
|
||||||
|
test: testSyncContent,
|
||||||
|
},*/
|
||||||
|
/*
|
||||||
|
{
|
||||||
|
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),
|
||||||
|
expectedSnapshots: newSnapshotArray("snap1-10", "snapuid1-10", "claim1-10", "", validSecretClass, "content1-10", &False, nil, nil, nil),
|
||||||
|
expectedEvents: noevents,
|
||||||
|
initialSecrets: []*v1.Secret{secret()},
|
||||||
|
errors: noerrors,
|
||||||
|
test: testSyncContent,
|
||||||
|
},*/
|
||||||
|
{
|
||||||
|
name: "1-11 - content will not be deleted if it is bound to a snapshot correctly, snapsht uid is not specified",
|
||||||
|
initialContents: newContentArrayWithReadyToUse("content1-11", "", "snap1-11", "sid1-11", validSecretClass, "", "", deletePolicy, nil, &defaultSize, &True, true),
|
||||||
|
expectedContents: newContentArrayWithReadyToUse("content1-11", "", "snap1-11", "sid1-11", validSecretClass, "", "", deletePolicy, nil, &defaultSize, &True, true),
|
||||||
|
expectedEvents: noevents,
|
||||||
|
expectedCreateCalls: []createCall{
|
||||||
|
{
|
||||||
|
snapshotName: "snap1-11",
|
||||||
|
volumeHandle: "snap1-11",
|
||||||
|
parameters: map[string]string{"param1": "value1"},
|
||||||
|
driverName: mockDriverName,
|
||||||
|
size: defaultSize,
|
||||||
|
snapshotId: "snapuid1-1-deleted",
|
||||||
|
creationTime: timeNow,
|
||||||
|
readyToUse: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
expectedListCalls: []listCall{{"sid1-11", true, time.Now(), 1000, nil}},
|
||||||
|
initialSecrets: []*v1.Secret{secret()},
|
||||||
|
errors: noerrors,
|
||||||
|
test: testSyncContent,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "1-12 - content with retain policy will not be deleted if it is bound to a non-exist snapshot and also has a snapshot uid specified",
|
||||||
|
initialContents: newContentArrayWithReadyToUse("content1-12", "sid1-12", "snap1-11", "sid1-11", validSecretClass, "", "", retainPolicy, nil, &defaultSize, &True, true),
|
||||||
|
expectedContents: newContentArrayWithReadyToUse("content1-12", "sid1-12", "snap1-11", "sid1-11", validSecretClass, "", "", retainPolicy, nil, &defaultSize, &True, true),
|
||||||
|
expectedEvents: noevents,
|
||||||
|
expectedListCalls: []listCall{{"sid1-11", true, time.Now(), 0, nil}},
|
||||||
|
errors: noerrors,
|
||||||
|
test: testSyncContent,
|
||||||
|
},
|
||||||
|
/*{
|
||||||
|
name: "1-13 - content with empty snapshot class is not deleted when Deletion policy is not set even if it is bound to a non-exist snapshot and also has a snapshot uid specified",
|
||||||
|
initialContents: newContentArray("content1-13", "sid1-13", "snap1-13", "sid1-13", validSecretClass, "", "", retainPolicy, nil, nil, true),
|
||||||
|
expectedContents: newContentArray("content1-13", "sid1-13", "snap1-13", "sid1-13", validSecretClass, "", "", retainPolicy, nil, nil, true),
|
||||||
|
expectedEvents: noevents,
|
||||||
|
errors: noerrors,
|
||||||
|
test: testSyncContent,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "1-14 - content will not be deleted if it is bound to a snapshot correctly, snapshot uid is specified",
|
||||||
|
initialContents: newContentArray("content1-14", "snapuid1-14", "snap1-14", "sid1-14", validSecretClass, "", "", retainPolicy, nil, nil, true),
|
||||||
|
expectedContents: newContentArray("content1-14", "snapuid1-14", "snap1-14", "sid1-14", validSecretClass, "", "", retainPolicy, nil, nil, true),
|
||||||
|
expectedEvents: noevents,
|
||||||
|
initialSecrets: []*v1.Secret{secret()},
|
||||||
|
errors: noerrors,
|
||||||
|
test: testSyncContent,
|
||||||
|
},*/
|
||||||
|
{
|
||||||
|
name: "1-16 - continue delete with snapshot class that has nonexistent secret",
|
||||||
|
initialContents: newContentArrayWithDeletionTimestamp("content1-16", "sid1-16", "snap1-16", "sid1-16", emptySecretClass, "", "", deletePolicy, nil, &defaultSize, true, &timeNowMetav1),
|
||||||
|
expectedContents: newContentArrayWithDeletionTimestamp("content1-16", "sid1-16", "snap1-16", "sid1-16", emptySecretClass, "", "", deletePolicy, nil, &defaultSize, false, &timeNowMetav1),
|
||||||
|
expectedEvents: noevents,
|
||||||
|
expectedListCalls: []listCall{{"sid1-16", true, time.Now(), 0, nil}},
|
||||||
|
errors: noerrors,
|
||||||
|
initialSecrets: []*v1.Secret{}, // secret does not exist
|
||||||
|
expectedDeleteCalls: []deleteCall{{"sid1-16", nil, nil}},
|
||||||
|
test: testSyncContent,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
runSyncContentTests(t, tests, snapshotClasses)
|
||||||
|
}
|
34
pkg/sidecar-controller/snapshot_finalizer_test.go
Normal file
34
pkg/sidecar-controller/snapshot_finalizer_test.go
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2019 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 sidecar_controller
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
// Test single call to ensureSnapshotSourceFinalizer and checkandRemoveSnapshotSourceFinalizer,
|
||||||
|
// expecting PVCFinalizer to be added or removed
|
||||||
|
func TestContentFinalizer(t *testing.T) {
|
||||||
|
|
||||||
|
// GG TODO - add content finalizer tests
|
||||||
|
/*
|
||||||
|
tests := []controllerTest{
|
||||||
|
{},
|
||||||
|
}
|
||||||
|
runPVCFinalizerTests(t, tests, snapshotClasses)
|
||||||
|
*/
|
||||||
|
}
|
Reference in New Issue
Block a user