Fix flaky e2e: Use expectation model for deployment's new rc creation

This commit is contained in:
Janet Kuo 2016-01-08 14:46:08 -08:00
parent 6d367480f9
commit e1554c0f4d

View File

@ -78,7 +78,11 @@ type DeploymentController struct {
podStoreSynced func() bool podStoreSynced func() bool
// A TTLCache of pod creates/deletes each deployment expects to see // A TTLCache of pod creates/deletes each deployment expects to see
expectations controller.ControllerExpectationsInterface podExpectations controller.ControllerExpectationsInterface
// A TTLCache of rc creates/deletes each deployment expects to see
// TODO: make expectation model understand (rc) updates (besides adds and deletes)
rcExpectations controller.ControllerExpectationsInterface
// Deployments that need to be synced // Deployments that need to be synced
queue *workqueue.Type queue *workqueue.Type
@ -95,7 +99,8 @@ func NewDeploymentController(client client.Interface, resyncPeriod controller.Re
expClient: client.Extensions(), expClient: client.Extensions(),
eventRecorder: eventBroadcaster.NewRecorder(api.EventSource{Component: "deployment-controller"}), eventRecorder: eventBroadcaster.NewRecorder(api.EventSource{Component: "deployment-controller"}),
queue: workqueue.New(), queue: workqueue.New(),
expectations: controller.NewControllerExpectations(), podExpectations: controller.NewControllerExpectations(),
rcExpectations: controller.NewControllerExpectations(),
} }
dc.dStore.Store, dc.dController = framework.NewInformer( dc.dStore.Store, dc.dController = framework.NewInformer(
@ -192,6 +197,12 @@ func (dc *DeploymentController) addRC(obj interface{}) {
rc := obj.(*api.ReplicationController) rc := obj.(*api.ReplicationController)
glog.V(4).Infof("Replication controller %s added.", rc.Name) glog.V(4).Infof("Replication controller %s added.", rc.Name)
if d := dc.getDeploymentForRC(rc); rc != nil { if d := dc.getDeploymentForRC(rc); rc != nil {
dKey, err := controller.KeyFunc(d)
if err != nil {
glog.Errorf("Couldn't get key for deployment controller %#v: %v", d, err)
return
}
dc.rcExpectations.CreationObserved(dKey)
dc.enqueueDeployment(d) dc.enqueueDeployment(d)
} }
} }
@ -329,7 +340,7 @@ func (dc *DeploymentController) deletePod(obj interface{}) {
glog.Errorf("Couldn't get key for deployment controller %#v: %v", d, err) glog.Errorf("Couldn't get key for deployment controller %#v: %v", d, err)
return return
} }
dc.expectations.DeletionObserved(dKey) dc.podExpectations.DeletionObserved(dKey)
} }
} }
@ -384,7 +395,8 @@ func (dc *DeploymentController) syncDeployment(key string) error {
} }
if !exists { if !exists {
glog.Infof("Deployment has been deleted %v", key) glog.Infof("Deployment has been deleted %v", key)
dc.expectations.DeleteExpectations(key) dc.podExpectations.DeleteExpectations(key)
dc.rcExpectations.DeleteExpectations(key)
return nil return nil
} }
d := *obj.(*extensions.Deployment) d := *obj.(*extensions.Deployment)
@ -392,7 +404,7 @@ func (dc *DeploymentController) syncDeployment(key string) error {
// Sleep so we give the rc reflector goroutine a chance to run. // Sleep so we give the rc reflector goroutine a chance to run.
time.Sleep(RcStoreSyncedPollPeriod) time.Sleep(RcStoreSyncedPollPeriod)
glog.Infof("Waiting for rc controller to sync, requeuing deployment %s", d.Name) glog.Infof("Waiting for rc controller to sync, requeuing deployment %s", d.Name)
dc.enqueueDeployment(d) dc.enqueueDeployment(&d)
return nil return nil
} }
@ -475,6 +487,15 @@ func (dc *DeploymentController) getNewRC(deployment extensions.Deployment) (*api
if err != nil || existingNewRC != nil { if err != nil || existingNewRC != nil {
return existingNewRC, err return existingNewRC, err
} }
// Check the rc expectations of deployment before creating a new rc
dKey, err := controller.KeyFunc(&deployment)
if err != nil {
return nil, fmt.Errorf("couldn't get key for deployment %#v: %v", deployment, err)
}
if !dc.rcExpectations.SatisfiedExpectations(dKey) {
dc.enqueueDeployment(&deployment)
return nil, fmt.Errorf("RC expectations not met yet before getting new RC\n")
}
// new RC does not exist, create one. // new RC does not exist, create one.
namespace := deployment.ObjectMeta.Namespace namespace := deployment.ObjectMeta.Namespace
podTemplateSpecHash := deploymentutil.GetPodTemplateSpecHash(deployment.Spec.Template) podTemplateSpecHash := deploymentutil.GetPodTemplateSpecHash(deployment.Spec.Template)
@ -482,6 +503,13 @@ func (dc *DeploymentController) getNewRC(deployment extensions.Deployment) (*api
// Add podTemplateHash label to selector. // Add podTemplateHash label to selector.
newRCSelector := deploymentutil.CloneAndAddLabel(deployment.Spec.Selector, deployment.Spec.UniqueLabelKey, podTemplateSpecHash) newRCSelector := deploymentutil.CloneAndAddLabel(deployment.Spec.Selector, deployment.Spec.UniqueLabelKey, podTemplateSpecHash)
// Set RC expectations (1 rc should be created)
dKey, err = controller.KeyFunc(&deployment)
if err != nil {
return nil, fmt.Errorf("couldn't get key for deployment controller %#v: %v", deployment, err)
}
dc.rcExpectations.ExpectCreations(dKey, 1)
// Create new RC
newRC := api.ReplicationController{ newRC := api.ReplicationController{
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
GenerateName: deployment.Name + "-", GenerateName: deployment.Name + "-",
@ -495,6 +523,7 @@ func (dc *DeploymentController) getNewRC(deployment extensions.Deployment) (*api
} }
createdRC, err := dc.client.ReplicationControllers(namespace).Create(&newRC) createdRC, err := dc.client.ReplicationControllers(namespace).Create(&newRC)
if err != nil { if err != nil {
dc.rcExpectations.DeleteExpectations(dKey)
return nil, fmt.Errorf("error creating replication controller: %v", err) return nil, fmt.Errorf("error creating replication controller: %v", err)
} }
return createdRC, nil return createdRC, nil
@ -556,8 +585,8 @@ func (dc *DeploymentController) reconcileOldRCs(allRCs []*api.ReplicationControl
if err != nil { if err != nil {
return false, fmt.Errorf("Couldn't get key for deployment %#v: %v", deployment, err) return false, fmt.Errorf("Couldn't get key for deployment %#v: %v", deployment, err)
} }
if expectationsCheck && !dc.expectations.SatisfiedExpectations(dKey) { if expectationsCheck && !dc.podExpectations.SatisfiedExpectations(dKey) {
fmt.Printf("Expectations not met yet before reconciling old RCs\n") glog.V(4).Infof("Pod expectations not met yet before reconciling old RCs\n")
return false, nil return false, nil
} }
// Find the number of ready pods. // Find the number of ready pods.
@ -593,7 +622,7 @@ func (dc *DeploymentController) reconcileOldRCs(allRCs []*api.ReplicationControl
return false, fmt.Errorf("Couldn't get key for deployment %#v: %v", deployment, err) return false, fmt.Errorf("Couldn't get key for deployment %#v: %v", deployment, err)
} }
if expectationsCheck { if expectationsCheck {
dc.expectations.ExpectDeletions(dKey, scaleDownCount) dc.podExpectations.ExpectDeletions(dKey, scaleDownCount)
} }
} }
return true, err return true, err