mirror of
https://github.com/anchore/syft.git
synced 2026-11-01 23:16:30 +01:00
Add file catalogers to selection configuration (#3505)
* add file catalogers to selection configuration Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * fix typos Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * warn when there is conflicting file cataloging configuration Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * allow for explicit removal of all package and file tasks Signed-off-by: Alex Goodman <wagoodman@users.noreply.github.com> * address PR feedback 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:
+459
-41
@@ -10,7 +10,7 @@ import (
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/anchore/syft/internal/sbomsync"
|
||||
"github.com/anchore/syft/syft/cataloging/pkgcataloging"
|
||||
"github.com/anchore/syft/syft/cataloging"
|
||||
"github.com/anchore/syft/syft/file"
|
||||
)
|
||||
|
||||
@@ -21,45 +21,54 @@ func dummyTask(name string, tags ...string) Task {
|
||||
}
|
||||
|
||||
// note: this test fixture does not need to be kept up to date here, but makes a great test subject
|
||||
func createDummyTasks() tasks {
|
||||
func createDummyPackageTasks() tasks {
|
||||
return []Task{
|
||||
// OS package installed catalogers
|
||||
dummyTask("alpm-db-cataloger", "directory", "installed", "image", "os", "alpm", "archlinux"),
|
||||
dummyTask("apk-db-cataloger", "directory", "installed", "image", "os", "apk", "alpine"),
|
||||
dummyTask("dpkg-db-cataloger", "directory", "installed", "image", "os", "dpkg", "debian"),
|
||||
dummyTask("portage-cataloger", "directory", "installed", "image", "os", "portage", "gentoo"),
|
||||
dummyTask("rpm-db-cataloger", "directory", "installed", "image", "os", "rpm", "redhat"),
|
||||
dummyTask("alpm-db-cataloger", "package", "directory", "installed", "image", "os", "alpm", "archlinux"),
|
||||
dummyTask("apk-db-cataloger", "package", "directory", "installed", "image", "os", "apk", "alpine"),
|
||||
dummyTask("dpkg-db-cataloger", "package", "directory", "installed", "image", "os", "dpkg", "debian"),
|
||||
dummyTask("portage-cataloger", "package", "directory", "installed", "image", "os", "portage", "gentoo"),
|
||||
dummyTask("rpm-db-cataloger", "package", "directory", "installed", "image", "os", "rpm", "redhat"),
|
||||
|
||||
// OS package declared catalogers
|
||||
dummyTask("rpm-archive-cataloger", "declared", "directory", "os", "rpm", "redhat"),
|
||||
dummyTask("rpm-archive-cataloger", "package", "declared", "directory", "os", "rpm", "redhat"),
|
||||
|
||||
// language-specific package installed catalogers
|
||||
dummyTask("conan-info-cataloger", "installed", "image", "language", "cpp", "conan"),
|
||||
dummyTask("javascript-package-cataloger", "installed", "image", "language", "javascript", "node"),
|
||||
dummyTask("php-composer-installed-cataloger", "installed", "image", "language", "php", "composer"),
|
||||
dummyTask("ruby-installed-gemspec-cataloger", "installed", "image", "language", "ruby", "gem", "gemspec"),
|
||||
dummyTask("rust-cargo-lock-cataloger", "installed", "image", "language", "rust", "binary"),
|
||||
dummyTask("conan-info-cataloger", "package", "installed", "image", "language", "cpp", "conan"),
|
||||
dummyTask("javascript-package-cataloger", "package", "installed", "image", "language", "javascript", "node"),
|
||||
dummyTask("php-composer-installed-cataloger", "package", "installed", "image", "language", "php", "composer"),
|
||||
dummyTask("ruby-installed-gemspec-cataloger", "package", "installed", "image", "language", "ruby", "gem", "gemspec"),
|
||||
dummyTask("rust-cargo-lock-cataloger", "package", "installed", "image", "language", "rust", "binary"),
|
||||
|
||||
// language-specific package declared catalogers
|
||||
dummyTask("conan-cataloger", "declared", "directory", "language", "cpp", "conan"),
|
||||
dummyTask("dart-pubspec-lock-cataloger", "declared", "directory", "language", "dart"),
|
||||
dummyTask("dotnet-deps-cataloger", "declared", "directory", "language", "dotnet", "c#"),
|
||||
dummyTask("elixir-mix-lock-cataloger", "declared", "directory", "language", "elixir"),
|
||||
dummyTask("erlang-rebar-lock-cataloger", "declared", "directory", "language", "erlang"),
|
||||
dummyTask("javascript-lock-cataloger", "declared", "directory", "language", "javascript", "node", "npm"),
|
||||
dummyTask("conan-cataloger", "package", "declared", "directory", "language", "cpp", "conan"),
|
||||
dummyTask("dart-pubspec-lock-cataloger", "package", "declared", "directory", "language", "dart"),
|
||||
dummyTask("dotnet-deps-cataloger", "package", "declared", "directory", "language", "dotnet", "c#"),
|
||||
dummyTask("elixir-mix-lock-cataloger", "package", "declared", "directory", "language", "elixir"),
|
||||
dummyTask("erlang-rebar-lock-cataloger", "package", "declared", "directory", "language", "erlang"),
|
||||
dummyTask("javascript-lock-cataloger", "package", "declared", "directory", "language", "javascript", "node", "npm"),
|
||||
|
||||
// language-specific package for both image and directory scans (but not necessarily declared)
|
||||
dummyTask("dotnet-portable-executable-cataloger", "directory", "installed", "image", "language", "dotnet", "c#"),
|
||||
dummyTask("python-installed-package-cataloger", "directory", "installed", "image", "language", "python"),
|
||||
dummyTask("go-module-binary-cataloger", "directory", "installed", "image", "language", "go", "golang", "gomod", "binary"),
|
||||
dummyTask("java-archive-cataloger", "directory", "installed", "image", "language", "java", "maven"),
|
||||
dummyTask("graalvm-native-image-cataloger", "directory", "installed", "image", "language", "java"),
|
||||
dummyTask("dotnet-portable-executable-cataloger", "package", "directory", "installed", "image", "language", "dotnet", "c#"),
|
||||
dummyTask("python-installed-package-cataloger", "package", "directory", "installed", "image", "language", "python"),
|
||||
dummyTask("go-module-binary-cataloger", "package", "directory", "installed", "image", "language", "go", "golang", "gomod", "binary"),
|
||||
dummyTask("java-archive-cataloger", "package", "directory", "installed", "image", "language", "java", "maven"),
|
||||
dummyTask("graalvm-native-image-cataloger", "package", "directory", "installed", "image", "language", "java"),
|
||||
|
||||
// other package catalogers
|
||||
dummyTask("binary-cataloger", "declared", "directory", "image", "binary"),
|
||||
dummyTask("github-actions-usage-cataloger", "declared", "directory", "github", "github-actions"),
|
||||
dummyTask("github-action-workflow-usage-cataloger", "declared", "directory", "github", "github-actions"),
|
||||
dummyTask("sbom-cataloger", "declared", "directory", "image", "sbom"),
|
||||
dummyTask("binary-cataloger", "package", "declared", "directory", "image", "binary"),
|
||||
dummyTask("github-actions-usage-cataloger", "package", "declared", "directory", "github", "github-actions"),
|
||||
dummyTask("github-action-workflow-usage-cataloger", "package", "declared", "directory", "github", "github-actions"),
|
||||
dummyTask("sbom-cataloger", "package", "declared", "directory", "image", "sbom"),
|
||||
}
|
||||
}
|
||||
|
||||
func createDummyFileTasks() tasks {
|
||||
return []Task{
|
||||
dummyTask("file-content-cataloger", "file", "content"),
|
||||
dummyTask("file-metadata-cataloger", "file", "metadata"),
|
||||
dummyTask("file-digest-cataloger", "file", "digest"),
|
||||
dummyTask("file-executable-cataloger", "file", "binary-metadata"),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,7 +81,7 @@ func TestSelect(t *testing.T) {
|
||||
expressions []string
|
||||
wantNames []string
|
||||
wantTokens map[string]TokenSelection
|
||||
wantRequest pkgcataloging.SelectionRequest
|
||||
wantRequest cataloging.SelectionRequest
|
||||
wantErr assert.ErrorAssertionFunc
|
||||
}{
|
||||
{
|
||||
@@ -82,11 +91,11 @@ func TestSelect(t *testing.T) {
|
||||
expressions: []string{},
|
||||
wantNames: []string{},
|
||||
wantTokens: map[string]TokenSelection{},
|
||||
wantRequest: pkgcataloging.SelectionRequest{},
|
||||
wantRequest: cataloging.SelectionRequest{},
|
||||
},
|
||||
{
|
||||
name: "use default tasks",
|
||||
allTasks: createDummyTasks(),
|
||||
allTasks: createDummyPackageTasks(),
|
||||
basis: []string{
|
||||
"image",
|
||||
},
|
||||
@@ -129,13 +138,13 @@ func TestSelect(t *testing.T) {
|
||||
"binary-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"sbom-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
},
|
||||
wantRequest: pkgcataloging.SelectionRequest{
|
||||
wantRequest: cataloging.SelectionRequest{
|
||||
DefaultNamesOrTags: []string{"image"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "select, add, and remove tasks",
|
||||
allTasks: createDummyTasks(),
|
||||
allTasks: createDummyPackageTasks(),
|
||||
basis: []string{
|
||||
"image",
|
||||
},
|
||||
@@ -175,7 +184,7 @@ func TestSelect(t *testing.T) {
|
||||
"binary-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"sbom-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
},
|
||||
wantRequest: pkgcataloging.SelectionRequest{
|
||||
wantRequest: cataloging.SelectionRequest{
|
||||
DefaultNamesOrTags: []string{"image"},
|
||||
SubSelectTags: []string{"os"},
|
||||
RemoveNamesOrTags: []string{"dpkg"},
|
||||
@@ -184,7 +193,7 @@ func TestSelect(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "allow for partial selections",
|
||||
allTasks: createDummyTasks(),
|
||||
allTasks: createDummyPackageTasks(),
|
||||
basis: []string{
|
||||
"image",
|
||||
},
|
||||
@@ -228,7 +237,7 @@ func TestSelect(t *testing.T) {
|
||||
"binary-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"sbom-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
},
|
||||
wantRequest: pkgcataloging.SelectionRequest{
|
||||
wantRequest: cataloging.SelectionRequest{
|
||||
DefaultNamesOrTags: []string{"image"},
|
||||
SubSelectTags: []string{"os", "rust-cargo-lock-cataloger"},
|
||||
RemoveNamesOrTags: []string{"dpkg"},
|
||||
@@ -238,7 +247,7 @@ func TestSelect(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "select all tasks",
|
||||
allTasks: createDummyTasks(),
|
||||
allTasks: createDummyPackageTasks(),
|
||||
basis: []string{
|
||||
"all",
|
||||
},
|
||||
@@ -299,13 +308,13 @@ func TestSelect(t *testing.T) {
|
||||
"github-action-workflow-usage-cataloger": newTokenSelection([]string{"all"}, nil),
|
||||
"sbom-cataloger": newTokenSelection([]string{"all"}, nil),
|
||||
},
|
||||
wantRequest: pkgcataloging.SelectionRequest{
|
||||
wantRequest: cataloging.SelectionRequest{
|
||||
DefaultNamesOrTags: []string{"all"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "set default with multiple tags",
|
||||
allTasks: createDummyTasks(),
|
||||
allTasks: createDummyPackageTasks(),
|
||||
basis: []string{
|
||||
"gemspec",
|
||||
"python",
|
||||
@@ -319,10 +328,31 @@ func TestSelect(t *testing.T) {
|
||||
"ruby-installed-gemspec-cataloger": newTokenSelection([]string{"gemspec"}, nil),
|
||||
"python-installed-package-cataloger": newTokenSelection([]string{"python"}, nil),
|
||||
},
|
||||
wantRequest: pkgcataloging.SelectionRequest{
|
||||
wantRequest: cataloging.SelectionRequest{
|
||||
DefaultNamesOrTags: []string{"gemspec", "python"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "automatically add file to default tags",
|
||||
allTasks: createDummyFileTasks(),
|
||||
basis: []string{},
|
||||
expressions: []string{},
|
||||
wantNames: []string{
|
||||
"file-content-cataloger",
|
||||
"file-metadata-cataloger",
|
||||
"file-digest-cataloger",
|
||||
"file-executable-cataloger",
|
||||
},
|
||||
wantTokens: map[string]TokenSelection{
|
||||
"file-content-cataloger": newTokenSelection([]string{"file"}, nil),
|
||||
"file-metadata-cataloger": newTokenSelection([]string{"file"}, nil),
|
||||
"file-digest-cataloger": newTokenSelection([]string{"file"}, nil),
|
||||
"file-executable-cataloger": newTokenSelection([]string{"file"}, nil),
|
||||
},
|
||||
wantRequest: cataloging.SelectionRequest{
|
||||
DefaultNamesOrTags: []string{"file"},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
@@ -330,7 +360,7 @@ func TestSelect(t *testing.T) {
|
||||
tt.wantErr = assert.NoError
|
||||
}
|
||||
|
||||
req := pkgcataloging.NewSelectionRequest().WithDefaults(tt.basis...).WithExpression(tt.expressions...)
|
||||
req := cataloging.NewSelectionRequest().WithDefaults(tt.basis...).WithExpression(tt.expressions...)
|
||||
|
||||
got, gotEvidence, err := Select(tt.allTasks, req)
|
||||
tt.wantErr(t, err)
|
||||
@@ -367,3 +397,391 @@ func TestSelect(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSelectInGroups(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
taskGroups [][]Task
|
||||
selectionReq cataloging.SelectionRequest
|
||||
wantGroups [][]string
|
||||
wantTokens map[string]TokenSelection
|
||||
wantRequest cataloging.SelectionRequest
|
||||
wantErr assert.ErrorAssertionFunc
|
||||
}{
|
||||
{
|
||||
name: "select only within the file tasks (leave package tasks alone)",
|
||||
taskGroups: [][]Task{
|
||||
createDummyPackageTasks(),
|
||||
createDummyFileTasks(),
|
||||
},
|
||||
selectionReq: cataloging.NewSelectionRequest().
|
||||
WithDefaults("image"). // note: file missing
|
||||
WithSubSelections("content", "digest"),
|
||||
wantGroups: [][]string{
|
||||
{
|
||||
// this is the original, untouched package task list
|
||||
"alpm-db-cataloger",
|
||||
"apk-db-cataloger",
|
||||
"dpkg-db-cataloger",
|
||||
"portage-cataloger",
|
||||
"rpm-db-cataloger",
|
||||
"conan-info-cataloger",
|
||||
"javascript-package-cataloger",
|
||||
"php-composer-installed-cataloger",
|
||||
"ruby-installed-gemspec-cataloger",
|
||||
"rust-cargo-lock-cataloger",
|
||||
"dotnet-portable-executable-cataloger",
|
||||
"python-installed-package-cataloger",
|
||||
"go-module-binary-cataloger",
|
||||
"java-archive-cataloger",
|
||||
"graalvm-native-image-cataloger",
|
||||
"binary-cataloger",
|
||||
"sbom-cataloger",
|
||||
},
|
||||
{
|
||||
// this has been filtered based on the request
|
||||
"file-content-cataloger",
|
||||
"file-digest-cataloger",
|
||||
},
|
||||
},
|
||||
wantTokens: map[string]TokenSelection{
|
||||
// packages
|
||||
"alpm-db-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"apk-db-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"binary-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"conan-info-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"dotnet-portable-executable-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"dpkg-db-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"go-module-binary-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"graalvm-native-image-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"java-archive-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"javascript-package-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"php-composer-installed-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"portage-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"python-installed-package-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"rpm-db-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"ruby-installed-gemspec-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"rust-cargo-lock-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"sbom-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
// files
|
||||
"file-content-cataloger": newTokenSelection([]string{"content", "file"}, nil),
|
||||
"file-digest-cataloger": newTokenSelection([]string{"digest", "file"}, nil),
|
||||
"file-executable-cataloger": newTokenSelection([]string{"file"}, nil),
|
||||
"file-metadata-cataloger": newTokenSelection([]string{"file"}, nil),
|
||||
},
|
||||
wantRequest: cataloging.SelectionRequest{
|
||||
DefaultNamesOrTags: []string{"image", "file"}, // note: file automatically added
|
||||
SubSelectTags: []string{"content", "digest"},
|
||||
},
|
||||
wantErr: assert.NoError,
|
||||
},
|
||||
{
|
||||
name: "select package tasks (leave file tasks alone)",
|
||||
taskGroups: [][]Task{
|
||||
createDummyPackageTasks(),
|
||||
createDummyFileTasks(),
|
||||
},
|
||||
selectionReq: cataloging.NewSelectionRequest().WithDefaults("image").WithSubSelections("os"),
|
||||
wantGroups: [][]string{
|
||||
{
|
||||
// filtered based on the request
|
||||
"alpm-db-cataloger",
|
||||
"apk-db-cataloger",
|
||||
"dpkg-db-cataloger",
|
||||
"portage-cataloger",
|
||||
"rpm-db-cataloger",
|
||||
},
|
||||
{
|
||||
// this is the original, untouched file task list
|
||||
"file-content-cataloger",
|
||||
"file-metadata-cataloger",
|
||||
"file-digest-cataloger",
|
||||
"file-executable-cataloger",
|
||||
},
|
||||
},
|
||||
wantTokens: map[string]TokenSelection{
|
||||
// packages - os
|
||||
"alpm-db-cataloger": newTokenSelection([]string{"os", "image"}, nil),
|
||||
"apk-db-cataloger": newTokenSelection([]string{"os", "image"}, nil),
|
||||
"rpm-archive-cataloger": newTokenSelection([]string{"os"}, nil),
|
||||
"rpm-db-cataloger": newTokenSelection([]string{"os", "image"}, nil),
|
||||
"portage-cataloger": newTokenSelection([]string{"os", "image"}, nil),
|
||||
"dpkg-db-cataloger": newTokenSelection([]string{"os", "image"}, nil),
|
||||
// packages - remaining
|
||||
"binary-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"conan-info-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"dotnet-portable-executable-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"go-module-binary-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"graalvm-native-image-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"java-archive-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"javascript-package-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"php-composer-installed-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"python-installed-package-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"ruby-installed-gemspec-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"rust-cargo-lock-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"sbom-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
// files
|
||||
"file-content-cataloger": newTokenSelection([]string{"file"}, nil),
|
||||
"file-digest-cataloger": newTokenSelection([]string{"file"}, nil),
|
||||
"file-executable-cataloger": newTokenSelection([]string{"file"}, nil),
|
||||
"file-metadata-cataloger": newTokenSelection([]string{"file"}, nil),
|
||||
},
|
||||
wantRequest: cataloging.SelectionRequest{
|
||||
DefaultNamesOrTags: []string{"image", "file"},
|
||||
SubSelectTags: []string{"os"},
|
||||
},
|
||||
wantErr: assert.NoError,
|
||||
},
|
||||
{
|
||||
name: "select only file tasks (default)",
|
||||
taskGroups: [][]Task{
|
||||
createDummyPackageTasks(),
|
||||
createDummyFileTasks(),
|
||||
},
|
||||
selectionReq: cataloging.NewSelectionRequest().WithDefaults("file"),
|
||||
wantGroups: [][]string{
|
||||
// filtered based on the request
|
||||
nil,
|
||||
{
|
||||
// this is the original, untouched file task list
|
||||
"file-content-cataloger",
|
||||
"file-metadata-cataloger",
|
||||
"file-digest-cataloger",
|
||||
"file-executable-cataloger",
|
||||
},
|
||||
},
|
||||
wantTokens: map[string]TokenSelection{
|
||||
// files
|
||||
"file-content-cataloger": newTokenSelection([]string{"file"}, nil),
|
||||
"file-digest-cataloger": newTokenSelection([]string{"file"}, nil),
|
||||
"file-executable-cataloger": newTokenSelection([]string{"file"}, nil),
|
||||
"file-metadata-cataloger": newTokenSelection([]string{"file"}, nil),
|
||||
},
|
||||
wantRequest: cataloging.SelectionRequest{
|
||||
DefaultNamesOrTags: []string{"file"},
|
||||
},
|
||||
wantErr: assert.NoError,
|
||||
},
|
||||
{
|
||||
name: "select only file tasks (via removal of package)",
|
||||
taskGroups: [][]Task{
|
||||
createDummyPackageTasks(),
|
||||
createDummyFileTasks(),
|
||||
},
|
||||
selectionReq: cataloging.NewSelectionRequest().WithDefaults("file", "image").WithRemovals("package"),
|
||||
wantGroups: [][]string{
|
||||
// filtered based on the request
|
||||
nil,
|
||||
{
|
||||
// this is the original, untouched file task list
|
||||
"file-content-cataloger",
|
||||
"file-metadata-cataloger",
|
||||
"file-digest-cataloger",
|
||||
"file-executable-cataloger",
|
||||
},
|
||||
},
|
||||
wantTokens: map[string]TokenSelection{
|
||||
// packages
|
||||
"alpm-db-cataloger": newTokenSelection([]string{"image"}, []string{"package"}),
|
||||
"apk-db-cataloger": newTokenSelection([]string{"image"}, []string{"package"}),
|
||||
"binary-cataloger": newTokenSelection([]string{"image"}, []string{"package"}),
|
||||
"conan-info-cataloger": newTokenSelection([]string{"image"}, []string{"package"}),
|
||||
"dotnet-portable-executable-cataloger": newTokenSelection([]string{"image"}, []string{"package"}),
|
||||
"dpkg-db-cataloger": newTokenSelection([]string{"image"}, []string{"package"}),
|
||||
"go-module-binary-cataloger": newTokenSelection([]string{"image"}, []string{"package"}),
|
||||
"graalvm-native-image-cataloger": newTokenSelection([]string{"image"}, []string{"package"}),
|
||||
"java-archive-cataloger": newTokenSelection([]string{"image"}, []string{"package"}),
|
||||
"javascript-package-cataloger": newTokenSelection([]string{"image"}, []string{"package"}),
|
||||
"php-composer-installed-cataloger": newTokenSelection([]string{"image"}, []string{"package"}),
|
||||
"portage-cataloger": newTokenSelection([]string{"image"}, []string{"package"}),
|
||||
"python-installed-package-cataloger": newTokenSelection([]string{"image"}, []string{"package"}),
|
||||
"rpm-db-cataloger": newTokenSelection([]string{"image"}, []string{"package"}),
|
||||
"ruby-installed-gemspec-cataloger": newTokenSelection([]string{"image"}, []string{"package"}),
|
||||
"rust-cargo-lock-cataloger": newTokenSelection([]string{"image"}, []string{"package"}),
|
||||
"sbom-cataloger": newTokenSelection([]string{"image"}, []string{"package"}),
|
||||
"rpm-archive-cataloger": newTokenSelection(nil, []string{"package"}),
|
||||
"conan-cataloger": newTokenSelection(nil, []string{"package"}),
|
||||
"dart-pubspec-lock-cataloger": newTokenSelection(nil, []string{"package"}),
|
||||
"dotnet-deps-cataloger": newTokenSelection(nil, []string{"package"}),
|
||||
"elixir-mix-lock-cataloger": newTokenSelection(nil, []string{"package"}),
|
||||
"erlang-rebar-lock-cataloger": newTokenSelection(nil, []string{"package"}),
|
||||
"javascript-lock-cataloger": newTokenSelection(nil, []string{"package"}),
|
||||
"github-actions-usage-cataloger": newTokenSelection(nil, []string{"package"}),
|
||||
"github-action-workflow-usage-cataloger": newTokenSelection(nil, []string{"package"}),
|
||||
// files
|
||||
"file-content-cataloger": newTokenSelection([]string{"file"}, nil),
|
||||
"file-digest-cataloger": newTokenSelection([]string{"file"}, nil),
|
||||
"file-executable-cataloger": newTokenSelection([]string{"file"}, nil),
|
||||
"file-metadata-cataloger": newTokenSelection([]string{"file"}, nil),
|
||||
},
|
||||
wantRequest: cataloging.SelectionRequest{
|
||||
DefaultNamesOrTags: []string{"file", "image"},
|
||||
RemoveNamesOrTags: []string{"package"},
|
||||
},
|
||||
wantErr: assert.NoError,
|
||||
},
|
||||
{
|
||||
name: "select file and package tasks",
|
||||
taskGroups: [][]Task{
|
||||
createDummyPackageTasks(),
|
||||
createDummyFileTasks(),
|
||||
},
|
||||
selectionReq: cataloging.NewSelectionRequest().
|
||||
WithDefaults("image").
|
||||
WithSubSelections("os", "content", "digest"),
|
||||
wantGroups: [][]string{
|
||||
{
|
||||
// filtered based on the request
|
||||
"alpm-db-cataloger",
|
||||
"apk-db-cataloger",
|
||||
"dpkg-db-cataloger",
|
||||
"portage-cataloger",
|
||||
"rpm-db-cataloger",
|
||||
},
|
||||
{
|
||||
// filtered based on the request
|
||||
"file-content-cataloger",
|
||||
"file-digest-cataloger",
|
||||
},
|
||||
},
|
||||
wantTokens: map[string]TokenSelection{
|
||||
// packages - os
|
||||
"alpm-db-cataloger": newTokenSelection([]string{"os", "image"}, nil),
|
||||
"apk-db-cataloger": newTokenSelection([]string{"os", "image"}, nil),
|
||||
"rpm-archive-cataloger": newTokenSelection([]string{"os"}, nil),
|
||||
"rpm-db-cataloger": newTokenSelection([]string{"os", "image"}, nil),
|
||||
"portage-cataloger": newTokenSelection([]string{"os", "image"}, nil),
|
||||
"dpkg-db-cataloger": newTokenSelection([]string{"os", "image"}, nil),
|
||||
// packages - remaining
|
||||
"binary-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"conan-info-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"dotnet-portable-executable-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"go-module-binary-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"graalvm-native-image-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"java-archive-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"javascript-package-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"php-composer-installed-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"python-installed-package-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"ruby-installed-gemspec-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"rust-cargo-lock-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
"sbom-cataloger": newTokenSelection([]string{"image"}, nil),
|
||||
// files
|
||||
"file-content-cataloger": newTokenSelection([]string{"file", "content"}, nil), // note extra tags
|
||||
"file-digest-cataloger": newTokenSelection([]string{"file", "digest"}, nil), // note extra tags
|
||||
"file-executable-cataloger": newTokenSelection([]string{"file"}, nil),
|
||||
"file-metadata-cataloger": newTokenSelection([]string{"file"}, nil),
|
||||
},
|
||||
wantRequest: cataloging.SelectionRequest{
|
||||
DefaultNamesOrTags: []string{"image", "file"},
|
||||
SubSelectTags: []string{"os", "content", "digest"},
|
||||
},
|
||||
wantErr: assert.NoError,
|
||||
},
|
||||
{
|
||||
name: "complex selection with multiple operators across groups",
|
||||
taskGroups: [][]Task{
|
||||
createDummyPackageTasks(),
|
||||
createDummyFileTasks(),
|
||||
},
|
||||
selectionReq: cataloging.NewSelectionRequest().
|
||||
WithDefaults("os"). // note: no file tag present
|
||||
WithExpression("+github-actions-usage-cataloger", "-dpkg", "-digest", "content", "+file-metadata-cataloger", "-declared"),
|
||||
wantGroups: [][]string{
|
||||
{
|
||||
"alpm-db-cataloger",
|
||||
"apk-db-cataloger",
|
||||
"portage-cataloger",
|
||||
"rpm-db-cataloger",
|
||||
"github-actions-usage-cataloger",
|
||||
},
|
||||
{
|
||||
"file-content-cataloger",
|
||||
"file-metadata-cataloger",
|
||||
},
|
||||
},
|
||||
wantTokens: map[string]TokenSelection{
|
||||
// selected package tasks
|
||||
"alpm-db-cataloger": newTokenSelection([]string{"os"}, nil),
|
||||
"apk-db-cataloger": newTokenSelection([]string{"os"}, nil),
|
||||
"dpkg-db-cataloger": newTokenSelection([]string{"os"}, []string{"dpkg"}),
|
||||
"portage-cataloger": newTokenSelection([]string{"os"}, nil),
|
||||
"rpm-archive-cataloger": newTokenSelection([]string{"os"}, []string{"declared"}),
|
||||
"rpm-db-cataloger": newTokenSelection([]string{"os"}, nil),
|
||||
"github-actions-usage-cataloger": newTokenSelection([]string{"github-actions-usage-cataloger"}, []string{"declared"}),
|
||||
|
||||
// selected file tasks
|
||||
"file-content-cataloger": newTokenSelection([]string{"content", "file"}, nil),
|
||||
"file-metadata-cataloger": newTokenSelection([]string{"file-metadata-cataloger", "file"}, nil),
|
||||
|
||||
// removed package tasks
|
||||
"binary-cataloger": newTokenSelection(nil, []string{"declared"}),
|
||||
"conan-cataloger": newTokenSelection(nil, []string{"declared"}),
|
||||
"dart-pubspec-lock-cataloger": newTokenSelection(nil, []string{"declared"}),
|
||||
"dotnet-deps-cataloger": newTokenSelection(nil, []string{"declared"}),
|
||||
"elixir-mix-lock-cataloger": newTokenSelection(nil, []string{"declared"}),
|
||||
"erlang-rebar-lock-cataloger": newTokenSelection(nil, []string{"declared"}),
|
||||
"github-action-workflow-usage-cataloger": newTokenSelection(nil, []string{"declared"}),
|
||||
"javascript-lock-cataloger": newTokenSelection(nil, []string{"declared"}),
|
||||
"sbom-cataloger": newTokenSelection(nil, []string{"declared"}),
|
||||
|
||||
// removed file tasks
|
||||
"file-executable-cataloger": newTokenSelection([]string{"file"}, nil),
|
||||
"file-digest-cataloger": newTokenSelection([]string{"file"}, []string{"digest"}),
|
||||
},
|
||||
wantRequest: cataloging.SelectionRequest{
|
||||
DefaultNamesOrTags: []string{"os", "file"}, // note: file added automatically
|
||||
SubSelectTags: []string{"content"},
|
||||
RemoveNamesOrTags: []string{"dpkg", "digest", "declared"},
|
||||
AddNames: []string{"github-actions-usage-cataloger", "file-metadata-cataloger"},
|
||||
},
|
||||
wantErr: assert.NoError,
|
||||
},
|
||||
{
|
||||
name: "invalid tag",
|
||||
taskGroups: [][]Task{
|
||||
createDummyPackageTasks(),
|
||||
createDummyFileTasks(),
|
||||
},
|
||||
selectionReq: cataloging.NewSelectionRequest().WithDefaults("invalid"),
|
||||
wantGroups: nil,
|
||||
wantTokens: nil,
|
||||
wantRequest: cataloging.SelectionRequest{
|
||||
DefaultNamesOrTags: []string{"invalid", "file"},
|
||||
},
|
||||
wantErr: assert.Error,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.wantErr == nil {
|
||||
tt.wantErr = assert.NoError
|
||||
}
|
||||
|
||||
gotGroups, gotSelection, err := SelectInGroups(tt.taskGroups, tt.selectionReq)
|
||||
tt.wantErr(t, err)
|
||||
if err != nil {
|
||||
// dev note: this is useful for debugging when needed...
|
||||
//for _, e := range gotEvidence.Request.Expressions {
|
||||
// t.Logf("expression (errors %q): %#v", e.Errors, e)
|
||||
//}
|
||||
|
||||
// note: we DON'T bail early in validations... this is because we should always return the full set of
|
||||
// of selected tasks and surrounding evidence.
|
||||
}
|
||||
|
||||
var gotGroupNames [][]string
|
||||
for _, group := range gotGroups {
|
||||
var names []string
|
||||
for _, task := range group {
|
||||
names = append(names, task.Name())
|
||||
}
|
||||
gotGroupNames = append(gotGroupNames, names)
|
||||
}
|
||||
|
||||
assert.Equal(t, tt.wantGroups, gotGroupNames)
|
||||
assert.Equal(t, tt.wantTokens, gotSelection.TokensByTask)
|
||||
assert.Equal(t, tt.wantRequest, gotSelection.Request)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user