Unverified Commit 3c6ff87f authored by Kubernetes Submit Queue's avatar Kubernetes Submit Queue Committed by GitHub

Merge pull request #52192 from liyinan926/ds-tests

Automatic merge from submit-queue (batch tested with PRs 54774, 54820, 52192, 54827). 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>. Initial integration test setup for DaemonSet controller **What this PR does / why we need it**: This PR setup and added some initial integration tests for the DaemonSet controller. All tests included were ported from their unit test counterparts that currently use fake client, informers, reactor, etc. Future PRs will port more tests over once this PR is approved and merged. **Which issue this PR fixes** *(optional, in `fixes #<issue number>(, fixes #<issue_number>, ...)` format, will close that issue when PR gets merged)*: #52191. **Special notes for your reviewer**: @kow3ns **Release note**: ```release-note NONE ```
parents a7a0a63f 4dc42d07
...@@ -298,8 +298,8 @@ func (dsc *DaemonSetsController) enqueueDaemonSetAfter(obj interface{}, after ti ...@@ -298,8 +298,8 @@ func (dsc *DaemonSetsController) enqueueDaemonSetAfter(obj interface{}, after ti
dsc.queue.AddAfter(key, after) dsc.queue.AddAfter(key, after)
} }
// getPodDaemonSets returns a list of DaemonSets that potentially match the pod. // getDaemonSetsForPod returns a list of DaemonSets that potentially match the pod.
func (dsc *DaemonSetsController) getPodDaemonSets(pod *v1.Pod) []*extensions.DaemonSet { func (dsc *DaemonSetsController) getDaemonSetsForPod(pod *v1.Pod) []*extensions.DaemonSet {
sets, err := dsc.dsLister.GetPodDaemonSets(pod) sets, err := dsc.dsLister.GetPodDaemonSets(pod)
if err != nil { if err != nil {
return nil return nil
...@@ -362,8 +362,8 @@ func (dsc *DaemonSetsController) addHistory(obj interface{}) { ...@@ -362,8 +362,8 @@ func (dsc *DaemonSetsController) addHistory(obj interface{}) {
} }
// updateHistory figures out what DaemonSet(s) manage a ControllerRevision when the ControllerRevision // updateHistory figures out what DaemonSet(s) manage a ControllerRevision when the ControllerRevision
// is updated and wake them up. If the anything of the ControllerRevision have changed, we need to // is updated and wake them up. If anything of the ControllerRevision has changed, we need to awaken
// awaken both the old and new DaemonSets. // both the old and new DaemonSets.
func (dsc *DaemonSetsController) updateHistory(old, cur interface{}) { func (dsc *DaemonSetsController) updateHistory(old, cur interface{}) {
curHistory := cur.(*apps.ControllerRevision) curHistory := cur.(*apps.ControllerRevision)
oldHistory := old.(*apps.ControllerRevision) oldHistory := old.(*apps.ControllerRevision)
...@@ -474,7 +474,7 @@ func (dsc *DaemonSetsController) addPod(obj interface{}) { ...@@ -474,7 +474,7 @@ func (dsc *DaemonSetsController) addPod(obj interface{}) {
// them to see if anyone wants to adopt it. // them to see if anyone wants to adopt it.
// DO NOT observe creation because no controller should be waiting for an // DO NOT observe creation because no controller should be waiting for an
// orphan. // orphan.
dss := dsc.getPodDaemonSets(pod) dss := dsc.getDaemonSetsForPod(pod)
if len(dss) == 0 { if len(dss) == 0 {
return return
} }
...@@ -495,8 +495,6 @@ func (dsc *DaemonSetsController) updatePod(old, cur interface{}) { ...@@ -495,8 +495,6 @@ func (dsc *DaemonSetsController) updatePod(old, cur interface{}) {
// Two different versions of the same pod will always have different RVs. // Two different versions of the same pod will always have different RVs.
return return
} }
changedToReady := !podutil.IsPodReady(oldPod) && podutil.IsPodReady(curPod)
labelChanged := !reflect.DeepEqual(curPod.Labels, oldPod.Labels)
curControllerRef := metav1.GetControllerOf(curPod) curControllerRef := metav1.GetControllerOf(curPod)
oldControllerRef := metav1.GetControllerOf(oldPod) oldControllerRef := metav1.GetControllerOf(oldPod)
...@@ -516,6 +514,7 @@ func (dsc *DaemonSetsController) updatePod(old, cur interface{}) { ...@@ -516,6 +514,7 @@ func (dsc *DaemonSetsController) updatePod(old, cur interface{}) {
} }
glog.V(4).Infof("Pod %s updated.", curPod.Name) glog.V(4).Infof("Pod %s updated.", curPod.Name)
dsc.enqueueDaemonSet(ds) dsc.enqueueDaemonSet(ds)
changedToReady := !podutil.IsPodReady(oldPod) && podutil.IsPodReady(curPod)
// See https://github.com/kubernetes/kubernetes/pull/38076 for more details // See https://github.com/kubernetes/kubernetes/pull/38076 for more details
if changedToReady && ds.Spec.MinReadySeconds > 0 { if changedToReady && ds.Spec.MinReadySeconds > 0 {
// Add a second to avoid milliseconds skew in AddAfter. // Add a second to avoid milliseconds skew in AddAfter.
...@@ -527,11 +526,12 @@ func (dsc *DaemonSetsController) updatePod(old, cur interface{}) { ...@@ -527,11 +526,12 @@ func (dsc *DaemonSetsController) updatePod(old, cur interface{}) {
// Otherwise, it's an orphan. If anything changed, sync matching controllers // Otherwise, it's an orphan. If anything changed, sync matching controllers
// to see if anyone wants to adopt it now. // to see if anyone wants to adopt it now.
dss := dsc.getPodDaemonSets(curPod) dss := dsc.getDaemonSetsForPod(curPod)
if len(dss) == 0 { if len(dss) == 0 {
return return
} }
glog.V(4).Infof("Orphan Pod %s updated.", curPod.Name) glog.V(4).Infof("Orphan Pod %s updated.", curPod.Name)
labelChanged := !reflect.DeepEqual(curPod.Labels, oldPod.Labels)
if labelChanged || controllerRefChanged { if labelChanged || controllerRefChanged {
for _, ds := range dss { for _, ds := range dss {
dsc.enqueueDaemonSet(ds) dsc.enqueueDaemonSet(ds)
...@@ -707,7 +707,7 @@ func (dsc *DaemonSetsController) updateNode(old, cur interface{}) { ...@@ -707,7 +707,7 @@ func (dsc *DaemonSetsController) updateNode(old, cur interface{}) {
dsList, err := dsc.dsLister.List(labels.Everything()) dsList, err := dsc.dsLister.List(labels.Everything())
if err != nil { if err != nil {
glog.V(4).Infof("Error enqueueing daemon sets: %v", err) glog.V(4).Infof("Error listing daemon sets: %v", err)
return return
} }
// TODO: it'd be nice to pass a hint with these enqueues, so that each ds would only examine the added node (unless it has other work to do, too). // TODO: it'd be nice to pass a hint with these enqueues, so that each ds would only examine the added node (unless it has other work to do, too).
...@@ -799,6 +799,10 @@ func (dsc *DaemonSetsController) resolveControllerRef(namespace string, controll ...@@ -799,6 +799,10 @@ func (dsc *DaemonSetsController) resolveControllerRef(namespace string, controll
return ds return ds
} }
// manage manages the scheduling and running of Pods of ds on nodes.
// After figuring out which nodes should run a Pod of ds but not yet running one and
// which nodes should not run a Pod of ds but currently running one, it calls function
// syncNodes with a list of pods to remove and a list of nodes to run a Pod of ds.
func (dsc *DaemonSetsController) manage(ds *extensions.DaemonSet, hash string) error { func (dsc *DaemonSetsController) manage(ds *extensions.DaemonSet, hash string) error {
// Find out which nodes are running the daemon pods controlled by ds. // Find out which nodes are running the daemon pods controlled by ds.
nodeToDaemonPods, err := dsc.getNodesToDaemonPods(ds) nodeToDaemonPods, err := dsc.getNodesToDaemonPods(ds)
......
...@@ -492,7 +492,7 @@ func TestOneNodeDaemonLaunchesPod(t *testing.T) { ...@@ -492,7 +492,7 @@ func TestOneNodeDaemonLaunchesPod(t *testing.T) {
} }
// DaemonSets should place onto NotReady nodes // DaemonSets should place onto NotReady nodes
func TestNotReadNodeDaemonDoesNotLaunchPod(t *testing.T) { func TestNotReadyNodeDaemonDoesLaunchPod(t *testing.T) {
for _, strategy := range updateStrategies() { for _, strategy := range updateStrategies() {
ds := newDaemonSet("foo") ds := newDaemonSet("foo")
ds.Spec.UpdateStrategy = *strategy ds.Spec.UpdateStrategy = *strategy
......
...@@ -36,6 +36,7 @@ filegroup( ...@@ -36,6 +36,7 @@ filegroup(
"//test/integration/auth:all-srcs", "//test/integration/auth:all-srcs",
"//test/integration/client:all-srcs", "//test/integration/client:all-srcs",
"//test/integration/configmap:all-srcs", "//test/integration/configmap:all-srcs",
"//test/integration/daemonset:all-srcs",
"//test/integration/defaulttolerationseconds:all-srcs", "//test/integration/defaulttolerationseconds:all-srcs",
"//test/integration/deployment:all-srcs", "//test/integration/deployment:all-srcs",
"//test/integration/etcd:all-srcs", "//test/integration/etcd:all-srcs",
......
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
)
go_test(
name = "go_default_test",
size = "large",
srcs = [
"daemonset_test.go",
"main_test.go",
],
importpath = "k8s.io/kubernetes/test/integration/daemonset",
tags = ["integration"],
deps = [
"//pkg/api/v1/pod:go_default_library",
"//pkg/controller/daemon: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/api/resource:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/intstr:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/util/wait:go_default_library",
"//vendor/k8s.io/client-go/informers:go_default_library",
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
"//vendor/k8s.io/client-go/kubernetes/typed/core/v1:go_default_library",
"//vendor/k8s.io/client-go/kubernetes/typed/extensions/v1beta1:go_default_library",
"//vendor/k8s.io/client-go/rest:go_default_library",
"//vendor/k8s.io/client-go/tools/cache:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)
approvers:
- mikedanese
- kow3ns
reviewers:
- mikedanese
- kargakis
- lukaszo
- janetkuo
- kow3ns
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package daemonset
import (
"testing"
"k8s.io/kubernetes/test/integration/framework"
)
func TestMain(m *testing.M) {
framework.EtcdMain(m.Run)
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment