github.com/anchore/syft@v1.4.2-0.20240516191711-1bec1fc5d397/syft/file/location_set_test.go (about) 1 package file 2 3 import ( 4 "testing" 5 6 "github.com/stretchr/testify/assert" 7 "github.com/stretchr/testify/require" 8 9 "github.com/anchore/syft/syft/artifact" 10 ) 11 12 func TestLocationSet(t *testing.T) { 13 14 etcHostsLinkVar := Location{ 15 LocationData: LocationData{ 16 Coordinates: Coordinates{ 17 RealPath: "/etc/hosts", 18 FileSystemID: "a", 19 }, 20 AccessPath: "/var/etc/hosts", 21 }, 22 } 23 24 etcHostsLinkHome := Location{ 25 LocationData: LocationData{ 26 Coordinates: Coordinates{ 27 RealPath: "/etc/hosts", 28 FileSystemID: "a", 29 }, 30 AccessPath: "/home/wagoodman/hosts", 31 }, 32 } 33 34 binA := Location{ 35 LocationData: LocationData{ 36 Coordinates: Coordinates{ 37 RealPath: "/bin", 38 FileSystemID: "a", 39 }, 40 AccessPath: "/usr/bin", 41 }, 42 } 43 44 binB := Location{ 45 LocationData: LocationData{ 46 Coordinates: Coordinates{ 47 RealPath: "/bin", 48 FileSystemID: "b", 49 }, 50 AccessPath: "/usr/bin", 51 }, 52 } 53 54 tests := []struct { 55 name string 56 input []Location 57 expected []Location 58 }{ 59 { 60 name: "de-dup same location", 61 input: []Location{ 62 binA, binA, binA, 63 }, 64 expected: []Location{ 65 binA, 66 }, 67 }, 68 { 69 name: "dont de-dup different filesystem", 70 input: []Location{ 71 binB, binA, 72 }, 73 expected: []Location{ 74 binA, binB, 75 }, 76 }, 77 { 78 name: "dont de-dup different virtual paths", 79 input: []Location{ 80 etcHostsLinkVar, etcHostsLinkHome, 81 }, 82 expected: []Location{ 83 etcHostsLinkHome, etcHostsLinkVar, 84 }, 85 }, 86 } 87 88 for _, test := range tests { 89 t.Run(test.name, func(t *testing.T) { 90 set := NewLocationSet(test.input...) 91 assert.Equal(t, test.expected, set.ToSlice()) 92 }) 93 } 94 } 95 96 func TestLocationSet_Hash(t *testing.T) { 97 etcAlink := Location{ 98 LocationData: LocationData{ 99 Coordinates: Coordinates{ 100 RealPath: "/etc/hosts", 101 FileSystemID: "a", 102 }, 103 AccessPath: "/var/etc/hosts", 104 }, 105 } 106 107 etcA := Location{ 108 LocationData: LocationData{ 109 Coordinates: Coordinates{ 110 RealPath: "/etc/hosts", 111 FileSystemID: "a", 112 }, 113 }, 114 } 115 116 etcB := Location{ 117 LocationData: LocationData{ 118 Coordinates: Coordinates{ 119 RealPath: "/etc/hosts", 120 FileSystemID: "b", 121 }, 122 }, 123 } 124 125 binA := Location{ 126 LocationData: LocationData{ 127 Coordinates: Coordinates{ 128 RealPath: "/bin", 129 FileSystemID: "a", 130 }, 131 AccessPath: "/usr/bin", 132 }, 133 } 134 135 binB := Location{ 136 LocationData: LocationData{ 137 Coordinates: Coordinates{ 138 RealPath: "/bin", 139 FileSystemID: "b", 140 }, 141 AccessPath: "/usr/bin", 142 }, 143 } 144 145 tests := []struct { 146 name string 147 setA LocationSet 148 setB LocationSet 149 want assert.ComparisonAssertionFunc 150 }{ 151 { 152 name: "empty sets have the same hash", 153 setA: NewLocationSet(), 154 setB: NewLocationSet(), 155 want: assert.Equal, 156 }, 157 { 158 name: "sets with same elements accessed through different paths have the same hash", 159 setA: NewLocationSet(binA, etcA), 160 setB: NewLocationSet(etcAlink, binA), 161 want: assert.Equal, 162 }, 163 { 164 name: "sets with same elements have the same hash", 165 setA: NewLocationSet(binA, etcA), 166 setB: NewLocationSet(etcA, binA), 167 want: assert.Equal, 168 }, 169 { 170 name: "sets with different element counts have different hashes", 171 setA: NewLocationSet(binA, etcA), 172 setB: NewLocationSet(binA), 173 want: assert.NotEqual, 174 }, 175 { 176 name: "sets with same path but different FS IDs have the same hash", 177 setA: NewLocationSet(binA), 178 setB: NewLocationSet(binB), 179 want: assert.Equal, 180 }, 181 { 182 name: "sets with same paths but different FS IDs have the same hash", 183 setA: NewLocationSet(etcA, binA), 184 setB: NewLocationSet(binB, etcB), 185 want: assert.Equal, 186 }, 187 } 188 for _, tt := range tests { 189 t.Run(tt.name, func(t *testing.T) { 190 gotA, err := artifact.IDByHash(tt.setA) 191 require.NoError(t, err) 192 gotB, err := artifact.IDByHash(tt.setB) 193 require.NoError(t, err) 194 tt.want(t, gotA, gotB) 195 }) 196 } 197 }