Skip to content

Commit de420ff

Browse files
committed
Test DC's AvailableReplicas reporting when MinReadySeconds set
1 parent 83ec4e2 commit de420ff

File tree

4 files changed

+78
-37
lines changed

4 files changed

+78
-37
lines changed

test/extended/deployments/deployments.go

Lines changed: 68 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package deployments
22

33
import (
4+
//"errors"
45
"fmt"
56
"math/rand"
67
"strings"
@@ -9,11 +10,11 @@ import (
910
g "github.com/onsi/ginkgo"
1011
o "github.com/onsi/gomega"
1112

12-
"k8s.io/apimachinery/pkg/api/errors"
13+
kerrors "k8s.io/apimachinery/pkg/api/errors"
1314
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
14-
"k8s.io/apimachinery/pkg/labels"
1515
"k8s.io/apimachinery/pkg/types"
1616
"k8s.io/apimachinery/pkg/util/wait"
17+
"k8s.io/apimachinery/pkg/watch"
1718
kapiv1 "k8s.io/kubernetes/pkg/api/v1"
1819
kcontroller "k8s.io/kubernetes/pkg/controller"
1920
e2e "k8s.io/kubernetes/test/e2e/framework"
@@ -382,7 +383,7 @@ var _ = g.Describe("deploymentconfigs", func() {
382383
var istag *imageapi.ImageStreamTag
383384
pollErr := wait.PollImmediate(100*time.Millisecond, 1*time.Minute, func() (bool, error) {
384385
istag, err = oc.Client().ImageStreamTags(oc.Namespace()).Get("sample-stream", "deployed")
385-
if errors.IsNotFound(err) {
386+
if kerrors.IsNotFound(err) {
386387
return false, nil
387388
}
388389
if err != nil {
@@ -882,53 +883,85 @@ var _ = g.Describe("deploymentconfigs", func() {
882883
})
883884

884885
g.Describe("with minimum ready seconds set [Conformance]", func() {
886+
dc := readDCFixtureOrDie(minReadySecondsFixture)
887+
rcName := func(i int) string { return fmt.Sprintf("%s-%d", dc.Name, i) }
885888
g.AfterEach(func() {
886-
failureTrap(oc, "minreadytest", g.CurrentGinkgoTestDescription().Failed)
889+
failureTrap(oc, dc.Name, g.CurrentGinkgoTestDescription().Failed)
887890
})
888891

889892
g.It("should not transition the deployment to Complete before satisfied", func() {
890-
_, name, err := createFixture(oc, minReadySecondsFixture)
893+
namespace := oc.Namespace()
894+
watcher, err := oc.KubeClient().CoreV1().ReplicationControllers(namespace).Watch(metav1.SingleObject(metav1.ObjectMeta{Name: rcName(1), ResourceVersion: ""}))
891895
o.Expect(err).NotTo(o.HaveOccurred())
892896

893-
g.By("verifying the deployment is marked running")
894-
o.Expect(waitForLatestCondition(oc, name, deploymentRunTimeout, deploymentRunning)).NotTo(o.HaveOccurred())
897+
o.Expect(dc.Spec.Triggers).To(o.BeNil())
898+
// FIXME: remove when tests are migrated to the new client
899+
// (the old one incorrectly translates nil into an empty array)
900+
dc.Spec.Triggers = append(dc.Spec.Triggers, deployapi.DeploymentTriggerPolicy{Type: deployapi.DeploymentTriggerOnConfigChange})
901+
dc, err = oc.Client().DeploymentConfigs(namespace).Create(dc)
902+
903+
g.By("verifying the deployment is created")
904+
rcEvent, err := watch.Until(deploymentChangeTimeout, watcher, func(event watch.Event) (bool, error) {
905+
if event.Type == watch.Added {
906+
return true, nil
907+
}
908+
return false, fmt.Errorf("different kind of event appeared while waiting for Added event: %#v", event)
909+
})
910+
o.Expect(err).NotTo(o.HaveOccurred())
911+
rc1 := rcEvent.Object.(*kapiv1.ReplicationController)
895912

896913
g.By("verifying that all pods are ready")
897-
config, err := oc.Client().DeploymentConfigs(oc.Namespace()).Get(name, metav1.GetOptions{})
914+
rc1, err = waitForRCModification(oc, namespace, rc1.Name, deploymentRunTimeout,
915+
rc1.GetResourceVersion(), func(rc *kapiv1.ReplicationController) (bool, error) {
916+
return rc.Status.ReadyReplicas == dc.Spec.Replicas, nil
917+
})
898918
o.Expect(err).NotTo(o.HaveOccurred())
919+
o.Expect(rc1.Status.AvailableReplicas).To(o.BeZero())
899920

900-
selector := labels.Set(config.Spec.Selector).AsSelector()
901-
opts := metav1.ListOptions{LabelSelector: selector.String()}
902-
ready := 0
903-
if err := wait.PollImmediate(500*time.Millisecond, 3*time.Minute, func() (bool, error) {
904-
pods, err := oc.KubeClient().CoreV1().Pods(oc.Namespace()).List(opts)
905-
if err != nil {
906-
return false, nil
907-
}
921+
g.By("verifying that the deployment is still running")
922+
o.Expect(err).NotTo(o.HaveOccurred())
923+
if deployutil.IsTerminatedDeployment(rc1) {
924+
o.Expect(fmt.Errorf("expected deployment %q not to have terminated", rc1.Name)).NotTo(o.HaveOccurred())
925+
}
908926

909-
ready = 0
910-
for i := range pods.Items {
911-
pod := pods.Items[i]
912-
if kapiv1.IsPodReady(&pod) {
913-
ready++
927+
g.By("waiting for the deployment to finish")
928+
rc1, err = waitForRCModification(oc, namespace, rc1.Name,
929+
deploymentChangeTimeout+time.Duration(dc.Spec.MinReadySeconds)*10*time.Second,
930+
rc1.GetResourceVersion(), func(rc *kapiv1.ReplicationController) (bool, error) {
931+
if rc.Status.AvailableReplicas == dc.Spec.Replicas {
932+
return true, nil
914933
}
915-
}
916-
917-
return len(pods.Items) == ready, nil
918-
}); err != nil {
919-
o.Expect(fmt.Errorf("deployment config %q never became ready (ready: %d, desired: %d)",
920-
config.Name, ready, config.Spec.Replicas)).NotTo(o.HaveOccurred())
921-
}
922934

923-
g.By("verifying that the deployment is still running")
924-
latestName := deployutil.DeploymentNameForConfigVersion(name, config.Status.LatestVersion)
925-
latest, err := oc.InternalKubeClient().Core().ReplicationControllers(oc.Namespace()).Get(latestName, metav1.GetOptions{})
935+
// FIXME: There is a race between deployer pod updating phase and RC updating AvailableReplicas
936+
// FIXME: Enable this when we switch pod acceptors to use RC AvailableReplicas with MinReadySecondsSet
937+
//if deployutil.DeploymentStatusFor(rc) == deployapi.DeploymentStatusComplete {
938+
// e2e.Logf("Failed RC: %#v", rc)
939+
// return false, errors.New("deployment shouldn't be completed before ReadyReplicas become AvailableReplicas")
940+
//}
941+
return false, nil
942+
})
926943
o.Expect(err).NotTo(o.HaveOccurred())
927-
928-
if deployutil.IsTerminatedDeployment(latest) {
929-
o.Expect(fmt.Errorf("expected deployment %q not to have terminated", latest.Name)).NotTo(o.HaveOccurred())
944+
o.Expect(rc1.Status.AvailableReplicas).To(o.Equal(dc.Spec.Replicas))
945+
// FIXME: There is a race between deployer pod updating phase and RC updating AvailableReplicas
946+
// FIXME: Enable this when we switch pod acceptors to use RC AvailableReplicas with MinReadySecondsSet
947+
//// Deployment status can't be updated yet but should be right after
948+
//o.Expect(deployutil.DeploymentStatusFor(rc1)).To(o.Equal(deployapi.DeploymentStatusRunning))
949+
// It should finish right after
950+
// FIXME: remove this condition when the above is fixed
951+
if deployutil.DeploymentStatusFor(rc1) != deployapi.DeploymentStatusComplete {
952+
// FIXME: remove this assertion when the above is fixed
953+
o.Expect(deployutil.DeploymentStatusFor(rc1)).To(o.Equal(deployapi.DeploymentStatusRunning))
954+
rc1, err = waitForRCModification(oc, namespace, rc1.Name, deploymentChangeTimeout,
955+
rc1.GetResourceVersion(), func(rc *kapiv1.ReplicationController) (bool, error) {
956+
return deployutil.DeploymentStatusFor(rc) == deployapi.DeploymentStatusComplete, nil
957+
})
958+
o.Expect(err).NotTo(o.HaveOccurred())
930959
}
931-
o.Expect(waitForLatestCondition(oc, name, deploymentRunTimeout, deploymentRunning)).NotTo(o.HaveOccurred())
960+
961+
// We might check that minReadySecond passed between pods becoming ready
962+
// and available but I don't think there is a way to get a timestamp from events
963+
// and other ways are just flaky.
964+
// But since we are reusing MinReadySeconds and AvailableReplicas from RC it should be tested there
932965
})
933966
})
934967

test/extended/deployments/util.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,3 +563,11 @@ func readDCFixture(path string) (*deployapi.DeploymentConfig, error) {
563563
err = deployapiv1.Convert_v1_DeploymentConfig_To_apps_DeploymentConfig(dcv1, dc, nil)
564564
return dc, err
565565
}
566+
567+
func readDCFixtureOrDie(path string) *deployapi.DeploymentConfig {
568+
data, err := readDCFixture(path)
569+
if err != nil {
570+
panic(err)
571+
}
572+
return data
573+
}

test/extended/testdata/bindata.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

test/extended/testdata/deployments/deployment-min-ready-seconds.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ metadata:
44
name: minreadytest
55
spec:
66
replicas: 2
7-
minReadySeconds: 500
7+
minReadySeconds: 60
88
selector:
99
name: minreadytest
1010
template:

0 commit comments

Comments
 (0)