taints_test.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760
  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 taints
  14. import (
  15. "reflect"
  16. "strings"
  17. "testing"
  18. "k8s.io/api/core/v1"
  19. api "k8s.io/kubernetes/pkg/apis/core"
  20. "github.com/spf13/pflag"
  21. )
  22. func TestTaintsVar(t *testing.T) {
  23. cases := []struct {
  24. f string
  25. err bool
  26. t []api.Taint
  27. }{
  28. {
  29. f: "",
  30. t: []api.Taint(nil),
  31. },
  32. {
  33. f: "--t=foo=bar:NoSchedule",
  34. t: []api.Taint{{Key: "foo", Value: "bar", Effect: "NoSchedule"}},
  35. },
  36. {
  37. f: "--t=baz:NoSchedule",
  38. t: []api.Taint{{Key: "baz", Value: "", Effect: "NoSchedule"}},
  39. },
  40. {
  41. f: "--t=foo=bar:NoSchedule,baz:NoSchedule,bing=bang:PreferNoSchedule,qux=:NoSchedule",
  42. t: []api.Taint{
  43. {Key: "foo", Value: "bar", Effect: api.TaintEffectNoSchedule},
  44. {Key: "baz", Value: "", Effect: "NoSchedule"},
  45. {Key: "bing", Value: "bang", Effect: api.TaintEffectPreferNoSchedule},
  46. {Key: "qux", Value: "", Effect: "NoSchedule"},
  47. },
  48. },
  49. {
  50. f: "--t=dedicated-for=user1:NoExecute,baz:NoSchedule,foo-bar=:NoSchedule",
  51. t: []api.Taint{
  52. {Key: "dedicated-for", Value: "user1", Effect: "NoExecute"},
  53. {Key: "baz", Value: "", Effect: "NoSchedule"},
  54. {Key: "foo-bar", Value: "", Effect: "NoSchedule"},
  55. },
  56. },
  57. }
  58. for i, c := range cases {
  59. args := append([]string{"test"}, strings.Fields(c.f)...)
  60. cli := pflag.NewFlagSet("test", pflag.ContinueOnError)
  61. var taints []api.Taint
  62. cli.Var(NewTaintsVar(&taints), "t", "bar")
  63. err := cli.Parse(args)
  64. if err == nil && c.err {
  65. t.Errorf("[%v] expected error", i)
  66. continue
  67. }
  68. if err != nil && !c.err {
  69. t.Errorf("[%v] unexpected error: %v", i, err)
  70. continue
  71. }
  72. if !reflect.DeepEqual(c.t, taints) {
  73. t.Errorf("[%v] unexpected taints:\n\texpected:\n\t\t%#v\n\tgot:\n\t\t%#v", i, c.t, taints)
  74. }
  75. }
  76. }
  77. func TestAddOrUpdateTaint(t *testing.T) {
  78. node := &v1.Node{}
  79. taint := &v1.Taint{
  80. Key: "foo",
  81. Value: "bar",
  82. Effect: v1.TaintEffectNoSchedule,
  83. }
  84. checkResult := func(testCaseName string, newNode *v1.Node, expectedTaint *v1.Taint, result, expectedResult bool, err error) {
  85. if err != nil {
  86. t.Errorf("[%s] should not raise error but got %v", testCaseName, err)
  87. }
  88. if result != expectedResult {
  89. t.Errorf("[%s] should return %t, but got: %t", testCaseName, expectedResult, result)
  90. }
  91. if len(newNode.Spec.Taints) != 1 || !reflect.DeepEqual(newNode.Spec.Taints[0], *expectedTaint) {
  92. t.Errorf("[%s] node should only have one taint: %v, but got: %v", testCaseName, *expectedTaint, newNode.Spec.Taints)
  93. }
  94. }
  95. // Add a new Taint.
  96. newNode, result, err := AddOrUpdateTaint(node, taint)
  97. checkResult("Add New Taint", newNode, taint, result, true, err)
  98. // Update a Taint.
  99. taint.Value = "bar_1"
  100. newNode, result, err = AddOrUpdateTaint(node, taint)
  101. checkResult("Update Taint", newNode, taint, result, true, err)
  102. // Add a duplicate Taint.
  103. node = newNode
  104. newNode, result, err = AddOrUpdateTaint(node, taint)
  105. checkResult("Add Duplicate Taint", newNode, taint, result, false, err)
  106. }
  107. func TestTaintExists(t *testing.T) {
  108. testingTaints := []v1.Taint{
  109. {
  110. Key: "foo_1",
  111. Value: "bar_1",
  112. Effect: v1.TaintEffectNoExecute,
  113. },
  114. {
  115. Key: "foo_2",
  116. Value: "bar_2",
  117. Effect: v1.TaintEffectNoSchedule,
  118. },
  119. }
  120. cases := []struct {
  121. name string
  122. taintToFind *v1.Taint
  123. expectedResult bool
  124. }{
  125. {
  126. name: "taint exists",
  127. taintToFind: &v1.Taint{Key: "foo_1", Value: "bar_1", Effect: v1.TaintEffectNoExecute},
  128. expectedResult: true,
  129. },
  130. {
  131. name: "different key",
  132. taintToFind: &v1.Taint{Key: "no_such_key", Value: "bar_1", Effect: v1.TaintEffectNoExecute},
  133. expectedResult: false,
  134. },
  135. {
  136. name: "different effect",
  137. taintToFind: &v1.Taint{Key: "foo_1", Value: "bar_1", Effect: v1.TaintEffectNoSchedule},
  138. expectedResult: false,
  139. },
  140. }
  141. for _, c := range cases {
  142. result := TaintExists(testingTaints, c.taintToFind)
  143. if result != c.expectedResult {
  144. t.Errorf("[%s] unexpected results: %v", c.name, result)
  145. continue
  146. }
  147. }
  148. }
  149. func TestRemoveTaint(t *testing.T) {
  150. cases := []struct {
  151. name string
  152. node *v1.Node
  153. taintToRemove *v1.Taint
  154. expectedTaints []v1.Taint
  155. expectedResult bool
  156. }{
  157. {
  158. name: "remove taint unsuccessfully",
  159. node: &v1.Node{
  160. Spec: v1.NodeSpec{
  161. Taints: []v1.Taint{
  162. {
  163. Key: "foo",
  164. Effect: v1.TaintEffectNoSchedule,
  165. },
  166. },
  167. },
  168. },
  169. taintToRemove: &v1.Taint{
  170. Key: "foo_1",
  171. Effect: v1.TaintEffectNoSchedule,
  172. },
  173. expectedTaints: []v1.Taint{
  174. {
  175. Key: "foo",
  176. Effect: v1.TaintEffectNoSchedule,
  177. },
  178. },
  179. expectedResult: false,
  180. },
  181. {
  182. name: "remove taint successfully",
  183. node: &v1.Node{
  184. Spec: v1.NodeSpec{
  185. Taints: []v1.Taint{
  186. {
  187. Key: "foo",
  188. Effect: v1.TaintEffectNoSchedule,
  189. },
  190. },
  191. },
  192. },
  193. taintToRemove: &v1.Taint{
  194. Key: "foo",
  195. Effect: v1.TaintEffectNoSchedule,
  196. },
  197. expectedTaints: []v1.Taint{},
  198. expectedResult: true,
  199. },
  200. {
  201. name: "remove taint from node with no taint",
  202. node: &v1.Node{
  203. Spec: v1.NodeSpec{
  204. Taints: []v1.Taint{},
  205. },
  206. },
  207. taintToRemove: &v1.Taint{
  208. Key: "foo",
  209. Effect: v1.TaintEffectNoSchedule,
  210. },
  211. expectedTaints: []v1.Taint{},
  212. expectedResult: false,
  213. },
  214. }
  215. for _, c := range cases {
  216. newNode, result, err := RemoveTaint(c.node, c.taintToRemove)
  217. if err != nil {
  218. t.Errorf("[%s] should not raise error but got: %v", c.name, err)
  219. }
  220. if result != c.expectedResult {
  221. t.Errorf("[%s] should return %t, but got: %t", c.name, c.expectedResult, result)
  222. }
  223. if !reflect.DeepEqual(newNode.Spec.Taints, c.expectedTaints) {
  224. t.Errorf("[%s] the new node object should have taints %v, but got: %v", c.name, c.expectedTaints, newNode.Spec.Taints)
  225. }
  226. }
  227. }
  228. func TestDeleteTaint(t *testing.T) {
  229. cases := []struct {
  230. name string
  231. taints []v1.Taint
  232. taintToDelete *v1.Taint
  233. expectedTaints []v1.Taint
  234. expectedResult bool
  235. }{
  236. {
  237. name: "delete taint with different name",
  238. taints: []v1.Taint{
  239. {
  240. Key: "foo",
  241. Effect: v1.TaintEffectNoSchedule,
  242. },
  243. },
  244. taintToDelete: &v1.Taint{Key: "foo_1", Effect: v1.TaintEffectNoSchedule},
  245. expectedTaints: []v1.Taint{
  246. {
  247. Key: "foo",
  248. Effect: v1.TaintEffectNoSchedule,
  249. },
  250. },
  251. expectedResult: false,
  252. },
  253. {
  254. name: "delete taint with different effect",
  255. taints: []v1.Taint{
  256. {
  257. Key: "foo",
  258. Effect: v1.TaintEffectNoSchedule,
  259. },
  260. },
  261. taintToDelete: &v1.Taint{Key: "foo", Effect: v1.TaintEffectNoExecute},
  262. expectedTaints: []v1.Taint{
  263. {
  264. Key: "foo",
  265. Effect: v1.TaintEffectNoSchedule,
  266. },
  267. },
  268. expectedResult: false,
  269. },
  270. {
  271. name: "delete taint successfully",
  272. taints: []v1.Taint{
  273. {
  274. Key: "foo",
  275. Effect: v1.TaintEffectNoSchedule,
  276. },
  277. },
  278. taintToDelete: &v1.Taint{Key: "foo", Effect: v1.TaintEffectNoSchedule},
  279. expectedTaints: []v1.Taint{},
  280. expectedResult: true,
  281. },
  282. {
  283. name: "delete taint from empty taint array",
  284. taints: []v1.Taint{},
  285. taintToDelete: &v1.Taint{Key: "foo", Effect: v1.TaintEffectNoSchedule},
  286. expectedTaints: []v1.Taint{},
  287. expectedResult: false,
  288. },
  289. }
  290. for _, c := range cases {
  291. taints, result := DeleteTaint(c.taints, c.taintToDelete)
  292. if result != c.expectedResult {
  293. t.Errorf("[%s] should return %t, but got: %t", c.name, c.expectedResult, result)
  294. }
  295. if !reflect.DeepEqual(taints, c.expectedTaints) {
  296. t.Errorf("[%s] the result taints should be %v, but got: %v", c.name, c.expectedTaints, taints)
  297. }
  298. }
  299. }
  300. func TestDeleteTaintByKey(t *testing.T) {
  301. cases := []struct {
  302. name string
  303. taints []v1.Taint
  304. taintKey string
  305. expectedTaints []v1.Taint
  306. expectedResult bool
  307. }{
  308. {
  309. name: "delete taint unsuccessfully",
  310. taints: []v1.Taint{
  311. {
  312. Key: "foo",
  313. Value: "bar",
  314. Effect: v1.TaintEffectNoSchedule,
  315. },
  316. },
  317. taintKey: "foo_1",
  318. expectedTaints: []v1.Taint{
  319. {
  320. Key: "foo",
  321. Value: "bar",
  322. Effect: v1.TaintEffectNoSchedule,
  323. },
  324. },
  325. expectedResult: false,
  326. },
  327. {
  328. name: "delete taint successfully",
  329. taints: []v1.Taint{
  330. {
  331. Key: "foo",
  332. Value: "bar",
  333. Effect: v1.TaintEffectNoSchedule,
  334. },
  335. },
  336. taintKey: "foo",
  337. expectedTaints: []v1.Taint{},
  338. expectedResult: true,
  339. },
  340. {
  341. name: "delete taint from empty taint array",
  342. taints: []v1.Taint{},
  343. taintKey: "foo",
  344. expectedTaints: []v1.Taint{},
  345. expectedResult: false,
  346. },
  347. }
  348. for _, c := range cases {
  349. taints, result := DeleteTaintsByKey(c.taints, c.taintKey)
  350. if result != c.expectedResult {
  351. t.Errorf("[%s] should return %t, but got: %t", c.name, c.expectedResult, result)
  352. }
  353. if !reflect.DeepEqual(c.expectedTaints, taints) {
  354. t.Errorf("[%s] the result taints should be %v, but got: %v", c.name, c.expectedTaints, taints)
  355. }
  356. }
  357. }
  358. func TestCheckIfTaintsAlreadyExists(t *testing.T) {
  359. oldTaints := []v1.Taint{
  360. {
  361. Key: "foo_1",
  362. Value: "bar",
  363. Effect: v1.TaintEffectNoSchedule,
  364. },
  365. {
  366. Key: "foo_2",
  367. Value: "bar",
  368. Effect: v1.TaintEffectNoSchedule,
  369. },
  370. {
  371. Key: "foo_3",
  372. Value: "bar",
  373. Effect: v1.TaintEffectNoSchedule,
  374. },
  375. }
  376. cases := []struct {
  377. name string
  378. taintsToCheck []v1.Taint
  379. expectedResult string
  380. }{
  381. {
  382. name: "empty array",
  383. taintsToCheck: []v1.Taint{},
  384. expectedResult: "",
  385. },
  386. {
  387. name: "no match",
  388. taintsToCheck: []v1.Taint{
  389. {
  390. Key: "foo_1",
  391. Effect: v1.TaintEffectNoExecute,
  392. },
  393. },
  394. expectedResult: "",
  395. },
  396. {
  397. name: "match one taint",
  398. taintsToCheck: []v1.Taint{
  399. {
  400. Key: "foo_2",
  401. Effect: v1.TaintEffectNoSchedule,
  402. },
  403. },
  404. expectedResult: "foo_2",
  405. },
  406. {
  407. name: "match two taints",
  408. taintsToCheck: []v1.Taint{
  409. {
  410. Key: "foo_2",
  411. Effect: v1.TaintEffectNoSchedule,
  412. },
  413. {
  414. Key: "foo_3",
  415. Effect: v1.TaintEffectNoSchedule,
  416. },
  417. },
  418. expectedResult: "foo_2,foo_3",
  419. },
  420. }
  421. for _, c := range cases {
  422. result := CheckIfTaintsAlreadyExists(oldTaints, c.taintsToCheck)
  423. if result != c.expectedResult {
  424. t.Errorf("[%s] should return '%s', but got: '%s'", c.name, c.expectedResult, result)
  425. }
  426. }
  427. }
  428. func TestReorganizeTaints(t *testing.T) {
  429. node := &v1.Node{
  430. Spec: v1.NodeSpec{
  431. Taints: []v1.Taint{
  432. {
  433. Key: "foo",
  434. Value: "bar",
  435. Effect: v1.TaintEffectNoSchedule,
  436. },
  437. },
  438. },
  439. }
  440. cases := []struct {
  441. name string
  442. overwrite bool
  443. taintsToAdd []v1.Taint
  444. taintsToDelete []v1.Taint
  445. expectedTaints []v1.Taint
  446. expectedOperation string
  447. expectedErr bool
  448. }{
  449. {
  450. name: "no changes with overwrite is true",
  451. overwrite: true,
  452. taintsToAdd: []v1.Taint{},
  453. taintsToDelete: []v1.Taint{},
  454. expectedTaints: node.Spec.Taints,
  455. expectedOperation: MODIFIED,
  456. expectedErr: false,
  457. },
  458. {
  459. name: "no changes with overwrite is false",
  460. overwrite: false,
  461. taintsToAdd: []v1.Taint{},
  462. taintsToDelete: []v1.Taint{},
  463. expectedTaints: node.Spec.Taints,
  464. expectedOperation: UNTAINTED,
  465. expectedErr: false,
  466. },
  467. {
  468. name: "add new taint",
  469. overwrite: false,
  470. taintsToAdd: []v1.Taint{
  471. {
  472. Key: "foo_1",
  473. Effect: v1.TaintEffectNoExecute,
  474. },
  475. },
  476. taintsToDelete: []v1.Taint{},
  477. expectedTaints: append([]v1.Taint{{Key: "foo_1", Effect: v1.TaintEffectNoExecute}}, node.Spec.Taints...),
  478. expectedOperation: TAINTED,
  479. expectedErr: false,
  480. },
  481. {
  482. name: "delete taint with effect",
  483. overwrite: false,
  484. taintsToAdd: []v1.Taint{},
  485. taintsToDelete: []v1.Taint{
  486. {
  487. Key: "foo",
  488. Effect: v1.TaintEffectNoSchedule,
  489. },
  490. },
  491. expectedTaints: []v1.Taint{},
  492. expectedOperation: UNTAINTED,
  493. expectedErr: false,
  494. },
  495. {
  496. name: "delete taint with no effect",
  497. overwrite: false,
  498. taintsToAdd: []v1.Taint{},
  499. taintsToDelete: []v1.Taint{
  500. {
  501. Key: "foo",
  502. },
  503. },
  504. expectedTaints: []v1.Taint{},
  505. expectedOperation: UNTAINTED,
  506. expectedErr: false,
  507. },
  508. {
  509. name: "delete non-exist taint",
  510. overwrite: false,
  511. taintsToAdd: []v1.Taint{},
  512. taintsToDelete: []v1.Taint{
  513. {
  514. Key: "foo_1",
  515. Effect: v1.TaintEffectNoSchedule,
  516. },
  517. },
  518. expectedTaints: node.Spec.Taints,
  519. expectedOperation: UNTAINTED,
  520. expectedErr: true,
  521. },
  522. {
  523. name: "add new taint and delete old one",
  524. overwrite: false,
  525. taintsToAdd: []v1.Taint{
  526. {
  527. Key: "foo_1",
  528. Effect: v1.TaintEffectNoSchedule,
  529. },
  530. },
  531. taintsToDelete: []v1.Taint{
  532. {
  533. Key: "foo",
  534. Effect: v1.TaintEffectNoSchedule,
  535. },
  536. },
  537. expectedTaints: []v1.Taint{
  538. {
  539. Key: "foo_1",
  540. Effect: v1.TaintEffectNoSchedule,
  541. },
  542. },
  543. expectedOperation: MODIFIED,
  544. expectedErr: false,
  545. },
  546. }
  547. for _, c := range cases {
  548. operation, taints, err := ReorganizeTaints(node, c.overwrite, c.taintsToAdd, c.taintsToDelete)
  549. if c.expectedErr && err == nil {
  550. t.Errorf("[%s] expect to see an error, but did not get one", c.name)
  551. } else if !c.expectedErr && err != nil {
  552. t.Errorf("[%s] expect not to see an error, but got one: %v", c.name, err)
  553. }
  554. if !reflect.DeepEqual(c.expectedTaints, taints) {
  555. t.Errorf("[%s] expect to see taint list %#v, but got: %#v", c.name, c.expectedTaints, taints)
  556. }
  557. if c.expectedOperation != operation {
  558. t.Errorf("[%s] expect to see operation %s, but got: %s", c.name, c.expectedOperation, operation)
  559. }
  560. }
  561. }
  562. func TestParseTaints(t *testing.T) {
  563. cases := []struct {
  564. name string
  565. spec []string
  566. expectedTaints []v1.Taint
  567. expectedTaintsToRemove []v1.Taint
  568. expectedErr bool
  569. }{
  570. {
  571. name: "invalid spec format",
  572. spec: []string{""},
  573. expectedErr: true,
  574. },
  575. {
  576. name: "invalid spec format",
  577. spec: []string{"foo=abc"},
  578. expectedErr: true,
  579. },
  580. {
  581. name: "invalid spec format",
  582. spec: []string{"foo=abc=xyz:NoSchedule"},
  583. expectedErr: true,
  584. },
  585. {
  586. name: "invalid spec format",
  587. spec: []string{"foo=abc:xyz:NoSchedule"},
  588. expectedErr: true,
  589. },
  590. {
  591. name: "invalid spec format for adding taint",
  592. spec: []string{"foo"},
  593. expectedErr: true,
  594. },
  595. {
  596. name: "invalid spec effect for adding taint",
  597. spec: []string{"foo=abc:invalid_effect"},
  598. expectedErr: true,
  599. },
  600. {
  601. name: "invalid spec effect for deleting taint",
  602. spec: []string{"foo:invalid_effect-"},
  603. expectedErr: true,
  604. },
  605. {
  606. name: "add new taints",
  607. spec: []string{"foo=abc:NoSchedule", "bar=abc:NoSchedule", "baz:NoSchedule", "qux:NoSchedule", "foobar=:NoSchedule"},
  608. expectedTaints: []v1.Taint{
  609. {
  610. Key: "foo",
  611. Value: "abc",
  612. Effect: v1.TaintEffectNoSchedule,
  613. },
  614. {
  615. Key: "bar",
  616. Value: "abc",
  617. Effect: v1.TaintEffectNoSchedule,
  618. },
  619. {
  620. Key: "baz",
  621. Value: "",
  622. Effect: v1.TaintEffectNoSchedule,
  623. },
  624. {
  625. Key: "qux",
  626. Value: "",
  627. Effect: v1.TaintEffectNoSchedule,
  628. },
  629. {
  630. Key: "foobar",
  631. Value: "",
  632. Effect: v1.TaintEffectNoSchedule,
  633. },
  634. },
  635. expectedErr: false,
  636. },
  637. {
  638. name: "delete taints",
  639. spec: []string{"foo:NoSchedule-", "bar:NoSchedule-", "qux=:NoSchedule-", "dedicated-"},
  640. expectedTaintsToRemove: []v1.Taint{
  641. {
  642. Key: "foo",
  643. Effect: v1.TaintEffectNoSchedule,
  644. },
  645. {
  646. Key: "bar",
  647. Effect: v1.TaintEffectNoSchedule,
  648. },
  649. {
  650. Key: "qux",
  651. Effect: v1.TaintEffectNoSchedule,
  652. },
  653. {
  654. Key: "dedicated",
  655. },
  656. },
  657. expectedErr: false,
  658. },
  659. {
  660. name: "add taints and delete taints",
  661. spec: []string{"foo=abc:NoSchedule", "bar=abc:NoSchedule", "baz:NoSchedule", "qux:NoSchedule", "foobar=:NoSchedule", "foo:NoSchedule-", "bar:NoSchedule-", "baz=:NoSchedule-"},
  662. expectedTaints: []v1.Taint{
  663. {
  664. Key: "foo",
  665. Value: "abc",
  666. Effect: v1.TaintEffectNoSchedule,
  667. },
  668. {
  669. Key: "bar",
  670. Value: "abc",
  671. Effect: v1.TaintEffectNoSchedule,
  672. },
  673. {
  674. Key: "baz",
  675. Value: "",
  676. Effect: v1.TaintEffectNoSchedule,
  677. },
  678. {
  679. Key: "qux",
  680. Value: "",
  681. Effect: v1.TaintEffectNoSchedule,
  682. },
  683. {
  684. Key: "foobar",
  685. Value: "",
  686. Effect: v1.TaintEffectNoSchedule,
  687. },
  688. },
  689. expectedTaintsToRemove: []v1.Taint{
  690. {
  691. Key: "foo",
  692. Effect: v1.TaintEffectNoSchedule,
  693. },
  694. {
  695. Key: "bar",
  696. Effect: v1.TaintEffectNoSchedule,
  697. },
  698. {
  699. Key: "baz",
  700. Value: "",
  701. Effect: v1.TaintEffectNoSchedule,
  702. },
  703. },
  704. expectedErr: false,
  705. },
  706. }
  707. for _, c := range cases {
  708. taints, taintsToRemove, err := ParseTaints(c.spec)
  709. if c.expectedErr && err == nil {
  710. t.Errorf("[%s] expected error for spec %s, but got nothing", c.name, c.spec)
  711. }
  712. if !c.expectedErr && err != nil {
  713. t.Errorf("[%s] expected no error for spec %s, but got: %v", c.name, c.spec, err)
  714. }
  715. if !reflect.DeepEqual(c.expectedTaints, taints) {
  716. t.Errorf("[%s] expected returen taints as %v, but got: %v", c.name, c.expectedTaints, taints)
  717. }
  718. if !reflect.DeepEqual(c.expectedTaintsToRemove, taintsToRemove) {
  719. t.Errorf("[%s] expected return taints to be removed as %v, but got: %v", c.name, c.expectedTaintsToRemove, taintsToRemove)
  720. }
  721. }
  722. }