controller_history_test.go 49 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705
  1. /*
  2. Copyright 2016 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 history
  14. import (
  15. "bytes"
  16. "context"
  17. "encoding/json"
  18. "fmt"
  19. "reflect"
  20. "testing"
  21. apps "k8s.io/api/apps/v1"
  22. "k8s.io/api/core/v1"
  23. "k8s.io/client-go/informers"
  24. "k8s.io/client-go/kubernetes/fake"
  25. clientscheme "k8s.io/client-go/kubernetes/scheme"
  26. "k8s.io/kubernetes/pkg/api/legacyscheme"
  27. "k8s.io/kubernetes/pkg/controller"
  28. "k8s.io/apimachinery/pkg/api/errors"
  29. "k8s.io/apimachinery/pkg/api/resource"
  30. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  31. "k8s.io/apimachinery/pkg/labels"
  32. "k8s.io/apimachinery/pkg/runtime"
  33. "k8s.io/apimachinery/pkg/types"
  34. "k8s.io/apimachinery/pkg/util/strategicpatch"
  35. core "k8s.io/client-go/testing"
  36. "time"
  37. )
  38. func TestRealHistory_ListControllerRevisions(t *testing.T) {
  39. type testcase struct {
  40. name string
  41. parent metav1.Object
  42. selector labels.Selector
  43. revisions []*apps.ControllerRevision
  44. want map[string]bool
  45. }
  46. testFn := func(test *testcase, t *testing.T) {
  47. client := fake.NewSimpleClientset()
  48. informerFactory := informers.NewSharedInformerFactory(client, controller.NoResyncPeriodFunc())
  49. stop := make(chan struct{})
  50. defer close(stop)
  51. informerFactory.Start(stop)
  52. informer := informerFactory.Apps().V1().ControllerRevisions()
  53. informerFactory.WaitForCacheSync(stop)
  54. for i := range test.revisions {
  55. informer.Informer().GetIndexer().Add(test.revisions[i])
  56. }
  57. history := NewHistory(client, informer.Lister())
  58. revisions, err := history.ListControllerRevisions(test.parent, test.selector)
  59. if err != nil {
  60. t.Errorf("%s: %s", test.name, err)
  61. }
  62. got := make(map[string]bool)
  63. for i := range revisions {
  64. got[revisions[i].Name] = true
  65. }
  66. if !reflect.DeepEqual(test.want, got) {
  67. t.Errorf("%s: want %v got %v", test.name, test.want, got)
  68. }
  69. }
  70. ss1 := newStatefulSet(3, "ss1", types.UID("ss1"), map[string]string{"foo": "bar"})
  71. ss2 := newStatefulSet(3, "ss2", types.UID("ss2"), map[string]string{"goo": "car"})
  72. sel1, err := metav1.LabelSelectorAsSelector(ss1.Spec.Selector)
  73. if err != nil {
  74. t.Fatal(err)
  75. }
  76. ss1Rev1, err := NewControllerRevision(ss1, parentKind, ss1.Spec.Template.Labels, rawTemplate(&ss1.Spec.Template), 1, nil)
  77. if err != nil {
  78. t.Fatal(err)
  79. }
  80. ss1Rev1.Namespace = ss1.Namespace
  81. ss1Rev2, err := NewControllerRevision(ss1, parentKind, ss1.Spec.Template.Labels, rawTemplate(&ss1.Spec.Template), 2, nil)
  82. if err != nil {
  83. t.Fatal(err)
  84. }
  85. ss1Rev2.Namespace = ss1.Namespace
  86. ss2Rev1, err := NewControllerRevision(ss2, parentKind, ss2.Spec.Template.Labels, rawTemplate(&ss2.Spec.Template), 1, nil)
  87. if err != nil {
  88. t.Fatal(err)
  89. }
  90. ss2Rev1.Namespace = ss2.Namespace
  91. ss1Orphan, err := NewControllerRevision(ss1, parentKind, ss1.Spec.Template.Labels, rawTemplate(&ss1.Spec.Template), 3, nil)
  92. if err != nil {
  93. t.Fatal(err)
  94. }
  95. ss1Orphan.Namespace = ss1.Namespace
  96. ss1Orphan.OwnerReferences = nil
  97. tests := []testcase{
  98. {
  99. name: "selects none",
  100. parent: &ss1.ObjectMeta,
  101. selector: sel1,
  102. revisions: nil,
  103. want: map[string]bool{},
  104. },
  105. {
  106. name: "selects all",
  107. parent: &ss1.ObjectMeta,
  108. selector: sel1,
  109. revisions: []*apps.ControllerRevision{ss1Rev1, ss1Rev2},
  110. want: map[string]bool{ss1Rev1.Name: true, ss1Rev2.Name: true},
  111. },
  112. {
  113. name: "doesn't select another Objects history",
  114. parent: &ss1.ObjectMeta,
  115. selector: sel1,
  116. revisions: []*apps.ControllerRevision{ss1Rev1, ss1Rev2, ss2Rev1},
  117. want: map[string]bool{ss1Rev1.Name: true, ss1Rev2.Name: true},
  118. },
  119. {
  120. name: "selects orphans",
  121. parent: &ss1.ObjectMeta,
  122. selector: sel1,
  123. revisions: []*apps.ControllerRevision{ss1Rev1, ss1Rev2, ss1Orphan},
  124. want: map[string]bool{ss1Rev1.Name: true, ss1Rev2.Name: true, ss1Orphan.Name: true},
  125. },
  126. }
  127. for i := range tests {
  128. testFn(&tests[i], t)
  129. }
  130. }
  131. func TestFakeHistory_ListControllerRevisions(t *testing.T) {
  132. type testcase struct {
  133. name string
  134. parent metav1.Object
  135. selector labels.Selector
  136. revisions []*apps.ControllerRevision
  137. want map[string]bool
  138. }
  139. testFn := func(test *testcase, t *testing.T) {
  140. client := fake.NewSimpleClientset()
  141. informerFactory := informers.NewSharedInformerFactory(client, controller.NoResyncPeriodFunc())
  142. stop := make(chan struct{})
  143. defer close(stop)
  144. informerFactory.Start(stop)
  145. informer := informerFactory.Apps().V1().ControllerRevisions()
  146. informerFactory.WaitForCacheSync(stop)
  147. for i := range test.revisions {
  148. informer.Informer().GetIndexer().Add(test.revisions[i])
  149. }
  150. history := NewFakeHistory(informer)
  151. revisions, err := history.ListControllerRevisions(test.parent, test.selector)
  152. if err != nil {
  153. t.Errorf("%s: %s", test.name, err)
  154. }
  155. got := make(map[string]bool)
  156. for i := range revisions {
  157. got[revisions[i].Name] = true
  158. }
  159. if !reflect.DeepEqual(test.want, got) {
  160. t.Errorf("%s: want %v got %v", test.name, test.want, got)
  161. }
  162. }
  163. ss1 := newStatefulSet(3, "ss1", types.UID("ss1"), map[string]string{"foo": "bar"})
  164. ss2 := newStatefulSet(3, "ss2", types.UID("ss2"), map[string]string{"goo": "car"})
  165. sel1, err := metav1.LabelSelectorAsSelector(ss1.Spec.Selector)
  166. if err != nil {
  167. t.Fatal(err)
  168. }
  169. ss1Rev1, err := NewControllerRevision(ss1, parentKind, ss1.Spec.Template.Labels, rawTemplate(&ss1.Spec.Template), 1, nil)
  170. if err != nil {
  171. t.Fatal(err)
  172. }
  173. ss1Rev1.Namespace = ss1.Namespace
  174. ss1Rev2, err := NewControllerRevision(ss1, parentKind, ss1.Spec.Template.Labels, rawTemplate(&ss1.Spec.Template), 2, nil)
  175. if err != nil {
  176. t.Fatal(err)
  177. }
  178. ss1Rev2.Namespace = ss1.Namespace
  179. ss2Rev1, err := NewControllerRevision(ss2, parentKind, ss2.Spec.Template.Labels, rawTemplate(&ss2.Spec.Template), 1, nil)
  180. if err != nil {
  181. t.Fatal(err)
  182. }
  183. ss2Rev1.Namespace = ss2.Namespace
  184. ss1Orphan, err := NewControllerRevision(ss1, parentKind, ss1.Spec.Template.Labels, rawTemplate(&ss1.Spec.Template), 3, nil)
  185. if err != nil {
  186. t.Fatal(err)
  187. }
  188. ss1Orphan.Namespace = ss1.Namespace
  189. ss1Orphan.OwnerReferences = nil
  190. tests := []testcase{
  191. {
  192. name: "selects none",
  193. parent: &ss1.ObjectMeta,
  194. selector: sel1,
  195. revisions: nil,
  196. want: map[string]bool{},
  197. },
  198. {
  199. name: "selects all",
  200. parent: &ss1.ObjectMeta,
  201. selector: sel1,
  202. revisions: []*apps.ControllerRevision{ss1Rev1, ss1Rev2},
  203. want: map[string]bool{ss1Rev1.Name: true, ss1Rev2.Name: true},
  204. },
  205. {
  206. name: "doesn't select another Objects history",
  207. parent: &ss1.ObjectMeta,
  208. selector: sel1,
  209. revisions: []*apps.ControllerRevision{ss1Rev1, ss1Rev2, ss2Rev1},
  210. want: map[string]bool{ss1Rev1.Name: true, ss1Rev2.Name: true},
  211. },
  212. {
  213. name: "selects orphans",
  214. parent: &ss1.ObjectMeta,
  215. selector: sel1,
  216. revisions: []*apps.ControllerRevision{ss1Rev1, ss1Rev2, ss1Orphan},
  217. want: map[string]bool{ss1Rev1.Name: true, ss1Rev2.Name: true, ss1Orphan.Name: true},
  218. },
  219. }
  220. for i := range tests {
  221. testFn(&tests[i], t)
  222. }
  223. }
  224. func TestRealHistory_CreateControllerRevision(t *testing.T) {
  225. type testcase struct {
  226. name string
  227. parent metav1.Object
  228. revision *apps.ControllerRevision
  229. existing []struct {
  230. parent metav1.Object
  231. revision *apps.ControllerRevision
  232. }
  233. rename bool
  234. }
  235. testFn := func(test *testcase, t *testing.T) {
  236. client := fake.NewSimpleClientset()
  237. informerFactory := informers.NewSharedInformerFactory(client, controller.NoResyncPeriodFunc())
  238. stop := make(chan struct{})
  239. defer close(stop)
  240. informerFactory.Start(stop)
  241. informer := informerFactory.Apps().V1().ControllerRevisions()
  242. informerFactory.WaitForCacheSync(stop)
  243. history := NewHistory(client, informer.Lister())
  244. var collisionCount int32
  245. for _, item := range test.existing {
  246. _, err := client.AppsV1().ControllerRevisions(item.parent.GetNamespace()).Create(context.TODO(), item.revision, metav1.CreateOptions{})
  247. if err != nil {
  248. t.Fatal(err)
  249. }
  250. }
  251. // Clear collisionCount before creating the test revision
  252. collisionCount = 0
  253. created, err := history.CreateControllerRevision(test.parent, test.revision, &collisionCount)
  254. if err != nil {
  255. t.Errorf("%s: %s", test.name, err)
  256. }
  257. if test.rename {
  258. if created.Name == test.revision.Name {
  259. t.Errorf("%s: wanted rename got %s %s", test.name, created.Name, test.revision.Name)
  260. }
  261. expectedName := ControllerRevisionName(test.parent.GetName(), HashControllerRevision(test.revision, &collisionCount))
  262. if created.Name != expectedName {
  263. t.Errorf("%s: on name collision wanted new name %s got %s", test.name, expectedName, created.Name)
  264. }
  265. // Second name collision will be caused by an identical revision, so no need to do anything
  266. _, err = history.CreateControllerRevision(test.parent, test.revision, &collisionCount)
  267. if err != nil {
  268. t.Errorf("%s: %s", test.name, err)
  269. }
  270. if collisionCount != 1 {
  271. t.Errorf("%s: on second name collision wanted collisionCount 1 got %d", test.name, collisionCount)
  272. }
  273. }
  274. if !test.rename && created.Name != test.revision.Name {
  275. t.Errorf("%s: wanted %s got %s", test.name, test.revision.Name, created.Name)
  276. }
  277. }
  278. ss1 := newStatefulSet(3, "ss1", types.UID("ss1"), map[string]string{"foo": "bar"})
  279. ss1.Status.CollisionCount = new(int32)
  280. ss2 := newStatefulSet(3, "ss2", types.UID("ss2"), map[string]string{"goo": "car"})
  281. ss2.Status.CollisionCount = new(int32)
  282. ss1Rev1, err := NewControllerRevision(ss1, parentKind, ss1.Spec.Template.Labels, rawTemplate(&ss1.Spec.Template), 1, ss1.Status.CollisionCount)
  283. if err != nil {
  284. t.Fatal(err)
  285. }
  286. ss1Rev1.Namespace = ss1.Namespace
  287. // Create a new revision with the same name and hash label as an existing revision, but with
  288. // a different template. This could happen as a result of a hash collision, but in this test
  289. // this situation is created by setting name and hash label to values known to be in use by
  290. // an existing revision.
  291. modTemplate := ss1.Spec.Template.DeepCopy()
  292. modTemplate.Labels["foo"] = "not_bar"
  293. ss1Rev2, err := NewControllerRevision(ss1, parentKind, ss1.Spec.Template.Labels, rawTemplate(modTemplate), 2, ss1.Status.CollisionCount)
  294. ss1Rev2.Name = ss1Rev1.Name
  295. ss1Rev2.Labels[ControllerRevisionHashLabel] = ss1Rev1.Labels[ControllerRevisionHashLabel]
  296. if err != nil {
  297. t.Fatal(err)
  298. }
  299. ss1Rev2.Namespace = ss1.Namespace
  300. ss2Rev1, err := NewControllerRevision(ss2, parentKind, ss2.Spec.Template.Labels, rawTemplate(&ss2.Spec.Template), 1, ss2.Status.CollisionCount)
  301. if err != nil {
  302. t.Fatal(err)
  303. }
  304. ss2Rev1.Namespace = ss2.Namespace
  305. tests := []testcase{
  306. {
  307. name: "creates new",
  308. parent: &ss1.ObjectMeta,
  309. revision: ss1Rev1,
  310. existing: nil,
  311. rename: false,
  312. },
  313. {
  314. name: "create doesn't conflict when parents differ",
  315. parent: &ss2.ObjectMeta,
  316. revision: ss2Rev1,
  317. existing: []struct {
  318. parent metav1.Object
  319. revision *apps.ControllerRevision
  320. }{
  321. {
  322. parent: ss1,
  323. revision: ss1Rev1,
  324. },
  325. },
  326. rename: false,
  327. },
  328. {
  329. name: "create renames on conflict",
  330. parent: &ss1.ObjectMeta,
  331. revision: ss1Rev1,
  332. existing: []struct {
  333. parent metav1.Object
  334. revision *apps.ControllerRevision
  335. }{
  336. {
  337. parent: ss1,
  338. revision: ss1Rev2,
  339. },
  340. },
  341. rename: true,
  342. },
  343. }
  344. for i := range tests {
  345. testFn(&tests[i], t)
  346. }
  347. }
  348. func TestFakeHistory_CreateControllerRevision(t *testing.T) {
  349. type testcase struct {
  350. name string
  351. parent metav1.Object
  352. revision *apps.ControllerRevision
  353. existing []struct {
  354. parent metav1.Object
  355. revision *apps.ControllerRevision
  356. }
  357. rename bool
  358. }
  359. testFn := func(test *testcase, t *testing.T) {
  360. client := fake.NewSimpleClientset()
  361. informerFactory := informers.NewSharedInformerFactory(client, controller.NoResyncPeriodFunc())
  362. stop := make(chan struct{})
  363. defer close(stop)
  364. informerFactory.Start(stop)
  365. informer := informerFactory.Apps().V1().ControllerRevisions()
  366. informerFactory.WaitForCacheSync(stop)
  367. history := NewFakeHistory(informer)
  368. var collisionCount int32
  369. for i := range test.existing {
  370. _, err := history.CreateControllerRevision(test.existing[i].parent, test.existing[i].revision, &collisionCount)
  371. if err != nil {
  372. t.Fatal(err)
  373. }
  374. }
  375. // Clear collisionCount before creating the test revision
  376. collisionCount = 0
  377. created, err := history.CreateControllerRevision(test.parent, test.revision, &collisionCount)
  378. if err != nil {
  379. t.Errorf("%s: %s", test.name, err)
  380. }
  381. if test.rename {
  382. if created.Name == test.revision.Name {
  383. t.Errorf("%s: wanted rename got %s %s", test.name, created.Name, test.revision.Name)
  384. }
  385. expectedName := ControllerRevisionName(test.parent.GetName(), HashControllerRevision(test.revision, &collisionCount))
  386. if created.Name != expectedName {
  387. t.Errorf("%s: on name collision wanted new name %s got %s", test.name, expectedName, created.Name)
  388. }
  389. // Second name collision should have incremented collisionCount to 2
  390. _, err = history.CreateControllerRevision(test.parent, test.revision, &collisionCount)
  391. if err != nil {
  392. t.Errorf("%s: %s", test.name, err)
  393. }
  394. if collisionCount != 2 {
  395. t.Errorf("%s: on second name collision wanted collisionCount 1 got %d", test.name, collisionCount)
  396. }
  397. }
  398. if !test.rename && created.Name != test.revision.Name {
  399. t.Errorf("%s: wanted %s got %s", test.name, test.revision.Name, created.Name)
  400. }
  401. }
  402. ss1 := newStatefulSet(3, "ss1", types.UID("ss1"), map[string]string{"foo": "bar"})
  403. ss1.Status.CollisionCount = new(int32)
  404. ss2 := newStatefulSet(3, "ss2", types.UID("ss2"), map[string]string{"goo": "car"})
  405. ss2.Status.CollisionCount = new(int32)
  406. ss1Rev1, err := NewControllerRevision(ss1, parentKind, ss1.Spec.Template.Labels, rawTemplate(&ss1.Spec.Template), 1, ss1.Status.CollisionCount)
  407. if err != nil {
  408. t.Fatal(err)
  409. }
  410. ss1Rev1.Namespace = ss1.Namespace
  411. ss1Rev2, err := NewControllerRevision(ss1, parentKind, ss1.Spec.Template.Labels, rawTemplate(&ss1.Spec.Template), 2, ss1.Status.CollisionCount)
  412. if err != nil {
  413. t.Fatal(err)
  414. }
  415. ss1Rev2.Namespace = ss1.Namespace
  416. ss2Rev1, err := NewControllerRevision(ss2, parentKind, ss2.Spec.Template.Labels, rawTemplate(&ss2.Spec.Template), 1, ss2.Status.CollisionCount)
  417. if err != nil {
  418. t.Fatal(err)
  419. }
  420. ss2Rev1.Namespace = ss2.Namespace
  421. tests := []testcase{
  422. {
  423. name: "creates new",
  424. parent: &ss1.ObjectMeta,
  425. revision: ss1Rev1,
  426. existing: nil,
  427. rename: false,
  428. },
  429. {
  430. name: "create doesn't conflict when parents differ",
  431. parent: &ss2.ObjectMeta,
  432. revision: ss2Rev1,
  433. existing: []struct {
  434. parent metav1.Object
  435. revision *apps.ControllerRevision
  436. }{
  437. {
  438. parent: ss1,
  439. revision: ss1Rev1,
  440. },
  441. },
  442. rename: false,
  443. },
  444. {
  445. name: "create renames on conflict",
  446. parent: &ss1.ObjectMeta,
  447. revision: ss1Rev1,
  448. existing: []struct {
  449. parent metav1.Object
  450. revision *apps.ControllerRevision
  451. }{
  452. {
  453. parent: ss1,
  454. revision: ss1Rev1,
  455. },
  456. },
  457. rename: true,
  458. },
  459. }
  460. for i := range tests {
  461. testFn(&tests[i], t)
  462. }
  463. }
  464. func TestRealHistory_UpdateControllerRevision(t *testing.T) {
  465. conflictAttempts := 0
  466. type testcase struct {
  467. name string
  468. revision *apps.ControllerRevision
  469. newRevision int64
  470. existing []struct {
  471. parent metav1.Object
  472. revision *apps.ControllerRevision
  473. }
  474. reactor core.ReactionFunc
  475. err bool
  476. }
  477. conflictSuccess := func(action core.Action) (bool, runtime.Object, error) {
  478. defer func() {
  479. conflictAttempts++
  480. }()
  481. switch action.(type) {
  482. case core.UpdateActionImpl:
  483. update := action.(core.UpdateAction)
  484. if conflictAttempts < 2 {
  485. return true, update.GetObject(), errors.NewConflict(update.GetResource().GroupResource(), "", fmt.Errorf("conflict"))
  486. }
  487. return true, update.GetObject(), nil
  488. default:
  489. return false, nil, nil
  490. }
  491. }
  492. internalError := func(action core.Action) (bool, runtime.Object, error) {
  493. switch action.(type) {
  494. case core.UpdateActionImpl:
  495. return true, nil, errors.NewInternalError(fmt.Errorf("internal error"))
  496. default:
  497. return false, nil, nil
  498. }
  499. }
  500. testFn := func(test *testcase, t *testing.T) {
  501. client := fake.NewSimpleClientset()
  502. informerFactory := informers.NewSharedInformerFactory(client, controller.NoResyncPeriodFunc())
  503. stop := make(chan struct{})
  504. defer close(stop)
  505. informerFactory.Start(stop)
  506. informer := informerFactory.Apps().V1().ControllerRevisions()
  507. informerFactory.WaitForCacheSync(stop)
  508. history := NewHistory(client, informer.Lister())
  509. var collisionCount int32
  510. for i := range test.existing {
  511. _, err := history.CreateControllerRevision(test.existing[i].parent, test.existing[i].revision, &collisionCount)
  512. if err != nil {
  513. t.Fatal(err)
  514. }
  515. }
  516. if test.reactor != nil {
  517. client.PrependReactor("*", "*", test.reactor)
  518. }
  519. updated, err := history.UpdateControllerRevision(test.revision, test.newRevision)
  520. if !test.err && err != nil {
  521. t.Errorf("%s: %s", test.name, err)
  522. }
  523. if !test.err && updated.Revision != test.newRevision {
  524. t.Errorf("%s: got %d want %d", test.name, updated.Revision, test.newRevision)
  525. }
  526. if test.err && err == nil {
  527. t.Errorf("%s: expected error", test.name)
  528. }
  529. }
  530. ss1 := newStatefulSet(3, "ss1", types.UID("ss1"), map[string]string{"foo": "bar"})
  531. ss1.Status.CollisionCount = new(int32)
  532. ss1Rev1, err := NewControllerRevision(ss1, parentKind, ss1.Spec.Template.Labels, rawTemplate(&ss1.Spec.Template), 1, ss1.Status.CollisionCount)
  533. if err != nil {
  534. t.Fatal(err)
  535. }
  536. ss1Rev1.Namespace = ss1.Namespace
  537. ss1Rev2, err := NewControllerRevision(ss1, parentKind, ss1.Spec.Template.Labels, rawTemplate(&ss1.Spec.Template), 2, ss1.Status.CollisionCount)
  538. if err != nil {
  539. t.Fatal(err)
  540. }
  541. ss1Rev2.Namespace = ss1.Namespace
  542. tests := []testcase{
  543. {
  544. name: "update succeeds",
  545. revision: ss1Rev1,
  546. newRevision: ss1Rev1.Revision + 1,
  547. existing: []struct {
  548. parent metav1.Object
  549. revision *apps.ControllerRevision
  550. }{
  551. {
  552. parent: ss1,
  553. revision: ss1Rev1,
  554. },
  555. },
  556. reactor: nil,
  557. err: false,
  558. },
  559. {
  560. name: "update succeeds no noop",
  561. revision: ss1Rev1,
  562. newRevision: ss1Rev1.Revision,
  563. existing: []struct {
  564. parent metav1.Object
  565. revision *apps.ControllerRevision
  566. }{
  567. {
  568. parent: ss1,
  569. revision: ss1Rev1,
  570. },
  571. },
  572. reactor: nil,
  573. err: false,
  574. }, {
  575. name: "update fails on error",
  576. revision: ss1Rev1,
  577. newRevision: ss1Rev1.Revision + 10,
  578. existing: []struct {
  579. parent metav1.Object
  580. revision *apps.ControllerRevision
  581. }{
  582. {
  583. parent: ss1,
  584. revision: ss1Rev1,
  585. },
  586. },
  587. reactor: internalError,
  588. err: true,
  589. },
  590. {
  591. name: "update on succeeds on conflict",
  592. revision: ss1Rev1,
  593. newRevision: ss1Rev1.Revision + 1,
  594. existing: []struct {
  595. parent metav1.Object
  596. revision *apps.ControllerRevision
  597. }{
  598. {
  599. parent: ss1,
  600. revision: ss1Rev1,
  601. },
  602. },
  603. reactor: conflictSuccess,
  604. err: false,
  605. },
  606. }
  607. for i := range tests {
  608. conflictAttempts = 0
  609. testFn(&tests[i], t)
  610. }
  611. }
  612. func TestFakeHistory_UpdateControllerRevision(t *testing.T) {
  613. type testcase struct {
  614. name string
  615. revision *apps.ControllerRevision
  616. newRevision int64
  617. existing []struct {
  618. parent metav1.Object
  619. revision *apps.ControllerRevision
  620. }
  621. err bool
  622. }
  623. testFn := func(test *testcase, t *testing.T) {
  624. client := fake.NewSimpleClientset()
  625. informerFactory := informers.NewSharedInformerFactory(client, controller.NoResyncPeriodFunc())
  626. stop := make(chan struct{})
  627. defer close(stop)
  628. informerFactory.Start(stop)
  629. informer := informerFactory.Apps().V1().ControllerRevisions()
  630. informerFactory.WaitForCacheSync(stop)
  631. history := NewFakeHistory(informer)
  632. var collisionCount int32
  633. for i := range test.existing {
  634. _, err := history.CreateControllerRevision(test.existing[i].parent, test.existing[i].revision, &collisionCount)
  635. if err != nil {
  636. t.Fatal(err)
  637. }
  638. }
  639. updated, err := history.UpdateControllerRevision(test.revision, test.newRevision)
  640. if !test.err && err != nil {
  641. t.Errorf("%s: %s", test.name, err)
  642. }
  643. if !test.err && updated.Revision != test.newRevision {
  644. t.Errorf("%s: got %d want %d", test.name, updated.Revision, test.newRevision)
  645. }
  646. if test.err && err == nil {
  647. t.Errorf("%s: expected error", test.name)
  648. }
  649. }
  650. ss1 := newStatefulSet(3, "ss1", types.UID("ss1"), map[string]string{"foo": "bar"})
  651. ss1.Status.CollisionCount = new(int32)
  652. ss1Rev1, err := NewControllerRevision(ss1, parentKind, ss1.Spec.Template.Labels, rawTemplate(&ss1.Spec.Template), 1, ss1.Status.CollisionCount)
  653. if err != nil {
  654. t.Fatal(err)
  655. }
  656. ss1Rev1.Namespace = ss1.Namespace
  657. ss1Rev2, err := NewControllerRevision(ss1, parentKind, ss1.Spec.Template.Labels, rawTemplate(&ss1.Spec.Template), 2, ss1.Status.CollisionCount)
  658. if err != nil {
  659. t.Fatal(err)
  660. }
  661. ss1Rev2.Namespace = ss1.Namespace
  662. tests := []testcase{
  663. {
  664. name: "update succeeds",
  665. revision: ss1Rev1,
  666. newRevision: ss1Rev1.Revision + 1,
  667. existing: []struct {
  668. parent metav1.Object
  669. revision *apps.ControllerRevision
  670. }{
  671. {
  672. parent: ss1,
  673. revision: ss1Rev1,
  674. },
  675. },
  676. err: false,
  677. },
  678. {
  679. name: "update succeeds no noop",
  680. revision: ss1Rev1,
  681. newRevision: ss1Rev1.Revision,
  682. existing: []struct {
  683. parent metav1.Object
  684. revision *apps.ControllerRevision
  685. }{
  686. {
  687. parent: ss1,
  688. revision: ss1Rev1,
  689. },
  690. },
  691. err: false,
  692. },
  693. }
  694. for i := range tests {
  695. testFn(&tests[i], t)
  696. }
  697. }
  698. func TestRealHistory_DeleteControllerRevision(t *testing.T) {
  699. type testcase struct {
  700. name string
  701. revision *apps.ControllerRevision
  702. existing []struct {
  703. parent metav1.Object
  704. revision *apps.ControllerRevision
  705. }
  706. err bool
  707. }
  708. testFn := func(test *testcase, t *testing.T) {
  709. client := fake.NewSimpleClientset()
  710. informerFactory := informers.NewSharedInformerFactory(client, controller.NoResyncPeriodFunc())
  711. stop := make(chan struct{})
  712. defer close(stop)
  713. informerFactory.Start(stop)
  714. informer := informerFactory.Apps().V1().ControllerRevisions()
  715. informerFactory.WaitForCacheSync(stop)
  716. history := NewHistory(client, informer.Lister())
  717. var collisionCount int32
  718. for i := range test.existing {
  719. _, err := history.CreateControllerRevision(test.existing[i].parent, test.existing[i].revision, &collisionCount)
  720. if err != nil {
  721. t.Fatal(err)
  722. }
  723. }
  724. err := history.DeleteControllerRevision(test.revision)
  725. if !test.err && err != nil {
  726. t.Errorf("%s: %s", test.name, err)
  727. }
  728. if test.err && err == nil {
  729. t.Errorf("%s: expected error", test.name)
  730. }
  731. }
  732. ss1 := newStatefulSet(3, "ss1", types.UID("ss1"), map[string]string{"foo": "bar"})
  733. ss1.Status.CollisionCount = new(int32)
  734. ss2 := newStatefulSet(3, "ss2", types.UID("ss2"), map[string]string{"goo": "car"})
  735. ss2.Status.CollisionCount = new(int32)
  736. ss1Rev1, err := NewControllerRevision(ss1, parentKind, ss1.Spec.Template.Labels, rawTemplate(&ss1.Spec.Template), 1, ss1.Status.CollisionCount)
  737. if err != nil {
  738. t.Fatal(err)
  739. }
  740. ss1Rev1.Namespace = ss1.Namespace
  741. ss1Rev2, err := NewControllerRevision(ss1, parentKind, ss1.Spec.Template.Labels, rawTemplate(&ss1.Spec.Template), 2, ss1.Status.CollisionCount)
  742. if err != nil {
  743. t.Fatal(err)
  744. }
  745. ss1Rev2.Namespace = ss1.Namespace
  746. ss2Rev1, err := NewControllerRevision(ss2, parentKind, ss2.Spec.Template.Labels, rawTemplate(&ss2.Spec.Template), 1, ss2.Status.CollisionCount)
  747. if err != nil {
  748. t.Fatal(err)
  749. }
  750. ss2Rev1.Namespace = ss2.Namespace
  751. ss2Rev2, err := NewControllerRevision(ss2, parentKind, ss2.Spec.Template.Labels, rawTemplate(&ss2.Spec.Template), 2, ss2.Status.CollisionCount)
  752. if err != nil {
  753. t.Fatal(err)
  754. }
  755. ss2Rev2.Namespace = ss2.Namespace
  756. tests := []testcase{
  757. {
  758. name: "delete empty fails",
  759. revision: ss1Rev1,
  760. existing: nil,
  761. err: true,
  762. },
  763. {
  764. name: "delete existing succeeds",
  765. revision: ss1Rev1,
  766. existing: []struct {
  767. parent metav1.Object
  768. revision *apps.ControllerRevision
  769. }{
  770. {
  771. parent: ss1,
  772. revision: ss1Rev1,
  773. },
  774. },
  775. err: false,
  776. }, {
  777. name: "delete non-existing fails",
  778. revision: ss1Rev1,
  779. existing: []struct {
  780. parent metav1.Object
  781. revision *apps.ControllerRevision
  782. }{
  783. {
  784. parent: ss2,
  785. revision: ss2Rev1,
  786. },
  787. {
  788. parent: ss2,
  789. revision: ss2Rev2,
  790. },
  791. },
  792. err: true,
  793. },
  794. }
  795. for i := range tests {
  796. testFn(&tests[i], t)
  797. }
  798. }
  799. func TestFakeHistory_DeleteControllerRevision(t *testing.T) {
  800. type testcase struct {
  801. name string
  802. revision *apps.ControllerRevision
  803. existing []struct {
  804. parent metav1.Object
  805. revision *apps.ControllerRevision
  806. }
  807. err bool
  808. }
  809. testFn := func(test *testcase, t *testing.T) {
  810. client := fake.NewSimpleClientset()
  811. informerFactory := informers.NewSharedInformerFactory(client, controller.NoResyncPeriodFunc())
  812. stop := make(chan struct{})
  813. defer close(stop)
  814. informerFactory.Start(stop)
  815. informer := informerFactory.Apps().V1().ControllerRevisions()
  816. informerFactory.WaitForCacheSync(stop)
  817. history := NewFakeHistory(informer)
  818. var collisionCount int32
  819. for i := range test.existing {
  820. _, err := history.CreateControllerRevision(test.existing[i].parent, test.existing[i].revision, &collisionCount)
  821. if err != nil {
  822. t.Fatal(err)
  823. }
  824. }
  825. err := history.DeleteControllerRevision(test.revision)
  826. if !test.err && err != nil {
  827. t.Errorf("%s: %s", test.name, err)
  828. }
  829. if test.err && err == nil {
  830. t.Errorf("%s: expected error", test.name)
  831. }
  832. }
  833. ss1 := newStatefulSet(3, "ss1", types.UID("ss1"), map[string]string{"foo": "bar"})
  834. ss1.Status.CollisionCount = new(int32)
  835. ss2 := newStatefulSet(3, "ss2", types.UID("ss2"), map[string]string{"goo": "car"})
  836. ss2.Status.CollisionCount = new(int32)
  837. ss1Rev1, err := NewControllerRevision(ss1, parentKind, ss1.Spec.Template.Labels, rawTemplate(&ss1.Spec.Template), 1, ss1.Status.CollisionCount)
  838. if err != nil {
  839. t.Fatal(err)
  840. }
  841. ss1Rev1.Namespace = ss1.Namespace
  842. ss1Rev2, err := NewControllerRevision(ss1, parentKind, ss1.Spec.Template.Labels, rawTemplate(&ss1.Spec.Template), 2, ss1.Status.CollisionCount)
  843. if err != nil {
  844. t.Fatal(err)
  845. }
  846. ss1Rev2.Namespace = ss1.Namespace
  847. ss2Rev1, err := NewControllerRevision(ss2, parentKind, ss2.Spec.Template.Labels, rawTemplate(&ss2.Spec.Template), 1, ss2.Status.CollisionCount)
  848. if err != nil {
  849. t.Fatal(err)
  850. }
  851. ss2Rev1.Namespace = ss2.Namespace
  852. ss2Rev2, err := NewControllerRevision(ss2, parentKind, ss2.Spec.Template.Labels, rawTemplate(&ss2.Spec.Template), 2, ss2.Status.CollisionCount)
  853. if err != nil {
  854. t.Fatal(err)
  855. }
  856. ss2Rev2.Namespace = ss2.Namespace
  857. tests := []testcase{
  858. {
  859. name: "delete empty fails",
  860. revision: ss1Rev1,
  861. existing: nil,
  862. err: true,
  863. },
  864. {
  865. name: "delete existing succeeds",
  866. revision: ss1Rev1,
  867. existing: []struct {
  868. parent metav1.Object
  869. revision *apps.ControllerRevision
  870. }{
  871. {
  872. parent: ss1,
  873. revision: ss1Rev1,
  874. },
  875. },
  876. err: false,
  877. }, {
  878. name: "delete non-existing fails",
  879. revision: ss1Rev1,
  880. existing: []struct {
  881. parent metav1.Object
  882. revision *apps.ControllerRevision
  883. }{
  884. {
  885. parent: ss2,
  886. revision: ss2Rev1,
  887. },
  888. {
  889. parent: ss2,
  890. revision: ss2Rev2,
  891. },
  892. },
  893. err: true,
  894. },
  895. }
  896. for i := range tests {
  897. testFn(&tests[i], t)
  898. }
  899. }
  900. func TestRealHistory_AdoptControllerRevision(t *testing.T) {
  901. type testcase struct {
  902. name string
  903. parent metav1.Object
  904. revision *apps.ControllerRevision
  905. existing []struct {
  906. parent metav1.Object
  907. revision *apps.ControllerRevision
  908. }
  909. err bool
  910. }
  911. testFn := func(test *testcase, t *testing.T) {
  912. client := fake.NewSimpleClientset()
  913. client.AddReactor("*", "*", func(action core.Action) (bool, runtime.Object, error) {
  914. switch action := action.(type) {
  915. case core.PatchActionImpl:
  916. var found *apps.ControllerRevision
  917. for i := range test.existing {
  918. if test.revision.Name == test.existing[i].revision.Name &&
  919. test.revision.Namespace == test.existing[i].revision.Namespace {
  920. found = test.existing[i].revision
  921. break
  922. }
  923. }
  924. if found == nil {
  925. return true, nil, errors.NewNotFound(apps.Resource("controllerrevisions"), test.revision.Name)
  926. }
  927. b, err := strategicpatch.StrategicMergePatch(
  928. []byte(runtime.EncodeOrDie(clientscheme.Codecs.LegacyCodec(apps.SchemeGroupVersion), test.revision)),
  929. action.GetPatch(), test.revision)
  930. if err != nil {
  931. return true, nil, err
  932. }
  933. obj, err := runtime.Decode(clientscheme.Codecs.LegacyCodec(apps.SchemeGroupVersion), b)
  934. if err != nil {
  935. return true, nil, err
  936. }
  937. patched, err := legacyscheme.Scheme.ConvertToVersion(obj, apps.SchemeGroupVersion)
  938. if err != nil {
  939. return true, nil, err
  940. }
  941. return true, patched, err
  942. default:
  943. return false, nil, nil
  944. }
  945. })
  946. informerFactory := informers.NewSharedInformerFactory(client, controller.NoResyncPeriodFunc())
  947. stop := make(chan struct{})
  948. defer close(stop)
  949. informerFactory.Start(stop)
  950. informer := informerFactory.Apps().V1().ControllerRevisions()
  951. informerFactory.WaitForCacheSync(stop)
  952. history := NewHistory(client, informer.Lister())
  953. var collisionCount int32
  954. for i := range test.existing {
  955. _, err := history.CreateControllerRevision(test.existing[i].parent, test.existing[i].revision, &collisionCount)
  956. if err != nil {
  957. t.Fatal(err)
  958. }
  959. }
  960. adopted, err := history.AdoptControllerRevision(test.parent, parentKind, test.revision)
  961. if !test.err && err != nil {
  962. t.Errorf("%s: %s", test.name, err)
  963. }
  964. if !test.err && !metav1.IsControlledBy(adopted, test.parent) {
  965. t.Errorf("%s: adoption failed", test.name)
  966. }
  967. if test.err && err == nil {
  968. t.Errorf("%s: expected error", test.name)
  969. }
  970. }
  971. ss1 := newStatefulSet(3, "ss1", types.UID("ss1"), map[string]string{"foo": "bar"})
  972. ss1.Status.CollisionCount = new(int32)
  973. ss2 := newStatefulSet(3, "ss2", types.UID("ss2"), map[string]string{"goo": "car"})
  974. ss2.Status.CollisionCount = new(int32)
  975. ss1Rev1, err := NewControllerRevision(ss1, parentKind, ss1.Spec.Template.Labels, rawTemplate(&ss1.Spec.Template), 1, ss1.Status.CollisionCount)
  976. if err != nil {
  977. t.Fatal(err)
  978. }
  979. ss1Rev1.Namespace = ss1.Namespace
  980. ss1Rev2, err := NewControllerRevision(ss1, parentKind, ss1.Spec.Template.Labels, rawTemplate(&ss1.Spec.Template), 2, ss1.Status.CollisionCount)
  981. if err != nil {
  982. t.Fatal(err)
  983. }
  984. ss1Rev2.Namespace = ss1.Namespace
  985. ss1Rev2.OwnerReferences = []metav1.OwnerReference{}
  986. ss2Rev1, err := NewControllerRevision(ss2, parentKind, ss2.Spec.Template.Labels, rawTemplate(&ss2.Spec.Template), 1, ss2.Status.CollisionCount)
  987. if err != nil {
  988. t.Fatal(err)
  989. }
  990. ss2Rev1.Namespace = ss2.Namespace
  991. tests := []testcase{
  992. {
  993. name: "adopting an orphan succeeds",
  994. parent: ss1,
  995. revision: ss1Rev2,
  996. existing: []struct {
  997. parent metav1.Object
  998. revision *apps.ControllerRevision
  999. }{
  1000. {
  1001. parent: ss1,
  1002. revision: ss1Rev2,
  1003. },
  1004. },
  1005. err: false,
  1006. },
  1007. {
  1008. name: "adopting an owned revision fails",
  1009. parent: ss1,
  1010. revision: ss2Rev1,
  1011. existing: []struct {
  1012. parent metav1.Object
  1013. revision *apps.ControllerRevision
  1014. }{
  1015. {
  1016. parent: ss2,
  1017. revision: ss2Rev1,
  1018. },
  1019. },
  1020. err: true,
  1021. },
  1022. {
  1023. name: "adopting a non-existent revision fails",
  1024. parent: ss1,
  1025. revision: ss1Rev2,
  1026. existing: nil,
  1027. err: true,
  1028. },
  1029. }
  1030. for i := range tests {
  1031. testFn(&tests[i], t)
  1032. }
  1033. }
  1034. func TestFakeHistory_AdoptControllerRevision(t *testing.T) {
  1035. type testcase struct {
  1036. name string
  1037. parent metav1.Object
  1038. parentType *metav1.TypeMeta
  1039. revision *apps.ControllerRevision
  1040. existing []struct {
  1041. parent metav1.Object
  1042. revision *apps.ControllerRevision
  1043. }
  1044. err bool
  1045. }
  1046. testFn := func(test *testcase, t *testing.T) {
  1047. client := fake.NewSimpleClientset()
  1048. informerFactory := informers.NewSharedInformerFactory(client, controller.NoResyncPeriodFunc())
  1049. stop := make(chan struct{})
  1050. defer close(stop)
  1051. informerFactory.Start(stop)
  1052. informer := informerFactory.Apps().V1().ControllerRevisions()
  1053. informerFactory.WaitForCacheSync(stop)
  1054. history := NewFakeHistory(informer)
  1055. var collisionCount int32
  1056. for i := range test.existing {
  1057. _, err := history.CreateControllerRevision(test.existing[i].parent, test.existing[i].revision, &collisionCount)
  1058. if err != nil {
  1059. t.Fatal(err)
  1060. }
  1061. }
  1062. adopted, err := history.AdoptControllerRevision(test.parent, parentKind, test.revision)
  1063. if !test.err && err != nil {
  1064. t.Errorf("%s: %s", test.name, err)
  1065. }
  1066. if !test.err && !metav1.IsControlledBy(adopted, test.parent) {
  1067. t.Errorf("%s: adoption failed", test.name)
  1068. }
  1069. if test.err && err == nil {
  1070. t.Errorf("%s: expected error", test.name)
  1071. }
  1072. }
  1073. ss1 := newStatefulSet(3, "ss1", types.UID("ss1"), map[string]string{"foo": "bar"})
  1074. ss1.Status.CollisionCount = new(int32)
  1075. ss2 := newStatefulSet(3, "ss2", types.UID("ss2"), map[string]string{"goo": "car"})
  1076. ss2.Status.CollisionCount = new(int32)
  1077. ss1Rev1, err := NewControllerRevision(ss1, parentKind, ss1.Spec.Template.Labels, rawTemplate(&ss1.Spec.Template), 1, ss1.Status.CollisionCount)
  1078. if err != nil {
  1079. t.Fatal(err)
  1080. }
  1081. ss1Rev1.Namespace = ss1.Namespace
  1082. ss1Rev2, err := NewControllerRevision(ss1, parentKind, ss1.Spec.Template.Labels, rawTemplate(&ss1.Spec.Template), 2, ss1.Status.CollisionCount)
  1083. if err != nil {
  1084. t.Fatal(err)
  1085. }
  1086. ss1Rev2.Namespace = ss1.Namespace
  1087. ss1Rev2.OwnerReferences = []metav1.OwnerReference{}
  1088. ss2Rev1, err := NewControllerRevision(ss2, parentKind, ss2.Spec.Template.Labels, rawTemplate(&ss2.Spec.Template), 1, ss2.Status.CollisionCount)
  1089. if err != nil {
  1090. t.Fatal(err)
  1091. }
  1092. ss2Rev1.Namespace = ss2.Namespace
  1093. tests := []testcase{
  1094. {
  1095. name: "adopting an orphan succeeds",
  1096. parent: ss1,
  1097. parentType: &ss1.TypeMeta,
  1098. revision: ss1Rev2,
  1099. existing: []struct {
  1100. parent metav1.Object
  1101. revision *apps.ControllerRevision
  1102. }{
  1103. {
  1104. parent: ss1,
  1105. revision: ss1Rev2,
  1106. },
  1107. },
  1108. err: false,
  1109. },
  1110. {
  1111. name: "adopting an owned revision fails",
  1112. parent: ss1,
  1113. parentType: &ss1.TypeMeta,
  1114. revision: ss2Rev1,
  1115. existing: []struct {
  1116. parent metav1.Object
  1117. revision *apps.ControllerRevision
  1118. }{
  1119. {
  1120. parent: ss2,
  1121. revision: ss2Rev1,
  1122. },
  1123. },
  1124. err: true,
  1125. },
  1126. {
  1127. name: "adopting a non-existent revision fails",
  1128. parent: ss1,
  1129. parentType: &ss1.TypeMeta,
  1130. revision: ss1Rev2,
  1131. existing: nil,
  1132. err: true,
  1133. },
  1134. }
  1135. for i := range tests {
  1136. testFn(&tests[i], t)
  1137. }
  1138. }
  1139. func TestRealHistory_ReleaseControllerRevision(t *testing.T) {
  1140. type testcase struct {
  1141. name string
  1142. parent metav1.Object
  1143. revision *apps.ControllerRevision
  1144. existing []struct {
  1145. parent metav1.Object
  1146. revision *apps.ControllerRevision
  1147. }
  1148. err bool
  1149. }
  1150. testFn := func(test *testcase, t *testing.T) {
  1151. client := fake.NewSimpleClientset()
  1152. client.AddReactor("*", "*", func(action core.Action) (bool, runtime.Object, error) {
  1153. switch action := action.(type) {
  1154. case core.PatchActionImpl:
  1155. var found *apps.ControllerRevision
  1156. for i := range test.existing {
  1157. if test.revision.Name == test.existing[i].revision.Name &&
  1158. test.revision.Namespace == test.existing[i].revision.Namespace {
  1159. found = test.existing[i].revision
  1160. break
  1161. }
  1162. }
  1163. if found == nil {
  1164. return true, nil, errors.NewNotFound(apps.Resource("controllerrevisions"), test.revision.Name)
  1165. }
  1166. if !metav1.IsControlledBy(test.revision, test.parent) {
  1167. return true, nil, errors.NewInvalid(
  1168. test.revision.GroupVersionKind().GroupKind(), test.revision.Name, nil)
  1169. }
  1170. b, err := strategicpatch.StrategicMergePatch(
  1171. []byte(runtime.EncodeOrDie(clientscheme.Codecs.LegacyCodec(apps.SchemeGroupVersion), test.revision)),
  1172. action.GetPatch(), test.revision)
  1173. if err != nil {
  1174. return true, nil, err
  1175. }
  1176. obj, err := runtime.Decode(clientscheme.Codecs.LegacyCodec(apps.SchemeGroupVersion), b)
  1177. if err != nil {
  1178. return true, nil, err
  1179. }
  1180. patched, err := legacyscheme.Scheme.ConvertToVersion(obj, apps.SchemeGroupVersion)
  1181. if err != nil {
  1182. return true, nil, err
  1183. }
  1184. return true, patched, err
  1185. default:
  1186. return false, nil, nil
  1187. }
  1188. })
  1189. informerFactory := informers.NewSharedInformerFactory(client, controller.NoResyncPeriodFunc())
  1190. stop := make(chan struct{})
  1191. defer close(stop)
  1192. informerFactory.Start(stop)
  1193. informer := informerFactory.Apps().V1().ControllerRevisions()
  1194. informerFactory.WaitForCacheSync(stop)
  1195. history := NewHistory(client, informer.Lister())
  1196. var collisionCount int32
  1197. for i := range test.existing {
  1198. _, err := history.CreateControllerRevision(test.existing[i].parent, test.existing[i].revision, &collisionCount)
  1199. if err != nil {
  1200. t.Fatal(err)
  1201. }
  1202. }
  1203. adopted, err := history.ReleaseControllerRevision(test.parent, test.revision)
  1204. if !test.err {
  1205. if err != nil {
  1206. t.Errorf("%s: %s", test.name, err)
  1207. }
  1208. if adopted == nil {
  1209. return
  1210. }
  1211. if metav1.IsControlledBy(adopted, test.parent) {
  1212. t.Errorf("%s: release failed", test.name)
  1213. }
  1214. }
  1215. if test.err && err == nil {
  1216. t.Errorf("%s: expected error", test.name)
  1217. }
  1218. }
  1219. ss1 := newStatefulSet(3, "ss1", types.UID("ss1"), map[string]string{"foo": "bar"})
  1220. ss2 := newStatefulSet(3, "ss2", types.UID("ss2"), map[string]string{"goo": "car"})
  1221. ss1Rev1, err := NewControllerRevision(ss1, parentKind, ss1.Spec.Template.Labels, rawTemplate(&ss1.Spec.Template), 1, nil)
  1222. if err != nil {
  1223. t.Fatal(err)
  1224. }
  1225. ss1Rev1.Namespace = ss1.Namespace
  1226. ss1Rev2, err := NewControllerRevision(ss1, parentKind, ss1.Spec.Template.Labels, rawTemplate(&ss1.Spec.Template), 2, nil)
  1227. if err != nil {
  1228. t.Fatal(err)
  1229. }
  1230. ss1Rev2.Namespace = ss1.Namespace
  1231. ss1Rev2.OwnerReferences = []metav1.OwnerReference{}
  1232. ss2Rev1, err := NewControllerRevision(ss2, parentKind, ss2.Spec.Template.Labels, rawTemplate(&ss2.Spec.Template), 1, nil)
  1233. if err != nil {
  1234. t.Fatal(err)
  1235. }
  1236. ss2Rev1.Namespace = ss2.Namespace
  1237. tests := []testcase{
  1238. {
  1239. name: "releasing an owned revision succeeds",
  1240. parent: ss1,
  1241. revision: ss1Rev1,
  1242. existing: []struct {
  1243. parent metav1.Object
  1244. revision *apps.ControllerRevision
  1245. }{
  1246. {
  1247. parent: ss1,
  1248. revision: ss1Rev1,
  1249. },
  1250. },
  1251. err: false,
  1252. },
  1253. {
  1254. name: "releasing an orphan succeeds",
  1255. parent: ss1,
  1256. revision: ss1Rev2,
  1257. existing: []struct {
  1258. parent metav1.Object
  1259. revision *apps.ControllerRevision
  1260. }{
  1261. {
  1262. parent: ss1,
  1263. revision: ss1Rev2,
  1264. },
  1265. },
  1266. err: false,
  1267. },
  1268. {
  1269. name: "releasing a revision owned by another controller succeeds",
  1270. parent: ss1,
  1271. revision: ss2Rev1,
  1272. existing: []struct {
  1273. parent metav1.Object
  1274. revision *apps.ControllerRevision
  1275. }{
  1276. {
  1277. parent: ss2,
  1278. revision: ss2Rev1,
  1279. },
  1280. },
  1281. err: false,
  1282. },
  1283. {
  1284. name: "releasing a non-existent revision succeeds",
  1285. parent: ss1,
  1286. revision: ss1Rev1,
  1287. existing: nil,
  1288. err: false,
  1289. },
  1290. }
  1291. for i := range tests {
  1292. testFn(&tests[i], t)
  1293. }
  1294. }
  1295. func TestFakeHistory_ReleaseControllerRevision(t *testing.T) {
  1296. type testcase struct {
  1297. name string
  1298. parent metav1.Object
  1299. revision *apps.ControllerRevision
  1300. existing []struct {
  1301. parent metav1.Object
  1302. revision *apps.ControllerRevision
  1303. }
  1304. err bool
  1305. }
  1306. testFn := func(test *testcase, t *testing.T) {
  1307. client := fake.NewSimpleClientset()
  1308. informerFactory := informers.NewSharedInformerFactory(client, controller.NoResyncPeriodFunc())
  1309. stop := make(chan struct{})
  1310. defer close(stop)
  1311. informerFactory.Start(stop)
  1312. informer := informerFactory.Apps().V1().ControllerRevisions()
  1313. informerFactory.WaitForCacheSync(stop)
  1314. history := NewFakeHistory(informer)
  1315. var collisionCount int32
  1316. for i := range test.existing {
  1317. _, err := history.CreateControllerRevision(test.existing[i].parent, test.existing[i].revision, &collisionCount)
  1318. if err != nil {
  1319. t.Fatal(err)
  1320. }
  1321. }
  1322. adopted, err := history.ReleaseControllerRevision(test.parent, test.revision)
  1323. if !test.err {
  1324. if err != nil {
  1325. t.Errorf("%s: %s", test.name, err)
  1326. }
  1327. if adopted == nil {
  1328. return
  1329. }
  1330. if metav1.IsControlledBy(adopted, test.parent) {
  1331. t.Errorf("%s: release failed", test.name)
  1332. }
  1333. }
  1334. if test.err && err == nil {
  1335. t.Errorf("%s: expected error", test.name)
  1336. }
  1337. }
  1338. ss1 := newStatefulSet(3, "ss1", types.UID("ss1"), map[string]string{"foo": "bar"})
  1339. ss1.Status.CollisionCount = new(int32)
  1340. ss2 := newStatefulSet(3, "ss2", types.UID("ss2"), map[string]string{"goo": "car"})
  1341. ss2.Status.CollisionCount = new(int32)
  1342. ss1Rev1, err := NewControllerRevision(ss1, parentKind, ss1.Spec.Template.Labels, rawTemplate(&ss1.Spec.Template), 1, ss1.Status.CollisionCount)
  1343. if err != nil {
  1344. t.Fatal(err)
  1345. }
  1346. ss1Rev1.Namespace = ss1.Namespace
  1347. ss1Rev2, err := NewControllerRevision(ss1, parentKind, ss1.Spec.Template.Labels, rawTemplate(&ss1.Spec.Template), 2, ss1.Status.CollisionCount)
  1348. if err != nil {
  1349. t.Fatal(err)
  1350. }
  1351. ss1Rev2.Namespace = ss1.Namespace
  1352. ss1Rev2.OwnerReferences = []metav1.OwnerReference{}
  1353. ss2Rev1, err := NewControllerRevision(ss2, parentKind, ss2.Spec.Template.Labels, rawTemplate(&ss2.Spec.Template), 1, ss2.Status.CollisionCount)
  1354. if err != nil {
  1355. t.Fatal(err)
  1356. }
  1357. ss2Rev1.Namespace = ss2.Namespace
  1358. tests := []testcase{
  1359. {
  1360. name: "releasing an owned revision succeeds",
  1361. parent: ss1,
  1362. revision: ss1Rev1,
  1363. existing: []struct {
  1364. parent metav1.Object
  1365. revision *apps.ControllerRevision
  1366. }{
  1367. {
  1368. parent: ss1,
  1369. revision: ss1Rev1,
  1370. },
  1371. },
  1372. err: false,
  1373. },
  1374. {
  1375. name: "releasing an orphan succeeds",
  1376. parent: ss1,
  1377. revision: ss1Rev2,
  1378. existing: []struct {
  1379. parent metav1.Object
  1380. revision *apps.ControllerRevision
  1381. }{
  1382. {
  1383. parent: ss1,
  1384. revision: ss1Rev2,
  1385. },
  1386. },
  1387. err: false,
  1388. },
  1389. {
  1390. name: "releasing a revision owned by another controller succeeds",
  1391. parent: ss1,
  1392. revision: ss2Rev1,
  1393. existing: []struct {
  1394. parent metav1.Object
  1395. revision *apps.ControllerRevision
  1396. }{
  1397. {
  1398. parent: ss2,
  1399. revision: ss2Rev1,
  1400. },
  1401. },
  1402. err: false,
  1403. },
  1404. {
  1405. name: "releasing a non-existent revision succeeds",
  1406. parent: ss1,
  1407. revision: ss1Rev1,
  1408. existing: nil,
  1409. err: false,
  1410. },
  1411. }
  1412. for i := range tests {
  1413. testFn(&tests[i], t)
  1414. }
  1415. }
  1416. func TestFindEqualRevisions(t *testing.T) {
  1417. type testcase struct {
  1418. name string
  1419. revision *apps.ControllerRevision
  1420. revisions []*apps.ControllerRevision
  1421. want map[string]bool
  1422. }
  1423. testFn := func(test *testcase, t *testing.T) {
  1424. found := FindEqualRevisions(test.revisions, test.revision)
  1425. if len(found) != len(test.want) {
  1426. t.Errorf("%s: want %d revisions found %d", test.name, len(test.want), len(found))
  1427. }
  1428. for i := range found {
  1429. if !test.want[found[i].Name] {
  1430. t.Errorf("%s: wanted %s not found", test.name, found[i].Name)
  1431. }
  1432. }
  1433. }
  1434. ss1 := newStatefulSet(3, "ss1", types.UID("ss1"), map[string]string{"foo": "bar"})
  1435. ss1.Status.CollisionCount = new(int32)
  1436. ss2 := newStatefulSet(3, "ss2", types.UID("ss2"), map[string]string{"goo": "car"})
  1437. ss2.Status.CollisionCount = new(int32)
  1438. ss1Rev1, err := NewControllerRevision(ss1, parentKind, ss1.Spec.Template.Labels, rawTemplate(&ss1.Spec.Template), 1, ss1.Status.CollisionCount)
  1439. if err != nil {
  1440. t.Fatal(err)
  1441. }
  1442. ss1Rev1.Namespace = ss1.Namespace
  1443. ss1Rev2, err := NewControllerRevision(ss1, parentKind, ss1.Spec.Template.Labels, rawTemplate(&ss1.Spec.Template), 2, ss1.Status.CollisionCount)
  1444. if err != nil {
  1445. t.Fatal(err)
  1446. }
  1447. ss1Rev2.Namespace = ss1.Namespace
  1448. ss1Rev2.OwnerReferences = []metav1.OwnerReference{}
  1449. ss2Rev1, err := NewControllerRevision(ss2, parentKind, ss2.Spec.Template.Labels, rawTemplate(&ss2.Spec.Template), 1, ss2.Status.CollisionCount)
  1450. if err != nil {
  1451. t.Fatal(err)
  1452. }
  1453. ss2Rev1.Namespace = ss2.Namespace
  1454. ss2Rev2, err := NewControllerRevision(ss2, parentKind, ss2.Spec.Template.Labels, rawTemplate(&ss2.Spec.Template), 2, ss2.Status.CollisionCount)
  1455. if err != nil {
  1456. t.Fatal(err)
  1457. }
  1458. ss2Rev2.Namespace = ss2.Namespace
  1459. tests := []testcase{
  1460. {
  1461. name: "finds equivalent",
  1462. revision: ss1Rev1,
  1463. revisions: []*apps.ControllerRevision{ss1Rev1, ss2Rev1, ss2Rev2},
  1464. want: map[string]bool{ss1Rev1.Name: true},
  1465. },
  1466. {
  1467. name: "finds nothing when empty",
  1468. revision: ss1Rev1,
  1469. revisions: nil,
  1470. want: map[string]bool{},
  1471. },
  1472. {
  1473. name: "finds nothing with no matches",
  1474. revision: ss1Rev1,
  1475. revisions: []*apps.ControllerRevision{ss2Rev2, ss2Rev1},
  1476. want: map[string]bool{},
  1477. },
  1478. }
  1479. for i := range tests {
  1480. testFn(&tests[i], t)
  1481. }
  1482. }
  1483. func TestSortControllerRevisions(t *testing.T) {
  1484. type testcase struct {
  1485. name string
  1486. revisions []*apps.ControllerRevision
  1487. want []string
  1488. }
  1489. testFn := func(test *testcase, t *testing.T) {
  1490. t.Run(test.name, func(t *testing.T) {
  1491. SortControllerRevisions(test.revisions)
  1492. for i := range test.revisions {
  1493. if test.revisions[i].Name != test.want[i] {
  1494. t.Errorf("%s: want %s at %d got %s", test.name, test.want[i], i, test.revisions[i].Name)
  1495. }
  1496. }
  1497. })
  1498. }
  1499. ss1 := newStatefulSet(3, "ss1", types.UID("ss1"), map[string]string{"foo": "bar"})
  1500. ss1.Status.CollisionCount = new(int32)
  1501. ss1Rev1, err := NewControllerRevision(ss1, parentKind, ss1.Spec.Template.Labels, rawTemplate(&ss1.Spec.Template), 1, ss1.Status.CollisionCount)
  1502. if err != nil {
  1503. t.Fatal(err)
  1504. }
  1505. ss1Rev1.Namespace = ss1.Namespace
  1506. ss1Rev2, err := NewControllerRevision(ss1, parentKind, ss1.Spec.Template.Labels, rawTemplate(&ss1.Spec.Template), 2, ss1.Status.CollisionCount)
  1507. if err != nil {
  1508. t.Fatal(err)
  1509. }
  1510. ss1Rev2.Namespace = ss1.Namespace
  1511. ss1Rev3, err := NewControllerRevision(ss1, parentKind, ss1.Spec.Template.Labels, rawTemplate(&ss1.Spec.Template), 3, ss1.Status.CollisionCount)
  1512. if err != nil {
  1513. t.Fatal(err)
  1514. }
  1515. ss1Rev3Time2, err := NewControllerRevision(ss1, parentKind, ss1.Spec.Template.Labels, rawTemplate(&ss1.Spec.Template), 3, ss1.Status.CollisionCount)
  1516. if err != nil {
  1517. t.Fatal(err)
  1518. }
  1519. ss1Rev3Time2.Namespace = ss1.Namespace
  1520. ss1Rev3Time2.CreationTimestamp = metav1.Time{Time: ss1Rev3.CreationTimestamp.Add(time.Second)}
  1521. ss1Rev3Time2Name2, err := NewControllerRevision(ss1, parentKind, ss1.Spec.Template.Labels, rawTemplate(&ss1.Spec.Template), 3, ss1.Status.CollisionCount)
  1522. if err != nil {
  1523. t.Fatal(err)
  1524. }
  1525. ss1Rev3Time2Name2.Namespace = ss1.Namespace
  1526. ss1Rev3Time2Name2.CreationTimestamp = metav1.Time{Time: ss1Rev3.CreationTimestamp.Add(time.Second)}
  1527. tests := []testcase{
  1528. {
  1529. name: "out of order",
  1530. revisions: []*apps.ControllerRevision{ss1Rev2, ss1Rev1, ss1Rev3},
  1531. want: []string{ss1Rev1.Name, ss1Rev2.Name, ss1Rev3.Name},
  1532. },
  1533. {
  1534. name: "sorted",
  1535. revisions: []*apps.ControllerRevision{ss1Rev1, ss1Rev2, ss1Rev3},
  1536. want: []string{ss1Rev1.Name, ss1Rev2.Name, ss1Rev3.Name},
  1537. },
  1538. {
  1539. name: "reversed",
  1540. revisions: []*apps.ControllerRevision{ss1Rev3, ss1Rev2, ss1Rev1},
  1541. want: []string{ss1Rev1.Name, ss1Rev2.Name, ss1Rev3.Name},
  1542. },
  1543. {
  1544. name: "with ties",
  1545. revisions: []*apps.ControllerRevision{ss1Rev3, ss1Rev3Time2, ss1Rev2, ss1Rev1},
  1546. want: []string{ss1Rev1.Name, ss1Rev2.Name, ss1Rev3.Name, ss1Rev3Time2.Name, ss1Rev3Time2Name2.Name},
  1547. },
  1548. {
  1549. name: "empty",
  1550. revisions: nil,
  1551. want: nil,
  1552. },
  1553. }
  1554. for i := range tests {
  1555. testFn(&tests[i], t)
  1556. }
  1557. }
  1558. func newStatefulSet(replicas int, name string, uid types.UID, labels map[string]string) *apps.StatefulSet {
  1559. // Converting all the map-only selectors to set-based selectors.
  1560. var testMatchExpressions []metav1.LabelSelectorRequirement
  1561. for key, value := range labels {
  1562. sel := metav1.LabelSelectorRequirement{
  1563. Key: key,
  1564. Operator: metav1.LabelSelectorOpIn,
  1565. Values: []string{value},
  1566. }
  1567. testMatchExpressions = append(testMatchExpressions, sel)
  1568. }
  1569. return &apps.StatefulSet{
  1570. TypeMeta: metav1.TypeMeta{
  1571. Kind: "StatefulSet",
  1572. APIVersion: "apps/v1",
  1573. },
  1574. ObjectMeta: metav1.ObjectMeta{
  1575. Name: name,
  1576. Namespace: v1.NamespaceDefault,
  1577. UID: uid,
  1578. },
  1579. Spec: apps.StatefulSetSpec{
  1580. Selector: &metav1.LabelSelector{
  1581. // Purposely leaving MatchLabels nil, so to ensure it will break if any link
  1582. // in the chain ignores the set-based MatchExpressions.
  1583. MatchLabels: nil,
  1584. MatchExpressions: testMatchExpressions,
  1585. },
  1586. Replicas: func() *int32 { i := int32(replicas); return &i }(),
  1587. Template: v1.PodTemplateSpec{
  1588. ObjectMeta: metav1.ObjectMeta{
  1589. Labels: labels,
  1590. },
  1591. Spec: v1.PodSpec{
  1592. Containers: []v1.Container{
  1593. {
  1594. Name: "nginx",
  1595. Image: "nginx",
  1596. VolumeMounts: []v1.VolumeMount{
  1597. {Name: "datadir", MountPath: "/tmp/"},
  1598. {Name: "home", MountPath: "/home"},
  1599. },
  1600. },
  1601. },
  1602. Volumes: []v1.Volume{{
  1603. Name: "home",
  1604. VolumeSource: v1.VolumeSource{
  1605. HostPath: &v1.HostPathVolumeSource{
  1606. Path: fmt.Sprintf("/tmp/%v", "home"),
  1607. },
  1608. }}},
  1609. },
  1610. },
  1611. VolumeClaimTemplates: []v1.PersistentVolumeClaim{
  1612. {
  1613. ObjectMeta: metav1.ObjectMeta{Name: "datadir"},
  1614. Spec: v1.PersistentVolumeClaimSpec{
  1615. Resources: v1.ResourceRequirements{
  1616. Requests: v1.ResourceList{
  1617. v1.ResourceStorage: *resource.NewQuantity(1, resource.BinarySI),
  1618. },
  1619. },
  1620. },
  1621. },
  1622. },
  1623. ServiceName: "governingsvc",
  1624. },
  1625. }
  1626. }
  1627. var parentKind = apps.SchemeGroupVersion.WithKind("StatefulSet")
  1628. func rawTemplate(template *v1.PodTemplateSpec) runtime.RawExtension {
  1629. buf := new(bytes.Buffer)
  1630. enc := json.NewEncoder(buf)
  1631. if err := enc.Encode(template); err != nil {
  1632. panic(err)
  1633. }
  1634. return runtime.RawExtension{Raw: buf.Bytes()}
  1635. }