From 85ec49c9bb655cb2f2a7d33598780db4f2500b0c Mon Sep 17 00:00:00 2001 From: Janet Kuo Date: Wed, 24 May 2017 15:18:36 -0700 Subject: [PATCH] Verify histories and pods in DaemonSet e2e test --- pkg/controller/daemon/update.go | 12 ++--- test/e2e/daemon_set.go | 88 +++++++++++++++++++++++++++++++-- 2 files changed, 90 insertions(+), 10 deletions(-) diff --git a/pkg/controller/daemon/update.go b/pkg/controller/daemon/update.go index 9be6960e430..4f9eb91ee26 100644 --- a/pkg/controller/daemon/update.go +++ b/pkg/controller/daemon/update.go @@ -104,7 +104,7 @@ func (dsc *DaemonSetsController) constructHistory(ds *extensions.DaemonSet) (cur } // Compare histories with ds to separate cur and old history found := false - found, err = match(ds, history) + found, err = Match(&ds.Spec.Template, history) if err != nil { return nil, nil, err } @@ -295,10 +295,10 @@ func (dsc *DaemonSetsController) controlledHistories(ds *extensions.DaemonSet) ( return result, nil } -// match check if ds template is semantically equal to the template stored in history -func match(ds *extensions.DaemonSet, history *apps.ControllerRevision) (bool, error) { - template, err := decodeHistory(history) - return apiequality.Semantic.DeepEqual(&ds.Spec.Template, template), err +// Match check if ds template is semantically equal to the template stored in history +func Match(template *v1.PodTemplateSpec, history *apps.ControllerRevision) (bool, error) { + t, err := decodeHistory(history) + return apiequality.Semantic.DeepEqual(template, t), err } func decodeHistory(history *apps.ControllerRevision) (*v1.PodTemplateSpec, error) { @@ -343,7 +343,7 @@ func (dsc *DaemonSetsController) snapshot(ds *extensions.DaemonSet, revision int return nil, getErr } // Check if we already created it - done, err := match(ds, existedHistory) + done, err := Match(&ds.Spec.Template, existedHistory) if err != nil { return nil, err } diff --git a/test/e2e/daemon_set.go b/test/e2e/daemon_set.go index f0d269fe720..391287acb17 100644 --- a/test/e2e/daemon_set.go +++ b/test/e2e/daemon_set.go @@ -31,6 +31,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/v1" podutil "k8s.io/kubernetes/pkg/api/v1/pod" + apps "k8s.io/kubernetes/pkg/apis/apps/v1beta1" extensionsinternal "k8s.io/kubernetes/pkg/apis/extensions" extensions "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" "k8s.io/kubernetes/pkg/client/clientset_generated/clientset" @@ -260,9 +261,19 @@ var _ = framework.KubeDescribe("Daemon set [Serial]", func() { Expect(err).NotTo(HaveOccurred(), "error waiting for daemon pod to start") By("Make sure all daemon pods have correct template generation 1") + templateGeneration := "1" err = checkDaemonPodsTemplateGeneration(c, ns, label, "1") Expect(err).NotTo(HaveOccurred()) + // Check history and labels + ds, err = c.Extensions().DaemonSets(ns).Get(ds.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + first := curHistory(listDaemonHistories(c, ns, label), &ds.Spec.Template) + firstHash := ds.Labels[extensions.DefaultDaemonSetUniqueLabelKey] + Expect(first.Labels[extensions.DefaultDaemonSetUniqueLabelKey]).To(Equal(firstHash)) + Expect(first.Revision).To(Equal(int64(1))) + checkDaemonSetPodsLabels(listDaemonPods(c, ns, label), firstHash, templateGeneration) + By("Update daemon pods image.") patch := getDaemonSetImagePatch(ds.Spec.Template.Spec.Containers[0].Name, redisImage) ds, err = c.Extensions().DaemonSets(ns).Patch(dsName, types.StrategicMergePatchType, []byte(patch)) @@ -274,12 +285,21 @@ var _ = framework.KubeDescribe("Daemon set [Serial]", func() { Expect(err).NotTo(HaveOccurred()) By("Make sure all daemon pods have correct template generation 1") - err = checkDaemonPodsTemplateGeneration(c, ns, label, "1") + err = checkDaemonPodsTemplateGeneration(c, ns, label, templateGeneration) Expect(err).NotTo(HaveOccurred()) By("Check that daemon pods are still running on every node of the cluster.") err = wait.PollImmediate(dsRetryPeriod, dsRetryTimeout, checkRunningOnAllNodes(f, ds)) Expect(err).NotTo(HaveOccurred(), "error waiting for daemon pod to start") + + // Check history and labels + ds, err = c.Extensions().DaemonSets(ns).Get(ds.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + cur := curHistory(listDaemonHistories(c, ns, label), &ds.Spec.Template) + curHash := ds.Labels[extensions.DefaultDaemonSetUniqueLabelKey] + Expect(cur.Labels[extensions.DefaultDaemonSetUniqueLabelKey]).To(Equal(curHash)) + Expect(cur.Revision).To(Equal(int64(2))) + checkDaemonSetPodsLabels(listDaemonPods(c, ns, label), firstHash, templateGeneration) }) It("Should update pod when spec was updated and update strategy is RollingUpdate", func() { @@ -302,23 +322,42 @@ var _ = framework.KubeDescribe("Daemon set [Serial]", func() { err = checkDaemonPodsTemplateGeneration(c, ns, label, fmt.Sprint(templateGeneration)) Expect(err).NotTo(HaveOccurred()) + // Check history and labels + ds, err = c.Extensions().DaemonSets(ns).Get(ds.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + cur := curHistory(listDaemonHistories(c, ns, label), &ds.Spec.Template) + hash := ds.Labels[extensions.DefaultDaemonSetUniqueLabelKey] + Expect(cur.Labels[extensions.DefaultDaemonSetUniqueLabelKey]).To(Equal(hash)) + Expect(cur.Revision).To(Equal(int64(1))) + checkDaemonSetPodsLabels(listDaemonPods(c, ns, label), hash, fmt.Sprint(templateGeneration)) + By("Update daemon pods image.") patch := getDaemonSetImagePatch(ds.Spec.Template.Spec.Containers[0].Name, redisImage) ds, err = c.Extensions().DaemonSets(ns).Patch(dsName, types.StrategicMergePatchType, []byte(patch)) Expect(err).NotTo(HaveOccurred()) - Expect(ds.Spec.TemplateGeneration).To(Equal(templateGeneration + 1)) + templateGeneration++ + Expect(ds.Spec.TemplateGeneration).To(Equal(templateGeneration)) By("Check that daemon pods images are updated.") err = wait.PollImmediate(dsRetryPeriod, dsRetryTimeout, checkDaemonPodsImageAndAvailability(c, ds, redisImage, 1)) Expect(err).NotTo(HaveOccurred()) - By(fmt.Sprintf("Make sure all daemon pods have correct template generation %d", templateGeneration+1)) - err = checkDaemonPodsTemplateGeneration(c, ns, label, fmt.Sprint(templateGeneration+1)) + By(fmt.Sprintf("Make sure all daemon pods have correct template generation %d", templateGeneration)) + err = checkDaemonPodsTemplateGeneration(c, ns, label, fmt.Sprint(templateGeneration)) Expect(err).NotTo(HaveOccurred()) By("Check that daemon pods are still running on every node of the cluster.") err = wait.PollImmediate(dsRetryPeriod, dsRetryTimeout, checkRunningOnAllNodes(f, ds)) Expect(err).NotTo(HaveOccurred(), "error waiting for daemon pod to start") + + // Check history and labels + ds, err = c.Extensions().DaemonSets(ns).Get(ds.Name, metav1.GetOptions{}) + Expect(err).NotTo(HaveOccurred()) + cur = curHistory(listDaemonHistories(c, ns, label), &ds.Spec.Template) + hash = ds.Labels[extensions.DefaultDaemonSetUniqueLabelKey] + Expect(cur.Labels[extensions.DefaultDaemonSetUniqueLabelKey]).To(Equal(hash)) + Expect(cur.Revision).To(Equal(int64(2))) + checkDaemonSetPodsLabels(listDaemonPods(c, ns, label), hash, fmt.Sprint(templateGeneration)) }) It("Should adopt or recreate existing pods when creating a RollingUpdate DaemonSet with matching or mismatching templateGeneration", func() { @@ -698,3 +737,44 @@ func checkDaemonSetPodsName(c clientset.Interface, ns, prefix string, label map[ } return nil } + +func checkDaemonSetPodsLabels(podList *v1.PodList, hash, templateGeneration string) { + for _, pod := range podList.Items { + podHash := pod.Labels[extensions.DefaultDaemonSetUniqueLabelKey] + podTemplate := pod.Labels[extensions.DaemonSetTemplateGenerationKey] + Expect(len(podHash)).To(BeNumerically(">", 0)) + if len(hash) > 0 { + Expect(podHash).To(Equal(hash)) + } + Expect(len(podTemplate)).To(BeNumerically(">", 0)) + Expect(podTemplate).To(Equal(templateGeneration)) + } +} + +func listDaemonHistories(c clientset.Interface, ns string, label map[string]string) *apps.ControllerRevisionList { + selector := labels.Set(label).AsSelector() + options := metav1.ListOptions{LabelSelector: selector.String()} + historyList, err := c.Apps().ControllerRevisions(ns).List(options) + Expect(err).NotTo(HaveOccurred()) + Expect(len(historyList.Items)).To(BeNumerically(">", 0)) + return historyList +} + +func curHistory(historyList *apps.ControllerRevisionList, template *v1.PodTemplateSpec) *apps.ControllerRevision { + var curHistory *apps.ControllerRevision + foundCurHistories := 0 + for i := range historyList.Items { + history := &historyList.Items[i] + // Every history should have the hash label + Expect(len(history.Labels[extensions.DefaultDaemonSetUniqueLabelKey])).To(BeNumerically(">", 0)) + match, err := daemon.Match(template, history) + Expect(err).NotTo(HaveOccurred()) + if match { + curHistory = history + foundCurHistories++ + } + } + Expect(foundCurHistories).To(Equal(1)) + Expect(curHistory).NotTo(BeNil()) + return curHistory +}