defaults_test.go 39 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393
  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 v1_test
  14. import (
  15. "fmt"
  16. "reflect"
  17. "testing"
  18. "k8s.io/api/core/v1"
  19. "k8s.io/apimachinery/pkg/api/resource"
  20. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  21. "k8s.io/apimachinery/pkg/runtime"
  22. "k8s.io/apimachinery/pkg/util/intstr"
  23. "k8s.io/kubernetes/pkg/api/legacyscheme"
  24. corev1 "k8s.io/kubernetes/pkg/apis/core/v1"
  25. utilpointer "k8s.io/utils/pointer"
  26. // enforce that all types are installed
  27. _ "k8s.io/kubernetes/pkg/api/testapi"
  28. )
  29. func roundTrip(t *testing.T, obj runtime.Object) runtime.Object {
  30. codec := legacyscheme.Codecs.LegacyCodec(corev1.SchemeGroupVersion)
  31. data, err := runtime.Encode(codec, obj)
  32. if err != nil {
  33. t.Errorf("%v\n %#v", err, obj)
  34. return nil
  35. }
  36. obj2, err := runtime.Decode(codec, data)
  37. if err != nil {
  38. t.Errorf("%v\nData: %s\nSource: %#v", err, string(data), obj)
  39. return nil
  40. }
  41. obj3 := reflect.New(reflect.TypeOf(obj).Elem()).Interface().(runtime.Object)
  42. err = legacyscheme.Scheme.Convert(obj2, obj3, nil)
  43. if err != nil {
  44. t.Errorf("%v\nSource: %#v", err, obj2)
  45. return nil
  46. }
  47. return obj3
  48. }
  49. func TestSetDefaultReplicationController(t *testing.T) {
  50. tests := []struct {
  51. rc *v1.ReplicationController
  52. expectLabels bool
  53. expectSelector bool
  54. }{
  55. {
  56. rc: &v1.ReplicationController{
  57. Spec: v1.ReplicationControllerSpec{
  58. Template: &v1.PodTemplateSpec{
  59. ObjectMeta: metav1.ObjectMeta{
  60. Labels: map[string]string{
  61. "foo": "bar",
  62. },
  63. },
  64. },
  65. },
  66. },
  67. expectLabels: true,
  68. expectSelector: true,
  69. },
  70. {
  71. rc: &v1.ReplicationController{
  72. ObjectMeta: metav1.ObjectMeta{
  73. Labels: map[string]string{
  74. "bar": "foo",
  75. },
  76. },
  77. Spec: v1.ReplicationControllerSpec{
  78. Template: &v1.PodTemplateSpec{
  79. ObjectMeta: metav1.ObjectMeta{
  80. Labels: map[string]string{
  81. "foo": "bar",
  82. },
  83. },
  84. },
  85. },
  86. },
  87. expectLabels: false,
  88. expectSelector: true,
  89. },
  90. {
  91. rc: &v1.ReplicationController{
  92. ObjectMeta: metav1.ObjectMeta{
  93. Labels: map[string]string{
  94. "bar": "foo",
  95. },
  96. },
  97. Spec: v1.ReplicationControllerSpec{
  98. Selector: map[string]string{
  99. "some": "other",
  100. },
  101. Template: &v1.PodTemplateSpec{
  102. ObjectMeta: metav1.ObjectMeta{
  103. Labels: map[string]string{
  104. "foo": "bar",
  105. },
  106. },
  107. },
  108. },
  109. },
  110. expectLabels: false,
  111. expectSelector: false,
  112. },
  113. {
  114. rc: &v1.ReplicationController{
  115. Spec: v1.ReplicationControllerSpec{
  116. Selector: map[string]string{
  117. "some": "other",
  118. },
  119. Template: &v1.PodTemplateSpec{
  120. ObjectMeta: metav1.ObjectMeta{
  121. Labels: map[string]string{
  122. "foo": "bar",
  123. },
  124. },
  125. },
  126. },
  127. },
  128. expectLabels: true,
  129. expectSelector: false,
  130. },
  131. }
  132. for _, test := range tests {
  133. rc := test.rc
  134. obj2 := roundTrip(t, runtime.Object(rc))
  135. rc2, ok := obj2.(*v1.ReplicationController)
  136. if !ok {
  137. t.Errorf("unexpected object: %v", rc2)
  138. t.FailNow()
  139. }
  140. if test.expectSelector != reflect.DeepEqual(rc2.Spec.Selector, rc2.Spec.Template.Labels) {
  141. if test.expectSelector {
  142. t.Errorf("expected: %v, got: %v", rc2.Spec.Template.Labels, rc2.Spec.Selector)
  143. } else {
  144. t.Errorf("unexpected equality: %v", rc.Spec.Selector)
  145. }
  146. }
  147. if test.expectLabels != reflect.DeepEqual(rc2.Labels, rc2.Spec.Template.Labels) {
  148. if test.expectLabels {
  149. t.Errorf("expected: %v, got: %v", rc2.Spec.Template.Labels, rc2.Labels)
  150. } else {
  151. t.Errorf("unexpected equality: %v", rc.Labels)
  152. }
  153. }
  154. }
  155. }
  156. func TestSetDefaultReplicationControllerReplicas(t *testing.T) {
  157. tests := []struct {
  158. rc v1.ReplicationController
  159. expectReplicas int32
  160. }{
  161. {
  162. rc: v1.ReplicationController{
  163. Spec: v1.ReplicationControllerSpec{
  164. Template: &v1.PodTemplateSpec{
  165. ObjectMeta: metav1.ObjectMeta{
  166. Labels: map[string]string{
  167. "foo": "bar",
  168. },
  169. },
  170. },
  171. },
  172. },
  173. expectReplicas: 1,
  174. },
  175. {
  176. rc: v1.ReplicationController{
  177. Spec: v1.ReplicationControllerSpec{
  178. Replicas: utilpointer.Int32Ptr(0),
  179. Template: &v1.PodTemplateSpec{
  180. ObjectMeta: metav1.ObjectMeta{
  181. Labels: map[string]string{
  182. "foo": "bar",
  183. },
  184. },
  185. },
  186. },
  187. },
  188. expectReplicas: 0,
  189. },
  190. {
  191. rc: v1.ReplicationController{
  192. Spec: v1.ReplicationControllerSpec{
  193. Replicas: utilpointer.Int32Ptr(3),
  194. Template: &v1.PodTemplateSpec{
  195. ObjectMeta: metav1.ObjectMeta{
  196. Labels: map[string]string{
  197. "foo": "bar",
  198. },
  199. },
  200. },
  201. },
  202. },
  203. expectReplicas: 3,
  204. },
  205. }
  206. for _, test := range tests {
  207. rc := &test.rc
  208. obj2 := roundTrip(t, runtime.Object(rc))
  209. rc2, ok := obj2.(*v1.ReplicationController)
  210. if !ok {
  211. t.Errorf("unexpected object: %v", rc2)
  212. t.FailNow()
  213. }
  214. if rc2.Spec.Replicas == nil {
  215. t.Errorf("unexpected nil Replicas")
  216. } else if test.expectReplicas != *rc2.Spec.Replicas {
  217. t.Errorf("expected: %d replicas, got: %d", test.expectReplicas, *rc2.Spec.Replicas)
  218. }
  219. }
  220. }
  221. type InitContainerValidator func(got, expected *v1.Container) error
  222. func TestSetDefaultReplicationControllerInitContainers(t *testing.T) {
  223. assertEnvFieldRef := func(got, expected *v1.Container) error {
  224. if len(got.Env) != len(expected.Env) {
  225. return fmt.Errorf("different number of env: got <%v>, expected <%v>", len(got.Env), len(expected.Env))
  226. }
  227. for j := range got.Env {
  228. ge := &got.Env[j]
  229. ee := &expected.Env[j]
  230. if ge.Name != ee.Name {
  231. return fmt.Errorf("different name of env: got <%v>, expected <%v>", ge.Name, ee.Name)
  232. }
  233. if ge.ValueFrom.FieldRef.APIVersion != ee.ValueFrom.FieldRef.APIVersion {
  234. return fmt.Errorf("different api version of FieldRef <%v>: got <%v>, expected <%v>",
  235. ge.Name, ge.ValueFrom.FieldRef.APIVersion, ee.ValueFrom.FieldRef.APIVersion)
  236. }
  237. }
  238. return nil
  239. }
  240. assertImagePullPolicy := func(got, expected *v1.Container) error {
  241. if got.ImagePullPolicy != expected.ImagePullPolicy {
  242. return fmt.Errorf("different image pull poicy: got <%v>, expected <%v>", got.ImagePullPolicy, expected.ImagePullPolicy)
  243. }
  244. return nil
  245. }
  246. assertContainerPort := func(got, expected *v1.Container) error {
  247. if len(got.Ports) != len(expected.Ports) {
  248. return fmt.Errorf("different number of ports: got <%v>, expected <%v>", len(got.Ports), len(expected.Ports))
  249. }
  250. for i := range got.Ports {
  251. gp := &got.Ports[i]
  252. ep := &expected.Ports[i]
  253. if gp.Name != ep.Name {
  254. return fmt.Errorf("different name of port: got <%v>, expected <%v>", gp.Name, ep.Name)
  255. }
  256. if gp.Protocol != ep.Protocol {
  257. return fmt.Errorf("different port protocol <%v>: got <%v>, expected <%v>", gp.Name, gp.Protocol, ep.Protocol)
  258. }
  259. }
  260. return nil
  261. }
  262. assertResource := func(got, expected *v1.Container) error {
  263. if len(got.Resources.Limits) != len(expected.Resources.Limits) {
  264. return fmt.Errorf("different number of resources.Limits: got <%v>, expected <%v>", len(got.Resources.Limits), (expected.Resources.Limits))
  265. }
  266. for k, v := range got.Resources.Limits {
  267. if ev, found := expected.Resources.Limits[v1.ResourceName(k)]; !found {
  268. return fmt.Errorf("failed to find resource <%v> in expected resources.Limits.", k)
  269. } else {
  270. if ev.Value() != v.Value() {
  271. return fmt.Errorf("different resource.Limits: got <%v>, expected <%v>.", v.Value(), ev.Value())
  272. }
  273. }
  274. }
  275. if len(got.Resources.Requests) != len(expected.Resources.Requests) {
  276. return fmt.Errorf("different number of resources.Requests: got <%v>, expected <%v>", len(got.Resources.Requests), (expected.Resources.Requests))
  277. }
  278. for k, v := range got.Resources.Requests {
  279. if ev, found := expected.Resources.Requests[v1.ResourceName(k)]; !found {
  280. return fmt.Errorf("failed to find resource <%v> in expected resources.Requests.", k)
  281. } else {
  282. if ev.Value() != v.Value() {
  283. return fmt.Errorf("different resource.Requests: got <%v>, expected <%v>.", v.Value(), ev.Value())
  284. }
  285. }
  286. }
  287. return nil
  288. }
  289. assertProb := func(got, expected *v1.Container) error {
  290. // Assert LivenessProbe
  291. if got.LivenessProbe.Handler.HTTPGet.Path != expected.LivenessProbe.Handler.HTTPGet.Path ||
  292. got.LivenessProbe.Handler.HTTPGet.Scheme != expected.LivenessProbe.Handler.HTTPGet.Scheme ||
  293. got.LivenessProbe.FailureThreshold != expected.LivenessProbe.FailureThreshold ||
  294. got.LivenessProbe.SuccessThreshold != expected.LivenessProbe.SuccessThreshold ||
  295. got.LivenessProbe.PeriodSeconds != expected.LivenessProbe.PeriodSeconds ||
  296. got.LivenessProbe.TimeoutSeconds != expected.LivenessProbe.TimeoutSeconds {
  297. return fmt.Errorf("different LivenessProbe: got <%v>, expected <%v>", got.LivenessProbe, expected.LivenessProbe)
  298. }
  299. // Assert ReadinessProbe
  300. if got.ReadinessProbe.Handler.HTTPGet.Path != expected.ReadinessProbe.Handler.HTTPGet.Path ||
  301. got.ReadinessProbe.Handler.HTTPGet.Scheme != expected.ReadinessProbe.Handler.HTTPGet.Scheme ||
  302. got.ReadinessProbe.FailureThreshold != expected.ReadinessProbe.FailureThreshold ||
  303. got.ReadinessProbe.SuccessThreshold != expected.ReadinessProbe.SuccessThreshold ||
  304. got.ReadinessProbe.PeriodSeconds != expected.ReadinessProbe.PeriodSeconds ||
  305. got.ReadinessProbe.TimeoutSeconds != expected.ReadinessProbe.TimeoutSeconds {
  306. return fmt.Errorf("different ReadinessProbe: got <%v>, expected <%v>", got.ReadinessProbe, expected.ReadinessProbe)
  307. }
  308. return nil
  309. }
  310. assertLifeCycle := func(got, expected *v1.Container) error {
  311. if got.Lifecycle.PostStart.HTTPGet.Path != expected.Lifecycle.PostStart.HTTPGet.Path ||
  312. got.Lifecycle.PostStart.HTTPGet.Scheme != expected.Lifecycle.PostStart.HTTPGet.Scheme {
  313. return fmt.Errorf("different LifeCycle: got <%v>, expected <%v>", got.Lifecycle, expected.Lifecycle)
  314. }
  315. return nil
  316. }
  317. cpu, _ := resource.ParseQuantity("100m")
  318. mem, _ := resource.ParseQuantity("100Mi")
  319. tests := []struct {
  320. name string
  321. rc v1.ReplicationController
  322. expected []v1.Container
  323. validators []InitContainerValidator
  324. }{
  325. {
  326. name: "imagePullIPolicy",
  327. rc: v1.ReplicationController{
  328. Spec: v1.ReplicationControllerSpec{
  329. Template: &v1.PodTemplateSpec{
  330. Spec: v1.PodSpec{
  331. InitContainers: []v1.Container{
  332. {
  333. Name: "install",
  334. Image: "busybox",
  335. },
  336. },
  337. },
  338. },
  339. },
  340. },
  341. expected: []v1.Container{
  342. {
  343. ImagePullPolicy: v1.PullAlways,
  344. },
  345. },
  346. validators: []InitContainerValidator{assertImagePullPolicy},
  347. },
  348. {
  349. name: "FieldRef",
  350. rc: v1.ReplicationController{
  351. Spec: v1.ReplicationControllerSpec{
  352. Template: &v1.PodTemplateSpec{
  353. Spec: v1.PodSpec{
  354. InitContainers: []v1.Container{
  355. {
  356. Name: "fun",
  357. Image: "alpine",
  358. Env: []v1.EnvVar{
  359. {
  360. Name: "MY_POD_IP",
  361. ValueFrom: &v1.EnvVarSource{
  362. FieldRef: &v1.ObjectFieldSelector{
  363. APIVersion: "",
  364. FieldPath: "status.podIP",
  365. },
  366. },
  367. },
  368. },
  369. },
  370. },
  371. },
  372. },
  373. },
  374. },
  375. expected: []v1.Container{
  376. {
  377. Env: []v1.EnvVar{
  378. {
  379. Name: "MY_POD_IP",
  380. ValueFrom: &v1.EnvVarSource{
  381. FieldRef: &v1.ObjectFieldSelector{
  382. APIVersion: "v1",
  383. FieldPath: "status.podIP",
  384. },
  385. },
  386. },
  387. },
  388. },
  389. },
  390. validators: []InitContainerValidator{assertEnvFieldRef},
  391. },
  392. {
  393. name: "ContainerPort",
  394. rc: v1.ReplicationController{
  395. Spec: v1.ReplicationControllerSpec{
  396. Template: &v1.PodTemplateSpec{
  397. Spec: v1.PodSpec{
  398. InitContainers: []v1.Container{
  399. {
  400. Name: "fun",
  401. Image: "alpine",
  402. Ports: []v1.ContainerPort{
  403. {
  404. Name: "default",
  405. },
  406. },
  407. },
  408. },
  409. },
  410. },
  411. },
  412. },
  413. expected: []v1.Container{
  414. {
  415. Ports: []v1.ContainerPort{
  416. {
  417. Name: "default",
  418. Protocol: v1.ProtocolTCP,
  419. },
  420. },
  421. },
  422. },
  423. validators: []InitContainerValidator{assertContainerPort},
  424. },
  425. {
  426. name: "Resources",
  427. rc: v1.ReplicationController{
  428. Spec: v1.ReplicationControllerSpec{
  429. Template: &v1.PodTemplateSpec{
  430. Spec: v1.PodSpec{
  431. InitContainers: []v1.Container{
  432. {
  433. Name: "fun",
  434. Image: "alpine",
  435. Resources: v1.ResourceRequirements{
  436. Limits: v1.ResourceList{
  437. v1.ResourceCPU: resource.MustParse("100m"),
  438. v1.ResourceMemory: resource.MustParse("100Mi"),
  439. },
  440. Requests: v1.ResourceList{
  441. v1.ResourceCPU: resource.MustParse("100m"),
  442. v1.ResourceMemory: resource.MustParse("100Mi"),
  443. },
  444. },
  445. },
  446. },
  447. },
  448. },
  449. },
  450. },
  451. expected: []v1.Container{
  452. {
  453. Resources: v1.ResourceRequirements{
  454. Limits: v1.ResourceList{
  455. v1.ResourceCPU: cpu,
  456. v1.ResourceMemory: mem,
  457. },
  458. Requests: v1.ResourceList{
  459. v1.ResourceCPU: cpu,
  460. v1.ResourceMemory: mem,
  461. },
  462. },
  463. },
  464. },
  465. validators: []InitContainerValidator{assertResource},
  466. },
  467. {
  468. name: "Probe",
  469. rc: v1.ReplicationController{
  470. Spec: v1.ReplicationControllerSpec{
  471. Template: &v1.PodTemplateSpec{
  472. Spec: v1.PodSpec{
  473. InitContainers: []v1.Container{
  474. {
  475. Name: "fun",
  476. Image: "alpine",
  477. LivenessProbe: &v1.Probe{
  478. Handler: v1.Handler{
  479. HTTPGet: &v1.HTTPGetAction{
  480. Host: "localhost",
  481. },
  482. },
  483. },
  484. ReadinessProbe: &v1.Probe{
  485. Handler: v1.Handler{
  486. HTTPGet: &v1.HTTPGetAction{
  487. Host: "localhost",
  488. },
  489. },
  490. },
  491. },
  492. },
  493. },
  494. },
  495. },
  496. },
  497. expected: []v1.Container{
  498. {
  499. LivenessProbe: &v1.Probe{
  500. Handler: v1.Handler{
  501. HTTPGet: &v1.HTTPGetAction{
  502. Path: "/",
  503. Scheme: v1.URISchemeHTTP,
  504. },
  505. },
  506. TimeoutSeconds: 1,
  507. PeriodSeconds: 10,
  508. SuccessThreshold: 1,
  509. FailureThreshold: 3,
  510. },
  511. ReadinessProbe: &v1.Probe{
  512. Handler: v1.Handler{
  513. HTTPGet: &v1.HTTPGetAction{
  514. Path: "/",
  515. Scheme: v1.URISchemeHTTP,
  516. },
  517. },
  518. TimeoutSeconds: 1,
  519. PeriodSeconds: 10,
  520. SuccessThreshold: 1,
  521. FailureThreshold: 3,
  522. },
  523. },
  524. },
  525. validators: []InitContainerValidator{assertProb},
  526. },
  527. {
  528. name: "LifeCycle",
  529. rc: v1.ReplicationController{
  530. Spec: v1.ReplicationControllerSpec{
  531. Template: &v1.PodTemplateSpec{
  532. Spec: v1.PodSpec{
  533. InitContainers: []v1.Container{
  534. {
  535. Name: "fun",
  536. Image: "alpine",
  537. Ports: []v1.ContainerPort{
  538. {
  539. Name: "default",
  540. },
  541. },
  542. Lifecycle: &v1.Lifecycle{
  543. PostStart: &v1.Handler{
  544. HTTPGet: &v1.HTTPGetAction{
  545. Host: "localhost",
  546. },
  547. },
  548. PreStop: &v1.Handler{
  549. HTTPGet: &v1.HTTPGetAction{
  550. Host: "localhost",
  551. },
  552. },
  553. },
  554. },
  555. },
  556. },
  557. },
  558. },
  559. },
  560. expected: []v1.Container{
  561. {
  562. Lifecycle: &v1.Lifecycle{
  563. PostStart: &v1.Handler{
  564. HTTPGet: &v1.HTTPGetAction{
  565. Path: "/",
  566. Scheme: v1.URISchemeHTTP,
  567. },
  568. },
  569. PreStop: &v1.Handler{
  570. HTTPGet: &v1.HTTPGetAction{
  571. Path: "/",
  572. Scheme: v1.URISchemeHTTP,
  573. },
  574. },
  575. },
  576. },
  577. },
  578. validators: []InitContainerValidator{assertLifeCycle},
  579. },
  580. }
  581. assertInitContainers := func(got, expected []v1.Container, validators []InitContainerValidator) error {
  582. if len(got) != len(expected) {
  583. return fmt.Errorf("different number of init container: got <%d>, expected <%d>",
  584. len(got), len(expected))
  585. }
  586. for i := range got {
  587. g := &got[i]
  588. e := &expected[i]
  589. for _, validator := range validators {
  590. if err := validator(g, e); err != nil {
  591. return err
  592. }
  593. }
  594. }
  595. return nil
  596. }
  597. for _, test := range tests {
  598. rc := &test.rc
  599. obj2 := roundTrip(t, runtime.Object(rc))
  600. rc2, ok := obj2.(*v1.ReplicationController)
  601. if !ok {
  602. t.Errorf("unexpected object: %v", rc2)
  603. t.FailNow()
  604. }
  605. if err := assertInitContainers(rc2.Spec.Template.Spec.InitContainers, test.expected, test.validators); err != nil {
  606. t.Errorf("test %v failed: %v", test.name, err)
  607. }
  608. }
  609. }
  610. func TestSetDefaultService(t *testing.T) {
  611. svc := &v1.Service{}
  612. obj2 := roundTrip(t, runtime.Object(svc))
  613. svc2 := obj2.(*v1.Service)
  614. if svc2.Spec.SessionAffinity != v1.ServiceAffinityNone {
  615. t.Errorf("Expected default session affinity type:%s, got: %s", v1.ServiceAffinityNone, svc2.Spec.SessionAffinity)
  616. }
  617. if svc2.Spec.SessionAffinityConfig != nil {
  618. t.Errorf("Expected empty session affinity config when session affinity type: %s, got: %v", v1.ServiceAffinityNone, svc2.Spec.SessionAffinityConfig)
  619. }
  620. if svc2.Spec.Type != v1.ServiceTypeClusterIP {
  621. t.Errorf("Expected default type:%s, got: %s", v1.ServiceTypeClusterIP, svc2.Spec.Type)
  622. }
  623. }
  624. func TestSetDefaultServiceSessionAffinityConfig(t *testing.T) {
  625. testCases := map[string]v1.Service{
  626. "SessionAffinityConfig is empty": {
  627. Spec: v1.ServiceSpec{
  628. SessionAffinity: v1.ServiceAffinityClientIP,
  629. SessionAffinityConfig: nil,
  630. },
  631. },
  632. "ClientIP is empty": {
  633. Spec: v1.ServiceSpec{
  634. SessionAffinity: v1.ServiceAffinityClientIP,
  635. SessionAffinityConfig: &v1.SessionAffinityConfig{
  636. ClientIP: nil,
  637. },
  638. },
  639. },
  640. "TimeoutSeconds is empty": {
  641. Spec: v1.ServiceSpec{
  642. SessionAffinity: v1.ServiceAffinityClientIP,
  643. SessionAffinityConfig: &v1.SessionAffinityConfig{
  644. ClientIP: &v1.ClientIPConfig{
  645. TimeoutSeconds: nil,
  646. },
  647. },
  648. },
  649. },
  650. }
  651. for name, test := range testCases {
  652. obj2 := roundTrip(t, runtime.Object(&test))
  653. svc2 := obj2.(*v1.Service)
  654. if svc2.Spec.SessionAffinityConfig == nil || svc2.Spec.SessionAffinityConfig.ClientIP == nil || svc2.Spec.SessionAffinityConfig.ClientIP.TimeoutSeconds == nil {
  655. t.Fatalf("Case: %s, unexpected empty SessionAffinityConfig/ClientIP/TimeoutSeconds when session affinity type: %s, got: %v", name, v1.ServiceAffinityClientIP, svc2.Spec.SessionAffinityConfig)
  656. }
  657. if *svc2.Spec.SessionAffinityConfig.ClientIP.TimeoutSeconds != v1.DefaultClientIPServiceAffinitySeconds {
  658. t.Errorf("Case: %s, default TimeoutSeconds should be %d when session affinity type: %s, got: %d", name, v1.DefaultClientIPServiceAffinitySeconds, v1.ServiceAffinityClientIP, *svc2.Spec.SessionAffinityConfig.ClientIP.TimeoutSeconds)
  659. }
  660. }
  661. }
  662. func TestSetDefaultSecretVolumeSource(t *testing.T) {
  663. s := v1.PodSpec{}
  664. s.Volumes = []v1.Volume{
  665. {
  666. VolumeSource: v1.VolumeSource{
  667. Secret: &v1.SecretVolumeSource{},
  668. },
  669. },
  670. }
  671. pod := &v1.Pod{
  672. Spec: s,
  673. }
  674. output := roundTrip(t, runtime.Object(pod))
  675. pod2 := output.(*v1.Pod)
  676. defaultMode := pod2.Spec.Volumes[0].VolumeSource.Secret.DefaultMode
  677. expectedMode := v1.SecretVolumeSourceDefaultMode
  678. if defaultMode == nil || *defaultMode != expectedMode {
  679. t.Errorf("Expected secret DefaultMode %v, got %v", expectedMode, defaultMode)
  680. }
  681. }
  682. func TestSetDefaultConfigMapVolumeSource(t *testing.T) {
  683. s := v1.PodSpec{}
  684. s.Volumes = []v1.Volume{
  685. {
  686. VolumeSource: v1.VolumeSource{
  687. ConfigMap: &v1.ConfigMapVolumeSource{},
  688. },
  689. },
  690. }
  691. pod := &v1.Pod{
  692. Spec: s,
  693. }
  694. output := roundTrip(t, runtime.Object(pod))
  695. pod2 := output.(*v1.Pod)
  696. defaultMode := pod2.Spec.Volumes[0].VolumeSource.ConfigMap.DefaultMode
  697. expectedMode := v1.ConfigMapVolumeSourceDefaultMode
  698. if defaultMode == nil || *defaultMode != expectedMode {
  699. t.Errorf("Expected v1.ConfigMap DefaultMode %v, got %v", expectedMode, defaultMode)
  700. }
  701. }
  702. func TestSetDefaultDownwardAPIVolumeSource(t *testing.T) {
  703. s := v1.PodSpec{}
  704. s.Volumes = []v1.Volume{
  705. {
  706. VolumeSource: v1.VolumeSource{
  707. DownwardAPI: &v1.DownwardAPIVolumeSource{},
  708. },
  709. },
  710. }
  711. pod := &v1.Pod{
  712. Spec: s,
  713. }
  714. output := roundTrip(t, runtime.Object(pod))
  715. pod2 := output.(*v1.Pod)
  716. defaultMode := pod2.Spec.Volumes[0].VolumeSource.DownwardAPI.DefaultMode
  717. expectedMode := v1.DownwardAPIVolumeSourceDefaultMode
  718. if defaultMode == nil || *defaultMode != expectedMode {
  719. t.Errorf("Expected DownwardAPI DefaultMode %v, got %v", expectedMode, defaultMode)
  720. }
  721. }
  722. func TestSetDefaultProjectedVolumeSource(t *testing.T) {
  723. s := v1.PodSpec{}
  724. s.Volumes = []v1.Volume{
  725. {
  726. VolumeSource: v1.VolumeSource{
  727. Projected: &v1.ProjectedVolumeSource{},
  728. },
  729. },
  730. }
  731. pod := &v1.Pod{
  732. Spec: s,
  733. }
  734. output := roundTrip(t, runtime.Object(pod))
  735. pod2 := output.(*v1.Pod)
  736. defaultMode := pod2.Spec.Volumes[0].VolumeSource.Projected.DefaultMode
  737. expectedMode := v1.ProjectedVolumeSourceDefaultMode
  738. if defaultMode == nil || *defaultMode != expectedMode {
  739. t.Errorf("Expected v1.ProjectedVolumeSource DefaultMode %v, got %v", expectedMode, defaultMode)
  740. }
  741. }
  742. func TestSetDefaultSecret(t *testing.T) {
  743. s := &v1.Secret{}
  744. obj2 := roundTrip(t, runtime.Object(s))
  745. s2 := obj2.(*v1.Secret)
  746. if s2.Type != v1.SecretTypeOpaque {
  747. t.Errorf("Expected secret type %v, got %v", v1.SecretTypeOpaque, s2.Type)
  748. }
  749. }
  750. func TestSetDefaultPersistentVolume(t *testing.T) {
  751. fsMode := v1.PersistentVolumeFilesystem
  752. blockMode := v1.PersistentVolumeBlock
  753. tests := []struct {
  754. name string
  755. volumeMode *v1.PersistentVolumeMode
  756. expectedVolumeMode v1.PersistentVolumeMode
  757. }{
  758. {
  759. name: "volume mode nil",
  760. volumeMode: nil,
  761. expectedVolumeMode: v1.PersistentVolumeFilesystem,
  762. },
  763. {
  764. name: "volume mode filesystem",
  765. volumeMode: &fsMode,
  766. expectedVolumeMode: v1.PersistentVolumeFilesystem,
  767. },
  768. {
  769. name: "volume mode block",
  770. volumeMode: &blockMode,
  771. expectedVolumeMode: v1.PersistentVolumeBlock,
  772. },
  773. }
  774. for _, test := range tests {
  775. pv := &v1.PersistentVolume{
  776. Spec: v1.PersistentVolumeSpec{
  777. VolumeMode: test.volumeMode,
  778. },
  779. }
  780. obj1 := roundTrip(t, runtime.Object(pv))
  781. pv1 := obj1.(*v1.PersistentVolume)
  782. if pv1.Status.Phase != v1.VolumePending {
  783. t.Errorf("Expected claim phase %v, got %v", v1.ClaimPending, pv1.Status.Phase)
  784. }
  785. if pv1.Spec.PersistentVolumeReclaimPolicy != v1.PersistentVolumeReclaimRetain {
  786. t.Errorf("Expected pv reclaim policy %v, got %v", v1.PersistentVolumeReclaimRetain, pv1.Spec.PersistentVolumeReclaimPolicy)
  787. }
  788. if *pv1.Spec.VolumeMode != test.expectedVolumeMode {
  789. t.Errorf("Test %s failed, Expected VolumeMode: %v, but got %v", test.name, test.volumeMode, *pv1.Spec.VolumeMode)
  790. }
  791. }
  792. }
  793. func TestSetDefaultPersistentVolumeClaim(t *testing.T) {
  794. fsMode := v1.PersistentVolumeFilesystem
  795. blockMode := v1.PersistentVolumeBlock
  796. tests := []struct {
  797. name string
  798. volumeMode *v1.PersistentVolumeMode
  799. expectedVolumeMode v1.PersistentVolumeMode
  800. }{
  801. {
  802. name: "volume mode nil",
  803. volumeMode: nil,
  804. expectedVolumeMode: v1.PersistentVolumeFilesystem,
  805. },
  806. {
  807. name: "volume mode filesystem",
  808. volumeMode: &fsMode,
  809. expectedVolumeMode: v1.PersistentVolumeFilesystem,
  810. },
  811. {
  812. name: "volume mode block",
  813. volumeMode: &blockMode,
  814. expectedVolumeMode: v1.PersistentVolumeBlock,
  815. },
  816. }
  817. for _, test := range tests {
  818. pvc := &v1.PersistentVolumeClaim{
  819. Spec: v1.PersistentVolumeClaimSpec{
  820. VolumeMode: test.volumeMode,
  821. },
  822. }
  823. obj1 := roundTrip(t, runtime.Object(pvc))
  824. pvc1 := obj1.(*v1.PersistentVolumeClaim)
  825. if pvc1.Status.Phase != v1.ClaimPending {
  826. t.Errorf("Expected claim phase %v, got %v", v1.ClaimPending, pvc1.Status.Phase)
  827. }
  828. if *pvc1.Spec.VolumeMode != test.expectedVolumeMode {
  829. t.Errorf("Test %s failed, Expected VolumeMode: %v, but got %v", test.name, test.volumeMode, *pvc1.Spec.VolumeMode)
  830. }
  831. }
  832. }
  833. func TestSetDefaulEndpointsProtocol(t *testing.T) {
  834. in := &v1.Endpoints{Subsets: []v1.EndpointSubset{
  835. {Ports: []v1.EndpointPort{{}, {Protocol: "UDP"}, {}}},
  836. }}
  837. obj := roundTrip(t, runtime.Object(in))
  838. out := obj.(*v1.Endpoints)
  839. for i := range out.Subsets {
  840. for j := range out.Subsets[i].Ports {
  841. if in.Subsets[i].Ports[j].Protocol == "" {
  842. if out.Subsets[i].Ports[j].Protocol != v1.ProtocolTCP {
  843. t.Errorf("Expected protocol %s, got %s", v1.ProtocolTCP, out.Subsets[i].Ports[j].Protocol)
  844. }
  845. } else {
  846. if out.Subsets[i].Ports[j].Protocol != in.Subsets[i].Ports[j].Protocol {
  847. t.Errorf("Expected protocol %s, got %s", in.Subsets[i].Ports[j].Protocol, out.Subsets[i].Ports[j].Protocol)
  848. }
  849. }
  850. }
  851. }
  852. }
  853. func TestSetDefaulServiceTargetPort(t *testing.T) {
  854. in := &v1.Service{Spec: v1.ServiceSpec{Ports: []v1.ServicePort{{Port: 1234}}}}
  855. obj := roundTrip(t, runtime.Object(in))
  856. out := obj.(*v1.Service)
  857. if out.Spec.Ports[0].TargetPort != intstr.FromInt(1234) {
  858. t.Errorf("Expected TargetPort to be defaulted, got %v", out.Spec.Ports[0].TargetPort)
  859. }
  860. in = &v1.Service{Spec: v1.ServiceSpec{Ports: []v1.ServicePort{{Port: 1234, TargetPort: intstr.FromInt(5678)}}}}
  861. obj = roundTrip(t, runtime.Object(in))
  862. out = obj.(*v1.Service)
  863. if out.Spec.Ports[0].TargetPort != intstr.FromInt(5678) {
  864. t.Errorf("Expected TargetPort to be unchanged, got %v", out.Spec.Ports[0].TargetPort)
  865. }
  866. }
  867. func TestSetDefaultServicePort(t *testing.T) {
  868. // Unchanged if set.
  869. in := &v1.Service{Spec: v1.ServiceSpec{
  870. Ports: []v1.ServicePort{
  871. {Protocol: "UDP", Port: 9376, TargetPort: intstr.FromString("p")},
  872. {Protocol: "UDP", Port: 8675, TargetPort: intstr.FromInt(309)},
  873. },
  874. }}
  875. out := roundTrip(t, runtime.Object(in)).(*v1.Service)
  876. if out.Spec.Ports[0].Protocol != v1.ProtocolUDP {
  877. t.Errorf("Expected protocol %s, got %s", v1.ProtocolUDP, out.Spec.Ports[0].Protocol)
  878. }
  879. if out.Spec.Ports[0].TargetPort != intstr.FromString("p") {
  880. t.Errorf("Expected port %v, got %v", in.Spec.Ports[0].Port, out.Spec.Ports[0].TargetPort)
  881. }
  882. if out.Spec.Ports[1].Protocol != v1.ProtocolUDP {
  883. t.Errorf("Expected protocol %s, got %s", v1.ProtocolUDP, out.Spec.Ports[1].Protocol)
  884. }
  885. if out.Spec.Ports[1].TargetPort != intstr.FromInt(309) {
  886. t.Errorf("Expected port %v, got %v", in.Spec.Ports[1].Port, out.Spec.Ports[1].TargetPort)
  887. }
  888. // Defaulted.
  889. in = &v1.Service{Spec: v1.ServiceSpec{
  890. Ports: []v1.ServicePort{
  891. {Protocol: "", Port: 9376, TargetPort: intstr.FromString("")},
  892. {Protocol: "", Port: 8675, TargetPort: intstr.FromInt(0)},
  893. },
  894. }}
  895. out = roundTrip(t, runtime.Object(in)).(*v1.Service)
  896. if out.Spec.Ports[0].Protocol != v1.ProtocolTCP {
  897. t.Errorf("Expected protocol %s, got %s", v1.ProtocolTCP, out.Spec.Ports[0].Protocol)
  898. }
  899. if out.Spec.Ports[0].TargetPort != intstr.FromInt(int(in.Spec.Ports[0].Port)) {
  900. t.Errorf("Expected port %v, got %v", in.Spec.Ports[0].Port, out.Spec.Ports[0].TargetPort)
  901. }
  902. if out.Spec.Ports[1].Protocol != v1.ProtocolTCP {
  903. t.Errorf("Expected protocol %s, got %s", v1.ProtocolTCP, out.Spec.Ports[1].Protocol)
  904. }
  905. if out.Spec.Ports[1].TargetPort != intstr.FromInt(int(in.Spec.Ports[1].Port)) {
  906. t.Errorf("Expected port %v, got %v", in.Spec.Ports[1].Port, out.Spec.Ports[1].TargetPort)
  907. }
  908. }
  909. func TestSetDefaulServiceExternalTraffic(t *testing.T) {
  910. in := &v1.Service{}
  911. obj := roundTrip(t, runtime.Object(in))
  912. out := obj.(*v1.Service)
  913. if out.Spec.ExternalTrafficPolicy != "" {
  914. t.Errorf("Expected ExternalTrafficPolicy to be empty, got %v", out.Spec.ExternalTrafficPolicy)
  915. }
  916. in = &v1.Service{Spec: v1.ServiceSpec{Type: v1.ServiceTypeNodePort}}
  917. obj = roundTrip(t, runtime.Object(in))
  918. out = obj.(*v1.Service)
  919. if out.Spec.ExternalTrafficPolicy != v1.ServiceExternalTrafficPolicyTypeCluster {
  920. t.Errorf("Expected ExternalTrafficPolicy to be %v, got %v", v1.ServiceExternalTrafficPolicyTypeCluster, out.Spec.ExternalTrafficPolicy)
  921. }
  922. in = &v1.Service{Spec: v1.ServiceSpec{Type: v1.ServiceTypeLoadBalancer}}
  923. obj = roundTrip(t, runtime.Object(in))
  924. out = obj.(*v1.Service)
  925. if out.Spec.ExternalTrafficPolicy != v1.ServiceExternalTrafficPolicyTypeCluster {
  926. t.Errorf("Expected ExternalTrafficPolicy to be %v, got %v", v1.ServiceExternalTrafficPolicyTypeCluster, out.Spec.ExternalTrafficPolicy)
  927. }
  928. }
  929. func TestSetDefaultNamespace(t *testing.T) {
  930. s := &v1.Namespace{}
  931. obj2 := roundTrip(t, runtime.Object(s))
  932. s2 := obj2.(*v1.Namespace)
  933. if s2.Status.Phase != v1.NamespaceActive {
  934. t.Errorf("Expected phase %v, got %v", v1.NamespaceActive, s2.Status.Phase)
  935. }
  936. }
  937. func TestSetDefaultPodSpecHostNetwork(t *testing.T) {
  938. portNum := int32(8080)
  939. s := v1.PodSpec{}
  940. s.HostNetwork = true
  941. s.Containers = []v1.Container{
  942. {
  943. Ports: []v1.ContainerPort{
  944. {
  945. ContainerPort: portNum,
  946. },
  947. },
  948. },
  949. }
  950. s.InitContainers = []v1.Container{
  951. {
  952. Ports: []v1.ContainerPort{
  953. {
  954. ContainerPort: portNum,
  955. },
  956. },
  957. },
  958. }
  959. pod := &v1.Pod{
  960. Spec: s,
  961. }
  962. obj2 := roundTrip(t, runtime.Object(pod))
  963. pod2 := obj2.(*v1.Pod)
  964. s2 := pod2.Spec
  965. hostPortNum := s2.Containers[0].Ports[0].HostPort
  966. if hostPortNum != portNum {
  967. t.Errorf("Expected container port to be defaulted, was made %d instead of %d", hostPortNum, portNum)
  968. }
  969. hostPortNum = s2.InitContainers[0].Ports[0].HostPort
  970. if hostPortNum != portNum {
  971. t.Errorf("Expected container port to be defaulted, was made %d instead of %d", hostPortNum, portNum)
  972. }
  973. }
  974. func TestSetDefaultNodeStatusAllocatable(t *testing.T) {
  975. capacity := v1.ResourceList{
  976. v1.ResourceCPU: resource.MustParse("1000m"),
  977. v1.ResourceMemory: resource.MustParse("10G"),
  978. }
  979. allocatable := v1.ResourceList{
  980. v1.ResourceCPU: resource.MustParse("500m"),
  981. v1.ResourceMemory: resource.MustParse("5G"),
  982. }
  983. tests := []struct {
  984. capacity v1.ResourceList
  985. allocatable v1.ResourceList
  986. expectedAllocatable v1.ResourceList
  987. }{{ // Everything set, no defaulting.
  988. capacity: capacity,
  989. allocatable: allocatable,
  990. expectedAllocatable: allocatable,
  991. }, { // Allocatable set, no defaulting.
  992. capacity: nil,
  993. allocatable: allocatable,
  994. expectedAllocatable: allocatable,
  995. }, { // Capacity set, allocatable defaults to capacity.
  996. capacity: capacity,
  997. allocatable: nil,
  998. expectedAllocatable: capacity,
  999. }, { // Nothing set, allocatable "defaults" to capacity.
  1000. capacity: nil,
  1001. allocatable: nil,
  1002. expectedAllocatable: nil,
  1003. }}
  1004. copyResourceList := func(rl v1.ResourceList) v1.ResourceList {
  1005. if rl == nil {
  1006. return nil
  1007. }
  1008. copy := make(v1.ResourceList, len(rl))
  1009. for k, v := range rl {
  1010. copy[k] = *v.Copy()
  1011. }
  1012. return copy
  1013. }
  1014. resourceListsEqual := func(a v1.ResourceList, b v1.ResourceList) bool {
  1015. if len(a) != len(b) {
  1016. return false
  1017. }
  1018. for k, v := range a {
  1019. vb, found := b[k]
  1020. if !found {
  1021. return false
  1022. }
  1023. if v.Cmp(vb) != 0 {
  1024. return false
  1025. }
  1026. }
  1027. return true
  1028. }
  1029. for i, testcase := range tests {
  1030. node := v1.Node{
  1031. Status: v1.NodeStatus{
  1032. Capacity: copyResourceList(testcase.capacity),
  1033. Allocatable: copyResourceList(testcase.allocatable),
  1034. },
  1035. }
  1036. node2 := roundTrip(t, runtime.Object(&node)).(*v1.Node)
  1037. actual := node2.Status.Allocatable
  1038. expected := testcase.expectedAllocatable
  1039. if !resourceListsEqual(expected, actual) {
  1040. t.Errorf("[%d] Expected v1.NodeStatus.Allocatable: %+v; Got: %+v", i, expected, actual)
  1041. }
  1042. }
  1043. }
  1044. func TestSetDefaultObjectFieldSelectorAPIVersion(t *testing.T) {
  1045. s := v1.PodSpec{
  1046. Containers: []v1.Container{
  1047. {
  1048. Env: []v1.EnvVar{
  1049. {
  1050. ValueFrom: &v1.EnvVarSource{
  1051. FieldRef: &v1.ObjectFieldSelector{},
  1052. },
  1053. },
  1054. },
  1055. },
  1056. },
  1057. }
  1058. pod := &v1.Pod{
  1059. Spec: s,
  1060. }
  1061. obj2 := roundTrip(t, runtime.Object(pod))
  1062. pod2 := obj2.(*v1.Pod)
  1063. s2 := pod2.Spec
  1064. apiVersion := s2.Containers[0].Env[0].ValueFrom.FieldRef.APIVersion
  1065. if apiVersion != "v1" {
  1066. t.Errorf("Expected default APIVersion v1, got: %v", apiVersion)
  1067. }
  1068. }
  1069. func TestSetMinimumScalePod(t *testing.T) {
  1070. // verify we default if limits are specified (and that request=0 is preserved)
  1071. s := v1.PodSpec{}
  1072. s.Containers = []v1.Container{
  1073. {
  1074. Resources: v1.ResourceRequirements{
  1075. Requests: v1.ResourceList{
  1076. v1.ResourceMemory: resource.MustParse("1n"),
  1077. },
  1078. Limits: v1.ResourceList{
  1079. v1.ResourceCPU: resource.MustParse("2n"),
  1080. },
  1081. },
  1082. },
  1083. }
  1084. s.InitContainers = []v1.Container{
  1085. {
  1086. Resources: v1.ResourceRequirements{
  1087. Requests: v1.ResourceList{
  1088. v1.ResourceMemory: resource.MustParse("1n"),
  1089. },
  1090. Limits: v1.ResourceList{
  1091. v1.ResourceCPU: resource.MustParse("2n"),
  1092. },
  1093. },
  1094. },
  1095. }
  1096. pod := &v1.Pod{
  1097. Spec: s,
  1098. }
  1099. corev1.SetObjectDefaults_Pod(pod)
  1100. if expect := resource.MustParse("1m"); expect.Cmp(pod.Spec.Containers[0].Resources.Requests[v1.ResourceMemory]) != 0 {
  1101. t.Errorf("did not round resources: %#v", pod.Spec.Containers[0].Resources)
  1102. }
  1103. if expect := resource.MustParse("1m"); expect.Cmp(pod.Spec.InitContainers[0].Resources.Requests[v1.ResourceMemory]) != 0 {
  1104. t.Errorf("did not round resources: %#v", pod.Spec.InitContainers[0].Resources)
  1105. }
  1106. }
  1107. func TestSetDefaultRequestsPod(t *testing.T) {
  1108. // verify we default if limits are specified (and that request=0 is preserved)
  1109. s := v1.PodSpec{}
  1110. s.Containers = []v1.Container{
  1111. {
  1112. Resources: v1.ResourceRequirements{
  1113. Requests: v1.ResourceList{
  1114. v1.ResourceMemory: resource.MustParse("0"),
  1115. },
  1116. Limits: v1.ResourceList{
  1117. v1.ResourceCPU: resource.MustParse("100m"),
  1118. v1.ResourceMemory: resource.MustParse("1Gi"),
  1119. },
  1120. },
  1121. },
  1122. }
  1123. s.InitContainers = []v1.Container{
  1124. {
  1125. Resources: v1.ResourceRequirements{
  1126. Requests: v1.ResourceList{
  1127. v1.ResourceMemory: resource.MustParse("0"),
  1128. },
  1129. Limits: v1.ResourceList{
  1130. v1.ResourceCPU: resource.MustParse("100m"),
  1131. v1.ResourceMemory: resource.MustParse("1Gi"),
  1132. },
  1133. },
  1134. },
  1135. }
  1136. pod := &v1.Pod{
  1137. Spec: s,
  1138. }
  1139. output := roundTrip(t, runtime.Object(pod))
  1140. pod2 := output.(*v1.Pod)
  1141. defaultRequest := pod2.Spec.Containers[0].Resources.Requests
  1142. if requestValue := defaultRequest[v1.ResourceCPU]; requestValue.String() != "100m" {
  1143. t.Errorf("Expected request cpu: %s, got: %s", "100m", requestValue.String())
  1144. }
  1145. if requestValue := defaultRequest[v1.ResourceMemory]; requestValue.String() != "0" {
  1146. t.Errorf("Expected request memory: %s, got: %s", "0", requestValue.String())
  1147. }
  1148. defaultRequest = pod2.Spec.InitContainers[0].Resources.Requests
  1149. if requestValue := defaultRequest[v1.ResourceCPU]; requestValue.String() != "100m" {
  1150. t.Errorf("Expected request cpu: %s, got: %s", "100m", requestValue.String())
  1151. }
  1152. if requestValue := defaultRequest[v1.ResourceMemory]; requestValue.String() != "0" {
  1153. t.Errorf("Expected request memory: %s, got: %s", "0", requestValue.String())
  1154. }
  1155. // verify we do nothing if no limits are specified
  1156. s = v1.PodSpec{}
  1157. s.Containers = []v1.Container{{}}
  1158. s.InitContainers = []v1.Container{{}}
  1159. pod = &v1.Pod{
  1160. Spec: s,
  1161. }
  1162. output = roundTrip(t, runtime.Object(pod))
  1163. pod2 = output.(*v1.Pod)
  1164. defaultRequest = pod2.Spec.Containers[0].Resources.Requests
  1165. if requestValue := defaultRequest[v1.ResourceCPU]; requestValue.String() != "0" {
  1166. t.Errorf("Expected 0 request value, got: %s", requestValue.String())
  1167. }
  1168. defaultRequest = pod2.Spec.InitContainers[0].Resources.Requests
  1169. if requestValue := defaultRequest[v1.ResourceCPU]; requestValue.String() != "0" {
  1170. t.Errorf("Expected 0 request value, got: %s", requestValue.String())
  1171. }
  1172. }
  1173. func TestDefaultRequestIsNotSetForReplicationController(t *testing.T) {
  1174. s := v1.PodSpec{}
  1175. s.Containers = []v1.Container{
  1176. {
  1177. Resources: v1.ResourceRequirements{
  1178. Limits: v1.ResourceList{
  1179. v1.ResourceCPU: resource.MustParse("100m"),
  1180. },
  1181. },
  1182. },
  1183. }
  1184. rc := &v1.ReplicationController{
  1185. Spec: v1.ReplicationControllerSpec{
  1186. Replicas: utilpointer.Int32Ptr(3),
  1187. Template: &v1.PodTemplateSpec{
  1188. ObjectMeta: metav1.ObjectMeta{
  1189. Labels: map[string]string{
  1190. "foo": "bar",
  1191. },
  1192. },
  1193. Spec: s,
  1194. },
  1195. },
  1196. }
  1197. output := roundTrip(t, runtime.Object(rc))
  1198. rc2 := output.(*v1.ReplicationController)
  1199. defaultRequest := rc2.Spec.Template.Spec.Containers[0].Resources.Requests
  1200. requestValue := defaultRequest[v1.ResourceCPU]
  1201. if requestValue.String() != "0" {
  1202. t.Errorf("Expected 0 request value, got: %s", requestValue.String())
  1203. }
  1204. }
  1205. func TestSetDefaultLimitRangeItem(t *testing.T) {
  1206. limitRange := &v1.LimitRange{
  1207. ObjectMeta: metav1.ObjectMeta{
  1208. Name: "test-defaults",
  1209. },
  1210. Spec: v1.LimitRangeSpec{
  1211. Limits: []v1.LimitRangeItem{{
  1212. Type: v1.LimitTypeContainer,
  1213. Max: v1.ResourceList{
  1214. v1.ResourceCPU: resource.MustParse("100m"),
  1215. },
  1216. Min: v1.ResourceList{
  1217. v1.ResourceMemory: resource.MustParse("100Mi"),
  1218. },
  1219. Default: v1.ResourceList{},
  1220. DefaultRequest: v1.ResourceList{},
  1221. }},
  1222. },
  1223. }
  1224. output := roundTrip(t, runtime.Object(limitRange))
  1225. limitRange2 := output.(*v1.LimitRange)
  1226. defaultLimit := limitRange2.Spec.Limits[0].Default
  1227. defaultRequest := limitRange2.Spec.Limits[0].DefaultRequest
  1228. // verify that default cpu was set to the max
  1229. defaultValue := defaultLimit[v1.ResourceCPU]
  1230. if defaultValue.String() != "100m" {
  1231. t.Errorf("Expected default cpu: %s, got: %s", "100m", defaultValue.String())
  1232. }
  1233. // verify that default request was set to the limit
  1234. requestValue := defaultRequest[v1.ResourceCPU]
  1235. if requestValue.String() != "100m" {
  1236. t.Errorf("Expected request cpu: %s, got: %s", "100m", requestValue.String())
  1237. }
  1238. // verify that if a min is provided, it will be the default if no limit is specified
  1239. requestMinValue := defaultRequest[v1.ResourceMemory]
  1240. if requestMinValue.String() != "100Mi" {
  1241. t.Errorf("Expected request memory: %s, got: %s", "100Mi", requestMinValue.String())
  1242. }
  1243. }
  1244. func TestSetDefaultProbe(t *testing.T) {
  1245. originalProbe := v1.Probe{}
  1246. expectedProbe := v1.Probe{
  1247. InitialDelaySeconds: 0,
  1248. TimeoutSeconds: 1,
  1249. PeriodSeconds: 10,
  1250. SuccessThreshold: 1,
  1251. FailureThreshold: 3,
  1252. }
  1253. pod := &v1.Pod{
  1254. Spec: v1.PodSpec{
  1255. Containers: []v1.Container{{LivenessProbe: &originalProbe}},
  1256. },
  1257. }
  1258. output := roundTrip(t, runtime.Object(pod)).(*v1.Pod)
  1259. actualProbe := *output.Spec.Containers[0].LivenessProbe
  1260. if actualProbe != expectedProbe {
  1261. t.Errorf("Expected probe: %+v\ngot: %+v\n", expectedProbe, actualProbe)
  1262. }
  1263. }
  1264. func TestSetDefaultSchedulerName(t *testing.T) {
  1265. pod := &v1.Pod{}
  1266. output := roundTrip(t, runtime.Object(pod)).(*v1.Pod)
  1267. if output.Spec.SchedulerName != v1.DefaultSchedulerName {
  1268. t.Errorf("Expected scheduler name: %+v\ngot: %+v\n", v1.DefaultSchedulerName, output.Spec.SchedulerName)
  1269. }
  1270. }
  1271. func TestSetDefaultHostPathVolumeSource(t *testing.T) {
  1272. s := v1.PodSpec{}
  1273. s.Volumes = []v1.Volume{
  1274. {
  1275. VolumeSource: v1.VolumeSource{
  1276. HostPath: &v1.HostPathVolumeSource{Path: "foo"},
  1277. },
  1278. },
  1279. }
  1280. pod := &v1.Pod{
  1281. Spec: s,
  1282. }
  1283. output := roundTrip(t, runtime.Object(pod))
  1284. pod2 := output.(*v1.Pod)
  1285. defaultType := pod2.Spec.Volumes[0].VolumeSource.HostPath.Type
  1286. expectedType := v1.HostPathUnset
  1287. if defaultType == nil || *defaultType != expectedType {
  1288. t.Errorf("Expected v1.HostPathVolumeSource default type %v, got %v", expectedType, defaultType)
  1289. }
  1290. }
  1291. func TestSetDefaultEnableServiceLinks(t *testing.T) {
  1292. pod := &v1.Pod{}
  1293. output := roundTrip(t, runtime.Object(pod)).(*v1.Pod)
  1294. if output.Spec.EnableServiceLinks == nil || *output.Spec.EnableServiceLinks != v1.DefaultEnableServiceLinks {
  1295. t.Errorf("Expected enableServiceLinks value: %+v\ngot: %+v\n", v1.DefaultEnableServiceLinks, *output.Spec.EnableServiceLinks)
  1296. }
  1297. }