mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-01 15:58:37 +00:00
Add "multi-sync" tests.
These test will call syncVolume/syncClaim until they reach consistent state.
This commit is contained in:
parent
f4f252e81c
commit
50b61ae168
@ -461,3 +461,113 @@ func runSyncTests(t *testing.T, tests []controllerTest) {
|
||||
evaluateTestResults(ctrl, reactor, test, t)
|
||||
}
|
||||
}
|
||||
|
||||
// Test multiple calls to syncClaim/syncVolume and periodic sync of all
|
||||
// volume/claims. For all tests, 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 runMultisyncTests(t *testing.T, tests []controllerTest) {
|
||||
for _, test := range tests {
|
||||
glog.V(4).Infof("starting multisync test %q", test.name)
|
||||
|
||||
// Initialize the controller
|
||||
client := &fake.Clientset{}
|
||||
ctrl := newPersistentVolumeController(client)
|
||||
reactor := newVolumeReactor(client, ctrl, nil, nil)
|
||||
for _, claim := range test.initialClaims {
|
||||
ctrl.claims.Add(claim)
|
||||
reactor.claims[claim.Name] = claim
|
||||
}
|
||||
for _, volume := range test.initialVolumes {
|
||||
ctrl.volumes.store.Add(volume)
|
||||
reactor.volumes[volume.Name] = volume
|
||||
}
|
||||
|
||||
// Run the tested function
|
||||
err := test.test(ctrl, reactor, test)
|
||||
if err != nil {
|
||||
t.Errorf("Test %q failed: %v", test.name, err)
|
||||
}
|
||||
|
||||
// Simulate any "changed" events and "periodical sync" until we reach a
|
||||
// stable state.
|
||||
firstSync := true
|
||||
counter := 0
|
||||
for {
|
||||
counter++
|
||||
glog.V(4).Infof("test %q: iteration %d", test.name, counter)
|
||||
|
||||
if counter > 100 {
|
||||
t.Errorf("Test %q failed: too many iterations", test.name)
|
||||
break
|
||||
}
|
||||
|
||||
obj := reactor.popChange()
|
||||
if obj == nil {
|
||||
// Nothing was changed, should we exit?
|
||||
if firstSync || reactor.changedSinceLastSync > 0 {
|
||||
// There were some changes after the last "periodic sync".
|
||||
// Simulate "periodic sync" of everything (until it produces
|
||||
// no changes).
|
||||
firstSync = false
|
||||
glog.V(4).Infof("test %q: simulating periodical sync of all claims and volumes", test.name)
|
||||
reactor.syncAll()
|
||||
} else {
|
||||
// Last sync did not produce any updates, the test reached
|
||||
// stable state -> finish.
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// There were some changes, process them
|
||||
switch obj.(type) {
|
||||
case *api.PersistentVolumeClaim:
|
||||
claim := obj.(*api.PersistentVolumeClaim)
|
||||
// Simulate "claim updated" event
|
||||
ctrl.claims.Update(claim)
|
||||
err = ctrl.syncClaim(claim)
|
||||
if err != nil {
|
||||
if err == versionConflictError {
|
||||
// Ignore version errors
|
||||
glog.V(4).Infof("test intentionaly ignores version error.")
|
||||
} else {
|
||||
t.Errorf("Error calling syncClaim: %v", err)
|
||||
// Finish the loop on the first error
|
||||
break
|
||||
}
|
||||
}
|
||||
// Process generated changes
|
||||
continue
|
||||
case *api.PersistentVolume:
|
||||
volume := obj.(*api.PersistentVolume)
|
||||
// Simulate "volume updated" event
|
||||
ctrl.volumes.store.Update(volume)
|
||||
err = ctrl.syncVolume(volume)
|
||||
if err != nil {
|
||||
if err == versionConflictError {
|
||||
// Ignore version errors
|
||||
glog.V(4).Infof("test intentionaly ignores version error.")
|
||||
} else {
|
||||
t.Errorf("Error calling syncVolume: %v", err)
|
||||
// Finish the loop on the first error
|
||||
break
|
||||
}
|
||||
}
|
||||
// Process generated changes
|
||||
continue
|
||||
}
|
||||
}
|
||||
evaluateTestResults(ctrl, reactor, test, t)
|
||||
glog.V(4).Infof("test %q finished after %d iterations", test.name, counter)
|
||||
}
|
||||
}
|
||||
|
@ -377,3 +377,50 @@ func TestSync(t *testing.T) {
|
||||
}
|
||||
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 TestMultiSync(t *testing.T) {
|
||||
tests := []controllerTest{
|
||||
// Test simple binding
|
||||
{
|
||||
// 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),
|
||||
newClaimArray("claim10-1", "uid10-1", "1Gi", "", api.ClaimPending),
|
||||
newClaimArray("claim10-1", "uid10-1", "1Gi", "volume10-1", api.ClaimBound, annBoundByController, annBindCompleted),
|
||||
testSyncClaim,
|
||||
},
|
||||
{
|
||||
// Two controllers bound two PVs to single claim. Test one of them
|
||||
// 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),
|
||||
},
|
||||
[]*api.PersistentVolume{
|
||||
newVolume("volume10-2-1", "1Gi", "uid10-2", "claim10-2", api.VolumeBound, annBoundByController),
|
||||
newVolume("volume10-2-2", "1Gi", "", "", api.VolumeAvailable),
|
||||
},
|
||||
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),
|
||||
testSyncClaim,
|
||||
},
|
||||
}
|
||||
|
||||
runMultisyncTests(t, tests)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user