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  }