/cluster-autoscaler/cloudprovider/clusterapi/clusterapi_autodiscovery_test.go

https://github.com/kubernetes/autoscaler · Go · 324 lines · 302 code · 7 blank · 15 comment · 22 complexity · b18c27358760a99a364e672404417672 MD5 · raw file

  1. /*
  2. Copyright 2020 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 clusterapi
  14. import (
  15. "reflect"
  16. "testing"
  17. "k8s.io/apimachinery/pkg/labels"
  18. )
  19. func Test_parseAutoDiscoverySpec(t *testing.T) {
  20. for _, tc := range []struct {
  21. name string
  22. spec string
  23. want *clusterAPIAutoDiscoveryConfig
  24. wantErr bool
  25. }{{
  26. name: "missing ':'",
  27. spec: "foo",
  28. wantErr: true,
  29. }, {
  30. name: "wrong provider given",
  31. spec: "asg:tag=k8s.io/cluster-autoscaler/enabled,k8s.io/cluster-autoscaler/clustername",
  32. wantErr: true,
  33. }, {
  34. name: "invalid key/value pair given",
  35. spec: "clusterapi:invalid",
  36. wantErr: true,
  37. }, {
  38. name: "no attributes specified",
  39. spec: "clusterapi:",
  40. want: &clusterAPIAutoDiscoveryConfig{
  41. labelSelector: labels.NewSelector(),
  42. },
  43. wantErr: false,
  44. }, {
  45. name: "only clusterName given",
  46. spec: "clusterapi:clusterName=foo",
  47. want: &clusterAPIAutoDiscoveryConfig{
  48. clusterName: "foo",
  49. labelSelector: labels.NewSelector(),
  50. },
  51. wantErr: false,
  52. }, {
  53. name: "only namespace given",
  54. spec: "clusterapi:namespace=default",
  55. want: &clusterAPIAutoDiscoveryConfig{
  56. namespace: "default",
  57. labelSelector: labels.NewSelector(),
  58. },
  59. wantErr: false,
  60. }, {
  61. name: "no clustername or namespace given, key provided without value",
  62. spec: "clusterapi:mylabel=",
  63. want: &clusterAPIAutoDiscoveryConfig{
  64. labelSelector: labels.SelectorFromSet(labels.Set{"mylabel": ""}),
  65. },
  66. wantErr: false,
  67. }, {
  68. name: "no clustername or namespace given, single key/value pair for labels",
  69. spec: "clusterapi:mylabel=myval",
  70. want: &clusterAPIAutoDiscoveryConfig{
  71. labelSelector: labels.SelectorFromSet(labels.Set{"mylabel": "myval"}),
  72. },
  73. wantErr: false,
  74. }, {
  75. name: "no clustername or namespace given, multiple key/value pair for labels",
  76. spec: "clusterapi:color=blue,shape=square",
  77. want: &clusterAPIAutoDiscoveryConfig{
  78. labelSelector: labels.SelectorFromSet(labels.Set{"color": "blue", "shape": "square"}),
  79. },
  80. wantErr: false,
  81. }, {
  82. name: "no clustername given, multiple key/value pair for labels",
  83. spec: "clusterapi:namespace=test,color=blue,shape=square",
  84. want: &clusterAPIAutoDiscoveryConfig{
  85. namespace: "test",
  86. labelSelector: labels.SelectorFromSet(labels.Set{"color": "blue", "shape": "square"}),
  87. },
  88. wantErr: false,
  89. }, {
  90. name: "no clustername given, single key/value pair for labels",
  91. spec: "clusterapi:namespace=test,color=blue",
  92. want: &clusterAPIAutoDiscoveryConfig{
  93. namespace: "test",
  94. labelSelector: labels.SelectorFromSet(labels.Set{"color": "blue"}),
  95. },
  96. wantErr: false,
  97. }, {
  98. name: "no namespace given, multiple key/value pair for labels",
  99. spec: "clusterapi:clusterName=foo,color=blue,shape=square",
  100. want: &clusterAPIAutoDiscoveryConfig{
  101. clusterName: "foo",
  102. labelSelector: labels.SelectorFromSet(labels.Set{"color": "blue", "shape": "square"}),
  103. },
  104. wantErr: false,
  105. }, {
  106. name: "no namespace given, single key/value pair for labels",
  107. spec: "clusterapi:clusterName=foo,shape=square",
  108. want: &clusterAPIAutoDiscoveryConfig{
  109. clusterName: "foo",
  110. labelSelector: labels.SelectorFromSet(labels.Set{"shape": "square"}),
  111. },
  112. wantErr: false,
  113. }, {
  114. name: "clustername, namespace, multiple key/value pair for labels provided",
  115. spec: "clusterapi:namespace=test,color=blue,shape=square,clusterName=foo",
  116. want: &clusterAPIAutoDiscoveryConfig{
  117. namespace: "test",
  118. clusterName: "foo",
  119. labelSelector: labels.SelectorFromSet(labels.Set{"color": "blue", "shape": "square"}),
  120. },
  121. wantErr: false,
  122. }, {
  123. name: "clustername, namespace, single key/value pair for labels provided",
  124. spec: "clusterapi:namespace=test,color=blue,clusterName=foo",
  125. want: &clusterAPIAutoDiscoveryConfig{
  126. namespace: "test",
  127. clusterName: "foo",
  128. labelSelector: labels.SelectorFromSet(labels.Set{"color": "blue"}),
  129. },
  130. wantErr: false,
  131. }} {
  132. t.Run(tc.name, func(t *testing.T) {
  133. got, err := parseAutoDiscoverySpec(tc.spec)
  134. if (err != nil) != tc.wantErr {
  135. t.Errorf("parseAutoDiscoverySpec() error = %v, wantErr %v", err, tc.wantErr)
  136. return
  137. }
  138. if err == nil && !reflect.DeepEqual(got, tc.want) {
  139. t.Errorf("parseAutoDiscoverySpec() got = %v, want %v", got, tc.want)
  140. }
  141. })
  142. }
  143. }
  144. func Test_parseAutoDiscovery(t *testing.T) {
  145. for _, tc := range []struct {
  146. name string
  147. spec []string
  148. want []*clusterAPIAutoDiscoveryConfig
  149. wantErr bool
  150. }{{
  151. name: "contains invalid spec",
  152. spec: []string{"foo", "clusterapi:color=green"},
  153. wantErr: true,
  154. }, {
  155. name: "clustername, namespace, single key/value pair for labels provided",
  156. spec: []string{
  157. "clusterapi:namespace=test,color=blue,clusterName=foo",
  158. "clusterapi:namespace=default,color=green,clusterName=bar",
  159. },
  160. want: []*clusterAPIAutoDiscoveryConfig{
  161. {
  162. namespace: "test",
  163. clusterName: "foo",
  164. labelSelector: labels.SelectorFromSet(labels.Set{"color": "blue"}),
  165. },
  166. {
  167. namespace: "default",
  168. clusterName: "bar",
  169. labelSelector: labels.SelectorFromSet(labels.Set{"color": "green"}),
  170. },
  171. },
  172. wantErr: false,
  173. }} {
  174. t.Run(tc.name, func(t *testing.T) {
  175. got, err := parseAutoDiscovery(tc.spec)
  176. if (err != nil) != tc.wantErr {
  177. t.Errorf("parseAutoDiscoverySpec() error = %v, wantErr %v", err, tc.wantErr)
  178. return
  179. }
  180. if len(got) != len(tc.want) {
  181. t.Errorf("parseAutoDiscoverySpec() expected length of got to be = %v, got %v", len(tc.want), len(got))
  182. }
  183. if err == nil && !reflect.DeepEqual(got, tc.want) {
  184. t.Errorf("parseAutoDiscoverySpec() got = %v, want %v", got, tc.want)
  185. }
  186. })
  187. }
  188. }
  189. func Test_allowedByAutoDiscoverySpec(t *testing.T) {
  190. for _, tc := range []struct {
  191. name string
  192. testSpec testSpec
  193. autoDiscoveryConfig *clusterAPIAutoDiscoveryConfig
  194. additionalLabels map[string]string
  195. shouldMatch bool
  196. }{{
  197. name: "no clustername, namespace, or label selector specified should match any MachineSet",
  198. testSpec: createTestSpec(RandomString(6), RandomString(6), RandomString(6), 1, false, nil),
  199. autoDiscoveryConfig: &clusterAPIAutoDiscoveryConfig{labelSelector: labels.NewSelector()},
  200. shouldMatch: true,
  201. }, {
  202. name: "no clustername, namespace, or label selector specified should match any MachineDeployment",
  203. testSpec: createTestSpec(RandomString(6), RandomString(6), RandomString(6), 1, true, nil),
  204. autoDiscoveryConfig: &clusterAPIAutoDiscoveryConfig{labelSelector: labels.NewSelector()},
  205. shouldMatch: true,
  206. }, {
  207. name: "clustername specified does not match MachineSet, namespace matches, no labels specified",
  208. testSpec: createTestSpec("default", RandomString(6), RandomString(6), 1, false, nil),
  209. autoDiscoveryConfig: &clusterAPIAutoDiscoveryConfig{
  210. clusterName: "foo",
  211. namespace: "default",
  212. labelSelector: labels.NewSelector(),
  213. },
  214. shouldMatch: false,
  215. }, {
  216. name: "clustername specified does not match MachineDeployment, namespace matches, no labels specified",
  217. testSpec: createTestSpec("default", RandomString(6), RandomString(6), 1, true, nil),
  218. autoDiscoveryConfig: &clusterAPIAutoDiscoveryConfig{
  219. clusterName: "foo",
  220. namespace: "default",
  221. labelSelector: labels.NewSelector(),
  222. },
  223. shouldMatch: false,
  224. }, {
  225. name: "namespace specified does not match MachineSet, clusterName matches, no labels specified",
  226. testSpec: createTestSpec(RandomString(6), "foo", RandomString(6), 1, false, nil),
  227. autoDiscoveryConfig: &clusterAPIAutoDiscoveryConfig{
  228. clusterName: "foo",
  229. namespace: "default",
  230. labelSelector: labels.NewSelector(),
  231. },
  232. shouldMatch: false,
  233. }, {
  234. name: "clustername specified does not match MachineDeployment, namespace matches, no labels specified",
  235. testSpec: createTestSpec(RandomString(6), "foo", RandomString(6), 1, true, nil),
  236. autoDiscoveryConfig: &clusterAPIAutoDiscoveryConfig{
  237. clusterName: "foo",
  238. namespace: "default",
  239. labelSelector: labels.NewSelector(),
  240. },
  241. shouldMatch: false,
  242. }, {
  243. name: "namespace and clusterName matches MachineSet, no labels specified",
  244. testSpec: createTestSpec("default", "foo", RandomString(6), 1, false, nil),
  245. autoDiscoveryConfig: &clusterAPIAutoDiscoveryConfig{
  246. clusterName: "foo",
  247. namespace: "default",
  248. labelSelector: labels.NewSelector(),
  249. },
  250. shouldMatch: true,
  251. }, {
  252. name: "namespace and clusterName matches MachineDeployment, no labels specified",
  253. testSpec: createTestSpec("default", "foo", RandomString(6), 1, true, nil),
  254. autoDiscoveryConfig: &clusterAPIAutoDiscoveryConfig{
  255. clusterName: "foo",
  256. namespace: "default",
  257. labelSelector: labels.NewSelector(),
  258. },
  259. shouldMatch: true,
  260. }, {
  261. name: "namespace and clusterName matches MachineSet, does not match label selector",
  262. testSpec: createTestSpec("default", "foo", RandomString(6), 1, false, nil),
  263. autoDiscoveryConfig: &clusterAPIAutoDiscoveryConfig{
  264. clusterName: "foo",
  265. namespace: "default",
  266. labelSelector: labels.SelectorFromSet(labels.Set{"color": "green"}),
  267. },
  268. shouldMatch: false,
  269. }, {
  270. name: "namespace and clusterName matches MachineDeployment, does not match label selector",
  271. testSpec: createTestSpec("default", "foo", RandomString(6), 1, true, nil),
  272. autoDiscoveryConfig: &clusterAPIAutoDiscoveryConfig{
  273. clusterName: "foo",
  274. namespace: "default",
  275. labelSelector: labels.SelectorFromSet(labels.Set{"color": "green"}),
  276. },
  277. shouldMatch: false,
  278. }, {
  279. name: "namespace, clusterName, and label selector matches MachineSet",
  280. testSpec: createTestSpec("default", "foo", RandomString(6), 1, false, nil),
  281. additionalLabels: map[string]string{"color": "green"},
  282. autoDiscoveryConfig: &clusterAPIAutoDiscoveryConfig{
  283. clusterName: "foo",
  284. namespace: "default",
  285. labelSelector: labels.SelectorFromSet(labels.Set{"color": "green"}),
  286. },
  287. shouldMatch: true,
  288. }, {
  289. name: "namespace, clusterName, and label selector matches MachineDeployment",
  290. testSpec: createTestSpec("default", "foo", RandomString(6), 1, true, nil),
  291. additionalLabels: map[string]string{"color": "green"},
  292. autoDiscoveryConfig: &clusterAPIAutoDiscoveryConfig{
  293. clusterName: "foo",
  294. namespace: "default",
  295. labelSelector: labels.SelectorFromSet(labels.Set{"color": "green"}),
  296. },
  297. shouldMatch: true,
  298. }} {
  299. t.Run(tc.name, func(t *testing.T) {
  300. testConfigs := createTestConfigs(tc.testSpec)
  301. resource := testConfigs[0].machineSet
  302. if tc.testSpec.rootIsMachineDeployment {
  303. resource = testConfigs[0].machineDeployment
  304. }
  305. if tc.additionalLabels != nil {
  306. resource.SetLabels(labels.Merge(resource.GetLabels(), tc.additionalLabels))
  307. }
  308. got := allowedByAutoDiscoverySpec(tc.autoDiscoveryConfig, resource)
  309. if got != tc.shouldMatch {
  310. t.Errorf("allowedByAutoDiscoverySpec got = %v, want %v", got, tc.shouldMatch)
  311. }
  312. })
  313. }
  314. }