Merge pull request #54819 from janetkuo/dep-inte-rolling

Automatic merge from submit-queue (batch tested with PRs 54493, 52501, 55172, 54780, 54819). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

Add integration test for deployment rolling update, rollback, rollover

**What this PR does / why we need it**:

**Which issue this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*: ref #52113

**Special notes for your reviewer**:

**Release note**:

```release-note
NONE
```
This commit is contained in:
Kubernetes Submit Queue
2017-11-08 15:41:26 -08:00
committed by GitHub
3 changed files with 155 additions and 14 deletions

View File

@@ -19,6 +19,7 @@ package deployment
import (
"fmt"
"net/http/httptest"
"sync"
"testing"
"time"
@@ -211,40 +212,50 @@ func markPodReady(c clientset.Interface, ns string, pod *v1.Pod) error {
return err
}
// markUpdatedPodsReady manually marks updated Deployment pods status to ready
func (d *deploymentTester) markUpdatedPodsReady() {
// markUpdatedPodsReady manually marks updated Deployment pods status to ready,
// until the deployment is complete
func (d *deploymentTester) markUpdatedPodsReady(wg *sync.WaitGroup) {
defer wg.Done()
ns := d.deployment.Namespace
var readyPods int32
err := wait.PollImmediate(pollInterval, pollTimeout, func() (bool, error) {
readyPods = 0
// We're done when the deployment is complete
if completed, err := d.deploymentComplete(); err != nil {
return false, err
} else if completed {
return true, nil
}
// Otherwise, mark remaining pods as ready
pods, err := d.listUpdatedPods()
if err != nil {
d.t.Log(err)
return false, nil
}
if len(pods) != int(*d.deployment.Spec.Replicas) {
d.t.Logf("%d/%d of deployment pods are created", len(pods), *d.deployment.Spec.Replicas)
return false, nil
}
d.t.Logf("%d/%d of deployment pods are created", len(pods), *d.deployment.Spec.Replicas)
for i := range pods {
pod := pods[i]
if podutil.IsPodReady(&pod) {
readyPods++
continue
}
if err = markPodReady(d.c, ns, &pod); err != nil {
d.t.Logf("failed to update Deployment pod %s, will retry later: %v", pod.Name, err)
} else {
readyPods++
}
}
return readyPods >= *d.deployment.Spec.Replicas, nil
return false, nil
})
if err != nil {
d.t.Fatalf("failed to mark updated Deployment pods to ready: %v", err)
}
}
func (d *deploymentTester) deploymentComplete() (bool, error) {
latest, err := d.c.ExtensionsV1beta1().Deployments(d.deployment.Namespace).Get(d.deployment.Name, metav1.GetOptions{})
if err != nil {
return false, err
}
return deploymentutil.DeploymentComplete(d.deployment, &latest.Status), nil
}
// Waits for the deployment to complete, and check rolling update strategy isn't broken at any times.
// Rolling update strategy should not be broken during a rolling update.
func (d *deploymentTester) waitForDeploymentCompleteAndCheckRolling() error {
@@ -262,28 +273,42 @@ func (d *deploymentTester) waitForDeploymentComplete() error {
// while marking updated Deployment pods as ready at the same time.
// Uses hard check to make sure rolling update strategy is not violated at any times.
func (d *deploymentTester) waitForDeploymentCompleteAndCheckRollingAndMarkPodsReady() error {
var wg sync.WaitGroup
// Manually mark updated Deployment pods as ready in a separate goroutine
go d.markUpdatedPodsReady()
wg.Add(1)
go d.markUpdatedPodsReady(&wg)
// Wait for the Deployment status to complete while Deployment pods are becoming ready
err := d.waitForDeploymentCompleteAndCheckRolling()
if err != nil {
return fmt.Errorf("failed to wait for Deployment %s to complete: %v", d.deployment.Name, err)
}
// Wait for goroutine to finish
wg.Wait()
return nil
}
// waitForDeploymentCompleteAndMarkPodsReady waits for the Deployment to complete
// while marking updated Deployment pods as ready at the same time.
func (d *deploymentTester) waitForDeploymentCompleteAndMarkPodsReady() error {
var wg sync.WaitGroup
// Manually mark updated Deployment pods as ready in a separate goroutine
go d.markUpdatedPodsReady()
wg.Add(1)
go d.markUpdatedPodsReady(&wg)
// Wait for the Deployment status to complete using soft check, while Deployment pods are becoming ready
err := d.waitForDeploymentComplete()
if err != nil {
return fmt.Errorf("failed to wait for Deployment status %s: %v", d.deployment.Name, err)
}
// Wait for goroutine to finish
wg.Wait()
return nil
}