k8s.io/apiserver@v0.31.1/pkg/endpoints/installer_test.go (about) 1 /* 2 Copyright 2015 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package endpoints 18 19 import ( 20 "testing" 21 22 "github.com/stretchr/testify/require" 23 apidiscoveryv2 "k8s.io/api/apidiscovery/v2" 24 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 25 ) 26 27 func TestIsVowel(t *testing.T) { 28 tests := []struct { 29 name string 30 arg rune 31 want bool 32 }{ 33 { 34 name: "yes", 35 arg: 'E', 36 want: true, 37 }, 38 { 39 name: "no", 40 arg: 'n', 41 want: false, 42 }, 43 } 44 for _, tt := range tests { 45 if got := isVowel(tt.arg); got != tt.want { 46 t.Errorf("%q. IsVowel() = %v, want %v", tt.name, got, tt.want) 47 } 48 } 49 } 50 51 func TestGetArticleForNoun(t *testing.T) { 52 tests := []struct { 53 noun string 54 padding string 55 want string 56 }{ 57 { 58 noun: "Frog", 59 padding: " ", 60 want: " a ", 61 }, 62 { 63 noun: "frogs", 64 padding: " ", 65 want: " ", 66 }, 67 { 68 noun: "apple", 69 padding: "", 70 want: "an", 71 }, 72 { 73 noun: "Apples", 74 padding: " ", 75 want: " ", 76 }, 77 { 78 noun: "Ingress", 79 padding: " ", 80 want: " an ", 81 }, 82 { 83 noun: "Class", 84 padding: " ", 85 want: " a ", 86 }, 87 { 88 noun: "S", 89 padding: " ", 90 want: " a ", 91 }, 92 { 93 noun: "O", 94 padding: " ", 95 want: " an ", 96 }, 97 } 98 for _, tt := range tests { 99 if got := GetArticleForNoun(tt.noun, tt.padding); got != tt.want { 100 t.Errorf("%q. GetArticleForNoun() = %v, want %v", tt.noun, got, tt.want) 101 } 102 } 103 } 104 105 func TestConvertAPIResourceToDiscovery(t *testing.T) { 106 tests := []struct { 107 name string 108 resources []metav1.APIResource 109 wantAPIResourceDiscovery []apidiscoveryv2.APIResourceDiscovery 110 wantErr bool 111 }{ 112 { 113 name: "Basic Test", 114 resources: []metav1.APIResource{ 115 { 116 117 Name: "pods", 118 Namespaced: true, 119 Kind: "Pod", 120 ShortNames: []string{"po"}, 121 Verbs: []string{"create", "delete", "deletecollection", "get", "list", "patch", "update", "watch"}, 122 }, 123 }, 124 wantAPIResourceDiscovery: []apidiscoveryv2.APIResourceDiscovery{ 125 { 126 Resource: "pods", 127 Scope: apidiscoveryv2.ScopeNamespace, 128 ResponseKind: &metav1.GroupVersionKind{ 129 Kind: "Pod", 130 }, 131 ShortNames: []string{"po"}, 132 Verbs: []string{"create", "delete", "deletecollection", "get", "list", "patch", "update", "watch"}, 133 }, 134 }, 135 }, 136 { 137 name: "Basic Group Version Test", 138 resources: []metav1.APIResource{ 139 { 140 Name: "cronjobs", 141 Namespaced: true, 142 Group: "batch", 143 Version: "v1", 144 Kind: "CronJob", 145 ShortNames: []string{"cj"}, 146 Verbs: []string{"create", "delete", "deletecollection", "get", "list", "patch", "update", "watch"}, 147 }, 148 }, 149 wantAPIResourceDiscovery: []apidiscoveryv2.APIResourceDiscovery{ 150 { 151 Resource: "cronjobs", 152 Scope: apidiscoveryv2.ScopeNamespace, 153 ResponseKind: &metav1.GroupVersionKind{ 154 Group: "batch", 155 Version: "v1", 156 Kind: "CronJob", 157 }, 158 ShortNames: []string{"cj"}, 159 Verbs: []string{"create", "delete", "deletecollection", "get", "list", "patch", "update", "watch"}, 160 }, 161 }, 162 }, 163 { 164 name: "Test with subresource", 165 resources: []metav1.APIResource{ 166 { 167 Name: "cronjobs", 168 Namespaced: true, 169 Kind: "CronJob", 170 Group: "batch", 171 Version: "v1", 172 ShortNames: []string{"cj"}, 173 Verbs: []string{"create", "delete", "deletecollection", "get", "list", "patch", "update", "watch"}, 174 }, 175 { 176 Name: "cronjobs/status", 177 Namespaced: true, 178 Kind: "CronJob", 179 Group: "batch", 180 Version: "v1", 181 ShortNames: []string{"cj"}, 182 Verbs: []string{"create", "delete", "deletecollection", "get", "list", "patch", "update", "watch"}, 183 }, 184 }, 185 wantAPIResourceDiscovery: []apidiscoveryv2.APIResourceDiscovery{ 186 { 187 Resource: "cronjobs", 188 Scope: apidiscoveryv2.ScopeNamespace, 189 ResponseKind: &metav1.GroupVersionKind{ 190 Group: "batch", 191 Version: "v1", 192 Kind: "CronJob", 193 }, 194 ShortNames: []string{"cj"}, 195 Verbs: []string{"create", "delete", "deletecollection", "get", "list", "patch", "update", "watch"}, 196 Subresources: []apidiscoveryv2.APISubresourceDiscovery{{ 197 Subresource: "status", 198 ResponseKind: &metav1.GroupVersionKind{ 199 Group: "batch", 200 Version: "v1", 201 Kind: "CronJob", 202 }, 203 Verbs: []string{"create", "delete", "deletecollection", "get", "list", "patch", "update", "watch"}, 204 }}, 205 }, 206 }, 207 }, 208 { 209 name: "Test multiple resources and subresources", 210 resources: []metav1.APIResource{ 211 { 212 Name: "cronjobs", 213 Namespaced: true, 214 Kind: "CronJob", 215 Group: "batch", 216 Version: "v1", 217 ShortNames: []string{"cj"}, 218 Verbs: []string{"create", "delete", "deletecollection", "get", "list", "patch", "update", "watch"}, 219 }, 220 { 221 Name: "cronjobs/status", 222 Namespaced: true, 223 Kind: "CronJob", 224 Group: "batch", 225 Version: "v1", 226 ShortNames: []string{"cj"}, 227 Verbs: []string{"create", "delete", "deletecollection", "get", "list", "patch", "update", "watch"}, 228 }, 229 { 230 Name: "deployments", 231 Namespaced: true, 232 Kind: "Deployment", 233 Group: "apps", 234 Version: "v1", 235 ShortNames: []string{"deploy"}, 236 Verbs: []string{"create", "delete", "deletecollection", "get", "list", "patch", "update", "watch"}, 237 }, 238 { 239 Name: "deployments/status", 240 Namespaced: true, 241 Kind: "Deployment", 242 Group: "apps", 243 Version: "v1", 244 ShortNames: []string{"deploy"}, 245 Verbs: []string{"create", "delete", "deletecollection", "get", "list", "patch", "update", "watch"}, 246 }, 247 }, 248 wantAPIResourceDiscovery: []apidiscoveryv2.APIResourceDiscovery{ 249 { 250 Resource: "cronjobs", 251 Scope: apidiscoveryv2.ScopeNamespace, 252 ResponseKind: &metav1.GroupVersionKind{ 253 Group: "batch", 254 Version: "v1", 255 Kind: "CronJob", 256 }, 257 ShortNames: []string{"cj"}, 258 Verbs: []string{"create", "delete", "deletecollection", "get", "list", "patch", "update", "watch"}, 259 Subresources: []apidiscoveryv2.APISubresourceDiscovery{{ 260 Subresource: "status", 261 ResponseKind: &metav1.GroupVersionKind{ 262 Group: "batch", 263 Version: "v1", 264 Kind: "CronJob", 265 }, 266 Verbs: []string{"create", "delete", "deletecollection", "get", "list", "patch", "update", "watch"}, 267 }}, 268 }, { 269 Resource: "deployments", 270 Scope: apidiscoveryv2.ScopeNamespace, 271 ResponseKind: &metav1.GroupVersionKind{ 272 Group: "apps", 273 Version: "v1", 274 Kind: "Deployment", 275 }, 276 ShortNames: []string{"deploy"}, 277 Verbs: []string{"create", "delete", "deletecollection", "get", "list", "patch", "update", "watch"}, 278 Subresources: []apidiscoveryv2.APISubresourceDiscovery{{ 279 Subresource: "status", 280 ResponseKind: &metav1.GroupVersionKind{ 281 Group: "apps", 282 Version: "v1", 283 Kind: "Deployment", 284 }, 285 Verbs: []string{"create", "delete", "deletecollection", "get", "list", "patch", "update", "watch"}, 286 }}, 287 }, 288 }, 289 }, { 290 name: "Test with subresource with no parent", 291 resources: []metav1.APIResource{ 292 { 293 Name: "cronjobs/status", 294 Namespaced: true, 295 Kind: "CronJob", 296 Group: "batch", 297 Version: "v1", 298 Verbs: []string{"create", "delete", "deletecollection", "get", "list", "patch", "update", "watch"}, 299 }, 300 }, 301 wantAPIResourceDiscovery: []apidiscoveryv2.APIResourceDiscovery{ 302 { 303 Resource: "cronjobs", 304 Scope: apidiscoveryv2.ScopeNamespace, 305 // populated to avoid nil panics 306 ResponseKind: &metav1.GroupVersionKind{}, 307 Subresources: []apidiscoveryv2.APISubresourceDiscovery{{ 308 Subresource: "status", 309 ResponseKind: &metav1.GroupVersionKind{ 310 Group: "batch", 311 Version: "v1", 312 Kind: "CronJob", 313 }, 314 Verbs: []string{"create", "delete", "deletecollection", "get", "list", "patch", "update", "watch"}, 315 }}, 316 }, 317 }, 318 }, 319 { 320 name: "Test with subresource with missing kind", 321 resources: []metav1.APIResource{ 322 { 323 Name: "cronjobs/status", 324 Namespaced: true, 325 Group: "batch", 326 Version: "v1", 327 Verbs: []string{"create", "delete", "deletecollection", "get", "list", "patch", "update", "watch"}, 328 }, 329 }, 330 wantAPIResourceDiscovery: []apidiscoveryv2.APIResourceDiscovery{ 331 { 332 Resource: "cronjobs", 333 Scope: apidiscoveryv2.ScopeNamespace, 334 // populated to avoid nil panics 335 ResponseKind: &metav1.GroupVersionKind{}, 336 Subresources: []apidiscoveryv2.APISubresourceDiscovery{{ 337 Subresource: "status", 338 // populated to avoid nil panics 339 ResponseKind: &metav1.GroupVersionKind{}, 340 Verbs: []string{"create", "delete", "deletecollection", "get", "list", "patch", "update", "watch"}, 341 }}, 342 }, 343 }, 344 }, 345 { 346 name: "Test with mismatch parent and subresource scope", 347 resources: []metav1.APIResource{ 348 { 349 Name: "cronjobs", 350 Namespaced: true, 351 Kind: "CronJob", 352 Group: "batch", 353 Version: "v1", 354 ShortNames: []string{"cj"}, 355 Verbs: []string{"create", "delete", "deletecollection", "get", "list", "patch", "update", "watch"}, 356 }, 357 { 358 Name: "cronjobs/status", 359 Namespaced: false, 360 Kind: "CronJob", 361 Group: "batch", 362 Version: "v1", 363 ShortNames: []string{"cj"}, 364 Verbs: []string{"create", "delete", "deletecollection", "get", "list", "patch", "update", "watch"}, 365 }, 366 }, 367 wantAPIResourceDiscovery: []apidiscoveryv2.APIResourceDiscovery{}, 368 wantErr: true, 369 }, 370 { 371 name: "Cluster Scope Test", 372 resources: []metav1.APIResource{ 373 { 374 Name: "nodes", 375 Namespaced: false, 376 Kind: "Node", 377 ShortNames: []string{"no"}, 378 Verbs: []string{"create", "delete", "deletecollection", "get", "list", "patch", "update", "watch"}, 379 }, 380 }, 381 wantAPIResourceDiscovery: []apidiscoveryv2.APIResourceDiscovery{ 382 { 383 Resource: "nodes", 384 Scope: apidiscoveryv2.ScopeCluster, 385 ResponseKind: &metav1.GroupVersionKind{ 386 Kind: "Node", 387 }, 388 ShortNames: []string{"no"}, 389 Verbs: []string{"create", "delete", "deletecollection", "get", "list", "patch", "update", "watch"}, 390 }, 391 }, 392 }, 393 { 394 name: "Namespace Scope Test", 395 resources: []metav1.APIResource{ 396 { 397 Name: "nodes", 398 Namespaced: true, 399 Kind: "Node", 400 ShortNames: []string{"no"}, 401 Verbs: []string{"create", "delete", "deletecollection", "get", "list", "patch", "update", "watch"}, 402 }, 403 }, 404 wantAPIResourceDiscovery: []apidiscoveryv2.APIResourceDiscovery{ 405 { 406 Resource: "nodes", 407 Scope: apidiscoveryv2.ScopeNamespace, 408 ResponseKind: &metav1.GroupVersionKind{ 409 Kind: "Node", 410 }, 411 ShortNames: []string{"no"}, 412 Verbs: []string{"create", "delete", "deletecollection", "get", "list", "patch", "update", "watch"}, 413 }, 414 }, 415 }, 416 { 417 name: "Singular Resource Name", 418 resources: []metav1.APIResource{ 419 { 420 Name: "nodes", 421 SingularName: "node", 422 Kind: "Node", 423 ShortNames: []string{"no"}, 424 Verbs: []string{"create", "delete", "deletecollection", "get", "list", "patch", "update", "watch"}, 425 }, 426 }, 427 wantAPIResourceDiscovery: []apidiscoveryv2.APIResourceDiscovery{ 428 { 429 Resource: "nodes", 430 SingularResource: "node", 431 Scope: apidiscoveryv2.ScopeCluster, 432 ResponseKind: &metav1.GroupVersionKind{ 433 Kind: "Node", 434 }, 435 ShortNames: []string{"no"}, 436 Verbs: []string{"create", "delete", "deletecollection", "get", "list", "patch", "update", "watch"}, 437 }, 438 }, 439 }, 440 } 441 442 for _, tt := range tests { 443 discoveryAPIResources, err := ConvertGroupVersionIntoToDiscovery(tt.resources) 444 if err != nil { 445 if tt.wantErr == false { 446 t.Error(err) 447 } 448 } else { 449 require.Equal(t, tt.wantAPIResourceDiscovery, discoveryAPIResources) 450 } 451 } 452 }