Move paused deployment e2e tests to integration

This commit is contained in:
Janet Kuo
2017-09-06 13:42:26 -07:00
parent 4b63c1fb90
commit 124344a1a4
7 changed files with 246 additions and 185 deletions

View File

@@ -18,6 +18,7 @@ go_test(
"//pkg/controller/deployment/util:go_default_library",
"//test/integration/framework:go_default_library",
"//vendor/k8s.io/api/core/v1:go_default_library",
"//vendor/k8s.io/api/extensions/v1beta1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
],
)
@@ -28,6 +29,7 @@ go_library(
deps = [
"//pkg/api/v1/pod:go_default_library",
"//pkg/controller/deployment:go_default_library",
"//pkg/controller/deployment/util:go_default_library",
"//pkg/controller/replicaset:go_default_library",
"//test/integration/framework:go_default_library",
"//test/utils:go_default_library",

View File

@@ -22,6 +22,7 @@ import (
"testing"
"k8s.io/api/core/v1"
"k8s.io/api/extensions/v1beta1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
deploymentutil "k8s.io/kubernetes/pkg/controller/deployment/util"
"k8s.io/kubernetes/test/integration/framework"
@@ -39,9 +40,10 @@ func TestNewDeployment(t *testing.T) {
tester.deployment.Spec.MinReadySeconds = 4
tester.deployment.Annotations = map[string]string{"test": "should-copy-to-replica-set", v1.LastAppliedConfigAnnotation: "should-not-copy-to-replica-set"}
deploy, err := c.Extensions().Deployments(ns.Name).Create(tester.deployment)
var err error
tester.deployment, err = c.ExtensionsV1beta1().Deployments(ns.Name).Create(tester.deployment)
if err != nil {
t.Fatalf("failed to create deployment %s: %v", deploy.Name, err)
t.Fatalf("failed to create deployment %s: %v", tester.deployment.Name, err)
}
// Start informer and controllers
@@ -52,24 +54,18 @@ func TestNewDeployment(t *testing.T) {
go dc.Run(5, stopCh)
// Wait for the Deployment to be updated to revision 1
err = tester.waitForDeploymentRevisionAndImage("1", fakeImage)
if err != nil {
t.Fatalf("failed to wait for Deployment revision %s: %v", deploy.Name, err)
}
tester.waitForDeploymentRevisionAndImage("1", fakeImage)
// Make sure the Deployment status becomes valid while manually marking Deployment pods as ready at the same time
tester.waitForDeploymentStatusValidAndMarkPodsReady()
// Check new RS annotations
newRS, err := deploymentutil.GetNewReplicaSet(deploy, c.ExtensionsV1beta1())
if err != nil {
t.Fatalf("failed to get new ReplicaSet of Deployment %s: %v", deploy.Name, err)
}
newRS := tester.expectNewReplicaSet()
if newRS.Annotations["test"] != "should-copy-to-replica-set" {
t.Errorf("expected new ReplicaSet annotations copied from Deployment %s, got: %v", deploy.Name, newRS.Annotations)
t.Errorf("expected new ReplicaSet annotations copied from Deployment %s, got: %v", tester.deployment.Name, newRS.Annotations)
}
if newRS.Annotations[v1.LastAppliedConfigAnnotation] != "" {
t.Errorf("expected new ReplicaSet last-applied annotation not copied from Deployment %s", deploy.Name)
t.Errorf("expected new ReplicaSet last-applied annotation not copied from Deployment %s", tester.deployment.Name)
}
}
@@ -134,3 +130,154 @@ func TestDeploymentSelectorImmutability(t *testing.T) {
t.Errorf("error message does not match, expected type: %s, expected detail: %s, got: %s", expectedErrType, expectedErrDetail, err.Error())
}
}
// Paused deployment should not start new rollout
func TestPausedDeployment(t *testing.T) {
s, closeFn, rm, dc, informers, c := dcSetup(t)
defer closeFn()
name := "test-paused-deployment"
ns := framework.CreateTestingNamespace(name, s, t)
defer framework.DeleteTestingNamespace(ns, s, t)
replicas := int32(1)
tester := &deploymentTester{t: t, c: c, deployment: newDeployment(name, ns.Name, replicas)}
tester.deployment.Spec.Paused = true
tgps := int64(1)
tester.deployment.Spec.Template.Spec.TerminationGracePeriodSeconds = &tgps
var err error
tester.deployment, err = c.ExtensionsV1beta1().Deployments(ns.Name).Create(tester.deployment)
if err != nil {
t.Fatalf("failed to create deployment %s: %v", tester.deployment.Name, err)
}
// Start informer and controllers
stopCh := make(chan struct{})
defer close(stopCh)
informers.Start(stopCh)
go rm.Run(5, stopCh)
go dc.Run(5, stopCh)
// Verify that the paused deployment won't create new replica set.
tester.expectNoNewReplicaSet()
// Resume the deployment
tester.deployment, err = tester.updateDeployment(resumeFn())
if err != nil {
t.Errorf("failed to resume deployment %s: %v", tester.deployment.Name, err)
}
// Wait for the controller to notice the resume.
tester.waitForObservedDeployment(tester.deployment.Generation)
// Wait for the Deployment to be updated to revision 1
tester.waitForDeploymentRevisionAndImage("1", fakeImage)
// Make sure the Deployment status becomes valid while manually marking Deployment pods as ready at the same time
tester.waitForDeploymentStatusValidAndMarkPodsReady()
// A new replicaset should be created.
tester.expectNewReplicaSet()
// Pause the deployment.
// The paused deployment shouldn't trigger a new rollout.
tester.deployment, err = tester.updateDeployment(pauseFn())
if err != nil {
t.Errorf("failed to pause deployment %s: %v", tester.deployment.Name, err)
}
// Wait for the controller to notice the pause.
tester.waitForObservedDeployment(tester.deployment.Generation)
// Update the deployment template
newTGPS := int64(0)
tester.deployment, err = tester.updateDeployment(func(update *v1beta1.Deployment) {
update.Spec.Template.Spec.TerminationGracePeriodSeconds = &newTGPS
})
if err != nil {
t.Errorf("failed updating deployment %s: %v", tester.deployment.Name, err)
}
// Wait for the controller to notice the rollout.
tester.waitForObservedDeployment(tester.deployment.Generation)
// Verify that the paused deployment won't create new replica set.
tester.expectNoNewReplicaSet()
_, allOldRs, err := deploymentutil.GetOldReplicaSets(tester.deployment, c.ExtensionsV1beta1())
if err != nil {
t.Errorf("failed retrieving old replicasets of deployment %s: %v", tester.deployment.Name, err)
}
if len(allOldRs) != 1 {
t.Errorf("expected an old replica set, got %v", allOldRs)
}
if *allOldRs[0].Spec.Template.Spec.TerminationGracePeriodSeconds == newTGPS {
t.Errorf("TerminationGracePeriodSeconds on the replica set should be %d, got %d", tgps, newTGPS)
}
}
// Paused deployment can be scaled
func TestScalePausedDeployment(t *testing.T) {
s, closeFn, rm, dc, informers, c := dcSetup(t)
defer closeFn()
name := "test-scale-paused-deployment"
ns := framework.CreateTestingNamespace(name, s, t)
defer framework.DeleteTestingNamespace(ns, s, t)
replicas := int32(1)
tester := &deploymentTester{t: t, c: c, deployment: newDeployment(name, ns.Name, replicas)}
tgps := int64(1)
tester.deployment.Spec.Template.Spec.TerminationGracePeriodSeconds = &tgps
var err error
tester.deployment, err = c.ExtensionsV1beta1().Deployments(ns.Name).Create(tester.deployment)
if err != nil {
t.Fatalf("failed to create deployment %s: %v", tester.deployment.Name, err)
}
// Start informer and controllers
stopCh := make(chan struct{})
defer close(stopCh)
informers.Start(stopCh)
go rm.Run(5, stopCh)
go dc.Run(5, stopCh)
// Wait for the Deployment to be updated to revision 1
tester.waitForDeploymentRevisionAndImage("1", fakeImage)
// Make sure the Deployment status becomes valid while manually marking Deployment pods as ready at the same time
tester.waitForDeploymentStatusValidAndMarkPodsReady()
// A new replicaset should be created.
tester.expectNewReplicaSet()
// Pause the deployment.
tester.deployment, err = tester.updateDeployment(pauseFn())
if err != nil {
t.Errorf("failed to pause deployment %s: %v", tester.deployment.Name, err)
}
// Wait for the controller to notice the scale.
tester.waitForObservedDeployment(tester.deployment.Generation)
// Scale the paused deployment.
newReplicas := int32(10)
tester.deployment, err = tester.updateDeployment(func(update *v1beta1.Deployment) {
update.Spec.Replicas = &newReplicas
})
if err != nil {
t.Errorf("failed updating deployment %s: %v", tester.deployment.Name, err)
}
// Wait for the controller to notice the scale.
tester.waitForObservedDeployment(tester.deployment.Generation)
// Verify that the new replicaset is scaled.
rs := tester.expectNewReplicaSet()
if *rs.Spec.Replicas != newReplicas {
t.Errorf("expected new replicaset replicas = %d, got %d", newReplicas, *rs.Spec.Replicas)
}
// Make sure the Deployment status becomes valid while manually marking Deployment pods as ready at the same time
tester.waitForDeploymentStatusValidAndMarkPodsReady()
}

View File

@@ -30,6 +30,7 @@ import (
restclient "k8s.io/client-go/rest"
podutil "k8s.io/kubernetes/pkg/api/v1/pod"
"k8s.io/kubernetes/pkg/controller/deployment"
deploymentutil "k8s.io/kubernetes/pkg/controller/deployment/util"
"k8s.io/kubernetes/pkg/controller/replicaset"
"k8s.io/kubernetes/test/integration/framework"
testutil "k8s.io/kubernetes/test/utils"
@@ -143,8 +144,10 @@ func addPodConditionReady(pod *v1.Pod, time metav1.Time) {
}
}
func (d *deploymentTester) waitForDeploymentRevisionAndImage(revision, image string) error {
return testutil.WaitForDeploymentRevisionAndImage(d.c, d.deployment.Namespace, d.deployment.Name, revision, image, d.t.Logf, pollInterval, pollTimeout)
func (d *deploymentTester) waitForDeploymentRevisionAndImage(revision, image string) {
if err := testutil.WaitForDeploymentRevisionAndImage(d.c, d.deployment.Namespace, d.deployment.Name, revision, image, d.t.Logf, pollInterval, pollTimeout); err != nil {
d.t.Fatalf("failed to wait for Deployment revision %s: %v", d.deployment.Name, err)
}
}
// markAllPodsReady manually updates all Deployment pods status to ready
@@ -201,3 +204,48 @@ func (d *deploymentTester) waitForDeploymentStatusValidAndMarkPodsReady() {
d.t.Fatalf("failed to wait for Deployment status %s: %v", d.deployment.Name, err)
}
}
func (d *deploymentTester) updateDeployment(applyUpdate testutil.UpdateDeploymentFunc) (*v1beta1.Deployment, error) {
return testutil.UpdateDeploymentWithRetries(d.c, d.deployment.Namespace, d.deployment.Name, applyUpdate, d.t.Logf)
}
func (d *deploymentTester) waitForObservedDeployment(desiredGeneration int64) {
if err := testutil.WaitForObservedDeployment(d.c, d.deployment.Namespace, d.deployment.Name, desiredGeneration); err != nil {
d.t.Fatalf("failed waiting for ObservedGeneration of deployment %s to become %d: %v", d.deployment.Name, desiredGeneration, err)
}
}
func (d *deploymentTester) getNewReplicaSet() *v1beta1.ReplicaSet {
rs, err := deploymentutil.GetNewReplicaSet(d.deployment, d.c.ExtensionsV1beta1())
if err != nil {
d.t.Fatalf("failed retrieving new replicaset of deployment %s: %v", d.deployment.Name, err)
}
return rs
}
func (d *deploymentTester) expectNoNewReplicaSet() {
rs := d.getNewReplicaSet()
if rs != nil {
d.t.Fatalf("expected deployment %s not to create a new replicaset, got %v", d.deployment.Name, rs)
}
}
func (d *deploymentTester) expectNewReplicaSet() *v1beta1.ReplicaSet {
rs := d.getNewReplicaSet()
if rs == nil {
d.t.Fatalf("expected deployment %s to create a new replicaset, got nil", d.deployment.Name)
}
return rs
}
func pauseFn() func(update *v1beta1.Deployment) {
return func(update *v1beta1.Deployment) {
update.Spec.Paused = true
}
}
func resumeFn() func(update *v1beta1.Deployment) {
return func(update *v1beta1.Deployment) {
update.Spec.Paused = false
}
}