From d0b5de855f1b92751fe7b07e4ebf0ea33b9287ac Mon Sep 17 00:00:00 2001 From: Janet Kuo Date: Mon, 20 Mar 2017 12:07:17 -0700 Subject: [PATCH 1/2] Add a test for semantically equal DaemonSet updates --- hack/make-rules/test-cmd-util.sh | 26 +++++++++++++++++++++ hack/testdata/rollingupdate-daemonset.yaml | 27 ++++++++++++++++++++++ 2 files changed, 53 insertions(+) create mode 100644 hack/testdata/rollingupdate-daemonset.yaml diff --git a/hack/make-rules/test-cmd-util.sh b/hack/make-rules/test-cmd-util.sh index 5cd3da9b855..5874ea7e30e 100644 --- a/hack/make-rules/test-cmd-util.sh +++ b/hack/make-rules/test-cmd-util.sh @@ -66,6 +66,7 @@ static="static" storageclass="storageclass" subjectaccessreviews="subjectaccessreviews" thirdpartyresources="thirdpartyresources" +daemonsets="daemonsets" # Stops the running kubectl proxy, if there is one. @@ -2574,6 +2575,22 @@ run_rs_tests() { fi } +run_daemonset_tests() { + kube::log::status "Testing kubectl(v1:daemonsets)" + + ### Create a rolling update DaemonSet + # Pre-condition: no DaemonSet exists + kube::test::get_object_assert daemonsets "{{range.items}}{{$id_field}}:{{end}}" '' + # Command + kubectl apply -f hack/testdata/rollingupdate-daemonset.yaml "${kube_flags[@]}" + # Template Generation should be 1 + kube::test::get_object_assert 'daemonsets bind' "{{${template_generation_field}}}" '1' + kubectl apply -f hack/testdata/rollingupdate-daemonset.yaml "${kube_flags[@]}" + # Template Generation should stay 1 + kube::test::get_object_assert 'daemonsets bind' "{{${template_generation_field}}}" '1' + kubectl delete -f hack/testdata/rollingupdate-daemonset.yaml "${kube_flags[@]}" +} + run_multi_resources_tests() { kube::log::status "Testing kubectl(v1:multiple resources)" @@ -2798,6 +2815,7 @@ runTests() { deployment_second_image_field="(index .spec.template.spec.containers 1).image" change_cause_annotation='.*kubernetes.io/change-cause.*' pdb_min_available=".spec.minAvailable" + template_generation_field=".spec.templateGeneration" # Make sure "default" namespace exists. if kube::test::if_supports_resource "${namespaces}" ; then @@ -3180,6 +3198,14 @@ runTests() { fi + ################## + # DaemonSets # + ################## + + if kube::test::if_supports_resource "${daemonsets}" ; then + run_daemonset_tests + fi + ########################### # Replication controllers # ########################### diff --git a/hack/testdata/rollingupdate-daemonset.yaml b/hack/testdata/rollingupdate-daemonset.yaml new file mode 100644 index 00000000000..c8a9cdca21d --- /dev/null +++ b/hack/testdata/rollingupdate-daemonset.yaml @@ -0,0 +1,27 @@ +apiVersion: extensions/v1beta1 +kind: DaemonSet +metadata: + name: bind +spec: + updateStrategy: + type: RollingUpdate + rollingUpdate: + maxUnavailable: 10% + template: + metadata: + labels: + service: bind + spec: + affinity: + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchExpressions: + - key: "service" + operator: "In" + values: ["bind"] + topologyKey: "kubernetes.io/hostname" + namespaces: [] + containers: + - name: kubernetes-pause + image: gcr.io/google-containers/pause:2.0 From 24af8d3b72d5771076dc32d2f93baf3667e1c2a1 Mon Sep 17 00:00:00 2001 From: Janet Kuo Date: Mon, 20 Mar 2017 13:52:55 -0700 Subject: [PATCH 2/2] Add validation unit test for semantically equal DaemonSet template updates --- .../extensions/validation/validation_test.go | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/pkg/apis/extensions/validation/validation_test.go b/pkg/apis/extensions/validation/validation_test.go index 5a0d2b089e4..cdc0ae723b5 100644 --- a/pkg/apis/extensions/validation/validation_test.go +++ b/pkg/apis/extensions/validation/validation_test.go @@ -444,6 +444,15 @@ func TestValidateDaemonSetUpdate(t *testing.T) { Spec: validPodSpecAbc, }, } + validPodTemplateAbcSemanticallyEqual := api.PodTemplate{ + Template: api.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: validSelector, + }, + Spec: validPodSpecAbc, + }, + } + validPodTemplateAbcSemanticallyEqual.Template.Spec.ImagePullSecrets = []api.LocalObjectReference{} validPodTemplateNodeSelector := api.PodTemplate{ Template: api.PodTemplateSpec{ ObjectMeta: metav1.ObjectMeta{ @@ -618,6 +627,33 @@ func TestValidateDaemonSetUpdate(t *testing.T) { }, }, }, + "unchanged templateGeneration upon semantically equal template update": { + old: extensions.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: extensions.DaemonSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validSelector}, + TemplateGeneration: 4, + Template: validPodTemplateAbc.Template, + UpdateStrategy: extensions.DaemonSetUpdateStrategy{ + Type: extensions.OnDeleteDaemonSetStrategyType, + }, + }, + }, + update: extensions.DaemonSet{ + ObjectMeta: metav1.ObjectMeta{Name: "abc", Namespace: metav1.NamespaceDefault}, + Spec: extensions.DaemonSetSpec{ + Selector: &metav1.LabelSelector{MatchLabels: validSelector}, + TemplateGeneration: 4, + Template: validPodTemplateAbcSemanticallyEqual.Template, + UpdateStrategy: extensions.DaemonSetUpdateStrategy{ + Type: extensions.RollingUpdateDaemonSetStrategyType, + RollingUpdate: &extensions.RollingUpdateDaemonSet{ + MaxUnavailable: intstr.FromInt(1), + }, + }, + }, + }, + }, } for testName, successCase := range successCases { // ResourceVersion is required for updates.