diff --git a/test/e2e/deployment.go b/test/e2e/deployment.go index 91783a39c89..e63a057fee1 100644 --- a/test/e2e/deployment.go +++ b/test/e2e/deployment.go @@ -550,6 +550,9 @@ func testRolloverDeployment(f *framework.Framework) { framework.Logf("error in waiting for pods to come up: %s", err) Expect(err).NotTo(HaveOccurred()) } + // Wait for replica set to become fully available before adopting it. + framework.Logf("Waiting for replica set %q to become fully available", rsName) + Expect(framework.WaitForAvailableReplicaSet(c, ns, rsName)).NotTo(HaveOccurred()) // Create a deployment to delete nginx pods and instead bring up redis-slave pods. // We use a nonexistent image here, so that we make sure it won't finish diff --git a/test/e2e/framework/util.go b/test/e2e/framework/util.go index a48b9cf7bcd..36069ccecd1 100644 --- a/test/e2e/framework/util.go +++ b/test/e2e/framework/util.go @@ -2954,6 +2954,26 @@ func waitForReplicaSetPodsGone(c clientset.Interface, rs *extensions.ReplicaSet) }) } +// WaitForAvailableReplicaSet waits until the replica set has all of its replicas available +// and is observed by the replica set controller. +func WaitForAvailableReplicaSet(c clientset.Interface, ns, name string) error { + var status extensions.ReplicaSetStatus + err := wait.PollImmediate(Poll, 5*time.Minute, func() (bool, error) { + rs, err := c.Extensions().ReplicaSets(ns).Get(name) + if err != nil { + return false, err + } + status = rs.Status + return rs.Status.ObservedGeneration >= rs.Generation && + *(rs.Spec.Replicas) == rs.Status.Replicas && + *(rs.Spec.Replicas) == rs.Status.AvailableReplicas, nil + }) + if err == wait.ErrWaitTimeout { + err = fmt.Errorf("replica set %q never became available: %#v", name, status) + } + return err +} + // Waits for the deployment status to become valid (i.e. max unavailable and max surge aren't violated anymore). // Note that the status should stay valid at all times unless shortly after a scaling event or the deployment is just created. // To verify that the deployment status is valid and wait for the rollout to finish, use WaitForDeploymentStatus instead. @@ -2965,7 +2985,7 @@ func WaitForDeploymentStatusValid(c clientset.Interface, d *extensions.Deploymen reason string ) - err := wait.Poll(Poll, 5*time.Minute, func() (bool, error) { + err := wait.PollImmediate(Poll, 5*time.Minute, func() (bool, error) { var err error deployment, err = c.Extensions().Deployments(d.Namespace).Get(d.Name) if err != nil { @@ -3037,7 +3057,7 @@ func WaitForDeploymentStatus(c clientset.Interface, d *extensions.Deployment) er deployment *extensions.Deployment ) - err := wait.Poll(Poll, 5*time.Minute, func() (bool, error) { + err := wait.PollImmediate(Poll, 5*time.Minute, func() (bool, error) { var err error deployment, err = c.Extensions().Deployments(d.Namespace).Get(d.Name) if err != nil { @@ -3092,7 +3112,7 @@ func WaitForDeploymentStatus(c clientset.Interface, d *extensions.Deployment) er // WaitForDeploymentUpdatedReplicasLTE waits for given deployment to be observed by the controller and has at least a number of updatedReplicas func WaitForDeploymentUpdatedReplicasLTE(c clientset.Interface, ns, deploymentName string, minUpdatedReplicas int, desiredGeneration int64) error { - err := wait.Poll(Poll, 5*time.Minute, func() (bool, error) { + err := wait.PollImmediate(Poll, 5*time.Minute, func() (bool, error) { deployment, err := c.Extensions().Deployments(ns).Get(deploymentName) if err != nil { return false, err @@ -3111,7 +3131,7 @@ func WaitForDeploymentUpdatedReplicasLTE(c clientset.Interface, ns, deploymentNa // WaitForDeploymentRollbackCleared waits for given deployment either started rolling back or doesn't need to rollback. // Note that rollback should be cleared shortly, so we only wait for 1 minute here to fail early. func WaitForDeploymentRollbackCleared(c clientset.Interface, ns, deploymentName string) error { - err := wait.Poll(Poll, 1*time.Minute, func() (bool, error) { + err := wait.PollImmediate(Poll, 1*time.Minute, func() (bool, error) { deployment, err := c.Extensions().Deployments(ns).Get(deploymentName) if err != nil { return false, err @@ -3133,7 +3153,7 @@ func WaitForDeploymentRollbackCleared(c clientset.Interface, ns, deploymentName func WaitForDeploymentRevisionAndImage(c clientset.Interface, ns, deploymentName string, revision, image string) error { var deployment *extensions.Deployment var newRS *extensions.ReplicaSet - err := wait.Poll(Poll, 1*time.Minute, func() (bool, error) { + err := wait.PollImmediate(Poll, 1*time.Minute, func() (bool, error) { var err error deployment, err = c.Extensions().Deployments(ns).Get(deploymentName) if err != nil { @@ -3165,7 +3185,7 @@ func WaitForDeploymentRevisionAndImage(c clientset.Interface, ns, deploymentName } func WaitForOverlappingAnnotationMatch(c clientset.Interface, ns, deploymentName, expected string) error { - return wait.Poll(Poll, 1*time.Minute, func() (bool, error) { + return wait.PollImmediate(Poll, 1*time.Minute, func() (bool, error) { deployment, err := c.Extensions().Deployments(ns).Get(deploymentName) if err != nil { return false, err @@ -3199,7 +3219,7 @@ func CheckNewRSAnnotations(c clientset.Interface, ns, deploymentName string, exp func WaitForPodsReady(c clientset.Interface, ns, name string, minReadySeconds int) error { label := labels.SelectorFromSet(labels.Set(map[string]string{"name": name})) options := v1.ListOptions{LabelSelector: label.String()} - return wait.Poll(Poll, 5*time.Minute, func() (bool, error) { + return wait.PollImmediate(Poll, 5*time.Minute, func() (bool, error) { pods, err := c.Core().Pods(ns).List(options) if err != nil { return false, nil @@ -3215,7 +3235,7 @@ func WaitForPodsReady(c clientset.Interface, ns, name string, minReadySeconds in // Waits for the deployment to clean up old rcs. func WaitForDeploymentOldRSsNum(c clientset.Interface, ns, deploymentName string, desiredRSNum int) error { - return wait.Poll(Poll, 5*time.Minute, func() (bool, error) { + return wait.PollImmediate(Poll, 5*time.Minute, func() (bool, error) { deployment, err := c.Extensions().Deployments(ns).Get(deploymentName) if err != nil { return false, err