replicationcontroller_test.go 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862
  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 replicationcontroller
  14. import (
  15. "fmt"
  16. "net/http/httptest"
  17. "reflect"
  18. "testing"
  19. "time"
  20. "k8s.io/api/core/v1"
  21. "k8s.io/apimachinery/pkg/api/errors"
  22. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  23. "k8s.io/apimachinery/pkg/labels"
  24. "k8s.io/apimachinery/pkg/util/uuid"
  25. "k8s.io/apimachinery/pkg/util/wait"
  26. "k8s.io/client-go/informers"
  27. clientset "k8s.io/client-go/kubernetes"
  28. typedv1 "k8s.io/client-go/kubernetes/typed/core/v1"
  29. restclient "k8s.io/client-go/rest"
  30. "k8s.io/client-go/tools/cache"
  31. "k8s.io/client-go/util/retry"
  32. podutil "k8s.io/kubernetes/pkg/api/v1/pod"
  33. "k8s.io/kubernetes/pkg/controller/replication"
  34. "k8s.io/kubernetes/test/integration/framework"
  35. )
  36. const (
  37. interval = 100 * time.Millisecond
  38. timeout = 60 * time.Second
  39. )
  40. func labelMap() map[string]string {
  41. return map[string]string{"foo": "bar"}
  42. }
  43. func newRC(name, namespace string, replicas int) *v1.ReplicationController {
  44. replicasCopy := int32(replicas)
  45. return &v1.ReplicationController{
  46. TypeMeta: metav1.TypeMeta{
  47. Kind: "ReplicationController",
  48. APIVersion: "v1",
  49. },
  50. ObjectMeta: metav1.ObjectMeta{
  51. Namespace: namespace,
  52. Name: name,
  53. },
  54. Spec: v1.ReplicationControllerSpec{
  55. Selector: labelMap(),
  56. Replicas: &replicasCopy,
  57. Template: &v1.PodTemplateSpec{
  58. ObjectMeta: metav1.ObjectMeta{
  59. Labels: labelMap(),
  60. },
  61. Spec: v1.PodSpec{
  62. Containers: []v1.Container{
  63. {
  64. Name: "fake-name",
  65. Image: "fakeimage",
  66. },
  67. },
  68. },
  69. },
  70. },
  71. }
  72. }
  73. func newMatchingPod(podName, namespace string) *v1.Pod {
  74. return &v1.Pod{
  75. TypeMeta: metav1.TypeMeta{
  76. Kind: "Pod",
  77. APIVersion: "v1",
  78. },
  79. ObjectMeta: metav1.ObjectMeta{
  80. Name: podName,
  81. Namespace: namespace,
  82. Labels: labelMap(),
  83. },
  84. Spec: v1.PodSpec{
  85. Containers: []v1.Container{
  86. {
  87. Name: "fake-name",
  88. Image: "fakeimage",
  89. },
  90. },
  91. },
  92. Status: v1.PodStatus{
  93. Phase: v1.PodRunning,
  94. },
  95. }
  96. }
  97. func rmSetup(t *testing.T) (*httptest.Server, framework.CloseFunc, *replication.ReplicationManager, informers.SharedInformerFactory, clientset.Interface) {
  98. masterConfig := framework.NewIntegrationTestMasterConfig()
  99. _, s, closeFn := framework.RunAMaster(masterConfig)
  100. config := restclient.Config{Host: s.URL}
  101. clientSet, err := clientset.NewForConfig(&config)
  102. if err != nil {
  103. t.Fatalf("Error in create clientset: %v", err)
  104. }
  105. resyncPeriod := 12 * time.Hour
  106. informers := informers.NewSharedInformerFactory(clientset.NewForConfigOrDie(restclient.AddUserAgent(&config, "rc-informers")), resyncPeriod)
  107. rm := replication.NewReplicationManager(
  108. informers.Core().V1().Pods(),
  109. informers.Core().V1().ReplicationControllers(),
  110. clientset.NewForConfigOrDie(restclient.AddUserAgent(&config, "replication-controller")),
  111. replication.BurstReplicas,
  112. )
  113. if err != nil {
  114. t.Fatalf("Failed to create replication controller")
  115. }
  116. return s, closeFn, rm, informers, clientSet
  117. }
  118. func rmSimpleSetup(t *testing.T) (*httptest.Server, framework.CloseFunc, clientset.Interface) {
  119. masterConfig := framework.NewIntegrationTestMasterConfig()
  120. _, s, closeFn := framework.RunAMaster(masterConfig)
  121. config := restclient.Config{Host: s.URL}
  122. clientSet, err := clientset.NewForConfig(&config)
  123. if err != nil {
  124. t.Fatalf("Error in create clientset: %v", err)
  125. }
  126. return s, closeFn, clientSet
  127. }
  128. // Run RC controller and informers
  129. func runControllerAndInformers(t *testing.T, rm *replication.ReplicationManager, informers informers.SharedInformerFactory, podNum int) chan struct{} {
  130. stopCh := make(chan struct{})
  131. informers.Start(stopCh)
  132. waitToObservePods(t, informers.Core().V1().Pods().Informer(), podNum)
  133. go rm.Run(5, stopCh)
  134. return stopCh
  135. }
  136. // wait for the podInformer to observe the pods. Call this function before
  137. // running the RC controller to prevent the rc manager from creating new pods
  138. // rather than adopting the existing ones.
  139. func waitToObservePods(t *testing.T, podInformer cache.SharedIndexInformer, podNum int) {
  140. if err := wait.PollImmediate(interval, timeout, func() (bool, error) {
  141. objects := podInformer.GetIndexer().List()
  142. return len(objects) == podNum, nil
  143. }); err != nil {
  144. t.Fatalf("Error encountered when waiting for podInformer to observe the pods: %v", err)
  145. }
  146. }
  147. func createRCsPods(t *testing.T, clientSet clientset.Interface, rcs []*v1.ReplicationController, pods []*v1.Pod) ([]*v1.ReplicationController, []*v1.Pod) {
  148. var createdRCs []*v1.ReplicationController
  149. var createdPods []*v1.Pod
  150. for _, rc := range rcs {
  151. createdRC, err := clientSet.CoreV1().ReplicationControllers(rc.Namespace).Create(rc)
  152. if err != nil {
  153. t.Fatalf("Failed to create replication controller %s: %v", rc.Name, err)
  154. }
  155. createdRCs = append(createdRCs, createdRC)
  156. }
  157. for _, pod := range pods {
  158. createdPod, err := clientSet.CoreV1().Pods(pod.Namespace).Create(pod)
  159. if err != nil {
  160. t.Fatalf("Failed to create pod %s: %v", pod.Name, err)
  161. }
  162. createdPods = append(createdPods, createdPod)
  163. }
  164. return createdRCs, createdPods
  165. }
  166. // Verify .Status.Replicas is equal to .Spec.Replicas
  167. func waitRCStable(t *testing.T, clientSet clientset.Interface, rc *v1.ReplicationController) {
  168. rcClient := clientSet.CoreV1().ReplicationControllers(rc.Namespace)
  169. if err := wait.PollImmediate(interval, timeout, func() (bool, error) {
  170. newRC, err := rcClient.Get(rc.Name, metav1.GetOptions{})
  171. if err != nil {
  172. return false, err
  173. }
  174. return newRC.Status.Replicas == *rc.Spec.Replicas, nil
  175. }); err != nil {
  176. t.Fatalf("Failed to verify .Status.Replicas is equal to .Spec.Replicas for rc %s: %v", rc.Name, err)
  177. }
  178. }
  179. // Update .Spec.Replicas to replicas and verify .Status.Replicas is changed accordingly
  180. func scaleRC(t *testing.T, c clientset.Interface, rc *v1.ReplicationController, replicas int32) {
  181. rcClient := c.CoreV1().ReplicationControllers(rc.Namespace)
  182. rc = updateRC(t, rcClient, rc.Name, func(rc *v1.ReplicationController) {
  183. *rc.Spec.Replicas = replicas
  184. })
  185. waitRCStable(t, c, rc)
  186. }
  187. func updatePod(t *testing.T, podClient typedv1.PodInterface, podName string, updateFunc func(*v1.Pod)) *v1.Pod {
  188. var pod *v1.Pod
  189. if err := retry.RetryOnConflict(retry.DefaultBackoff, func() error {
  190. newPod, err := podClient.Get(podName, metav1.GetOptions{})
  191. if err != nil {
  192. return err
  193. }
  194. updateFunc(newPod)
  195. pod, err = podClient.Update(newPod)
  196. return err
  197. }); err != nil {
  198. t.Fatalf("Failed to update pod %s: %v", podName, err)
  199. }
  200. return pod
  201. }
  202. func updatePodStatus(t *testing.T, podClient typedv1.PodInterface, pod *v1.Pod, updateStatusFunc func(*v1.Pod)) {
  203. if err := retry.RetryOnConflict(retry.DefaultBackoff, func() error {
  204. newPod, err := podClient.Get(pod.Name, metav1.GetOptions{})
  205. if err != nil {
  206. return err
  207. }
  208. updateStatusFunc(newPod)
  209. _, err = podClient.UpdateStatus(newPod)
  210. return err
  211. }); err != nil {
  212. t.Fatalf("Failed to update status of pod %s: %v", pod.Name, err)
  213. }
  214. }
  215. func getPods(t *testing.T, podClient typedv1.PodInterface, labelMap map[string]string) *v1.PodList {
  216. podSelector := labels.Set(labelMap).AsSelector()
  217. options := metav1.ListOptions{LabelSelector: podSelector.String()}
  218. pods, err := podClient.List(options)
  219. if err != nil {
  220. t.Fatalf("Failed obtaining a list of pods that match the pod labels %v: %v", labelMap, err)
  221. }
  222. return pods
  223. }
  224. func updateRC(t *testing.T, rcClient typedv1.ReplicationControllerInterface, rcName string, updateFunc func(*v1.ReplicationController)) *v1.ReplicationController {
  225. var rc *v1.ReplicationController
  226. if err := retry.RetryOnConflict(retry.DefaultBackoff, func() error {
  227. newRC, err := rcClient.Get(rcName, metav1.GetOptions{})
  228. if err != nil {
  229. return err
  230. }
  231. updateFunc(newRC)
  232. rc, err = rcClient.Update(newRC)
  233. return err
  234. }); err != nil {
  235. t.Fatalf("Failed to update rc %s: %v", rcName, err)
  236. }
  237. return rc
  238. }
  239. // Verify ControllerRef of a RC pod that has incorrect attributes is automatically patched by the RC
  240. func testPodControllerRefPatch(t *testing.T, c clientset.Interface, pod *v1.Pod, ownerReference *metav1.OwnerReference, rc *v1.ReplicationController, expectedOwnerReferenceNum int) {
  241. ns := rc.Namespace
  242. podClient := c.CoreV1().Pods(ns)
  243. updatePod(t, podClient, pod.Name, func(pod *v1.Pod) {
  244. pod.OwnerReferences = []metav1.OwnerReference{*ownerReference}
  245. })
  246. if err := wait.PollImmediate(interval, timeout, func() (bool, error) {
  247. newPod, err := podClient.Get(pod.Name, metav1.GetOptions{})
  248. if err != nil {
  249. return false, err
  250. }
  251. return metav1.GetControllerOf(newPod) != nil, nil
  252. }); err != nil {
  253. t.Fatalf("Failed to verify ControllerRef for the pod %s is not nil: %v", pod.Name, err)
  254. }
  255. newPod, err := podClient.Get(pod.Name, metav1.GetOptions{})
  256. if err != nil {
  257. t.Fatalf("Failed to obtain pod %s: %v", pod.Name, err)
  258. }
  259. controllerRef := metav1.GetControllerOf(newPod)
  260. if controllerRef.UID != rc.UID {
  261. t.Fatalf("RC owner of the pod %s has a different UID: Expected %v, got %v", newPod.Name, rc.UID, controllerRef.UID)
  262. }
  263. ownerReferenceNum := len(newPod.GetOwnerReferences())
  264. if ownerReferenceNum != expectedOwnerReferenceNum {
  265. t.Fatalf("Unexpected number of owner references for pod %s: Expected %d, got %d", newPod.Name, expectedOwnerReferenceNum, ownerReferenceNum)
  266. }
  267. }
  268. func setPodsReadyCondition(t *testing.T, clientSet clientset.Interface, pods *v1.PodList, conditionStatus v1.ConditionStatus, lastTransitionTime time.Time) {
  269. replicas := int32(len(pods.Items))
  270. var readyPods int32
  271. err := wait.PollImmediate(interval, timeout, func() (bool, error) {
  272. readyPods = 0
  273. for i := range pods.Items {
  274. pod := &pods.Items[i]
  275. if podutil.IsPodReady(pod) {
  276. readyPods++
  277. continue
  278. }
  279. pod.Status.Phase = v1.PodRunning
  280. _, condition := podutil.GetPodCondition(&pod.Status, v1.PodReady)
  281. if condition != nil {
  282. condition.Status = conditionStatus
  283. condition.LastTransitionTime = metav1.Time{Time: lastTransitionTime}
  284. } else {
  285. condition = &v1.PodCondition{
  286. Type: v1.PodReady,
  287. Status: conditionStatus,
  288. LastTransitionTime: metav1.Time{Time: lastTransitionTime},
  289. }
  290. pod.Status.Conditions = append(pod.Status.Conditions, *condition)
  291. }
  292. _, err := clientSet.CoreV1().Pods(pod.Namespace).UpdateStatus(pod)
  293. if err != nil {
  294. // When status fails to be updated, we continue to next pod
  295. continue
  296. }
  297. readyPods++
  298. }
  299. return readyPods >= replicas, nil
  300. })
  301. if err != nil {
  302. t.Fatalf("failed to mark all ReplicationController pods to ready: %v", err)
  303. }
  304. }
  305. func testScalingUsingScaleSubresource(t *testing.T, c clientset.Interface, rc *v1.ReplicationController, replicas int32) {
  306. ns := rc.Namespace
  307. rcClient := c.CoreV1().ReplicationControllers(ns)
  308. newRC, err := rcClient.Get(rc.Name, metav1.GetOptions{})
  309. if err != nil {
  310. t.Fatalf("Failed to obtain rc %s: %v", rc.Name, err)
  311. }
  312. scale, err := c.CoreV1().ReplicationControllers(ns).GetScale(rc.Name, metav1.GetOptions{})
  313. if err != nil {
  314. t.Fatalf("Failed to obtain scale subresource for rc %s: %v", rc.Name, err)
  315. }
  316. if scale.Spec.Replicas != *newRC.Spec.Replicas {
  317. t.Fatalf("Scale subresource for rc %s does not match .Spec.Replicas: expected %d, got %d", rc.Name, *newRC.Spec.Replicas, scale.Spec.Replicas)
  318. }
  319. if err := retry.RetryOnConflict(retry.DefaultBackoff, func() error {
  320. scale, err := c.CoreV1().ReplicationControllers(ns).GetScale(rc.Name, metav1.GetOptions{})
  321. if err != nil {
  322. return err
  323. }
  324. scale.Spec.Replicas = replicas
  325. _, err = c.CoreV1().ReplicationControllers(ns).UpdateScale(rc.Name, scale)
  326. return err
  327. }); err != nil {
  328. t.Fatalf("Failed to set .Spec.Replicas of scale subresource for rc %s: %v", rc.Name, err)
  329. }
  330. newRC, err = rcClient.Get(rc.Name, metav1.GetOptions{})
  331. if err != nil {
  332. t.Fatalf("Failed to obtain rc %s: %v", rc.Name, err)
  333. }
  334. if *newRC.Spec.Replicas != replicas {
  335. t.Fatalf(".Spec.Replicas of rc %s does not match its scale subresource: expected %d, got %d", rc.Name, replicas, *newRC.Spec.Replicas)
  336. }
  337. }
  338. func TestAdoption(t *testing.T) {
  339. boolPtr := func(b bool) *bool { return &b }
  340. testCases := []struct {
  341. name string
  342. existingOwnerReferences func(rc *v1.ReplicationController) []metav1.OwnerReference
  343. expectedOwnerReferences func(rc *v1.ReplicationController) []metav1.OwnerReference
  344. }{
  345. {
  346. "pod refers rc as an owner, not a controller",
  347. func(rc *v1.ReplicationController) []metav1.OwnerReference {
  348. return []metav1.OwnerReference{{UID: rc.UID, Name: rc.Name, APIVersion: "v1", Kind: "ReplicationController"}}
  349. },
  350. func(rc *v1.ReplicationController) []metav1.OwnerReference {
  351. return []metav1.OwnerReference{{UID: rc.UID, Name: rc.Name, APIVersion: "v1", Kind: "ReplicationController", Controller: boolPtr(true), BlockOwnerDeletion: boolPtr(true)}}
  352. },
  353. },
  354. {
  355. "pod doesn't have owner references",
  356. func(rc *v1.ReplicationController) []metav1.OwnerReference {
  357. return []metav1.OwnerReference{}
  358. },
  359. func(rc *v1.ReplicationController) []metav1.OwnerReference {
  360. return []metav1.OwnerReference{{UID: rc.UID, Name: rc.Name, APIVersion: "v1", Kind: "ReplicationController", Controller: boolPtr(true), BlockOwnerDeletion: boolPtr(true)}}
  361. },
  362. },
  363. {
  364. "pod refers rc as a controller",
  365. func(rc *v1.ReplicationController) []metav1.OwnerReference {
  366. return []metav1.OwnerReference{{UID: rc.UID, Name: rc.Name, APIVersion: "v1", Kind: "ReplicationController", Controller: boolPtr(true)}}
  367. },
  368. func(rc *v1.ReplicationController) []metav1.OwnerReference {
  369. return []metav1.OwnerReference{{UID: rc.UID, Name: rc.Name, APIVersion: "v1", Kind: "ReplicationController", Controller: boolPtr(true)}}
  370. },
  371. },
  372. {
  373. "pod refers other rc as the controller, refers the rc as an owner",
  374. func(rc *v1.ReplicationController) []metav1.OwnerReference {
  375. return []metav1.OwnerReference{
  376. {UID: "1", Name: "anotherRC", APIVersion: "v1", Kind: "ReplicationController", Controller: boolPtr(true)},
  377. {UID: rc.UID, Name: rc.Name, APIVersion: "v1", Kind: "ReplicationController"},
  378. }
  379. },
  380. func(rc *v1.ReplicationController) []metav1.OwnerReference {
  381. return []metav1.OwnerReference{
  382. {UID: "1", Name: "anotherRC", APIVersion: "v1", Kind: "ReplicationController", Controller: boolPtr(true)},
  383. {UID: rc.UID, Name: rc.Name, APIVersion: "v1", Kind: "ReplicationController"},
  384. }
  385. },
  386. },
  387. }
  388. for i, tc := range testCases {
  389. func() {
  390. s, closeFn, rm, informers, clientSet := rmSetup(t)
  391. defer closeFn()
  392. ns := framework.CreateTestingNamespace(fmt.Sprintf("rc-adoption-%d", i), s, t)
  393. defer framework.DeleteTestingNamespace(ns, s, t)
  394. rcClient := clientSet.CoreV1().ReplicationControllers(ns.Name)
  395. podClient := clientSet.CoreV1().Pods(ns.Name)
  396. const rcName = "rc"
  397. rc, err := rcClient.Create(newRC(rcName, ns.Name, 1))
  398. if err != nil {
  399. t.Fatalf("Failed to create replication controllers: %v", err)
  400. }
  401. podName := fmt.Sprintf("pod%d", i)
  402. pod := newMatchingPod(podName, ns.Name)
  403. pod.OwnerReferences = tc.existingOwnerReferences(rc)
  404. _, err = podClient.Create(pod)
  405. if err != nil {
  406. t.Fatalf("Failed to create Pod: %v", err)
  407. }
  408. stopCh := runControllerAndInformers(t, rm, informers, 1)
  409. defer close(stopCh)
  410. if err := wait.PollImmediate(interval, timeout, func() (bool, error) {
  411. updatedPod, err := podClient.Get(pod.Name, metav1.GetOptions{})
  412. if err != nil {
  413. return false, err
  414. }
  415. e, a := tc.expectedOwnerReferences(rc), updatedPod.OwnerReferences
  416. if reflect.DeepEqual(e, a) {
  417. return true, nil
  418. }
  419. t.Logf("ownerReferences don't match, expect %v, got %v", e, a)
  420. return false, nil
  421. }); err != nil {
  422. t.Fatalf("test %q failed: %v", tc.name, err)
  423. }
  424. }()
  425. }
  426. }
  427. func TestSpecReplicasChange(t *testing.T) {
  428. s, closeFn, rm, informers, c := rmSetup(t)
  429. defer closeFn()
  430. ns := framework.CreateTestingNamespace("test-spec-replicas-change", s, t)
  431. defer framework.DeleteTestingNamespace(ns, s, t)
  432. stopCh := runControllerAndInformers(t, rm, informers, 0)
  433. defer close(stopCh)
  434. rc := newRC("rc", ns.Name, 2)
  435. rcs, _ := createRCsPods(t, c, []*v1.ReplicationController{rc}, []*v1.Pod{})
  436. rc = rcs[0]
  437. waitRCStable(t, c, rc)
  438. // Update .Spec.Replicas and verify .Status.Replicas is changed accordingly
  439. scaleRC(t, c, rc, 3)
  440. scaleRC(t, c, rc, 0)
  441. scaleRC(t, c, rc, 2)
  442. // Add a template annotation change to test RC's status does update
  443. // without .Spec.Replicas change
  444. rcClient := c.CoreV1().ReplicationControllers(ns.Name)
  445. var oldGeneration int64
  446. newRC := updateRC(t, rcClient, rc.Name, func(rc *v1.ReplicationController) {
  447. oldGeneration = rc.Generation
  448. rc.Spec.Template.Annotations = map[string]string{"test": "annotation"}
  449. })
  450. savedGeneration := newRC.Generation
  451. if savedGeneration == oldGeneration {
  452. t.Fatalf("Failed to verify .Generation has incremented for rc %s", rc.Name)
  453. }
  454. if err := wait.PollImmediate(interval, timeout, func() (bool, error) {
  455. newRC, err := rcClient.Get(rc.Name, metav1.GetOptions{})
  456. if err != nil {
  457. return false, err
  458. }
  459. return newRC.Status.ObservedGeneration >= savedGeneration, nil
  460. }); err != nil {
  461. t.Fatalf("Failed to verify .Status.ObservedGeneration has incremented for rc %s: %v", rc.Name, err)
  462. }
  463. }
  464. func TestDeletingAndFailedPods(t *testing.T) {
  465. s, closeFn, rm, informers, c := rmSetup(t)
  466. defer closeFn()
  467. ns := framework.CreateTestingNamespace("test-deleting-and-failed-pods", s, t)
  468. defer framework.DeleteTestingNamespace(ns, s, t)
  469. stopCh := runControllerAndInformers(t, rm, informers, 0)
  470. defer close(stopCh)
  471. rc := newRC("rc", ns.Name, 2)
  472. rcs, _ := createRCsPods(t, c, []*v1.ReplicationController{rc}, []*v1.Pod{})
  473. rc = rcs[0]
  474. waitRCStable(t, c, rc)
  475. // Verify RC creates 2 pods
  476. podClient := c.CoreV1().Pods(ns.Name)
  477. pods := getPods(t, podClient, labelMap())
  478. if len(pods.Items) != 2 {
  479. t.Fatalf("len(pods) = %d, want 2", len(pods.Items))
  480. }
  481. // Set first pod as deleting pod
  482. // Set finalizers for the pod to simulate pending deletion status
  483. deletingPod := &pods.Items[0]
  484. updatePod(t, podClient, deletingPod.Name, func(pod *v1.Pod) {
  485. pod.Finalizers = []string{"fake.example.com/blockDeletion"}
  486. })
  487. if err := c.CoreV1().Pods(ns.Name).Delete(deletingPod.Name, &metav1.DeleteOptions{}); err != nil {
  488. t.Fatalf("Error deleting pod %s: %v", deletingPod.Name, err)
  489. }
  490. // Set second pod as failed pod
  491. failedPod := &pods.Items[1]
  492. updatePodStatus(t, podClient, failedPod, func(pod *v1.Pod) {
  493. pod.Status.Phase = v1.PodFailed
  494. })
  495. // Pool until 2 new pods have been created to replace deleting and failed pods
  496. if err := wait.PollImmediate(interval, timeout, func() (bool, error) {
  497. pods = getPods(t, podClient, labelMap())
  498. return len(pods.Items) == 4, nil
  499. }); err != nil {
  500. t.Fatalf("Failed to verify 2 new pods have been created (expected 4 pods): %v", err)
  501. }
  502. // Verify deleting and failed pods are among the four pods
  503. foundDeletingPod := false
  504. foundFailedPod := false
  505. for _, pod := range pods.Items {
  506. if pod.UID == deletingPod.UID {
  507. foundDeletingPod = true
  508. }
  509. if pod.UID == failedPod.UID {
  510. foundFailedPod = true
  511. }
  512. }
  513. // Verify deleting pod exists
  514. if !foundDeletingPod {
  515. t.Fatalf("expected deleting pod %s exists, but it is not found", deletingPod.Name)
  516. }
  517. // Verify failed pod exists
  518. if !foundFailedPod {
  519. t.Fatalf("expected failed pod %s exists, but it is not found", failedPod.Name)
  520. }
  521. }
  522. func TestOverlappingRCs(t *testing.T) {
  523. s, closeFn, rm, informers, c := rmSetup(t)
  524. defer closeFn()
  525. ns := framework.CreateTestingNamespace("test-overlapping-rcs", s, t)
  526. defer framework.DeleteTestingNamespace(ns, s, t)
  527. stopCh := runControllerAndInformers(t, rm, informers, 0)
  528. defer close(stopCh)
  529. // Create 2 RCs with identical selectors
  530. for i := 0; i < 2; i++ {
  531. // One RC has 1 replica, and another has 2 replicas
  532. rc := newRC(fmt.Sprintf("rc-%d", i+1), ns.Name, i+1)
  533. rcs, _ := createRCsPods(t, c, []*v1.ReplicationController{rc}, []*v1.Pod{})
  534. waitRCStable(t, c, rcs[0])
  535. }
  536. // Expect 3 total Pods to be created
  537. podClient := c.CoreV1().Pods(ns.Name)
  538. pods := getPods(t, podClient, labelMap())
  539. if len(pods.Items) != 3 {
  540. t.Errorf("len(pods) = %d, want 3", len(pods.Items))
  541. }
  542. // Expect both RCs have .status.replicas = .spec.replicas
  543. for i := 0; i < 2; i++ {
  544. newRC, err := c.CoreV1().ReplicationControllers(ns.Name).Get(fmt.Sprintf("rc-%d", i+1), metav1.GetOptions{})
  545. if err != nil {
  546. t.Fatalf("failed to obtain rc rc-%d: %v", i+1, err)
  547. }
  548. if newRC.Status.Replicas != *newRC.Spec.Replicas {
  549. t.Fatalf(".Status.Replicas %d is not equal to .Spec.Replicas %d", newRC.Status.Replicas, *newRC.Spec.Replicas)
  550. }
  551. }
  552. }
  553. func TestPodOrphaningAndAdoptionWhenLabelsChange(t *testing.T) {
  554. s, closeFn, rm, informers, c := rmSetup(t)
  555. defer closeFn()
  556. ns := framework.CreateTestingNamespace("test-pod-orphaning-and-adoption-when-labels-change", s, t)
  557. defer framework.DeleteTestingNamespace(ns, s, t)
  558. stopCh := runControllerAndInformers(t, rm, informers, 0)
  559. defer close(stopCh)
  560. rc := newRC("rc", ns.Name, 1)
  561. rcs, _ := createRCsPods(t, c, []*v1.ReplicationController{rc}, []*v1.Pod{})
  562. rc = rcs[0]
  563. waitRCStable(t, c, rc)
  564. // Orphaning: RC should remove OwnerReference from a pod when the pod's labels change to not match its labels
  565. podClient := c.CoreV1().Pods(ns.Name)
  566. pods := getPods(t, podClient, labelMap())
  567. if len(pods.Items) != 1 {
  568. t.Fatalf("len(pods) = %d, want 1", len(pods.Items))
  569. }
  570. pod := &pods.Items[0]
  571. // Start by verifying ControllerRef for the pod is not nil
  572. if metav1.GetControllerOf(pod) == nil {
  573. t.Fatalf("ControllerRef of pod %s is nil", pod.Name)
  574. }
  575. newLabelMap := map[string]string{"new-foo": "new-bar"}
  576. updatePod(t, podClient, pod.Name, func(pod *v1.Pod) {
  577. pod.Labels = newLabelMap
  578. })
  579. if err := wait.PollImmediate(interval, timeout, func() (bool, error) {
  580. newPod, err := podClient.Get(pod.Name, metav1.GetOptions{})
  581. if err != nil {
  582. return false, err
  583. }
  584. pod = newPod
  585. return metav1.GetControllerOf(newPod) == nil, nil
  586. }); err != nil {
  587. t.Fatalf("Failed to verify ControllerRef for the pod %s is nil: %v", pod.Name, err)
  588. }
  589. // Adoption: RC should add ControllerRef to a pod when the pod's labels change to match its labels
  590. updatePod(t, podClient, pod.Name, func(pod *v1.Pod) {
  591. pod.Labels = labelMap()
  592. })
  593. if err := wait.PollImmediate(interval, timeout, func() (bool, error) {
  594. newPod, err := podClient.Get(pod.Name, metav1.GetOptions{})
  595. if err != nil {
  596. // If the pod is not found, it means the RC picks the pod for deletion (it is extra)
  597. // Verify there is only one pod in namespace and it has ControllerRef to the RC
  598. if errors.IsNotFound(err) {
  599. pods := getPods(t, podClient, labelMap())
  600. if len(pods.Items) != 1 {
  601. return false, fmt.Errorf("Expected 1 pod in current namespace, got %d", len(pods.Items))
  602. }
  603. // Set the pod accordingly
  604. pod = &pods.Items[0]
  605. return true, nil
  606. }
  607. return false, err
  608. }
  609. // Always update the pod so that we can save a GET call to API server later
  610. pod = newPod
  611. // If the pod is found, verify the pod has a ControllerRef
  612. return metav1.GetControllerOf(newPod) != nil, nil
  613. }); err != nil {
  614. t.Fatalf("Failed to verify ControllerRef for pod %s is not nil: %v", pod.Name, err)
  615. }
  616. // Verify the pod has a ControllerRef to the RC
  617. // Do nothing if the pod is nil (i.e., has been picked for deletion)
  618. if pod != nil {
  619. controllerRef := metav1.GetControllerOf(pod)
  620. if controllerRef.UID != rc.UID {
  621. t.Fatalf("RC owner of the pod %s has a different UID: Expected %v, got %v", pod.Name, rc.UID, controllerRef.UID)
  622. }
  623. }
  624. }
  625. func TestGeneralPodAdoption(t *testing.T) {
  626. s, closeFn, rm, informers, c := rmSetup(t)
  627. defer closeFn()
  628. ns := framework.CreateTestingNamespace("test-general-pod-adoption", s, t)
  629. defer framework.DeleteTestingNamespace(ns, s, t)
  630. stopCh := runControllerAndInformers(t, rm, informers, 0)
  631. defer close(stopCh)
  632. rc := newRC("rc", ns.Name, 1)
  633. rcs, _ := createRCsPods(t, c, []*v1.ReplicationController{rc}, []*v1.Pod{})
  634. rc = rcs[0]
  635. waitRCStable(t, c, rc)
  636. podClient := c.CoreV1().Pods(ns.Name)
  637. pods := getPods(t, podClient, labelMap())
  638. if len(pods.Items) != 1 {
  639. t.Fatalf("len(pods) = %d, want 1", len(pods.Items))
  640. }
  641. pod := &pods.Items[0]
  642. var falseVar = false
  643. // When the only OwnerReference of the pod points to another type of API object such as statefulset
  644. // with Controller=false, the RC should add a second OwnerReference (ControllerRef) pointing to itself
  645. // with Controller=true
  646. ownerReference := metav1.OwnerReference{UID: uuid.NewUUID(), APIVersion: "apps/v1beta1", Kind: "StatefulSet", Name: rc.Name, Controller: &falseVar}
  647. testPodControllerRefPatch(t, c, pod, &ownerReference, rc, 2)
  648. // When the only OwnerReference of the pod points to the RC, but Controller=false
  649. ownerReference = metav1.OwnerReference{UID: rc.UID, APIVersion: "v1", Kind: "ReplicationController", Name: rc.Name, Controller: &falseVar}
  650. testPodControllerRefPatch(t, c, pod, &ownerReference, rc, 1)
  651. }
  652. func TestReadyAndAvailableReplicas(t *testing.T) {
  653. s, closeFn, rm, informers, c := rmSetup(t)
  654. defer closeFn()
  655. ns := framework.CreateTestingNamespace("test-ready-and-available-replicas", s, t)
  656. defer framework.DeleteTestingNamespace(ns, s, t)
  657. stopCh := runControllerAndInformers(t, rm, informers, 0)
  658. defer close(stopCh)
  659. rc := newRC("rc", ns.Name, 3)
  660. rc.Spec.MinReadySeconds = 3600
  661. rcs, _ := createRCsPods(t, c, []*v1.ReplicationController{rc}, []*v1.Pod{})
  662. rc = rcs[0]
  663. waitRCStable(t, c, rc)
  664. // First verify no pod is available
  665. if rc.Status.AvailableReplicas != 0 {
  666. t.Fatalf("Unexpected .Status.AvailableReplicas: Expected 0, saw %d", rc.Status.AvailableReplicas)
  667. }
  668. podClient := c.CoreV1().Pods(ns.Name)
  669. pods := getPods(t, podClient, labelMap())
  670. if len(pods.Items) != 3 {
  671. t.Fatalf("len(pods) = %d, want 3", len(pods.Items))
  672. }
  673. // Separate 3 pods into their own list
  674. firstPodList := &v1.PodList{Items: pods.Items[:1]}
  675. secondPodList := &v1.PodList{Items: pods.Items[1:2]}
  676. thirdPodList := &v1.PodList{Items: pods.Items[2:]}
  677. // First pod: Running, but not Ready
  678. // by setting the Ready condition to false with LastTransitionTime to be now
  679. setPodsReadyCondition(t, c, firstPodList, v1.ConditionFalse, time.Now())
  680. // Second pod: Running and Ready, but not Available
  681. // by setting LastTransitionTime to now
  682. setPodsReadyCondition(t, c, secondPodList, v1.ConditionTrue, time.Now())
  683. // Third pod: Running, Ready, and Available
  684. // by setting LastTransitionTime to more than 3600 seconds ago
  685. setPodsReadyCondition(t, c, thirdPodList, v1.ConditionTrue, time.Now().Add(-120*time.Minute))
  686. rcClient := c.CoreV1().ReplicationControllers(ns.Name)
  687. if err := wait.PollImmediate(interval, timeout, func() (bool, error) {
  688. newRC, err := rcClient.Get(rc.Name, metav1.GetOptions{})
  689. if err != nil {
  690. return false, err
  691. }
  692. // Verify 3 pods exist, 2 pods are Ready, and 1 pod is Available
  693. return newRC.Status.Replicas == 3 && newRC.Status.ReadyReplicas == 2 && newRC.Status.AvailableReplicas == 1, nil
  694. }); err != nil {
  695. t.Fatalf("Failed to verify number of Replicas, ReadyReplicas and AvailableReplicas of rc %s to be as expected: %v", rc.Name, err)
  696. }
  697. }
  698. func TestRCScaleSubresource(t *testing.T) {
  699. s, closeFn, rm, informers, c := rmSetup(t)
  700. defer closeFn()
  701. ns := framework.CreateTestingNamespace("test-rc-scale-subresource", s, t)
  702. defer framework.DeleteTestingNamespace(ns, s, t)
  703. stopCh := runControllerAndInformers(t, rm, informers, 0)
  704. defer close(stopCh)
  705. rc := newRC("rc", ns.Name, 1)
  706. rcs, _ := createRCsPods(t, c, []*v1.ReplicationController{rc}, []*v1.Pod{})
  707. rc = rcs[0]
  708. waitRCStable(t, c, rc)
  709. // Use scale subresource to scale up .Spec.Replicas to 3
  710. testScalingUsingScaleSubresource(t, c, rc, 3)
  711. // Use the scale subresource to scale down .Spec.Replicas to 0
  712. testScalingUsingScaleSubresource(t, c, rc, 0)
  713. }
  714. func TestExtraPodsAdoptionAndDeletion(t *testing.T) {
  715. s, closeFn, rm, informers, c := rmSetup(t)
  716. defer closeFn()
  717. ns := framework.CreateTestingNamespace("test-extra-pods-adoption-and-deletion", s, t)
  718. defer framework.DeleteTestingNamespace(ns, s, t)
  719. rc := newRC("rc", ns.Name, 2)
  720. // Create 3 pods, RC should adopt only 2 of them
  721. podList := []*v1.Pod{}
  722. for i := 0; i < 3; i++ {
  723. pod := newMatchingPod(fmt.Sprintf("pod-%d", i+1), ns.Name)
  724. pod.Labels = labelMap()
  725. podList = append(podList, pod)
  726. }
  727. rcs, _ := createRCsPods(t, c, []*v1.ReplicationController{rc}, podList)
  728. rc = rcs[0]
  729. stopCh := runControllerAndInformers(t, rm, informers, 3)
  730. defer close(stopCh)
  731. waitRCStable(t, c, rc)
  732. // Verify the extra pod is deleted eventually by determining whether number of
  733. // all pods within namespace matches .spec.replicas of the RC (2 in this case)
  734. podClient := c.CoreV1().Pods(ns.Name)
  735. if err := wait.PollImmediate(interval, timeout, func() (bool, error) {
  736. // All pods have labelMap as their labels
  737. pods := getPods(t, podClient, labelMap())
  738. return int32(len(pods.Items)) == *rc.Spec.Replicas, nil
  739. }); err != nil {
  740. t.Fatalf("Failed to verify number of all pods within current namespace matches .spec.replicas of rc %s: %v", rc.Name, err)
  741. }
  742. }
  743. func TestFullyLabeledReplicas(t *testing.T) {
  744. s, closeFn, rm, informers, c := rmSetup(t)
  745. defer closeFn()
  746. ns := framework.CreateTestingNamespace("test-fully-labeled-replicas", s, t)
  747. defer framework.DeleteTestingNamespace(ns, s, t)
  748. stopCh := runControllerAndInformers(t, rm, informers, 0)
  749. defer close(stopCh)
  750. extraLabelMap := map[string]string{"foo": "bar", "extraKey": "extraValue"}
  751. rc := newRC("rc", ns.Name, 2)
  752. rcs, _ := createRCsPods(t, c, []*v1.ReplicationController{rc}, []*v1.Pod{})
  753. rc = rcs[0]
  754. waitRCStable(t, c, rc)
  755. // Change RC's template labels to have extra labels, but not its selector
  756. rcClient := c.CoreV1().ReplicationControllers(ns.Name)
  757. updateRC(t, rcClient, rc.Name, func(rc *v1.ReplicationController) {
  758. rc.Spec.Template.Labels = extraLabelMap
  759. })
  760. // Set one of the pods to have extra labels
  761. podClient := c.CoreV1().Pods(ns.Name)
  762. pods := getPods(t, podClient, labelMap())
  763. if len(pods.Items) != 2 {
  764. t.Fatalf("len(pods) = %d, want 2", len(pods.Items))
  765. }
  766. fullyLabeledPod := &pods.Items[0]
  767. updatePod(t, podClient, fullyLabeledPod.Name, func(pod *v1.Pod) {
  768. pod.Labels = extraLabelMap
  769. })
  770. // Verify only one pod is fully labeled
  771. if err := wait.PollImmediate(interval, timeout, func() (bool, error) {
  772. newRC, err := rcClient.Get(rc.Name, metav1.GetOptions{})
  773. if err != nil {
  774. return false, err
  775. }
  776. return (newRC.Status.Replicas == 2 && newRC.Status.FullyLabeledReplicas == 1), nil
  777. }); err != nil {
  778. t.Fatalf("Failed to verify only one pod is fully labeled: %v", err)
  779. }
  780. }