patch_test.go 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118
  1. /*
  2. Copyright 2014 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 strategicpatch
  14. import (
  15. "encoding/json"
  16. "fmt"
  17. "reflect"
  18. "strings"
  19. "testing"
  20. "github.com/davecgh/go-spew/spew"
  21. "github.com/ghodss/yaml"
  22. )
  23. type SortMergeListTestCases struct {
  24. TestCases []SortMergeListTestCase
  25. }
  26. type SortMergeListTestCase struct {
  27. Description string
  28. Original map[string]interface{}
  29. Sorted map[string]interface{}
  30. }
  31. type StrategicMergePatchTestCases struct {
  32. TestCases []StrategicMergePatchTestCase
  33. }
  34. type StrategicMergePatchTestCase struct {
  35. Description string
  36. StrategicMergePatchTestCaseData
  37. }
  38. type StrategicMergePatchTestCaseData struct {
  39. Original map[string]interface{}
  40. TwoWay map[string]interface{}
  41. Modified map[string]interface{}
  42. Current map[string]interface{}
  43. ThreeWay map[string]interface{}
  44. Result map[string]interface{}
  45. }
  46. type MergeItem struct {
  47. Name string
  48. Value string
  49. Other string
  50. MergingList []MergeItem `patchStrategy:"merge" patchMergeKey:"name"`
  51. NonMergingList []MergeItem
  52. MergingIntList []int `patchStrategy:"merge"`
  53. NonMergingIntList []int
  54. MergeItemPtr *MergeItem `patchStrategy:"merge" patchMergeKey:"name"`
  55. SimpleMap map[string]string
  56. }
  57. var mergeItem MergeItem
  58. // These are test cases for SortMergeList, used to assert that it (recursively)
  59. // sorts both merging and non merging lists correctly.
  60. var sortMergeListTestCaseData = []byte(`
  61. testCases:
  62. - description: sort one list of maps
  63. original:
  64. mergingList:
  65. - name: 1
  66. - name: 3
  67. - name: 2
  68. sorted:
  69. mergingList:
  70. - name: 1
  71. - name: 2
  72. - name: 3
  73. - description: sort lists of maps but not nested lists of maps
  74. original:
  75. mergingList:
  76. - name: 2
  77. nonMergingList:
  78. - name: 1
  79. - name: 3
  80. - name: 2
  81. - name: 1
  82. nonMergingList:
  83. - name: 2
  84. - name: 1
  85. sorted:
  86. mergingList:
  87. - name: 1
  88. nonMergingList:
  89. - name: 2
  90. - name: 1
  91. - name: 2
  92. nonMergingList:
  93. - name: 1
  94. - name: 3
  95. - name: 2
  96. - description: sort lists of maps and nested lists of maps
  97. fieldTypes:
  98. original:
  99. mergingList:
  100. - name: 2
  101. mergingList:
  102. - name: 1
  103. - name: 3
  104. - name: 2
  105. - name: 1
  106. mergingList:
  107. - name: 2
  108. - name: 1
  109. sorted:
  110. mergingList:
  111. - name: 1
  112. mergingList:
  113. - name: 1
  114. - name: 2
  115. - name: 2
  116. mergingList:
  117. - name: 1
  118. - name: 2
  119. - name: 3
  120. - description: merging list should NOT sort when nested in non merging list
  121. original:
  122. nonMergingList:
  123. - name: 2
  124. mergingList:
  125. - name: 1
  126. - name: 3
  127. - name: 2
  128. - name: 1
  129. mergingList:
  130. - name: 2
  131. - name: 1
  132. sorted:
  133. nonMergingList:
  134. - name: 2
  135. mergingList:
  136. - name: 1
  137. - name: 3
  138. - name: 2
  139. - name: 1
  140. mergingList:
  141. - name: 2
  142. - name: 1
  143. - description: sort very nested list of maps
  144. fieldTypes:
  145. original:
  146. mergingList:
  147. - mergingList:
  148. - mergingList:
  149. - name: 2
  150. - name: 1
  151. sorted:
  152. mergingList:
  153. - mergingList:
  154. - mergingList:
  155. - name: 1
  156. - name: 2
  157. - description: sort nested lists of ints
  158. original:
  159. mergingList:
  160. - name: 2
  161. mergingIntList:
  162. - 1
  163. - 3
  164. - 2
  165. - name: 1
  166. mergingIntList:
  167. - 2
  168. - 1
  169. sorted:
  170. mergingList:
  171. - name: 1
  172. mergingIntList:
  173. - 1
  174. - 2
  175. - name: 2
  176. mergingIntList:
  177. - 1
  178. - 2
  179. - 3
  180. - description: sort nested pointers of ints
  181. original:
  182. mergeItemPtr:
  183. - name: 2
  184. mergingIntList:
  185. - 1
  186. - 3
  187. - 2
  188. - name: 1
  189. mergingIntList:
  190. - 2
  191. - 1
  192. sorted:
  193. mergeItemPtr:
  194. - name: 1
  195. mergingIntList:
  196. - 1
  197. - 2
  198. - name: 2
  199. mergingIntList:
  200. - 1
  201. - 2
  202. - 3
  203. - description: sort merging list by pointer
  204. original:
  205. mergeItemPtr:
  206. - name: 1
  207. - name: 3
  208. - name: 2
  209. sorted:
  210. mergeItemPtr:
  211. - name: 1
  212. - name: 2
  213. - name: 3
  214. `)
  215. func TestSortMergeLists(t *testing.T) {
  216. tc := SortMergeListTestCases{}
  217. err := yaml.Unmarshal(sortMergeListTestCaseData, &tc)
  218. if err != nil {
  219. t.Errorf("can't unmarshal test cases: %s\n", err)
  220. return
  221. }
  222. for _, c := range tc.TestCases {
  223. original := testObjectToJSONOrFail(t, c.Original, c.Description)
  224. sorted := testObjectToJSONOrFail(t, c.Sorted, c.Description)
  225. if !reflect.DeepEqual(original, sorted) {
  226. t.Errorf("error in test case: %s\ncannot sort object:\n%s\nexpected:\n%s\ngot:\n%s\n",
  227. c.Description, toYAMLOrError(c.Original), toYAMLOrError(c.Sorted), jsonToYAMLOrError(original))
  228. }
  229. }
  230. }
  231. // These are test cases for StrategicMergePatch that cannot be generated using
  232. // CreateTwoWayMergePatch because it doesn't use the replace directive, generate
  233. // duplicate integers for a merging list patch, or generate empty merging lists.
  234. var customStrategicMergePatchTestCaseData = []byte(`
  235. testCases:
  236. - description: unique scalars when merging lists
  237. original:
  238. mergingIntList:
  239. - 1
  240. - 2
  241. twoWay:
  242. mergingIntList:
  243. - 2
  244. - 3
  245. modified:
  246. mergingIntList:
  247. - 1
  248. - 2
  249. - 3
  250. - description: delete map from nested map
  251. original:
  252. simpleMap:
  253. key1: 1
  254. key2: 1
  255. twoWay:
  256. simpleMap:
  257. $patch: delete
  258. modified:
  259. simpleMap:
  260. {}
  261. - description: delete all items from merging list
  262. original:
  263. mergingList:
  264. - name: 1
  265. - name: 2
  266. twoWay:
  267. mergingList:
  268. - $patch: replace
  269. modified:
  270. mergingList: []
  271. - description: merge empty merging lists
  272. original:
  273. mergingList: []
  274. twoWay:
  275. mergingList: []
  276. modified:
  277. mergingList: []
  278. - description: delete all keys from map
  279. original:
  280. name: 1
  281. value: 1
  282. twoWay:
  283. $patch: replace
  284. modified: {}
  285. - description: add key and delete all keys from map
  286. original:
  287. name: 1
  288. value: 1
  289. twoWay:
  290. other: a
  291. $patch: replace
  292. modified:
  293. other: a
  294. `)
  295. func TestCustomStrategicMergePatch(t *testing.T) {
  296. tc := StrategicMergePatchTestCases{}
  297. err := yaml.Unmarshal(customStrategicMergePatchTestCaseData, &tc)
  298. if err != nil {
  299. t.Errorf("can't unmarshal test cases: %v\n", err)
  300. return
  301. }
  302. for _, c := range tc.TestCases {
  303. original, twoWay, modified := twoWayTestCaseToJSONOrFail(t, c)
  304. testPatchApplication(t, original, twoWay, modified, c.Description)
  305. }
  306. }
  307. // These are test cases for StrategicMergePatch, to assert that applying a patch
  308. // yields the correct outcome. They are also test cases for CreateTwoWayMergePatch
  309. // and CreateThreeWayMergePatch, to assert that they both generate the correct patch
  310. // for the given set of input documents.
  311. //
  312. var createStrategicMergePatchTestCaseData = []byte(`
  313. testCases:
  314. - description: nil original
  315. twoWay:
  316. name: 1
  317. value: 1
  318. modified:
  319. name: 1
  320. value: 1
  321. current:
  322. name: 1
  323. other: a
  324. threeWay:
  325. value: 1
  326. result:
  327. name: 1
  328. value: 1
  329. other: a
  330. - description: nil patch
  331. original:
  332. name: 1
  333. twoWay:
  334. {}
  335. modified:
  336. name: 1
  337. current:
  338. name: 1
  339. threeWay:
  340. {}
  341. result:
  342. name: 1
  343. - description: add field to map
  344. original:
  345. name: 1
  346. twoWay:
  347. value: 1
  348. modified:
  349. name: 1
  350. value: 1
  351. current:
  352. name: 1
  353. other: a
  354. threeWay:
  355. value: 1
  356. result:
  357. name: 1
  358. value: 1
  359. other: a
  360. - description: add field to map with conflict
  361. original:
  362. name: 1
  363. twoWay:
  364. value: 1
  365. modified:
  366. name: 1
  367. value: 1
  368. current:
  369. name: a
  370. other: a
  371. threeWay:
  372. name: 1
  373. value: 1
  374. result:
  375. name: 1
  376. value: 1
  377. other: a
  378. - description: add field and delete field from map
  379. original:
  380. name: 1
  381. twoWay:
  382. name: null
  383. value: 1
  384. modified:
  385. value: 1
  386. current:
  387. name: 1
  388. other: a
  389. threeWay:
  390. name: null
  391. value: 1
  392. result:
  393. value: 1
  394. other: a
  395. - description: add field and delete field from map with conflict
  396. original:
  397. name: 1
  398. twoWay:
  399. name: null
  400. value: 1
  401. modified:
  402. value: 1
  403. current:
  404. name: a
  405. other: a
  406. threeWay:
  407. name: null
  408. value: 1
  409. result:
  410. value: 1
  411. other: a
  412. - description: delete field from nested map
  413. original:
  414. simpleMap:
  415. key1: 1
  416. key2: 1
  417. twoWay:
  418. simpleMap:
  419. key2: null
  420. modified:
  421. simpleMap:
  422. key1: 1
  423. current:
  424. simpleMap:
  425. key1: 1
  426. key2: 1
  427. other: a
  428. threeWay:
  429. simpleMap:
  430. key2: null
  431. result:
  432. simpleMap:
  433. key1: 1
  434. other: a
  435. - description: delete field from nested map with conflict
  436. original:
  437. simpleMap:
  438. key1: 1
  439. key2: 1
  440. twoWay:
  441. simpleMap:
  442. key2: null
  443. modified:
  444. simpleMap:
  445. key1: 1
  446. current:
  447. simpleMap:
  448. key1: a
  449. key2: 1
  450. other: a
  451. threeWay:
  452. simpleMap:
  453. key1: 1
  454. key2: null
  455. result:
  456. simpleMap:
  457. key1: 1
  458. other: a
  459. - description: delete all fields from map
  460. original:
  461. name: 1
  462. value: 1
  463. twoWay:
  464. name: null
  465. value: null
  466. modified: {}
  467. current:
  468. name: 1
  469. value: 1
  470. other: a
  471. threeWay:
  472. name: null
  473. value: null
  474. result:
  475. other: a
  476. - description: delete all fields from map with conflict
  477. original:
  478. name: 1
  479. value: 1
  480. twoWay:
  481. name: null
  482. value: null
  483. modified: {}
  484. current:
  485. name: 1
  486. value: a
  487. other: a
  488. threeWay:
  489. name: null
  490. value: null
  491. result:
  492. other: a
  493. - description: add field and delete all fields from map
  494. original:
  495. name: 1
  496. value: 1
  497. twoWay:
  498. name: null
  499. value: null
  500. other: a
  501. modified:
  502. other: a
  503. current:
  504. name: 1
  505. value: 1
  506. other: a
  507. threeWay:
  508. name: null
  509. value: null
  510. result:
  511. other: a
  512. - description: add field and delete all fields from map with conflict
  513. original:
  514. name: 1
  515. value: 1
  516. twoWay:
  517. name: null
  518. value: null
  519. other: a
  520. modified:
  521. other: a
  522. current:
  523. name: 1
  524. value: 1
  525. other: b
  526. threeWay:
  527. name: null
  528. value: null
  529. other: a
  530. result:
  531. other: a
  532. - description: replace list of scalars
  533. original:
  534. nonMergingIntList:
  535. - 1
  536. - 2
  537. twoWay:
  538. nonMergingIntList:
  539. - 2
  540. - 3
  541. modified:
  542. nonMergingIntList:
  543. - 2
  544. - 3
  545. current:
  546. nonMergingIntList:
  547. - 1
  548. - 2
  549. threeWay:
  550. nonMergingIntList:
  551. - 2
  552. - 3
  553. result:
  554. nonMergingIntList:
  555. - 2
  556. - 3
  557. - description: replace list of scalars with conflict
  558. original:
  559. nonMergingIntList:
  560. - 1
  561. - 2
  562. twoWay:
  563. nonMergingIntList:
  564. - 2
  565. - 3
  566. modified:
  567. nonMergingIntList:
  568. - 2
  569. - 3
  570. current:
  571. nonMergingIntList:
  572. - 1
  573. - 4
  574. threeWay:
  575. nonMergingIntList:
  576. - 2
  577. - 3
  578. result:
  579. nonMergingIntList:
  580. - 2
  581. - 3
  582. - description: merge lists of scalars
  583. original:
  584. mergingIntList:
  585. - 1
  586. - 2
  587. twoWay:
  588. mergingIntList:
  589. - 3
  590. modified:
  591. mergingIntList:
  592. - 1
  593. - 2
  594. - 3
  595. current:
  596. mergingIntList:
  597. - 1
  598. - 2
  599. - 4
  600. threeWay:
  601. mergingIntList:
  602. - 3
  603. result:
  604. mergingIntList:
  605. - 1
  606. - 2
  607. - 3
  608. - 4
  609. - description: merge lists of maps
  610. original:
  611. mergingList:
  612. - name: 1
  613. - name: 2
  614. value: 2
  615. twoWay:
  616. mergingList:
  617. - name: 3
  618. value: 3
  619. - name: 4
  620. value: 4
  621. modified:
  622. mergingList:
  623. - name: 4
  624. value: 4
  625. - name: 1
  626. - name: 2
  627. value: 2
  628. - name: 3
  629. value: 3
  630. current:
  631. mergingList:
  632. - name: 1
  633. other: a
  634. - name: 2
  635. value: 2
  636. other: b
  637. threeWay:
  638. mergingList:
  639. - name: 3
  640. value: 3
  641. - name: 4
  642. value: 4
  643. result:
  644. mergingList:
  645. - name: 1
  646. other: a
  647. - name: 2
  648. value: 2
  649. other: b
  650. - name: 3
  651. value: 3
  652. - name: 4
  653. value: 4
  654. - description: merge lists of maps with conflict
  655. original:
  656. mergingList:
  657. - name: 1
  658. - name: 2
  659. value: 2
  660. twoWay:
  661. mergingList:
  662. - name: 3
  663. value: 3
  664. modified:
  665. mergingList:
  666. - name: 1
  667. - name: 2
  668. value: 2
  669. - name: 3
  670. value: 3
  671. current:
  672. mergingList:
  673. - name: 1
  674. other: a
  675. - name: 2
  676. value: 3
  677. other: b
  678. threeWay:
  679. mergingList:
  680. - name: 2
  681. value: 2
  682. - name: 3
  683. value: 3
  684. result:
  685. mergingList:
  686. - name: 1
  687. other: a
  688. - name: 2
  689. value: 2
  690. other: b
  691. - name: 3
  692. value: 3
  693. - description: add field to map in merging list
  694. original:
  695. mergingList:
  696. - name: 1
  697. - name: 2
  698. value: 2
  699. twoWay:
  700. mergingList:
  701. - name: 1
  702. value: 1
  703. modified:
  704. mergingList:
  705. - name: 1
  706. value: 1
  707. - name: 2
  708. value: 2
  709. current:
  710. mergingList:
  711. - name: 1
  712. other: a
  713. - name: 2
  714. value: 2
  715. other: b
  716. threeWay:
  717. mergingList:
  718. - name: 1
  719. value: 1
  720. result:
  721. mergingList:
  722. - name: 1
  723. value: 1
  724. other: a
  725. - name: 2
  726. value: 2
  727. other: b
  728. - description: add field to map in merging list with conflict
  729. original:
  730. mergingList:
  731. - name: 1
  732. - name: 2
  733. value: 2
  734. twoWay:
  735. mergingList:
  736. - name: 1
  737. value: 1
  738. modified:
  739. mergingList:
  740. - name: 1
  741. value: 1
  742. - name: 2
  743. value: 2
  744. current:
  745. mergingList:
  746. - name: 1
  747. other: a
  748. - name: 3
  749. value: 2
  750. other: b
  751. threeWay:
  752. mergingList:
  753. - name: 1
  754. value: 1
  755. - name: 2
  756. value: 2
  757. result:
  758. mergingList:
  759. - name: 1
  760. value: 1
  761. other: a
  762. - name: 2
  763. value: 2
  764. - name: 3
  765. value: 2
  766. other: b
  767. - description: add duplicate field to map in merging list
  768. original:
  769. mergingList:
  770. - name: 1
  771. - name: 2
  772. value: 2
  773. twoWay:
  774. mergingList:
  775. - name: 1
  776. value: 1
  777. modified:
  778. mergingList:
  779. - name: 1
  780. value: 1
  781. - name: 2
  782. value: 2
  783. current:
  784. mergingList:
  785. - name: 1
  786. value: 1
  787. other: a
  788. - name: 2
  789. value: 2
  790. other: b
  791. threeWay:
  792. {}
  793. result:
  794. mergingList:
  795. - name: 1
  796. value: 1
  797. other: a
  798. - name: 2
  799. value: 2
  800. other: b
  801. - description: add duplicate field to map in merging list with conflict
  802. original:
  803. mergingList:
  804. - name: 1
  805. - name: 2
  806. value: 2
  807. twoWay:
  808. mergingList:
  809. - name: 1
  810. value: 1
  811. modified:
  812. mergingList:
  813. - name: 1
  814. value: 1
  815. - name: 2
  816. value: 2
  817. current:
  818. mergingList:
  819. - name: 1
  820. value: 1
  821. other: a
  822. - name: 2
  823. value: 3
  824. other: b
  825. threeWay:
  826. mergingList:
  827. - name: 2
  828. value: 2
  829. result:
  830. mergingList:
  831. - name: 1
  832. value: 1
  833. other: a
  834. - name: 2
  835. value: 2
  836. other: b
  837. - description: replace map field value in merging list
  838. original:
  839. mergingList:
  840. - name: 1
  841. value: 1
  842. - name: 2
  843. value: 2
  844. twoWay:
  845. mergingList:
  846. - name: 1
  847. value: a
  848. modified:
  849. mergingList:
  850. - name: 1
  851. value: a
  852. - name: 2
  853. value: 2
  854. current:
  855. mergingList:
  856. - name: 1
  857. value: 1
  858. other: a
  859. - name: 2
  860. value: 2
  861. other: b
  862. threeWay:
  863. mergingList:
  864. - name: 1
  865. value: a
  866. result:
  867. mergingList:
  868. - name: 1
  869. value: a
  870. other: a
  871. - name: 2
  872. value: 2
  873. other: b
  874. - description: replace map field value in merging list with conflict
  875. original:
  876. mergingList:
  877. - name: 1
  878. value: 1
  879. - name: 2
  880. value: 2
  881. twoWay:
  882. mergingList:
  883. - name: 1
  884. value: a
  885. modified:
  886. mergingList:
  887. - name: 1
  888. value: a
  889. - name: 2
  890. value: 2
  891. current:
  892. mergingList:
  893. - name: 1
  894. value: 3
  895. other: a
  896. - name: 2
  897. value: 2
  898. other: b
  899. threeWay:
  900. mergingList:
  901. - name: 1
  902. value: a
  903. result:
  904. mergingList:
  905. - name: 1
  906. value: a
  907. other: a
  908. - name: 2
  909. value: 2
  910. other: b
  911. - description: delete map from merging list
  912. original:
  913. mergingList:
  914. - name: 1
  915. - name: 2
  916. twoWay:
  917. mergingList:
  918. - name: 1
  919. $patch: delete
  920. modified:
  921. mergingList:
  922. - name: 2
  923. current:
  924. mergingList:
  925. - name: 1
  926. - name: 2
  927. other: b
  928. threeWay:
  929. mergingList:
  930. - name: 1
  931. $patch: delete
  932. result:
  933. mergingList:
  934. - name: 2
  935. other: b
  936. - description: delete map from merging list with conflict
  937. original:
  938. mergingList:
  939. - name: 1
  940. - name: 2
  941. twoWay:
  942. mergingList:
  943. - name: 1
  944. $patch: delete
  945. modified:
  946. mergingList:
  947. - name: 2
  948. current:
  949. mergingList:
  950. - name: 1
  951. other: a
  952. - name: 2
  953. other: b
  954. threeWay:
  955. mergingList:
  956. - name: 1
  957. $patch: delete
  958. result:
  959. mergingList:
  960. - name: 2
  961. other: b
  962. - description: delete missing map from merging list
  963. original:
  964. mergingList:
  965. - name: 1
  966. - name: 2
  967. twoWay:
  968. mergingList:
  969. - name: 1
  970. $patch: delete
  971. modified:
  972. mergingList:
  973. - name: 2
  974. current:
  975. mergingList:
  976. - name: 2
  977. other: b
  978. threeWay:
  979. mergingList:
  980. - name: 1
  981. $patch: delete
  982. result:
  983. mergingList:
  984. - name: 2
  985. other: b
  986. - description: delete missing map from merging list with conflict
  987. original:
  988. mergingList:
  989. - name: 1
  990. - name: 2
  991. twoWay:
  992. mergingList:
  993. - name: 1
  994. $patch: delete
  995. modified:
  996. mergingList:
  997. - name: 2
  998. current:
  999. mergingList:
  1000. - name: 3
  1001. other: a
  1002. threeWay:
  1003. mergingList:
  1004. - name: 1
  1005. $patch: delete
  1006. - name: 2
  1007. result:
  1008. mergingList:
  1009. - name: 2
  1010. - name: 3
  1011. other: a
  1012. - description: add map and delete map from merging list
  1013. original:
  1014. merginglist:
  1015. - name: 1
  1016. - name: 2
  1017. twoWay:
  1018. merginglist:
  1019. - name: 1
  1020. $patch: delete
  1021. - name: 3
  1022. modified:
  1023. merginglist:
  1024. - name: 2
  1025. - name: 3
  1026. current:
  1027. merginglist:
  1028. - name: 1
  1029. - name: 2
  1030. other: b
  1031. - name: 4
  1032. other: c
  1033. threeWay:
  1034. merginglist:
  1035. - name: 1
  1036. $patch: delete
  1037. - name: 3
  1038. result:
  1039. merginglist:
  1040. - name: 2
  1041. other: b
  1042. - name: 3
  1043. - name: 4
  1044. other: c
  1045. - description: add map and delete map from merging list with conflict
  1046. original:
  1047. merginglist:
  1048. - name: 1
  1049. - name: 2
  1050. twoWay:
  1051. merginglist:
  1052. - name: 1
  1053. $patch: delete
  1054. - name: 3
  1055. modified:
  1056. merginglist:
  1057. - name: 2
  1058. - name: 3
  1059. current:
  1060. merginglist:
  1061. - name: 1
  1062. other: a
  1063. - name: 4
  1064. other: c
  1065. threeWay:
  1066. merginglist:
  1067. - name: 1
  1068. $patch: delete
  1069. - name: 2
  1070. - name: 3
  1071. result:
  1072. merginglist:
  1073. - name: 2
  1074. - name: 3
  1075. - name: 4
  1076. other: c
  1077. - description: delete all maps from merging list
  1078. original:
  1079. mergingList:
  1080. - name: 1
  1081. - name: 2
  1082. twoWay:
  1083. mergingList:
  1084. - name: 1
  1085. $patch: delete
  1086. - name: 2
  1087. $patch: delete
  1088. modified:
  1089. mergingList: []
  1090. current:
  1091. mergingList:
  1092. - name: 1
  1093. - name: 2
  1094. threeWay:
  1095. mergingList:
  1096. - name: 1
  1097. $patch: delete
  1098. - name: 2
  1099. $patch: delete
  1100. result:
  1101. mergingList: []
  1102. - description: delete all maps from merging list with conflict
  1103. original:
  1104. mergingList:
  1105. - name: 1
  1106. - name: 2
  1107. twoWay:
  1108. mergingList:
  1109. - name: 1
  1110. $patch: delete
  1111. - name: 2
  1112. $patch: delete
  1113. modified:
  1114. mergingList: []
  1115. current:
  1116. mergingList:
  1117. - name: 1
  1118. other: a
  1119. - name: 2
  1120. other: b
  1121. threeWay:
  1122. mergingList:
  1123. - name: 1
  1124. $patch: delete
  1125. - name: 2
  1126. $patch: delete
  1127. result:
  1128. mergingList: []
  1129. - description: delete all maps from empty merging list
  1130. original:
  1131. mergingList:
  1132. - name: 1
  1133. - name: 2
  1134. twoWay:
  1135. mergingList:
  1136. - name: 1
  1137. $patch: delete
  1138. - name: 2
  1139. $patch: delete
  1140. modified:
  1141. mergingList: []
  1142. current:
  1143. mergingList: []
  1144. threeWay:
  1145. mergingList:
  1146. - name: 1
  1147. $patch: delete
  1148. - name: 2
  1149. $patch: delete
  1150. result:
  1151. mergingList: []
  1152. - description: delete field from map in merging list
  1153. original:
  1154. mergingList:
  1155. - name: 1
  1156. value: 1
  1157. - name: 2
  1158. value: 2
  1159. twoWay:
  1160. mergingList:
  1161. - name: 1
  1162. value: null
  1163. modified:
  1164. mergingList:
  1165. - name: 1
  1166. - name: 2
  1167. value: 2
  1168. current:
  1169. mergingList:
  1170. - name: 1
  1171. value: 1
  1172. other: a
  1173. - name: 2
  1174. value: 2
  1175. other: b
  1176. threeWay:
  1177. mergingList:
  1178. - name: 1
  1179. value: null
  1180. result:
  1181. mergingList:
  1182. - name: 1
  1183. other: a
  1184. - name: 2
  1185. value: 2
  1186. other: b
  1187. - description: delete field from map in merging list with conflict
  1188. original:
  1189. mergingList:
  1190. - name: 1
  1191. value: 1
  1192. - name: 2
  1193. value: 2
  1194. twoWay:
  1195. mergingList:
  1196. - name: 1
  1197. value: null
  1198. modified:
  1199. mergingList:
  1200. - name: 1
  1201. - name: 2
  1202. value: 2
  1203. current:
  1204. mergingList:
  1205. - name: 1
  1206. value: a
  1207. other: a
  1208. - name: 2
  1209. value: 2
  1210. threeWay:
  1211. mergingList:
  1212. - name: 1
  1213. value: null
  1214. result:
  1215. mergingList:
  1216. - name: 1
  1217. other: a
  1218. - name: 2
  1219. value: 2
  1220. - description: delete missing field from map in merging list
  1221. original:
  1222. mergingList:
  1223. - name: 1
  1224. value: 1
  1225. - name: 2
  1226. value: 2
  1227. twoWay:
  1228. mergingList:
  1229. - name: 1
  1230. value: null
  1231. modified:
  1232. mergingList:
  1233. - name: 1
  1234. - name: 2
  1235. value: 2
  1236. current:
  1237. mergingList:
  1238. - name: 1
  1239. other: a
  1240. - name: 2
  1241. value: 2
  1242. other: b
  1243. threeWay:
  1244. mergingList:
  1245. - name: 1
  1246. value: null
  1247. result:
  1248. mergingList:
  1249. - name: 1
  1250. other: a
  1251. - name: 2
  1252. value: 2
  1253. other: b
  1254. - description: delete missing field from map in merging list with conflict
  1255. original:
  1256. mergingList:
  1257. - name: 1
  1258. value: 1
  1259. - name: 2
  1260. value: 2
  1261. twoWay:
  1262. mergingList:
  1263. - name: 1
  1264. value: null
  1265. modified:
  1266. mergingList:
  1267. - name: 1
  1268. - name: 2
  1269. value: 2
  1270. current:
  1271. mergingList:
  1272. - name: 1
  1273. other: a
  1274. - name: 2
  1275. other: b
  1276. threeWay:
  1277. mergingList:
  1278. - name: 1
  1279. value: null
  1280. - name: 2
  1281. value: 2
  1282. result:
  1283. mergingList:
  1284. - name: 1
  1285. other: a
  1286. - name: 2
  1287. value: 2
  1288. other: b
  1289. - description: replace non merging list nested in merging list
  1290. original:
  1291. mergingList:
  1292. - name: 1
  1293. nonMergingList:
  1294. - name: 1
  1295. - name: 2
  1296. value: 2
  1297. - name: 2
  1298. twoWay:
  1299. mergingList:
  1300. - name: 1
  1301. nonMergingList:
  1302. - name: 1
  1303. value: 1
  1304. modified:
  1305. mergingList:
  1306. - name: 1
  1307. nonMergingList:
  1308. - name: 1
  1309. value: 1
  1310. - name: 2
  1311. current:
  1312. mergingList:
  1313. - name: 1
  1314. other: a
  1315. nonMergingList:
  1316. - name: 1
  1317. - name: 2
  1318. value: 2
  1319. - name: 2
  1320. other: b
  1321. threeWay:
  1322. mergingList:
  1323. - name: 1
  1324. nonMergingList:
  1325. - name: 1
  1326. value: 1
  1327. result:
  1328. mergingList:
  1329. - name: 1
  1330. other: a
  1331. nonMergingList:
  1332. - name: 1
  1333. value: 1
  1334. - name: 2
  1335. other: b
  1336. - description: replace non merging list nested in merging list with value conflict
  1337. original:
  1338. mergingList:
  1339. - name: 1
  1340. nonMergingList:
  1341. - name: 1
  1342. - name: 2
  1343. value: 2
  1344. - name: 2
  1345. twoWay:
  1346. mergingList:
  1347. - name: 1
  1348. nonMergingList:
  1349. - name: 1
  1350. value: 1
  1351. modified:
  1352. mergingList:
  1353. - name: 1
  1354. nonMergingList:
  1355. - name: 1
  1356. value: 1
  1357. - name: 2
  1358. current:
  1359. mergingList:
  1360. - name: 1
  1361. other: a
  1362. nonMergingList:
  1363. - name: 1
  1364. value: c
  1365. - name: 2
  1366. other: b
  1367. threeWay:
  1368. mergingList:
  1369. - name: 1
  1370. nonMergingList:
  1371. - name: 1
  1372. value: 1
  1373. result:
  1374. mergingList:
  1375. - name: 1
  1376. other: a
  1377. nonMergingList:
  1378. - name: 1
  1379. value: 1
  1380. - name: 2
  1381. other: b
  1382. - description: replace non merging list nested in merging list with deletion conflict
  1383. original:
  1384. mergingList:
  1385. - name: 1
  1386. nonMergingList:
  1387. - name: 1
  1388. - name: 2
  1389. value: 2
  1390. - name: 2
  1391. twoWay:
  1392. mergingList:
  1393. - name: 1
  1394. nonMergingList:
  1395. - name: 1
  1396. value: 1
  1397. modified:
  1398. mergingList:
  1399. - name: 1
  1400. nonMergingList:
  1401. - name: 1
  1402. value: 1
  1403. - name: 2
  1404. current:
  1405. mergingList:
  1406. - name: 1
  1407. other: a
  1408. nonMergingList:
  1409. - name: 2
  1410. value: 2
  1411. - name: 2
  1412. other: b
  1413. threeWay:
  1414. mergingList:
  1415. - name: 1
  1416. nonMergingList:
  1417. - name: 1
  1418. value: 1
  1419. result:
  1420. mergingList:
  1421. - name: 1
  1422. other: a
  1423. nonMergingList:
  1424. - name: 1
  1425. value: 1
  1426. - name: 2
  1427. other: b
  1428. - description: add field to map in merging list nested in merging list
  1429. original:
  1430. mergingList:
  1431. - name: 1
  1432. mergingList:
  1433. - name: 1
  1434. - name: 2
  1435. value: 2
  1436. - name: 2
  1437. twoWay:
  1438. mergingList:
  1439. - name: 1
  1440. mergingList:
  1441. - name: 1
  1442. value: 1
  1443. modified:
  1444. mergingList:
  1445. - name: 1
  1446. mergingList:
  1447. - name: 1
  1448. value: 1
  1449. - name: 2
  1450. value: 2
  1451. - name: 2
  1452. current:
  1453. mergingList:
  1454. - name: 1
  1455. other: a
  1456. mergingList:
  1457. - name: 1
  1458. - name: 2
  1459. value: 2
  1460. - name: 2
  1461. other: b
  1462. threeWay:
  1463. mergingList:
  1464. - name: 1
  1465. mergingList:
  1466. - name: 1
  1467. value: 1
  1468. result:
  1469. mergingList:
  1470. - name: 1
  1471. other: a
  1472. mergingList:
  1473. - name: 1
  1474. value: 1
  1475. - name: 2
  1476. value: 2
  1477. - name: 2
  1478. other: b
  1479. - description: add field to map in merging list nested in merging list with value conflict
  1480. original:
  1481. mergingList:
  1482. - name: 1
  1483. mergingList:
  1484. - name: 1
  1485. - name: 2
  1486. value: 2
  1487. - name: 2
  1488. twoWay:
  1489. mergingList:
  1490. - name: 1
  1491. mergingList:
  1492. - name: 1
  1493. value: 1
  1494. modified:
  1495. mergingList:
  1496. - name: 1
  1497. mergingList:
  1498. - name: 1
  1499. value: 1
  1500. - name: 2
  1501. value: 2
  1502. - name: 2
  1503. current:
  1504. mergingList:
  1505. - name: 1
  1506. other: a
  1507. mergingList:
  1508. - name: 1
  1509. value: a
  1510. other: c
  1511. - name: 2
  1512. value: b
  1513. other: d
  1514. - name: 2
  1515. other: b
  1516. threeWay:
  1517. mergingList:
  1518. - name: 1
  1519. mergingList:
  1520. - name: 1
  1521. value: 1
  1522. - name: 2
  1523. value: 2
  1524. result:
  1525. mergingList:
  1526. - name: 1
  1527. other: a
  1528. mergingList:
  1529. - name: 1
  1530. value: 1
  1531. other: c
  1532. - name: 2
  1533. value: 2
  1534. other: d
  1535. - name: 2
  1536. other: b
  1537. - description: add field to map in merging list nested in merging list with deletion conflict
  1538. original:
  1539. mergingList:
  1540. - name: 1
  1541. mergingList:
  1542. - name: 1
  1543. - name: 2
  1544. value: 2
  1545. - name: 2
  1546. twoWay:
  1547. mergingList:
  1548. - name: 1
  1549. mergingList:
  1550. - name: 1
  1551. value: 1
  1552. modified:
  1553. mergingList:
  1554. - name: 1
  1555. mergingList:
  1556. - name: 1
  1557. value: 1
  1558. - name: 2
  1559. value: 2
  1560. - name: 2
  1561. current:
  1562. mergingList:
  1563. - name: 1
  1564. other: a
  1565. mergingList:
  1566. - name: 2
  1567. value: 2
  1568. other: d
  1569. - name: 2
  1570. other: b
  1571. threeWay:
  1572. mergingList:
  1573. - name: 1
  1574. mergingList:
  1575. - name: 1
  1576. value: 1
  1577. result:
  1578. mergingList:
  1579. - name: 1
  1580. other: a
  1581. mergingList:
  1582. - name: 1
  1583. value: 1
  1584. - name: 2
  1585. value: 2
  1586. other: d
  1587. - name: 2
  1588. other: b
  1589. - description: merge empty merging lists
  1590. original:
  1591. mergingList: []
  1592. twoWay:
  1593. {}
  1594. modified:
  1595. mergingList: []
  1596. current:
  1597. mergingList: []
  1598. threeWay:
  1599. {}
  1600. result:
  1601. mergingList: []
  1602. - description: add map to merging list by pointer
  1603. original:
  1604. mergeItemPtr:
  1605. - name: 1
  1606. twoWay:
  1607. mergeItemPtr:
  1608. - name: 2
  1609. modified:
  1610. mergeItemPtr:
  1611. - name: 1
  1612. - name: 2
  1613. current:
  1614. mergeItemPtr:
  1615. - name: 1
  1616. other: a
  1617. - name: 3
  1618. threeWay:
  1619. mergeItemPtr:
  1620. - name: 2
  1621. result:
  1622. mergeItemPtr:
  1623. - name: 1
  1624. other: a
  1625. - name: 2
  1626. - name: 3
  1627. - description: add map to merging list by pointer with conflict
  1628. original:
  1629. mergeItemPtr:
  1630. - name: 1
  1631. twoWay:
  1632. mergeItemPtr:
  1633. - name: 2
  1634. modified:
  1635. mergeItemPtr:
  1636. - name: 1
  1637. - name: 2
  1638. current:
  1639. mergeItemPtr:
  1640. - name: 3
  1641. threeWay:
  1642. mergeItemPtr:
  1643. - name: 1
  1644. - name: 2
  1645. result:
  1646. mergeItemPtr:
  1647. - name: 1
  1648. - name: 2
  1649. - name: 3
  1650. - description: add field to map in merging list by pointer
  1651. original:
  1652. mergeItemPtr:
  1653. - name: 1
  1654. mergeItemPtr:
  1655. - name: 1
  1656. - name: 2
  1657. value: 2
  1658. - name: 2
  1659. twoWay:
  1660. mergeItemPtr:
  1661. - name: 1
  1662. mergeItemPtr:
  1663. - name: 1
  1664. value: 1
  1665. modified:
  1666. mergeItemPtr:
  1667. - name: 1
  1668. mergeItemPtr:
  1669. - name: 1
  1670. value: 1
  1671. - name: 2
  1672. value: 2
  1673. - name: 2
  1674. current:
  1675. mergeItemPtr:
  1676. - name: 1
  1677. other: a
  1678. mergeItemPtr:
  1679. - name: 1
  1680. other: a
  1681. - name: 2
  1682. value: 2
  1683. other: b
  1684. - name: 2
  1685. other: b
  1686. threeWay:
  1687. mergeItemPtr:
  1688. - name: 1
  1689. mergeItemPtr:
  1690. - name: 1
  1691. value: 1
  1692. result:
  1693. mergeItemPtr:
  1694. - name: 1
  1695. other: a
  1696. mergeItemPtr:
  1697. - name: 1
  1698. value: 1
  1699. other: a
  1700. - name: 2
  1701. value: 2
  1702. other: b
  1703. - name: 2
  1704. other: b
  1705. - description: add field to map in merging list by pointer with conflict
  1706. original:
  1707. mergeItemPtr:
  1708. - name: 1
  1709. mergeItemPtr:
  1710. - name: 1
  1711. - name: 2
  1712. value: 2
  1713. - name: 2
  1714. twoWay:
  1715. mergeItemPtr:
  1716. - name: 1
  1717. mergeItemPtr:
  1718. - name: 1
  1719. value: 1
  1720. modified:
  1721. mergeItemPtr:
  1722. - name: 1
  1723. mergeItemPtr:
  1724. - name: 1
  1725. value: 1
  1726. - name: 2
  1727. value: 2
  1728. - name: 2
  1729. current:
  1730. mergeItemPtr:
  1731. - name: 1
  1732. other: a
  1733. mergeItemPtr:
  1734. - name: 1
  1735. value: a
  1736. - name: 2
  1737. value: 2
  1738. other: b
  1739. - name: 2
  1740. other: b
  1741. threeWay:
  1742. mergeItemPtr:
  1743. - name: 1
  1744. mergeItemPtr:
  1745. - name: 1
  1746. value: 1
  1747. result:
  1748. mergeItemPtr:
  1749. - name: 1
  1750. other: a
  1751. mergeItemPtr:
  1752. - name: 1
  1753. value: 1
  1754. - name: 2
  1755. value: 2
  1756. other: b
  1757. - name: 2
  1758. other: b
  1759. `)
  1760. func TestStrategicMergePatch(t *testing.T) {
  1761. testStrategicMergePatchWithCustomArguments(t, "bad original",
  1762. "<THIS IS NOT JSON>", "{}", mergeItem, errBadJSONDoc)
  1763. testStrategicMergePatchWithCustomArguments(t, "bad patch",
  1764. "{}", "<THIS IS NOT JSON>", mergeItem, errBadJSONDoc)
  1765. testStrategicMergePatchWithCustomArguments(t, "bad struct",
  1766. "{}", "{}", []byte("<THIS IS NOT A STRUCT>"), fmt.Errorf(errBadArgTypeFmt, "struct", "slice"))
  1767. testStrategicMergePatchWithCustomArguments(t, "nil struct",
  1768. "{}", "{}", nil, fmt.Errorf(errBadArgTypeFmt, "struct", "nil"))
  1769. tc := StrategicMergePatchTestCases{}
  1770. err := yaml.Unmarshal(createStrategicMergePatchTestCaseData, &tc)
  1771. if err != nil {
  1772. t.Errorf("can't unmarshal test cases: %s\n", err)
  1773. return
  1774. }
  1775. for _, c := range tc.TestCases {
  1776. testTwoWayPatch(t, c)
  1777. testThreeWayPatch(t, c)
  1778. }
  1779. }
  1780. func testStrategicMergePatchWithCustomArguments(t *testing.T, description, original, patch string, dataStruct interface{}, err error) {
  1781. _, err2 := StrategicMergePatch([]byte(original), []byte(patch), dataStruct)
  1782. if err2 != err {
  1783. if err2 == nil {
  1784. t.Errorf("expected error: %s\ndid not occur in test case: %s", err, description)
  1785. return
  1786. }
  1787. if err == nil || err2.Error() != err.Error() {
  1788. t.Errorf("unexpected error: %s\noccurred in test case: %s", err2, description)
  1789. return
  1790. }
  1791. }
  1792. }
  1793. func testTwoWayPatch(t *testing.T, c StrategicMergePatchTestCase) {
  1794. original, expected, modified := twoWayTestCaseToJSONOrFail(t, c)
  1795. actual, err := CreateTwoWayMergePatch(original, modified, mergeItem)
  1796. if err != nil {
  1797. t.Errorf("error: %s\nin test case: %s\ncannot create two way patch: %s:\n%s\n",
  1798. err, c.Description, original, toYAMLOrError(c.StrategicMergePatchTestCaseData))
  1799. return
  1800. }
  1801. testPatchCreation(t, expected, actual, c.Description)
  1802. testPatchApplication(t, original, actual, modified, c.Description)
  1803. }
  1804. func twoWayTestCaseToJSONOrFail(t *testing.T, c StrategicMergePatchTestCase) ([]byte, []byte, []byte) {
  1805. return testObjectToJSONOrFail(t, c.Original, c.Description),
  1806. testObjectToJSONOrFail(t, c.TwoWay, c.Description),
  1807. testObjectToJSONOrFail(t, c.Modified, c.Description)
  1808. }
  1809. func testThreeWayPatch(t *testing.T, c StrategicMergePatchTestCase) {
  1810. original, modified, current, expected, result := threeWayTestCaseToJSONOrFail(t, c)
  1811. actual, err := CreateThreeWayMergePatch(original, modified, current, mergeItem, false)
  1812. if err != nil {
  1813. if !IsConflict(err) {
  1814. t.Errorf("error: %s\nin test case: %s\ncannot create three way patch:\n%s\n",
  1815. err, c.Description, toYAMLOrError(c.StrategicMergePatchTestCaseData))
  1816. return
  1817. }
  1818. if !strings.Contains(c.Description, "conflict") {
  1819. t.Errorf("unexpected conflict: %s\nin test case: %s\ncannot create three way patch:\n%s\n",
  1820. err, c.Description, toYAMLOrError(c.StrategicMergePatchTestCaseData))
  1821. return
  1822. }
  1823. if len(c.Result) > 0 {
  1824. actual, err := CreateThreeWayMergePatch(original, modified, current, mergeItem, true)
  1825. if err != nil {
  1826. t.Errorf("error: %s\nin test case: %s\ncannot force three way patch application:\n%s\n",
  1827. err, c.Description, toYAMLOrError(c.StrategicMergePatchTestCaseData))
  1828. return
  1829. }
  1830. testPatchCreation(t, expected, actual, c.Description)
  1831. testPatchApplication(t, current, actual, result, c.Description)
  1832. }
  1833. return
  1834. }
  1835. if strings.Contains(c.Description, "conflict") || len(c.Result) < 1 {
  1836. t.Errorf("error in test case: %s\nexpected conflict did not occur:\n%s\n",
  1837. c.Description, toYAMLOrError(c.StrategicMergePatchTestCaseData))
  1838. return
  1839. }
  1840. testPatchCreation(t, expected, actual, c.Description)
  1841. testPatchApplication(t, current, actual, result, c.Description)
  1842. }
  1843. func threeWayTestCaseToJSONOrFail(t *testing.T, c StrategicMergePatchTestCase) ([]byte, []byte, []byte, []byte, []byte) {
  1844. return testObjectToJSONOrFail(t, c.Original, c.Description),
  1845. testObjectToJSONOrFail(t, c.Modified, c.Description),
  1846. testObjectToJSONOrFail(t, c.Current, c.Description),
  1847. testObjectToJSONOrFail(t, c.ThreeWay, c.Description),
  1848. testObjectToJSONOrFail(t, c.Result, c.Description)
  1849. }
  1850. func testPatchCreation(t *testing.T, expected, actual []byte, description string) {
  1851. sorted, err := sortMergeListsByName(actual, mergeItem)
  1852. if err != nil {
  1853. t.Errorf("error: %s\nin test case: %s\ncannot sort patch:\n%s\n",
  1854. err, description, jsonToYAMLOrError(actual))
  1855. return
  1856. }
  1857. if !reflect.DeepEqual(sorted, expected) {
  1858. t.Errorf("error in test case: %s\nexpected patch:\n%s\ngot:\n%s\n",
  1859. description, jsonToYAMLOrError(expected), jsonToYAMLOrError(sorted))
  1860. return
  1861. }
  1862. }
  1863. func testPatchApplication(t *testing.T, original, patch, expected []byte, description string) {
  1864. result, err := StrategicMergePatch(original, patch, mergeItem)
  1865. if err != nil {
  1866. t.Errorf("error: %s\nin test case: %s\ncannot apply patch:\n%s\nto original:\n%s\n",
  1867. err, description, jsonToYAMLOrError(patch), jsonToYAMLOrError(original))
  1868. return
  1869. }
  1870. sorted, err := sortMergeListsByName(result, mergeItem)
  1871. if err != nil {
  1872. t.Errorf("error: %s\nin test case: %s\ncannot sort result object:\n%s\n",
  1873. err, description, jsonToYAMLOrError(result))
  1874. return
  1875. }
  1876. if !reflect.DeepEqual(sorted, expected) {
  1877. format := "error in test case: %s\npatch application failed:\noriginal:\n%s\npatch:\n%s\nexpected:\n%s\ngot:\n%s\n"
  1878. t.Errorf(format, description,
  1879. jsonToYAMLOrError(original), jsonToYAMLOrError(patch),
  1880. jsonToYAMLOrError(expected), jsonToYAMLOrError(sorted))
  1881. return
  1882. }
  1883. }
  1884. func testObjectToJSONOrFail(t *testing.T, o map[string]interface{}, description string) []byte {
  1885. if o == nil {
  1886. return nil
  1887. }
  1888. j, err := toJSON(o)
  1889. if err != nil {
  1890. t.Error(err)
  1891. }
  1892. r, err := sortMergeListsByName(j, mergeItem)
  1893. if err != nil {
  1894. t.Errorf("error: %s\nin test case: %s\ncannot sort object:\n%s\n", err, description, j)
  1895. return nil
  1896. }
  1897. return r
  1898. }
  1899. func jsonToYAMLOrError(j []byte) string {
  1900. y, err := jsonToYAML(j)
  1901. if err != nil {
  1902. return err.Error()
  1903. }
  1904. return string(y)
  1905. }
  1906. func toJSON(v interface{}) ([]byte, error) {
  1907. j, err := json.Marshal(v)
  1908. if err != nil {
  1909. return nil, fmt.Errorf("json marshal failed: %v\n%v\n", err, spew.Sdump(v))
  1910. }
  1911. return j, nil
  1912. }
  1913. func jsonToYAML(j []byte) ([]byte, error) {
  1914. y, err := yaml.JSONToYAML(j)
  1915. if err != nil {
  1916. return nil, fmt.Errorf("json to yaml failed: %v\n%v\n", err, j)
  1917. }
  1918. return y, nil
  1919. }
  1920. func TestHasConflicts(t *testing.T) {
  1921. testCases := []struct {
  1922. A interface{}
  1923. B interface{}
  1924. Ret bool
  1925. }{
  1926. {A: "hello", B: "hello", Ret: false}, // 0
  1927. {A: "hello", B: "hell", Ret: true},
  1928. {A: "hello", B: nil, Ret: true},
  1929. {A: "hello", B: 1, Ret: true},
  1930. {A: "hello", B: float64(1.0), Ret: true},
  1931. {A: "hello", B: false, Ret: true},
  1932. {A: 1, B: 1, Ret: false},
  1933. {A: false, B: false, Ret: false},
  1934. {A: float64(3), B: float64(3), Ret: false},
  1935. {A: "hello", B: []interface{}{}, Ret: true}, // 6
  1936. {A: []interface{}{1}, B: []interface{}{}, Ret: true},
  1937. {A: []interface{}{}, B: []interface{}{}, Ret: false},
  1938. {A: []interface{}{1}, B: []interface{}{1}, Ret: false},
  1939. {A: map[string]interface{}{}, B: []interface{}{1}, Ret: true},
  1940. {A: map[string]interface{}{}, B: map[string]interface{}{"a": 1}, Ret: false}, // 11
  1941. {A: map[string]interface{}{"a": 1}, B: map[string]interface{}{"a": 1}, Ret: false},
  1942. {A: map[string]interface{}{"a": 1}, B: map[string]interface{}{"a": 2}, Ret: true},
  1943. {A: map[string]interface{}{"a": 1}, B: map[string]interface{}{"b": 2}, Ret: false},
  1944. { // 15
  1945. A: map[string]interface{}{"a": []interface{}{1}},
  1946. B: map[string]interface{}{"a": []interface{}{1}},
  1947. Ret: false,
  1948. },
  1949. {
  1950. A: map[string]interface{}{"a": []interface{}{1}},
  1951. B: map[string]interface{}{"a": []interface{}{}},
  1952. Ret: true,
  1953. },
  1954. {
  1955. A: map[string]interface{}{"a": []interface{}{1}},
  1956. B: map[string]interface{}{"a": 1},
  1957. Ret: true,
  1958. },
  1959. }
  1960. for i, testCase := range testCases {
  1961. out, err := HasConflicts(testCase.A, testCase.B)
  1962. if err != nil {
  1963. t.Errorf("%d: unexpected error: %v", i, err)
  1964. }
  1965. if out != testCase.Ret {
  1966. t.Errorf("%d: expected %t got %t", i, testCase.Ret, out)
  1967. continue
  1968. }
  1969. out, err = HasConflicts(testCase.B, testCase.A)
  1970. if err != nil {
  1971. t.Errorf("%d: unexpected error: %v", i, err)
  1972. }
  1973. if out != testCase.Ret {
  1974. t.Errorf("%d: expected reversed %t got %t", i, testCase.Ret, out)
  1975. }
  1976. }
  1977. }
  1978. type PrecisionItem struct {
  1979. Name string
  1980. Int32 int32
  1981. Int64 int64
  1982. Float32 float32
  1983. Float64 float64
  1984. }
  1985. var precisionItem PrecisionItem
  1986. func TestNumberConversion(t *testing.T) {
  1987. testcases := map[string]struct {
  1988. Old string
  1989. New string
  1990. ExpectedPatch string
  1991. ExpectedResult string
  1992. }{
  1993. "empty": {
  1994. Old: `{}`,
  1995. New: `{}`,
  1996. ExpectedPatch: `{}`,
  1997. ExpectedResult: `{}`,
  1998. },
  1999. "int32 medium": {
  2000. Old: `{"int32":1000000}`,
  2001. New: `{"int32":1000000,"name":"newname"}`,
  2002. ExpectedPatch: `{"name":"newname"}`,
  2003. ExpectedResult: `{"int32":1000000,"name":"newname"}`,
  2004. },
  2005. "int32 max": {
  2006. Old: `{"int32":2147483647}`,
  2007. New: `{"int32":2147483647,"name":"newname"}`,
  2008. ExpectedPatch: `{"name":"newname"}`,
  2009. ExpectedResult: `{"int32":2147483647,"name":"newname"}`,
  2010. },
  2011. "int64 medium": {
  2012. Old: `{"int64":1000000}`,
  2013. New: `{"int64":1000000,"name":"newname"}`,
  2014. ExpectedPatch: `{"name":"newname"}`,
  2015. ExpectedResult: `{"int64":1000000,"name":"newname"}`,
  2016. },
  2017. "int64 max": {
  2018. Old: `{"int64":9223372036854775807}`,
  2019. New: `{"int64":9223372036854775807,"name":"newname"}`,
  2020. ExpectedPatch: `{"name":"newname"}`,
  2021. ExpectedResult: `{"int64":9223372036854775807,"name":"newname"}`,
  2022. },
  2023. "float32 max": {
  2024. Old: `{"float32":3.4028234663852886e+38}`,
  2025. New: `{"float32":3.4028234663852886e+38,"name":"newname"}`,
  2026. ExpectedPatch: `{"name":"newname"}`,
  2027. ExpectedResult: `{"float32":3.4028234663852886e+38,"name":"newname"}`,
  2028. },
  2029. "float64 max": {
  2030. Old: `{"float64":1.7976931348623157e+308}`,
  2031. New: `{"float64":1.7976931348623157e+308,"name":"newname"}`,
  2032. ExpectedPatch: `{"name":"newname"}`,
  2033. ExpectedResult: `{"float64":1.7976931348623157e+308,"name":"newname"}`,
  2034. },
  2035. }
  2036. for k, tc := range testcases {
  2037. patch, err := CreateTwoWayMergePatch([]byte(tc.Old), []byte(tc.New), precisionItem)
  2038. if err != nil {
  2039. t.Errorf("%s: unexpected error %v", k, err)
  2040. continue
  2041. }
  2042. if tc.ExpectedPatch != string(patch) {
  2043. t.Errorf("%s: expected %s, got %s", k, tc.ExpectedPatch, string(patch))
  2044. continue
  2045. }
  2046. result, err := StrategicMergePatch([]byte(tc.Old), patch, precisionItem)
  2047. if err != nil {
  2048. t.Errorf("%s: unexpected error %v", k, err)
  2049. continue
  2050. }
  2051. if tc.ExpectedResult != string(result) {
  2052. t.Errorf("%s: expected %s, got %s", k, tc.ExpectedResult, string(result))
  2053. continue
  2054. }
  2055. }
  2056. }