daemon_controller_test.go 102 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013
  1. /*
  2. Copyright 2015 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package daemon
  14. import (
  15. "fmt"
  16. "reflect"
  17. "sort"
  18. "strconv"
  19. "sync"
  20. "testing"
  21. "time"
  22. apps "k8s.io/api/apps/v1"
  23. "k8s.io/api/core/v1"
  24. "k8s.io/apimachinery/pkg/api/resource"
  25. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  26. "k8s.io/apimachinery/pkg/runtime"
  27. "k8s.io/apimachinery/pkg/util/clock"
  28. "k8s.io/apimachinery/pkg/util/intstr"
  29. "k8s.io/apimachinery/pkg/util/uuid"
  30. "k8s.io/apiserver/pkg/storage/names"
  31. utilfeature "k8s.io/apiserver/pkg/util/feature"
  32. "k8s.io/client-go/informers"
  33. "k8s.io/client-go/kubernetes/fake"
  34. core "k8s.io/client-go/testing"
  35. "k8s.io/client-go/tools/cache"
  36. "k8s.io/client-go/tools/record"
  37. "k8s.io/client-go/util/flowcontrol"
  38. "k8s.io/client-go/util/workqueue"
  39. featuregatetesting "k8s.io/component-base/featuregate/testing"
  40. "k8s.io/kubernetes/pkg/api/legacyscheme"
  41. podutil "k8s.io/kubernetes/pkg/api/v1/pod"
  42. api "k8s.io/kubernetes/pkg/apis/core"
  43. "k8s.io/kubernetes/pkg/controller"
  44. "k8s.io/kubernetes/pkg/features"
  45. kubelettypes "k8s.io/kubernetes/pkg/kubelet/types"
  46. schedulerapi "k8s.io/kubernetes/pkg/scheduler/api"
  47. "k8s.io/kubernetes/pkg/securitycontext"
  48. labelsutil "k8s.io/kubernetes/pkg/util/labels"
  49. )
  50. // IMPORTANT NOTE: Some tests in file need to pass irrespective of ScheduleDaemonSetPods feature is enabled. For rest
  51. // of the tests, an explicit comment is mentioned whether we are testing codepath specific to ScheduleDaemonSetPods or
  52. // without that feature.
  53. var (
  54. simpleDaemonSetLabel = map[string]string{"name": "simple-daemon", "type": "production"}
  55. simpleDaemonSetLabel2 = map[string]string{"name": "simple-daemon", "type": "test"}
  56. simpleNodeLabel = map[string]string{"color": "blue", "speed": "fast"}
  57. simpleNodeLabel2 = map[string]string{"color": "red", "speed": "fast"}
  58. alwaysReady = func() bool { return true }
  59. )
  60. var (
  61. noScheduleTolerations = []v1.Toleration{{Key: "dedicated", Value: "user1", Effect: "NoSchedule"}}
  62. noScheduleTaints = []v1.Taint{{Key: "dedicated", Value: "user1", Effect: "NoSchedule"}}
  63. noExecuteTaints = []v1.Taint{{Key: "dedicated", Value: "user1", Effect: "NoExecute"}}
  64. )
  65. func nowPointer() *metav1.Time {
  66. now := metav1.Now()
  67. return &now
  68. }
  69. var (
  70. nodeNotReady = []v1.Taint{{
  71. Key: schedulerapi.TaintNodeNotReady,
  72. Effect: v1.TaintEffectNoExecute,
  73. TimeAdded: nowPointer(),
  74. }}
  75. nodeUnreachable = []v1.Taint{{
  76. Key: schedulerapi.TaintNodeUnreachable,
  77. Effect: v1.TaintEffectNoExecute,
  78. TimeAdded: nowPointer(),
  79. }}
  80. )
  81. func newDaemonSet(name string) *apps.DaemonSet {
  82. two := int32(2)
  83. return &apps.DaemonSet{
  84. ObjectMeta: metav1.ObjectMeta{
  85. UID: uuid.NewUUID(),
  86. Name: name,
  87. Namespace: metav1.NamespaceDefault,
  88. },
  89. Spec: apps.DaemonSetSpec{
  90. RevisionHistoryLimit: &two,
  91. UpdateStrategy: apps.DaemonSetUpdateStrategy{
  92. Type: apps.OnDeleteDaemonSetStrategyType,
  93. },
  94. Selector: &metav1.LabelSelector{MatchLabels: simpleDaemonSetLabel},
  95. Template: v1.PodTemplateSpec{
  96. ObjectMeta: metav1.ObjectMeta{
  97. Labels: simpleDaemonSetLabel,
  98. },
  99. Spec: v1.PodSpec{
  100. Containers: []v1.Container{
  101. {
  102. Image: "foo/bar",
  103. TerminationMessagePath: v1.TerminationMessagePathDefault,
  104. ImagePullPolicy: v1.PullIfNotPresent,
  105. SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(),
  106. },
  107. },
  108. DNSPolicy: v1.DNSDefault,
  109. },
  110. },
  111. },
  112. }
  113. }
  114. func newRollbackStrategy() *apps.DaemonSetUpdateStrategy {
  115. one := intstr.FromInt(1)
  116. return &apps.DaemonSetUpdateStrategy{
  117. Type: apps.RollingUpdateDaemonSetStrategyType,
  118. RollingUpdate: &apps.RollingUpdateDaemonSet{MaxUnavailable: &one},
  119. }
  120. }
  121. func newOnDeleteStrategy() *apps.DaemonSetUpdateStrategy {
  122. return &apps.DaemonSetUpdateStrategy{
  123. Type: apps.OnDeleteDaemonSetStrategyType,
  124. }
  125. }
  126. func updateStrategies() []*apps.DaemonSetUpdateStrategy {
  127. return []*apps.DaemonSetUpdateStrategy{newOnDeleteStrategy(), newRollbackStrategy()}
  128. }
  129. func newNode(name string, label map[string]string) *v1.Node {
  130. return &v1.Node{
  131. TypeMeta: metav1.TypeMeta{APIVersion: "v1"},
  132. ObjectMeta: metav1.ObjectMeta{
  133. Name: name,
  134. Labels: label,
  135. Namespace: metav1.NamespaceNone,
  136. },
  137. Status: v1.NodeStatus{
  138. Conditions: []v1.NodeCondition{
  139. {Type: v1.NodeReady, Status: v1.ConditionTrue},
  140. },
  141. Allocatable: v1.ResourceList{
  142. v1.ResourcePods: resource.MustParse("100"),
  143. },
  144. },
  145. }
  146. }
  147. func addNodes(nodeStore cache.Store, startIndex, numNodes int, label map[string]string) {
  148. for i := startIndex; i < startIndex+numNodes; i++ {
  149. nodeStore.Add(newNode(fmt.Sprintf("node-%d", i), label))
  150. }
  151. }
  152. func newPod(podName string, nodeName string, label map[string]string, ds *apps.DaemonSet) *v1.Pod {
  153. // Add hash unique label to the pod
  154. newLabels := label
  155. var podSpec v1.PodSpec
  156. // Copy pod spec from DaemonSet template, or use a default one if DaemonSet is nil
  157. if ds != nil {
  158. hash := controller.ComputeHash(&ds.Spec.Template, ds.Status.CollisionCount)
  159. newLabels = labelsutil.CloneAndAddLabel(label, apps.DefaultDaemonSetUniqueLabelKey, hash)
  160. podSpec = ds.Spec.Template.Spec
  161. } else {
  162. podSpec = v1.PodSpec{
  163. Containers: []v1.Container{
  164. {
  165. Image: "foo/bar",
  166. TerminationMessagePath: v1.TerminationMessagePathDefault,
  167. ImagePullPolicy: v1.PullIfNotPresent,
  168. SecurityContext: securitycontext.ValidSecurityContextWithContainerDefaults(),
  169. },
  170. },
  171. }
  172. }
  173. // Add node name to the pod
  174. if len(nodeName) > 0 {
  175. podSpec.NodeName = nodeName
  176. }
  177. pod := &v1.Pod{
  178. TypeMeta: metav1.TypeMeta{APIVersion: "v1"},
  179. ObjectMeta: metav1.ObjectMeta{
  180. GenerateName: podName,
  181. Labels: newLabels,
  182. Namespace: metav1.NamespaceDefault,
  183. },
  184. Spec: podSpec,
  185. }
  186. pod.Name = names.SimpleNameGenerator.GenerateName(podName)
  187. if ds != nil {
  188. pod.OwnerReferences = []metav1.OwnerReference{*metav1.NewControllerRef(ds, controllerKind)}
  189. }
  190. return pod
  191. }
  192. func addPods(podStore cache.Store, nodeName string, label map[string]string, ds *apps.DaemonSet, number int) {
  193. for i := 0; i < number; i++ {
  194. pod := newPod(fmt.Sprintf("%s-", nodeName), nodeName, label, ds)
  195. podStore.Add(pod)
  196. }
  197. }
  198. func addFailedPods(podStore cache.Store, nodeName string, label map[string]string, ds *apps.DaemonSet, number int) {
  199. for i := 0; i < number; i++ {
  200. pod := newPod(fmt.Sprintf("%s-", nodeName), nodeName, label, ds)
  201. pod.Status = v1.PodStatus{Phase: v1.PodFailed}
  202. podStore.Add(pod)
  203. }
  204. }
  205. type fakePodControl struct {
  206. sync.Mutex
  207. *controller.FakePodControl
  208. podStore cache.Store
  209. podIDMap map[string]*v1.Pod
  210. expectations controller.ControllerExpectationsInterface
  211. dsc *daemonSetsController
  212. }
  213. func newFakePodControl() *fakePodControl {
  214. podIDMap := make(map[string]*v1.Pod)
  215. return &fakePodControl{
  216. FakePodControl: &controller.FakePodControl{},
  217. podIDMap: podIDMap,
  218. }
  219. }
  220. func (f *fakePodControl) CreatePodsOnNode(nodeName, namespace string, template *v1.PodTemplateSpec, object runtime.Object, controllerRef *metav1.OwnerReference) error {
  221. f.Lock()
  222. defer f.Unlock()
  223. if err := f.FakePodControl.CreatePodsOnNode(nodeName, namespace, template, object, controllerRef); err != nil {
  224. return fmt.Errorf("failed to create pod on node %q", nodeName)
  225. }
  226. pod := &v1.Pod{
  227. ObjectMeta: metav1.ObjectMeta{
  228. Labels: template.Labels,
  229. Namespace: namespace,
  230. GenerateName: fmt.Sprintf("%s-", nodeName),
  231. },
  232. }
  233. if err := legacyscheme.Scheme.Convert(&template.Spec, &pod.Spec, nil); err != nil {
  234. return fmt.Errorf("unable to convert pod template: %v", err)
  235. }
  236. if len(nodeName) != 0 {
  237. pod.Spec.NodeName = nodeName
  238. }
  239. pod.Name = names.SimpleNameGenerator.GenerateName(fmt.Sprintf("%s-", nodeName))
  240. f.podStore.Update(pod)
  241. f.podIDMap[pod.Name] = pod
  242. ds := object.(*apps.DaemonSet)
  243. dsKey, _ := controller.KeyFunc(ds)
  244. f.expectations.CreationObserved(dsKey)
  245. return nil
  246. }
  247. func (f *fakePodControl) CreatePodsWithControllerRef(namespace string, template *v1.PodTemplateSpec, object runtime.Object, controllerRef *metav1.OwnerReference) error {
  248. f.Lock()
  249. defer f.Unlock()
  250. if err := f.FakePodControl.CreatePodsWithControllerRef(namespace, template, object, controllerRef); err != nil {
  251. return fmt.Errorf("failed to create pod for DaemonSet")
  252. }
  253. pod := &v1.Pod{
  254. ObjectMeta: metav1.ObjectMeta{
  255. Labels: template.Labels,
  256. Namespace: namespace,
  257. },
  258. }
  259. pod.Name = names.SimpleNameGenerator.GenerateName(fmt.Sprintf("%p-", pod))
  260. if err := legacyscheme.Scheme.Convert(&template.Spec, &pod.Spec, nil); err != nil {
  261. return fmt.Errorf("unable to convert pod template: %v", err)
  262. }
  263. f.podStore.Update(pod)
  264. f.podIDMap[pod.Name] = pod
  265. ds := object.(*apps.DaemonSet)
  266. dsKey, _ := controller.KeyFunc(ds)
  267. f.expectations.CreationObserved(dsKey)
  268. return nil
  269. }
  270. func (f *fakePodControl) DeletePod(namespace string, podID string, object runtime.Object) error {
  271. f.Lock()
  272. defer f.Unlock()
  273. if err := f.FakePodControl.DeletePod(namespace, podID, object); err != nil {
  274. return fmt.Errorf("failed to delete pod %q", podID)
  275. }
  276. pod, ok := f.podIDMap[podID]
  277. if !ok {
  278. return fmt.Errorf("pod %q does not exist", podID)
  279. }
  280. f.podStore.Delete(pod)
  281. delete(f.podIDMap, podID)
  282. ds := object.(*apps.DaemonSet)
  283. dsKey, _ := controller.KeyFunc(ds)
  284. f.expectations.DeletionObserved(dsKey)
  285. return nil
  286. }
  287. type daemonSetsController struct {
  288. *DaemonSetsController
  289. dsStore cache.Store
  290. historyStore cache.Store
  291. podStore cache.Store
  292. nodeStore cache.Store
  293. fakeRecorder *record.FakeRecorder
  294. }
  295. func newTestController(initialObjects ...runtime.Object) (*daemonSetsController, *fakePodControl, *fake.Clientset, error) {
  296. clientset := fake.NewSimpleClientset(initialObjects...)
  297. informerFactory := informers.NewSharedInformerFactory(clientset, controller.NoResyncPeriodFunc())
  298. dsc, err := NewDaemonSetsController(
  299. informerFactory.Apps().V1().DaemonSets(),
  300. informerFactory.Apps().V1().ControllerRevisions(),
  301. informerFactory.Core().V1().Pods(),
  302. informerFactory.Core().V1().Nodes(),
  303. clientset,
  304. flowcontrol.NewFakeBackOff(50*time.Millisecond, 500*time.Millisecond, clock.NewFakeClock(time.Now())),
  305. )
  306. if err != nil {
  307. return nil, nil, nil, err
  308. }
  309. fakeRecorder := record.NewFakeRecorder(100)
  310. dsc.eventRecorder = fakeRecorder
  311. dsc.podStoreSynced = alwaysReady
  312. dsc.nodeStoreSynced = alwaysReady
  313. dsc.dsStoreSynced = alwaysReady
  314. dsc.historyStoreSynced = alwaysReady
  315. podControl := newFakePodControl()
  316. dsc.podControl = podControl
  317. podControl.podStore = informerFactory.Core().V1().Pods().Informer().GetStore()
  318. newDsc := &daemonSetsController{
  319. dsc,
  320. informerFactory.Apps().V1().DaemonSets().Informer().GetStore(),
  321. informerFactory.Apps().V1().ControllerRevisions().Informer().GetStore(),
  322. informerFactory.Core().V1().Pods().Informer().GetStore(),
  323. informerFactory.Core().V1().Nodes().Informer().GetStore(),
  324. fakeRecorder,
  325. }
  326. podControl.expectations = newDsc.expectations
  327. return newDsc, podControl, clientset, nil
  328. }
  329. func resetCounters(manager *daemonSetsController) {
  330. manager.podControl.(*fakePodControl).Clear()
  331. fakeRecorder := record.NewFakeRecorder(100)
  332. manager.eventRecorder = fakeRecorder
  333. manager.fakeRecorder = fakeRecorder
  334. }
  335. func validateSyncDaemonSets(t *testing.T, manager *daemonSetsController, fakePodControl *fakePodControl, expectedCreates, expectedDeletes int, expectedEvents int) {
  336. if len(fakePodControl.Templates) != expectedCreates {
  337. t.Errorf("Unexpected number of creates. Expected %d, saw %d\n", expectedCreates, len(fakePodControl.Templates))
  338. }
  339. if len(fakePodControl.DeletePodName) != expectedDeletes {
  340. t.Errorf("Unexpected number of deletes. Expected %d, saw %d\n", expectedDeletes, len(fakePodControl.DeletePodName))
  341. }
  342. if len(manager.fakeRecorder.Events) != expectedEvents {
  343. t.Errorf("Unexpected number of events. Expected %d, saw %d\n", expectedEvents, len(manager.fakeRecorder.Events))
  344. }
  345. // Every Pod created should have a ControllerRef.
  346. if got, want := len(fakePodControl.ControllerRefs), expectedCreates; got != want {
  347. t.Errorf("len(ControllerRefs) = %v, want %v", got, want)
  348. }
  349. // Make sure the ControllerRefs are correct.
  350. for _, controllerRef := range fakePodControl.ControllerRefs {
  351. if got, want := controllerRef.APIVersion, "apps/v1"; got != want {
  352. t.Errorf("controllerRef.APIVersion = %q, want %q", got, want)
  353. }
  354. if got, want := controllerRef.Kind, "DaemonSet"; got != want {
  355. t.Errorf("controllerRef.Kind = %q, want %q", got, want)
  356. }
  357. if controllerRef.Controller == nil || *controllerRef.Controller != true {
  358. t.Errorf("controllerRef.Controller is not set to true")
  359. }
  360. }
  361. }
  362. func syncAndValidateDaemonSets(t *testing.T, manager *daemonSetsController, ds *apps.DaemonSet, podControl *fakePodControl, expectedCreates, expectedDeletes int, expectedEvents int) {
  363. key, err := controller.KeyFunc(ds)
  364. if err != nil {
  365. t.Errorf("Could not get key for daemon.")
  366. }
  367. manager.syncHandler(key)
  368. validateSyncDaemonSets(t, manager, podControl, expectedCreates, expectedDeletes, expectedEvents)
  369. }
  370. // clearExpectations copies the FakePodControl to PodStore and clears the create and delete expectations.
  371. func clearExpectations(t *testing.T, manager *daemonSetsController, ds *apps.DaemonSet, fakePodControl *fakePodControl) {
  372. fakePodControl.Clear()
  373. key, err := controller.KeyFunc(ds)
  374. if err != nil {
  375. t.Errorf("Could not get key for daemon.")
  376. return
  377. }
  378. manager.expectations.DeleteExpectations(key)
  379. }
  380. func TestDeleteFinalStateUnknown(t *testing.T) {
  381. for _, f := range []bool{true, false} {
  382. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  383. for _, strategy := range updateStrategies() {
  384. manager, _, _, err := newTestController()
  385. if err != nil {
  386. t.Fatalf("error creating DaemonSets controller: %v", err)
  387. }
  388. addNodes(manager.nodeStore, 0, 1, nil)
  389. ds := newDaemonSet("foo")
  390. ds.Spec.UpdateStrategy = *strategy
  391. // DeletedFinalStateUnknown should queue the embedded DS if found.
  392. manager.deleteDaemonset(cache.DeletedFinalStateUnknown{Key: "foo", Obj: ds})
  393. enqueuedKey, _ := manager.queue.Get()
  394. if enqueuedKey.(string) != "default/foo" {
  395. t.Errorf("expected delete of DeletedFinalStateUnknown to enqueue the daemonset but found: %#v", enqueuedKey)
  396. }
  397. }
  398. }
  399. }
  400. func markPodsReady(store cache.Store) {
  401. // mark pods as ready
  402. for _, obj := range store.List() {
  403. pod := obj.(*v1.Pod)
  404. markPodReady(pod)
  405. }
  406. }
  407. func markPodReady(pod *v1.Pod) {
  408. condition := v1.PodCondition{Type: v1.PodReady, Status: v1.ConditionTrue}
  409. podutil.UpdatePodCondition(&pod.Status, &condition)
  410. }
  411. // DaemonSets without node selectors should launch pods on every node.
  412. func TestSimpleDaemonSetLaunchesPods(t *testing.T) {
  413. for _, f := range []bool{true, false} {
  414. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  415. for _, strategy := range updateStrategies() {
  416. ds := newDaemonSet("foo")
  417. ds.Spec.UpdateStrategy = *strategy
  418. manager, podControl, _, err := newTestController(ds)
  419. if err != nil {
  420. t.Fatalf("error creating DaemonSets controller: %v", err)
  421. }
  422. addNodes(manager.nodeStore, 0, 5, nil)
  423. manager.dsStore.Add(ds)
  424. syncAndValidateDaemonSets(t, manager, ds, podControl, 5, 0, 0)
  425. }
  426. }
  427. }
  428. // When ScheduleDaemonSetPods is enabled, DaemonSets without node selectors should
  429. // launch pods on every node by NodeAffinity.
  430. func TestSimpleDaemonSetScheduleDaemonSetPodsLaunchesPods(t *testing.T) {
  431. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, true)()
  432. nodeNum := 5
  433. for _, strategy := range updateStrategies() {
  434. ds := newDaemonSet("foo")
  435. ds.Spec.UpdateStrategy = *strategy
  436. manager, podControl, _, err := newTestController(ds)
  437. if err != nil {
  438. t.Fatalf("error creating DaemonSets controller: %v", err)
  439. }
  440. addNodes(manager.nodeStore, 0, nodeNum, nil)
  441. manager.dsStore.Add(ds)
  442. syncAndValidateDaemonSets(t, manager, ds, podControl, nodeNum, 0, 0)
  443. // Check for ScheduleDaemonSetPods feature
  444. if len(podControl.podIDMap) != nodeNum {
  445. t.Fatalf("failed to create pods for DaemonSet when enabled ScheduleDaemonSetPods.")
  446. }
  447. nodeMap := make(map[string]*v1.Node)
  448. for _, node := range manager.nodeStore.List() {
  449. n := node.(*v1.Node)
  450. nodeMap[n.Name] = n
  451. }
  452. if len(nodeMap) != nodeNum {
  453. t.Fatalf("not enough nodes in the store, expected: %v, got: %v",
  454. nodeNum, len(nodeMap))
  455. }
  456. for _, pod := range podControl.podIDMap {
  457. if len(pod.Spec.NodeName) != 0 {
  458. t.Fatalf("the hostname of pod %v should be empty, but got %s",
  459. pod.Name, pod.Spec.NodeName)
  460. }
  461. if pod.Spec.Affinity == nil {
  462. t.Fatalf("the Affinity of pod %s is nil.", pod.Name)
  463. }
  464. if pod.Spec.Affinity.NodeAffinity == nil {
  465. t.Fatalf("the NodeAffinity of pod %s is nil.", pod.Name)
  466. }
  467. nodeSelector := pod.Spec.Affinity.NodeAffinity.RequiredDuringSchedulingIgnoredDuringExecution
  468. if nodeSelector == nil {
  469. t.Fatalf("the node selector of pod %s is nil.", pod.Name)
  470. }
  471. if len(nodeSelector.NodeSelectorTerms) != 1 {
  472. t.Fatalf("incorrect number of node selector terms in pod %s, expected: 1, got: %d.",
  473. pod.Name, len(nodeSelector.NodeSelectorTerms))
  474. }
  475. if len(nodeSelector.NodeSelectorTerms[0].MatchFields) != 1 {
  476. t.Fatalf("incorrect number of fields in node selector term for pod %s, expected: 1, got: %d.",
  477. pod.Name, len(nodeSelector.NodeSelectorTerms[0].MatchFields))
  478. }
  479. field := nodeSelector.NodeSelectorTerms[0].MatchFields[0]
  480. if field.Key == schedulerapi.NodeFieldSelectorKeyNodeName {
  481. if field.Operator != v1.NodeSelectorOpIn {
  482. t.Fatalf("the operation of hostname NodeAffinity is not %v", v1.NodeSelectorOpIn)
  483. }
  484. if len(field.Values) != 1 {
  485. t.Fatalf("incorrect hostname in node affinity: expected 1, got %v", len(field.Values))
  486. }
  487. delete(nodeMap, field.Values[0])
  488. }
  489. }
  490. if len(nodeMap) != 0 {
  491. t.Fatalf("did not foud pods on nodes %+v", nodeMap)
  492. }
  493. }
  494. }
  495. // Simulate a cluster with 100 nodes, but simulate a limit (like a quota limit)
  496. // of 10 pods, and verify that the ds doesn't make 100 create calls per sync pass
  497. func TestSimpleDaemonSetPodCreateErrors(t *testing.T) {
  498. for _, f := range []bool{true, false} {
  499. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  500. for _, strategy := range updateStrategies() {
  501. ds := newDaemonSet("foo")
  502. ds.Spec.UpdateStrategy = *strategy
  503. manager, podControl, _, err := newTestController(ds)
  504. if err != nil {
  505. t.Fatalf("error creating DaemonSets controller: %v", err)
  506. }
  507. podControl.FakePodControl.CreateLimit = 10
  508. addNodes(manager.nodeStore, 0, podControl.FakePodControl.CreateLimit*10, nil)
  509. manager.dsStore.Add(ds)
  510. syncAndValidateDaemonSets(t, manager, ds, podControl, podControl.FakePodControl.CreateLimit, 0, 0)
  511. expectedLimit := 0
  512. for pass := uint8(0); expectedLimit <= podControl.FakePodControl.CreateLimit; pass++ {
  513. expectedLimit += controller.SlowStartInitialBatchSize << pass
  514. }
  515. if podControl.FakePodControl.CreateCallCount > expectedLimit {
  516. t.Errorf("Unexpected number of create calls. Expected <= %d, saw %d\n", podControl.FakePodControl.CreateLimit*2, podControl.FakePodControl.CreateCallCount)
  517. }
  518. }
  519. }
  520. }
  521. func TestDaemonSetPodCreateExpectationsError(t *testing.T) {
  522. for _, f := range []bool{true, false} {
  523. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  524. strategies := updateStrategies()
  525. for _, strategy := range strategies {
  526. ds := newDaemonSet("foo")
  527. ds.Spec.UpdateStrategy = *strategy
  528. manager, podControl, _, err := newTestController(ds)
  529. if err != nil {
  530. t.Fatalf("error creating DaemonSets controller: %v", err)
  531. }
  532. podControl.FakePodControl.CreateLimit = 10
  533. creationExpectations := 100
  534. addNodes(manager.nodeStore, 0, 100, nil)
  535. manager.dsStore.Add(ds)
  536. syncAndValidateDaemonSets(t, manager, ds, podControl, podControl.FakePodControl.CreateLimit, 0, 0)
  537. dsKey, err := controller.KeyFunc(ds)
  538. if err != nil {
  539. t.Fatalf("error get DaemonSets controller key: %v", err)
  540. }
  541. if !manager.expectations.SatisfiedExpectations(dsKey) {
  542. t.Errorf("Unsatisfied pod creation expectatitons. Expected %d", creationExpectations)
  543. }
  544. }
  545. }
  546. }
  547. func TestSimpleDaemonSetUpdatesStatusAfterLaunchingPods(t *testing.T) {
  548. for _, f := range []bool{true, false} {
  549. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  550. for _, strategy := range updateStrategies() {
  551. ds := newDaemonSet("foo")
  552. ds.Spec.UpdateStrategy = *strategy
  553. manager, podControl, clientset, err := newTestController(ds)
  554. if err != nil {
  555. t.Fatalf("error creating DaemonSets controller: %v", err)
  556. }
  557. var updated *apps.DaemonSet
  558. clientset.PrependReactor("update", "daemonsets", func(action core.Action) (handled bool, ret runtime.Object, err error) {
  559. if action.GetSubresource() != "status" {
  560. return false, nil, nil
  561. }
  562. if u, ok := action.(core.UpdateAction); ok {
  563. updated = u.GetObject().(*apps.DaemonSet)
  564. }
  565. return false, nil, nil
  566. })
  567. manager.dsStore.Add(ds)
  568. addNodes(manager.nodeStore, 0, 5, nil)
  569. syncAndValidateDaemonSets(t, manager, ds, podControl, 5, 0, 0)
  570. // Make sure the single sync() updated Status already for the change made
  571. // during the manage() phase.
  572. if got, want := updated.Status.CurrentNumberScheduled, int32(5); got != want {
  573. t.Errorf("Status.CurrentNumberScheduled = %v, want %v", got, want)
  574. }
  575. }
  576. }
  577. }
  578. // DaemonSets should do nothing if there aren't any nodes
  579. func TestNoNodesDoesNothing(t *testing.T) {
  580. for _, f := range []bool{true, false} {
  581. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  582. for _, strategy := range updateStrategies() {
  583. manager, podControl, _, err := newTestController()
  584. if err != nil {
  585. t.Fatalf("error creating DaemonSets controller: %v", err)
  586. }
  587. ds := newDaemonSet("foo")
  588. ds.Spec.UpdateStrategy = *strategy
  589. manager.dsStore.Add(ds)
  590. syncAndValidateDaemonSets(t, manager, ds, podControl, 0, 0, 0)
  591. }
  592. }
  593. }
  594. // DaemonSets without node selectors should launch on a single node in a
  595. // single node cluster.
  596. func TestOneNodeDaemonLaunchesPod(t *testing.T) {
  597. for _, f := range []bool{true, false} {
  598. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  599. for _, strategy := range updateStrategies() {
  600. ds := newDaemonSet("foo")
  601. ds.Spec.UpdateStrategy = *strategy
  602. manager, podControl, _, err := newTestController(ds)
  603. if err != nil {
  604. t.Fatalf("error creating DaemonSets controller: %v", err)
  605. }
  606. manager.nodeStore.Add(newNode("only-node", nil))
  607. manager.dsStore.Add(ds)
  608. syncAndValidateDaemonSets(t, manager, ds, podControl, 1, 0, 0)
  609. }
  610. }
  611. }
  612. // DaemonSets should place onto NotReady nodes
  613. func TestNotReadyNodeDaemonDoesLaunchPod(t *testing.T) {
  614. for _, f := range []bool{true, false} {
  615. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  616. for _, strategy := range updateStrategies() {
  617. ds := newDaemonSet("foo")
  618. ds.Spec.UpdateStrategy = *strategy
  619. manager, podControl, _, err := newTestController(ds)
  620. if err != nil {
  621. t.Fatalf("error creating DaemonSets controller: %v", err)
  622. }
  623. node := newNode("not-ready", nil)
  624. node.Status.Conditions = []v1.NodeCondition{
  625. {Type: v1.NodeReady, Status: v1.ConditionFalse},
  626. }
  627. manager.nodeStore.Add(node)
  628. manager.dsStore.Add(ds)
  629. syncAndValidateDaemonSets(t, manager, ds, podControl, 1, 0, 0)
  630. }
  631. }
  632. }
  633. func resourcePodSpec(nodeName, memory, cpu string) v1.PodSpec {
  634. return v1.PodSpec{
  635. NodeName: nodeName,
  636. Containers: []v1.Container{{
  637. Resources: v1.ResourceRequirements{
  638. Requests: allocatableResources(memory, cpu),
  639. },
  640. }},
  641. }
  642. }
  643. func resourceContainerSpec(memory, cpu string) v1.ResourceRequirements {
  644. return v1.ResourceRequirements{
  645. Requests: allocatableResources(memory, cpu),
  646. }
  647. }
  648. func resourcePodSpecWithoutNodeName(memory, cpu string) v1.PodSpec {
  649. return v1.PodSpec{
  650. Containers: []v1.Container{{
  651. Resources: v1.ResourceRequirements{
  652. Requests: allocatableResources(memory, cpu),
  653. },
  654. }},
  655. }
  656. }
  657. func allocatableResources(memory, cpu string) v1.ResourceList {
  658. return v1.ResourceList{
  659. v1.ResourceMemory: resource.MustParse(memory),
  660. v1.ResourceCPU: resource.MustParse(cpu),
  661. v1.ResourcePods: resource.MustParse("100"),
  662. }
  663. }
  664. // When ScheduleDaemonSetPods is disabled, DaemonSets should not place onto nodes with insufficient free resource
  665. func TestInsufficientCapacityNodeDaemonDoesNotLaunchPod(t *testing.T) {
  666. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, false)()
  667. for _, strategy := range updateStrategies() {
  668. podSpec := resourcePodSpec("too-much-mem", "75M", "75m")
  669. ds := newDaemonSet("foo")
  670. ds.Spec.UpdateStrategy = *strategy
  671. ds.Spec.Template.Spec = podSpec
  672. manager, podControl, _, err := newTestController(ds)
  673. if err != nil {
  674. t.Fatalf("error creating DaemonSets controller: %v", err)
  675. }
  676. node := newNode("too-much-mem", nil)
  677. node.Status.Allocatable = allocatableResources("100M", "200m")
  678. manager.nodeStore.Add(node)
  679. manager.podStore.Add(&v1.Pod{
  680. Spec: podSpec,
  681. })
  682. manager.dsStore.Add(ds)
  683. switch strategy.Type {
  684. case apps.OnDeleteDaemonSetStrategyType:
  685. syncAndValidateDaemonSets(t, manager, ds, podControl, 0, 0, 2)
  686. case apps.RollingUpdateDaemonSetStrategyType:
  687. syncAndValidateDaemonSets(t, manager, ds, podControl, 0, 0, 3)
  688. default:
  689. t.Fatalf("unexpected UpdateStrategy %+v", strategy)
  690. }
  691. }
  692. }
  693. // DaemonSets should not unschedule a daemonset pod from a node with insufficient free resource
  694. func TestInsufficientCapacityNodeDaemonDoesNotUnscheduleRunningPod(t *testing.T) {
  695. for _, f := range []bool{true, false} {
  696. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  697. for _, strategy := range updateStrategies() {
  698. podSpec := resourcePodSpec("too-much-mem", "75M", "75m")
  699. podSpec.NodeName = "too-much-mem"
  700. ds := newDaemonSet("foo")
  701. ds.Spec.UpdateStrategy = *strategy
  702. ds.Spec.Template.Spec = podSpec
  703. manager, podControl, _, err := newTestController(ds)
  704. if err != nil {
  705. t.Fatalf("error creating DaemonSets controller: %v", err)
  706. }
  707. node := newNode("too-much-mem", nil)
  708. node.Status.Allocatable = allocatableResources("100M", "200m")
  709. manager.nodeStore.Add(node)
  710. manager.podStore.Add(&v1.Pod{
  711. Spec: podSpec,
  712. })
  713. manager.dsStore.Add(ds)
  714. switch strategy.Type {
  715. case apps.OnDeleteDaemonSetStrategyType:
  716. if !utilfeature.DefaultFeatureGate.Enabled(features.ScheduleDaemonSetPods) {
  717. syncAndValidateDaemonSets(t, manager, ds, podControl, 0, 0, 2)
  718. } else {
  719. syncAndValidateDaemonSets(t, manager, ds, podControl, 1, 0, 0)
  720. }
  721. case apps.RollingUpdateDaemonSetStrategyType:
  722. if !utilfeature.DefaultFeatureGate.Enabled(features.ScheduleDaemonSetPods) {
  723. syncAndValidateDaemonSets(t, manager, ds, podControl, 0, 0, 3)
  724. } else {
  725. syncAndValidateDaemonSets(t, manager, ds, podControl, 1, 0, 0)
  726. }
  727. default:
  728. t.Fatalf("unexpected UpdateStrategy %+v", strategy)
  729. }
  730. }
  731. }
  732. }
  733. // DaemonSets should only place onto nodes with sufficient free resource and matched node selector
  734. func TestInsufficientCapacityNodeSufficientCapacityWithNodeLabelDaemonLaunchPod(t *testing.T) {
  735. for _, f := range []bool{true, false} {
  736. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  737. podSpec := resourcePodSpecWithoutNodeName("50M", "75m")
  738. ds := newDaemonSet("foo")
  739. ds.Spec.Template.Spec = podSpec
  740. ds.Spec.Template.Spec.NodeSelector = simpleNodeLabel
  741. manager, podControl, _, err := newTestController(ds)
  742. if err != nil {
  743. t.Fatalf("error creating DaemonSets controller: %v", err)
  744. }
  745. node1 := newNode("not-enough-resource", nil)
  746. node1.Status.Allocatable = allocatableResources("10M", "20m")
  747. node2 := newNode("enough-resource", simpleNodeLabel)
  748. node2.Status.Allocatable = allocatableResources("100M", "200m")
  749. manager.nodeStore.Add(node1)
  750. manager.nodeStore.Add(node2)
  751. manager.dsStore.Add(ds)
  752. syncAndValidateDaemonSets(t, manager, ds, podControl, 1, 0, 0)
  753. // we do not expect any event for insufficient free resource
  754. if len(manager.fakeRecorder.Events) != 0 {
  755. t.Fatalf("unexpected events, got %v, expected %v: %+v", len(manager.fakeRecorder.Events), 0, manager.fakeRecorder.Events)
  756. }
  757. }
  758. }
  759. // When ScheduleDaemonSetPods is disabled, DaemonSetPods should launch onto node with terminated pods if there
  760. // are sufficient resources.
  761. func TestSufficientCapacityWithTerminatedPodsDaemonLaunchesPod(t *testing.T) {
  762. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, false)()
  763. validate := func(strategy *apps.DaemonSetUpdateStrategy, expectedEvents int) {
  764. podSpec := resourcePodSpec("too-much-mem", "75M", "75m")
  765. ds := newDaemonSet("foo")
  766. ds.Spec.UpdateStrategy = *strategy
  767. ds.Spec.Template.Spec = podSpec
  768. manager, podControl, _, err := newTestController(ds)
  769. if err != nil {
  770. t.Fatalf("error creating DaemonSets controller: %v", err)
  771. }
  772. node := newNode("too-much-mem", nil)
  773. node.Status.Allocatable = allocatableResources("100M", "200m")
  774. manager.nodeStore.Add(node)
  775. manager.podStore.Add(&v1.Pod{
  776. Spec: podSpec,
  777. Status: v1.PodStatus{Phase: v1.PodSucceeded},
  778. })
  779. manager.dsStore.Add(ds)
  780. syncAndValidateDaemonSets(t, manager, ds, podControl, 1, 0, expectedEvents)
  781. }
  782. tests := []struct {
  783. strategy *apps.DaemonSetUpdateStrategy
  784. expectedEvents int
  785. }{
  786. {
  787. strategy: newOnDeleteStrategy(),
  788. expectedEvents: 1,
  789. },
  790. {
  791. strategy: newRollbackStrategy(),
  792. expectedEvents: 2,
  793. },
  794. }
  795. for _, t := range tests {
  796. validate(t.strategy, t.expectedEvents)
  797. }
  798. }
  799. // When ScheduleDaemonSetPods is disabled, DaemonSets should place onto nodes with sufficient free resources.
  800. func TestSufficientCapacityNodeDaemonLaunchesPod(t *testing.T) {
  801. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, false)()
  802. validate := func(strategy *apps.DaemonSetUpdateStrategy, expectedEvents int) {
  803. podSpec := resourcePodSpec("not-too-much-mem", "75M", "75m")
  804. ds := newDaemonSet("foo")
  805. ds.Spec.UpdateStrategy = *strategy
  806. ds.Spec.Template.Spec = podSpec
  807. manager, podControl, _, err := newTestController(ds)
  808. if err != nil {
  809. t.Fatalf("error creating DaemonSets controller: %v", err)
  810. }
  811. node := newNode("not-too-much-mem", nil)
  812. node.Status.Allocatable = allocatableResources("200M", "200m")
  813. manager.nodeStore.Add(node)
  814. manager.podStore.Add(&v1.Pod{
  815. Spec: podSpec,
  816. })
  817. manager.dsStore.Add(ds)
  818. syncAndValidateDaemonSets(t, manager, ds, podControl, 1, 0, expectedEvents)
  819. }
  820. tests := []struct {
  821. strategy *apps.DaemonSetUpdateStrategy
  822. expectedEvents int
  823. }{
  824. {
  825. strategy: newOnDeleteStrategy(),
  826. expectedEvents: 1,
  827. },
  828. {
  829. strategy: newRollbackStrategy(),
  830. expectedEvents: 2,
  831. },
  832. }
  833. for _, t := range tests {
  834. validate(t.strategy, t.expectedEvents)
  835. }
  836. }
  837. // DaemonSet should launch a pod on a node with taint NetworkUnavailable condition.
  838. func TestNetworkUnavailableNodeDaemonLaunchesPod(t *testing.T) {
  839. for _, f := range []bool{true, false} {
  840. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  841. for _, strategy := range updateStrategies() {
  842. ds := newDaemonSet("simple")
  843. ds.Spec.UpdateStrategy = *strategy
  844. manager, podControl, _, err := newTestController(ds)
  845. if err != nil {
  846. t.Fatalf("error creating DaemonSets controller: %v", err)
  847. }
  848. node := newNode("network-unavailable", nil)
  849. node.Status.Conditions = []v1.NodeCondition{
  850. {Type: v1.NodeNetworkUnavailable, Status: v1.ConditionTrue},
  851. }
  852. manager.nodeStore.Add(node)
  853. manager.dsStore.Add(ds)
  854. syncAndValidateDaemonSets(t, manager, ds, podControl, 1, 0, 0)
  855. }
  856. }
  857. }
  858. // DaemonSets not take any actions when being deleted
  859. func TestDontDoAnythingIfBeingDeleted(t *testing.T) {
  860. for _, f := range []bool{true, false} {
  861. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  862. for _, strategy := range updateStrategies() {
  863. podSpec := resourcePodSpec("not-too-much-mem", "75M", "75m")
  864. ds := newDaemonSet("foo")
  865. ds.Spec.UpdateStrategy = *strategy
  866. ds.Spec.Template.Spec = podSpec
  867. now := metav1.Now()
  868. ds.DeletionTimestamp = &now
  869. manager, podControl, _, err := newTestController(ds)
  870. if err != nil {
  871. t.Fatalf("error creating DaemonSets controller: %v", err)
  872. }
  873. node := newNode("not-too-much-mem", nil)
  874. node.Status.Allocatable = allocatableResources("200M", "200m")
  875. manager.nodeStore.Add(node)
  876. manager.podStore.Add(&v1.Pod{
  877. Spec: podSpec,
  878. })
  879. manager.dsStore.Add(ds)
  880. syncAndValidateDaemonSets(t, manager, ds, podControl, 0, 0, 0)
  881. }
  882. }
  883. }
  884. func TestDontDoAnythingIfBeingDeletedRace(t *testing.T) {
  885. for _, f := range []bool{true, false} {
  886. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  887. for _, strategy := range updateStrategies() {
  888. // Bare client says it IS deleted.
  889. ds := newDaemonSet("foo")
  890. ds.Spec.UpdateStrategy = *strategy
  891. now := metav1.Now()
  892. ds.DeletionTimestamp = &now
  893. manager, podControl, _, err := newTestController(ds)
  894. if err != nil {
  895. t.Fatalf("error creating DaemonSets controller: %v", err)
  896. }
  897. addNodes(manager.nodeStore, 0, 5, nil)
  898. // Lister (cache) says it's NOT deleted.
  899. ds2 := *ds
  900. ds2.DeletionTimestamp = nil
  901. manager.dsStore.Add(&ds2)
  902. // The existence of a matching orphan should block all actions in this state.
  903. pod := newPod("pod1-", "node-0", simpleDaemonSetLabel, nil)
  904. manager.podStore.Add(pod)
  905. syncAndValidateDaemonSets(t, manager, ds, podControl, 0, 0, 0)
  906. }
  907. }
  908. }
  909. // When ScheduleDaemonSetPods is disabled, DaemonSets should not place onto nodes that would cause port conflicts.
  910. func TestPortConflictNodeDaemonDoesNotLaunchPod(t *testing.T) {
  911. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, false)()
  912. for _, strategy := range updateStrategies() {
  913. podSpec := v1.PodSpec{
  914. NodeName: "port-conflict",
  915. Containers: []v1.Container{{
  916. Ports: []v1.ContainerPort{{
  917. HostPort: 666,
  918. }},
  919. }},
  920. }
  921. manager, podControl, _, err := newTestController()
  922. if err != nil {
  923. t.Fatalf("error creating DaemonSets controller: %v", err)
  924. }
  925. node := newNode("port-conflict", nil)
  926. manager.nodeStore.Add(node)
  927. manager.podStore.Add(&v1.Pod{
  928. Spec: podSpec,
  929. })
  930. ds := newDaemonSet("foo")
  931. ds.Spec.UpdateStrategy = *strategy
  932. ds.Spec.Template.Spec = podSpec
  933. manager.dsStore.Add(ds)
  934. syncAndValidateDaemonSets(t, manager, ds, podControl, 0, 0, 0)
  935. }
  936. }
  937. // Test that if the node is already scheduled with a pod using a host port
  938. // but belonging to the same daemonset, we don't delete that pod
  939. //
  940. // Issue: https://github.com/kubernetes/kubernetes/issues/22309
  941. func TestPortConflictWithSameDaemonPodDoesNotDeletePod(t *testing.T) {
  942. for _, f := range []bool{true, false} {
  943. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  944. for _, strategy := range updateStrategies() {
  945. podSpec := v1.PodSpec{
  946. NodeName: "port-conflict",
  947. Containers: []v1.Container{{
  948. Ports: []v1.ContainerPort{{
  949. HostPort: 666,
  950. }},
  951. }},
  952. }
  953. manager, podControl, _, err := newTestController()
  954. if err != nil {
  955. t.Fatalf("error creating DaemonSets controller: %v", err)
  956. }
  957. node := newNode("port-conflict", nil)
  958. manager.nodeStore.Add(node)
  959. ds := newDaemonSet("foo")
  960. ds.Spec.UpdateStrategy = *strategy
  961. ds.Spec.Template.Spec = podSpec
  962. manager.dsStore.Add(ds)
  963. pod := newPod(ds.Name+"-", node.Name, simpleDaemonSetLabel, ds)
  964. manager.podStore.Add(pod)
  965. syncAndValidateDaemonSets(t, manager, ds, podControl, 0, 0, 0)
  966. }
  967. }
  968. }
  969. // DaemonSets should place onto nodes that would not cause port conflicts
  970. func TestNoPortConflictNodeDaemonLaunchesPod(t *testing.T) {
  971. for _, f := range []bool{true, false} {
  972. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  973. for _, strategy := range updateStrategies() {
  974. podSpec1 := v1.PodSpec{
  975. NodeName: "no-port-conflict",
  976. Containers: []v1.Container{{
  977. Ports: []v1.ContainerPort{{
  978. HostPort: 6661,
  979. }},
  980. }},
  981. }
  982. podSpec2 := v1.PodSpec{
  983. NodeName: "no-port-conflict",
  984. Containers: []v1.Container{{
  985. Ports: []v1.ContainerPort{{
  986. HostPort: 6662,
  987. }},
  988. }},
  989. }
  990. ds := newDaemonSet("foo")
  991. ds.Spec.UpdateStrategy = *strategy
  992. ds.Spec.Template.Spec = podSpec2
  993. manager, podControl, _, err := newTestController(ds)
  994. if err != nil {
  995. t.Fatalf("error creating DaemonSets controller: %v", err)
  996. }
  997. node := newNode("no-port-conflict", nil)
  998. manager.nodeStore.Add(node)
  999. manager.podStore.Add(&v1.Pod{
  1000. Spec: podSpec1,
  1001. })
  1002. manager.dsStore.Add(ds)
  1003. syncAndValidateDaemonSets(t, manager, ds, podControl, 1, 0, 0)
  1004. }
  1005. }
  1006. }
  1007. // DaemonSetController should not sync DaemonSets with empty pod selectors.
  1008. //
  1009. // issue https://github.com/kubernetes/kubernetes/pull/23223
  1010. func TestPodIsNotDeletedByDaemonsetWithEmptyLabelSelector(t *testing.T) {
  1011. // Create a misconfigured DaemonSet. An empty pod selector is invalid but could happen
  1012. // if we upgrade and make a backwards incompatible change.
  1013. //
  1014. // The node selector matches no nodes which mimics the behavior of kubectl delete.
  1015. //
  1016. // The DaemonSet should not schedule pods and should not delete scheduled pods in
  1017. // this case even though it's empty pod selector matches all pods. The DaemonSetController
  1018. // should detect this misconfiguration and choose not to sync the DaemonSet. We should
  1019. // not observe a deletion of the pod on node1.
  1020. for _, f := range []bool{true, false} {
  1021. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  1022. for _, strategy := range updateStrategies() {
  1023. ds := newDaemonSet("foo")
  1024. ds.Spec.UpdateStrategy = *strategy
  1025. ls := metav1.LabelSelector{}
  1026. ds.Spec.Selector = &ls
  1027. ds.Spec.Template.Spec.NodeSelector = map[string]string{"foo": "bar"}
  1028. manager, podControl, _, err := newTestController(ds)
  1029. if err != nil {
  1030. t.Fatalf("error creating DaemonSets controller: %v", err)
  1031. }
  1032. manager.nodeStore.Add(newNode("node1", nil))
  1033. // Create pod not controlled by a daemonset.
  1034. manager.podStore.Add(&v1.Pod{
  1035. ObjectMeta: metav1.ObjectMeta{
  1036. Labels: map[string]string{"bang": "boom"},
  1037. Namespace: metav1.NamespaceDefault,
  1038. },
  1039. Spec: v1.PodSpec{
  1040. NodeName: "node1",
  1041. },
  1042. })
  1043. manager.dsStore.Add(ds)
  1044. syncAndValidateDaemonSets(t, manager, ds, podControl, 0, 0, 1)
  1045. }
  1046. }
  1047. }
  1048. // Controller should not create pods on nodes which have daemon pods, and should remove excess pods from nodes that have extra pods.
  1049. func TestDealsWithExistingPods(t *testing.T) {
  1050. for _, f := range []bool{true, false} {
  1051. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  1052. for _, strategy := range updateStrategies() {
  1053. ds := newDaemonSet("foo")
  1054. ds.Spec.UpdateStrategy = *strategy
  1055. manager, podControl, _, err := newTestController(ds)
  1056. if err != nil {
  1057. t.Fatalf("error creating DaemonSets controller: %v", err)
  1058. }
  1059. manager.dsStore.Add(ds)
  1060. addNodes(manager.nodeStore, 0, 5, nil)
  1061. addPods(manager.podStore, "node-1", simpleDaemonSetLabel, ds, 1)
  1062. addPods(manager.podStore, "node-2", simpleDaemonSetLabel, ds, 2)
  1063. addPods(manager.podStore, "node-3", simpleDaemonSetLabel, ds, 5)
  1064. addPods(manager.podStore, "node-4", simpleDaemonSetLabel2, ds, 2)
  1065. syncAndValidateDaemonSets(t, manager, ds, podControl, 2, 5, 0)
  1066. }
  1067. }
  1068. }
  1069. // Daemon with node selector should launch pods on nodes matching selector.
  1070. func TestSelectorDaemonLaunchesPods(t *testing.T) {
  1071. for _, f := range []bool{true, false} {
  1072. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  1073. for _, strategy := range updateStrategies() {
  1074. daemon := newDaemonSet("foo")
  1075. daemon.Spec.UpdateStrategy = *strategy
  1076. daemon.Spec.Template.Spec.NodeSelector = simpleNodeLabel
  1077. manager, podControl, _, err := newTestController(daemon)
  1078. if err != nil {
  1079. t.Fatalf("error creating DaemonSets controller: %v", err)
  1080. }
  1081. addNodes(manager.nodeStore, 0, 4, nil)
  1082. addNodes(manager.nodeStore, 4, 3, simpleNodeLabel)
  1083. manager.dsStore.Add(daemon)
  1084. syncAndValidateDaemonSets(t, manager, daemon, podControl, 3, 0, 0)
  1085. }
  1086. }
  1087. }
  1088. // Daemon with node selector should delete pods from nodes that do not satisfy selector.
  1089. func TestSelectorDaemonDeletesUnselectedPods(t *testing.T) {
  1090. for _, f := range []bool{true, false} {
  1091. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  1092. for _, strategy := range updateStrategies() {
  1093. ds := newDaemonSet("foo")
  1094. ds.Spec.UpdateStrategy = *strategy
  1095. ds.Spec.Template.Spec.NodeSelector = simpleNodeLabel
  1096. manager, podControl, _, err := newTestController(ds)
  1097. if err != nil {
  1098. t.Fatalf("error creating DaemonSets controller: %v", err)
  1099. }
  1100. manager.dsStore.Add(ds)
  1101. addNodes(manager.nodeStore, 0, 5, nil)
  1102. addNodes(manager.nodeStore, 5, 5, simpleNodeLabel)
  1103. addPods(manager.podStore, "node-0", simpleDaemonSetLabel2, ds, 2)
  1104. addPods(manager.podStore, "node-1", simpleDaemonSetLabel, ds, 3)
  1105. addPods(manager.podStore, "node-1", simpleDaemonSetLabel2, ds, 1)
  1106. addPods(manager.podStore, "node-4", simpleDaemonSetLabel, ds, 1)
  1107. syncAndValidateDaemonSets(t, manager, ds, podControl, 5, 4, 0)
  1108. }
  1109. }
  1110. }
  1111. // DaemonSet with node selector should launch pods on nodes matching selector, but also deal with existing pods on nodes.
  1112. func TestSelectorDaemonDealsWithExistingPods(t *testing.T) {
  1113. for _, f := range []bool{true, false} {
  1114. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  1115. for _, strategy := range updateStrategies() {
  1116. ds := newDaemonSet("foo")
  1117. ds.Spec.UpdateStrategy = *strategy
  1118. ds.Spec.Template.Spec.NodeSelector = simpleNodeLabel
  1119. manager, podControl, _, err := newTestController(ds)
  1120. if err != nil {
  1121. t.Fatalf("error creating DaemonSets controller: %v", err)
  1122. }
  1123. manager.dsStore.Add(ds)
  1124. addNodes(manager.nodeStore, 0, 5, nil)
  1125. addNodes(manager.nodeStore, 5, 5, simpleNodeLabel)
  1126. addPods(manager.podStore, "node-0", simpleDaemonSetLabel, ds, 1)
  1127. addPods(manager.podStore, "node-1", simpleDaemonSetLabel, ds, 3)
  1128. addPods(manager.podStore, "node-1", simpleDaemonSetLabel2, ds, 2)
  1129. addPods(manager.podStore, "node-2", simpleDaemonSetLabel, ds, 4)
  1130. addPods(manager.podStore, "node-6", simpleDaemonSetLabel, ds, 13)
  1131. addPods(manager.podStore, "node-7", simpleDaemonSetLabel2, ds, 4)
  1132. addPods(manager.podStore, "node-9", simpleDaemonSetLabel, ds, 1)
  1133. addPods(manager.podStore, "node-9", simpleDaemonSetLabel2, ds, 1)
  1134. syncAndValidateDaemonSets(t, manager, ds, podControl, 3, 20, 0)
  1135. }
  1136. }
  1137. }
  1138. // DaemonSet with node selector which does not match any node labels should not launch pods.
  1139. func TestBadSelectorDaemonDoesNothing(t *testing.T) {
  1140. for _, f := range []bool{true, false} {
  1141. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  1142. for _, strategy := range updateStrategies() {
  1143. manager, podControl, _, err := newTestController()
  1144. if err != nil {
  1145. t.Fatalf("error creating DaemonSets controller: %v", err)
  1146. }
  1147. addNodes(manager.nodeStore, 0, 4, nil)
  1148. addNodes(manager.nodeStore, 4, 3, simpleNodeLabel)
  1149. ds := newDaemonSet("foo")
  1150. ds.Spec.UpdateStrategy = *strategy
  1151. ds.Spec.Template.Spec.NodeSelector = simpleNodeLabel2
  1152. manager.dsStore.Add(ds)
  1153. syncAndValidateDaemonSets(t, manager, ds, podControl, 0, 0, 0)
  1154. }
  1155. }
  1156. }
  1157. // DaemonSet with node name should launch pod on node with corresponding name.
  1158. func TestNameDaemonSetLaunchesPods(t *testing.T) {
  1159. for _, f := range []bool{true, false} {
  1160. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  1161. for _, strategy := range updateStrategies() {
  1162. ds := newDaemonSet("foo")
  1163. ds.Spec.UpdateStrategy = *strategy
  1164. ds.Spec.Template.Spec.NodeName = "node-0"
  1165. manager, podControl, _, err := newTestController(ds)
  1166. if err != nil {
  1167. t.Fatalf("error creating DaemonSets controller: %v", err)
  1168. }
  1169. addNodes(manager.nodeStore, 0, 5, nil)
  1170. manager.dsStore.Add(ds)
  1171. syncAndValidateDaemonSets(t, manager, ds, podControl, 1, 0, 0)
  1172. }
  1173. }
  1174. }
  1175. // DaemonSet with node name that does not exist should not launch pods.
  1176. func TestBadNameDaemonSetDoesNothing(t *testing.T) {
  1177. for _, f := range []bool{true, false} {
  1178. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  1179. for _, strategy := range updateStrategies() {
  1180. ds := newDaemonSet("foo")
  1181. ds.Spec.UpdateStrategy = *strategy
  1182. ds.Spec.Template.Spec.NodeName = "node-10"
  1183. manager, podControl, _, err := newTestController(ds)
  1184. if err != nil {
  1185. t.Fatalf("error creating DaemonSets controller: %v", err)
  1186. }
  1187. addNodes(manager.nodeStore, 0, 5, nil)
  1188. manager.dsStore.Add(ds)
  1189. syncAndValidateDaemonSets(t, manager, ds, podControl, 0, 0, 0)
  1190. }
  1191. }
  1192. }
  1193. // DaemonSet with node selector, and node name, matching a node, should launch a pod on the node.
  1194. func TestNameAndSelectorDaemonSetLaunchesPods(t *testing.T) {
  1195. for _, f := range []bool{true, false} {
  1196. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  1197. for _, strategy := range updateStrategies() {
  1198. ds := newDaemonSet("foo")
  1199. ds.Spec.UpdateStrategy = *strategy
  1200. ds.Spec.Template.Spec.NodeSelector = simpleNodeLabel
  1201. ds.Spec.Template.Spec.NodeName = "node-6"
  1202. manager, podControl, _, err := newTestController(ds)
  1203. if err != nil {
  1204. t.Fatalf("error creating DaemonSets controller: %v", err)
  1205. }
  1206. addNodes(manager.nodeStore, 0, 4, nil)
  1207. addNodes(manager.nodeStore, 4, 3, simpleNodeLabel)
  1208. manager.dsStore.Add(ds)
  1209. syncAndValidateDaemonSets(t, manager, ds, podControl, 1, 0, 0)
  1210. }
  1211. }
  1212. }
  1213. // DaemonSet with node selector that matches some nodes, and node name that matches a different node, should do nothing.
  1214. func TestInconsistentNameSelectorDaemonSetDoesNothing(t *testing.T) {
  1215. for _, f := range []bool{true, false} {
  1216. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  1217. for _, strategy := range updateStrategies() {
  1218. ds := newDaemonSet("foo")
  1219. ds.Spec.UpdateStrategy = *strategy
  1220. ds.Spec.Template.Spec.NodeSelector = simpleNodeLabel
  1221. ds.Spec.Template.Spec.NodeName = "node-0"
  1222. manager, podControl, _, err := newTestController(ds)
  1223. if err != nil {
  1224. t.Fatalf("error creating DaemonSets controller: %v", err)
  1225. }
  1226. addNodes(manager.nodeStore, 0, 4, nil)
  1227. addNodes(manager.nodeStore, 4, 3, simpleNodeLabel)
  1228. manager.dsStore.Add(ds)
  1229. syncAndValidateDaemonSets(t, manager, ds, podControl, 0, 0, 0)
  1230. }
  1231. }
  1232. }
  1233. // DaemonSet with node selector, matching some nodes, should launch pods on all the nodes.
  1234. func TestSelectorDaemonSetLaunchesPods(t *testing.T) {
  1235. for _, f := range []bool{true, false} {
  1236. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  1237. ds := newDaemonSet("foo")
  1238. ds.Spec.Template.Spec.NodeSelector = simpleNodeLabel
  1239. manager, podControl, _, err := newTestController(ds)
  1240. if err != nil {
  1241. t.Fatalf("error creating DaemonSets controller: %v", err)
  1242. }
  1243. addNodes(manager.nodeStore, 0, 4, nil)
  1244. addNodes(manager.nodeStore, 4, 3, simpleNodeLabel)
  1245. manager.dsStore.Add(ds)
  1246. syncAndValidateDaemonSets(t, manager, ds, podControl, 3, 0, 0)
  1247. }
  1248. }
  1249. // Daemon with node affinity should launch pods on nodes matching affinity.
  1250. func TestNodeAffinityDaemonLaunchesPods(t *testing.T) {
  1251. for _, f := range []bool{true, false} {
  1252. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  1253. for _, strategy := range updateStrategies() {
  1254. daemon := newDaemonSet("foo")
  1255. daemon.Spec.UpdateStrategy = *strategy
  1256. daemon.Spec.Template.Spec.Affinity = &v1.Affinity{
  1257. NodeAffinity: &v1.NodeAffinity{
  1258. RequiredDuringSchedulingIgnoredDuringExecution: &v1.NodeSelector{
  1259. NodeSelectorTerms: []v1.NodeSelectorTerm{
  1260. {
  1261. MatchExpressions: []v1.NodeSelectorRequirement{
  1262. {
  1263. Key: "color",
  1264. Operator: v1.NodeSelectorOpIn,
  1265. Values: []string{simpleNodeLabel["color"]},
  1266. },
  1267. },
  1268. },
  1269. },
  1270. },
  1271. },
  1272. }
  1273. manager, podControl, _, err := newTestController(daemon)
  1274. if err != nil {
  1275. t.Fatalf("rrror creating DaemonSetsController: %v", err)
  1276. }
  1277. addNodes(manager.nodeStore, 0, 4, nil)
  1278. addNodes(manager.nodeStore, 4, 3, simpleNodeLabel)
  1279. manager.dsStore.Add(daemon)
  1280. syncAndValidateDaemonSets(t, manager, daemon, podControl, 3, 0, 0)
  1281. }
  1282. }
  1283. }
  1284. func TestNumberReadyStatus(t *testing.T) {
  1285. for _, f := range []bool{true, false} {
  1286. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  1287. for _, strategy := range updateStrategies() {
  1288. ds := newDaemonSet("foo")
  1289. ds.Spec.UpdateStrategy = *strategy
  1290. manager, podControl, clientset, err := newTestController(ds)
  1291. if err != nil {
  1292. t.Fatalf("error creating DaemonSets controller: %v", err)
  1293. }
  1294. var updated *apps.DaemonSet
  1295. clientset.PrependReactor("update", "daemonsets", func(action core.Action) (handled bool, ret runtime.Object, err error) {
  1296. if action.GetSubresource() != "status" {
  1297. return false, nil, nil
  1298. }
  1299. if u, ok := action.(core.UpdateAction); ok {
  1300. updated = u.GetObject().(*apps.DaemonSet)
  1301. }
  1302. return false, nil, nil
  1303. })
  1304. addNodes(manager.nodeStore, 0, 2, simpleNodeLabel)
  1305. addPods(manager.podStore, "node-0", simpleDaemonSetLabel, ds, 1)
  1306. addPods(manager.podStore, "node-1", simpleDaemonSetLabel, ds, 1)
  1307. manager.dsStore.Add(ds)
  1308. syncAndValidateDaemonSets(t, manager, ds, podControl, 0, 0, 0)
  1309. if updated.Status.NumberReady != 0 {
  1310. t.Errorf("Wrong daemon %s status: %v", updated.Name, updated.Status)
  1311. }
  1312. selector, _ := metav1.LabelSelectorAsSelector(ds.Spec.Selector)
  1313. daemonPods, _ := manager.podLister.Pods(ds.Namespace).List(selector)
  1314. for _, pod := range daemonPods {
  1315. condition := v1.PodCondition{Type: v1.PodReady, Status: v1.ConditionTrue}
  1316. pod.Status.Conditions = append(pod.Status.Conditions, condition)
  1317. }
  1318. syncAndValidateDaemonSets(t, manager, ds, podControl, 0, 0, 0)
  1319. if updated.Status.NumberReady != 2 {
  1320. t.Errorf("Wrong daemon %s status: %v", updated.Name, updated.Status)
  1321. }
  1322. }
  1323. }
  1324. }
  1325. func TestObservedGeneration(t *testing.T) {
  1326. for _, f := range []bool{true, false} {
  1327. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  1328. for _, strategy := range updateStrategies() {
  1329. ds := newDaemonSet("foo")
  1330. ds.Spec.UpdateStrategy = *strategy
  1331. ds.Generation = 1
  1332. manager, podControl, clientset, err := newTestController(ds)
  1333. if err != nil {
  1334. t.Fatalf("error creating DaemonSets controller: %v", err)
  1335. }
  1336. var updated *apps.DaemonSet
  1337. clientset.PrependReactor("update", "daemonsets", func(action core.Action) (handled bool, ret runtime.Object, err error) {
  1338. if action.GetSubresource() != "status" {
  1339. return false, nil, nil
  1340. }
  1341. if u, ok := action.(core.UpdateAction); ok {
  1342. updated = u.GetObject().(*apps.DaemonSet)
  1343. }
  1344. return false, nil, nil
  1345. })
  1346. addNodes(manager.nodeStore, 0, 1, simpleNodeLabel)
  1347. addPods(manager.podStore, "node-0", simpleDaemonSetLabel, ds, 1)
  1348. manager.dsStore.Add(ds)
  1349. syncAndValidateDaemonSets(t, manager, ds, podControl, 0, 0, 0)
  1350. if updated.Status.ObservedGeneration != ds.Generation {
  1351. t.Errorf("Wrong ObservedGeneration for daemon %s in status. Expected %d, got %d", updated.Name, ds.Generation, updated.Status.ObservedGeneration)
  1352. }
  1353. }
  1354. }
  1355. }
  1356. // DaemonSet controller should kill all failed pods and create at most 1 pod on every node.
  1357. func TestDaemonKillFailedPods(t *testing.T) {
  1358. tests := []struct {
  1359. numFailedPods, numNormalPods, expectedCreates, expectedDeletes, expectedEvents int
  1360. test string
  1361. }{
  1362. {numFailedPods: 0, numNormalPods: 1, expectedCreates: 0, expectedDeletes: 0, expectedEvents: 0, test: "normal (do nothing)"},
  1363. {numFailedPods: 0, numNormalPods: 0, expectedCreates: 1, expectedDeletes: 0, expectedEvents: 0, test: "no pods (create 1)"},
  1364. {numFailedPods: 1, numNormalPods: 0, expectedCreates: 0, expectedDeletes: 1, expectedEvents: 1, test: "1 failed pod (kill 1), 0 normal pod (create 0; will create in the next sync)"},
  1365. {numFailedPods: 1, numNormalPods: 3, expectedCreates: 0, expectedDeletes: 3, expectedEvents: 1, test: "1 failed pod (kill 1), 3 normal pods (kill 2)"},
  1366. }
  1367. for _, test := range tests {
  1368. t.Run(test.test, func(t *testing.T) {
  1369. for _, f := range []bool{true, false} {
  1370. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  1371. for _, strategy := range updateStrategies() {
  1372. ds := newDaemonSet("foo")
  1373. ds.Spec.UpdateStrategy = *strategy
  1374. manager, podControl, _, err := newTestController(ds)
  1375. if err != nil {
  1376. t.Fatalf("error creating DaemonSets controller: %v", err)
  1377. }
  1378. manager.dsStore.Add(ds)
  1379. addNodes(manager.nodeStore, 0, 1, nil)
  1380. addFailedPods(manager.podStore, "node-0", simpleDaemonSetLabel, ds, test.numFailedPods)
  1381. addPods(manager.podStore, "node-0", simpleDaemonSetLabel, ds, test.numNormalPods)
  1382. syncAndValidateDaemonSets(t, manager, ds, podControl, test.expectedCreates, test.expectedDeletes, test.expectedEvents)
  1383. }
  1384. }
  1385. })
  1386. }
  1387. }
  1388. // DaemonSet controller needs to backoff when killing failed pods to avoid hot looping and fighting with kubelet.
  1389. func TestDaemonKillFailedPodsBackoff(t *testing.T) {
  1390. for _, f := range []bool{true, false} {
  1391. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  1392. for _, strategy := range updateStrategies() {
  1393. t.Run(string(strategy.Type), func(t *testing.T) {
  1394. ds := newDaemonSet("foo")
  1395. ds.Spec.UpdateStrategy = *strategy
  1396. manager, podControl, _, err := newTestController(ds)
  1397. if err != nil {
  1398. t.Fatalf("error creating DaemonSets controller: %v", err)
  1399. }
  1400. manager.dsStore.Add(ds)
  1401. addNodes(manager.nodeStore, 0, 1, nil)
  1402. nodeName := "node-0"
  1403. pod := newPod(fmt.Sprintf("%s-", nodeName), nodeName, simpleDaemonSetLabel, ds)
  1404. // Add a failed Pod
  1405. pod.Status.Phase = v1.PodFailed
  1406. err = manager.podStore.Add(pod)
  1407. if err != nil {
  1408. t.Fatal(err)
  1409. }
  1410. backoffKey := failedPodsBackoffKey(ds, nodeName)
  1411. // First sync will delete the pod, initializing backoff
  1412. syncAndValidateDaemonSets(t, manager, ds, podControl, 0, 1, 1)
  1413. initialDelay := manager.failedPodsBackoff.Get(backoffKey)
  1414. if initialDelay <= 0 {
  1415. t.Fatal("Initial delay is expected to be set.")
  1416. }
  1417. resetCounters(manager)
  1418. // Immediate (second) sync gets limited by the backoff
  1419. syncAndValidateDaemonSets(t, manager, ds, podControl, 0, 0, 0)
  1420. delay := manager.failedPodsBackoff.Get(backoffKey)
  1421. if delay != initialDelay {
  1422. t.Fatal("Backoff delay shouldn't be raised while waiting.")
  1423. }
  1424. resetCounters(manager)
  1425. // Sleep to wait out backoff
  1426. fakeClock := manager.failedPodsBackoff.Clock
  1427. // Move just before the backoff end time
  1428. fakeClock.Sleep(delay - 1*time.Nanosecond)
  1429. if !manager.failedPodsBackoff.IsInBackOffSinceUpdate(backoffKey, fakeClock.Now()) {
  1430. t.Errorf("Backoff delay didn't last the whole waitout period.")
  1431. }
  1432. // Move to the backoff end time
  1433. fakeClock.Sleep(1 * time.Nanosecond)
  1434. if manager.failedPodsBackoff.IsInBackOffSinceUpdate(backoffKey, fakeClock.Now()) {
  1435. t.Fatal("Backoff delay hasn't been reset after the period has passed.")
  1436. }
  1437. // After backoff time, it will delete the failed pod
  1438. syncAndValidateDaemonSets(t, manager, ds, podControl, 0, 1, 1)
  1439. })
  1440. }
  1441. }
  1442. }
  1443. // Daemonset should not remove a running pod from a node if the pod doesn't
  1444. // tolerate the nodes NoSchedule taint
  1445. func TestNoScheduleTaintedDoesntEvicitRunningIntolerantPod(t *testing.T) {
  1446. for _, f := range []bool{true, false} {
  1447. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  1448. for _, strategy := range updateStrategies() {
  1449. ds := newDaemonSet("intolerant")
  1450. ds.Spec.UpdateStrategy = *strategy
  1451. manager, podControl, _, err := newTestController(ds)
  1452. if err != nil {
  1453. t.Fatalf("error creating DaemonSets controller: %v", err)
  1454. }
  1455. node := newNode("tainted", nil)
  1456. manager.nodeStore.Add(node)
  1457. setNodeTaint(node, noScheduleTaints)
  1458. manager.podStore.Add(newPod("keep-running-me", "tainted", simpleDaemonSetLabel, ds))
  1459. manager.dsStore.Add(ds)
  1460. syncAndValidateDaemonSets(t, manager, ds, podControl, 0, 0, 0)
  1461. }
  1462. }
  1463. }
  1464. // Daemonset should remove a running pod from a node if the pod doesn't
  1465. // tolerate the nodes NoExecute taint
  1466. func TestNoExecuteTaintedDoesEvicitRunningIntolerantPod(t *testing.T) {
  1467. for _, f := range []bool{true, false} {
  1468. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  1469. for _, strategy := range updateStrategies() {
  1470. ds := newDaemonSet("intolerant")
  1471. ds.Spec.UpdateStrategy = *strategy
  1472. manager, podControl, _, err := newTestController(ds)
  1473. if err != nil {
  1474. t.Fatalf("error creating DaemonSets controller: %v", err)
  1475. }
  1476. node := newNode("tainted", nil)
  1477. manager.nodeStore.Add(node)
  1478. setNodeTaint(node, noExecuteTaints)
  1479. manager.podStore.Add(newPod("stop-running-me", "tainted", simpleDaemonSetLabel, ds))
  1480. manager.dsStore.Add(ds)
  1481. syncAndValidateDaemonSets(t, manager, ds, podControl, 0, 1, 0)
  1482. }
  1483. }
  1484. }
  1485. // DaemonSet should not launch a pod on a tainted node when the pod doesn't tolerate that taint.
  1486. func TestTaintedNodeDaemonDoesNotLaunchIntolerantPod(t *testing.T) {
  1487. for _, f := range []bool{true, false} {
  1488. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  1489. for _, strategy := range updateStrategies() {
  1490. ds := newDaemonSet("intolerant")
  1491. ds.Spec.UpdateStrategy = *strategy
  1492. manager, podControl, _, err := newTestController(ds)
  1493. if err != nil {
  1494. t.Fatalf("error creating DaemonSets controller: %v", err)
  1495. }
  1496. node := newNode("tainted", nil)
  1497. setNodeTaint(node, noScheduleTaints)
  1498. manager.nodeStore.Add(node)
  1499. manager.dsStore.Add(ds)
  1500. syncAndValidateDaemonSets(t, manager, ds, podControl, 0, 0, 0)
  1501. }
  1502. }
  1503. }
  1504. // DaemonSet should launch a pod on a tainted node when the pod can tolerate that taint.
  1505. func TestTaintedNodeDaemonLaunchesToleratePod(t *testing.T) {
  1506. for _, f := range []bool{true, false} {
  1507. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  1508. for _, strategy := range updateStrategies() {
  1509. ds := newDaemonSet("tolerate")
  1510. ds.Spec.UpdateStrategy = *strategy
  1511. setDaemonSetToleration(ds, noScheduleTolerations)
  1512. manager, podControl, _, err := newTestController(ds)
  1513. if err != nil {
  1514. t.Fatalf("error creating DaemonSets controller: %v", err)
  1515. }
  1516. node := newNode("tainted", nil)
  1517. setNodeTaint(node, noScheduleTaints)
  1518. manager.nodeStore.Add(node)
  1519. manager.dsStore.Add(ds)
  1520. syncAndValidateDaemonSets(t, manager, ds, podControl, 1, 0, 0)
  1521. }
  1522. }
  1523. }
  1524. // DaemonSet should launch a pod on a not ready node with taint notReady:NoExecute.
  1525. func TestNotReadyNodeDaemonLaunchesPod(t *testing.T) {
  1526. for _, f := range []bool{true, false} {
  1527. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  1528. for _, strategy := range updateStrategies() {
  1529. ds := newDaemonSet("simple")
  1530. ds.Spec.UpdateStrategy = *strategy
  1531. manager, podControl, _, err := newTestController(ds)
  1532. if err != nil {
  1533. t.Fatalf("error creating DaemonSets controller: %v", err)
  1534. }
  1535. node := newNode("tainted", nil)
  1536. setNodeTaint(node, nodeNotReady)
  1537. node.Status.Conditions = []v1.NodeCondition{
  1538. {Type: v1.NodeReady, Status: v1.ConditionFalse},
  1539. }
  1540. manager.nodeStore.Add(node)
  1541. manager.dsStore.Add(ds)
  1542. syncAndValidateDaemonSets(t, manager, ds, podControl, 1, 0, 0)
  1543. }
  1544. }
  1545. }
  1546. // DaemonSet should launch a pod on an unreachable node with taint unreachable:NoExecute.
  1547. func TestUnreachableNodeDaemonLaunchesPod(t *testing.T) {
  1548. for _, f := range []bool{true, false} {
  1549. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  1550. for _, strategy := range updateStrategies() {
  1551. ds := newDaemonSet("simple")
  1552. ds.Spec.UpdateStrategy = *strategy
  1553. manager, podControl, _, err := newTestController(ds)
  1554. if err != nil {
  1555. t.Fatalf("error creating DaemonSets controller: %v", err)
  1556. }
  1557. node := newNode("tainted", nil)
  1558. setNodeTaint(node, nodeUnreachable)
  1559. node.Status.Conditions = []v1.NodeCondition{
  1560. {Type: v1.NodeReady, Status: v1.ConditionUnknown},
  1561. }
  1562. manager.nodeStore.Add(node)
  1563. manager.dsStore.Add(ds)
  1564. syncAndValidateDaemonSets(t, manager, ds, podControl, 1, 0, 0)
  1565. }
  1566. }
  1567. }
  1568. // DaemonSet should launch a pod on an untainted node when the pod has tolerations.
  1569. func TestNodeDaemonLaunchesToleratePod(t *testing.T) {
  1570. for _, f := range []bool{true, false} {
  1571. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  1572. for _, strategy := range updateStrategies() {
  1573. ds := newDaemonSet("tolerate")
  1574. ds.Spec.UpdateStrategy = *strategy
  1575. setDaemonSetToleration(ds, noScheduleTolerations)
  1576. manager, podControl, _, err := newTestController(ds)
  1577. if err != nil {
  1578. t.Fatalf("error creating DaemonSets controller: %v", err)
  1579. }
  1580. addNodes(manager.nodeStore, 0, 1, nil)
  1581. manager.dsStore.Add(ds)
  1582. syncAndValidateDaemonSets(t, manager, ds, podControl, 1, 0, 0)
  1583. }
  1584. }
  1585. }
  1586. // DaemonSet should launch a pod on a not ready node with taint notReady:NoExecute.
  1587. func TestDaemonSetRespectsTermination(t *testing.T) {
  1588. for _, f := range []bool{true, false} {
  1589. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  1590. for _, strategy := range updateStrategies() {
  1591. ds := newDaemonSet("foo")
  1592. ds.Spec.UpdateStrategy = *strategy
  1593. manager, podControl, _, err := newTestController(ds)
  1594. if err != nil {
  1595. t.Fatalf("error creating DaemonSets controller: %v", err)
  1596. }
  1597. addNodes(manager.nodeStore, 0, 1, simpleNodeLabel)
  1598. pod := newPod(fmt.Sprintf("%s-", "node-0"), "node-0", simpleDaemonSetLabel, ds)
  1599. dt := metav1.Now()
  1600. pod.DeletionTimestamp = &dt
  1601. manager.podStore.Add(pod)
  1602. manager.dsStore.Add(ds)
  1603. syncAndValidateDaemonSets(t, manager, ds, podControl, 0, 0, 0)
  1604. }
  1605. }
  1606. }
  1607. func setNodeTaint(node *v1.Node, taints []v1.Taint) {
  1608. node.Spec.Taints = taints
  1609. }
  1610. func setDaemonSetToleration(ds *apps.DaemonSet, tolerations []v1.Toleration) {
  1611. ds.Spec.Template.Spec.Tolerations = tolerations
  1612. }
  1613. // DaemonSet should launch a pod even when the node with MemoryPressure/DiskPressure/PIDPressure taints.
  1614. func TestTaintPressureNodeDaemonLaunchesPod(t *testing.T) {
  1615. for _, f := range []bool{true, false} {
  1616. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  1617. for _, strategy := range updateStrategies() {
  1618. ds := newDaemonSet("critical")
  1619. ds.Spec.UpdateStrategy = *strategy
  1620. setDaemonSetCritical(ds)
  1621. manager, podControl, _, err := newTestController(ds)
  1622. if err != nil {
  1623. t.Fatalf("error creating DaemonSets controller: %v", err)
  1624. }
  1625. node := newNode("resources-pressure", nil)
  1626. node.Status.Conditions = []v1.NodeCondition{
  1627. {Type: v1.NodeDiskPressure, Status: v1.ConditionTrue},
  1628. {Type: v1.NodeMemoryPressure, Status: v1.ConditionTrue},
  1629. {Type: v1.NodePIDPressure, Status: v1.ConditionTrue},
  1630. }
  1631. node.Spec.Taints = []v1.Taint{
  1632. {Key: schedulerapi.TaintNodeDiskPressure, Effect: v1.TaintEffectNoSchedule},
  1633. {Key: schedulerapi.TaintNodeMemoryPressure, Effect: v1.TaintEffectNoSchedule},
  1634. {Key: schedulerapi.TaintNodePIDPressure, Effect: v1.TaintEffectNoSchedule},
  1635. }
  1636. manager.nodeStore.Add(node)
  1637. // Enabling critical pod and taint nodes by condition feature gate should create critical pod
  1638. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.TaintNodesByCondition, true)()
  1639. manager.dsStore.Add(ds)
  1640. syncAndValidateDaemonSets(t, manager, ds, podControl, 1, 0, 0)
  1641. }
  1642. }
  1643. }
  1644. // When ScheduleDaemonSetPods is disabled, DaemonSet should launch a critical pod even when the node has insufficient free resource.
  1645. func TestInsufficientCapacityNodeDaemonLaunchesCriticalPod(t *testing.T) {
  1646. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, false)()
  1647. for _, strategy := range updateStrategies() {
  1648. podSpec := resourcePodSpec("too-much-mem", "75M", "75m")
  1649. ds := newDaemonSet("critical")
  1650. ds.Spec.UpdateStrategy = *strategy
  1651. ds.Spec.Template.Spec = podSpec
  1652. setDaemonSetCritical(ds)
  1653. manager, podControl, _, err := newTestController(ds)
  1654. if err != nil {
  1655. t.Fatalf("error creating DaemonSets controller: %v", err)
  1656. }
  1657. node := newNode("too-much-mem", nil)
  1658. node.Status.Allocatable = allocatableResources("100M", "200m")
  1659. manager.nodeStore.Add(node)
  1660. manager.podStore.Add(&v1.Pod{
  1661. Spec: podSpec,
  1662. })
  1663. // Without enabling critical pod annotation feature gate, we shouldn't create critical pod
  1664. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ExperimentalCriticalPodAnnotation, false)()
  1665. manager.dsStore.Add(ds)
  1666. switch strategy.Type {
  1667. case apps.OnDeleteDaemonSetStrategyType:
  1668. syncAndValidateDaemonSets(t, manager, ds, podControl, 0, 0, 2)
  1669. case apps.RollingUpdateDaemonSetStrategyType:
  1670. syncAndValidateDaemonSets(t, manager, ds, podControl, 0, 0, 3)
  1671. default:
  1672. t.Fatalf("unexpected UpdateStrategy %+v", strategy)
  1673. }
  1674. // Enabling critical pod annotation feature gate should create critical pod
  1675. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ExperimentalCriticalPodAnnotation, true)()
  1676. switch strategy.Type {
  1677. case apps.OnDeleteDaemonSetStrategyType:
  1678. syncAndValidateDaemonSets(t, manager, ds, podControl, 1, 0, 2)
  1679. case apps.RollingUpdateDaemonSetStrategyType:
  1680. syncAndValidateDaemonSets(t, manager, ds, podControl, 1, 0, 3)
  1681. default:
  1682. t.Fatalf("unexpected UpdateStrategy %+v", strategy)
  1683. }
  1684. }
  1685. }
  1686. // When ScheduleDaemonSetPods is disabled, DaemonSets should NOT launch a critical pod when there are port conflicts.
  1687. func TestPortConflictNodeDaemonDoesNotLaunchCriticalPod(t *testing.T) {
  1688. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, false)()
  1689. for _, strategy := range updateStrategies() {
  1690. podSpec := v1.PodSpec{
  1691. NodeName: "port-conflict",
  1692. Containers: []v1.Container{{
  1693. Ports: []v1.ContainerPort{{
  1694. HostPort: 666,
  1695. }},
  1696. }},
  1697. }
  1698. manager, podControl, _, err := newTestController()
  1699. if err != nil {
  1700. t.Fatalf("error creating DaemonSets controller: %v", err)
  1701. }
  1702. node := newNode("port-conflict", nil)
  1703. manager.nodeStore.Add(node)
  1704. manager.podStore.Add(&v1.Pod{
  1705. Spec: podSpec,
  1706. })
  1707. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ExperimentalCriticalPodAnnotation, true)()
  1708. ds := newDaemonSet("critical")
  1709. ds.Spec.UpdateStrategy = *strategy
  1710. ds.Spec.Template.Spec = podSpec
  1711. setDaemonSetCritical(ds)
  1712. manager.dsStore.Add(ds)
  1713. syncAndValidateDaemonSets(t, manager, ds, podControl, 0, 0, 0)
  1714. }
  1715. }
  1716. func setDaemonSetCritical(ds *apps.DaemonSet) {
  1717. ds.Namespace = api.NamespaceSystem
  1718. if ds.Spec.Template.ObjectMeta.Annotations == nil {
  1719. ds.Spec.Template.ObjectMeta.Annotations = make(map[string]string)
  1720. }
  1721. ds.Spec.Template.ObjectMeta.Annotations[kubelettypes.CriticalPodAnnotationKey] = ""
  1722. }
  1723. func TestNodeShouldRunDaemonPod(t *testing.T) {
  1724. for _, f := range []bool{true, false} {
  1725. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  1726. var shouldCreate, wantToRun, shouldContinueRunning bool
  1727. if utilfeature.DefaultFeatureGate.Enabled(features.ScheduleDaemonSetPods) {
  1728. shouldCreate = true
  1729. wantToRun = true
  1730. shouldContinueRunning = true
  1731. }
  1732. cases := []struct {
  1733. predicateName string
  1734. podsOnNode []*v1.Pod
  1735. nodeCondition []v1.NodeCondition
  1736. nodeUnschedulable bool
  1737. ds *apps.DaemonSet
  1738. wantToRun, shouldCreate, shouldContinueRunning bool
  1739. err error
  1740. }{
  1741. {
  1742. predicateName: "ShouldRunDaemonPod",
  1743. ds: &apps.DaemonSet{
  1744. Spec: apps.DaemonSetSpec{
  1745. Selector: &metav1.LabelSelector{MatchLabels: simpleDaemonSetLabel},
  1746. Template: v1.PodTemplateSpec{
  1747. ObjectMeta: metav1.ObjectMeta{
  1748. Labels: simpleDaemonSetLabel,
  1749. },
  1750. Spec: resourcePodSpec("", "50M", "0.5"),
  1751. },
  1752. },
  1753. },
  1754. wantToRun: true,
  1755. shouldCreate: true,
  1756. shouldContinueRunning: true,
  1757. },
  1758. {
  1759. predicateName: "InsufficientResourceError",
  1760. ds: &apps.DaemonSet{
  1761. Spec: apps.DaemonSetSpec{
  1762. Selector: &metav1.LabelSelector{MatchLabels: simpleDaemonSetLabel},
  1763. Template: v1.PodTemplateSpec{
  1764. ObjectMeta: metav1.ObjectMeta{
  1765. Labels: simpleDaemonSetLabel,
  1766. },
  1767. Spec: resourcePodSpec("", "200M", "0.5"),
  1768. },
  1769. },
  1770. },
  1771. wantToRun: true,
  1772. shouldCreate: shouldCreate,
  1773. shouldContinueRunning: true,
  1774. },
  1775. {
  1776. predicateName: "ErrPodNotMatchHostName",
  1777. ds: &apps.DaemonSet{
  1778. Spec: apps.DaemonSetSpec{
  1779. Selector: &metav1.LabelSelector{MatchLabels: simpleDaemonSetLabel},
  1780. Template: v1.PodTemplateSpec{
  1781. ObjectMeta: metav1.ObjectMeta{
  1782. Labels: simpleDaemonSetLabel,
  1783. },
  1784. Spec: resourcePodSpec("other-node", "50M", "0.5"),
  1785. },
  1786. },
  1787. },
  1788. wantToRun: false,
  1789. shouldCreate: false,
  1790. shouldContinueRunning: false,
  1791. },
  1792. {
  1793. predicateName: "ErrPodNotFitsHostPorts",
  1794. podsOnNode: []*v1.Pod{
  1795. {
  1796. Spec: v1.PodSpec{
  1797. Containers: []v1.Container{{
  1798. Ports: []v1.ContainerPort{{
  1799. HostPort: 666,
  1800. }},
  1801. }},
  1802. },
  1803. },
  1804. },
  1805. ds: &apps.DaemonSet{
  1806. Spec: apps.DaemonSetSpec{
  1807. Selector: &metav1.LabelSelector{MatchLabels: simpleDaemonSetLabel},
  1808. Template: v1.PodTemplateSpec{
  1809. ObjectMeta: metav1.ObjectMeta{
  1810. Labels: simpleDaemonSetLabel,
  1811. },
  1812. Spec: v1.PodSpec{
  1813. Containers: []v1.Container{{
  1814. Ports: []v1.ContainerPort{{
  1815. HostPort: 666,
  1816. }},
  1817. }},
  1818. },
  1819. },
  1820. },
  1821. },
  1822. wantToRun: wantToRun,
  1823. shouldCreate: shouldCreate,
  1824. shouldContinueRunning: shouldContinueRunning,
  1825. },
  1826. {
  1827. predicateName: "InsufficientResourceError",
  1828. podsOnNode: []*v1.Pod{
  1829. {
  1830. Spec: v1.PodSpec{
  1831. Containers: []v1.Container{{
  1832. Ports: []v1.ContainerPort{{
  1833. HostPort: 666,
  1834. }},
  1835. Resources: resourceContainerSpec("50M", "0.5"),
  1836. }},
  1837. },
  1838. },
  1839. },
  1840. ds: &apps.DaemonSet{
  1841. Spec: apps.DaemonSetSpec{
  1842. Selector: &metav1.LabelSelector{MatchLabels: simpleDaemonSetLabel},
  1843. Template: v1.PodTemplateSpec{
  1844. ObjectMeta: metav1.ObjectMeta{
  1845. Labels: simpleDaemonSetLabel,
  1846. },
  1847. Spec: resourcePodSpec("", "100M", "0.5"),
  1848. },
  1849. },
  1850. },
  1851. wantToRun: true,
  1852. shouldCreate: shouldCreate, // This is because we don't care about the resource constraints any more and let default scheduler handle it.
  1853. shouldContinueRunning: true,
  1854. },
  1855. {
  1856. predicateName: "ShouldRunDaemonPod",
  1857. podsOnNode: []*v1.Pod{
  1858. {
  1859. Spec: v1.PodSpec{
  1860. Containers: []v1.Container{{
  1861. Ports: []v1.ContainerPort{{
  1862. HostPort: 666,
  1863. }},
  1864. Resources: resourceContainerSpec("50M", "0.5"),
  1865. }},
  1866. },
  1867. },
  1868. },
  1869. ds: &apps.DaemonSet{
  1870. Spec: apps.DaemonSetSpec{
  1871. Selector: &metav1.LabelSelector{MatchLabels: simpleDaemonSetLabel},
  1872. Template: v1.PodTemplateSpec{
  1873. ObjectMeta: metav1.ObjectMeta{
  1874. Labels: simpleDaemonSetLabel,
  1875. },
  1876. Spec: resourcePodSpec("", "50M", "0.5"),
  1877. },
  1878. },
  1879. },
  1880. wantToRun: true,
  1881. shouldCreate: true,
  1882. shouldContinueRunning: true,
  1883. },
  1884. {
  1885. predicateName: "ErrNodeSelectorNotMatch",
  1886. ds: &apps.DaemonSet{
  1887. Spec: apps.DaemonSetSpec{
  1888. Selector: &metav1.LabelSelector{MatchLabels: simpleDaemonSetLabel},
  1889. Template: v1.PodTemplateSpec{
  1890. ObjectMeta: metav1.ObjectMeta{
  1891. Labels: simpleDaemonSetLabel,
  1892. },
  1893. Spec: v1.PodSpec{
  1894. NodeSelector: simpleDaemonSetLabel2,
  1895. },
  1896. },
  1897. },
  1898. },
  1899. wantToRun: false,
  1900. shouldCreate: false,
  1901. shouldContinueRunning: false,
  1902. },
  1903. {
  1904. predicateName: "ShouldRunDaemonPod",
  1905. ds: &apps.DaemonSet{
  1906. Spec: apps.DaemonSetSpec{
  1907. Selector: &metav1.LabelSelector{MatchLabels: simpleDaemonSetLabel},
  1908. Template: v1.PodTemplateSpec{
  1909. ObjectMeta: metav1.ObjectMeta{
  1910. Labels: simpleDaemonSetLabel,
  1911. },
  1912. Spec: v1.PodSpec{
  1913. NodeSelector: simpleDaemonSetLabel,
  1914. },
  1915. },
  1916. },
  1917. },
  1918. wantToRun: true,
  1919. shouldCreate: true,
  1920. shouldContinueRunning: true,
  1921. },
  1922. {
  1923. predicateName: "ErrPodAffinityNotMatch",
  1924. ds: &apps.DaemonSet{
  1925. Spec: apps.DaemonSetSpec{
  1926. Selector: &metav1.LabelSelector{MatchLabels: simpleDaemonSetLabel},
  1927. Template: v1.PodTemplateSpec{
  1928. ObjectMeta: metav1.ObjectMeta{
  1929. Labels: simpleDaemonSetLabel,
  1930. },
  1931. Spec: v1.PodSpec{
  1932. Affinity: &v1.Affinity{
  1933. NodeAffinity: &v1.NodeAffinity{
  1934. RequiredDuringSchedulingIgnoredDuringExecution: &v1.NodeSelector{
  1935. NodeSelectorTerms: []v1.NodeSelectorTerm{
  1936. {
  1937. MatchExpressions: []v1.NodeSelectorRequirement{
  1938. {
  1939. Key: "type",
  1940. Operator: v1.NodeSelectorOpIn,
  1941. Values: []string{"test"},
  1942. },
  1943. },
  1944. },
  1945. },
  1946. },
  1947. },
  1948. },
  1949. },
  1950. },
  1951. },
  1952. },
  1953. wantToRun: false,
  1954. shouldCreate: false,
  1955. shouldContinueRunning: false,
  1956. },
  1957. {
  1958. predicateName: "ShouldRunDaemonPod",
  1959. ds: &apps.DaemonSet{
  1960. Spec: apps.DaemonSetSpec{
  1961. Selector: &metav1.LabelSelector{MatchLabels: simpleDaemonSetLabel},
  1962. Template: v1.PodTemplateSpec{
  1963. ObjectMeta: metav1.ObjectMeta{
  1964. Labels: simpleDaemonSetLabel,
  1965. },
  1966. Spec: v1.PodSpec{
  1967. Affinity: &v1.Affinity{
  1968. NodeAffinity: &v1.NodeAffinity{
  1969. RequiredDuringSchedulingIgnoredDuringExecution: &v1.NodeSelector{
  1970. NodeSelectorTerms: []v1.NodeSelectorTerm{
  1971. {
  1972. MatchExpressions: []v1.NodeSelectorRequirement{
  1973. {
  1974. Key: "type",
  1975. Operator: v1.NodeSelectorOpIn,
  1976. Values: []string{"production"},
  1977. },
  1978. },
  1979. },
  1980. },
  1981. },
  1982. },
  1983. },
  1984. },
  1985. },
  1986. },
  1987. },
  1988. wantToRun: true,
  1989. shouldCreate: true,
  1990. shouldContinueRunning: true,
  1991. },
  1992. {
  1993. predicateName: "ShouldRunDaemonPodOnUnscheduableNode",
  1994. ds: &apps.DaemonSet{
  1995. Spec: apps.DaemonSetSpec{
  1996. Selector: &metav1.LabelSelector{MatchLabels: simpleDaemonSetLabel},
  1997. Template: v1.PodTemplateSpec{
  1998. ObjectMeta: metav1.ObjectMeta{
  1999. Labels: simpleDaemonSetLabel,
  2000. },
  2001. Spec: resourcePodSpec("", "50M", "0.5"),
  2002. },
  2003. },
  2004. },
  2005. nodeUnschedulable: true,
  2006. wantToRun: true,
  2007. shouldCreate: true,
  2008. shouldContinueRunning: true,
  2009. },
  2010. }
  2011. for i, c := range cases {
  2012. for _, strategy := range updateStrategies() {
  2013. node := newNode("test-node", simpleDaemonSetLabel)
  2014. node.Status.Conditions = append(node.Status.Conditions, c.nodeCondition...)
  2015. node.Status.Allocatable = allocatableResources("100M", "1")
  2016. node.Spec.Unschedulable = c.nodeUnschedulable
  2017. manager, _, _, err := newTestController()
  2018. if err != nil {
  2019. t.Fatalf("error creating DaemonSets controller: %v", err)
  2020. }
  2021. manager.nodeStore.Add(node)
  2022. for _, p := range c.podsOnNode {
  2023. manager.podStore.Add(p)
  2024. p.Spec.NodeName = "test-node"
  2025. manager.podNodeIndex.Add(p)
  2026. }
  2027. c.ds.Spec.UpdateStrategy = *strategy
  2028. wantToRun, shouldRun, shouldContinueRunning, err := manager.nodeShouldRunDaemonPod(node, c.ds)
  2029. if wantToRun != c.wantToRun {
  2030. t.Errorf("[%v] strategy: %v, predicateName: %v expected wantToRun: %v, got: %v", i, c.ds.Spec.UpdateStrategy.Type, c.predicateName, c.wantToRun, wantToRun)
  2031. }
  2032. if shouldRun != c.shouldCreate {
  2033. t.Errorf("[%v] strategy: %v, predicateName: %v expected shouldRun: %v, got: %v", i, c.ds.Spec.UpdateStrategy.Type, c.predicateName, c.shouldCreate, shouldRun)
  2034. }
  2035. if shouldContinueRunning != c.shouldContinueRunning {
  2036. t.Errorf("[%v] strategy: %v, predicateName: %v expected shouldContinueRunning: %v, got: %v", i, c.ds.Spec.UpdateStrategy.Type, c.predicateName, c.shouldContinueRunning, shouldContinueRunning)
  2037. }
  2038. if err != c.err {
  2039. t.Errorf("[%v] strategy: %v, predicateName: %v expected err: %v, got: %v", i, c.predicateName, c.ds.Spec.UpdateStrategy.Type, c.err, err)
  2040. }
  2041. }
  2042. }
  2043. }
  2044. }
  2045. // DaemonSets should be resynced when node labels or taints changed
  2046. func TestUpdateNode(t *testing.T) {
  2047. var enqueued bool
  2048. for _, f := range []bool{true, false} {
  2049. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  2050. cases := []struct {
  2051. test string
  2052. newNode *v1.Node
  2053. oldNode *v1.Node
  2054. ds *apps.DaemonSet
  2055. expectedEventsFunc func(strategyType apps.DaemonSetUpdateStrategyType) int
  2056. shouldEnqueue bool
  2057. expectedCreates func() int
  2058. }{
  2059. {
  2060. test: "Nothing changed, should not enqueue",
  2061. oldNode: newNode("node1", nil),
  2062. newNode: newNode("node1", nil),
  2063. ds: func() *apps.DaemonSet {
  2064. ds := newDaemonSet("ds")
  2065. ds.Spec.Template.Spec.NodeSelector = simpleNodeLabel
  2066. return ds
  2067. }(),
  2068. shouldEnqueue: false,
  2069. expectedCreates: func() int { return 0 },
  2070. },
  2071. {
  2072. test: "Node labels changed",
  2073. oldNode: newNode("node1", nil),
  2074. newNode: newNode("node1", simpleNodeLabel),
  2075. ds: func() *apps.DaemonSet {
  2076. ds := newDaemonSet("ds")
  2077. ds.Spec.Template.Spec.NodeSelector = simpleNodeLabel
  2078. return ds
  2079. }(),
  2080. shouldEnqueue: true,
  2081. expectedCreates: func() int { return 0 },
  2082. },
  2083. {
  2084. test: "Node taints changed",
  2085. oldNode: func() *v1.Node {
  2086. node := newNode("node1", nil)
  2087. setNodeTaint(node, noScheduleTaints)
  2088. return node
  2089. }(),
  2090. newNode: newNode("node1", nil),
  2091. ds: newDaemonSet("ds"),
  2092. shouldEnqueue: true,
  2093. expectedCreates: func() int { return 0 },
  2094. },
  2095. {
  2096. test: "Node Allocatable changed",
  2097. oldNode: newNode("node1", nil),
  2098. newNode: func() *v1.Node {
  2099. node := newNode("node1", nil)
  2100. node.Status.Allocatable = allocatableResources("200M", "200m")
  2101. return node
  2102. }(),
  2103. ds: func() *apps.DaemonSet {
  2104. ds := newDaemonSet("ds")
  2105. ds.Spec.Template.Spec = resourcePodSpecWithoutNodeName("200M", "200m")
  2106. return ds
  2107. }(),
  2108. expectedEventsFunc: func(strategyType apps.DaemonSetUpdateStrategyType) int {
  2109. switch strategyType {
  2110. case apps.OnDeleteDaemonSetStrategyType:
  2111. if !utilfeature.DefaultFeatureGate.Enabled(features.ScheduleDaemonSetPods) {
  2112. return 2
  2113. }
  2114. return 0
  2115. case apps.RollingUpdateDaemonSetStrategyType:
  2116. if !utilfeature.DefaultFeatureGate.Enabled(features.ScheduleDaemonSetPods) {
  2117. return 3
  2118. }
  2119. return 0
  2120. default:
  2121. t.Fatalf("unexpected UpdateStrategy %+v", strategyType)
  2122. }
  2123. return 0
  2124. },
  2125. shouldEnqueue: !utilfeature.DefaultFeatureGate.Enabled(features.ScheduleDaemonSetPods),
  2126. expectedCreates: func() int {
  2127. if !utilfeature.DefaultFeatureGate.Enabled(features.ScheduleDaemonSetPods) {
  2128. return 0
  2129. } else {
  2130. return 1
  2131. }
  2132. },
  2133. },
  2134. }
  2135. for _, c := range cases {
  2136. for _, strategy := range updateStrategies() {
  2137. manager, podControl, _, err := newTestController()
  2138. if err != nil {
  2139. t.Fatalf("error creating DaemonSets controller: %v", err)
  2140. }
  2141. manager.nodeStore.Add(c.oldNode)
  2142. c.ds.Spec.UpdateStrategy = *strategy
  2143. manager.dsStore.Add(c.ds)
  2144. expectedEvents := 0
  2145. if c.expectedEventsFunc != nil {
  2146. expectedEvents = c.expectedEventsFunc(strategy.Type)
  2147. }
  2148. expectedCreates := 0
  2149. if c.expectedCreates != nil {
  2150. expectedCreates = c.expectedCreates()
  2151. }
  2152. syncAndValidateDaemonSets(t, manager, c.ds, podControl, expectedCreates, 0, expectedEvents)
  2153. manager.enqueueDaemonSet = func(ds *apps.DaemonSet) {
  2154. if ds.Name == "ds" {
  2155. enqueued = true
  2156. }
  2157. }
  2158. enqueued = false
  2159. manager.updateNode(c.oldNode, c.newNode)
  2160. if enqueued != c.shouldEnqueue {
  2161. t.Errorf("Test case: '%s', expected: %t, got: %t", c.test, c.shouldEnqueue, enqueued)
  2162. }
  2163. }
  2164. }
  2165. }
  2166. }
  2167. // DaemonSets should be resynced when non-daemon pods was deleted.
  2168. func TestDeleteNoDaemonPod(t *testing.T) {
  2169. var enqueued bool
  2170. cases := []struct {
  2171. test string
  2172. node *v1.Node
  2173. existPods []*v1.Pod
  2174. deletedPod *v1.Pod
  2175. ds *apps.DaemonSet
  2176. shouldEnqueue bool
  2177. }{
  2178. {
  2179. test: "Deleted non-daemon pods to release resources",
  2180. node: func() *v1.Node {
  2181. node := newNode("node1", nil)
  2182. node.Status.Conditions = []v1.NodeCondition{
  2183. {Type: v1.NodeReady, Status: v1.ConditionTrue},
  2184. }
  2185. node.Status.Allocatable = allocatableResources("200M", "200m")
  2186. return node
  2187. }(),
  2188. existPods: func() []*v1.Pod {
  2189. pods := []*v1.Pod{}
  2190. for i := 0; i < 4; i++ {
  2191. podSpec := resourcePodSpec("node1", "50M", "50m")
  2192. pods = append(pods, &v1.Pod{
  2193. ObjectMeta: metav1.ObjectMeta{
  2194. Name: fmt.Sprintf("pod_%d", i),
  2195. },
  2196. Spec: podSpec,
  2197. })
  2198. }
  2199. return pods
  2200. }(),
  2201. deletedPod: func() *v1.Pod {
  2202. podSpec := resourcePodSpec("node1", "50M", "50m")
  2203. return &v1.Pod{
  2204. ObjectMeta: metav1.ObjectMeta{
  2205. Name: "pod_0",
  2206. },
  2207. Spec: podSpec,
  2208. }
  2209. }(),
  2210. ds: func() *apps.DaemonSet {
  2211. ds := newDaemonSet("ds")
  2212. ds.Spec.Template.Spec = resourcePodSpec("", "50M", "50m")
  2213. return ds
  2214. }(),
  2215. shouldEnqueue: !utilfeature.DefaultFeatureGate.Enabled(features.ScheduleDaemonSetPods),
  2216. },
  2217. {
  2218. test: "Deleted non-daemon pods (with controller) to release resources",
  2219. node: func() *v1.Node {
  2220. node := newNode("node1", nil)
  2221. node.Status.Conditions = []v1.NodeCondition{
  2222. {Type: v1.NodeReady, Status: v1.ConditionTrue},
  2223. }
  2224. node.Status.Allocatable = allocatableResources("200M", "200m")
  2225. return node
  2226. }(),
  2227. existPods: func() []*v1.Pod {
  2228. pods := []*v1.Pod{}
  2229. for i := 0; i < 4; i++ {
  2230. podSpec := resourcePodSpec("node1", "50M", "50m")
  2231. pods = append(pods, &v1.Pod{
  2232. ObjectMeta: metav1.ObjectMeta{
  2233. Name: fmt.Sprintf("pod_%d", i),
  2234. OwnerReferences: []metav1.OwnerReference{
  2235. {Controller: func() *bool { res := true; return &res }()},
  2236. },
  2237. },
  2238. Spec: podSpec,
  2239. })
  2240. }
  2241. return pods
  2242. }(),
  2243. deletedPod: func() *v1.Pod {
  2244. podSpec := resourcePodSpec("node1", "50M", "50m")
  2245. return &v1.Pod{
  2246. ObjectMeta: metav1.ObjectMeta{
  2247. Name: "pod_0",
  2248. OwnerReferences: []metav1.OwnerReference{
  2249. {Controller: func() *bool { res := true; return &res }()},
  2250. },
  2251. },
  2252. Spec: podSpec,
  2253. }
  2254. }(),
  2255. ds: func() *apps.DaemonSet {
  2256. ds := newDaemonSet("ds")
  2257. ds.Spec.Template.Spec = resourcePodSpec("", "50M", "50m")
  2258. return ds
  2259. }(),
  2260. shouldEnqueue: !utilfeature.DefaultFeatureGate.Enabled(features.ScheduleDaemonSetPods),
  2261. },
  2262. {
  2263. test: "Deleted no scheduled pods",
  2264. node: func() *v1.Node {
  2265. node := newNode("node1", nil)
  2266. node.Status.Conditions = []v1.NodeCondition{
  2267. {Type: v1.NodeReady, Status: v1.ConditionTrue},
  2268. }
  2269. node.Status.Allocatable = allocatableResources("200M", "200m")
  2270. return node
  2271. }(),
  2272. existPods: func() []*v1.Pod {
  2273. pods := []*v1.Pod{}
  2274. for i := 0; i < 4; i++ {
  2275. podSpec := resourcePodSpec("node1", "50M", "50m")
  2276. pods = append(pods, &v1.Pod{
  2277. ObjectMeta: metav1.ObjectMeta{
  2278. Name: fmt.Sprintf("pod_%d", i),
  2279. OwnerReferences: []metav1.OwnerReference{
  2280. {Controller: func() *bool { res := true; return &res }()},
  2281. },
  2282. },
  2283. Spec: podSpec,
  2284. })
  2285. }
  2286. return pods
  2287. }(),
  2288. deletedPod: func() *v1.Pod {
  2289. podSpec := resourcePodSpec("", "50M", "50m")
  2290. return &v1.Pod{
  2291. ObjectMeta: metav1.ObjectMeta{
  2292. Name: "pod_5",
  2293. },
  2294. Spec: podSpec,
  2295. }
  2296. }(),
  2297. ds: func() *apps.DaemonSet {
  2298. ds := newDaemonSet("ds")
  2299. ds.Spec.Template.Spec = resourcePodSpec("", "50M", "50m")
  2300. return ds
  2301. }(),
  2302. shouldEnqueue: false,
  2303. },
  2304. }
  2305. for _, c := range cases {
  2306. for _, strategy := range updateStrategies() {
  2307. manager, podControl, _, err := newTestController()
  2308. if err != nil {
  2309. t.Fatalf("error creating DaemonSets controller: %v", err)
  2310. }
  2311. manager.nodeStore.Add(c.node)
  2312. c.ds.Spec.UpdateStrategy = *strategy
  2313. manager.dsStore.Add(c.ds)
  2314. for _, pod := range c.existPods {
  2315. manager.podStore.Add(pod)
  2316. }
  2317. switch strategy.Type {
  2318. case apps.OnDeleteDaemonSetStrategyType:
  2319. if utilfeature.DefaultFeatureGate.Enabled(features.ScheduleDaemonSetPods) {
  2320. syncAndValidateDaemonSets(t, manager, c.ds, podControl, 1, 0, 0)
  2321. } else {
  2322. syncAndValidateDaemonSets(t, manager, c.ds, podControl, 0, 0, 2)
  2323. }
  2324. case apps.RollingUpdateDaemonSetStrategyType:
  2325. if utilfeature.DefaultFeatureGate.Enabled(features.ScheduleDaemonSetPods) {
  2326. syncAndValidateDaemonSets(t, manager, c.ds, podControl, 1, 0, 0)
  2327. } else {
  2328. syncAndValidateDaemonSets(t, manager, c.ds, podControl, 0, 0, 3)
  2329. }
  2330. default:
  2331. t.Fatalf("unexpected UpdateStrategy %+v", strategy)
  2332. }
  2333. manager.enqueueDaemonSetRateLimited = func(ds *apps.DaemonSet) {
  2334. if ds.Name == "ds" {
  2335. enqueued = true
  2336. }
  2337. }
  2338. enqueued = false
  2339. manager.deletePod(c.deletedPod)
  2340. if enqueued != c.shouldEnqueue {
  2341. t.Errorf("Test case: '%s', expected: %t, got: %t", c.test, c.shouldEnqueue, enqueued)
  2342. }
  2343. }
  2344. }
  2345. }
  2346. func TestDeleteUnscheduledPodForNotExistingNode(t *testing.T) {
  2347. for _, f := range []bool{true, false} {
  2348. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  2349. for _, strategy := range updateStrategies() {
  2350. ds := newDaemonSet("foo")
  2351. ds.Spec.UpdateStrategy = *strategy
  2352. manager, podControl, _, err := newTestController(ds)
  2353. if err != nil {
  2354. t.Fatalf("error creating DaemonSets controller: %v", err)
  2355. }
  2356. manager.dsStore.Add(ds)
  2357. addNodes(manager.nodeStore, 0, 1, nil)
  2358. addPods(manager.podStore, "node-0", simpleDaemonSetLabel, ds, 1)
  2359. addPods(manager.podStore, "node-1", simpleDaemonSetLabel, ds, 1)
  2360. podScheduledUsingAffinity := newPod("pod1-node-3", "", simpleDaemonSetLabel, ds)
  2361. podScheduledUsingAffinity.Spec.Affinity = &v1.Affinity{
  2362. NodeAffinity: &v1.NodeAffinity{
  2363. RequiredDuringSchedulingIgnoredDuringExecution: &v1.NodeSelector{
  2364. NodeSelectorTerms: []v1.NodeSelectorTerm{
  2365. {
  2366. MatchFields: []v1.NodeSelectorRequirement{
  2367. {
  2368. Key: schedulerapi.NodeFieldSelectorKeyNodeName,
  2369. Operator: v1.NodeSelectorOpIn,
  2370. Values: []string{"node-2"},
  2371. },
  2372. },
  2373. },
  2374. },
  2375. },
  2376. },
  2377. }
  2378. manager.podStore.Add(podScheduledUsingAffinity)
  2379. if f {
  2380. syncAndValidateDaemonSets(t, manager, ds, podControl, 0, 1, 0)
  2381. } else {
  2382. syncAndValidateDaemonSets(t, manager, ds, podControl, 0, 0, 0)
  2383. }
  2384. }
  2385. }
  2386. }
  2387. func TestGetNodesToDaemonPods(t *testing.T) {
  2388. for _, f := range []bool{true, false} {
  2389. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  2390. for _, strategy := range updateStrategies() {
  2391. ds := newDaemonSet("foo")
  2392. ds.Spec.UpdateStrategy = *strategy
  2393. ds2 := newDaemonSet("foo2")
  2394. ds2.Spec.UpdateStrategy = *strategy
  2395. manager, _, _, err := newTestController(ds, ds2)
  2396. if err != nil {
  2397. t.Fatalf("error creating DaemonSets controller: %v", err)
  2398. }
  2399. manager.dsStore.Add(ds)
  2400. manager.dsStore.Add(ds2)
  2401. addNodes(manager.nodeStore, 0, 2, nil)
  2402. // These pods should be returned.
  2403. wantedPods := []*v1.Pod{
  2404. newPod("matching-owned-0-", "node-0", simpleDaemonSetLabel, ds),
  2405. newPod("matching-orphan-0-", "node-0", simpleDaemonSetLabel, nil),
  2406. newPod("matching-owned-1-", "node-1", simpleDaemonSetLabel, ds),
  2407. newPod("matching-orphan-1-", "node-1", simpleDaemonSetLabel, nil),
  2408. }
  2409. failedPod := newPod("matching-owned-failed-pod-1-", "node-1", simpleDaemonSetLabel, ds)
  2410. failedPod.Status = v1.PodStatus{Phase: v1.PodFailed}
  2411. wantedPods = append(wantedPods, failedPod)
  2412. for _, pod := range wantedPods {
  2413. manager.podStore.Add(pod)
  2414. }
  2415. // These pods should be ignored.
  2416. ignoredPods := []*v1.Pod{
  2417. newPod("non-matching-owned-0-", "node-0", simpleDaemonSetLabel2, ds),
  2418. newPod("non-matching-orphan-1-", "node-1", simpleDaemonSetLabel2, nil),
  2419. newPod("matching-owned-by-other-0-", "node-0", simpleDaemonSetLabel, ds2),
  2420. }
  2421. for _, pod := range ignoredPods {
  2422. manager.podStore.Add(pod)
  2423. }
  2424. nodesToDaemonPods, err := manager.getNodesToDaemonPods(ds)
  2425. if err != nil {
  2426. t.Fatalf("getNodesToDaemonPods() error: %v", err)
  2427. }
  2428. gotPods := map[string]bool{}
  2429. for node, pods := range nodesToDaemonPods {
  2430. for _, pod := range pods {
  2431. if pod.Spec.NodeName != node {
  2432. t.Errorf("pod %v grouped into %v but belongs in %v", pod.Name, node, pod.Spec.NodeName)
  2433. }
  2434. gotPods[pod.Name] = true
  2435. }
  2436. }
  2437. for _, pod := range wantedPods {
  2438. if !gotPods[pod.Name] {
  2439. t.Errorf("expected pod %v but didn't get it", pod.Name)
  2440. }
  2441. delete(gotPods, pod.Name)
  2442. }
  2443. for podName := range gotPods {
  2444. t.Errorf("unexpected pod %v was returned", podName)
  2445. }
  2446. }
  2447. }
  2448. }
  2449. func TestAddNode(t *testing.T) {
  2450. for _, f := range []bool{true, false} {
  2451. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  2452. manager, _, _, err := newTestController()
  2453. if err != nil {
  2454. t.Fatalf("error creating DaemonSets controller: %v", err)
  2455. }
  2456. node1 := newNode("node1", nil)
  2457. ds := newDaemonSet("ds")
  2458. ds.Spec.Template.Spec.NodeSelector = simpleNodeLabel
  2459. manager.dsStore.Add(ds)
  2460. manager.addNode(node1)
  2461. if got, want := manager.queue.Len(), 0; got != want {
  2462. t.Fatalf("queue.Len() = %v, want %v", got, want)
  2463. }
  2464. node2 := newNode("node2", simpleNodeLabel)
  2465. manager.addNode(node2)
  2466. if got, want := manager.queue.Len(), 1; got != want {
  2467. t.Fatalf("queue.Len() = %v, want %v", got, want)
  2468. }
  2469. key, done := manager.queue.Get()
  2470. if key == nil || done {
  2471. t.Fatalf("failed to enqueue controller for node %v", node2.Name)
  2472. }
  2473. }
  2474. }
  2475. func TestAddPod(t *testing.T) {
  2476. for _, f := range []bool{true, false} {
  2477. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  2478. for _, strategy := range updateStrategies() {
  2479. manager, _, _, err := newTestController()
  2480. if err != nil {
  2481. t.Fatalf("error creating DaemonSets controller: %v", err)
  2482. }
  2483. ds1 := newDaemonSet("foo1")
  2484. ds1.Spec.UpdateStrategy = *strategy
  2485. ds2 := newDaemonSet("foo2")
  2486. ds2.Spec.UpdateStrategy = *strategy
  2487. manager.dsStore.Add(ds1)
  2488. manager.dsStore.Add(ds2)
  2489. pod1 := newPod("pod1-", "node-0", simpleDaemonSetLabel, ds1)
  2490. manager.addPod(pod1)
  2491. if got, want := manager.queue.Len(), 1; got != want {
  2492. t.Fatalf("queue.Len() = %v, want %v", got, want)
  2493. }
  2494. key, done := manager.queue.Get()
  2495. if key == nil || done {
  2496. t.Fatalf("failed to enqueue controller for pod %v", pod1.Name)
  2497. }
  2498. expectedKey, _ := controller.KeyFunc(ds1)
  2499. if got, want := key.(string), expectedKey; got != want {
  2500. t.Errorf("queue.Get() = %v, want %v", got, want)
  2501. }
  2502. pod2 := newPod("pod2-", "node-0", simpleDaemonSetLabel, ds2)
  2503. manager.addPod(pod2)
  2504. if got, want := manager.queue.Len(), 1; got != want {
  2505. t.Fatalf("queue.Len() = %v, want %v", got, want)
  2506. }
  2507. key, done = manager.queue.Get()
  2508. if key == nil || done {
  2509. t.Fatalf("failed to enqueue controller for pod %v", pod2.Name)
  2510. }
  2511. expectedKey, _ = controller.KeyFunc(ds2)
  2512. if got, want := key.(string), expectedKey; got != want {
  2513. t.Errorf("queue.Get() = %v, want %v", got, want)
  2514. }
  2515. }
  2516. }
  2517. }
  2518. func TestAddPodOrphan(t *testing.T) {
  2519. for _, f := range []bool{true, false} {
  2520. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  2521. for _, strategy := range updateStrategies() {
  2522. manager, _, _, err := newTestController()
  2523. if err != nil {
  2524. t.Fatalf("error creating DaemonSets controller: %v", err)
  2525. }
  2526. ds1 := newDaemonSet("foo1")
  2527. ds1.Spec.UpdateStrategy = *strategy
  2528. ds2 := newDaemonSet("foo2")
  2529. ds2.Spec.UpdateStrategy = *strategy
  2530. ds3 := newDaemonSet("foo3")
  2531. ds3.Spec.UpdateStrategy = *strategy
  2532. ds3.Spec.Selector.MatchLabels = simpleDaemonSetLabel2
  2533. manager.dsStore.Add(ds1)
  2534. manager.dsStore.Add(ds2)
  2535. manager.dsStore.Add(ds3)
  2536. // Make pod an orphan. Expect matching sets to be queued.
  2537. pod := newPod("pod1-", "node-0", simpleDaemonSetLabel, nil)
  2538. manager.addPod(pod)
  2539. if got, want := manager.queue.Len(), 2; got != want {
  2540. t.Fatalf("queue.Len() = %v, want %v", got, want)
  2541. }
  2542. if got, want := getQueuedKeys(manager.queue), []string{"default/foo1", "default/foo2"}; !reflect.DeepEqual(got, want) {
  2543. t.Errorf("getQueuedKeys() = %v, want %v", got, want)
  2544. }
  2545. }
  2546. }
  2547. }
  2548. func TestUpdatePod(t *testing.T) {
  2549. for _, f := range []bool{true, false} {
  2550. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  2551. for _, strategy := range updateStrategies() {
  2552. manager, _, _, err := newTestController()
  2553. if err != nil {
  2554. t.Fatalf("error creating DaemonSets controller: %v", err)
  2555. }
  2556. ds1 := newDaemonSet("foo1")
  2557. ds1.Spec.UpdateStrategy = *strategy
  2558. ds2 := newDaemonSet("foo2")
  2559. ds2.Spec.UpdateStrategy = *strategy
  2560. manager.dsStore.Add(ds1)
  2561. manager.dsStore.Add(ds2)
  2562. pod1 := newPod("pod1-", "node-0", simpleDaemonSetLabel, ds1)
  2563. prev := *pod1
  2564. bumpResourceVersion(pod1)
  2565. manager.updatePod(&prev, pod1)
  2566. if got, want := manager.queue.Len(), 1; got != want {
  2567. t.Fatalf("queue.Len() = %v, want %v", got, want)
  2568. }
  2569. key, done := manager.queue.Get()
  2570. if key == nil || done {
  2571. t.Fatalf("failed to enqueue controller for pod %v", pod1.Name)
  2572. }
  2573. expectedKey, _ := controller.KeyFunc(ds1)
  2574. if got, want := key.(string), expectedKey; got != want {
  2575. t.Errorf("queue.Get() = %v, want %v", got, want)
  2576. }
  2577. pod2 := newPod("pod2-", "node-0", simpleDaemonSetLabel, ds2)
  2578. prev = *pod2
  2579. bumpResourceVersion(pod2)
  2580. manager.updatePod(&prev, pod2)
  2581. if got, want := manager.queue.Len(), 1; got != want {
  2582. t.Fatalf("queue.Len() = %v, want %v", got, want)
  2583. }
  2584. key, done = manager.queue.Get()
  2585. if key == nil || done {
  2586. t.Fatalf("failed to enqueue controller for pod %v", pod2.Name)
  2587. }
  2588. expectedKey, _ = controller.KeyFunc(ds2)
  2589. if got, want := key.(string), expectedKey; got != want {
  2590. t.Errorf("queue.Get() = %v, want %v", got, want)
  2591. }
  2592. }
  2593. }
  2594. }
  2595. func TestUpdatePodOrphanSameLabels(t *testing.T) {
  2596. for _, f := range []bool{true, false} {
  2597. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  2598. for _, strategy := range updateStrategies() {
  2599. manager, _, _, err := newTestController()
  2600. if err != nil {
  2601. t.Fatalf("error creating DaemonSets controller: %v", err)
  2602. }
  2603. ds1 := newDaemonSet("foo1")
  2604. ds1.Spec.UpdateStrategy = *strategy
  2605. ds2 := newDaemonSet("foo2")
  2606. ds2.Spec.UpdateStrategy = *strategy
  2607. manager.dsStore.Add(ds1)
  2608. manager.dsStore.Add(ds2)
  2609. pod := newPod("pod1-", "node-0", simpleDaemonSetLabel, nil)
  2610. prev := *pod
  2611. bumpResourceVersion(pod)
  2612. manager.updatePod(&prev, pod)
  2613. if got, want := manager.queue.Len(), 0; got != want {
  2614. t.Fatalf("queue.Len() = %v, want %v", got, want)
  2615. }
  2616. }
  2617. }
  2618. }
  2619. func TestUpdatePodOrphanWithNewLabels(t *testing.T) {
  2620. for _, f := range []bool{true, false} {
  2621. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  2622. for _, strategy := range updateStrategies() {
  2623. manager, _, _, err := newTestController()
  2624. if err != nil {
  2625. t.Fatalf("error creating DaemonSets controller: %v", err)
  2626. }
  2627. ds1 := newDaemonSet("foo1")
  2628. ds1.Spec.UpdateStrategy = *strategy
  2629. ds2 := newDaemonSet("foo2")
  2630. ds2.Spec.UpdateStrategy = *strategy
  2631. manager.dsStore.Add(ds1)
  2632. manager.dsStore.Add(ds2)
  2633. pod := newPod("pod1-", "node-0", simpleDaemonSetLabel, nil)
  2634. prev := *pod
  2635. prev.Labels = map[string]string{"foo2": "bar2"}
  2636. bumpResourceVersion(pod)
  2637. manager.updatePod(&prev, pod)
  2638. if got, want := manager.queue.Len(), 2; got != want {
  2639. t.Fatalf("queue.Len() = %v, want %v", got, want)
  2640. }
  2641. if got, want := getQueuedKeys(manager.queue), []string{"default/foo1", "default/foo2"}; !reflect.DeepEqual(got, want) {
  2642. t.Errorf("getQueuedKeys() = %v, want %v", got, want)
  2643. }
  2644. }
  2645. }
  2646. }
  2647. func TestUpdatePodChangeControllerRef(t *testing.T) {
  2648. for _, f := range []bool{true, false} {
  2649. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  2650. for _, strategy := range updateStrategies() {
  2651. ds := newDaemonSet("foo")
  2652. ds.Spec.UpdateStrategy = *strategy
  2653. manager, _, _, err := newTestController()
  2654. if err != nil {
  2655. t.Fatalf("error creating DaemonSets controller: %v", err)
  2656. }
  2657. ds1 := newDaemonSet("foo1")
  2658. ds2 := newDaemonSet("foo2")
  2659. manager.dsStore.Add(ds1)
  2660. manager.dsStore.Add(ds2)
  2661. pod := newPod("pod1-", "node-0", simpleDaemonSetLabel, ds1)
  2662. prev := *pod
  2663. prev.OwnerReferences = []metav1.OwnerReference{*metav1.NewControllerRef(ds2, controllerKind)}
  2664. bumpResourceVersion(pod)
  2665. manager.updatePod(&prev, pod)
  2666. if got, want := manager.queue.Len(), 2; got != want {
  2667. t.Fatalf("queue.Len() = %v, want %v", got, want)
  2668. }
  2669. }
  2670. }
  2671. }
  2672. func TestUpdatePodControllerRefRemoved(t *testing.T) {
  2673. for _, f := range []bool{true, false} {
  2674. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  2675. for _, strategy := range updateStrategies() {
  2676. manager, _, _, err := newTestController()
  2677. if err != nil {
  2678. t.Fatalf("error creating DaemonSets controller: %v", err)
  2679. }
  2680. ds1 := newDaemonSet("foo1")
  2681. ds1.Spec.UpdateStrategy = *strategy
  2682. ds2 := newDaemonSet("foo2")
  2683. ds2.Spec.UpdateStrategy = *strategy
  2684. manager.dsStore.Add(ds1)
  2685. manager.dsStore.Add(ds2)
  2686. pod := newPod("pod1-", "node-0", simpleDaemonSetLabel, ds1)
  2687. prev := *pod
  2688. pod.OwnerReferences = nil
  2689. bumpResourceVersion(pod)
  2690. manager.updatePod(&prev, pod)
  2691. if got, want := manager.queue.Len(), 2; got != want {
  2692. t.Fatalf("queue.Len() = %v, want %v", got, want)
  2693. }
  2694. }
  2695. }
  2696. }
  2697. func TestDeletePod(t *testing.T) {
  2698. for _, f := range []bool{true, false} {
  2699. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  2700. for _, strategy := range updateStrategies() {
  2701. manager, _, _, err := newTestController()
  2702. if err != nil {
  2703. t.Fatalf("error creating DaemonSets controller: %v", err)
  2704. }
  2705. ds1 := newDaemonSet("foo1")
  2706. ds1.Spec.UpdateStrategy = *strategy
  2707. ds2 := newDaemonSet("foo2")
  2708. ds2.Spec.UpdateStrategy = *strategy
  2709. manager.dsStore.Add(ds1)
  2710. manager.dsStore.Add(ds2)
  2711. pod1 := newPod("pod1-", "node-0", simpleDaemonSetLabel, ds1)
  2712. manager.deletePod(pod1)
  2713. if got, want := manager.queue.Len(), 1; got != want {
  2714. t.Fatalf("queue.Len() = %v, want %v", got, want)
  2715. }
  2716. key, done := manager.queue.Get()
  2717. if key == nil || done {
  2718. t.Fatalf("failed to enqueue controller for pod %v", pod1.Name)
  2719. }
  2720. expectedKey, _ := controller.KeyFunc(ds1)
  2721. if got, want := key.(string), expectedKey; got != want {
  2722. t.Errorf("queue.Get() = %v, want %v", got, want)
  2723. }
  2724. pod2 := newPod("pod2-", "node-0", simpleDaemonSetLabel, ds2)
  2725. manager.deletePod(pod2)
  2726. if got, want := manager.queue.Len(), 1; got != want {
  2727. t.Fatalf("queue.Len() = %v, want %v", got, want)
  2728. }
  2729. key, done = manager.queue.Get()
  2730. if key == nil || done {
  2731. t.Fatalf("failed to enqueue controller for pod %v", pod2.Name)
  2732. }
  2733. expectedKey, _ = controller.KeyFunc(ds2)
  2734. if got, want := key.(string), expectedKey; got != want {
  2735. t.Errorf("queue.Get() = %v, want %v", got, want)
  2736. }
  2737. }
  2738. }
  2739. }
  2740. func TestDeletePodOrphan(t *testing.T) {
  2741. for _, f := range []bool{true, false} {
  2742. defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ScheduleDaemonSetPods, f)()
  2743. for _, strategy := range updateStrategies() {
  2744. manager, _, _, err := newTestController()
  2745. if err != nil {
  2746. t.Fatalf("error creating DaemonSets controller: %v", err)
  2747. }
  2748. ds1 := newDaemonSet("foo1")
  2749. ds1.Spec.UpdateStrategy = *strategy
  2750. ds2 := newDaemonSet("foo2")
  2751. ds2.Spec.UpdateStrategy = *strategy
  2752. ds3 := newDaemonSet("foo3")
  2753. ds3.Spec.UpdateStrategy = *strategy
  2754. ds3.Spec.Selector.MatchLabels = simpleDaemonSetLabel2
  2755. manager.dsStore.Add(ds1)
  2756. manager.dsStore.Add(ds2)
  2757. manager.dsStore.Add(ds3)
  2758. pod := newPod("pod1-", "node-0", simpleDaemonSetLabel, nil)
  2759. manager.deletePod(pod)
  2760. if got, want := manager.queue.Len(), 0; got != want {
  2761. t.Fatalf("queue.Len() = %v, want %v", got, want)
  2762. }
  2763. }
  2764. }
  2765. }
  2766. func bumpResourceVersion(obj metav1.Object) {
  2767. ver, _ := strconv.ParseInt(obj.GetResourceVersion(), 10, 32)
  2768. obj.SetResourceVersion(strconv.FormatInt(ver+1, 10))
  2769. }
  2770. // getQueuedKeys returns a sorted list of keys in the queue.
  2771. // It can be used to quickly check that multiple keys are in there.
  2772. func getQueuedKeys(queue workqueue.RateLimitingInterface) []string {
  2773. var keys []string
  2774. count := queue.Len()
  2775. for i := 0; i < count; i++ {
  2776. key, done := queue.Get()
  2777. if done {
  2778. return keys
  2779. }
  2780. keys = append(keys, key.(string))
  2781. }
  2782. sort.Strings(keys)
  2783. return keys
  2784. }