Skip to content

Commit 09403be

Browse files
committed
test(vuln): check that every OS driver narrows the package set
Add a conformance test over the registered drivers, plus a filtering test for Echo. Dropping third-party packages is the default expectation, so a driver that keeps them has to be listed explicitly.
1 parent e075963 commit 09403be

3 files changed

Lines changed: 88 additions & 0 deletions

File tree

pkg/detector/ospkg/detect_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,3 +195,35 @@ func TestNewDetector(t *testing.T) {
195195
})
196196
}
197197
}
198+
199+
// TestDriversFilterThirdPartyPackages checks that every registered driver narrows the
200+
// package set, so a driver whose FilterPackages became a no-op is caught here.
201+
// Provider-built drivers (Root.io, Seal) are not registered and have their own tests.
202+
func TestDriversFilterThirdPartyPackages(t *testing.T) {
203+
// Drivers whose own advisories describe third-party packages, so they keep them.
204+
// Dropping is the default: keeping has to be listed here explicitly.
205+
keepsThirdPartyPackages := map[ftypes.OSType]bool{
206+
ftypes.Echo: true,
207+
}
208+
209+
thirdParty := ftypes.Package{
210+
Name: "nginx",
211+
Repository: ftypes.PackageRepository{
212+
Class: ftypes.RepositoryClassThirdParty,
213+
},
214+
}
215+
216+
for family, drv := range ospkg.Drivers() {
217+
t.Run(string(family), func(t *testing.T) {
218+
got := drv.FilterPackages(t.Context(), []ftypes.Package{thirdParty})
219+
220+
if keepsThirdPartyPackages[family] {
221+
assert.Equal(t, []ftypes.Package{thirdParty}, got,
222+
"%s reads its own advisory feed, so it must keep third-party packages", family)
223+
return
224+
}
225+
assert.Empty(t, got,
226+
"%s matches against the OS vendor's advisories, so it must drop third-party packages", family)
227+
})
228+
}
229+
}

pkg/detector/ospkg/echo/echo_test.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,3 +267,48 @@ func TestScanner_Detect(t *testing.T) {
267267
})
268268
}
269269
}
270+
271+
func TestScanner_FilterPackages(t *testing.T) {
272+
// Echo publishes advisories for software Debian does not ship, which users
273+
// install from the vendor's own repository, so those packages must be kept.
274+
thirdParty := ftypes.Package{
275+
Name: "docker-compose-plugin",
276+
Repository: ftypes.PackageRepository{
277+
Class: ftypes.RepositoryClassThirdParty,
278+
},
279+
}
280+
official := ftypes.Package{
281+
Name: "curl",
282+
Repository: ftypes.PackageRepository{
283+
Class: ftypes.RepositoryClassOfficial,
284+
},
285+
}
286+
287+
tests := []struct {
288+
name string
289+
pkgs []ftypes.Package
290+
want []ftypes.Package
291+
}{
292+
{
293+
name: "package from a third-party repository is kept",
294+
pkgs: []ftypes.Package{thirdParty},
295+
want: []ftypes.Package{thirdParty},
296+
},
297+
{
298+
name: "package from an official repository is kept",
299+
pkgs: []ftypes.Package{official},
300+
want: []ftypes.Package{official},
301+
},
302+
{
303+
name: "no package is dropped",
304+
pkgs: []ftypes.Package{official, thirdParty},
305+
want: []ftypes.Package{official, thirdParty},
306+
},
307+
}
308+
309+
for _, tt := range tests {
310+
t.Run(tt.name, func(t *testing.T) {
311+
assert.Equal(t, tt.want, NewScanner().FilterPackages(t.Context(), tt.pkgs))
312+
})
313+
}
314+
}

pkg/detector/ospkg/export_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package ospkg
2+
3+
import (
4+
"github.com/aquasecurity/trivy/pkg/detector/ospkg/driver"
5+
ftypes "github.com/aquasecurity/trivy/pkg/fanal/types"
6+
)
7+
8+
// Bridge to expose ospkg internals to tests in the ospkg_test package.
9+
10+
// Drivers exports drivers for testing.
11+
var Drivers = func() map[ftypes.OSType]driver.Driver { return drivers }

0 commit comments

Comments
 (0)