mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 11:50:44 +00:00
recycler: unit tests
- Add reclaim policy to newVolume() call. - Implement reactor Volumes().Get(). - Implement mock volume plugin. - Add recycler tests. - Add a synchronization condition to controller.scheduleOperation - we need to pause the controller here, let the test to do some bad things to the controller and test error cases in recycleVolumeOperation. Test framework gets more and more complicated... But this is the last piece, I promise.
This commit is contained in:
parent
a08d826ca5
commit
22e68d4622
@ -108,6 +108,10 @@ type PersistentVolumeController struct {
|
||||
// runningOperations is map of running operations. The value does not
|
||||
// matter, presence of a key is enough to consider an operation running.
|
||||
runningOperations map[string]bool
|
||||
|
||||
// For testing only: hook to call before an asynchronous operation starts.
|
||||
// Not used when set to nil.
|
||||
preOperationHook func(operationName string, operationArgument interface{})
|
||||
}
|
||||
|
||||
// NewPersistentVolumeController creates a new PersistentVolumeController
|
||||
@ -1184,6 +1188,11 @@ func (ctrl *PersistentVolumeController) isVolumeReleased(volume *api.PersistentV
|
||||
func (ctrl *PersistentVolumeController) scheduleOperation(operationName string, operation func(arg interface{}), arg interface{}) {
|
||||
glog.V(4).Infof("scheduleOperation[%s]", operationName)
|
||||
|
||||
// Poke test code that an operation is just about to get started.
|
||||
if ctrl.preOperationHook != nil {
|
||||
ctrl.preOperationHook(operationName, arg)
|
||||
}
|
||||
|
||||
isRunning := func() bool {
|
||||
// In anonymous func() to get the locking right.
|
||||
ctrl.runningOperationsMapLock.Lock()
|
||||
|
@ -45,13 +45,13 @@ func TestControllerSync(t *testing.T) {
|
||||
// syncClaim, not on addVolume.
|
||||
"5-1 - addVolume",
|
||||
novolumes, /* added in testCall below */
|
||||
newVolumeArray("volume5-1", "10Gi", "", "", api.VolumeAvailable),
|
||||
newVolumeArray("volume5-1", "10Gi", "", "", api.VolumeAvailable, api.PersistentVolumeReclaimRetain),
|
||||
newClaimArray("claim5-1", "uid5-1", "1Gi", "", api.ClaimPending),
|
||||
newClaimArray("claim5-1", "uid5-1", "1Gi", "", api.ClaimPending),
|
||||
noevents,
|
||||
// Custom test function that generates an add event
|
||||
func(ctrl *PersistentVolumeController, reactor *volumeReactor, test controllerTest) error {
|
||||
volume := newVolume("volume5-1", "10Gi", "", "", api.VolumePending)
|
||||
volume := newVolume("volume5-1", "10Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain)
|
||||
reactor.volumes[volume.Name] = volume
|
||||
reactor.volumeSource.Add(volume)
|
||||
return nil
|
||||
@ -60,8 +60,8 @@ func TestControllerSync(t *testing.T) {
|
||||
{
|
||||
// addClaim gets a new claim. Check it's bound to a volume.
|
||||
"5-2 - complete bind",
|
||||
newVolumeArray("volume5-2", "10Gi", "", "", api.VolumeAvailable),
|
||||
newVolumeArray("volume5-2", "10Gi", "uid5-2", "claim5-2", api.VolumeBound, annBoundByController),
|
||||
newVolumeArray("volume5-2", "10Gi", "", "", api.VolumeAvailable, api.PersistentVolumeReclaimRetain),
|
||||
newVolumeArray("volume5-2", "10Gi", "uid5-2", "claim5-2", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController),
|
||||
noclaims, /* added in testAddClaim5_2 */
|
||||
newClaimArray("claim5-2", "uid5-2", "1Gi", "volume5-2", api.ClaimBound, annBoundByController, annBindCompleted),
|
||||
noevents,
|
||||
@ -76,8 +76,8 @@ func TestControllerSync(t *testing.T) {
|
||||
{
|
||||
// deleteClaim with a bound claim makes bound volume released.
|
||||
"5-3 - delete claim",
|
||||
newVolumeArray("volume5-3", "10Gi", "uid5-3", "claim5-3", api.VolumeBound, annBoundByController),
|
||||
newVolumeArray("volume5-3", "10Gi", "uid5-3", "claim5-3", api.VolumeReleased, annBoundByController),
|
||||
newVolumeArray("volume5-3", "10Gi", "uid5-3", "claim5-3", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController),
|
||||
newVolumeArray("volume5-3", "10Gi", "uid5-3", "claim5-3", api.VolumeReleased, api.PersistentVolumeReclaimRetain, annBoundByController),
|
||||
newClaimArray("claim5-3", "uid5-3", "1Gi", "volume5-3", api.ClaimBound, annBoundByController, annBindCompleted),
|
||||
noclaims,
|
||||
noevents,
|
||||
@ -99,7 +99,7 @@ func TestControllerSync(t *testing.T) {
|
||||
{
|
||||
// deleteVolume with a bound volume. Check the claim is Lost.
|
||||
"5-4 - delete volume",
|
||||
newVolumeArray("volume5-4", "10Gi", "uid5-4", "claim5-4", api.VolumeBound),
|
||||
newVolumeArray("volume5-4", "10Gi", "uid5-4", "claim5-4", api.VolumeBound, api.PersistentVolumeReclaimRetain),
|
||||
novolumes,
|
||||
newClaimArray("claim5-4", "uid5-4", "1Gi", "volume5-4", api.ClaimBound, annBoundByController, annBindCompleted),
|
||||
newClaimArray("claim5-4", "uid5-4", "1Gi", "volume5-4", api.ClaimLost, annBoundByController, annBindCompleted),
|
||||
|
@ -23,6 +23,7 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
@ -41,6 +42,7 @@ import (
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/types"
|
||||
"k8s.io/kubernetes/pkg/util/diff"
|
||||
vol "k8s.io/kubernetes/pkg/volume"
|
||||
)
|
||||
|
||||
// This is a unit test framework for persistent volume controller.
|
||||
@ -185,6 +187,17 @@ func (r *volumeReactor) React(action core.Action) (handled bool, ret runtime.Obj
|
||||
r.changedSinceLastSync++
|
||||
glog.V(4).Infof("saved updated claim %s", claim.Name)
|
||||
return true, claim, nil
|
||||
|
||||
case action.Matches("get", "persistentvolumes"):
|
||||
name := action.(core.GetAction).GetName()
|
||||
volume, found := r.volumes[name]
|
||||
if found {
|
||||
glog.V(4).Infof("GetVolume: found %s", volume.Name)
|
||||
return true, volume, nil
|
||||
} else {
|
||||
glog.V(4).Infof("GetVolume: volume %s not found", name)
|
||||
return true, nil, fmt.Errorf("Cannot find volume %s", name)
|
||||
}
|
||||
}
|
||||
return false, nil, nil
|
||||
}
|
||||
@ -382,16 +395,31 @@ func newVolumeReactor(client *fake.Clientset, ctrl *PersistentVolumeController,
|
||||
|
||||
func newPersistentVolumeController(kubeClient clientset.Interface) *PersistentVolumeController {
|
||||
ctrl := &PersistentVolumeController{
|
||||
volumes: newPersistentVolumeOrderedIndex(),
|
||||
claims: cache.NewStore(cache.MetaNamespaceKeyFunc),
|
||||
kubeClient: kubeClient,
|
||||
eventRecorder: record.NewFakeRecorder(1000),
|
||||
volumes: newPersistentVolumeOrderedIndex(),
|
||||
claims: cache.NewStore(cache.MetaNamespaceKeyFunc),
|
||||
kubeClient: kubeClient,
|
||||
eventRecorder: record.NewFakeRecorder(1000),
|
||||
runningOperations: make(map[string]bool),
|
||||
}
|
||||
return ctrl
|
||||
}
|
||||
|
||||
func addRecyclePlugin(ctrl *PersistentVolumeController, expectedRecycleCalls []error) {
|
||||
plugin := &mockVolumePlugin{
|
||||
recycleCalls: expectedRecycleCalls,
|
||||
}
|
||||
ctrl.recyclePluginMgr.InitPlugins([]vol.VolumePlugin{plugin}, ctrl)
|
||||
}
|
||||
|
||||
func addDeletePlugin(ctrl *PersistentVolumeController, expectedDeleteCalls []error) {
|
||||
plugin := &mockVolumePlugin{
|
||||
deleteCalls: expectedDeleteCalls,
|
||||
}
|
||||
ctrl.recyclePluginMgr.InitPlugins([]vol.VolumePlugin{plugin}, ctrl)
|
||||
}
|
||||
|
||||
// newVolume returns a new volume with given attributes
|
||||
func newVolume(name, capacity, boundToClaimUID, boundToClaimName string, phase api.PersistentVolumePhase, annotations ...string) *api.PersistentVolume {
|
||||
func newVolume(name, capacity, boundToClaimUID, boundToClaimName string, phase api.PersistentVolumePhase, reclaimPolicy api.PersistentVolumeReclaimPolicy, annotations ...string) *api.PersistentVolume {
|
||||
volume := api.PersistentVolume{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: name,
|
||||
@ -404,7 +432,8 @@ func newVolume(name, capacity, boundToClaimUID, boundToClaimName string, phase a
|
||||
PersistentVolumeSource: api.PersistentVolumeSource{
|
||||
GCEPersistentDisk: &api.GCEPersistentDiskVolumeSource{},
|
||||
},
|
||||
AccessModes: []api.PersistentVolumeAccessMode{api.ReadWriteOnce, api.ReadOnlyMany},
|
||||
AccessModes: []api.PersistentVolumeAccessMode{api.ReadWriteOnce, api.ReadOnlyMany},
|
||||
PersistentVolumeReclaimPolicy: reclaimPolicy,
|
||||
},
|
||||
Status: api.PersistentVolumeStatus{
|
||||
Phase: phase,
|
||||
@ -433,9 +462,9 @@ func newVolume(name, capacity, boundToClaimUID, boundToClaimName string, phase a
|
||||
|
||||
// newVolumeArray returns array with a single volume that would be returned by
|
||||
// newVolume() with the same parameters.
|
||||
func newVolumeArray(name, capacity, boundToClaimUID, boundToClaimName string, phase api.PersistentVolumePhase, annotations ...string) []*api.PersistentVolume {
|
||||
func newVolumeArray(name, capacity, boundToClaimUID, boundToClaimName string, phase api.PersistentVolumePhase, reclaimPolicy api.PersistentVolumeReclaimPolicy, annotations ...string) []*api.PersistentVolume {
|
||||
return []*api.PersistentVolume{
|
||||
newVolume(name, capacity, boundToClaimUID, boundToClaimName, phase, annotations...),
|
||||
newVolume(name, capacity, boundToClaimUID, boundToClaimName, phase, reclaimPolicy, annotations...),
|
||||
}
|
||||
}
|
||||
|
||||
@ -498,6 +527,66 @@ func testSyncVolume(ctrl *PersistentVolumeController, reactor *volumeReactor, te
|
||||
return ctrl.syncVolume(test.initialVolumes[0])
|
||||
}
|
||||
|
||||
type operationType string
|
||||
|
||||
const operationDelete = "Delete"
|
||||
const operationRecycle = "Recycle"
|
||||
|
||||
// wrapTestWithControllerConfig returns a testCall that:
|
||||
// - configures controller with recycler or deleter which will return provided
|
||||
// errors when a volume is deleted or recycled.
|
||||
// - calls given testCall
|
||||
func wrapTestWithControllerConfig(operation operationType, expectedOperationCalls []error, toWrap testCall) testCall {
|
||||
expected := expectedOperationCalls
|
||||
|
||||
return func(ctrl *PersistentVolumeController, reactor *volumeReactor, test controllerTest) error {
|
||||
switch operation {
|
||||
case operationDelete:
|
||||
addDeletePlugin(ctrl, expected)
|
||||
case operationRecycle:
|
||||
addRecyclePlugin(ctrl, expected)
|
||||
}
|
||||
|
||||
return toWrap(ctrl, reactor, test)
|
||||
}
|
||||
}
|
||||
|
||||
// wrapTestWithInjectedOperation returns a testCall that:
|
||||
// - starts the controller and lets it run original testCall until
|
||||
// scheduleOperation() call. It blocks the controller there and calls the
|
||||
// injected function to simulate that something is happenning when the
|
||||
// controller waits for the operation lock. Controller is then resumed and we
|
||||
// check how it behaves.
|
||||
func wrapTestWithInjectedOperation(toWrap testCall, injectBeforeOperation func(ctrl *PersistentVolumeController, reactor *volumeReactor)) testCall {
|
||||
|
||||
return func(ctrl *PersistentVolumeController, reactor *volumeReactor, test controllerTest) error {
|
||||
// Inject a hook before async operation starts
|
||||
ctrl.preOperationHook = func(operationName string, arg interface{}) {
|
||||
// Inside the hook, run the function to inject
|
||||
glog.V(4).Infof("reactor: scheduleOperation reached, injecting call")
|
||||
injectBeforeOperation(ctrl, reactor)
|
||||
}
|
||||
|
||||
// Run the tested function (typically syncClaim/syncVolume) in a
|
||||
// separate goroutine.
|
||||
var testError error
|
||||
var testFinished int32
|
||||
|
||||
go func() {
|
||||
testError = toWrap(ctrl, reactor, test)
|
||||
// Let the "main" test function know that syncVolume has finished.
|
||||
atomic.StoreInt32(&testFinished, 1)
|
||||
}()
|
||||
|
||||
// Wait for the controler to finish the test function.
|
||||
for atomic.LoadInt32(&testFinished) == 0 {
|
||||
time.Sleep(time.Millisecond * 10)
|
||||
}
|
||||
|
||||
return testError
|
||||
}
|
||||
}
|
||||
|
||||
func evaluateTestResults(ctrl *PersistentVolumeController, reactor *volumeReactor, test controllerTest, t *testing.T) {
|
||||
// Evaluate results
|
||||
if err := reactor.checkClaims(t, test.expectedClaims); err != nil {
|
||||
@ -542,6 +631,9 @@ func runSyncTests(t *testing.T, tests []controllerTest) {
|
||||
t.Errorf("Test %q failed: %v", test.name, err)
|
||||
}
|
||||
|
||||
// Wait for all goroutines to finish
|
||||
reactor.waitTest()
|
||||
|
||||
evaluateTestResults(ctrl, reactor, test, t)
|
||||
}
|
||||
}
|
||||
@ -596,6 +688,9 @@ func runMultisyncTests(t *testing.T, tests []controllerTest) {
|
||||
break
|
||||
}
|
||||
|
||||
// Wait for all goroutines to finish
|
||||
reactor.waitTest()
|
||||
|
||||
obj := reactor.popChange()
|
||||
if obj == nil {
|
||||
// Nothing was changed, should we exit?
|
||||
@ -655,3 +750,122 @@ func runMultisyncTests(t *testing.T, tests []controllerTest) {
|
||||
glog.V(4).Infof("test %q finished after %d iterations", test.name, counter)
|
||||
}
|
||||
}
|
||||
|
||||
// Dummy volume plugin for provisioning, deletion and recycling. It contains
|
||||
// lists of expected return values to simulate errors.
|
||||
type mockVolumePlugin struct {
|
||||
provisionCalls []error
|
||||
provisionCallCounter int
|
||||
deleteCalls []error
|
||||
deleteCallCounter int
|
||||
recycleCalls []error
|
||||
recycleCallCounter int
|
||||
}
|
||||
|
||||
var _ vol.VolumePlugin = &mockVolumePlugin{}
|
||||
|
||||
func (plugin *mockVolumePlugin) Init(host vol.VolumeHost) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (plugin *mockVolumePlugin) Name() string {
|
||||
return "mockVolumePlugin"
|
||||
}
|
||||
|
||||
func (plugin *mockVolumePlugin) CanSupport(spec *vol.Spec) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (plugin *mockVolumePlugin) NewMounter(spec *vol.Spec, podRef *api.Pod, opts vol.VolumeOptions) (vol.Mounter, error) {
|
||||
return nil, fmt.Errorf("Mounter is not supported by this plugin")
|
||||
}
|
||||
|
||||
func (plugin *mockVolumePlugin) NewUnmounter(name string, podUID types.UID) (vol.Unmounter, error) {
|
||||
return nil, fmt.Errorf("Unmounter is not supported by this plugin")
|
||||
}
|
||||
|
||||
// Provisioner interfaces
|
||||
|
||||
func (plugin *mockVolumePlugin) NewProvisioner(options vol.VolumeOptions) (vol.Provisioner, error) {
|
||||
if len(plugin.provisionCalls) > 0 {
|
||||
// mockVolumePlugin directly implements Provisioner interface
|
||||
glog.V(4).Infof("mock plugin NewProvisioner called, returning mock provisioner")
|
||||
return plugin, nil
|
||||
} else {
|
||||
return nil, fmt.Errorf("Mock plugin error: no provisionCalls configured")
|
||||
}
|
||||
}
|
||||
|
||||
func (plugin *mockVolumePlugin) Provision(*api.PersistentVolume) error {
|
||||
if len(plugin.provisionCalls) <= plugin.provisionCallCounter {
|
||||
return fmt.Errorf("Mock plugin error: unexpected provisioner call %d", plugin.provisionCallCounter)
|
||||
}
|
||||
ret := plugin.provisionCalls[plugin.provisionCallCounter]
|
||||
plugin.provisionCallCounter++
|
||||
glog.V(4).Infof("mock plugin Provision call nr. %d, returning %v", plugin.provisionCallCounter, ret)
|
||||
return ret
|
||||
}
|
||||
|
||||
func (plugin *mockVolumePlugin) NewPersistentVolumeTemplate() (*api.PersistentVolume, error) {
|
||||
if len(plugin.provisionCalls) <= plugin.provisionCallCounter {
|
||||
return nil, fmt.Errorf("Mock plugin error: unexpected provisioner call %d", plugin.provisionCallCounter)
|
||||
}
|
||||
ret := plugin.provisionCalls[plugin.provisionCallCounter]
|
||||
plugin.provisionCallCounter++
|
||||
glog.V(4).Infof("mock plugin NewPersistentVolumeTemplate call nr. %d, returning %v", plugin.provisionCallCounter, ret)
|
||||
return nil, ret
|
||||
}
|
||||
|
||||
// Deleter interfaces
|
||||
|
||||
func (plugin *mockVolumePlugin) NewDeleter(spec *vol.Spec) (vol.Deleter, error) {
|
||||
if len(plugin.deleteCalls) > 0 {
|
||||
// mockVolumePlugin directly implements Deleter interface
|
||||
glog.V(4).Infof("mock plugin NewDeleter called, returning mock deleter")
|
||||
return plugin, nil
|
||||
} else {
|
||||
return nil, fmt.Errorf("Mock plugin error: no deleteCalls configured")
|
||||
}
|
||||
}
|
||||
|
||||
func (plugin *mockVolumePlugin) Delete() error {
|
||||
if len(plugin.deleteCalls) <= plugin.deleteCallCounter {
|
||||
return fmt.Errorf("Mock plugin error: unexpected deleter call %d", plugin.deleteCallCounter)
|
||||
}
|
||||
ret := plugin.deleteCalls[plugin.deleteCallCounter]
|
||||
plugin.deleteCallCounter++
|
||||
glog.V(4).Infof("mock plugin Delete call nr. %d, returning %v", plugin.deleteCallCounter, ret)
|
||||
return ret
|
||||
}
|
||||
|
||||
// Volume interfaces
|
||||
|
||||
func (plugin *mockVolumePlugin) GetPath() string {
|
||||
return ""
|
||||
}
|
||||
|
||||
func (plugin *mockVolumePlugin) GetMetrics() (*vol.Metrics, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// Recycler interfaces
|
||||
|
||||
func (plugin *mockVolumePlugin) NewRecycler(spec *vol.Spec) (vol.Recycler, error) {
|
||||
if len(plugin.recycleCalls) > 0 {
|
||||
// mockVolumePlugin directly implements Recycler interface
|
||||
glog.V(4).Infof("mock plugin NewRecycler called, returning mock recycler")
|
||||
return plugin, nil
|
||||
} else {
|
||||
return nil, fmt.Errorf("Mock plugin error: no recycleCalls configured")
|
||||
}
|
||||
}
|
||||
|
||||
func (plugin *mockVolumePlugin) Recycle() error {
|
||||
if len(plugin.recycleCalls) <= plugin.recycleCallCounter {
|
||||
return fmt.Errorf("Mock plugin error: unexpected recycle call %d", plugin.recycleCallCounter)
|
||||
}
|
||||
ret := plugin.recycleCalls[plugin.recycleCallCounter]
|
||||
plugin.recycleCallCounter++
|
||||
glog.V(4).Infof("mock plugin Recycle call nr. %d, returning %v", plugin.recycleCallCounter, ret)
|
||||
return ret
|
||||
}
|
||||
|
196
pkg/controller/persistentvolume/persistentvolume_recycle_test.go
Normal file
196
pkg/controller/persistentvolume/persistentvolume_recycle_test.go
Normal file
@ -0,0 +1,196 @@
|
||||
/*
|
||||
Copyright 2016 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 persistentvolume
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
)
|
||||
|
||||
// Test single call to syncVolume, expecting recycling to happen.
|
||||
// 1. Fill in the controller with initial data
|
||||
// 2. Call the syncVolume *once*.
|
||||
// 3. Compare resulting volumes with expected volumes.
|
||||
func TestRecycleSync(t *testing.T) {
|
||||
tests := []controllerTest{
|
||||
{
|
||||
// recycle volume bound by controller
|
||||
"6-1 - successful recycle",
|
||||
newVolumeArray("volume6-1", "1Gi", "uid6-1", "claim6-1", api.VolumeBound, api.PersistentVolumeReclaimRecycle, annBoundByController),
|
||||
newVolumeArray("volume6-1", "1Gi", "", "", api.VolumeAvailable, api.PersistentVolumeReclaimRecycle),
|
||||
noclaims,
|
||||
noclaims,
|
||||
noevents,
|
||||
// Inject recycler into the controller and call syncVolume. The
|
||||
// recycler simulates one recycle() call that succeeds.
|
||||
wrapTestWithControllerConfig(operationRecycle, []error{nil}, testSyncVolume),
|
||||
},
|
||||
{
|
||||
// recycle volume bound by user
|
||||
"6-2 - successful recycle with prebound volume",
|
||||
newVolumeArray("volume6-2", "1Gi", "uid6-2", "claim6-2", api.VolumeBound, api.PersistentVolumeReclaimRecycle),
|
||||
newVolumeArray("volume6-2", "1Gi", "", "claim6-2", api.VolumeAvailable, api.PersistentVolumeReclaimRecycle),
|
||||
noclaims,
|
||||
noclaims,
|
||||
noevents,
|
||||
// Inject recycler into the controller and call syncVolume. The
|
||||
// recycler simulates one recycle() call that succeeds.
|
||||
wrapTestWithControllerConfig(operationRecycle, []error{nil}, testSyncVolume),
|
||||
},
|
||||
{
|
||||
// recycle failure - plugin not found
|
||||
"6-3 - plugin not found",
|
||||
newVolumeArray("volume6-3", "1Gi", "uid6-3", "claim6-3", api.VolumeBound, api.PersistentVolumeReclaimRecycle),
|
||||
newVolumeArray("volume6-3", "1Gi", "uid6-3", "claim6-3", api.VolumeFailed, api.PersistentVolumeReclaimRecycle),
|
||||
noclaims,
|
||||
noclaims,
|
||||
[]string{"Warning VolumeFailedRecycle"}, testSyncVolume,
|
||||
},
|
||||
{
|
||||
// recycle failure - newRecycler returns error
|
||||
"6-4 - newRecycler returns error",
|
||||
newVolumeArray("volume6-4", "1Gi", "uid6-4", "claim6-4", api.VolumeBound, api.PersistentVolumeReclaimRecycle),
|
||||
newVolumeArray("volume6-4", "1Gi", "uid6-4", "claim6-4", api.VolumeFailed, api.PersistentVolumeReclaimRecycle),
|
||||
noclaims,
|
||||
noclaims,
|
||||
[]string{"Warning VolumeFailedRecycle"},
|
||||
wrapTestWithControllerConfig(operationRecycle, []error{}, testSyncVolume),
|
||||
},
|
||||
{
|
||||
// recycle failure - recycle returns error
|
||||
"6-5 - recycle returns error",
|
||||
newVolumeArray("volume6-5", "1Gi", "uid6-5", "claim6-5", api.VolumeBound, api.PersistentVolumeReclaimRecycle),
|
||||
newVolumeArray("volume6-5", "1Gi", "uid6-5", "claim6-5", api.VolumeFailed, api.PersistentVolumeReclaimRecycle),
|
||||
noclaims,
|
||||
noclaims,
|
||||
[]string{"Warning VolumeFailedRecycle"},
|
||||
wrapTestWithControllerConfig(operationRecycle, []error{errors.New("Mock recycle error")}, testSyncVolume),
|
||||
},
|
||||
{
|
||||
// recycle success(?) - volume is deleted before doRecycle() starts
|
||||
"6-6 - volume is deleted before recycling",
|
||||
newVolumeArray("volume6-6", "1Gi", "uid6-6", "claim6-6", api.VolumeBound, api.PersistentVolumeReclaimRecycle),
|
||||
novolumes,
|
||||
noclaims,
|
||||
noclaims,
|
||||
noevents,
|
||||
wrapTestWithInjectedOperation(wrapTestWithControllerConfig(operationRecycle, []error{}, testSyncVolume), func(ctrl *PersistentVolumeController, reactor *volumeReactor) {
|
||||
// Delete the volume before recycle operation starts
|
||||
reactor.lock.Lock()
|
||||
delete(reactor.volumes, "volume6-6")
|
||||
reactor.lock.Unlock()
|
||||
}),
|
||||
},
|
||||
{
|
||||
// recycle success(?) - volume is recycled by previous recycler just
|
||||
// at the time new doRecycle() starts. This simulates "volume no
|
||||
// longer needs recycling, skipping".
|
||||
"6-7 - volume is deleted before recycling",
|
||||
newVolumeArray("volume6-7", "1Gi", "uid6-7", "claim6-7", api.VolumeBound, api.PersistentVolumeReclaimRecycle, annBoundByController),
|
||||
newVolumeArray("volume6-7", "1Gi", "", "", api.VolumeAvailable, api.PersistentVolumeReclaimRecycle),
|
||||
noclaims,
|
||||
noclaims,
|
||||
noevents,
|
||||
wrapTestWithInjectedOperation(wrapTestWithControllerConfig(operationRecycle, []error{}, testSyncVolume), func(ctrl *PersistentVolumeController, reactor *volumeReactor) {
|
||||
// Mark the volume as Available before the recycler starts
|
||||
reactor.lock.Lock()
|
||||
volume := reactor.volumes["volume6-7"]
|
||||
volume.Spec.ClaimRef = nil
|
||||
volume.Status.Phase = api.VolumeAvailable
|
||||
volume.Annotations = nil
|
||||
reactor.lock.Unlock()
|
||||
}),
|
||||
},
|
||||
{
|
||||
// recycle success(?) - volume bound by user is recycled by previous
|
||||
// recycler just at the time new doRecycle() starts. This simulates
|
||||
// "volume no longer needs recycling, skipping" with volume bound by
|
||||
// user.
|
||||
"6-8 - prebound volume is deleted before recycling",
|
||||
newVolumeArray("volume6-8", "1Gi", "uid6-8", "claim6-8", api.VolumeBound, api.PersistentVolumeReclaimRecycle),
|
||||
newVolumeArray("volume6-8", "1Gi", "", "claim6-8", api.VolumeAvailable, api.PersistentVolumeReclaimRecycle),
|
||||
noclaims,
|
||||
noclaims,
|
||||
noevents,
|
||||
wrapTestWithInjectedOperation(wrapTestWithControllerConfig(operationRecycle, []error{}, testSyncVolume), func(ctrl *PersistentVolumeController, reactor *volumeReactor) {
|
||||
// Mark the volume as Available before the recycler starts
|
||||
reactor.lock.Lock()
|
||||
volume := reactor.volumes["volume6-8"]
|
||||
volume.Spec.ClaimRef.UID = ""
|
||||
volume.Status.Phase = api.VolumeAvailable
|
||||
reactor.lock.Unlock()
|
||||
}),
|
||||
},
|
||||
{
|
||||
// recycle success - volume bound by user is recycled, while a new
|
||||
// claim is created with another UID.
|
||||
"6-9 - prebound volume is recycled while the claim exists",
|
||||
newVolumeArray("volume6-9", "1Gi", "uid6-9", "claim6-9", api.VolumeBound, api.PersistentVolumeReclaimRecycle),
|
||||
newVolumeArray("volume6-9", "1Gi", "", "claim6-9", api.VolumeAvailable, api.PersistentVolumeReclaimRecycle),
|
||||
newClaimArray("claim6-9", "uid6-9-x", "10Gi", "", api.ClaimPending),
|
||||
newClaimArray("claim6-9", "uid6-9-x", "10Gi", "", api.ClaimPending),
|
||||
noevents,
|
||||
// Inject recycler into the controller and call syncVolume. The
|
||||
// recycler simulates one recycle() call that succeeds.
|
||||
wrapTestWithControllerConfig(operationRecycle, []error{nil}, testSyncVolume),
|
||||
},
|
||||
{
|
||||
// volume has unknown reclaim policy - failure expected
|
||||
"6-10 - unknown reclaim policy",
|
||||
newVolumeArray("volume6-10", "1Gi", "uid6-10", "claim6-10", api.VolumeBound, "Unknown"),
|
||||
newVolumeArray("volume6-10", "1Gi", "uid6-10", "claim6-10", api.VolumeFailed, "Unknown"),
|
||||
noclaims,
|
||||
noclaims,
|
||||
[]string{"Warning VolumeUnknownReclaimPolicy"}, testSyncVolume,
|
||||
},
|
||||
}
|
||||
runSyncTests(t, tests)
|
||||
}
|
||||
|
||||
// Test multiple calls to syncClaim/syncVolume and periodic sync of all
|
||||
// volume/claims. The test follows this pattern:
|
||||
// 0. Load the controller with initial data.
|
||||
// 1. Call controllerTest.testCall() once as in TestSync()
|
||||
// 2. For all volumes/claims changed by previous syncVolume/syncClaim calls,
|
||||
// call appropriate syncVolume/syncClaim (simulating "volume/claim changed"
|
||||
// events). Go to 2. if these calls change anything.
|
||||
// 3. When all changes are processed and no new changes were made, call
|
||||
// syncVolume/syncClaim on all volumes/claims (simulating "periodic sync").
|
||||
// 4. If some changes were done by step 3., go to 2. (simulation of
|
||||
// "volume/claim updated" events, eventually performing step 3. again)
|
||||
// 5. When 3. does not do any changes, finish the tests and compare final set
|
||||
// of volumes/claims with expected claims/volumes and report differences.
|
||||
// Some limit of calls in enforced to prevent endless loops.
|
||||
func TestRecycleMultiSync(t *testing.T) {
|
||||
tests := []controllerTest{
|
||||
{
|
||||
// recycle failure - recycle returns error. The controller should
|
||||
// try again.
|
||||
"7-1 - recycle returns error",
|
||||
newVolumeArray("volume7-1", "1Gi", "uid7-1", "claim7-1", api.VolumeBound, api.PersistentVolumeReclaimRecycle),
|
||||
newVolumeArray("volume7-1", "1Gi", "", "claim7-1", api.VolumeAvailable, api.PersistentVolumeReclaimRecycle),
|
||||
noclaims,
|
||||
noclaims,
|
||||
[]string{"Warning VolumeFailedRecycle"},
|
||||
wrapTestWithControllerConfig(operationRecycle, []error{errors.New("Mock recycle error"), nil}, testSyncVolume),
|
||||
},
|
||||
}
|
||||
|
||||
runMultisyncTests(t, tests)
|
||||
}
|
@ -35,8 +35,8 @@ func TestSync(t *testing.T) {
|
||||
{
|
||||
// syncClaim binds to a matching unbound volume.
|
||||
"1-1 - successful bind",
|
||||
newVolumeArray("volume1-1", "1Gi", "", "", api.VolumePending),
|
||||
newVolumeArray("volume1-1", "1Gi", "uid1-1", "claim1-1", api.VolumeBound, annBoundByController),
|
||||
newVolumeArray("volume1-1", "1Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
|
||||
newVolumeArray("volume1-1", "1Gi", "uid1-1", "claim1-1", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController),
|
||||
newClaimArray("claim1-1", "uid1-1", "1Gi", "", api.ClaimPending),
|
||||
newClaimArray("claim1-1", "uid1-1", "1Gi", "volume1-1", api.ClaimBound, annBoundByController, annBindCompleted),
|
||||
noevents, testSyncClaim,
|
||||
@ -44,8 +44,8 @@ func TestSync(t *testing.T) {
|
||||
{
|
||||
// syncClaim does not do anything when there is no matching volume.
|
||||
"1-2 - noop",
|
||||
newVolumeArray("volume1-2", "1Gi", "", "", api.VolumePending),
|
||||
newVolumeArray("volume1-2", "1Gi", "", "", api.VolumePending),
|
||||
newVolumeArray("volume1-2", "1Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
|
||||
newVolumeArray("volume1-2", "1Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
|
||||
newClaimArray("claim1-2", "uid1-2", "10Gi", "", api.ClaimPending),
|
||||
newClaimArray("claim1-2", "uid1-2", "10Gi", "", api.ClaimPending),
|
||||
noevents, testSyncClaim,
|
||||
@ -54,8 +54,8 @@ func TestSync(t *testing.T) {
|
||||
// syncClaim resets claim.Status to Pending when there is no
|
||||
// matching volume.
|
||||
"1-3 - reset to Pending",
|
||||
newVolumeArray("volume1-3", "1Gi", "", "", api.VolumePending),
|
||||
newVolumeArray("volume1-3", "1Gi", "", "", api.VolumePending),
|
||||
newVolumeArray("volume1-3", "1Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
|
||||
newVolumeArray("volume1-3", "1Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
|
||||
newClaimArray("claim1-3", "uid1-3", "10Gi", "", api.ClaimBound),
|
||||
newClaimArray("claim1-3", "uid1-3", "10Gi", "", api.ClaimPending),
|
||||
noevents, testSyncClaim,
|
||||
@ -64,12 +64,12 @@ func TestSync(t *testing.T) {
|
||||
// syncClaim binds claims to the smallest matching volume
|
||||
"1-4 - smallest volume",
|
||||
[]*api.PersistentVolume{
|
||||
newVolume("volume1-4_1", "10Gi", "", "", api.VolumePending),
|
||||
newVolume("volume1-4_2", "1Gi", "", "", api.VolumePending),
|
||||
newVolume("volume1-4_1", "10Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
|
||||
newVolume("volume1-4_2", "1Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
|
||||
},
|
||||
[]*api.PersistentVolume{
|
||||
newVolume("volume1-4_1", "10Gi", "", "", api.VolumePending),
|
||||
newVolume("volume1-4_2", "1Gi", "uid1-4", "claim1-4", api.VolumeBound, annBoundByController),
|
||||
newVolume("volume1-4_1", "10Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
|
||||
newVolume("volume1-4_2", "1Gi", "uid1-4", "claim1-4", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController),
|
||||
},
|
||||
newClaimArray("claim1-4", "uid1-4", "1Gi", "", api.ClaimPending),
|
||||
newClaimArray("claim1-4", "uid1-4", "1Gi", "volume1-4_2", api.ClaimBound, annBoundByController, annBindCompleted),
|
||||
@ -80,12 +80,12 @@ func TestSync(t *testing.T) {
|
||||
// name), even though a smaller one is available.
|
||||
"1-5 - prebound volume by name - success",
|
||||
[]*api.PersistentVolume{
|
||||
newVolume("volume1-5_1", "10Gi", "", "claim1-5", api.VolumePending),
|
||||
newVolume("volume1-5_2", "1Gi", "", "", api.VolumePending),
|
||||
newVolume("volume1-5_1", "10Gi", "", "claim1-5", api.VolumePending, api.PersistentVolumeReclaimRetain),
|
||||
newVolume("volume1-5_2", "1Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
|
||||
},
|
||||
[]*api.PersistentVolume{
|
||||
newVolume("volume1-5_1", "10Gi", "uid1-5", "claim1-5", api.VolumeBound),
|
||||
newVolume("volume1-5_2", "1Gi", "", "", api.VolumePending),
|
||||
newVolume("volume1-5_1", "10Gi", "uid1-5", "claim1-5", api.VolumeBound, api.PersistentVolumeReclaimRetain),
|
||||
newVolume("volume1-5_2", "1Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
|
||||
},
|
||||
newClaimArray("claim1-5", "uid1-5", "1Gi", "", api.ClaimPending),
|
||||
newClaimArray("claim1-5", "uid1-5", "1Gi", "volume1-5_1", api.ClaimBound, annBoundByController, annBindCompleted),
|
||||
@ -96,12 +96,12 @@ func TestSync(t *testing.T) {
|
||||
// UID), even though a smaller one is available.
|
||||
"1-6 - prebound volume by UID - success",
|
||||
[]*api.PersistentVolume{
|
||||
newVolume("volume1-6_1", "10Gi", "uid1-6", "claim1-6", api.VolumePending),
|
||||
newVolume("volume1-6_2", "1Gi", "", "", api.VolumePending),
|
||||
newVolume("volume1-6_1", "10Gi", "uid1-6", "claim1-6", api.VolumePending, api.PersistentVolumeReclaimRetain),
|
||||
newVolume("volume1-6_2", "1Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
|
||||
},
|
||||
[]*api.PersistentVolume{
|
||||
newVolume("volume1-6_1", "10Gi", "uid1-6", "claim1-6", api.VolumeBound),
|
||||
newVolume("volume1-6_2", "1Gi", "", "", api.VolumePending),
|
||||
newVolume("volume1-6_1", "10Gi", "uid1-6", "claim1-6", api.VolumeBound, api.PersistentVolumeReclaimRetain),
|
||||
newVolume("volume1-6_2", "1Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
|
||||
},
|
||||
newClaimArray("claim1-6", "uid1-6", "1Gi", "", api.ClaimPending),
|
||||
newClaimArray("claim1-6", "uid1-6", "1Gi", "volume1-6_1", api.ClaimBound, annBoundByController, annBindCompleted),
|
||||
@ -111,8 +111,8 @@ func TestSync(t *testing.T) {
|
||||
// syncClaim does not bind claim to a volume prebound to a claim with
|
||||
// same name and different UID
|
||||
"1-7 - prebound volume to different claim",
|
||||
newVolumeArray("volume1-7", "10Gi", "uid1-777", "claim1-7", api.VolumePending),
|
||||
newVolumeArray("volume1-7", "10Gi", "uid1-777", "claim1-7", api.VolumePending),
|
||||
newVolumeArray("volume1-7", "10Gi", "uid1-777", "claim1-7", api.VolumePending, api.PersistentVolumeReclaimRetain),
|
||||
newVolumeArray("volume1-7", "10Gi", "uid1-777", "claim1-7", api.VolumePending, api.PersistentVolumeReclaimRetain),
|
||||
newClaimArray("claim1-7", "uid1-7", "1Gi", "", api.ClaimPending),
|
||||
newClaimArray("claim1-7", "uid1-7", "1Gi", "", api.ClaimPending),
|
||||
noevents, testSyncClaim,
|
||||
@ -121,8 +121,8 @@ func TestSync(t *testing.T) {
|
||||
// syncClaim completes binding - simulates controller crash after
|
||||
// PV.ClaimRef is saved
|
||||
"1-8 - complete bind after crash - PV bound",
|
||||
newVolumeArray("volume1-8", "1Gi", "uid1-8", "claim1-8", api.VolumePending, annBoundByController),
|
||||
newVolumeArray("volume1-8", "1Gi", "uid1-8", "claim1-8", api.VolumeBound, annBoundByController),
|
||||
newVolumeArray("volume1-8", "1Gi", "uid1-8", "claim1-8", api.VolumePending, api.PersistentVolumeReclaimRetain, annBoundByController),
|
||||
newVolumeArray("volume1-8", "1Gi", "uid1-8", "claim1-8", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController),
|
||||
newClaimArray("claim1-8", "uid1-8", "1Gi", "", api.ClaimPending),
|
||||
newClaimArray("claim1-8", "uid1-8", "1Gi", "volume1-8", api.ClaimBound, annBoundByController, annBindCompleted),
|
||||
noevents, testSyncClaim,
|
||||
@ -131,8 +131,8 @@ func TestSync(t *testing.T) {
|
||||
// syncClaim completes binding - simulates controller crash after
|
||||
// PV.Status is saved
|
||||
"1-9 - complete bind after crash - PV status saved",
|
||||
newVolumeArray("volume1-9", "1Gi", "uid1-9", "claim1-9", api.VolumeBound, annBoundByController),
|
||||
newVolumeArray("volume1-9", "1Gi", "uid1-9", "claim1-9", api.VolumeBound, annBoundByController),
|
||||
newVolumeArray("volume1-9", "1Gi", "uid1-9", "claim1-9", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController),
|
||||
newVolumeArray("volume1-9", "1Gi", "uid1-9", "claim1-9", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController),
|
||||
newClaimArray("claim1-9", "uid1-9", "1Gi", "", api.ClaimPending),
|
||||
newClaimArray("claim1-9", "uid1-9", "1Gi", "volume1-9", api.ClaimBound, annBoundByController, annBindCompleted),
|
||||
noevents, testSyncClaim,
|
||||
@ -141,8 +141,8 @@ func TestSync(t *testing.T) {
|
||||
// syncClaim completes binding - simulates controller crash after
|
||||
// PVC.VolumeName is saved
|
||||
"10 - complete bind after crash - PVC bound",
|
||||
newVolumeArray("volume1-10", "1Gi", "uid1-10", "claim1-10", api.VolumeBound, annBoundByController),
|
||||
newVolumeArray("volume1-10", "1Gi", "uid1-10", "claim1-10", api.VolumeBound, annBoundByController),
|
||||
newVolumeArray("volume1-10", "1Gi", "uid1-10", "claim1-10", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController),
|
||||
newVolumeArray("volume1-10", "1Gi", "uid1-10", "claim1-10", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController),
|
||||
newClaimArray("claim1-10", "uid1-10", "1Gi", "volume1-10", api.ClaimPending, annBoundByController, annBindCompleted),
|
||||
newClaimArray("claim1-10", "uid1-10", "1Gi", "volume1-10", api.ClaimBound, annBoundByController, annBindCompleted),
|
||||
noevents, testSyncClaim,
|
||||
@ -173,8 +173,8 @@ func TestSync(t *testing.T) {
|
||||
// syncClaim with claim pre-bound to a PV that exists and is
|
||||
// unbound. Check it gets bound and no annBoundByController is set.
|
||||
"2-3 - claim prebound to unbound volume",
|
||||
newVolumeArray("volume2-3", "1Gi", "", "", api.VolumePending),
|
||||
newVolumeArray("volume2-3", "1Gi", "uid2-3", "claim2-3", api.VolumeBound, annBoundByController),
|
||||
newVolumeArray("volume2-3", "1Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
|
||||
newVolumeArray("volume2-3", "1Gi", "uid2-3", "claim2-3", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController),
|
||||
newClaimArray("claim2-3", "uid2-3", "10Gi", "volume2-3", api.ClaimPending),
|
||||
newClaimArray("claim2-3", "uid2-3", "10Gi", "volume2-3", api.ClaimBound, annBindCompleted),
|
||||
noevents, testSyncClaim,
|
||||
@ -183,8 +183,8 @@ func TestSync(t *testing.T) {
|
||||
// claim with claim pre-bound to a PV that is pre-bound to the claim
|
||||
// by name. Check it gets bound and no annBoundByController is set.
|
||||
"2-4 - claim prebound to prebound volume by name",
|
||||
newVolumeArray("volume2-4", "1Gi", "", "claim2-4", api.VolumePending),
|
||||
newVolumeArray("volume2-4", "1Gi", "uid2-4", "claim2-4", api.VolumeBound),
|
||||
newVolumeArray("volume2-4", "1Gi", "", "claim2-4", api.VolumePending, api.PersistentVolumeReclaimRetain),
|
||||
newVolumeArray("volume2-4", "1Gi", "uid2-4", "claim2-4", api.VolumeBound, api.PersistentVolumeReclaimRetain),
|
||||
newClaimArray("claim2-4", "uid2-4", "10Gi", "volume2-4", api.ClaimPending),
|
||||
newClaimArray("claim2-4", "uid2-4", "10Gi", "volume2-4", api.ClaimBound, annBindCompleted),
|
||||
noevents, testSyncClaim,
|
||||
@ -194,8 +194,8 @@ func TestSync(t *testing.T) {
|
||||
// claim by UID. Check it gets bound and no annBoundByController is
|
||||
// set.
|
||||
"2-5 - claim prebound to prebound volume by UID",
|
||||
newVolumeArray("volume2-5", "1Gi", "uid2-5", "claim2-5", api.VolumePending),
|
||||
newVolumeArray("volume2-5", "1Gi", "uid2-5", "claim2-5", api.VolumeBound),
|
||||
newVolumeArray("volume2-5", "1Gi", "uid2-5", "claim2-5", api.VolumePending, api.PersistentVolumeReclaimRetain),
|
||||
newVolumeArray("volume2-5", "1Gi", "uid2-5", "claim2-5", api.VolumeBound, api.PersistentVolumeReclaimRetain),
|
||||
newClaimArray("claim2-5", "uid2-5", "10Gi", "volume2-5", api.ClaimPending),
|
||||
newClaimArray("claim2-5", "uid2-5", "10Gi", "volume2-5", api.ClaimBound, annBindCompleted),
|
||||
noevents, testSyncClaim,
|
||||
@ -204,8 +204,8 @@ func TestSync(t *testing.T) {
|
||||
// syncClaim with claim pre-bound to a PV that is bound to different
|
||||
// claim. Check it's reset to Pending.
|
||||
"2-6 - claim prebound to already bound volume",
|
||||
newVolumeArray("volume2-6", "1Gi", "uid2-6_1", "claim2-6_1", api.VolumeBound),
|
||||
newVolumeArray("volume2-6", "1Gi", "uid2-6_1", "claim2-6_1", api.VolumeBound),
|
||||
newVolumeArray("volume2-6", "1Gi", "uid2-6_1", "claim2-6_1", api.VolumeBound, api.PersistentVolumeReclaimRetain),
|
||||
newVolumeArray("volume2-6", "1Gi", "uid2-6_1", "claim2-6_1", api.VolumeBound, api.PersistentVolumeReclaimRetain),
|
||||
newClaimArray("claim2-6", "uid2-6", "10Gi", "volume2-6", api.ClaimBound),
|
||||
newClaimArray("claim2-6", "uid2-6", "10Gi", "volume2-6", api.ClaimPending),
|
||||
noevents, testSyncClaim,
|
||||
@ -214,8 +214,8 @@ func TestSync(t *testing.T) {
|
||||
// syncClaim with claim bound by controller to a PV that is bound to
|
||||
// different claim. Check it throws an error.
|
||||
"2-7 - claim bound by controller to already bound volume",
|
||||
newVolumeArray("volume2-7", "1Gi", "uid2-7_1", "claim2-7_1", api.VolumeBound),
|
||||
newVolumeArray("volume2-7", "1Gi", "uid2-7_1", "claim2-7_1", api.VolumeBound),
|
||||
newVolumeArray("volume2-7", "1Gi", "uid2-7_1", "claim2-7_1", api.VolumeBound, api.PersistentVolumeReclaimRetain),
|
||||
newVolumeArray("volume2-7", "1Gi", "uid2-7_1", "claim2-7_1", api.VolumeBound, api.PersistentVolumeReclaimRetain),
|
||||
newClaimArray("claim2-7", "uid2-7", "10Gi", "volume2-7", api.ClaimBound, annBoundByController),
|
||||
newClaimArray("claim2-7", "uid2-7", "10Gi", "volume2-7", api.ClaimBound, annBoundByController),
|
||||
noevents, testSyncClaimError,
|
||||
@ -245,8 +245,8 @@ func TestSync(t *testing.T) {
|
||||
// syncClaim with claim bound to unbound volume. Check it's bound.
|
||||
// Also check that Pending phase is set to Bound
|
||||
"3-3 - bound claim with unbound volume",
|
||||
newVolumeArray("volume3-3", "10Gi", "", "", api.VolumePending),
|
||||
newVolumeArray("volume3-3", "10Gi", "uid3-3", "claim3-3", api.VolumeBound, annBoundByController),
|
||||
newVolumeArray("volume3-3", "10Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
|
||||
newVolumeArray("volume3-3", "10Gi", "uid3-3", "claim3-3", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController),
|
||||
newClaimArray("claim3-3", "uid3-3", "10Gi", "volume3-3", api.ClaimPending, annBoundByController, annBindCompleted),
|
||||
newClaimArray("claim3-3", "uid3-3", "10Gi", "volume3-3", api.ClaimBound, annBoundByController, annBindCompleted),
|
||||
noevents, testSyncClaim,
|
||||
@ -255,8 +255,8 @@ func TestSync(t *testing.T) {
|
||||
// syncClaim with claim bound to volume with missing (or different)
|
||||
// volume.Spec.ClaimRef.UID. Check that the claim is marked as lost.
|
||||
"3-4 - bound claim with prebound volume",
|
||||
newVolumeArray("volume3-4", "10Gi", "claim3-4-x", "claim3-4", api.VolumePending),
|
||||
newVolumeArray("volume3-4", "10Gi", "claim3-4-x", "claim3-4", api.VolumePending),
|
||||
newVolumeArray("volume3-4", "10Gi", "claim3-4-x", "claim3-4", api.VolumePending, api.PersistentVolumeReclaimRetain),
|
||||
newVolumeArray("volume3-4", "10Gi", "claim3-4-x", "claim3-4", api.VolumePending, api.PersistentVolumeReclaimRetain),
|
||||
newClaimArray("claim3-4", "uid3-4", "10Gi", "volume3-4", api.ClaimPending, annBoundByController, annBindCompleted),
|
||||
newClaimArray("claim3-4", "uid3-4", "10Gi", "volume3-4", api.ClaimLost, annBoundByController, annBindCompleted),
|
||||
[]string{"Warning ClaimMisbound"}, testSyncClaim,
|
||||
@ -266,8 +266,8 @@ func TestSync(t *testing.T) {
|
||||
// controller does not do anything. Also check that Pending phase is
|
||||
// set to Bound
|
||||
"3-5 - bound claim with bound volume",
|
||||
newVolumeArray("volume3-5", "10Gi", "uid3-5", "claim3-5", api.VolumePending),
|
||||
newVolumeArray("volume3-5", "10Gi", "uid3-5", "claim3-5", api.VolumeBound),
|
||||
newVolumeArray("volume3-5", "10Gi", "uid3-5", "claim3-5", api.VolumePending, api.PersistentVolumeReclaimRetain),
|
||||
newVolumeArray("volume3-5", "10Gi", "uid3-5", "claim3-5", api.VolumeBound, api.PersistentVolumeReclaimRetain),
|
||||
newClaimArray("claim3-5", "uid3-5", "10Gi", "volume3-5", api.ClaimPending, annBindCompleted),
|
||||
newClaimArray("claim3-5", "uid3-5", "10Gi", "volume3-5", api.ClaimBound, annBindCompleted),
|
||||
noevents, testSyncClaim,
|
||||
@ -277,8 +277,8 @@ func TestSync(t *testing.T) {
|
||||
// claim. Check that the claim is marked as lost.
|
||||
// TODO: test that an event is emitted
|
||||
"3-6 - bound claim with bound volume",
|
||||
newVolumeArray("volume3-6", "10Gi", "uid3-6-x", "claim3-6-x", api.VolumePending),
|
||||
newVolumeArray("volume3-6", "10Gi", "uid3-6-x", "claim3-6-x", api.VolumePending),
|
||||
newVolumeArray("volume3-6", "10Gi", "uid3-6-x", "claim3-6-x", api.VolumePending, api.PersistentVolumeReclaimRetain),
|
||||
newVolumeArray("volume3-6", "10Gi", "uid3-6-x", "claim3-6-x", api.VolumePending, api.PersistentVolumeReclaimRetain),
|
||||
newClaimArray("claim3-6", "uid3-6", "10Gi", "volume3-6", api.ClaimPending, annBindCompleted),
|
||||
newClaimArray("claim3-6", "uid3-6", "10Gi", "volume3-6", api.ClaimLost, annBindCompleted),
|
||||
[]string{"Warning ClaimMisbound"}, testSyncClaim,
|
||||
@ -287,8 +287,8 @@ func TestSync(t *testing.T) {
|
||||
{
|
||||
// syncVolume with pending volume. Check it's marked as Available.
|
||||
"4-1 - pending volume",
|
||||
newVolumeArray("volume4-1", "10Gi", "", "", api.VolumePending),
|
||||
newVolumeArray("volume4-1", "10Gi", "", "", api.VolumeAvailable),
|
||||
newVolumeArray("volume4-1", "10Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
|
||||
newVolumeArray("volume4-1", "10Gi", "", "", api.VolumeAvailable, api.PersistentVolumeReclaimRetain),
|
||||
noclaims,
|
||||
noclaims,
|
||||
noevents, testSyncVolume,
|
||||
@ -297,8 +297,8 @@ func TestSync(t *testing.T) {
|
||||
// syncVolume with prebound pending volume. Check it's marked as
|
||||
// Available.
|
||||
"4-2 - pending prebound volume",
|
||||
newVolumeArray("volume4-2", "10Gi", "", "claim4-2", api.VolumePending),
|
||||
newVolumeArray("volume4-2", "10Gi", "", "claim4-2", api.VolumeAvailable),
|
||||
newVolumeArray("volume4-2", "10Gi", "", "claim4-2", api.VolumePending, api.PersistentVolumeReclaimRetain),
|
||||
newVolumeArray("volume4-2", "10Gi", "", "claim4-2", api.VolumeAvailable, api.PersistentVolumeReclaimRetain),
|
||||
noclaims,
|
||||
noclaims,
|
||||
noevents, testSyncVolume,
|
||||
@ -307,8 +307,8 @@ func TestSync(t *testing.T) {
|
||||
// syncVolume with volume bound to missing claim.
|
||||
// Check the volume gets Released
|
||||
"4-3 - bound volume with missing claim",
|
||||
newVolumeArray("volume4-3", "10Gi", "uid4-3", "claim4-3", api.VolumeBound),
|
||||
newVolumeArray("volume4-3", "10Gi", "uid4-3", "claim4-3", api.VolumeReleased),
|
||||
newVolumeArray("volume4-3", "10Gi", "uid4-3", "claim4-3", api.VolumeBound, api.PersistentVolumeReclaimRetain),
|
||||
newVolumeArray("volume4-3", "10Gi", "uid4-3", "claim4-3", api.VolumeReleased, api.PersistentVolumeReclaimRetain),
|
||||
noclaims,
|
||||
noclaims,
|
||||
noevents, testSyncVolume,
|
||||
@ -317,8 +317,8 @@ func TestSync(t *testing.T) {
|
||||
// syncVolume with volume bound to claim with different UID.
|
||||
// Check the volume gets Released.
|
||||
"4-4 - volume bound to claim with different UID",
|
||||
newVolumeArray("volume4-4", "10Gi", "uid4-4", "claim4-4", api.VolumeBound),
|
||||
newVolumeArray("volume4-4", "10Gi", "uid4-4", "claim4-4", api.VolumeReleased),
|
||||
newVolumeArray("volume4-4", "10Gi", "uid4-4", "claim4-4", api.VolumeBound, api.PersistentVolumeReclaimRetain),
|
||||
newVolumeArray("volume4-4", "10Gi", "uid4-4", "claim4-4", api.VolumeReleased, api.PersistentVolumeReclaimRetain),
|
||||
newClaimArray("claim4-4", "uid4-4-x", "10Gi", "volume4-4", api.ClaimBound, annBindCompleted),
|
||||
newClaimArray("claim4-4", "uid4-4-x", "10Gi", "volume4-4", api.ClaimBound, annBindCompleted),
|
||||
noevents, testSyncVolume,
|
||||
@ -327,8 +327,8 @@ func TestSync(t *testing.T) {
|
||||
// syncVolume with volume bound by controller to unbound claim.
|
||||
// Check syncVolume does not do anything.
|
||||
"4-5 - volume bound by controller to unbound claim",
|
||||
newVolumeArray("volume4-5", "10Gi", "uid4-5", "claim4-5", api.VolumeBound, annBoundByController),
|
||||
newVolumeArray("volume4-5", "10Gi", "uid4-5", "claim4-5", api.VolumeBound, annBoundByController),
|
||||
newVolumeArray("volume4-5", "10Gi", "uid4-5", "claim4-5", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController),
|
||||
newVolumeArray("volume4-5", "10Gi", "uid4-5", "claim4-5", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController),
|
||||
newClaimArray("claim4-5", "uid4-5", "10Gi", "", api.ClaimPending),
|
||||
newClaimArray("claim4-5", "uid4-5", "10Gi", "", api.ClaimPending),
|
||||
noevents, testSyncVolume,
|
||||
@ -337,8 +337,8 @@ func TestSync(t *testing.T) {
|
||||
// syncVolume with volume bound by user to unbound claim.
|
||||
// Check syncVolume does not do anything.
|
||||
"4-5 - volume bound by user to bound claim",
|
||||
newVolumeArray("volume4-5", "10Gi", "uid4-5", "claim4-5", api.VolumeBound),
|
||||
newVolumeArray("volume4-5", "10Gi", "uid4-5", "claim4-5", api.VolumeBound),
|
||||
newVolumeArray("volume4-5", "10Gi", "uid4-5", "claim4-5", api.VolumeBound, api.PersistentVolumeReclaimRetain),
|
||||
newVolumeArray("volume4-5", "10Gi", "uid4-5", "claim4-5", api.VolumeBound, api.PersistentVolumeReclaimRetain),
|
||||
newClaimArray("claim4-5", "uid4-5", "10Gi", "", api.ClaimPending),
|
||||
newClaimArray("claim4-5", "uid4-5", "10Gi", "", api.ClaimPending),
|
||||
noevents, testSyncVolume,
|
||||
@ -347,8 +347,8 @@ func TestSync(t *testing.T) {
|
||||
// syncVolume with volume bound to bound claim.
|
||||
// Check that the volume is marked as Bound.
|
||||
"4-6 - volume bound by to bound claim",
|
||||
newVolumeArray("volume4-6", "10Gi", "uid4-6", "claim4-6", api.VolumeAvailable),
|
||||
newVolumeArray("volume4-6", "10Gi", "uid4-6", "claim4-6", api.VolumeBound),
|
||||
newVolumeArray("volume4-6", "10Gi", "uid4-6", "claim4-6", api.VolumeAvailable, api.PersistentVolumeReclaimRetain),
|
||||
newVolumeArray("volume4-6", "10Gi", "uid4-6", "claim4-6", api.VolumeBound, api.PersistentVolumeReclaimRetain),
|
||||
newClaimArray("claim4-6", "uid4-6", "10Gi", "volume4-6", api.ClaimBound),
|
||||
newClaimArray("claim4-6", "uid4-6", "10Gi", "volume4-6", api.ClaimBound),
|
||||
noevents, testSyncVolume,
|
||||
@ -357,8 +357,8 @@ func TestSync(t *testing.T) {
|
||||
// syncVolume with volume bound by controller to claim bound to
|
||||
// another volume. Check that the volume is rolled back.
|
||||
"4-7 - volume bound by controller to claim bound somewhere else",
|
||||
newVolumeArray("volume4-7", "10Gi", "uid4-7", "claim4-7", api.VolumeBound, annBoundByController),
|
||||
newVolumeArray("volume4-7", "10Gi", "", "", api.VolumeAvailable),
|
||||
newVolumeArray("volume4-7", "10Gi", "uid4-7", "claim4-7", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController),
|
||||
newVolumeArray("volume4-7", "10Gi", "", "", api.VolumeAvailable, api.PersistentVolumeReclaimRetain),
|
||||
newClaimArray("claim4-7", "uid4-7", "10Gi", "volume4-7-x", api.ClaimBound),
|
||||
newClaimArray("claim4-7", "uid4-7", "10Gi", "volume4-7-x", api.ClaimBound),
|
||||
noevents, testSyncVolume,
|
||||
@ -368,8 +368,8 @@ func TestSync(t *testing.T) {
|
||||
// another volume. Check that the volume is marked as Available
|
||||
// and its UID is reset.
|
||||
"4-8 - volume bound by user to claim bound somewhere else",
|
||||
newVolumeArray("volume4-8", "10Gi", "uid4-8", "claim4-8", api.VolumeBound),
|
||||
newVolumeArray("volume4-8", "10Gi", "", "claim4-8", api.VolumeAvailable),
|
||||
newVolumeArray("volume4-8", "10Gi", "uid4-8", "claim4-8", api.VolumeBound, api.PersistentVolumeReclaimRetain),
|
||||
newVolumeArray("volume4-8", "10Gi", "", "claim4-8", api.VolumeAvailable, api.PersistentVolumeReclaimRetain),
|
||||
newClaimArray("claim4-8", "uid4-8", "10Gi", "volume4-8-x", api.ClaimBound),
|
||||
newClaimArray("claim4-8", "uid4-8", "10Gi", "volume4-8-x", api.ClaimBound),
|
||||
noevents, testSyncVolume,
|
||||
@ -398,8 +398,8 @@ func TestMultiSync(t *testing.T) {
|
||||
{
|
||||
// syncClaim binds to a matching unbound volume.
|
||||
"10-1 - successful bind",
|
||||
newVolumeArray("volume10-1", "1Gi", "", "", api.VolumePending),
|
||||
newVolumeArray("volume10-1", "1Gi", "uid10-1", "claim10-1", api.VolumeBound, annBoundByController),
|
||||
newVolumeArray("volume10-1", "1Gi", "", "", api.VolumePending, api.PersistentVolumeReclaimRetain),
|
||||
newVolumeArray("volume10-1", "1Gi", "uid10-1", "claim10-1", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController),
|
||||
newClaimArray("claim10-1", "uid10-1", "1Gi", "", api.ClaimPending),
|
||||
newClaimArray("claim10-1", "uid10-1", "1Gi", "volume10-1", api.ClaimBound, annBoundByController, annBindCompleted),
|
||||
noevents, testSyncClaim,
|
||||
@ -409,12 +409,12 @@ func TestMultiSync(t *testing.T) {
|
||||
// wins and the second rolls back.
|
||||
"10-2 - bind PV race",
|
||||
[]*api.PersistentVolume{
|
||||
newVolume("volume10-2-1", "1Gi", "uid10-2", "claim10-2", api.VolumeBound, annBoundByController),
|
||||
newVolume("volume10-2-2", "1Gi", "uid10-2", "claim10-2", api.VolumeBound, annBoundByController),
|
||||
newVolume("volume10-2-1", "1Gi", "uid10-2", "claim10-2", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController),
|
||||
newVolume("volume10-2-2", "1Gi", "uid10-2", "claim10-2", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController),
|
||||
},
|
||||
[]*api.PersistentVolume{
|
||||
newVolume("volume10-2-1", "1Gi", "uid10-2", "claim10-2", api.VolumeBound, annBoundByController),
|
||||
newVolume("volume10-2-2", "1Gi", "", "", api.VolumeAvailable),
|
||||
newVolume("volume10-2-1", "1Gi", "uid10-2", "claim10-2", api.VolumeBound, api.PersistentVolumeReclaimRetain, annBoundByController),
|
||||
newVolume("volume10-2-2", "1Gi", "", "", api.VolumeAvailable, api.PersistentVolumeReclaimRetain),
|
||||
},
|
||||
newClaimArray("claim10-2", "uid10-2", "1Gi", "volume10-2-1", api.ClaimBound, annBoundByController, annBindCompleted),
|
||||
newClaimArray("claim10-2", "uid10-2", "1Gi", "volume10-2-1", api.ClaimBound, annBoundByController, annBindCompleted),
|
||||
|
Loading…
Reference in New Issue
Block a user