diff --git a/.golangci.yaml b/.golangci.yaml index 8a3a134ee7..10d4995ccd 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -14,6 +14,8 @@ linters: desc: "Use 'slices' instead" - pkg: "golang.org/x/exp/maps" desc: "Use 'maps' or 'github.com/samber/lo' instead" + - pkg: "io/ioutil" + desc: "io/ioutil is deprecated. Use 'io' or 'os' instead" dupl: threshold: 100 errcheck: diff --git a/integration/client_server_test.go b/integration/client_server_test.go index 7e80fd9f16..145496b731 100644 --- a/integration/client_server_test.go +++ b/integration/client_server_test.go @@ -11,14 +11,14 @@ import ( "testing" "time" - "github.com/aquasecurity/trivy/pkg/types" - dockercontainer "github.com/docker/docker/api/types/container" "github.com/docker/go-connections/nat" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/testcontainers/testcontainers-go" "github.com/aquasecurity/trivy/pkg/report" + "github.com/aquasecurity/trivy/pkg/types" ) type csArgs struct { @@ -60,7 +60,7 @@ func TestClientServer(t *testing.T) { Input: "testdata/fixtures/images/alpine-39.tar.gz", Distro: "alpine/3.10", }, - override: func(t *testing.T, want, got *types.Report) { + override: func(_ *testing.T, want, _ *types.Report) { want.Metadata.OS.Name = "3.10" want.Results[0].Target = "testdata/fixtures/images/alpine-39.tar.gz (alpine 3.10)" }, @@ -312,7 +312,7 @@ func TestClientServer(t *testing.T) { Target: "https://github.com/knqyf263/trivy-ci-test", }, golden: "testdata/test-repo.json.golden", - override: func(t *testing.T, want, got *types.Report) { + override: func(_ *testing.T, want, _ *types.Report) { want.ArtifactName = "https://github.com/knqyf263/trivy-ci-test" }, }, @@ -444,7 +444,7 @@ func TestClientServerWithFormat(t *testing.T) { t.Setenv("GITHUB_WORKFLOW", "workflow-name") t.Cleanup(func() { - report.CustomTemplateFuncMap = map[string]any{} + report.CustomTemplateFuncMap = make(map[string]any) }) addr, cacheDir := setup(t, setupOptions{}) @@ -561,7 +561,7 @@ func TestClientServerWithCustomOptions(t *testing.T) { func TestClientServerWithRedis(t *testing.T) { // Set up a Redis container - ctx := context.Background() + ctx := t.Context() // This test includes 2 checks // redisC container will terminate after first check redisC, addr := setupRedis(t, ctx) @@ -622,10 +622,11 @@ func setup(t *testing.T, options setupOptions) (string, string) { osArgs := setupServer(addr, options.token, options.tokenHeader, options.pathPrefix, cacheDir, options.cacheBackend) // Run Trivy server - require.NoError(t, execute(osArgs)) + assert.NoError(t, execute(osArgs)) }() - ctx, _ := context.WithTimeout(context.Background(), 5*time.Second) + ctx, cancel := context.WithTimeout(t.Context(), 5*time.Second) + defer cancel() err = waitPort(ctx, addr) require.NoError(t, err) @@ -653,7 +654,7 @@ func setupServer(addr, token, tokenHeader, pathPrefix, cacheDir, cacheBackend st return osArgs } -func setupClient(t *testing.T, c csArgs, addr string, cacheDir string) []string { +func setupClient(t *testing.T, c csArgs, addr, cacheDir string) []string { t.Helper() if c.Command == "" { c.Command = "image" @@ -699,7 +700,7 @@ func setupClient(t *testing.T, c csArgs, addr string, cacheDir string) []string if len(c.IgnoreIDs) != 0 { trivyIgnore := filepath.Join(t.TempDir(), ".trivyignore") - err := os.WriteFile(trivyIgnore, []byte(strings.Join(c.IgnoreIDs, "\n")), 0444) + err := os.WriteFile(trivyIgnore, []byte(strings.Join(c.IgnoreIDs, "\n")), 0o444) require.NoError(t, err, "failed to write .trivyignore") osArgs = append(osArgs, "--ignorefile", trivyIgnore) } diff --git a/integration/config_test.go b/integration/config_test.go index b7c58e8238..8d72900780 100644 --- a/integration/config_test.go +++ b/integration/config_test.go @@ -202,7 +202,7 @@ severity: outputFile := filepath.Join(t.TempDir(), "output.json") configFile := tt.args.configFile - configFile = configFile + fmt.Sprintf(` + configFile += fmt.Sprintf(` format: json output: %s cache: @@ -212,7 +212,7 @@ db: `, outputFile, cacheDir) configPath := filepath.Join(t.TempDir(), "trivy.yaml") - err := os.WriteFile(configPath, []byte(configFile), 0444) + err := os.WriteFile(configPath, []byte(configFile), 0o444) require.NoError(t, err) osArgs := []string{ diff --git a/integration/convert_test.go b/integration/convert_test.go index e7d2a5f5e6..b323403c6b 100644 --- a/integration/convert_test.go +++ b/integration/convert_test.go @@ -76,8 +76,7 @@ func TestConvert(t *testing.T) { outputFile = tt.golden } - osArgs = append(osArgs, "--output", outputFile) - osArgs = append(osArgs, tt.args.input) + osArgs = append(osArgs, "--output", outputFile, tt.args.input) // Run "trivy convert" runTest(t, osArgs, tt.golden, outputFile, types.Format(tt.args.format), runOptions{ diff --git a/integration/docker_engine_test.go b/integration/docker_engine_test.go index 9113f65f58..bdd37160fb 100644 --- a/integration/docker_engine_test.go +++ b/integration/docker_engine_test.go @@ -3,15 +3,14 @@ package integration import ( - "context" "os" "strings" "testing" + "github.com/stretchr/testify/require" + "github.com/aquasecurity/trivy/internal/testutil" "github.com/aquasecurity/trivy/pkg/types" - - "github.com/stretchr/testify/require" ) func TestDockerEngine(t *testing.T) { @@ -216,7 +215,7 @@ func TestDockerEngine(t *testing.T) { // Set a temp dir so that modules will not be loaded t.Setenv("XDG_DATA_HOME", cacheDir) - ctx := context.Background() + ctx := t.Context() defer ctx.Done() cli := testutil.NewDockerClient(t) @@ -272,7 +271,7 @@ func TestDockerEngine(t *testing.T) { } if len(tt.ignoreIDs) != 0 { trivyIgnore := ".trivyignore" - err := os.WriteFile(trivyIgnore, []byte(strings.Join(tt.ignoreIDs, "\n")), 0444) + err := os.WriteFile(trivyIgnore, []byte(strings.Join(tt.ignoreIDs, "\n")), 0o444) require.NoError(t, err, "failed to write .trivyignore") defer os.Remove(trivyIgnore) } diff --git a/integration/integration_test.go b/integration/integration_test.go index cf53f38319..ca1f06601a 100644 --- a/integration/integration_test.go +++ b/integration/integration_test.go @@ -296,7 +296,7 @@ func compareRawFiles(t *testing.T, wantFile, gotFile string) { require.NoError(t, err) got, err := os.ReadFile(gotFile) require.NoError(t, err) - assert.EqualValues(t, string(want), string(got)) + assert.Equal(t, string(want), string(got)) } func compareReports(t *testing.T, wantFile, gotFile string, override func(t *testing.T, want, got *types.Report)) { @@ -378,7 +378,7 @@ func overrideUID(t *testing.T, want, got *types.Report) { // overrideDockerRemovedFields clears image config fields that were removed from Docker API // cf. https://github.com/moby/moby/blob/d0ad1357a141c795e1e0490e3fed00ddabcb91b9/docs/api/version-history.md -func overrideDockerRemovedFields(t *testing.T, want, got *types.Report) { +func overrideDockerRemovedFields(_ *testing.T, want, got *types.Report) { // Clear Container field (removed in Docker API v1.45) got.Metadata.ImageConfig.Container = "" want.Metadata.ImageConfig.Container = "" diff --git a/integration/plugin_test.go b/integration/plugin_test.go index e4a6bf4d00..0662ebcadd 100644 --- a/integration/plugin_test.go +++ b/integration/plugin_test.go @@ -77,6 +77,7 @@ func TestPlugin(t *testing.T) { } err = execute(args) + require.NoError(t, err) if *update { fsutils.CopyFile(tempStdOut.Name(), tt.golden) diff --git a/integration/registry_test.go b/integration/registry_test.go index 3f0469e2c3..7ef0e73324 100644 --- a/integration/registry_test.go +++ b/integration/registry_test.go @@ -17,8 +17,6 @@ import ( "path/filepath" "testing" - "github.com/aquasecurity/trivy/pkg/types" - dockercontainer "github.com/docker/docker/api/types/container" "github.com/docker/go-connections/nat" "github.com/google/go-containerregistry/pkg/authn" @@ -28,6 +26,8 @@ import ( "github.com/stretchr/testify/require" "github.com/testcontainers/testcontainers-go" "github.com/testcontainers/testcontainers-go/wait" + + "github.com/aquasecurity/trivy/pkg/types" ) const ( @@ -121,7 +121,7 @@ type registryOption struct { } func TestRegistry(t *testing.T) { - ctx := context.Background() + ctx := t.Context() baseDir, err := filepath.Abs(".") require.NoError(t, err) @@ -241,7 +241,7 @@ func TestRegistry(t *testing.T) { // Run Trivy runTest(t, osArgs, tt.golden, "", types.FormatJSON, runOptions{ wantErr: tt.wantErr, - override: overrideFuncs(overrideUID, func(t *testing.T, want, got *types.Report) { + override: overrideFuncs(overrideUID, func(_ *testing.T, want, _ *types.Report) { want.ArtifactName = s for i := range want.Results { want.Results[i].Target = fmt.Sprintf("%s (%s)", s, tt.os) @@ -334,7 +334,7 @@ func requestRegistryToken(imageRef name.Reference, baseDir string, opt registryO } // Get a registry token - req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/auth", opt.AuthURL), nil) + req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s/auth", opt.AuthURL), http.NoBody) if err != nil { return "", err } diff --git a/integration/repo_test.go b/integration/repo_test.go index 9d9f9ce23c..f77ee38bbd 100644 --- a/integration/repo_test.go +++ b/integration/repo_test.go @@ -3,8 +3,9 @@ package integration import ( - "fmt" "os" + "path/filepath" + "strconv" "strings" "testing" @@ -14,38 +15,39 @@ import ( "github.com/aquasecurity/trivy/pkg/types" ) +type repoTestArgs struct { + scanner types.Scanner + ignoreIDs []string + policyPaths []string + namespaces []string + listAllPkgs bool + input string + secretConfig string + filePatterns []string + helmSet []string + helmValuesFile []string + skipFiles []string + skipDirs []string + command string + format types.Format + includeDevDeps bool + parallel int + vex string + vulnSeveritySources []string +} + // TestRepository tests `trivy repo` with the local code repositories func TestRepository(t *testing.T) { t.Setenv("NUGET_PACKAGES", t.TempDir()) - type args struct { - scanner types.Scanner - ignoreIDs []string - policyPaths []string - namespaces []string - listAllPkgs bool - input string - secretConfig string - filePatterns []string - helmSet []string - helmValuesFile []string - skipFiles []string - skipDirs []string - command string - format types.Format - includeDevDeps bool - parallel int - vex string - vulnSeveritySources []string - } tests := []struct { name string - args args + args repoTestArgs golden string override func(t *testing.T, want, got *types.Report) }{ { name: "gomod", - args: args{ + args: repoTestArgs{ scanner: types.VulnerabilityScanner, input: "testdata/fixtures/repo/gomod", }, @@ -53,7 +55,7 @@ func TestRepository(t *testing.T) { }, { name: "gomod with skip files", - args: args{ + args: repoTestArgs{ scanner: types.VulnerabilityScanner, input: "testdata/fixtures/repo/gomod", skipFiles: []string{"testdata/fixtures/repo/gomod/submod2/go.mod"}, @@ -62,7 +64,7 @@ func TestRepository(t *testing.T) { }, { name: "gomod with skip dirs", - args: args{ + args: repoTestArgs{ scanner: types.VulnerabilityScanner, input: "testdata/fixtures/repo/gomod", skipDirs: []string{"testdata/fixtures/repo/gomod/submod2"}, @@ -71,7 +73,7 @@ func TestRepository(t *testing.T) { }, { name: "gomod in series", - args: args{ + args: repoTestArgs{ scanner: types.VulnerabilityScanner, input: "testdata/fixtures/repo/gomod", parallel: 1, @@ -80,7 +82,7 @@ func TestRepository(t *testing.T) { }, { name: "gomod with local VEX file", - args: args{ + args: repoTestArgs{ scanner: types.VulnerabilityScanner, input: "testdata/fixtures/repo/gomod", vex: "testdata/fixtures/vex/file/openvex.json", @@ -89,7 +91,7 @@ func TestRepository(t *testing.T) { }, { name: "gomod with VEX repository", - args: args{ + args: repoTestArgs{ scanner: types.VulnerabilityScanner, input: "testdata/fixtures/repo/gomod", vex: "repo", @@ -98,7 +100,7 @@ func TestRepository(t *testing.T) { }, { name: "npm", - args: args{ + args: repoTestArgs{ scanner: types.VulnerabilityScanner, input: "testdata/fixtures/repo/npm", listAllPkgs: true, @@ -107,7 +109,7 @@ func TestRepository(t *testing.T) { }, { name: "npm with severity from ubuntu", - args: args{ + args: repoTestArgs{ scanner: types.VulnerabilityScanner, input: "testdata/fixtures/repo/npm", vulnSeveritySources: []string{ @@ -119,7 +121,7 @@ func TestRepository(t *testing.T) { }, { name: "npm with dev deps", - args: args{ + args: repoTestArgs{ scanner: types.VulnerabilityScanner, input: "testdata/fixtures/repo/npm", listAllPkgs: true, @@ -129,7 +131,7 @@ func TestRepository(t *testing.T) { }, { name: "yarn", - args: args{ + args: repoTestArgs{ scanner: types.VulnerabilityScanner, input: "testdata/fixtures/repo/yarn", listAllPkgs: true, @@ -138,7 +140,7 @@ func TestRepository(t *testing.T) { }, { name: "pnpm", - args: args{ + args: repoTestArgs{ scanner: types.VulnerabilityScanner, input: "testdata/fixtures/repo/pnpm", listAllPkgs: true, @@ -147,7 +149,7 @@ func TestRepository(t *testing.T) { }, { name: "bun", - args: args{ + args: repoTestArgs{ scanner: types.VulnerabilityScanner, input: "testdata/fixtures/repo/bun", listAllPkgs: true, @@ -156,7 +158,7 @@ func TestRepository(t *testing.T) { }, { name: "pip", - args: args{ + args: repoTestArgs{ scanner: types.VulnerabilityScanner, listAllPkgs: true, input: "testdata/fixtures/repo/pip", @@ -165,7 +167,7 @@ func TestRepository(t *testing.T) { }, { name: "pipenv", - args: args{ + args: repoTestArgs{ scanner: types.VulnerabilityScanner, listAllPkgs: true, input: "testdata/fixtures/repo/pipenv", @@ -174,7 +176,7 @@ func TestRepository(t *testing.T) { }, { name: "poetry", - args: args{ + args: repoTestArgs{ scanner: types.VulnerabilityScanner, listAllPkgs: true, input: "testdata/fixtures/repo/poetry", @@ -183,7 +185,7 @@ func TestRepository(t *testing.T) { }, { name: "uv", - args: args{ + args: repoTestArgs{ scanner: types.VulnerabilityScanner, listAllPkgs: true, input: "testdata/fixtures/repo/uv", @@ -192,7 +194,7 @@ func TestRepository(t *testing.T) { }, { name: "pom", - args: args{ + args: repoTestArgs{ scanner: types.VulnerabilityScanner, input: "testdata/fixtures/repo/pom", }, @@ -200,7 +202,7 @@ func TestRepository(t *testing.T) { }, { name: "gradle", - args: args{ + args: repoTestArgs{ scanner: types.VulnerabilityScanner, input: "testdata/fixtures/repo/gradle", }, @@ -208,7 +210,7 @@ func TestRepository(t *testing.T) { }, { name: "sbt", - args: args{ + args: repoTestArgs{ scanner: types.VulnerabilityScanner, input: "testdata/fixtures/repo/sbt", }, @@ -216,7 +218,7 @@ func TestRepository(t *testing.T) { }, { name: "conan", - args: args{ + args: repoTestArgs{ scanner: types.VulnerabilityScanner, listAllPkgs: true, input: "testdata/fixtures/repo/conan", @@ -225,7 +227,7 @@ func TestRepository(t *testing.T) { }, { name: "nuget", - args: args{ + args: repoTestArgs{ scanner: types.VulnerabilityScanner, listAllPkgs: true, input: "testdata/fixtures/repo/nuget", @@ -234,7 +236,7 @@ func TestRepository(t *testing.T) { }, { name: "dotnet", - args: args{ + args: repoTestArgs{ scanner: types.VulnerabilityScanner, listAllPkgs: true, input: "testdata/fixtures/repo/dotnet", @@ -243,7 +245,7 @@ func TestRepository(t *testing.T) { }, { name: "packages-props", - args: args{ + args: repoTestArgs{ scanner: types.VulnerabilityScanner, listAllPkgs: true, input: "testdata/fixtures/repo/packagesprops", @@ -252,7 +254,7 @@ func TestRepository(t *testing.T) { }, { name: "swift", - args: args{ + args: repoTestArgs{ scanner: types.VulnerabilityScanner, listAllPkgs: true, input: "testdata/fixtures/repo/swift", @@ -261,7 +263,7 @@ func TestRepository(t *testing.T) { }, { name: "cocoapods", - args: args{ + args: repoTestArgs{ scanner: types.VulnerabilityScanner, listAllPkgs: true, input: "testdata/fixtures/repo/cocoapods", @@ -270,7 +272,7 @@ func TestRepository(t *testing.T) { }, { name: "pubspec.lock", - args: args{ + args: repoTestArgs{ scanner: types.VulnerabilityScanner, listAllPkgs: true, input: "testdata/fixtures/repo/pubspec", @@ -279,7 +281,7 @@ func TestRepository(t *testing.T) { }, { name: "mix.lock", - args: args{ + args: repoTestArgs{ scanner: types.VulnerabilityScanner, listAllPkgs: true, input: "testdata/fixtures/repo/mixlock", @@ -288,7 +290,7 @@ func TestRepository(t *testing.T) { }, { name: "composer.lock", - args: args{ + args: repoTestArgs{ scanner: types.VulnerabilityScanner, listAllPkgs: true, input: "testdata/fixtures/repo/composer", @@ -297,7 +299,7 @@ func TestRepository(t *testing.T) { }, { name: "cargo.lock", - args: args{ + args: repoTestArgs{ scanner: types.VulnerabilityScanner, listAllPkgs: true, input: "testdata/fixtures/repo/cargo", @@ -306,7 +308,7 @@ func TestRepository(t *testing.T) { }, { name: "multiple lockfiles", - args: args{ + args: repoTestArgs{ scanner: types.VulnerabilityScanner, input: "testdata/fixtures/repo/trivy-ci-test", }, @@ -314,7 +316,7 @@ func TestRepository(t *testing.T) { }, { name: "installed.json", - args: args{ + args: repoTestArgs{ command: "rootfs", scanner: types.VulnerabilityScanner, listAllPkgs: true, @@ -324,7 +326,7 @@ func TestRepository(t *testing.T) { }, { name: "dockerfile", - args: args{ + args: repoTestArgs{ scanner: types.MisconfigScanner, input: "testdata/fixtures/repo/dockerfile", namespaces: []string{"testing"}, @@ -333,7 +335,7 @@ func TestRepository(t *testing.T) { }, { name: "dockerfile with custom file pattern", - args: args{ + args: repoTestArgs{ scanner: types.MisconfigScanner, input: "testdata/fixtures/repo/dockerfile_file_pattern", namespaces: []string{"testing"}, @@ -343,7 +345,7 @@ func TestRepository(t *testing.T) { }, { name: "dockerfile with custom policies", - args: args{ + args: repoTestArgs{ scanner: types.MisconfigScanner, policyPaths: []string{"testdata/fixtures/repo/custom-policy/policy"}, namespaces: []string{"user"}, @@ -353,7 +355,7 @@ func TestRepository(t *testing.T) { }, { name: "tarball helm chart scanning with builtin policies", - args: args{ + args: repoTestArgs{ scanner: types.MisconfigScanner, input: "testdata/fixtures/repo/helm", }, @@ -361,7 +363,7 @@ func TestRepository(t *testing.T) { }, { name: "helm chart directory scanning with builtin policies", - args: args{ + args: repoTestArgs{ scanner: types.MisconfigScanner, input: "testdata/fixtures/repo/helm_testchart", }, @@ -369,7 +371,7 @@ func TestRepository(t *testing.T) { }, { name: "helm chart directory scanning with value overrides using set", - args: args{ + args: repoTestArgs{ scanner: types.MisconfigScanner, input: "testdata/fixtures/repo/helm_testchart", helmSet: []string{"securityContext.runAsUser=0"}, @@ -378,7 +380,7 @@ func TestRepository(t *testing.T) { }, { name: "helm chart directory scanning with value overrides using value file", - args: args{ + args: repoTestArgs{ scanner: types.MisconfigScanner, input: "testdata/fixtures/repo/helm_testchart", helmValuesFile: []string{"testdata/fixtures/repo/helm_values/values.yaml"}, @@ -387,7 +389,7 @@ func TestRepository(t *testing.T) { }, { name: "helm chart directory scanning with builtin policies and non string Chart name", - args: args{ + args: repoTestArgs{ scanner: types.MisconfigScanner, input: "testdata/fixtures/repo/helm_badname", }, @@ -395,7 +397,7 @@ func TestRepository(t *testing.T) { }, { name: "secrets", - args: args{ + args: repoTestArgs{ scanner: "vuln,secret", input: "testdata/fixtures/repo/secrets", secretConfig: "testdata/fixtures/repo/secrets/trivy-secret.yaml", @@ -404,7 +406,7 @@ func TestRepository(t *testing.T) { }, { name: "conda generating CycloneDX SBOM", - args: args{ + args: repoTestArgs{ command: "rootfs", format: "cyclonedx", input: "testdata/fixtures/repo/conda", @@ -413,7 +415,7 @@ func TestRepository(t *testing.T) { }, { name: "conda environment.yaml generating CycloneDX SBOM", - args: args{ + args: repoTestArgs{ command: "fs", format: "cyclonedx", input: "testdata/fixtures/repo/conda-environment", @@ -422,7 +424,7 @@ func TestRepository(t *testing.T) { }, { name: "pom.xml generating CycloneDX SBOM (with vulnerabilities)", - args: args{ + args: repoTestArgs{ command: "fs", scanner: types.VulnerabilityScanner, format: "cyclonedx", @@ -432,7 +434,7 @@ func TestRepository(t *testing.T) { }, { name: "conda generating SPDX SBOM", - args: args{ + args: repoTestArgs{ command: "rootfs", format: "spdx-json", input: "testdata/fixtures/repo/conda", @@ -441,7 +443,7 @@ func TestRepository(t *testing.T) { }, { name: "gomod with fs subcommand", - args: args{ + args: repoTestArgs{ command: "fs", scanner: types.VulnerabilityScanner, input: "testdata/fixtures/repo/gomod", @@ -454,7 +456,7 @@ func TestRepository(t *testing.T) { }, { name: "dockerfile with fs subcommand and an alias scanner", - args: args{ + args: repoTestArgs{ command: "fs", scanner: "config", // for backward compatibility policyPaths: []string{"testdata/fixtures/repo/custom-policy/policy"}, @@ -462,13 +464,13 @@ func TestRepository(t *testing.T) { input: "testdata/fixtures/repo/custom-policy", }, golden: "testdata/dockerfile-custom-policies.json.golden", - override: func(_ *testing.T, want, got *types.Report) { + override: func(_ *testing.T, want, _ *types.Report) { want.ArtifactType = ftypes.TypeFilesystem }, }, { name: "julia generating SPDX SBOM", - args: args{ + args: repoTestArgs{ command: "rootfs", format: "spdx-json", input: "testdata/fixtures/repo/julia", @@ -501,95 +503,7 @@ func TestRepository(t *testing.T) { format = tt.args.format } - osArgs := []string{ - "-q", - "--cache-dir", - cacheDir, - command, - "--skip-db-update", - "--skip-policy-update", - "--format", - string(format), - "--parallel", - fmt.Sprint(tt.args.parallel), - "--offline-scan", - tt.args.input, - } - - if tt.args.scanner != "" { - osArgs = append(osArgs, "--scanners", string(tt.args.scanner)) - } - - if len(tt.args.policyPaths) != 0 { - for _, policyPath := range tt.args.policyPaths { - osArgs = append(osArgs, "--config-policy", policyPath) - } - } - - if len(tt.args.namespaces) != 0 { - for _, namespace := range tt.args.namespaces { - osArgs = append(osArgs, "--policy-namespaces", namespace) - } - } - - if len(tt.args.ignoreIDs) != 0 { - trivyIgnore := ".trivyignore" - err := os.WriteFile(trivyIgnore, []byte(strings.Join(tt.args.ignoreIDs, "\n")), 0444) - require.NoError(t, err, "failed to write .trivyignore") - defer os.Remove(trivyIgnore) - } - - if len(tt.args.filePatterns) != 0 { - for _, filePattern := range tt.args.filePatterns { - osArgs = append(osArgs, "--file-patterns", filePattern) - } - } - - if len(tt.args.helmSet) != 0 { - for _, helmSet := range tt.args.helmSet { - osArgs = append(osArgs, "--helm-set", helmSet) - } - } - - if len(tt.args.helmValuesFile) != 0 { - for _, helmValuesFile := range tt.args.helmValuesFile { - osArgs = append(osArgs, "--helm-values", helmValuesFile) - } - } - - if len(tt.args.skipFiles) != 0 { - for _, skipFile := range tt.args.skipFiles { - osArgs = append(osArgs, "--skip-files", skipFile) - } - } - - if len(tt.args.skipDirs) != 0 { - for _, skipDir := range tt.args.skipDirs { - osArgs = append(osArgs, "--skip-dirs", skipDir) - } - } - - if len(tt.args.vulnSeveritySources) != 0 { - osArgs = append(osArgs, - "--vuln-severity-source", strings.Join(tt.args.vulnSeveritySources, ","), - ) - } - - if tt.args.listAllPkgs { - osArgs = append(osArgs, "--list-all-pkgs") - } - - if tt.args.includeDevDeps { - osArgs = append(osArgs, "--include-dev-deps") - } - - if tt.args.secretConfig != "" { - osArgs = append(osArgs, "--secret-config", tt.args.secretConfig) - } - - if tt.args.vex != "" { - osArgs = append(osArgs, "--vex", tt.args.vex) - } + osArgs := buildArgs(t, cacheDir, command, format, tt.args) runTest(t, osArgs, tt.golden, "", format, runOptions{ fakeUUID: "3ff14136-e09f-4df9-80ea-%012d", @@ -598,3 +512,78 @@ func TestRepository(t *testing.T) { }) } } + +func buildArgs(t *testing.T, cacheDir, command string, format types.Format, testArgs repoTestArgs) []string { + // Build base arguments + osArgs := []string{ + "-q", + "--cache-dir", + cacheDir, + command, + "--skip-db-update", + "--skip-policy-update", + "--format", + string(format), + "--parallel", + strconv.Itoa(testArgs.parallel), + "--offline-scan", + testArgs.input, + } + + if testArgs.scanner != "" { + osArgs = append(osArgs, "--scanners", string(testArgs.scanner)) + } + + for _, policyPath := range testArgs.policyPaths { + osArgs = append(osArgs, "--config-policy", policyPath) + } + for _, namespace := range testArgs.namespaces { + osArgs = append(osArgs, "--policy-namespaces", namespace) + } + + // Handle ignore file using temporary directory + if len(testArgs.ignoreIDs) != 0 { + trivyIgnore := filepath.Join(t.TempDir(), ".trivyignore") + err := os.WriteFile(trivyIgnore, []byte(strings.Join(testArgs.ignoreIDs, "\n")), 0o444) + require.NoError(t, err, "failed to write .trivyignore") + osArgs = append(osArgs, "--ignorefile", trivyIgnore) + } + + for _, filePattern := range testArgs.filePatterns { + osArgs = append(osArgs, "--file-patterns", filePattern) + } + + for _, hs := range testArgs.helmSet { + osArgs = append(osArgs, "--helm-set", hs) + } + for _, hvf := range testArgs.helmValuesFile { + osArgs = append(osArgs, "--helm-values", hvf) + } + + for _, skipFile := range testArgs.skipFiles { + osArgs = append(osArgs, "--skip-files", skipFile) + } + for _, skipDir := range testArgs.skipDirs { + osArgs = append(osArgs, "--skip-dirs", skipDir) + } + + if len(testArgs.vulnSeveritySources) != 0 { + osArgs = append(osArgs, + "--vuln-severity-source", strings.Join(testArgs.vulnSeveritySources, ","), + ) + } + if testArgs.listAllPkgs { + osArgs = append(osArgs, "--list-all-pkgs") + } + if testArgs.includeDevDeps { + osArgs = append(osArgs, "--include-dev-deps") + } + if testArgs.secretConfig != "" { + osArgs = append(osArgs, "--secret-config", testArgs.secretConfig) + } + if testArgs.vex != "" { + osArgs = append(osArgs, "--vex", testArgs.vex) + } + + return osArgs +} diff --git a/integration/sbom_test.go b/integration/sbom_test.go index f97a7c0c61..060f593571 100644 --- a/integration/sbom_test.go +++ b/integration/sbom_test.go @@ -186,8 +186,7 @@ func TestSBOM(t *testing.T) { outputFile = tt.golden } - osArgs = append(osArgs, "--output", outputFile) - osArgs = append(osArgs, tt.args.input) + osArgs = append(osArgs, "--output", outputFile, tt.args.input) // Run "trivy sbom" runTest(t, osArgs, tt.golden, outputFile, types.Format(tt.args.format), runOptions{ @@ -198,7 +197,7 @@ func TestSBOM(t *testing.T) { } } -func overrideSBOMReport(t *testing.T, want, got *types.Report) { +func overrideSBOMReport(_ *testing.T, want, got *types.Report) { want.Metadata.ImageID = "" want.Metadata.ImageConfig = v1.ConfigFile{} want.Metadata.DiffIDs = nil diff --git a/integration/standalone_tar_test.go b/integration/standalone_tar_test.go index 490ef07159..9f465afb1c 100644 --- a/integration/standalone_tar_test.go +++ b/integration/standalone_tar_test.go @@ -8,10 +8,10 @@ import ( "strings" "testing" + "github.com/stretchr/testify/require" + ftypes "github.com/aquasecurity/trivy/pkg/fanal/types" "github.com/aquasecurity/trivy/pkg/types" - - "github.com/stretchr/testify/require" ) func TestTar(t *testing.T) { @@ -168,7 +168,7 @@ func TestTar(t *testing.T) { Input: "testdata/fixtures/images/alpine-39.tar.gz", Distro: "alpine/3.10", }, - override: func(t *testing.T, want, got *types.Report) { + override: func(_ *testing.T, want, _ *types.Report) { want.Metadata.OS.Name = "3.10" want.Results[0].Target = "testdata/fixtures/images/alpine-39.tar.gz (alpine 3.10)" }, @@ -425,7 +425,7 @@ func TestTar(t *testing.T) { } if len(tt.args.IgnoreIDs) != 0 { trivyIgnore := ".trivyignore" - err := os.WriteFile(trivyIgnore, []byte(strings.Join(tt.args.IgnoreIDs, "\n")), 0444) + err := os.WriteFile(trivyIgnore, []byte(strings.Join(tt.args.IgnoreIDs, "\n")), 0o444) require.NoError(t, err, "failed to write .trivyignore") defer os.Remove(trivyIgnore) } diff --git a/magefiles/magefile.go b/magefiles/magefile.go index e7f1363483..86d62e2684 100644 --- a/magefiles/magefile.go +++ b/magefiles/magefile.go @@ -348,13 +348,13 @@ type Lint mg.Namespace // Run runs linters func (Lint) Run() error { mg.Deps(Tool{}.GolangciLint) - return sh.RunV("golangci-lint", "run") + return sh.RunV("golangci-lint", "run", "--build-tags=integration") } // Fix auto fixes linters func (Lint) Fix() error { mg.Deps(Tool{}.GolangciLint) - return sh.RunV("golangci-lint", "run", "--fix") + return sh.RunV("golangci-lint", "run", "--fix", "--build-tags=integration") } // Fmt formats Go code and proto files diff --git a/pkg/fanal/test/integration/library_test.go b/pkg/fanal/test/integration/library_test.go index 1777fa91c0..6f6584efa7 100644 --- a/pkg/fanal/test/integration/library_test.go +++ b/pkg/fanal/test/integration/library_test.go @@ -11,20 +11,20 @@ import ( "sort" "testing" - "github.com/aquasecurity/trivy/internal/testutil" - "github.com/aquasecurity/trivy/pkg/cache" - "github.com/aquasecurity/trivy/pkg/fanal/analyzer" - _ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/all" - "github.com/aquasecurity/trivy/pkg/fanal/applier" - "github.com/aquasecurity/trivy/pkg/fanal/artifact" - aimage "github.com/aquasecurity/trivy/pkg/fanal/artifact/image" - _ "github.com/aquasecurity/trivy/pkg/fanal/handler/all" - "github.com/aquasecurity/trivy/pkg/fanal/image" - "github.com/aquasecurity/trivy/pkg/fanal/types" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/aquasecurity/trivy/internal/testutil" + "github.com/aquasecurity/trivy/pkg/cache" + "github.com/aquasecurity/trivy/pkg/fanal/analyzer" + "github.com/aquasecurity/trivy/pkg/fanal/applier" + "github.com/aquasecurity/trivy/pkg/fanal/artifact" + aimage "github.com/aquasecurity/trivy/pkg/fanal/artifact/image" + "github.com/aquasecurity/trivy/pkg/fanal/image" + "github.com/aquasecurity/trivy/pkg/fanal/types" + + _ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/all" + _ "github.com/aquasecurity/trivy/pkg/fanal/handler/all" _ "modernc.org/sqlite" ) @@ -145,7 +145,7 @@ func TestFanal_Library_DockerMode(t *testing.T) { cli := testutil.NewDockerClient(t) for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - ctx := context.Background() + ctx := t.Context() d := t.TempDir() c, err := cache.NewFSCache(d) @@ -186,7 +186,7 @@ func TestFanal_Library_TarMode(t *testing.T) { for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { t.Parallel() - ctx := context.Background() + ctx := t.Context() d := t.TempDir() c, err := cache.NewFSCache(d) @@ -237,7 +237,7 @@ func checkOSPackages(t *testing.T, detail types.ArtifactDetail, tc testCase) { if *update { b, err := json.MarshalIndent(detail.Packages, "", " ") require.NoError(t, err) - err = os.WriteFile(goldenFile, b, 0666) + err = os.WriteFile(goldenFile, b, 0o666) require.NoError(t, err) return } @@ -248,7 +248,7 @@ func checkOSPackages(t *testing.T, detail types.ArtifactDetail, tc testCase) { err = json.Unmarshal(data, &expectedPkgs) require.NoError(t, err) - require.Equal(t, len(expectedPkgs), len(detail.Packages), tc.name) + require.Len(t, expectedPkgs, len(detail.Packages), tc.name) sort.Slice(expectedPkgs, func(i, j int) bool { return expectedPkgs[i].Name < expectedPkgs[j].Name }) sort.Sort(detail.Packages) @@ -285,7 +285,7 @@ func checkLangPkgs(detail types.ArtifactDetail, t *testing.T, tc testCase) { if *update { b, err := json.MarshalIndent(detail.Applications, "", " ") require.NoError(t, err) - err = os.WriteFile(tc.wantApplicationFile, b, 0666) + err = os.WriteFile(tc.wantApplicationFile, b, 0o666) require.NoError(t, err) return } @@ -308,7 +308,7 @@ func checkPackageFromCommands(t *testing.T, detail types.ArtifactDetail, tc test sort.Sort(types.Packages(detail.ImageConfig.Packages)) b, err := json.MarshalIndent(detail.ImageConfig.Packages, "", " ") require.NoError(t, err) - err = os.WriteFile(tc.wantPkgsFromCmds, b, 0666) + err = os.WriteFile(tc.wantPkgsFromCmds, b, 0o666) require.NoError(t, err) return } diff --git a/pkg/fanal/test/integration/registry_test.go b/pkg/fanal/test/integration/registry_test.go index e6fc7445cc..9ac682471e 100644 --- a/pkg/fanal/test/integration/registry_test.go +++ b/pkg/fanal/test/integration/registry_test.go @@ -1,14 +1,11 @@ //go:build integration -// +build integration package integration import ( "context" "fmt" - "io/ioutil" "net/url" - "os" "path/filepath" "testing" @@ -23,13 +20,14 @@ import ( "github.com/aquasecurity/trivy/internal/testutil" "github.com/aquasecurity/trivy/pkg/cache" "github.com/aquasecurity/trivy/pkg/fanal/analyzer" - _ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/all" "github.com/aquasecurity/trivy/pkg/fanal/applier" "github.com/aquasecurity/trivy/pkg/fanal/artifact" aimage "github.com/aquasecurity/trivy/pkg/fanal/artifact/image" "github.com/aquasecurity/trivy/pkg/fanal/image" testdocker "github.com/aquasecurity/trivy/pkg/fanal/test/integration/docker" "github.com/aquasecurity/trivy/pkg/fanal/types" + + _ "github.com/aquasecurity/trivy/pkg/fanal/analyzer/all" ) const ( @@ -40,7 +38,7 @@ const ( ) func TestTLSRegistry(t *testing.T) { - ctx := context.Background() + ctx := t.Context() baseDir, err := filepath.Abs(".") require.NoError(t, err) @@ -189,7 +187,7 @@ func TestTLSRegistry(t *testing.T) { // 2. Analyze it imageRef := fmt.Sprintf("%s/%s", registryURL.Host, tc.imageName) - imageDetail, err := analyze(ctx, imageRef, tc.option) + imageDetail, err := analyze(t, ctx, imageRef, tc.option) require.Equal(t, tc.wantErr, err != nil, err) if err != nil { return @@ -216,12 +214,8 @@ func getRegistryURL(ctx context.Context, registryC testcontainers.Container, exp return url.Parse(urlStr) } -func analyze(ctx context.Context, imageRef string, opt types.ImageOptions) (*types.ArtifactDetail, error) { - d, err := ioutil.TempDir("", "TestRegistry-*") - if err != nil { - return nil, err - } - defer os.RemoveAll(d) +func analyze(t *testing.T, ctx context.Context, imageRef string, opt types.ImageOptions) (*types.ArtifactDetail, error) { + d := t.TempDir() c, err := cache.NewFSCache(d) if err != nil {