Location order on packages should consider evidence annotations when sorting (#3720)

* fix: sorting locations should consider pkg evidence

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

* simplify location test options for comparison

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>

---------

Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com>
This commit is contained in:
Alex Goodman
2025-03-11 10:34:37 -04:00
committed by GitHub
parent 04941c8b97
commit 34e5ff753f
13 changed files with 226 additions and 151 deletions
+9 -9
View File
@@ -30,11 +30,11 @@ func TestDpkgCataloger(t *testing.T) {
pkg.NewLicenseFromLocations("LGPL-2.1", file.NewLocation("/usr/share/doc/libpam-runtime/copyright")),
),
Locations: file.NewLocationSet(
file.NewLocation("/var/lib/dpkg/status"),
file.NewLocation("/var/lib/dpkg/info/libpam-runtime.preinst"),
file.NewLocation("/var/lib/dpkg/info/libpam-runtime.md5sums"),
file.NewLocation("/var/lib/dpkg/info/libpam-runtime.conffiles"),
file.NewLocation("/usr/share/doc/libpam-runtime/copyright"),
file.NewLocation("/var/lib/dpkg/status").WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
file.NewLocation("/var/lib/dpkg/info/libpam-runtime.preinst").WithAnnotation(pkg.EvidenceAnnotationKey, pkg.SupportingEvidenceAnnotation),
file.NewLocation("/var/lib/dpkg/info/libpam-runtime.md5sums").WithAnnotation(pkg.EvidenceAnnotationKey, pkg.SupportingEvidenceAnnotation),
file.NewLocation("/var/lib/dpkg/info/libpam-runtime.conffiles").WithAnnotation(pkg.EvidenceAnnotationKey, pkg.SupportingEvidenceAnnotation),
file.NewLocation("/usr/share/doc/libpam-runtime/copyright").WithAnnotation(pkg.EvidenceAnnotationKey, pkg.SupportingEvidenceAnnotation),
),
Type: pkg.DebPkg,
Metadata: pkg.DpkgDBEntry{
@@ -104,10 +104,10 @@ func TestDpkgCataloger(t *testing.T) {
pkg.NewLicenseFromLocations("GPL-2", file.NewLocation("/usr/share/doc/libsqlite3-0/copyright")),
),
Locations: file.NewLocationSet(
file.NewLocation("/var/lib/dpkg/status.d/libsqlite3-0"),
file.NewLocation("/var/lib/dpkg/status.d/libsqlite3-0.md5sums"),
file.NewLocation("/var/lib/dpkg/status.d/libsqlite3-0.preinst"),
file.NewLocation("/usr/share/doc/libsqlite3-0/copyright"),
file.NewLocation("/var/lib/dpkg/status.d/libsqlite3-0").WithAnnotation(pkg.EvidenceAnnotationKey, pkg.PrimaryEvidenceAnnotation),
file.NewLocation("/var/lib/dpkg/status.d/libsqlite3-0.md5sums").WithAnnotation(pkg.EvidenceAnnotationKey, pkg.SupportingEvidenceAnnotation),
file.NewLocation("/var/lib/dpkg/status.d/libsqlite3-0.preinst").WithAnnotation(pkg.EvidenceAnnotationKey, pkg.SupportingEvidenceAnnotation),
file.NewLocation("/usr/share/doc/libsqlite3-0/copyright").WithAnnotation(pkg.EvidenceAnnotationKey, pkg.SupportingEvidenceAnnotation),
),
Type: pkg.DebPkg,
Metadata: pkg.DpkgDBEntry{
@@ -139,14 +139,14 @@ func Test_stdlibPackageAndRelationships_values(t *testing.T) {
require.Len(t, gotPkgs, 1)
gotPkg := gotPkgs[0]
if d := cmp.Diff(expectedPkg, gotPkg, cmptest.DefaultCommonOptions()...); d != "" {
if d := cmp.Diff(expectedPkg, gotPkg, cmptest.DefaultOptions()...); d != "" {
t.Errorf("unexpected package (-want +got): %s", d)
}
require.Len(t, gotRels, 1)
gotRel := gotRels[0]
if d := cmp.Diff(expectedRel, gotRel, cmptest.DefaultCommonOptions()...); d != "" {
if d := cmp.Diff(expectedRel, gotRel, cmptest.DefaultOptions()...); d != "" {
t.Errorf("unexpected relationship (-want +got): %s", d)
}
@@ -146,29 +146,8 @@ func (p *CatalogTester) ExpectsAssertion(a func(t *testing.T, pkgs []pkg.Package
}
func (p *CatalogTester) IgnoreLocationLayer() *CatalogTester {
p.locationComparer = func(x, y file.Location) bool {
return cmp.Equal(x.Coordinates.RealPath, y.Coordinates.RealPath) && cmp.Equal(x.AccessPath, y.AccessPath)
}
// we need to update the license comparer to use the ignored location layer
p.licenseComparer = func(x, y pkg.License) bool {
return cmp.Equal(x, y, cmp.Comparer(p.locationComparer), cmp.Comparer(
func(x, y file.LocationSet) bool {
xs := x.ToSlice()
ys := y.ToSlice()
if len(xs) != len(ys) {
return false
}
for i, xe := range xs {
ye := ys[i]
if !p.locationComparer(xe, ye) {
return false
}
}
return true
}))
}
p.locationComparer = cmptest.LocationComparerWithoutLayer
p.licenseComparer = cmptest.LicenseComparerWithoutLocationLayer
return p
}
@@ -272,7 +251,7 @@ func (p *CatalogTester) TestCataloger(t *testing.T, cataloger pkg.Cataloger) {
func (p *CatalogTester) assertPkgs(t *testing.T, pkgs []pkg.Package, relationships []artifact.Relationship) {
t.Helper()
p.compareOptions = append(p.compareOptions, cmptest.CommonOptions(p.licenseComparer, p.locationComparer)...)
p.compareOptions = append(p.compareOptions, cmptest.BuildOptions(p.licenseComparer, p.locationComparer)...)
{
r := cmptest.NewDiffReporter()
@@ -325,53 +304,20 @@ func TestFileParserWithEnv(t *testing.T, fixturePath string, parser generic.Pars
NewCatalogTester().FromFile(t, fixturePath).WithEnv(env).Expects(expectedPkgs, expectedRelationships).TestParser(t, parser)
}
func AssertPackagesEqual(t *testing.T, a, b pkg.Package) {
func AssertPackagesEqual(t *testing.T, a, b pkg.Package, userOpts ...cmp.Option) {
t.Helper()
opts := []cmp.Option{
cmpopts.IgnoreFields(pkg.Package{}, "id"), // note: ID is not deterministic for test purposes
cmp.Comparer(
func(x, y file.LocationSet) bool {
xs := x.ToSlice()
ys := y.ToSlice()
opts := cmptest.DefaultOptions()
opts = append(opts, userOpts...)
if len(xs) != len(ys) {
return false
}
for i, xe := range xs {
ye := ys[i]
if !cmptest.DefaultLocationComparer(xe, ye) {
return false
}
}
return true
},
),
cmp.Comparer(
func(x, y pkg.LicenseSet) bool {
xs := x.ToSlice()
ys := y.ToSlice()
if len(xs) != len(ys) {
return false
}
for i, xe := range xs {
ye := ys[i]
if !cmptest.DefaultLicenseComparer(xe, ye) {
return false
}
}
return true
},
),
cmp.Comparer(
cmptest.DefaultLocationComparer,
),
cmp.Comparer(
cmptest.DefaultLicenseComparer,
),
if diff := cmp.Diff(a, b, opts...); diff != "" {
t.Errorf("unexpected packages from parsing (-expected +actual)\n%s", diff)
}
}
func AssertPackagesEqualIgnoreLayers(t *testing.T, a, b pkg.Package, userOpts ...cmp.Option) {
t.Helper()
opts := cmptest.DefaultIgnoreLocationLayerOptions()
opts = append(opts, userOpts...)
if diff := cmp.Diff(a, b, opts...); diff != "" {
t.Errorf("unexpected packages from parsing (-expected +actual)\n%s", diff)
@@ -76,7 +76,7 @@ func TestParseWheelEggMetadata(t *testing.T) {
t.Fatalf("failed to parse: %+v", err)
}
if d := cmp.Diff(test.ExpectedMetadata, actual, cmptest.DefaultCommonOptions()...); d != "" {
if d := cmp.Diff(test.ExpectedMetadata, actual, cmptest.DefaultOptions()...); d != "" {
t.Errorf("metadata mismatch (-want +got):\n%s", d)
}
})