Commit 2d43e454 authored by Jan Safranek's avatar Jan Safranek

Fix data race in volume controller unit test.

Reactor must be locked when fiddling with reactor.volumes and reactor.claims. Therefore add new functions to add/delete volume/claim with sending an event.
parent c0dfccc3
...@@ -25,7 +25,6 @@ import ( ...@@ -25,7 +25,6 @@ import (
"k8s.io/kubernetes/pkg/client/cache" "k8s.io/kubernetes/pkg/client/cache"
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake" "k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset/fake"
"k8s.io/kubernetes/pkg/controller/framework" "k8s.io/kubernetes/pkg/controller/framework"
"k8s.io/kubernetes/pkg/conversion"
) )
// Test the real controller methods (add/update/delete claim/volume) with // Test the real controller methods (add/update/delete claim/volume) with
...@@ -52,8 +51,7 @@ func TestControllerSync(t *testing.T) { ...@@ -52,8 +51,7 @@ func TestControllerSync(t *testing.T) {
// Custom test function that generates an add event // Custom test function that generates an add event
func(ctrl *PersistentVolumeController, reactor *volumeReactor, test controllerTest) error { func(ctrl *PersistentVolumeController, reactor *volumeReactor, test controllerTest) error {
claim := newClaim("claim5-2", "uid5-2", "1Gi", "", api.ClaimPending) claim := newClaim("claim5-2", "uid5-2", "1Gi", "", api.ClaimPending)
reactor.claims[claim.Name] = claim reactor.addClaimEvent(claim)
reactor.claimSource.Add(claim)
return nil return nil
}, },
}, },
...@@ -69,14 +67,7 @@ func TestControllerSync(t *testing.T) { ...@@ -69,14 +67,7 @@ func TestControllerSync(t *testing.T) {
func(ctrl *PersistentVolumeController, reactor *volumeReactor, test controllerTest) error { func(ctrl *PersistentVolumeController, reactor *volumeReactor, test controllerTest) error {
obj := ctrl.claims.List()[0] obj := ctrl.claims.List()[0]
claim := obj.(*api.PersistentVolumeClaim) claim := obj.(*api.PersistentVolumeClaim)
// Remove the claim from list of resulting claims. reactor.deleteClaimEvent(claim)
delete(reactor.claims, claim.Name)
// Poke the controller with deletion event. Cloned claim is
// needed to prevent races (and we would get a clone from etcd
// too).
clone, _ := conversion.NewCloner().DeepCopy(claim)
claimClone := clone.(*api.PersistentVolumeClaim)
reactor.claimSource.Delete(claimClone)
return nil return nil
}, },
}, },
...@@ -92,14 +83,7 @@ func TestControllerSync(t *testing.T) { ...@@ -92,14 +83,7 @@ func TestControllerSync(t *testing.T) {
func(ctrl *PersistentVolumeController, reactor *volumeReactor, test controllerTest) error { func(ctrl *PersistentVolumeController, reactor *volumeReactor, test controllerTest) error {
obj := ctrl.volumes.store.List()[0] obj := ctrl.volumes.store.List()[0]
volume := obj.(*api.PersistentVolume) volume := obj.(*api.PersistentVolume)
// Remove the volume from list of resulting volumes. reactor.deleteVolumeEvent(volume)
delete(reactor.volumes, volume.Name)
// Poke the controller with deletion event. Cloned volume is
// needed to prevent races (and we would get a clone from etcd
// too).
clone, _ := conversion.NewCloner().DeepCopy(volume)
volumeClone := clone.(*api.PersistentVolume)
reactor.volumeSource.Delete(volumeClone)
return nil return nil
}, },
}, },
......
...@@ -472,6 +472,62 @@ func (r *volumeReactor) waitTest() { ...@@ -472,6 +472,62 @@ func (r *volumeReactor) waitTest() {
} }
} }
// deleteVolumeEvent simulates that a volume has been deleted in etcd and
// the controller receives 'volume deleted' event.
func (r *volumeReactor) deleteVolumeEvent(volume *api.PersistentVolume) {
r.lock.Lock()
defer r.lock.Unlock()
// Remove the volume from list of resulting volumes.
delete(r.volumes, volume.Name)
// Generate deletion event. Cloned volume is needed to prevent races (and we
// would get a clone from etcd too).
clone, _ := conversion.NewCloner().DeepCopy(volume)
volumeClone := clone.(*api.PersistentVolume)
r.volumeSource.Delete(volumeClone)
}
// deleteClaimEvent simulates that a claim has been deleted in etcd and the
// controller receives 'claim deleted' event.
func (r *volumeReactor) deleteClaimEvent(claim *api.PersistentVolumeClaim) {
r.lock.Lock()
defer r.lock.Unlock()
// Remove the claim from list of resulting claims.
delete(r.claims, claim.Name)
// Generate deletion event. Cloned volume is needed to prevent races (and we
// would get a clone from etcd too).
clone, _ := conversion.NewCloner().DeepCopy(claim)
claimClone := clone.(*api.PersistentVolumeClaim)
r.claimSource.Delete(claimClone)
}
// addVolumeEvent simulates that a volume has been added in etcd and the
// controller receives 'volume added' event.
func (r *volumeReactor) addVolumeEvent(volume *api.PersistentVolume) {
r.lock.Lock()
defer r.lock.Unlock()
r.volumes[volume.Name] = volume
// Generate event. No cloning is needed, this claim is not stored in the
// controller cache yet.
r.volumeSource.Add(volume)
}
// addClaimEvent simulates that a claim has been deleted in etcd and the
// controller receives 'claim added' event.
func (r *volumeReactor) addClaimEvent(claim *api.PersistentVolumeClaim) {
r.lock.Lock()
defer r.lock.Unlock()
r.claims[claim.Name] = claim
// Generate event. No cloning is needed, this claim is not stored in the
// controller cache yet.
r.claimSource.Add(claim)
}
func newVolumeReactor(client *fake.Clientset, ctrl *PersistentVolumeController, volumeSource, claimSource *framework.FakeControllerSource, errors []reactorError) *volumeReactor { func newVolumeReactor(client *fake.Clientset, ctrl *PersistentVolumeController, volumeSource, claimSource *framework.FakeControllerSource, errors []reactorError) *volumeReactor {
reactor := &volumeReactor{ reactor := &volumeReactor{
volumes: make(map[string]*api.PersistentVolume), volumes: make(map[string]*api.PersistentVolume),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment