github.com/wmuizelaar/kpt@v0.0.0-20221018115725-bd564717b2ed/internal/util/pkgutil/pkgutil_test.go (about) 1 // Copyright 2021 Google LLC 2 // 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 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package pkgutil_test 16 17 import ( 18 "os" 19 "path/filepath" 20 "sort" 21 "testing" 22 23 "github.com/GoogleContainerTools/kpt/internal/pkg" 24 "github.com/GoogleContainerTools/kpt/internal/testutil" 25 "github.com/GoogleContainerTools/kpt/internal/testutil/pkgbuilder" 26 "github.com/GoogleContainerTools/kpt/internal/util/pkgutil" 27 kptfilev1 "github.com/GoogleContainerTools/kpt/pkg/api/kptfile/v1" 28 "github.com/stretchr/testify/assert" 29 ) 30 31 func TestWalkPackage(t *testing.T) { 32 testCases := map[string]struct { 33 pkg *pkgbuilder.RootPkg 34 expected []string 35 }{ 36 "walks subdirectories of a package": { 37 pkg: pkgbuilder.NewRootPkg(). 38 WithFile("abc.yaml", "42"). 39 WithFile("test.txt", "Hello, World!"). 40 WithSubPackages( 41 pkgbuilder.NewSubPkg("foo"). 42 WithFile("def.yaml", "123"), 43 ), 44 expected: []string{ 45 ".", 46 "abc.yaml", 47 "foo", 48 "foo/def.yaml", 49 "test.txt", 50 }, 51 }, 52 "ignores .git folder": { 53 pkg: pkgbuilder.NewRootPkg(). 54 WithFile("abc.yaml", "42"). 55 WithSubPackages( 56 pkgbuilder.NewSubPkg(".git"). 57 WithFile("INDEX", "ABC123"), 58 ), 59 expected: []string{ 60 ".", 61 "abc.yaml", 62 }, 63 }, 64 "ignores subpackages": { 65 pkg: pkgbuilder.NewRootPkg(). 66 WithFile("abc.yaml", "42"). 67 WithFile("test.txt", "Hello, World!"). 68 WithSubPackages( 69 pkgbuilder.NewSubPkg("foo"). 70 WithKptfile(). 71 WithFile("def.yaml", "123"), 72 ), 73 expected: []string{ 74 ".", 75 "abc.yaml", 76 "test.txt", 77 }, 78 }, 79 } 80 81 for tn, tc := range testCases { 82 t.Run(tn, func(t *testing.T) { 83 pkgPath := tc.pkg.ExpandPkg(t, testutil.EmptyReposInfo) 84 85 var visited []string 86 if err := pkgutil.WalkPackage(pkgPath, func(s string, info os.FileInfo, err error) error { 87 if err != nil { 88 return err 89 } 90 91 relPath, err := filepath.Rel(pkgPath, s) 92 if err != nil { 93 return err 94 } 95 visited = append(visited, relPath) 96 return nil 97 }); !assert.NoError(t, err) { 98 t.FailNow() 99 } 100 101 sort.Strings(visited) 102 103 assert.Equal(t, tc.expected, visited) 104 }) 105 } 106 } 107 108 func TestCopyPackage(t *testing.T) { 109 testCases := map[string]struct { 110 pkg *pkgbuilder.RootPkg 111 copyRootKptfile bool 112 subpackageMatcher pkg.SubpackageMatcher 113 expected []string 114 }{ 115 "subpackages without root kptfile": { 116 pkg: pkgbuilder.NewRootPkg(). 117 WithFile("abc.yaml", "42"). 118 WithFile("test.txt", "Hello, World!"). 119 WithSubPackages( 120 pkgbuilder.NewSubPkg("foo"). 121 WithKptfile(). 122 WithFile("def.yaml", "123"), 123 ), 124 copyRootKptfile: false, 125 subpackageMatcher: pkg.Local, 126 expected: []string{ 127 ".", 128 "abc.yaml", 129 "foo", 130 "foo/Kptfile", 131 "foo/def.yaml", 132 "test.txt", 133 }, 134 }, 135 "ignores .git folder": { 136 pkg: pkgbuilder.NewRootPkg(). 137 WithFile("abc.yaml", "42"). 138 WithSubPackages( 139 pkgbuilder.NewSubPkg(".git"). 140 WithFile("INDEX", "ABC123"), 141 ), 142 subpackageMatcher: pkg.None, 143 expected: []string{ 144 ".", 145 "abc.yaml", 146 }, 147 }, 148 "ignore subpackages": { 149 pkg: pkgbuilder.NewRootPkg(). 150 WithKptfile(). 151 WithFile("abc.yaml", "42"). 152 WithFile("test.txt", "Hello, World!"). 153 WithSubPackages( 154 pkgbuilder.NewSubPkg("foo"). 155 WithKptfile(). 156 WithFile("def.yaml", "123"), 157 ), 158 copyRootKptfile: true, 159 subpackageMatcher: pkg.None, 160 expected: []string{ 161 ".", 162 "Kptfile", 163 "abc.yaml", 164 "test.txt", 165 }, 166 }, 167 "include all subpackages": { 168 pkg: pkgbuilder.NewRootPkg(). 169 WithKptfile(). 170 WithFile("abc.yaml", "42"). 171 WithFile("test.txt", "Hello, World!"). 172 WithSubPackages( 173 pkgbuilder.NewSubPkg("foo"). 174 WithKptfile(). 175 WithFile("def.yaml", "123"), 176 pkgbuilder.NewSubPkg("bar"). 177 WithKptfile(pkgbuilder.NewKptfile().WithUpstream("", "", "", "")). 178 WithFile("def.yaml", "123"), 179 ), 180 copyRootKptfile: true, 181 subpackageMatcher: pkg.All, 182 expected: []string{ 183 ".", 184 "Kptfile", 185 "abc.yaml", 186 "bar", 187 "bar/Kptfile", 188 "bar/def.yaml", 189 "foo", 190 "foo/Kptfile", 191 "foo/def.yaml", 192 "test.txt", 193 }, 194 }, 195 "include only local subpackages": { 196 pkg: pkgbuilder.NewRootPkg(). 197 WithKptfile(). 198 WithFile("abc.yaml", "42"). 199 WithFile("test.txt", "Hello, World!"). 200 WithSubPackages( 201 pkgbuilder.NewSubPkg("foo"). 202 WithKptfile(). 203 WithFile("def.yaml", "123"), 204 pkgbuilder.NewSubPkg("bar"). 205 WithKptfile(pkgbuilder.NewKptfile().WithUpstream("", "", "", "")). 206 WithFile("def.yaml", "123"), 207 ), 208 copyRootKptfile: true, 209 subpackageMatcher: pkg.Local, 210 expected: []string{ 211 ".", 212 "Kptfile", 213 "abc.yaml", 214 "foo", 215 "foo/Kptfile", 216 "foo/def.yaml", 217 "test.txt", 218 }, 219 }, 220 "include only remote subpackages": { 221 pkg: pkgbuilder.NewRootPkg(). 222 WithKptfile(). 223 WithFile("abc.yaml", "42"). 224 WithFile("test.txt", "Hello, World!"). 225 WithSubPackages( 226 pkgbuilder.NewSubPkg("foo"). 227 WithKptfile(). 228 WithFile("def.yaml", "123"), 229 pkgbuilder.NewSubPkg("bar"). 230 WithKptfile(pkgbuilder.NewKptfile().WithUpstream("", "", "", "")). 231 WithFile("def.yaml", "123"), 232 ), 233 copyRootKptfile: true, 234 subpackageMatcher: pkg.Remote, 235 expected: []string{ 236 ".", 237 "Kptfile", 238 "abc.yaml", 239 "bar", 240 "bar/Kptfile", 241 "bar/def.yaml", 242 "test.txt", 243 }, 244 }, 245 "include local subpackage with remote child": { 246 pkg: pkgbuilder.NewRootPkg(). 247 WithKptfile(). 248 WithFile("abc.yaml", "42"). 249 WithFile("test.txt", "Hello, World!"). 250 WithSubPackages( 251 pkgbuilder.NewSubPkg("foo"). 252 WithKptfile(). 253 WithFile("def.yaml", "123").WithSubPackages( 254 pkgbuilder.NewSubPkg("bar"). 255 WithKptfile(pkgbuilder.NewKptfile().WithUpstream("", "", "", "")). 256 WithFile("def.yaml", "123"), 257 ), 258 ), 259 copyRootKptfile: true, 260 subpackageMatcher: pkg.Local, 261 expected: []string{ 262 ".", 263 "Kptfile", 264 "abc.yaml", 265 "foo", 266 "foo/Kptfile", 267 "foo/bar", 268 "foo/bar/Kptfile", 269 "foo/bar/def.yaml", 270 "foo/def.yaml", 271 "test.txt", 272 }, 273 }, 274 "include local subpackage with local child": { 275 pkg: pkgbuilder.NewRootPkg(). 276 WithKptfile(). 277 WithFile("abc.yaml", "42"). 278 WithFile("test.txt", "Hello, World!"). 279 WithSubPackages( 280 pkgbuilder.NewSubPkg("foo"). 281 WithKptfile(). 282 WithFile("def.yaml", "123").WithSubPackages( 283 pkgbuilder.NewSubPkg("bar"). 284 WithKptfile(). 285 WithFile("def.yaml", "123"), 286 ), 287 ), 288 copyRootKptfile: true, 289 subpackageMatcher: pkg.Local, 290 expected: []string{ 291 ".", 292 "Kptfile", 293 "abc.yaml", 294 "foo", 295 "foo/Kptfile", 296 "foo/bar", 297 "foo/bar/Kptfile", 298 "foo/bar/def.yaml", 299 "foo/def.yaml", 300 "test.txt", 301 }, 302 }, 303 "include remote subpackage with local child": { 304 pkg: pkgbuilder.NewRootPkg(). 305 WithKptfile(). 306 WithFile("abc.yaml", "42"). 307 WithFile("test.txt", "Hello, World!"). 308 WithSubPackages( 309 pkgbuilder.NewSubPkg("foo"). 310 WithKptfile(pkgbuilder.NewKptfile().WithUpstream("", "", "", "")). 311 WithFile("def.yaml", "123").WithSubPackages( 312 pkgbuilder.NewSubPkg("bar"). 313 WithKptfile(). 314 WithFile("def.yaml", "123"), 315 ), 316 ), 317 copyRootKptfile: true, 318 subpackageMatcher: pkg.Remote, 319 expected: []string{ 320 ".", 321 "Kptfile", 322 "abc.yaml", 323 "foo", 324 "foo/Kptfile", 325 "foo/def.yaml", 326 "foo/bar", 327 "foo/bar/Kptfile", 328 "foo/bar/def.yaml", 329 "test.txt", 330 }, 331 }, 332 "include remote subpackage with remote child": { 333 pkg: pkgbuilder.NewRootPkg(). 334 WithKptfile(). 335 WithFile("abc.yaml", "42"). 336 WithFile("test.txt", "Hello, World!"). 337 WithSubPackages( 338 pkgbuilder.NewSubPkg("foo"). 339 WithKptfile(pkgbuilder.NewKptfile().WithUpstream("", "", "", "")). 340 WithFile("def.yaml", "123").WithSubPackages( 341 pkgbuilder.NewSubPkg("bar"). 342 WithKptfile(pkgbuilder.NewKptfile().WithUpstream("", "", "", "")). 343 WithFile("def.yaml", "123"), 344 ), 345 ), 346 copyRootKptfile: true, 347 subpackageMatcher: pkg.Remote, 348 expected: []string{ 349 ".", 350 "Kptfile", 351 "abc.yaml", 352 "foo", 353 "foo/Kptfile", 354 "foo/def.yaml", 355 "foo/bar", 356 "foo/bar/Kptfile", 357 "foo/bar/def.yaml", 358 "test.txt", 359 }, 360 }, 361 } 362 363 for tn, tc := range testCases { 364 t.Run(tn, func(t *testing.T) { 365 pkgPath := tc.pkg.ExpandPkg(t, testutil.EmptyReposInfo) 366 dest := t.TempDir() 367 368 err := pkgutil.CopyPackage(pkgPath, dest, tc.copyRootKptfile, tc.subpackageMatcher) 369 if !assert.NoError(t, err) { 370 t.FailNow() 371 } 372 373 var visited []string 374 if err = filepath.Walk(dest, func(s string, info os.FileInfo, err error) error { 375 if err != nil { 376 return err 377 } 378 379 relPath, err := filepath.Rel(dest, s) 380 if err != nil { 381 return err 382 } 383 visited = append(visited, relPath) 384 return nil 385 }); !assert.NoError(t, err) { 386 t.FailNow() 387 } 388 389 sort.Strings(visited) 390 391 assert.ElementsMatch(t, tc.expected, visited) 392 }) 393 } 394 } 395 396 func TestFindLocalRecursiveSubpackagesForPaths(t *testing.T) { 397 testCases := map[string]struct { 398 pkgs []*pkgbuilder.RootPkg 399 expected []string 400 }{ 401 "does not include remote subpackages": { 402 pkgs: []*pkgbuilder.RootPkg{ 403 pkgbuilder.NewRootPkg(). 404 WithResource(pkgbuilder.DeploymentResource). 405 WithSubPackages( 406 pkgbuilder.NewSubPkg("foo"). 407 WithKptfile( 408 pkgbuilder.NewKptfile(). 409 WithUpstream("github.com/GoogleContainerTools/kpt", 410 "/", "main", string(kptfilev1.ResourceMerge)), 411 ). 412 WithResource(pkgbuilder.ConfigMapResource), 413 ), 414 }, 415 expected: []string{}, 416 }, 417 "includes local subpackages": { 418 pkgs: []*pkgbuilder.RootPkg{ 419 pkgbuilder.NewRootPkg(). 420 WithResource(pkgbuilder.DeploymentResource). 421 WithSubPackages( 422 pkgbuilder.NewSubPkg("foo"). 423 WithKptfile(). 424 WithResource(pkgbuilder.ConfigMapResource), 425 ), 426 }, 427 expected: []string{ 428 "foo", 429 }, 430 }, 431 "includes root package": { 432 pkgs: []*pkgbuilder.RootPkg{ 433 pkgbuilder.NewRootPkg(). 434 WithKptfile(). 435 WithResource(pkgbuilder.DeploymentResource), 436 }, 437 expected: []string{}, 438 }, 439 "does not include nested remote subpackages": { 440 pkgs: []*pkgbuilder.RootPkg{ 441 pkgbuilder.NewRootPkg(). 442 WithResource(pkgbuilder.DeploymentResource). 443 WithSubPackages( 444 pkgbuilder.NewSubPkg("foo"). 445 WithKptfile( 446 pkgbuilder.NewKptfile(). 447 WithUpstream("github.com/GoogleContainerTools/kpt", 448 "/", "main", string(kptfilev1.ResourceMerge)), 449 ). 450 WithResource(pkgbuilder.ConfigMapResource). 451 WithSubPackages( 452 pkgbuilder.NewSubPkg("bar"). 453 WithSubPackages( 454 pkgbuilder.NewSubPkg("zork"). 455 WithKptfile( 456 pkgbuilder.NewKptfile(). 457 WithUpstream("github.com/GoogleContainerTools/kpt", 458 "/", "main", string(kptfilev1.ResourceMerge)), 459 ). 460 WithResource(pkgbuilder.ConfigMapResource), 461 ), 462 ), 463 ), 464 }, 465 expected: []string{}, 466 }, 467 "includes nested local subpackages": { 468 pkgs: []*pkgbuilder.RootPkg{ 469 pkgbuilder.NewRootPkg(). 470 WithResource(pkgbuilder.DeploymentResource). 471 WithSubPackages( 472 pkgbuilder.NewSubPkg("foo"). 473 WithKptfile(). 474 WithResource(pkgbuilder.ConfigMapResource). 475 WithSubPackages( 476 pkgbuilder.NewSubPkg("zork"). 477 WithKptfile(). 478 WithResource(pkgbuilder.ConfigMapResource), 479 ), 480 pkgbuilder.NewSubPkg("subpkg"). 481 WithKptfile(), 482 ), 483 }, 484 expected: []string{ 485 "foo", 486 "foo/zork", 487 "subpkg", 488 }, 489 }, 490 "multiple packages": { 491 pkgs: []*pkgbuilder.RootPkg{ 492 pkgbuilder.NewRootPkg(). 493 WithResource(pkgbuilder.DeploymentResource). 494 WithSubPackages( 495 pkgbuilder.NewSubPkg("foo"). 496 WithKptfile(). 497 WithResource(pkgbuilder.ConfigMapResource). 498 WithSubPackages( 499 pkgbuilder.NewSubPkg("zork"). 500 WithKptfile(). 501 WithResource(pkgbuilder.ConfigMapResource), 502 ), 503 pkgbuilder.NewSubPkg("subpkg"). 504 WithKptfile(), 505 ), 506 pkgbuilder.NewRootPkg(). 507 WithKptfile(). 508 WithSubPackages( 509 pkgbuilder.NewSubPkg("foo"). 510 WithKptfile(), 511 ), 512 pkgbuilder.NewRootPkg(). 513 WithKptfile(). 514 WithSubPackages( 515 pkgbuilder.NewSubPkg("bar"). 516 WithKptfile(), 517 pkgbuilder.NewSubPkg("remotebar"). 518 WithKptfile( 519 pkgbuilder.NewKptfile(). 520 WithUpstream("github.com/GoogleContainerTools/kpt", 521 "/", "main", string(kptfilev1.ResourceMerge)), 522 ), 523 ), 524 }, 525 expected: []string{ 526 "bar", 527 "foo", 528 "foo/zork", 529 "subpkg", 530 }, 531 }, 532 } 533 534 for tn, tc := range testCases { 535 t.Run(tn, func(t *testing.T) { 536 var pkgPaths []string 537 for _, p := range tc.pkgs { 538 pkgPaths = append(pkgPaths, p.ExpandPkg(t, testutil.EmptyReposInfo)) 539 } 540 541 paths, err := pkgutil.FindSubpackagesForPaths(pkg.Local, true, pkgPaths...) 542 if !assert.NoError(t, err) { 543 t.FailNow() 544 } 545 546 sort.Strings(paths) 547 548 assert.Equal(t, tc.expected, paths) 549 }) 550 } 551 }