mirror of
https://github.com/anchore/syft.git
synced 2026-11-02 15:36:41 +01:00
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:
@@ -1,15 +1,17 @@
|
||||
package file
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/anchore/syft/internal/evidence"
|
||||
"github.com/anchore/syft/syft/artifact"
|
||||
)
|
||||
|
||||
func TestLocationSet(t *testing.T) {
|
||||
func TestLocationSet_SortPaths(t *testing.T) {
|
||||
|
||||
etcHostsLinkVar := Location{
|
||||
LocationData: LocationData{
|
||||
@@ -93,6 +95,117 @@ func TestLocationSet(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestLocationSet_SortEvidence(t *testing.T) {
|
||||
primaryEvidence := map[string]string{evidence.AnnotationKey: evidence.PrimaryAnnotation}
|
||||
secondaryEvidence := map[string]string{evidence.AnnotationKey: evidence.SupportingAnnotation}
|
||||
|
||||
binPrimary := Location{
|
||||
LocationData: LocationData{
|
||||
Coordinates: Coordinates{
|
||||
RealPath: "/bin",
|
||||
FileSystemID: "a",
|
||||
},
|
||||
AccessPath: "/usr/bin",
|
||||
},
|
||||
LocationMetadata: LocationMetadata{
|
||||
Annotations: primaryEvidence,
|
||||
},
|
||||
}
|
||||
|
||||
binSecondary := Location{
|
||||
LocationData: LocationData{
|
||||
Coordinates: Coordinates{
|
||||
RealPath: "/bin",
|
||||
FileSystemID: "a",
|
||||
},
|
||||
AccessPath: "/usr/bin",
|
||||
},
|
||||
LocationMetadata: LocationMetadata{
|
||||
Annotations: secondaryEvidence,
|
||||
},
|
||||
}
|
||||
|
||||
binNoEvidence := Location{
|
||||
LocationData: LocationData{
|
||||
Coordinates: Coordinates{
|
||||
RealPath: "/bin",
|
||||
FileSystemID: "a",
|
||||
},
|
||||
AccessPath: "/usr/bin",
|
||||
},
|
||||
}
|
||||
|
||||
etcHostsPrimary := Location{
|
||||
LocationData: LocationData{
|
||||
Coordinates: Coordinates{
|
||||
RealPath: "/etc/hosts",
|
||||
FileSystemID: "a",
|
||||
},
|
||||
AccessPath: "/var/etc/hosts",
|
||||
},
|
||||
LocationMetadata: LocationMetadata{
|
||||
Annotations: primaryEvidence,
|
||||
},
|
||||
}
|
||||
|
||||
etcHostsSecondary := Location{
|
||||
LocationData: LocationData{
|
||||
Coordinates: Coordinates{
|
||||
RealPath: "/etc/hosts",
|
||||
FileSystemID: "a",
|
||||
},
|
||||
AccessPath: "/var/etc/hosts",
|
||||
},
|
||||
LocationMetadata: LocationMetadata{
|
||||
Annotations: secondaryEvidence,
|
||||
},
|
||||
}
|
||||
|
||||
etcHostsNoEvidence := Location{
|
||||
LocationData: LocationData{
|
||||
Coordinates: Coordinates{
|
||||
RealPath: "/etc/hosts",
|
||||
FileSystemID: "a",
|
||||
},
|
||||
AccessPath: "/var/etc/hosts",
|
||||
},
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
input []Location
|
||||
expected []Location
|
||||
}{
|
||||
{
|
||||
name: "sort primary, secondary, tertiary, no evidence",
|
||||
input: []Location{
|
||||
binNoEvidence, binPrimary, binSecondary,
|
||||
},
|
||||
expected: []Location{
|
||||
binPrimary, binSecondary, binNoEvidence,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "sort by evidence, then path",
|
||||
input: []Location{
|
||||
etcHostsNoEvidence, etcHostsSecondary,
|
||||
binSecondary, binNoEvidence,
|
||||
binPrimary, etcHostsPrimary,
|
||||
},
|
||||
expected: []Location{
|
||||
binPrimary, etcHostsPrimary, binSecondary, etcHostsSecondary, binNoEvidence, etcHostsNoEvidence,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
sort.Sort(Locations(test.input))
|
||||
assert.Equal(t, test.expected, test.input)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestLocationSet_Hash(t *testing.T) {
|
||||
etcAlink := Location{
|
||||
LocationData: LocationData{
|
||||
|
||||
+19
-5
@@ -1,5 +1,7 @@
|
||||
package file
|
||||
|
||||
import "github.com/anchore/syft/internal/evidence"
|
||||
|
||||
type Locations []Location
|
||||
|
||||
func (l Locations) Len() int {
|
||||
@@ -7,13 +9,25 @@ func (l Locations) Len() int {
|
||||
}
|
||||
|
||||
func (l Locations) Less(i, j int) bool {
|
||||
if l[i].RealPath == l[j].RealPath {
|
||||
if l[i].AccessPath == l[j].AccessPath {
|
||||
return l[i].FileSystemID < l[j].FileSystemID
|
||||
liEvidence := l[i].Annotations[evidence.AnnotationKey]
|
||||
ljEvidence := l[j].Annotations[evidence.AnnotationKey]
|
||||
if liEvidence == ljEvidence {
|
||||
if l[i].RealPath == l[j].RealPath {
|
||||
if l[i].AccessPath == l[j].AccessPath {
|
||||
return l[i].FileSystemID < l[j].FileSystemID
|
||||
}
|
||||
return l[i].AccessPath < l[j].AccessPath
|
||||
}
|
||||
return l[i].AccessPath < l[j].AccessPath
|
||||
return l[i].RealPath < l[j].RealPath
|
||||
}
|
||||
return l[i].RealPath < l[j].RealPath
|
||||
if liEvidence == evidence.PrimaryAnnotation {
|
||||
return true
|
||||
}
|
||||
if ljEvidence == evidence.PrimaryAnnotation {
|
||||
return false
|
||||
}
|
||||
|
||||
return liEvidence > ljEvidence
|
||||
}
|
||||
|
||||
func (l Locations) Swap(i, j int) {
|
||||
|
||||
Reference in New Issue
Block a user