github.com/zppinho/prow@v0.0.0-20240510014325-1738badeb017/cmd/config-bootstrapper/main_test.go (about) 1 /* 2 Copyright 2019 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 main 18 19 import ( 20 "context" 21 "path/filepath" 22 "testing" 23 24 "github.com/google/go-cmp/cmp" 25 26 coreapi "k8s.io/api/core/v1" 27 "k8s.io/apimachinery/pkg/api/equality" 28 "k8s.io/apimachinery/pkg/api/errors" 29 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 30 "k8s.io/apimachinery/pkg/runtime" 31 "k8s.io/client-go/kubernetes/fake" 32 33 "sigs.k8s.io/prow/pkg/git/localgit" 34 "sigs.k8s.io/prow/pkg/plugins" 35 ) 36 37 var ( 38 defaultNamespace = "default" 39 defaultBranch = localgit.DefaultBranch("") 40 ) 41 42 func TestRunV2(t *testing.T) { 43 testRun(localgit.NewV2, t) 44 } 45 46 func testRun(clients localgit.Clients, t *testing.T) { 47 lg, c, err := clients() 48 if err != nil { 49 t.Fatalf("Making local git repo: %v", err) 50 } 51 52 defer func() { 53 if err := c.Clean(); err != nil { 54 t.Errorf("Could not clean up git client cache: %v.", err) 55 } 56 }() 57 58 if err := lg.MakeFakeRepo("openshift", "release"); err != nil { 59 t.Fatalf("Making fake repo: %v", err) 60 } 61 if err := lg.Checkout("openshift", "release", defaultBranch); err != nil { 62 t.Fatalf("Checkout new branch: %v", err) 63 } 64 65 if err := lg.AddCommit("openshift", "release", map[string][]byte{ 66 "config/foo.yaml": []byte(`#foo.yaml`), 67 "config/bar.yaml": []byte(`#bar.yaml`), 68 "VERSION": []byte("some-git-sha"), 69 }); err != nil { 70 t.Fatalf("Add commit: %v", err) 71 } 72 73 if err := lg.MakeFakeRepo("openshift", "other"); err != nil { 74 t.Fatalf("Making fake repo: %v", err) 75 } 76 if err := lg.Checkout("openshift", "other", defaultBranch); err != nil { 77 t.Fatalf("Checkout new branch: %v", err) 78 } 79 80 if err := lg.AddCommit("openshift", "other", map[string][]byte{ 81 "config/other-foo.yaml": []byte(`#other-foo.yaml`), 82 "config/other-bar.yaml": []byte(`#other-bar.yaml`), 83 }); err != nil { 84 t.Fatalf("Add commit: %v", err) 85 } 86 87 if err := lg.MakeFakeRepo("org", "partition-test"); err != nil { 88 t.Fatalf("Making fake repo: %v", err) 89 } 90 if err := lg.Checkout("org", "partition-test", defaultBranch); err != nil { 91 t.Fatalf("Checkout new branch: %v", err) 92 } 93 94 if err := lg.AddCommit("org", "partition-test", map[string][]byte{ 95 "config/foo.yaml": []byte(`#foo.yaml`), 96 "config/bar.yaml": []byte(`#bar.yaml`), 97 "config/baz.yaml": []byte(`#baz.yaml`), 98 }); err != nil { 99 t.Fatalf("Add commit: %v", err) 100 } 101 102 if err := lg.MakeFakeRepo("org", "partition-test2"); err != nil { 103 t.Fatalf("Making fake repo: %v", err) 104 } 105 if err := lg.Checkout("org", "partition-test2", defaultBranch); err != nil { 106 t.Fatalf("Checkout new branch: %v", err) 107 } 108 109 if err := lg.AddCommit("org", "partition-test2", map[string][]byte{ 110 "config/foo.yaml": []byte(`#foo.yaml`), 111 "config/bar.yaml": []byte(`#bar.yaml`), 112 }); err != nil { 113 t.Fatalf("Add commit: %v", err) 114 } 115 116 testcases := []struct { 117 name string 118 sourcePaths []string 119 defaultNamespace string 120 configUpdater plugins.ConfigUpdater 121 expected int 122 123 existConfigMaps []runtime.Object 124 expectedConfigMaps []*coreapi.ConfigMap 125 }{ 126 { 127 name: "issues/15570 is covered", 128 sourcePaths: []string{filepath.Join(lg.Dir, "openshift/release")}, 129 defaultNamespace: defaultNamespace, 130 configUpdater: plugins.ConfigUpdater{ 131 Maps: map[string]plugins.ConfigMapSpec{ 132 "config/foo.yaml": { 133 Name: "multikey-config", 134 Clusters: map[string][]string{ 135 "default": {defaultNamespace}, 136 }, 137 }, 138 "config/bar.yaml": { 139 Name: "multikey-config", 140 }, 141 }, 142 }, 143 existConfigMaps: []runtime.Object{ 144 &coreapi.ConfigMap{ 145 ObjectMeta: metav1.ObjectMeta{ 146 Name: "multikey-config", 147 Namespace: defaultNamespace, 148 Labels: map[string]string{ 149 "app.kubernetes.io/name": "prow", 150 "app.kubernetes.io/component": "updateconfig-plugin", 151 }, 152 }, 153 Data: map[string]string{}, 154 }, 155 }, 156 expectedConfigMaps: []*coreapi.ConfigMap{ 157 { 158 ObjectMeta: metav1.ObjectMeta{ 159 Name: "multikey-config", 160 Namespace: defaultNamespace, 161 Labels: map[string]string{ 162 "app.kubernetes.io/name": "prow", 163 "app.kubernetes.io/component": "updateconfig-plugin", 164 }, 165 }, 166 Data: map[string]string{ 167 "VERSION": "some-git-sha", 168 "foo.yaml": "#foo.yaml", 169 "bar.yaml": "#bar.yaml", 170 }, 171 }, 172 }, 173 }, 174 { 175 name: "multiple sources", 176 sourcePaths: []string{filepath.Join(lg.Dir, "openshift/release"), filepath.Join(lg.Dir, "openshift/other")}, 177 defaultNamespace: defaultNamespace, 178 configUpdater: plugins.ConfigUpdater{ 179 Maps: map[string]plugins.ConfigMapSpec{ 180 "config/foo.yaml": { 181 Name: "multikey-config", 182 Clusters: map[string][]string{ 183 "default": {defaultNamespace}, 184 }, 185 }, 186 "config/bar.yaml": { 187 Name: "multikey-config", 188 }, 189 "config/other-foo.yaml": { 190 Name: "other", 191 Clusters: map[string][]string{ 192 "default": {defaultNamespace}, 193 }, 194 }, 195 "config/other-bar.yaml": { 196 Name: "bar", 197 }, 198 }, 199 }, 200 existConfigMaps: []runtime.Object{ 201 &coreapi.ConfigMap{ 202 ObjectMeta: metav1.ObjectMeta{ 203 Name: "multikey-config", 204 Namespace: defaultNamespace, 205 Labels: map[string]string{ 206 "app.kubernetes.io/name": "prow", 207 "app.kubernetes.io/component": "updateconfig-plugin", 208 }, 209 }, 210 Data: map[string]string{}, 211 }, 212 }, 213 expectedConfigMaps: []*coreapi.ConfigMap{ 214 { 215 ObjectMeta: metav1.ObjectMeta{ 216 Name: "multikey-config", 217 Namespace: defaultNamespace, 218 Labels: map[string]string{ 219 "app.kubernetes.io/name": "prow", 220 "app.kubernetes.io/component": "updateconfig-plugin", 221 }, 222 }, 223 Data: map[string]string{ 224 "VERSION": "some-git-sha", 225 "foo.yaml": "#foo.yaml", 226 "bar.yaml": "#bar.yaml", 227 }, 228 }, 229 { 230 ObjectMeta: metav1.ObjectMeta{ 231 Name: "other", 232 Namespace: defaultNamespace, 233 Labels: map[string]string{ 234 "app.kubernetes.io/name": "prow", 235 "app.kubernetes.io/component": "updateconfig-plugin", 236 }, 237 }, 238 Data: map[string]string{ 239 "VERSION": "some-git-sha", 240 "other-foo.yaml": "#other-foo.yaml", 241 }, 242 }, 243 { 244 ObjectMeta: metav1.ObjectMeta{ 245 Name: "bar", 246 Namespace: defaultNamespace, 247 Labels: map[string]string{ 248 "app.kubernetes.io/name": "prow", 249 "app.kubernetes.io/component": "updateconfig-plugin", 250 }, 251 }, 252 Data: map[string]string{ 253 "VERSION": "some-git-sha", 254 "other-bar.yaml": "#other-bar.yaml", 255 }, 256 }, 257 }, 258 }, 259 { 260 name: "undefined cluster errors", 261 sourcePaths: []string{filepath.Join(lg.Dir, "openshift/release")}, 262 defaultNamespace: defaultNamespace, 263 configUpdater: plugins.ConfigUpdater{ 264 Maps: map[string]plugins.ConfigMapSpec{ 265 "config/foo.yaml": { 266 Name: "multikey-config", 267 Clusters: map[string][]string{ 268 "undef": {defaultNamespace}, 269 }, 270 }, 271 }, 272 }, 273 expected: 1, 274 }, 275 { 276 name: "PartitionedNames properly partitions", 277 sourcePaths: []string{filepath.Join(lg.Dir, "org/partition-test")}, 278 defaultNamespace: defaultNamespace, 279 configUpdater: plugins.ConfigUpdater{ 280 Maps: map[string]plugins.ConfigMapSpec{ 281 "config/**/*.yaml": { 282 PartitionedNames: []string{"job-config-part-1", "job-config-part-2"}, 283 }, 284 }, 285 }, 286 expectedConfigMaps: []*coreapi.ConfigMap{ 287 { 288 ObjectMeta: metav1.ObjectMeta{ 289 Name: "job-config-part-1", 290 Namespace: defaultNamespace, 291 Labels: map[string]string{ 292 "app.kubernetes.io/name": "prow", 293 "app.kubernetes.io/component": "updateconfig-plugin", 294 }, 295 }, 296 Data: map[string]string{ 297 "foo.yaml": "#foo.yaml", 298 "bar.yaml": "#bar.yaml", 299 }, 300 }, 301 { 302 ObjectMeta: metav1.ObjectMeta{ 303 Name: "job-config-part-2", 304 Namespace: defaultNamespace, 305 Labels: map[string]string{ 306 "app.kubernetes.io/name": "prow", 307 "app.kubernetes.io/component": "updateconfig-plugin", 308 }, 309 }, 310 Data: map[string]string{ 311 "baz.yaml": "#baz.yaml", 312 }, 313 }, 314 }, 315 }, 316 { 317 name: "PartitionedNames file moves between partitions properly", 318 sourcePaths: []string{filepath.Join(lg.Dir, "org/partition-test")}, 319 defaultNamespace: defaultNamespace, 320 configUpdater: plugins.ConfigUpdater{ 321 Maps: map[string]plugins.ConfigMapSpec{ 322 "config/**/*.yaml": { 323 PartitionedNames: []string{"job-config-part-1", "job-config-part-2"}, 324 }, 325 }, 326 }, 327 existConfigMaps: []runtime.Object{ 328 &coreapi.ConfigMap{ 329 ObjectMeta: metav1.ObjectMeta{ 330 Name: "job-config-part-1", 331 Namespace: defaultNamespace, 332 Labels: map[string]string{ 333 "app.kubernetes.io/name": "prow", 334 "app.kubernetes.io/component": "updateconfig-plugin", 335 }, 336 }, 337 Data: map[string]string{ 338 "foo.yaml": "#foo.yaml", 339 }, 340 }, 341 &coreapi.ConfigMap{ 342 ObjectMeta: metav1.ObjectMeta{ 343 Name: "job-config-part-2", 344 Namespace: defaultNamespace, 345 Labels: map[string]string{ 346 "app.kubernetes.io/name": "prow", 347 "app.kubernetes.io/component": "updateconfig-plugin", 348 }, 349 }, 350 Data: map[string]string{ 351 "baz.yaml": "#baz.yaml", 352 "barbarbar.yaml": "#bar.yaml", 353 }, 354 }, 355 }, 356 expectedConfigMaps: []*coreapi.ConfigMap{ 357 { 358 ObjectMeta: metav1.ObjectMeta{ 359 Name: "job-config-part-1", 360 Namespace: defaultNamespace, 361 Labels: map[string]string{ 362 "app.kubernetes.io/name": "prow", 363 "app.kubernetes.io/component": "updateconfig-plugin", 364 }, 365 }, 366 Data: map[string]string{ 367 "foo.yaml": "#foo.yaml", 368 "bar.yaml": "#bar.yaml", 369 }, 370 }, 371 { 372 ObjectMeta: metav1.ObjectMeta{ 373 Name: "job-config-part-2", 374 Namespace: defaultNamespace, 375 Labels: map[string]string{ 376 "app.kubernetes.io/name": "prow", 377 "app.kubernetes.io/component": "updateconfig-plugin", 378 }, 379 }, 380 Data: map[string]string{ 381 "baz.yaml": "#baz.yaml", 382 }, 383 }, 384 }, 385 }, 386 { 387 name: "PartitionedNames: emptied partition is properly wiped", 388 sourcePaths: []string{filepath.Join(lg.Dir, "org/partition-test2")}, 389 defaultNamespace: defaultNamespace, 390 configUpdater: plugins.ConfigUpdater{ 391 Maps: map[string]plugins.ConfigMapSpec{ 392 "config/**/*.yaml": { 393 PartitionedNames: []string{"job-config-part-1", "job-config-part-2"}, 394 }, 395 }, 396 }, 397 existConfigMaps: []runtime.Object{ 398 &coreapi.ConfigMap{ 399 ObjectMeta: metav1.ObjectMeta{ 400 Name: "job-config-part-1", 401 Namespace: defaultNamespace, 402 Labels: map[string]string{ 403 "app.kubernetes.io/name": "prow", 404 "app.kubernetes.io/component": "updateconfig-plugin", 405 }, 406 }, 407 Data: map[string]string{ 408 "foo.yaml": "#foo.yaml", 409 }, 410 }, 411 &coreapi.ConfigMap{ 412 ObjectMeta: metav1.ObjectMeta{ 413 Name: "job-config-part-2", 414 Namespace: defaultNamespace, 415 Labels: map[string]string{ 416 "app.kubernetes.io/name": "prow", 417 "app.kubernetes.io/component": "updateconfig-plugin", 418 }, 419 }, 420 Data: map[string]string{ 421 "barbarbar.yaml": "#bar.yaml", 422 }, 423 }, 424 }, 425 expectedConfigMaps: []*coreapi.ConfigMap{ 426 { 427 ObjectMeta: metav1.ObjectMeta{ 428 Name: "job-config-part-1", 429 Namespace: defaultNamespace, 430 Labels: map[string]string{ 431 "app.kubernetes.io/name": "prow", 432 "app.kubernetes.io/component": "updateconfig-plugin", 433 }, 434 }, 435 Data: map[string]string{ 436 "foo.yaml": "#foo.yaml", 437 "bar.yaml": "#bar.yaml", // renamed from barbarbar.yaml 438 }, 439 }, 440 { 441 ObjectMeta: metav1.ObjectMeta{ 442 Name: "job-config-part-2", 443 Namespace: defaultNamespace, 444 Labels: map[string]string{ 445 "app.kubernetes.io/name": "prow", 446 "app.kubernetes.io/component": "updateconfig-plugin", 447 }, 448 }, 449 Data: map[string]string{}, 450 }, 451 }, 452 }, 453 { 454 // The keys for files a, b, and c are unaccounted for (they don't 455 // exist in the repo), so they should be deleted. 456 name: "untouched keys are deleted", 457 sourcePaths: []string{filepath.Join(lg.Dir, "openshift/other")}, 458 defaultNamespace: defaultNamespace, 459 configUpdater: plugins.ConfigUpdater{ 460 Maps: map[string]plugins.ConfigMapSpec{ 461 "config/other-foo.yaml": { 462 Name: "job-config", 463 }, 464 "config/other-bar.yaml": { 465 Name: "job-config", 466 }, 467 }, 468 }, 469 existConfigMaps: []runtime.Object{ 470 &coreapi.ConfigMap{ 471 ObjectMeta: metav1.ObjectMeta{ 472 Name: "job-config", 473 Namespace: defaultNamespace, 474 Labels: map[string]string{ 475 "app.kubernetes.io/name": "prow", 476 "app.kubernetes.io/component": "updateconfig-plugin", 477 }, 478 }, 479 Data: map[string]string{ 480 "other-foo.yaml": "#other-foo.yaml", 481 "other-bar.yaml": "#other-bar.yaml", 482 483 // The ones below should be deleted. 484 "a": "xxx", 485 "b": "xxx", 486 "c": "xxx", 487 }, 488 }, 489 }, 490 expectedConfigMaps: []*coreapi.ConfigMap{ 491 { 492 ObjectMeta: metav1.ObjectMeta{ 493 Name: "job-config", 494 Namespace: defaultNamespace, 495 Labels: map[string]string{ 496 "app.kubernetes.io/name": "prow", 497 "app.kubernetes.io/component": "updateconfig-plugin", 498 }, 499 }, 500 Data: map[string]string{ 501 "other-foo.yaml": "#other-foo.yaml", 502 "other-bar.yaml": "#other-bar.yaml", 503 }, 504 }, 505 }, 506 }, 507 } 508 509 for _, tc := range testcases { 510 t.Run(tc.name, func(t *testing.T) { 511 fkc := fake.NewSimpleClientset(tc.existConfigMaps...) 512 tc.configUpdater.SetDefaults() 513 actual := run(tc.sourcePaths, tc.defaultNamespace, tc.configUpdater, fkc, nil) 514 if tc.expected != actual { 515 t.Errorf("%s: incorrect errors '%d': expecting '%d'", tc.name, actual, tc.expected) 516 } 517 518 for _, expected := range tc.expectedConfigMaps { 519 actual, err := fkc.CoreV1().ConfigMaps(expected.Namespace).Get(context.TODO(), expected.Name, metav1.GetOptions{}) 520 if err != nil && errors.IsNotFound(err) { 521 t.Errorf("%s: Should have updated or created configmap for '%s'", tc.name, expected) 522 } else if !equality.Semantic.DeepEqual(expected, actual) { 523 t.Errorf("%s: incorrect ConfigMap state after update: %v", tc.name, cmp.Diff(expected, actual)) 524 } 525 } 526 }) 527 528 } 529 }