range_allocator_test.go 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804
  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 ipam
  14. import (
  15. "context"
  16. "net"
  17. "testing"
  18. "time"
  19. v1 "k8s.io/api/core/v1"
  20. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  21. "k8s.io/apimachinery/pkg/util/wait"
  22. "k8s.io/client-go/informers"
  23. coreinformers "k8s.io/client-go/informers/core/v1"
  24. "k8s.io/client-go/kubernetes/fake"
  25. "k8s.io/kubernetes/pkg/controller"
  26. "k8s.io/kubernetes/pkg/controller/testutil"
  27. )
  28. const (
  29. nodePollInterval = 100 * time.Millisecond
  30. )
  31. var alwaysReady = func() bool { return true }
  32. func waitForUpdatedNodeWithTimeout(nodeHandler *testutil.FakeNodeHandler, number int, timeout time.Duration) error {
  33. return wait.Poll(nodePollInterval, timeout, func() (bool, error) {
  34. if len(nodeHandler.GetUpdatedNodesCopy()) >= number {
  35. return true, nil
  36. }
  37. return false, nil
  38. })
  39. }
  40. // Creates a fakeNodeInformer using the provided fakeNodeHandler.
  41. func getFakeNodeInformer(fakeNodeHandler *testutil.FakeNodeHandler) coreinformers.NodeInformer {
  42. fakeClient := &fake.Clientset{}
  43. fakeInformerFactory := informers.NewSharedInformerFactory(fakeClient, controller.NoResyncPeriodFunc())
  44. fakeNodeInformer := fakeInformerFactory.Core().V1().Nodes()
  45. for _, node := range fakeNodeHandler.Existing {
  46. fakeNodeInformer.Informer().GetStore().Add(node)
  47. }
  48. return fakeNodeInformer
  49. }
  50. type testCase struct {
  51. description string
  52. fakeNodeHandler *testutil.FakeNodeHandler
  53. allocatorParams CIDRAllocatorParams
  54. // key is index of the cidr allocated
  55. expectedAllocatedCIDR map[int]string
  56. allocatedCIDRs map[int][]string
  57. // should controller creation fail?
  58. ctrlCreateFail bool
  59. }
  60. func TestOccupyPreExistingCIDR(t *testing.T) {
  61. // all tests operate on a single node
  62. testCases := []testCase{
  63. {
  64. description: "success, single stack no node allocation",
  65. fakeNodeHandler: &testutil.FakeNodeHandler{
  66. Existing: []*v1.Node{
  67. {
  68. ObjectMeta: metav1.ObjectMeta{
  69. Name: "node0",
  70. },
  71. },
  72. },
  73. Clientset: fake.NewSimpleClientset(),
  74. },
  75. allocatorParams: CIDRAllocatorParams{
  76. ClusterCIDRs: func() []*net.IPNet {
  77. _, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16")
  78. return []*net.IPNet{clusterCIDRv4}
  79. }(),
  80. ServiceCIDR: nil,
  81. SecondaryServiceCIDR: nil,
  82. NodeCIDRMaskSizes: []int{24},
  83. },
  84. allocatedCIDRs: nil,
  85. expectedAllocatedCIDR: nil,
  86. ctrlCreateFail: false,
  87. },
  88. {
  89. description: "success, dual stack no node allocation",
  90. fakeNodeHandler: &testutil.FakeNodeHandler{
  91. Existing: []*v1.Node{
  92. {
  93. ObjectMeta: metav1.ObjectMeta{
  94. Name: "node0",
  95. },
  96. },
  97. },
  98. Clientset: fake.NewSimpleClientset(),
  99. },
  100. allocatorParams: CIDRAllocatorParams{
  101. ClusterCIDRs: func() []*net.IPNet {
  102. _, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16")
  103. _, clusterCIDRv6, _ := net.ParseCIDR("ace:cab:deca::/8")
  104. return []*net.IPNet{clusterCIDRv4, clusterCIDRv6}
  105. }(),
  106. ServiceCIDR: nil,
  107. SecondaryServiceCIDR: nil,
  108. NodeCIDRMaskSizes: []int{24, 24},
  109. },
  110. allocatedCIDRs: nil,
  111. expectedAllocatedCIDR: nil,
  112. ctrlCreateFail: false,
  113. },
  114. {
  115. description: "success, single stack correct node allocation",
  116. fakeNodeHandler: &testutil.FakeNodeHandler{
  117. Existing: []*v1.Node{
  118. {
  119. ObjectMeta: metav1.ObjectMeta{
  120. Name: "node0",
  121. },
  122. Spec: v1.NodeSpec{
  123. PodCIDRs: []string{"10.10.0.1/24"},
  124. },
  125. },
  126. },
  127. Clientset: fake.NewSimpleClientset(),
  128. },
  129. allocatorParams: CIDRAllocatorParams{
  130. ClusterCIDRs: func() []*net.IPNet {
  131. _, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16")
  132. return []*net.IPNet{clusterCIDRv4}
  133. }(),
  134. ServiceCIDR: nil,
  135. SecondaryServiceCIDR: nil,
  136. NodeCIDRMaskSizes: []int{24},
  137. },
  138. allocatedCIDRs: nil,
  139. expectedAllocatedCIDR: nil,
  140. ctrlCreateFail: false,
  141. },
  142. {
  143. description: "success, dual stack both allocated correctly",
  144. fakeNodeHandler: &testutil.FakeNodeHandler{
  145. Existing: []*v1.Node{
  146. {
  147. ObjectMeta: metav1.ObjectMeta{
  148. Name: "node0",
  149. },
  150. Spec: v1.NodeSpec{
  151. PodCIDRs: []string{"10.10.0.1/24", "a00::/86"},
  152. },
  153. },
  154. },
  155. Clientset: fake.NewSimpleClientset(),
  156. },
  157. allocatorParams: CIDRAllocatorParams{
  158. ClusterCIDRs: func() []*net.IPNet {
  159. _, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16")
  160. _, clusterCIDRv6, _ := net.ParseCIDR("ace:cab:deca::/8")
  161. return []*net.IPNet{clusterCIDRv4, clusterCIDRv6}
  162. }(),
  163. ServiceCIDR: nil,
  164. SecondaryServiceCIDR: nil,
  165. NodeCIDRMaskSizes: []int{24, 24},
  166. },
  167. allocatedCIDRs: nil,
  168. expectedAllocatedCIDR: nil,
  169. ctrlCreateFail: false,
  170. },
  171. // failure cases
  172. {
  173. description: "fail, single stack incorrect node allocation",
  174. fakeNodeHandler: &testutil.FakeNodeHandler{
  175. Existing: []*v1.Node{
  176. {
  177. ObjectMeta: metav1.ObjectMeta{
  178. Name: "node0",
  179. },
  180. Spec: v1.NodeSpec{
  181. PodCIDRs: []string{"172.10.0.1/24"},
  182. },
  183. },
  184. },
  185. Clientset: fake.NewSimpleClientset(),
  186. },
  187. allocatorParams: CIDRAllocatorParams{
  188. ClusterCIDRs: func() []*net.IPNet {
  189. _, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16")
  190. return []*net.IPNet{clusterCIDRv4}
  191. }(),
  192. ServiceCIDR: nil,
  193. SecondaryServiceCIDR: nil,
  194. NodeCIDRMaskSizes: []int{24},
  195. },
  196. allocatedCIDRs: nil,
  197. expectedAllocatedCIDR: nil,
  198. ctrlCreateFail: true,
  199. },
  200. {
  201. description: "fail, dualstack node allocating from non existing cidr",
  202. fakeNodeHandler: &testutil.FakeNodeHandler{
  203. Existing: []*v1.Node{
  204. {
  205. ObjectMeta: metav1.ObjectMeta{
  206. Name: "node0",
  207. },
  208. Spec: v1.NodeSpec{
  209. PodCIDRs: []string{"10.10.0.1/24", "a00::/86"},
  210. },
  211. },
  212. },
  213. Clientset: fake.NewSimpleClientset(),
  214. },
  215. allocatorParams: CIDRAllocatorParams{
  216. ClusterCIDRs: func() []*net.IPNet {
  217. _, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16")
  218. return []*net.IPNet{clusterCIDRv4}
  219. }(),
  220. ServiceCIDR: nil,
  221. SecondaryServiceCIDR: nil,
  222. NodeCIDRMaskSizes: []int{24},
  223. },
  224. allocatedCIDRs: nil,
  225. expectedAllocatedCIDR: nil,
  226. ctrlCreateFail: true,
  227. },
  228. {
  229. description: "fail, dualstack node allocating bad v4",
  230. fakeNodeHandler: &testutil.FakeNodeHandler{
  231. Existing: []*v1.Node{
  232. {
  233. ObjectMeta: metav1.ObjectMeta{
  234. Name: "node0",
  235. },
  236. Spec: v1.NodeSpec{
  237. PodCIDRs: []string{"172.10.0.1/24", "a00::/86"},
  238. },
  239. },
  240. },
  241. Clientset: fake.NewSimpleClientset(),
  242. },
  243. allocatorParams: CIDRAllocatorParams{
  244. ClusterCIDRs: func() []*net.IPNet {
  245. _, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16")
  246. _, clusterCIDRv6, _ := net.ParseCIDR("ace:cab:deca::/8")
  247. return []*net.IPNet{clusterCIDRv4, clusterCIDRv6}
  248. }(),
  249. ServiceCIDR: nil,
  250. SecondaryServiceCIDR: nil,
  251. NodeCIDRMaskSizes: []int{24, 24},
  252. },
  253. allocatedCIDRs: nil,
  254. expectedAllocatedCIDR: nil,
  255. ctrlCreateFail: true,
  256. },
  257. {
  258. description: "fail, dualstack node allocating bad v6",
  259. fakeNodeHandler: &testutil.FakeNodeHandler{
  260. Existing: []*v1.Node{
  261. {
  262. ObjectMeta: metav1.ObjectMeta{
  263. Name: "node0",
  264. },
  265. Spec: v1.NodeSpec{
  266. PodCIDRs: []string{"10.10.0.1/24", "cdd::/86"},
  267. },
  268. },
  269. },
  270. Clientset: fake.NewSimpleClientset(),
  271. },
  272. allocatorParams: CIDRAllocatorParams{
  273. ClusterCIDRs: func() []*net.IPNet {
  274. _, clusterCIDRv4, _ := net.ParseCIDR("10.10.0.0/16")
  275. _, clusterCIDRv6, _ := net.ParseCIDR("ace:cab:deca::/8")
  276. return []*net.IPNet{clusterCIDRv4, clusterCIDRv6}
  277. }(),
  278. ServiceCIDR: nil,
  279. SecondaryServiceCIDR: nil,
  280. NodeCIDRMaskSizes: []int{24, 24},
  281. },
  282. allocatedCIDRs: nil,
  283. expectedAllocatedCIDR: nil,
  284. ctrlCreateFail: true,
  285. },
  286. }
  287. // test function
  288. for _, tc := range testCases {
  289. t.Run(tc.description, func(t *testing.T) {
  290. // Initialize the range allocator.
  291. fakeNodeInformer := getFakeNodeInformer(tc.fakeNodeHandler)
  292. nodeList, _ := tc.fakeNodeHandler.List(context.TODO(), metav1.ListOptions{})
  293. _, err := NewCIDRRangeAllocator(tc.fakeNodeHandler, fakeNodeInformer, tc.allocatorParams, nodeList)
  294. if err == nil && tc.ctrlCreateFail {
  295. t.Fatalf("creating range allocator was expected to fail, but it did not")
  296. }
  297. if err != nil && !tc.ctrlCreateFail {
  298. t.Fatalf("creating range allocator was expected to succeed, but it did not")
  299. }
  300. })
  301. }
  302. }
  303. func TestAllocateOrOccupyCIDRSuccess(t *testing.T) {
  304. // all tests operate on a single node
  305. testCases := []testCase{
  306. {
  307. description: "When there's no ServiceCIDR return first CIDR in range",
  308. fakeNodeHandler: &testutil.FakeNodeHandler{
  309. Existing: []*v1.Node{
  310. {
  311. ObjectMeta: metav1.ObjectMeta{
  312. Name: "node0",
  313. },
  314. },
  315. },
  316. Clientset: fake.NewSimpleClientset(),
  317. },
  318. allocatorParams: CIDRAllocatorParams{
  319. ClusterCIDRs: func() []*net.IPNet {
  320. _, clusterCIDR, _ := net.ParseCIDR("127.123.234.0/24")
  321. return []*net.IPNet{clusterCIDR}
  322. }(),
  323. ServiceCIDR: nil,
  324. SecondaryServiceCIDR: nil,
  325. NodeCIDRMaskSizes: []int{30},
  326. },
  327. expectedAllocatedCIDR: map[int]string{
  328. 0: "127.123.234.0/30",
  329. },
  330. },
  331. {
  332. description: "Correctly filter out ServiceCIDR",
  333. fakeNodeHandler: &testutil.FakeNodeHandler{
  334. Existing: []*v1.Node{
  335. {
  336. ObjectMeta: metav1.ObjectMeta{
  337. Name: "node0",
  338. },
  339. },
  340. },
  341. Clientset: fake.NewSimpleClientset(),
  342. },
  343. allocatorParams: CIDRAllocatorParams{
  344. ClusterCIDRs: func() []*net.IPNet {
  345. _, clusterCIDR, _ := net.ParseCIDR("127.123.234.0/24")
  346. return []*net.IPNet{clusterCIDR}
  347. }(),
  348. ServiceCIDR: func() *net.IPNet {
  349. _, serviceCIDR, _ := net.ParseCIDR("127.123.234.0/26")
  350. return serviceCIDR
  351. }(),
  352. SecondaryServiceCIDR: nil,
  353. NodeCIDRMaskSizes: []int{30},
  354. },
  355. // it should return first /30 CIDR after service range
  356. expectedAllocatedCIDR: map[int]string{
  357. 0: "127.123.234.64/30",
  358. },
  359. },
  360. {
  361. description: "Correctly ignore already allocated CIDRs",
  362. fakeNodeHandler: &testutil.FakeNodeHandler{
  363. Existing: []*v1.Node{
  364. {
  365. ObjectMeta: metav1.ObjectMeta{
  366. Name: "node0",
  367. },
  368. },
  369. },
  370. Clientset: fake.NewSimpleClientset(),
  371. },
  372. allocatorParams: CIDRAllocatorParams{
  373. ClusterCIDRs: func() []*net.IPNet {
  374. _, clusterCIDR, _ := net.ParseCIDR("127.123.234.0/24")
  375. return []*net.IPNet{clusterCIDR}
  376. }(),
  377. ServiceCIDR: func() *net.IPNet {
  378. _, serviceCIDR, _ := net.ParseCIDR("127.123.234.0/26")
  379. return serviceCIDR
  380. }(),
  381. SecondaryServiceCIDR: nil,
  382. NodeCIDRMaskSizes: []int{30},
  383. },
  384. allocatedCIDRs: map[int][]string{
  385. 0: {"127.123.234.64/30", "127.123.234.68/30", "127.123.234.72/30", "127.123.234.80/30"},
  386. },
  387. expectedAllocatedCIDR: map[int]string{
  388. 0: "127.123.234.76/30",
  389. },
  390. },
  391. {
  392. description: "Dualstack CIDRs v4,v6",
  393. fakeNodeHandler: &testutil.FakeNodeHandler{
  394. Existing: []*v1.Node{
  395. {
  396. ObjectMeta: metav1.ObjectMeta{
  397. Name: "node0",
  398. },
  399. },
  400. },
  401. Clientset: fake.NewSimpleClientset(),
  402. },
  403. allocatorParams: CIDRAllocatorParams{
  404. ClusterCIDRs: func() []*net.IPNet {
  405. _, clusterCIDRv4, _ := net.ParseCIDR("127.123.234.0/8")
  406. _, clusterCIDRv6, _ := net.ParseCIDR("ace:cab:deca::/84")
  407. return []*net.IPNet{clusterCIDRv4, clusterCIDRv6}
  408. }(),
  409. ServiceCIDR: func() *net.IPNet {
  410. _, serviceCIDR, _ := net.ParseCIDR("127.123.234.0/26")
  411. return serviceCIDR
  412. }(),
  413. SecondaryServiceCIDR: nil,
  414. NodeCIDRMaskSizes: []int{24, 98},
  415. },
  416. },
  417. {
  418. description: "Dualstack CIDRs v6,v4",
  419. fakeNodeHandler: &testutil.FakeNodeHandler{
  420. Existing: []*v1.Node{
  421. {
  422. ObjectMeta: metav1.ObjectMeta{
  423. Name: "node0",
  424. },
  425. },
  426. },
  427. Clientset: fake.NewSimpleClientset(),
  428. },
  429. allocatorParams: CIDRAllocatorParams{
  430. ClusterCIDRs: func() []*net.IPNet {
  431. _, clusterCIDRv4, _ := net.ParseCIDR("127.123.234.0/8")
  432. _, clusterCIDRv6, _ := net.ParseCIDR("ace:cab:deca::/84")
  433. return []*net.IPNet{clusterCIDRv6, clusterCIDRv4}
  434. }(),
  435. ServiceCIDR: func() *net.IPNet {
  436. _, serviceCIDR, _ := net.ParseCIDR("127.123.234.0/26")
  437. return serviceCIDR
  438. }(),
  439. SecondaryServiceCIDR: nil,
  440. NodeCIDRMaskSizes: []int{98, 24},
  441. },
  442. },
  443. {
  444. description: "Dualstack CIDRs, more than two",
  445. fakeNodeHandler: &testutil.FakeNodeHandler{
  446. Existing: []*v1.Node{
  447. {
  448. ObjectMeta: metav1.ObjectMeta{
  449. Name: "node0",
  450. },
  451. },
  452. },
  453. Clientset: fake.NewSimpleClientset(),
  454. },
  455. allocatorParams: CIDRAllocatorParams{
  456. ClusterCIDRs: func() []*net.IPNet {
  457. _, clusterCIDRv4, _ := net.ParseCIDR("127.123.234.0/8")
  458. _, clusterCIDRv6, _ := net.ParseCIDR("ace:cab:deca::/84")
  459. _, clusterCIDRv4_2, _ := net.ParseCIDR("10.0.0.0/8")
  460. return []*net.IPNet{clusterCIDRv4, clusterCIDRv6, clusterCIDRv4_2}
  461. }(),
  462. ServiceCIDR: func() *net.IPNet {
  463. _, serviceCIDR, _ := net.ParseCIDR("127.123.234.0/26")
  464. return serviceCIDR
  465. }(),
  466. SecondaryServiceCIDR: nil,
  467. NodeCIDRMaskSizes: []int{24, 98, 24},
  468. },
  469. },
  470. }
  471. // test function
  472. testFunc := func(tc testCase) {
  473. // Initialize the range allocator.
  474. allocator, err := NewCIDRRangeAllocator(tc.fakeNodeHandler, getFakeNodeInformer(tc.fakeNodeHandler), tc.allocatorParams, nil)
  475. if err != nil {
  476. t.Errorf("%v: failed to create CIDRRangeAllocator with error %v", tc.description, err)
  477. return
  478. }
  479. rangeAllocator, ok := allocator.(*rangeAllocator)
  480. if !ok {
  481. t.Logf("%v: found non-default implementation of CIDRAllocator, skipping white-box test...", tc.description)
  482. return
  483. }
  484. rangeAllocator.nodesSynced = alwaysReady
  485. rangeAllocator.recorder = testutil.NewFakeRecorder()
  486. go allocator.Run(wait.NeverStop)
  487. // this is a bit of white box testing
  488. // pre allocate the cidrs as per the test
  489. for idx, allocatedList := range tc.allocatedCIDRs {
  490. for _, allocated := range allocatedList {
  491. _, cidr, err := net.ParseCIDR(allocated)
  492. if err != nil {
  493. t.Fatalf("%v: unexpected error when parsing CIDR %v: %v", tc.description, allocated, err)
  494. }
  495. if err = rangeAllocator.cidrSets[idx].Occupy(cidr); err != nil {
  496. t.Fatalf("%v: unexpected error when occupying CIDR %v: %v", tc.description, allocated, err)
  497. }
  498. }
  499. if err := allocator.AllocateOrOccupyCIDR(tc.fakeNodeHandler.Existing[0]); err != nil {
  500. t.Errorf("%v: unexpected error in AllocateOrOccupyCIDR: %v", tc.description, err)
  501. }
  502. if err := waitForUpdatedNodeWithTimeout(tc.fakeNodeHandler, 1, wait.ForeverTestTimeout); err != nil {
  503. t.Fatalf("%v: timeout while waiting for Node update: %v", tc.description, err)
  504. }
  505. }
  506. if len(tc.expectedAllocatedCIDR) == 0 {
  507. // nothing further expected
  508. return
  509. }
  510. for _, updatedNode := range tc.fakeNodeHandler.GetUpdatedNodesCopy() {
  511. if len(updatedNode.Spec.PodCIDRs) == 0 {
  512. continue // not assigned yet
  513. }
  514. //match
  515. for podCIDRIdx, expectedPodCIDR := range tc.expectedAllocatedCIDR {
  516. if updatedNode.Spec.PodCIDRs[podCIDRIdx] != expectedPodCIDR {
  517. t.Errorf("%v: Unable to find allocated CIDR %v, found updated Nodes with CIDRs: %v", tc.description, expectedPodCIDR, updatedNode.Spec.PodCIDRs)
  518. break
  519. }
  520. }
  521. }
  522. }
  523. // run the test cases
  524. for _, tc := range testCases {
  525. testFunc(tc)
  526. }
  527. }
  528. func TestAllocateOrOccupyCIDRFailure(t *testing.T) {
  529. testCases := []testCase{
  530. {
  531. description: "When there's no ServiceCIDR return first CIDR in range",
  532. fakeNodeHandler: &testutil.FakeNodeHandler{
  533. Existing: []*v1.Node{
  534. {
  535. ObjectMeta: metav1.ObjectMeta{
  536. Name: "node0",
  537. },
  538. },
  539. },
  540. Clientset: fake.NewSimpleClientset(),
  541. },
  542. allocatorParams: CIDRAllocatorParams{
  543. ClusterCIDRs: func() []*net.IPNet {
  544. _, clusterCIDR, _ := net.ParseCIDR("127.123.234.0/28")
  545. return []*net.IPNet{clusterCIDR}
  546. }(),
  547. ServiceCIDR: nil,
  548. SecondaryServiceCIDR: nil,
  549. NodeCIDRMaskSizes: []int{30},
  550. },
  551. allocatedCIDRs: map[int][]string{
  552. 0: {"127.123.234.0/30", "127.123.234.4/30", "127.123.234.8/30", "127.123.234.12/30"},
  553. },
  554. },
  555. }
  556. testFunc := func(tc testCase) {
  557. // Initialize the range allocator.
  558. allocator, err := NewCIDRRangeAllocator(tc.fakeNodeHandler, getFakeNodeInformer(tc.fakeNodeHandler), tc.allocatorParams, nil)
  559. if err != nil {
  560. t.Logf("%v: failed to create CIDRRangeAllocator with error %v", tc.description, err)
  561. }
  562. rangeAllocator, ok := allocator.(*rangeAllocator)
  563. if !ok {
  564. t.Logf("%v: found non-default implementation of CIDRAllocator, skipping white-box test...", tc.description)
  565. return
  566. }
  567. rangeAllocator.nodesSynced = alwaysReady
  568. rangeAllocator.recorder = testutil.NewFakeRecorder()
  569. go allocator.Run(wait.NeverStop)
  570. // this is a bit of white box testing
  571. for setIdx, allocatedList := range tc.allocatedCIDRs {
  572. for _, allocated := range allocatedList {
  573. _, cidr, err := net.ParseCIDR(allocated)
  574. if err != nil {
  575. t.Fatalf("%v: unexpected error when parsing CIDR %v: %v", tc.description, cidr, err)
  576. }
  577. err = rangeAllocator.cidrSets[setIdx].Occupy(cidr)
  578. if err != nil {
  579. t.Fatalf("%v: unexpected error when occupying CIDR %v: %v", tc.description, cidr, err)
  580. }
  581. }
  582. }
  583. if err := allocator.AllocateOrOccupyCIDR(tc.fakeNodeHandler.Existing[0]); err == nil {
  584. t.Errorf("%v: unexpected success in AllocateOrOccupyCIDR: %v", tc.description, err)
  585. }
  586. // We don't expect any updates, so just sleep for some time
  587. time.Sleep(time.Second)
  588. if len(tc.fakeNodeHandler.GetUpdatedNodesCopy()) != 0 {
  589. t.Fatalf("%v: unexpected update of nodes: %v", tc.description, tc.fakeNodeHandler.GetUpdatedNodesCopy())
  590. }
  591. if len(tc.expectedAllocatedCIDR) == 0 {
  592. // nothing further expected
  593. return
  594. }
  595. for _, updatedNode := range tc.fakeNodeHandler.GetUpdatedNodesCopy() {
  596. if len(updatedNode.Spec.PodCIDRs) == 0 {
  597. continue // not assigned yet
  598. }
  599. //match
  600. for podCIDRIdx, expectedPodCIDR := range tc.expectedAllocatedCIDR {
  601. if updatedNode.Spec.PodCIDRs[podCIDRIdx] == expectedPodCIDR {
  602. t.Errorf("%v: found cidr %v that should not be allocated on node with CIDRs:%v", tc.description, expectedPodCIDR, updatedNode.Spec.PodCIDRs)
  603. break
  604. }
  605. }
  606. }
  607. }
  608. for _, tc := range testCases {
  609. testFunc(tc)
  610. }
  611. }
  612. type releaseTestCase struct {
  613. description string
  614. fakeNodeHandler *testutil.FakeNodeHandler
  615. allocatorParams CIDRAllocatorParams
  616. expectedAllocatedCIDRFirstRound map[int]string
  617. expectedAllocatedCIDRSecondRound map[int]string
  618. allocatedCIDRs map[int][]string
  619. cidrsToRelease [][]string
  620. }
  621. func TestReleaseCIDRSuccess(t *testing.T) {
  622. testCases := []releaseTestCase{
  623. {
  624. description: "Correctly release preallocated CIDR",
  625. fakeNodeHandler: &testutil.FakeNodeHandler{
  626. Existing: []*v1.Node{
  627. {
  628. ObjectMeta: metav1.ObjectMeta{
  629. Name: "node0",
  630. },
  631. },
  632. },
  633. Clientset: fake.NewSimpleClientset(),
  634. },
  635. allocatorParams: CIDRAllocatorParams{
  636. ClusterCIDRs: func() []*net.IPNet {
  637. _, clusterCIDR, _ := net.ParseCIDR("127.123.234.0/28")
  638. return []*net.IPNet{clusterCIDR}
  639. }(),
  640. ServiceCIDR: nil,
  641. SecondaryServiceCIDR: nil,
  642. NodeCIDRMaskSizes: []int{30},
  643. },
  644. allocatedCIDRs: map[int][]string{
  645. 0: {"127.123.234.0/30", "127.123.234.4/30", "127.123.234.8/30", "127.123.234.12/30"},
  646. },
  647. expectedAllocatedCIDRFirstRound: nil,
  648. cidrsToRelease: [][]string{
  649. {"127.123.234.4/30"},
  650. },
  651. expectedAllocatedCIDRSecondRound: map[int]string{
  652. 0: "127.123.234.4/30",
  653. },
  654. },
  655. {
  656. description: "Correctly recycle CIDR",
  657. fakeNodeHandler: &testutil.FakeNodeHandler{
  658. Existing: []*v1.Node{
  659. {
  660. ObjectMeta: metav1.ObjectMeta{
  661. Name: "node0",
  662. },
  663. },
  664. },
  665. Clientset: fake.NewSimpleClientset(),
  666. },
  667. allocatorParams: CIDRAllocatorParams{
  668. ClusterCIDRs: func() []*net.IPNet {
  669. _, clusterCIDR, _ := net.ParseCIDR("127.123.234.0/28")
  670. return []*net.IPNet{clusterCIDR}
  671. }(),
  672. ServiceCIDR: nil,
  673. SecondaryServiceCIDR: nil,
  674. NodeCIDRMaskSizes: []int{30},
  675. },
  676. allocatedCIDRs: map[int][]string{
  677. 0: {"127.123.234.4/30", "127.123.234.8/30", "127.123.234.12/30"},
  678. },
  679. expectedAllocatedCIDRFirstRound: map[int]string{
  680. 0: "127.123.234.0/30",
  681. },
  682. cidrsToRelease: [][]string{
  683. {"127.123.234.0/30"},
  684. },
  685. expectedAllocatedCIDRSecondRound: map[int]string{
  686. 0: "127.123.234.0/30",
  687. },
  688. },
  689. }
  690. testFunc := func(tc releaseTestCase) {
  691. // Initialize the range allocator.
  692. allocator, _ := NewCIDRRangeAllocator(tc.fakeNodeHandler, getFakeNodeInformer(tc.fakeNodeHandler), tc.allocatorParams, nil)
  693. rangeAllocator, ok := allocator.(*rangeAllocator)
  694. if !ok {
  695. t.Logf("%v: found non-default implementation of CIDRAllocator, skipping white-box test...", tc.description)
  696. return
  697. }
  698. rangeAllocator.nodesSynced = alwaysReady
  699. rangeAllocator.recorder = testutil.NewFakeRecorder()
  700. go allocator.Run(wait.NeverStop)
  701. // this is a bit of white box testing
  702. for setIdx, allocatedList := range tc.allocatedCIDRs {
  703. for _, allocated := range allocatedList {
  704. _, cidr, err := net.ParseCIDR(allocated)
  705. if err != nil {
  706. t.Fatalf("%v: unexpected error when parsing CIDR %v: %v", tc.description, allocated, err)
  707. }
  708. err = rangeAllocator.cidrSets[setIdx].Occupy(cidr)
  709. if err != nil {
  710. t.Fatalf("%v: unexpected error when occupying CIDR %v: %v", tc.description, allocated, err)
  711. }
  712. }
  713. }
  714. err := allocator.AllocateOrOccupyCIDR(tc.fakeNodeHandler.Existing[0])
  715. if len(tc.expectedAllocatedCIDRFirstRound) != 0 {
  716. if err != nil {
  717. t.Fatalf("%v: unexpected error in AllocateOrOccupyCIDR: %v", tc.description, err)
  718. }
  719. if err := waitForUpdatedNodeWithTimeout(tc.fakeNodeHandler, 1, wait.ForeverTestTimeout); err != nil {
  720. t.Fatalf("%v: timeout while waiting for Node update: %v", tc.description, err)
  721. }
  722. } else {
  723. if err == nil {
  724. t.Fatalf("%v: unexpected success in AllocateOrOccupyCIDR: %v", tc.description, err)
  725. }
  726. // We don't expect any updates here
  727. time.Sleep(time.Second)
  728. if len(tc.fakeNodeHandler.GetUpdatedNodesCopy()) != 0 {
  729. t.Fatalf("%v: unexpected update of nodes: %v", tc.description, tc.fakeNodeHandler.GetUpdatedNodesCopy())
  730. }
  731. }
  732. for _, cidrToRelease := range tc.cidrsToRelease {
  733. nodeToRelease := v1.Node{
  734. ObjectMeta: metav1.ObjectMeta{
  735. Name: "node0",
  736. },
  737. }
  738. nodeToRelease.Spec.PodCIDRs = cidrToRelease
  739. err = allocator.ReleaseCIDR(&nodeToRelease)
  740. if err != nil {
  741. t.Fatalf("%v: unexpected error in ReleaseCIDR: %v", tc.description, err)
  742. }
  743. }
  744. if err = allocator.AllocateOrOccupyCIDR(tc.fakeNodeHandler.Existing[0]); err != nil {
  745. t.Fatalf("%v: unexpected error in AllocateOrOccupyCIDR: %v", tc.description, err)
  746. }
  747. if err := waitForUpdatedNodeWithTimeout(tc.fakeNodeHandler, 1, wait.ForeverTestTimeout); err != nil {
  748. t.Fatalf("%v: timeout while waiting for Node update: %v", tc.description, err)
  749. }
  750. if len(tc.expectedAllocatedCIDRSecondRound) == 0 {
  751. // nothing further expected
  752. return
  753. }
  754. for _, updatedNode := range tc.fakeNodeHandler.GetUpdatedNodesCopy() {
  755. if len(updatedNode.Spec.PodCIDRs) == 0 {
  756. continue // not assigned yet
  757. }
  758. //match
  759. for podCIDRIdx, expectedPodCIDR := range tc.expectedAllocatedCIDRSecondRound {
  760. if updatedNode.Spec.PodCIDRs[podCIDRIdx] != expectedPodCIDR {
  761. t.Errorf("%v: found cidr %v that should not be allocated on node with CIDRs:%v", tc.description, expectedPodCIDR, updatedNode.Spec.PodCIDRs)
  762. break
  763. }
  764. }
  765. }
  766. }
  767. for _, tc := range testCases {
  768. testFunc(tc)
  769. }
  770. }