merge_primitive_test.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541
  1. /*
  2. Copyright 2017 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 strategy_test
  14. import (
  15. . "github.com/onsi/ginkgo"
  16. "k8s.io/kubernetes/pkg/kubectl/apply/strategy"
  17. )
  18. var _ = Describe("Merging fields of type map with openapi", func() {
  19. Context("where a field has been deleted", func() {
  20. It("should delete the field when it is the only field in the map", func() {
  21. recorded := create(`
  22. apiVersion: apps/v1
  23. kind: Deployment
  24. spec:
  25. # delete - recorded/remote match
  26. paused: true
  27. # delete - recorded/remote differ
  28. progressDeadlineSeconds: 1
  29. `)
  30. local := create(`
  31. apiVersion: apps/v1
  32. kind: Deployment
  33. spec:
  34. # delete - not present in recorded
  35. replicas: null
  36. `)
  37. remote := create(`
  38. apiVersion: apps/v1
  39. kind: Deployment
  40. spec:
  41. replicas: 3
  42. paused: true
  43. progressDeadlineSeconds: 2
  44. `)
  45. expected := create(`
  46. apiVersion: apps/v1
  47. kind: Deployment
  48. spec:
  49. `)
  50. run(strategy.Create(strategy.Options{}), recorded, local, remote, expected)
  51. })
  52. It("should delete the field when there are other fields in the map", func() {
  53. recorded := create(`
  54. apiVersion: apps/v1
  55. kind: Deployment
  56. spec:
  57. # delete - recorded/remote match
  58. paused: true
  59. # delete - recorded/remote differ
  60. progressDeadlineSeconds: 1
  61. `)
  62. local := create(`
  63. apiVersion: apps/v1
  64. kind: Deployment
  65. spec:
  66. # delete - not present in recorded
  67. replicas: null
  68. # keep
  69. revisionHistoryLimit: 1
  70. `)
  71. remote := create(`
  72. apiVersion: apps/v1
  73. kind: Deployment
  74. spec:
  75. replicas: 3
  76. paused: true
  77. progressDeadlineSeconds: 2
  78. revisionHistoryLimit: 1
  79. `)
  80. expected := create(`
  81. apiVersion: apps/v1
  82. kind: Deployment
  83. spec:
  84. revisionHistoryLimit: 1
  85. `)
  86. run(strategy.Create(strategy.Options{}), recorded, local, remote, expected)
  87. })
  88. })
  89. Context("where a field is has been added", func() {
  90. It("should add the field", func() {
  91. recorded := create(`
  92. apiVersion: apps/v1
  93. kind: Deployment
  94. spec:
  95. paused: true
  96. progressDeadlineSeconds: 1
  97. `)
  98. local := create(`
  99. apiVersion: apps/v1
  100. kind: Deployment
  101. spec:
  102. # Add this - it is missing from recorded and remote
  103. replicas: 3
  104. # Add this - it is missing from remote but matches recorded
  105. paused: true
  106. # Add this - it is missing from remote and differs from recorded
  107. progressDeadlineSeconds: 2
  108. `)
  109. remote := create(`
  110. apiVersion: apps/v1
  111. kind: Deployment
  112. spec:
  113. `)
  114. expected := create(`
  115. apiVersion: apps/v1
  116. kind: Deployment
  117. spec:
  118. replicas: 3
  119. paused: true
  120. progressDeadlineSeconds: 2
  121. `)
  122. run(strategy.Create(strategy.Options{}), recorded, local, remote, expected)
  123. })
  124. })
  125. Context("where a field is has been updated", func() {
  126. It("should add the field", func() {
  127. recorded := create(`
  128. apiVersion: apps/v1
  129. kind: Deployment
  130. spec:
  131. paused: true
  132. progressDeadlineSeconds: 1
  133. `)
  134. local := create(`
  135. apiVersion: apps/v1
  136. kind: Deployment
  137. spec:
  138. # Missing from recorded
  139. replicas: 3
  140. # Matches the recorded
  141. paused: true
  142. # Differs from recorded
  143. progressDeadlineSeconds: 2
  144. `)
  145. remote := create(`
  146. apiVersion: apps/v1
  147. kind: Deployment
  148. spec:
  149. replicas: 2
  150. paused: false
  151. progressDeadlineSeconds: 3
  152. `)
  153. expected := create(`
  154. apiVersion: apps/v1
  155. kind: Deployment
  156. spec:
  157. replicas: 3
  158. paused: true
  159. progressDeadlineSeconds: 2
  160. `)
  161. run(strategy.Create(strategy.Options{}), recorded, local, remote, expected)
  162. })
  163. It("should update the field", func() {
  164. recorded := create(`
  165. apiVersion: apps/v1
  166. kind: Deployment
  167. spec:
  168. replicas: 2
  169. `)
  170. local := create(`
  171. apiVersion: apps/v1
  172. kind: Deployment
  173. spec:
  174. replicas: 3
  175. `)
  176. remote := create(`
  177. apiVersion: apps/v1
  178. kind: Deployment
  179. spec:
  180. replicas: 2
  181. `)
  182. expected := create(`
  183. apiVersion: apps/v1
  184. kind: Deployment
  185. spec:
  186. replicas: 3
  187. `)
  188. run(strategy.Create(strategy.Options{}), recorded, local, remote, expected)
  189. })
  190. })
  191. })
  192. var _ = Describe("Merging fields of type map without openapi", func() {
  193. Context("where a field has been deleted", func() {
  194. It("should delete the field when it is the only field in the map", func() {
  195. recorded := create(`
  196. apiVersion: apps/v1
  197. kind: Foo
  198. spec:
  199. # delete - recorded/remote match
  200. paused: true
  201. # delete - recorded/remote differ
  202. progressDeadlineSeconds: 1
  203. `)
  204. local := create(`
  205. apiVersion: apps/v1
  206. kind: Foo
  207. spec:
  208. # delete - not present in recorded
  209. replicas: null
  210. `)
  211. remote := create(`
  212. apiVersion: apps/v1
  213. kind: Foo
  214. spec:
  215. replicas: 3
  216. paused: true
  217. progressDeadlineSeconds: 2
  218. `)
  219. expected := create(`
  220. apiVersion: apps/v1
  221. kind: Foo
  222. spec:
  223. `)
  224. run(strategy.Create(strategy.Options{}), recorded, local, remote, expected)
  225. })
  226. It("should delete the field when there are other fields in the map", func() {
  227. recorded := create(`
  228. apiVersion: apps/v1
  229. kind: Foo
  230. spec:
  231. # delete - recorded/remote match
  232. paused: true
  233. # delete - recorded/remote differ
  234. progressDeadlineSeconds: 1
  235. `)
  236. local := create(`
  237. apiVersion: apps/v1
  238. kind: Foo
  239. spec:
  240. # delete - not present in recorded
  241. replicas: null
  242. # keep
  243. revisionHistoryLimit: 1
  244. `)
  245. remote := create(`
  246. apiVersion: apps/v1
  247. kind: Foo
  248. spec:
  249. replicas: 3
  250. paused: true
  251. progressDeadlineSeconds: 2
  252. revisionHistoryLimit: 1
  253. `)
  254. expected := create(`
  255. apiVersion: apps/v1
  256. kind: Foo
  257. spec:
  258. revisionHistoryLimit: 1
  259. `)
  260. run(strategy.Create(strategy.Options{}), recorded, local, remote, expected)
  261. })
  262. })
  263. Context("where a field is has been added", func() {
  264. It("should add the field", func() {
  265. recorded := create(`
  266. apiVersion: apps/v1
  267. kind: Foo
  268. spec:
  269. paused: true
  270. progressDeadlineSeconds: 1
  271. `)
  272. local := create(`
  273. apiVersion: apps/v1
  274. kind: Foo
  275. spec:
  276. # Add this - it is missing from recorded and remote
  277. replicas: 3
  278. # Add this - it is missing from remote but matches recorded
  279. paused: true
  280. # Add this - it is missing from remote and differs from recorded
  281. progressDeadlineSeconds: 2
  282. `)
  283. remote := create(`
  284. apiVersion: apps/v1
  285. kind: Foo
  286. spec:
  287. `)
  288. expected := create(`
  289. apiVersion: apps/v1
  290. kind: Foo
  291. spec:
  292. replicas: 3
  293. paused: true
  294. progressDeadlineSeconds: 2
  295. `)
  296. run(strategy.Create(strategy.Options{}), recorded, local, remote, expected)
  297. })
  298. })
  299. Context("where a field is has been updated", func() {
  300. It("should add the field", func() {
  301. recorded := create(`
  302. apiVersion: apps/v1
  303. kind: Foo
  304. spec:
  305. paused: true
  306. progressDeadlineSeconds: 1
  307. `)
  308. local := create(`
  309. apiVersion: apps/v1
  310. kind: Foo
  311. spec:
  312. # Matches recorded
  313. replicas: 3
  314. # Matches the recorded
  315. paused: true
  316. # Differs from recorded
  317. progressDeadlineSeconds: 2
  318. `)
  319. remote := create(`
  320. apiVersion: apps/v1
  321. kind: Foo
  322. spec:
  323. replicas: 2
  324. paused: false
  325. progressDeadlineSeconds: 3
  326. `)
  327. expected := create(`
  328. apiVersion: apps/v1
  329. kind: Foo
  330. spec:
  331. replicas: 3
  332. paused: true
  333. progressDeadlineSeconds: 2
  334. `)
  335. run(strategy.Create(strategy.Options{}), recorded, local, remote, expected)
  336. })
  337. It("should update the field", func() {
  338. recorded := create(`
  339. apiVersion: apps/v1
  340. kind: Foo
  341. spec:
  342. replicas: 2
  343. `)
  344. local := create(`
  345. apiVersion: apps/v1
  346. kind: Foo
  347. spec:
  348. replicas: 3
  349. `)
  350. remote := create(`
  351. apiVersion: apps/v1
  352. kind: Foo
  353. spec:
  354. replicas: 2
  355. `)
  356. expected := create(`
  357. apiVersion: apps/v1
  358. kind: Foo
  359. spec:
  360. replicas: 3
  361. `)
  362. run(strategy.Create(strategy.Options{}), recorded, local, remote, expected)
  363. })
  364. })
  365. })
  366. var _ = Describe("Merging fields of type map with openapi", func() {
  367. Context("where a field has been deleted", func() {
  368. It("should delete the field when it is the only field in the map", func() {
  369. recorded := create(`
  370. apiVersion: apps/v1
  371. kind: Deployment
  372. spec:
  373. # delete - recorded/remote match
  374. foo: true
  375. # delete - recorded/remote differ
  376. bar: 1
  377. `)
  378. local := create(`
  379. apiVersion: apps/v1
  380. kind: Deployment
  381. spec:
  382. # delete - not present in recorded
  383. baz: null
  384. `)
  385. remote := create(`
  386. apiVersion: apps/v1
  387. kind: Deployment
  388. spec:
  389. baz: 3
  390. foo: true
  391. bar: 2
  392. `)
  393. expected := create(`
  394. apiVersion: apps/v1
  395. kind: Deployment
  396. spec:
  397. `)
  398. run(strategy.Create(strategy.Options{}), recorded, local, remote, expected)
  399. })
  400. It("should delete the field when there are other fields in the map", func() {
  401. recorded := create(`
  402. apiVersion: apps/v1
  403. kind: Deployment
  404. spec:
  405. # delete - recorded/remote match
  406. foo: true
  407. # delete - recorded/remote differ
  408. bar: 1
  409. `)
  410. local := create(`
  411. apiVersion: apps/v1
  412. kind: Deployment
  413. spec:
  414. # delete - not present in recorded
  415. baz: null
  416. # keep
  417. biz: 1
  418. `)
  419. remote := create(`
  420. apiVersion: apps/v1
  421. kind: Deployment
  422. spec:
  423. bar: 3
  424. foo: true
  425. baz: 2
  426. biz: 1
  427. `)
  428. expected := create(`
  429. apiVersion: apps/v1
  430. kind: Deployment
  431. spec:
  432. biz: 1
  433. `)
  434. run(strategy.Create(strategy.Options{}), recorded, local, remote, expected)
  435. })
  436. })
  437. Context("where a field is has been added", func() {
  438. It("should add the field", func() {
  439. recorded := create(`
  440. apiVersion: apps/v1
  441. kind: Deployment
  442. spec:
  443. foo: true
  444. biz: 1
  445. `)
  446. local := create(`
  447. apiVersion: apps/v1
  448. kind: Deployment
  449. spec:
  450. # Add this - it is missing from recorded and remote
  451. baz: 3
  452. # Add this - it is missing from remote but matches recorded
  453. foo: true
  454. # Add this - it is missing from remote and differs from recorded
  455. biz: 2
  456. `)
  457. remote := create(`
  458. apiVersion: apps/v1
  459. kind: Deployment
  460. spec:
  461. `)
  462. expected := create(`
  463. apiVersion: apps/v1
  464. kind: Deployment
  465. spec:
  466. baz: 3
  467. foo: true
  468. biz: 2
  469. `)
  470. run(strategy.Create(strategy.Options{}), recorded, local, remote, expected)
  471. })
  472. })
  473. Context("where a field is has been updated", func() {
  474. It("should add the field", func() {
  475. recorded := create(`
  476. apiVersion: apps/v1
  477. kind: Deployment
  478. spec:
  479. foo: true
  480. baz: 1
  481. `)
  482. local := create(`
  483. apiVersion: apps/v1
  484. kind: Deployment
  485. spec:
  486. # Missing from recorded
  487. bar: 3
  488. # Matches the recorded
  489. foo: true
  490. # Differs from recorded
  491. baz: 2
  492. `)
  493. remote := create(`
  494. apiVersion: apps/v1
  495. kind: Deployment
  496. spec:
  497. bar: 2
  498. foo: false
  499. baz: 3
  500. `)
  501. expected := create(`
  502. apiVersion: apps/v1
  503. kind: Deployment
  504. spec:
  505. bar: 3
  506. foo: true
  507. baz: 2
  508. `)
  509. run(strategy.Create(strategy.Options{}), recorded, local, remote, expected)
  510. })
  511. })
  512. })