github.com/devseccon/trivy@v0.47.1-0.20231123133102-bd902a0bd996/pkg/detector/ospkg/alpine/alpine_test.go (about) 1 package alpine_test 2 3 import ( 4 "sort" 5 "testing" 6 "time" 7 8 "github.com/stretchr/testify/assert" 9 "github.com/stretchr/testify/require" 10 fake "k8s.io/utils/clock/testing" 11 12 "github.com/aquasecurity/trivy-db/pkg/db" 13 dbTypes "github.com/aquasecurity/trivy-db/pkg/types" 14 "github.com/aquasecurity/trivy-db/pkg/vulnsrc/vulnerability" 15 "github.com/devseccon/trivy/pkg/dbtest" 16 "github.com/devseccon/trivy/pkg/detector/ospkg/alpine" 17 ftypes "github.com/devseccon/trivy/pkg/fanal/types" 18 "github.com/devseccon/trivy/pkg/types" 19 ) 20 21 func TestScanner_Detect(t *testing.T) { 22 type args struct { 23 osVer string 24 repo *ftypes.Repository 25 pkgs []ftypes.Package 26 } 27 tests := []struct { 28 name string 29 args args 30 fixtures []string 31 want []types.DetectedVulnerability 32 wantErr string 33 }{ 34 { 35 name: "happy path", 36 fixtures: []string{ 37 "testdata/fixtures/alpine.yaml", 38 "testdata/fixtures/data-source.yaml", 39 }, 40 args: args{ 41 osVer: "3.10.2", 42 pkgs: []ftypes.Package{ 43 { 44 Name: "ansible", 45 Version: "2.6.4", 46 SrcName: "ansible", 47 SrcVersion: "2.6.4", 48 Layer: ftypes.Layer{ 49 DiffID: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", 50 }, 51 }, 52 { 53 Name: "invalid", 54 Version: "invalid", // skipped 55 SrcName: "invalid", 56 SrcVersion: "invalid", 57 }, 58 }, 59 }, 60 want: []types.DetectedVulnerability{ 61 { 62 PkgName: "ansible", 63 VulnerabilityID: "CVE-2019-10217", 64 InstalledVersion: "2.6.4", 65 FixedVersion: "2.8.4-r0", 66 Layer: ftypes.Layer{ 67 DiffID: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", 68 }, 69 DataSource: &dbTypes.DataSource{ 70 ID: vulnerability.Alpine, 71 Name: "Alpine Secdb", 72 URL: "https://secdb.alpinelinux.org/", 73 }, 74 }, 75 { 76 PkgName: "ansible", 77 VulnerabilityID: "CVE-2021-20191", 78 InstalledVersion: "2.6.4", 79 FixedVersion: "", 80 Layer: ftypes.Layer{ 81 DiffID: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", 82 }, 83 DataSource: &dbTypes.DataSource{ 84 ID: vulnerability.Alpine, 85 Name: "Alpine Secdb", 86 URL: "https://secdb.alpinelinux.org/", 87 }, 88 }, 89 }, 90 }, 91 { 92 name: "contain rc", 93 fixtures: []string{ 94 "testdata/fixtures/alpine.yaml", 95 "testdata/fixtures/data-source.yaml", 96 }, 97 args: args{ 98 osVer: "3.10", 99 pkgs: []ftypes.Package{ 100 { 101 Name: "jq", 102 Version: "1.6-r0", 103 SrcName: "jq", 104 SrcVersion: "1.6-r0", 105 }, 106 }, 107 }, 108 want: []types.DetectedVulnerability{ 109 { 110 PkgName: "jq", 111 VulnerabilityID: "CVE-2020-1234", 112 InstalledVersion: "1.6-r0", 113 FixedVersion: "1.6-r1", 114 DataSource: &dbTypes.DataSource{ 115 ID: vulnerability.Alpine, 116 Name: "Alpine Secdb", 117 URL: "https://secdb.alpinelinux.org/", 118 }, 119 }, 120 }, 121 }, 122 { 123 name: "contain pre", 124 fixtures: []string{ 125 "testdata/fixtures/alpine.yaml", 126 "testdata/fixtures/data-source.yaml", 127 }, 128 args: args{ 129 osVer: "3.10", 130 pkgs: []ftypes.Package{ 131 { 132 Name: "test", 133 Version: "0.1.0_alpha", 134 SrcName: "test-src", 135 SrcVersion: "0.1.0_alpha", 136 Layer: ftypes.Layer{ 137 DiffID: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", 138 }, 139 }, 140 }, 141 }, 142 want: []types.DetectedVulnerability{ 143 { 144 VulnerabilityID: "CVE-2030-0002", 145 PkgName: "test", 146 InstalledVersion: "0.1.0_alpha", 147 FixedVersion: "0.1.0_alpha2", 148 Layer: ftypes.Layer{ 149 DiffID: "sha256:932da51564135c98a49a34a193d6cd363d8fa4184d957fde16c9d8527b3f3b02", 150 }, 151 DataSource: &dbTypes.DataSource{ 152 ID: vulnerability.Alpine, 153 Name: "Alpine Secdb", 154 URL: "https://secdb.alpinelinux.org/", 155 }, 156 }, 157 }, 158 }, 159 { 160 name: "repository is newer than OS version", 161 fixtures: []string{ 162 "testdata/fixtures/alpine.yaml", 163 "testdata/fixtures/data-source.yaml", 164 }, 165 args: args{ 166 osVer: "3.9.3", 167 repo: &ftypes.Repository{ 168 Family: ftypes.Alpine, 169 Release: "3.10", 170 }, 171 pkgs: []ftypes.Package{ 172 { 173 Name: "jq", 174 Version: "1.6-r0", 175 SrcName: "jq", 176 SrcVersion: "1.6-r0", 177 }, 178 }, 179 }, 180 want: []types.DetectedVulnerability{ 181 { 182 PkgName: "jq", 183 VulnerabilityID: "CVE-2020-1234", 184 InstalledVersion: "1.6-r0", 185 FixedVersion: "1.6-r1", 186 DataSource: &dbTypes.DataSource{ 187 ID: vulnerability.Alpine, 188 Name: "Alpine Secdb", 189 URL: "https://secdb.alpinelinux.org/", 190 }, 191 }, 192 }, 193 }, 194 { 195 name: "Get returns an error", 196 fixtures: []string{ 197 "testdata/fixtures/invalid.yaml", 198 "testdata/fixtures/data-source.yaml", 199 }, 200 args: args{ 201 osVer: "3.10.2", 202 pkgs: []ftypes.Package{ 203 { 204 Name: "jq", 205 Version: "1.6-r0", 206 SrcName: "jq", 207 SrcVersion: "1.6-r0", 208 }, 209 }, 210 }, 211 wantErr: "failed to get alpine advisories", 212 }, 213 { 214 name: "No src name", 215 fixtures: []string{ 216 "testdata/fixtures/alpine.yaml", 217 "testdata/fixtures/data-source.yaml", 218 }, 219 args: args{ 220 osVer: "3.9.3", 221 repo: &ftypes.Repository{ 222 Family: ftypes.Alpine, 223 Release: "3.10", 224 }, 225 pkgs: []ftypes.Package{ 226 { 227 Name: "jq", 228 Version: "1.6-r0", 229 SrcVersion: "1.6-r0", 230 }, 231 }, 232 }, 233 want: []types.DetectedVulnerability{ 234 { 235 PkgName: "jq", 236 VulnerabilityID: "CVE-2020-1234", 237 InstalledVersion: "1.6-r0", 238 FixedVersion: "1.6-r1", 239 DataSource: &dbTypes.DataSource{ 240 ID: vulnerability.Alpine, 241 Name: "Alpine Secdb", 242 URL: "https://secdb.alpinelinux.org/", 243 }, 244 }, 245 }, 246 }, 247 } 248 for _, tt := range tests { 249 t.Run(tt.name, func(t *testing.T) { 250 _ = dbtest.InitDB(t, tt.fixtures) 251 defer db.Close() 252 253 s := alpine.NewScanner() 254 got, err := s.Detect(tt.args.osVer, tt.args.repo, tt.args.pkgs) 255 if tt.wantErr != "" { 256 require.Error(t, err) 257 assert.Contains(t, err.Error(), tt.wantErr) 258 return 259 } 260 261 sort.Slice(got, func(i, j int) bool { 262 return got[i].VulnerabilityID < got[j].VulnerabilityID 263 }) 264 assert.NoError(t, err) 265 assert.Equal(t, tt.want, got) 266 }) 267 } 268 } 269 270 func TestScanner_IsSupportedVersion(t *testing.T) { 271 type args struct { 272 osFamily ftypes.OSType 273 osVer string 274 } 275 tests := []struct { 276 name string 277 now time.Time 278 args args 279 want bool 280 }{ 281 { 282 name: "alpine 3.6", 283 now: time.Date(2019, 3, 2, 23, 59, 59, 0, time.UTC), 284 args: args{ 285 osFamily: "alpine", 286 osVer: "3.6", 287 }, 288 want: true, 289 }, 290 { 291 name: "alpine 3.6 with EOL", 292 now: time.Date(2019, 5, 2, 23, 59, 59, 0, time.UTC), 293 args: args{ 294 osFamily: "alpine", 295 osVer: "3.6.5", 296 }, 297 want: false, 298 }, 299 { 300 name: "alpine 3.9", 301 now: time.Date(2019, 5, 2, 23, 59, 59, 0, time.UTC), 302 args: args{ 303 osFamily: "alpine", 304 osVer: "3.9.0", 305 }, 306 want: true, 307 }, 308 { 309 name: "alpine 3.10", 310 now: time.Date(2019, 5, 2, 23, 59, 59, 0, time.UTC), 311 args: args{ 312 osFamily: "alpine", 313 osVer: "3.10", 314 }, 315 want: true, 316 }, 317 { 318 name: "unknown", 319 now: time.Date(2019, 5, 2, 23, 59, 59, 0, time.UTC), 320 args: args{ 321 osFamily: "alpine", 322 osVer: "unknown", 323 }, 324 want: true, 325 }, 326 } 327 for _, tt := range tests { 328 t.Run(tt.name, func(t *testing.T) { 329 s := alpine.NewScanner(alpine.WithClock(fake.NewFakeClock(tt.now))) 330 got := s.IsSupportedVersion(tt.args.osFamily, tt.args.osVer) 331 assert.Equal(t, tt.want, got) 332 }) 333 } 334 }