github.com/devseccon/trivy@v0.47.1-0.20231123133102-bd902a0bd996/pkg/fanal/applier/docker_test.go (about) 1 package applier_test 2 3 import ( 4 "sort" 5 "testing" 6 7 "github.com/stretchr/testify/assert" 8 9 "github.com/devseccon/trivy/pkg/fanal/applier" 10 "github.com/devseccon/trivy/pkg/fanal/types" 11 ) 12 13 func TestApplyLayers(t *testing.T) { 14 tests := []struct { 15 name string 16 inputLayers []types.BlobInfo 17 want types.ArtifactDetail 18 }{ 19 { 20 name: "happy path", 21 inputLayers: []types.BlobInfo{ 22 { 23 SchemaVersion: 1, 24 Digest: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", 25 DiffID: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", 26 OS: types.OS{ 27 Family: "alpine", 28 Name: "3.10", 29 }, 30 PackageInfos: []types.PackageInfo{ 31 { 32 FilePath: "lib/apk/db/installed", 33 Packages: types.Packages{ 34 { 35 Name: "openssl", 36 Version: "1.2.3", 37 Release: "4.5.6", 38 }, 39 }, 40 }, 41 }, 42 Applications: []types.Application{ 43 { 44 Type: types.Bundler, 45 FilePath: "app/Gemfile.lock", 46 Libraries: types.Packages{ 47 { 48 Name: "gemlibrary1", 49 Version: "1.2.3", 50 }, 51 }, 52 }, 53 { 54 Type: types.Composer, 55 FilePath: "app/composer.lock", 56 Libraries: types.Packages{ 57 { 58 Name: "phplibrary1", 59 Version: "6.6.6", 60 }, 61 }, 62 }, 63 { 64 Type: types.GemSpec, 65 FilePath: "usr/local/bundle/specifications/gon-6.3.2.gemspec", 66 Libraries: types.Packages{ 67 { 68 Name: "gon", 69 Version: "6.3.2", 70 FilePath: "usr/local/bundle/specifications/gon-6.3.2.gemspec", 71 }, 72 }, 73 }, 74 }, 75 }, 76 { 77 SchemaVersion: 1, 78 Digest: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", 79 DiffID: "sha256:aad63a9339440e7c3e1fff2b988991b9bfb81280042fa7f39a5e327023056819", 80 PackageInfos: []types.PackageInfo{ 81 { 82 FilePath: "lib/apk/db/installed", 83 Packages: types.Packages{ 84 { 85 Name: "openssl", 86 Version: "1.2.3", 87 Release: "4.5.6", 88 }, 89 { 90 // added 91 Name: "musl", 92 Version: "1.2.4", 93 Release: "4.5.7", 94 }, 95 }, 96 }, 97 }, 98 WhiteoutFiles: []string{"app/composer.lock"}, 99 }, 100 { 101 SchemaVersion: 1, 102 Digest: "sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4", 103 DiffID: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", 104 PackageInfos: []types.PackageInfo{ 105 { 106 FilePath: "lib/apk/db/installed", 107 Packages: types.Packages{ 108 { 109 Name: "openssl", 110 Version: "1.2.3", 111 Release: "4.5.6", 112 }, 113 { 114 Name: "musl", 115 Version: "1.2.4", 116 Release: "4.5.8", // updated 117 }, 118 }, 119 }, 120 }, 121 Applications: []types.Application{ 122 { 123 Type: types.GemSpec, 124 FilePath: "var/lib/gems/2.5.0/specifications/activesupport-6.0.2.1.gemspec", 125 Libraries: types.Packages{ 126 { 127 Name: "activesupport", 128 Version: "6.0.2.1", 129 FilePath: "var/lib/gems/2.5.0/specifications/activesupport-6.0.2.1.gemspec", 130 }, 131 }, 132 }, 133 }, 134 }, 135 }, 136 want: types.ArtifactDetail{ 137 OS: types.OS{ 138 Family: "alpine", 139 Name: "3.10", 140 }, 141 Packages: types.Packages{ 142 { 143 Name: "musl", 144 Version: "1.2.4", 145 Release: "4.5.8", 146 Layer: types.Layer{ 147 Digest: "sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4", 148 DiffID: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", 149 }, 150 }, 151 { 152 Name: "openssl", 153 Version: "1.2.3", 154 Release: "4.5.6", 155 Layer: types.Layer{ 156 Digest: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", 157 DiffID: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", 158 }, 159 }, 160 }, 161 Applications: []types.Application{ 162 { 163 Type: types.GemSpec, 164 Libraries: types.Packages{ 165 { 166 Name: "activesupport", 167 Version: "6.0.2.1", 168 FilePath: "var/lib/gems/2.5.0/specifications/activesupport-6.0.2.1.gemspec", 169 Layer: types.Layer{ 170 Digest: "sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4", 171 DiffID: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", 172 }, 173 }, 174 { 175 Name: "gon", 176 Version: "6.3.2", 177 FilePath: "usr/local/bundle/specifications/gon-6.3.2.gemspec", 178 Layer: types.Layer{ 179 Digest: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", 180 DiffID: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", 181 }, 182 }, 183 }, 184 }, 185 { 186 Type: types.Bundler, 187 FilePath: "app/Gemfile.lock", 188 Libraries: types.Packages{ 189 { 190 Name: "gemlibrary1", 191 Version: "1.2.3", 192 Layer: types.Layer{ 193 Digest: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", 194 DiffID: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", 195 }, 196 }, 197 }, 198 }, 199 }, 200 }, 201 }, 202 { 203 name: "happy path with digests in libs/packages (as for SBOM)", 204 inputLayers: []types.BlobInfo{ 205 { 206 SchemaVersion: 2, 207 OS: types.OS{ 208 Family: "debian", 209 Name: "11.8", 210 }, 211 PackageInfos: []types.PackageInfo{ 212 { 213 Packages: types.Packages{ 214 { 215 ID: "adduser@3.118+deb11u1", 216 Name: "adduser", 217 Version: "3.118+deb11u1", 218 Arch: "all", 219 SrcName: "adduser", 220 SrcVersion: "3.118+deb11u1", 221 Ref: "pkg:deb/debian/adduser@3.118%2Bdeb11u1?arch=all&distro=debian-11.8", 222 Layer: types.Layer{ 223 Digest: "sha256:e67fdae3559346105027c63e7fb032bba57e62b1fe9f2da23e6fdfb56384e00b", 224 DiffID: "sha256:633f5bf471f7595b236a21e62dc60beef321db45916363a02ad5af02d794d497", 225 }, 226 }, 227 }, 228 }, 229 }, 230 Applications: []types.Application{ 231 { 232 Type: types.PythonPkg, 233 Libraries: types.Packages{ 234 { 235 Name: "pip", 236 Version: "23.0.1", 237 Layer: types.Layer{ 238 DiffID: "sha256:1def056a3160854c9395aa76282dd62172ec08c18a5fa03bb7d50a777c15ba99", 239 }, 240 FilePath: "usr/local/lib/python3.9/site-packages/pip-23.0.1.dist-info/METADATA", 241 }, 242 }, 243 }, 244 }, 245 }, 246 }, 247 want: types.ArtifactDetail{ 248 OS: types.OS{ 249 Family: "debian", 250 Name: "11.8", 251 }, 252 Packages: types.Packages{ 253 { 254 ID: "adduser@3.118+deb11u1", 255 Name: "adduser", 256 Version: "3.118+deb11u1", 257 Arch: "all", 258 SrcName: "adduser", 259 SrcVersion: "3.118+deb11u1", 260 Ref: "pkg:deb/debian/adduser@3.118%2Bdeb11u1?arch=all&distro=debian-11.8", 261 Layer: types.Layer{ 262 Digest: "sha256:e67fdae3559346105027c63e7fb032bba57e62b1fe9f2da23e6fdfb56384e00b", 263 DiffID: "sha256:633f5bf471f7595b236a21e62dc60beef321db45916363a02ad5af02d794d497", 264 }, 265 }, 266 }, 267 Applications: []types.Application{ 268 { 269 Type: types.PythonPkg, 270 Libraries: types.Packages{ 271 { 272 Name: "pip", 273 Version: "23.0.1", 274 FilePath: "usr/local/lib/python3.9/site-packages/pip-23.0.1.dist-info/METADATA", 275 Layer: types.Layer{ 276 DiffID: "sha256:1def056a3160854c9395aa76282dd62172ec08c18a5fa03bb7d50a777c15ba99", 277 }, 278 }, 279 }, 280 }, 281 }, 282 }, 283 }, 284 { 285 name: "happy path with merging ubuntu version and ESM", 286 inputLayers: []types.BlobInfo{ 287 { 288 SchemaVersion: 1, 289 Digest: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", 290 DiffID: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", 291 OS: types.OS{ 292 Family: "ubuntu", 293 Extended: true, 294 }, 295 }, 296 { 297 SchemaVersion: 1, 298 Digest: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", 299 DiffID: "sha256:aad63a9339440e7c3e1fff2b988991b9bfb81280042fa7f39a5e327023056819", 300 OS: types.OS{ 301 Family: "ubuntu", 302 Name: "16.04", 303 }, 304 }, 305 }, 306 want: types.ArtifactDetail{ 307 OS: types.OS{ 308 Family: "ubuntu", 309 Name: "16.04", 310 Extended: true, 311 }, 312 }, 313 }, 314 { 315 name: "happy path with removed and updated lockfile", 316 inputLayers: []types.BlobInfo{ 317 { 318 SchemaVersion: 1, 319 Digest: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", 320 DiffID: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", 321 OS: types.OS{ 322 Family: "alpine", 323 Name: "3.10", 324 }, 325 Applications: []types.Application{ 326 { 327 Type: types.Bundler, 328 FilePath: "app/Gemfile.lock", 329 Libraries: types.Packages{ 330 { 331 Name: "rails", 332 Version: "5.0.0", 333 }, 334 { 335 Name: "rack", 336 Version: "4.0.0", 337 }, 338 }, 339 }, 340 { 341 Type: types.Composer, 342 FilePath: "app/composer.lock", 343 Libraries: types.Packages{ 344 { 345 Name: "phplibrary1", 346 Version: "6.6.6", 347 }, 348 }, 349 }, 350 { 351 Type: types.GemSpec, 352 FilePath: "var/lib/gems/2.5.0/specifications/activesupport-6.0.2.1.gemspec", 353 Libraries: types.Packages{ 354 { 355 Name: "activesupport", 356 Version: "6.0.2.1", 357 FilePath: "var/lib/gems/2.5.0/specifications/activesupport-6.0.2.1.gemspec", 358 }, 359 }, 360 }, 361 }, 362 }, 363 { 364 SchemaVersion: 1, 365 Digest: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", 366 DiffID: "sha256:aad63a9339440e7c3e1fff2b988991b9bfb81280042fa7f39a5e327023056819", 367 Applications: []types.Application{ 368 { 369 Type: types.Bundler, 370 FilePath: "app/Gemfile.lock", 371 Libraries: types.Packages{ 372 { 373 Name: "rails", 374 Version: "6.0.0", 375 }, 376 { 377 Name: "rack", 378 Version: "4.0.0", 379 }, 380 }, 381 }, 382 { 383 Type: "composer", 384 FilePath: "app/composer2.lock", 385 Libraries: types.Packages{ 386 { 387 Name: "phplibrary1", 388 Version: "6.6.6", 389 }, 390 }, 391 }, 392 }, 393 WhiteoutFiles: []string{ 394 "app/composer.lock", 395 "var/lib/gems/2.5.0/specifications/activesupport-6.0.2.1.gemspec", 396 }, 397 }, 398 }, 399 want: types.ArtifactDetail{ 400 OS: types.OS{ 401 Family: "alpine", 402 Name: "3.10", 403 }, 404 Applications: []types.Application{ 405 { 406 Type: types.Bundler, 407 FilePath: "app/Gemfile.lock", 408 Libraries: types.Packages{ 409 { 410 Name: "rack", 411 Version: "4.0.0", 412 Layer: types.Layer{ 413 Digest: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", 414 DiffID: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", 415 }, 416 }, 417 { 418 Name: "rails", 419 Version: "6.0.0", 420 Layer: types.Layer{ 421 Digest: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", 422 DiffID: "sha256:aad63a9339440e7c3e1fff2b988991b9bfb81280042fa7f39a5e327023056819", 423 }, 424 }, 425 }, 426 }, 427 { 428 Type: types.Composer, 429 FilePath: "app/composer2.lock", 430 Libraries: types.Packages{ 431 { 432 Name: "phplibrary1", 433 Version: "6.6.6", 434 Layer: types.Layer{ 435 Digest: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", 436 DiffID: "sha256:aad63a9339440e7c3e1fff2b988991b9bfb81280042fa7f39a5e327023056819", 437 }, 438 }, 439 }, 440 }, 441 }, 442 }, 443 }, 444 { 445 name: "happy path with removed and updated secret", 446 inputLayers: []types.BlobInfo{ 447 { 448 SchemaVersion: 2, 449 Digest: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", 450 DiffID: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", 451 CreatedBy: "Line_1", 452 Secrets: []types.Secret{ 453 { 454 FilePath: "usr/secret.txt", 455 Findings: []types.SecretFinding{ 456 { 457 RuleID: "aws-access-key-id", 458 Category: "AWS", 459 Severity: "CRITICAL", 460 Title: "AWS Access Key ID", 461 StartLine: 1, 462 EndLine: 1, 463 Match: "AWS_ACCESS_KEY_ID=********************", 464 Code: types.Code{ 465 Lines: []types.Line{ 466 { 467 Number: 1, 468 Content: "AWS_ACCESS_KEY_ID=********************", 469 IsCause: true, 470 Highlighted: "AWS_ACCESS_KEY_ID=********************", 471 FirstCause: true, 472 LastCause: true, 473 }, 474 }, 475 }, 476 }, 477 }, 478 }, 479 }, 480 }, 481 { 482 SchemaVersion: 2, 483 Digest: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", 484 DiffID: "sha256:aad63a9339440e7c3e1fff2b988991b9bfb81280042fa7f39a5e327023056819", 485 CreatedBy: "Line_2", 486 Secrets: []types.Secret{ 487 { 488 FilePath: "usr/secret.txt", 489 Findings: []types.SecretFinding{ 490 { 491 RuleID: "github-pat", 492 Category: "GitHub", 493 Severity: "CRITICAL", 494 Title: "GitHub Personal Access Token", 495 StartLine: 1, 496 EndLine: 1, 497 Match: "GITHUB_PAT=****************************************", 498 Code: types.Code{ 499 Lines: []types.Line{ 500 { 501 Number: 1, 502 Content: "GITHUB_PAT=****************************************", 503 IsCause: true, 504 Highlighted: "GITHUB_PAT=****************************************", 505 FirstCause: true, 506 LastCause: true, 507 }, 508 }, 509 }, 510 }, 511 { 512 RuleID: "aws-access-key-id", 513 Category: "AWS", 514 Severity: "CRITICAL", 515 Title: "AWS Access Key ID", 516 StartLine: 2, 517 EndLine: 2, 518 Match: "AWS_ACCESS_KEY_ID=********************", 519 Code: types.Code{ 520 Lines: []types.Line{ 521 { 522 Number: 1, 523 Content: "AWS_ACCESS_KEY_ID=********************", 524 IsCause: true, 525 Highlighted: "AWS_ACCESS_KEY_ID=********************", 526 FirstCause: true, 527 LastCause: true, 528 }, 529 }, 530 }, 531 }, 532 }, 533 }, 534 }, 535 }, 536 { 537 SchemaVersion: 2, 538 Digest: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", 539 DiffID: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", 540 CreatedBy: "Line_3", 541 WhiteoutFiles: []string{ 542 "usr/secret.txt", 543 }, 544 }, 545 }, 546 want: types.ArtifactDetail{ 547 Secrets: []types.Secret{ 548 { 549 FilePath: "usr/secret.txt", 550 Findings: []types.SecretFinding{ 551 { 552 RuleID: "github-pat", 553 Category: "GitHub", 554 Severity: "CRITICAL", 555 Title: "GitHub Personal Access Token", 556 StartLine: 1, 557 EndLine: 1, 558 Match: "GITHUB_PAT=****************************************", 559 Layer: types.Layer{ 560 Digest: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", 561 DiffID: "sha256:aad63a9339440e7c3e1fff2b988991b9bfb81280042fa7f39a5e327023056819", 562 CreatedBy: "Line_2", 563 }, 564 Code: types.Code{ 565 Lines: []types.Line{ 566 { 567 Number: 1, 568 Content: "GITHUB_PAT=****************************************", 569 IsCause: true, 570 Highlighted: "GITHUB_PAT=****************************************", 571 FirstCause: true, 572 LastCause: true, 573 }, 574 }, 575 }, 576 }, 577 { 578 RuleID: "aws-access-key-id", 579 Category: "AWS", 580 Severity: "CRITICAL", 581 Title: "AWS Access Key ID", 582 StartLine: 2, 583 EndLine: 2, 584 Match: "AWS_ACCESS_KEY_ID=********************", 585 Layer: types.Layer{ 586 Digest: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", 587 DiffID: "sha256:aad63a9339440e7c3e1fff2b988991b9bfb81280042fa7f39a5e327023056819", 588 CreatedBy: "Line_2", 589 }, 590 Code: types.Code{ 591 Lines: []types.Line{ 592 { 593 Number: 1, 594 Content: "AWS_ACCESS_KEY_ID=********************", 595 IsCause: true, 596 Highlighted: "AWS_ACCESS_KEY_ID=********************", 597 FirstCause: true, 598 LastCause: true, 599 }, 600 }, 601 }, 602 }, 603 }, 604 }, 605 }, 606 }, 607 }, 608 { 609 name: "happy path with status.d and opaque dirs without the trailing slash", 610 inputLayers: []types.BlobInfo{ 611 { 612 SchemaVersion: 1, 613 Digest: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", 614 DiffID: "sha256:aad63a9339440e7c3e1fff2b988991b9bfb81280042fa7f39a5e327023056819", 615 OS: types.OS{ 616 Family: "debian", 617 Name: "8", 618 }, 619 PackageInfos: []types.PackageInfo{ 620 { 621 FilePath: "var/lib/dpkg/status.d/openssl", 622 Packages: types.Packages{ 623 { 624 Name: "openssl", 625 Version: "1.2.3", 626 Release: "4.5.6", 627 }, 628 }, 629 }, 630 }, 631 Applications: []types.Application{ 632 { 633 Type: "composer", 634 FilePath: "app/composer.lock", 635 Libraries: types.Packages{ 636 { 637 Name: "phplibrary1", 638 Version: "6.6.6", 639 }, 640 }, 641 }, 642 }, 643 Licenses: []types.LicenseFile{ 644 { 645 Type: types.LicenseTypeDpkg, 646 FilePath: "usr/share/doc/openssl/copyright", 647 Findings: []types.LicenseFinding{ 648 {Name: "OpenSSL"}, 649 }, 650 PkgName: "openssl", 651 }, 652 }, 653 }, 654 { 655 SchemaVersion: 1, 656 Digest: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", 657 DiffID: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", 658 PackageInfos: []types.PackageInfo{ 659 { 660 FilePath: "var/lib/dpkg/status.d/libc", 661 Packages: types.Packages{ 662 { 663 Name: "libc", 664 Version: "1.2.4", 665 Release: "4.5.7", 666 }, 667 }, 668 }, 669 }, 670 Licenses: []types.LicenseFile{ 671 { 672 Type: types.LicenseTypeDpkg, 673 FilePath: "usr/share/doc/libc/copyright", 674 Findings: []types.LicenseFinding{ 675 {Name: "GPL-2"}, 676 }, 677 PkgName: "libc", 678 }, 679 }, 680 OpaqueDirs: []string{"app"}, 681 }, 682 }, 683 want: types.ArtifactDetail{ 684 OS: types.OS{ 685 Family: "debian", 686 Name: "8", 687 }, 688 Packages: types.Packages{ 689 { 690 Name: "libc", 691 Version: "1.2.4", 692 Release: "4.5.7", 693 Licenses: []string{"GPL-2"}, 694 Layer: types.Layer{ 695 Digest: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", 696 DiffID: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", 697 }, 698 }, 699 { 700 Name: "openssl", 701 Version: "1.2.3", 702 Release: "4.5.6", 703 Licenses: []string{"OpenSSL"}, 704 Layer: types.Layer{ 705 Digest: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", 706 DiffID: "sha256:aad63a9339440e7c3e1fff2b988991b9bfb81280042fa7f39a5e327023056819", 707 }, 708 }, 709 }, 710 }, 711 }, 712 { 713 name: "happy path, opaque dirs with the trailing slash", 714 inputLayers: []types.BlobInfo{ 715 { 716 SchemaVersion: 1, 717 Digest: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", 718 DiffID: "sha256:aad63a9339440e7c3e1fff2b988991b9bfb81280042fa7f39a5e327023056819", 719 Applications: []types.Application{ 720 { 721 Type: "composer", 722 FilePath: "app/composer.lock", 723 Libraries: types.Packages{ 724 { 725 Name: "phplibrary1", 726 Version: "6.6.6", 727 }, 728 }, 729 }, 730 }, 731 }, 732 { 733 SchemaVersion: 1, 734 Digest: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", 735 DiffID: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", 736 OpaqueDirs: []string{"app/"}, 737 }, 738 }, 739 want: types.ArtifactDetail{}, 740 }, 741 { 742 name: "happy path with Red Hat content sets", 743 inputLayers: []types.BlobInfo{ 744 { 745 SchemaVersion: 1, 746 Digest: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", 747 DiffID: "sha256:aad63a9339440e7c3e1fff2b988991b9bfb81280042fa7f39a5e327023056819", 748 OS: types.OS{ 749 Family: "redhat", 750 Name: "8", 751 }, 752 PackageInfos: []types.PackageInfo{ 753 { 754 FilePath: "var/lib/rpm/Packages", 755 Packages: types.Packages{ 756 { 757 Name: "openssl", 758 Version: "1.2.3", 759 Release: "4", 760 }, 761 }, 762 }, 763 }, 764 }, 765 { 766 SchemaVersion: 1, 767 Digest: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", 768 DiffID: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", 769 BuildInfo: &types.BuildInfo{ 770 ContentSets: []string{ 771 "rhel-8-for-x86_64-baseos-rpms", 772 "rhel-8-for-x86_64-appstream-rpms", 773 }, 774 }, 775 PackageInfos: []types.PackageInfo{ 776 { 777 FilePath: "var/lib/rpm/Packages", 778 Packages: types.Packages{ 779 { 780 Name: "openssl", 781 Version: "1.2.3", 782 Release: "4", 783 }, 784 { 785 Name: "libc", 786 Version: "1.2.4", 787 Release: "5", 788 }, 789 }, 790 }, 791 }, 792 }, 793 { 794 SchemaVersion: 1, 795 Digest: "sha256:a64e5f34c33ed4c5121498e721e24d95dae2c9599bee4aa6d07850702b401406", 796 DiffID: "sha256:0abd3f2c73de6f02e033f410590111f9339b9500dc07270234f283f2d9a2694b", 797 BuildInfo: &types.BuildInfo{ 798 Nvr: "3scale-amp-apicast-gateway-container-1.11-1", 799 Arch: "x86_64", 800 }, 801 }, 802 { 803 SchemaVersion: 1, 804 Digest: "sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4", 805 DiffID: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", 806 PackageInfos: []types.PackageInfo{ 807 { 808 FilePath: "var/lib/rpm/Packages", 809 Packages: types.Packages{ 810 { 811 Name: "openssl", 812 Version: "1.2.3", 813 Release: "4", 814 }, 815 { 816 Name: "libc", 817 Version: "1.2.4", 818 Release: "5", 819 }, 820 { 821 Name: "bash", 822 Version: "5.6.7", 823 Release: "8", 824 }, 825 }, 826 }, 827 }, 828 }, 829 }, 830 want: types.ArtifactDetail{ 831 OS: types.OS{ 832 Family: "redhat", 833 Name: "8", 834 }, 835 Packages: types.Packages{ 836 { 837 Name: "bash", 838 Version: "5.6.7", 839 Release: "8", 840 Layer: types.Layer{ 841 Digest: "sha256:a3ed95caeb02ffe68cdd9fd84406680ae93d633cb16422d00e8a7c22955b46d4", 842 DiffID: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", 843 }, 844 BuildInfo: &types.BuildInfo{ 845 Nvr: "3scale-amp-apicast-gateway-container-1.11-1", 846 Arch: "x86_64", 847 }, 848 }, 849 { 850 Name: "libc", 851 Version: "1.2.4", 852 Release: "5", 853 Layer: types.Layer{ 854 Digest: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", 855 DiffID: "sha256:a187dde48cd289ac374ad8539930628314bc581a481cdb41409c9289419ddb72", 856 }, 857 BuildInfo: &types.BuildInfo{ 858 ContentSets: []string{ 859 "rhel-8-for-x86_64-baseos-rpms", 860 "rhel-8-for-x86_64-appstream-rpms", 861 }, 862 }, 863 }, 864 { 865 Name: "openssl", 866 Version: "1.2.3", 867 Release: "4", 868 Layer: types.Layer{ 869 Digest: "sha256:24df0d4e20c0f42d3703bf1f1db2bdd77346c7956f74f423603d651e8e5ae8a7", 870 DiffID: "sha256:aad63a9339440e7c3e1fff2b988991b9bfb81280042fa7f39a5e327023056819", 871 }, 872 BuildInfo: &types.BuildInfo{ 873 ContentSets: []string{ 874 "rhel-8-for-x86_64-baseos-rpms", 875 "rhel-8-for-x86_64-appstream-rpms", 876 }, 877 }, 878 }, 879 }, 880 }, 881 }, 882 } 883 884 for _, tt := range tests { 885 t.Run(tt.name, func(t *testing.T) { 886 got := applier.ApplyLayers(tt.inputLayers) 887 sort.Sort(got.Packages) 888 sort.Slice(got.Applications, func(i, j int) bool { 889 return got.Applications[i].FilePath < got.Applications[j].FilePath 890 }) 891 for _, app := range got.Applications { 892 sort.Sort(app.Libraries) 893 } 894 assert.Equal(t, tt.want, got, tt.name) 895 }) 896 } 897 }