github.com/nextlinux/gosbom@v0.81.1-0.20230627115839-1ff50c281391/test/integration/package_deduplication_test.go (about) 1 //go:build !arm64 2 3 package integration 4 5 import ( 6 "fmt" 7 "testing" 8 9 "github.com/nextlinux/gosbom/gosbom/pkg" 10 "github.com/nextlinux/gosbom/gosbom/source" 11 "github.com/stretchr/testify/assert" 12 "github.com/stretchr/testify/require" 13 ) 14 15 func TestPackageDeduplication(t *testing.T) { 16 tests := []struct { 17 scope source.Scope 18 packageCount int 19 instanceCount map[string]int 20 locationCount map[string]int 21 }{ 22 { 23 scope: source.AllLayersScope, 24 packageCount: 174, // without deduplication this would be 618 25 instanceCount: map[string]int{ 26 "basesystem": 1, 27 "wget": 1, 28 "curl": 2, // upgraded in the image 29 "vsftpd": 1, 30 "httpd": 2, // rpm, binary 31 }, 32 locationCount: map[string]int{ 33 "basesystem-10.0-7.el7.centos": 4, 34 "curl-7.29.0-59.el7": 1, // from base image 35 "curl-7.29.0-59.el7_9.1": 3, // upgrade 36 "wget-1.14-18.el7_6.1": 3, 37 "vsftpd-3.0.2-29.el7_9": 2, 38 "httpd-2.4.6-97.el7.centos.5": 1, 39 "httpd-2.4.6": 1, // binary 40 }, 41 }, 42 { 43 scope: source.SquashedScope, 44 packageCount: 172, 45 instanceCount: map[string]int{ 46 "basesystem": 1, 47 "wget": 1, 48 "curl": 1, // upgraded, but the most recent 49 "vsftpd": 1, 50 "httpd": 2, // rpm, binary 51 }, 52 locationCount: map[string]int{ 53 "basesystem-10.0-7.el7.centos": 1, 54 "curl-7.29.0-59.el7_9.1": 1, // upgrade 55 "wget-1.14-18.el7_6.1": 1, 56 "vsftpd-3.0.2-29.el7_9": 1, 57 "httpd-2.4.6-97.el7.centos.5": 1, 58 "httpd-2.4.6": 1, // binary 59 }, 60 }, 61 } 62 63 for _, tt := range tests { 64 t.Run(string(tt.scope), func(t *testing.T) { 65 sbom, _ := catalogFixtureImage(t, "image-vertical-package-dups", tt.scope, nil) 66 67 for _, p := range sbom.Artifacts.Packages.Sorted() { 68 if p.Type == pkg.BinaryPkg { 69 assert.NotEmpty(t, p.Name) 70 } 71 } 72 73 assert.Equal(t, tt.packageCount, sbom.Artifacts.Packages.PackageCount()) 74 for name, expectedInstanceCount := range tt.instanceCount { 75 pkgs := sbom.Artifacts.Packages.PackagesByName(name) 76 77 // with multiple packages with the same name, something is wrong (or this is the wrong fixture) 78 require.Len(t, pkgs, expectedInstanceCount) 79 80 for _, p := range pkgs { 81 nameVersion := fmt.Sprintf("%s-%s", name, p.Version) 82 expectedLocationCount, ok := tt.locationCount[nameVersion] 83 if !ok { 84 t.Fatalf("missing name-version: %s", nameVersion) 85 } 86 87 // we should see merged locations (assumption, there was 1 location for each package) 88 assert.Len(t, p.Locations.ToSlice(), expectedLocationCount) 89 90 // all paths should match 91 assert.Len(t, p.Locations.CoordinateSet().Paths(), 1) 92 } 93 } 94 95 }) 96 } 97 }