test: improve golden file management in integration tests (#9699)

This commit is contained in:
Teppei Fukuda
2025-10-24 11:49:29 +04:00
committed by GitHub
parent e0c04168b9
commit a6010c3eda
60 changed files with 5626 additions and 13780 deletions

193
integration/README.md Normal file
View File

@@ -0,0 +1,193 @@
# Integration Tests
This directory contains integration tests for Trivy. These tests verify Trivy's behavior by running actual commands and comparing the output against golden files.
## Running Tests
### Run integration tests
```bash
# Run standard integration tests (excludes VM, K8s, and module tests)
mage test:integration
# Run all types of integration tests separately
mage test:integration # Standard integration tests
mage test:module # Wasm module tests
mage test:vm # VM integration tests
mage test:k8s # Kubernetes integration tests
```
### Run specific test
```bash
GOEXPERIMENT=jsonv2 go test -tags=integration -run TestRepository ./integration -v
```
## Golden Files
Golden files store the expected output for integration tests. They are located in `integration/testdata/*.golden`.
### Updating Golden Files
When you make changes that affect test output, you need to update the golden files:
```bash
# Update golden files for standard integration tests
mage test:updateGolden
# Update golden files for Wasm module tests
mage test:updateModuleGolden
# Update golden files for VM integration tests
mage test:updateVMGolden
# Update specific golden files manually
GOEXPERIMENT=jsonv2 go test -tags=integration -run TestRepository ./integration -v -update
```
**Important**:
- Only tests that generate golden files as the canonical source support the `-update` flag
- Tests that reuse golden files from other tests will be **skipped** during updates
- Look for `override: nil` comment in test code to identify canonical source tests
### Golden File Management Strategy
#### 1. Canonical Source Tests (Can Update Golden Files)
These tests generate golden files and should have:
- `override: nil` comment in the code
- No `t.Skipf()` for the `-update` flag
Example:
```go
func TestRepository(t *testing.T) {
// ...
runTest(t, osArgs, tt.golden, format, runOptions{
fakeUUID: "3ff14136-e09f-4df9-80ea-%012d",
override: nil, // Do not use overrides - golden files are generated from this test as the canonical source
})
}
```
#### 2. Consumer Tests (Cannot Update Golden Files)
These tests reuse golden files from canonical source tests and should have:
- `if *update { t.Skipf(...) }` at the beginning of the test function
- `override` functions to adjust for differences (e.g., different artifact names, paths)
- Simplified comment: `Golden files are shared with TestXXX.`
Example:
```go
// TestClientServer tests the client-server mode of Trivy.
//
// Golden files are shared with TestTar or TestRepository.
func TestClientServer(t *testing.T) {
if *update {
t.Skipf("Skipping TestClientServer when -update flag is set. Golden files should be updated via TestTar or TestRepository.")
}
// ...
runTest(t, osArgs, tt.golden, types.FormatJSON, runOptions{
override: overrideFuncs(overrideUID, func(_ *testing.T, want, _ *types.Report) {
want.ArtifactName = "https://github.com/knqyf263/trivy-ci-test"
}),
fakeUUID: "3ff14136-e09f-4df9-80ea-%012d",
})
}
```
### Why Only One Test Updates Each Golden File
**Critical constraint**: Each golden file must be updated by exactly one test function.
If multiple tests update the same golden file, they may introduce subtle differences in the output. This causes the golden file to change every time tests are run, depending on which test executed last. This makes the golden files unstable and defeats their purpose.
**Solution**: Designate one test as the "canonical source" for each golden file. Other tests that want to verify equivalent results share the golden file in read-only mode (with `t.Skipf()` during updates).
### When to Share Golden Files
Share golden files between tests when you want to verify that different commands, flags, or configurations produce equivalent results with the **same output format**:
**Good reasons to share:**
- Testing different input methods that produce the same JSON output (local path vs remote URL vs client-server mode)
- Testing different ways to specify the same configuration (environment variables vs CLI flags vs config files)
- Testing different image sources that produce the same scan results (tar archive vs Docker Engine vs registry)
**Use override functions to handle:**
- Different artifact names or paths
- Different metadata (e.g., image config, repo info)
- Different ReportIDs or UUIDs
- Minor formatting differences in paths (e.g., Windows vs Unix separators)
**Example**: TestTar generates golden files for image scanning, and these are reused by:
- TestDockerEngine (different image source: Docker Engine API)
- TestRegistry (different image source: container registry)
- TestClientServer (different execution mode: client-server)
All of these produce the same JSON format with the same vulnerability data, but with different artifact names and metadata.
### Validation
The test framework automatically validates that:
- Tests updating golden files (`*update == true`) cannot use override functions
- This prevents accidentally updating golden files with modified data
If you try to update a golden file with an override function, the test will fail with:
```
invalid test configuration: cannot use override functions when update=true
```
## Test Organization
### Test Files
Tests are organized by functionality:
- `standalone_tar_test.go` - Container image scanning from tar archives
- `repo_test.go` - Repository and filesystem scanning
- `sbom_test.go` - SBOM scanning and generation
- `client_server_test.go` - Client-server mode
- `docker_engine_test.go` - Docker Engine API integration
- `registry_test.go` - Container registry integration
- `config_test.go` - Configuration handling (CLI flags, env vars, config files)
- `vm_test.go` - Virtual machine image scanning
- `module_test.go` - Wasm module integration
### Test Data Directory Structure
```
integration/testdata/
├── *.golden # Golden files (expected test outputs)
└── fixtures/ # Test input files
├── images/ # Container images (auto-downloaded)
├── vm-images/ # VM images (auto-downloaded)
├── repo/ # Repository and filesystem test data
├── sbom/ # SBOM test files
└── ...
```
**Important**: `testdata/fixtures/images/` and `testdata/fixtures/vm-images/` are automatically downloaded by mage commands:
- `mage test:integration` downloads container images
- `mage test:vm` downloads VM images
If you run tests directly with `go test` without using mage commands, these fixtures will not be present and tests will fail. Use mage commands to ensure fixtures are properly set up.
## Troubleshooting
### Golden file shared between tests shows unexpected differences
1. Identify which test is the canonical source (has `override: nil`)
2. Update golden file from the canonical source test only
3. Adjust override functions in consumer tests to handle differences
### Cannot update golden files for a specific test
1. Check if the test has `if *update { t.Skipf(...) }` - this prevents updates
2. Find the canonical source test mentioned in the skip message
3. Update golden files from the canonical source test instead
## Best Practices
1. **One golden file, one updater**: Each golden file should be updated by exactly one test function
2. **Use `mage test:updateGolden`**: This automatically updates all golden files from canonical source tests
3. **Minimize golden file duplication**: Share golden files when testing equivalent functionality
4. **Keep override functions simple**: Complex overrides may indicate tests shouldn't share golden files
5. **Add `override: nil` comments**: Clearly mark canonical source tests in the code

View File

@@ -40,7 +40,14 @@ type csArgs struct {
VulnSeveritySources []string
}
// TestClientServer tests the client-server mode of Trivy.
//
// Golden files are shared with TestTar or TestRepository.
func TestClientServer(t *testing.T) {
if *update {
t.Skipf("Skipping TestClientServer when -update flag is set. Golden files should be updated via TestTar or TestRepository.")
}
tests := []struct {
name string
args csArgs
@@ -52,7 +59,7 @@ func TestClientServer(t *testing.T) {
args: csArgs{
Input: "testdata/fixtures/images/alpine-39.tar.gz",
},
golden: "testdata/alpine-39.json.golden",
golden: goldenAlpine39,
},
{
name: "alpine 3.9 as alpine 3.10",
@@ -64,7 +71,7 @@ func TestClientServer(t *testing.T) {
want.Metadata.OS.Name = "3.10"
want.Results[0].Target = "testdata/fixtures/images/alpine-39.tar.gz (alpine 3.10)"
},
golden: "testdata/alpine-39.json.golden",
golden: goldenAlpine39,
},
{
name: "alpine 3.9 with high and critical severity",
@@ -76,7 +83,7 @@ func TestClientServer(t *testing.T) {
},
Input: "testdata/fixtures/images/alpine-39.tar.gz",
},
golden: "testdata/alpine-39-high-critical.json.golden",
golden: goldenAlpine39HighCritical,
},
{
name: "alpine 3.9 with .trivyignore",
@@ -88,28 +95,28 @@ func TestClientServer(t *testing.T) {
},
Input: "testdata/fixtures/images/alpine-39.tar.gz",
},
golden: "testdata/alpine-39-ignore-cveids.json.golden",
golden: goldenAlpine39IgnoreCVEIDs,
},
{
name: "alpine 3.10",
args: csArgs{
Input: "testdata/fixtures/images/alpine-310.tar.gz",
},
golden: "testdata/alpine-310.json.golden",
golden: goldenAlpine310JSON,
},
{
name: "alpine distroless",
args: csArgs{
Input: "testdata/fixtures/images/alpine-distroless.tar.gz",
},
golden: "testdata/alpine-distroless.json.golden",
golden: goldenAlpineDistroless,
},
{
name: "debian buster/10",
args: csArgs{
Input: "testdata/fixtures/images/debian-buster.tar.gz",
},
golden: "testdata/debian-buster.json.golden",
golden: goldenDebianBuster,
},
{
name: "debian buster/10 with --ignore-unfixed option",
@@ -117,28 +124,28 @@ func TestClientServer(t *testing.T) {
IgnoreUnfixed: true,
Input: "testdata/fixtures/images/debian-buster.tar.gz",
},
golden: "testdata/debian-buster-ignore-unfixed.json.golden",
golden: goldenDebianBusterIgnoreUnfixed,
},
{
name: "debian stretch/9",
args: csArgs{
Input: "testdata/fixtures/images/debian-stretch.tar.gz",
},
golden: "testdata/debian-stretch.json.golden",
golden: goldenDebianStretch,
},
{
name: "ubuntu 18.04",
args: csArgs{
Input: "testdata/fixtures/images/ubuntu-1804.tar.gz",
},
golden: "testdata/ubuntu-1804.json.golden",
golden: goldenUbuntu1804,
},
{
name: "centos 7",
args: csArgs{
Input: "testdata/fixtures/images/centos-7.tar.gz",
},
golden: "testdata/centos-7.json.golden",
golden: goldenCentOS7,
},
{
name: "centos 7 with --ignore-unfixed option",
@@ -146,7 +153,7 @@ func TestClientServer(t *testing.T) {
IgnoreUnfixed: true,
Input: "testdata/fixtures/images/centos-7.tar.gz",
},
golden: "testdata/centos-7-ignore-unfixed.json.golden",
golden: goldenCentOS7IgnoreUnfixed,
},
{
name: "centos 7 with medium severity",
@@ -155,112 +162,112 @@ func TestClientServer(t *testing.T) {
Severity: []string{"MEDIUM"},
Input: "testdata/fixtures/images/centos-7.tar.gz",
},
golden: "testdata/centos-7-medium.json.golden",
golden: goldenCentOS7Medium,
},
{
name: "centos 6",
args: csArgs{
Input: "testdata/fixtures/images/centos-6.tar.gz",
},
golden: "testdata/centos-6.json.golden",
golden: goldenCentOS6,
},
{
name: "ubi 7",
args: csArgs{
Input: "testdata/fixtures/images/ubi-7.tar.gz",
},
golden: "testdata/ubi-7.json.golden",
golden: goldenUBI7,
},
{
name: "almalinux 8",
args: csArgs{
Input: "testdata/fixtures/images/almalinux-8.tar.gz",
},
golden: "testdata/almalinux-8.json.golden",
golden: goldenAlmaLinux8,
},
{
name: "rocky linux 8",
args: csArgs{
Input: "testdata/fixtures/images/rockylinux-8.tar.gz",
},
golden: "testdata/rockylinux-8.json.golden",
golden: goldenRockyLinux8,
},
{
name: "distroless base",
args: csArgs{
Input: "testdata/fixtures/images/distroless-base.tar.gz",
},
golden: "testdata/distroless-base.json.golden",
golden: goldenDistrolessBase,
},
{
name: "distroless python27",
args: csArgs{
Input: "testdata/fixtures/images/distroless-python27.tar.gz",
},
golden: "testdata/distroless-python27.json.golden",
golden: goldenDistrolessPython27,
},
{
name: "amazon 1",
args: csArgs{
Input: "testdata/fixtures/images/amazon-1.tar.gz",
},
golden: "testdata/amazon-1.json.golden",
golden: goldenAmazon1,
},
{
name: "amazon 2",
args: csArgs{
Input: "testdata/fixtures/images/amazon-2.tar.gz",
},
golden: "testdata/amazon-2.json.golden",
golden: goldenAmazon2,
},
{
name: "oracle 8",
args: csArgs{
Input: "testdata/fixtures/images/oraclelinux-8.tar.gz",
},
golden: "testdata/oraclelinux-8.json.golden",
golden: goldenOracleLinux8,
},
{
name: "opensuse leap 15.1",
args: csArgs{
Input: "testdata/fixtures/images/opensuse-leap-151.tar.gz",
},
golden: "testdata/opensuse-leap-151.json.golden",
golden: goldenOpenSUSELeap151,
},
{
name: "opensuse tumbleweed",
args: csArgs{
Input: "testdata/fixtures/images/opensuse-tumbleweed.tar.gz",
},
golden: "testdata/opensuse-tumbleweed.json.golden",
golden: goldenOpenSUSETumbleweed,
},
{
name: "sle micro rancher 5.4",
args: csArgs{
Input: "testdata/fixtures/images/sle-micro-rancher-5.4_ndb.tar.gz",
},
golden: "testdata/sl-micro-rancher5.4.json.golden",
golden: goldenSLMicroRancher54,
},
{
name: "photon 3.0",
args: csArgs{
Input: "testdata/fixtures/images/photon-30.tar.gz",
},
golden: "testdata/photon-30.json.golden",
golden: goldenPhoton30,
},
{
name: "CBL-Mariner 1.0",
args: csArgs{
Input: "testdata/fixtures/images/mariner-1.0.tar.gz",
},
golden: "testdata/mariner-1.0.json.golden",
golden: goldenMariner10,
},
{
name: "busybox with Cargo.lock",
args: csArgs{
Input: "testdata/fixtures/images/busybox-with-lockfile.tar.gz",
},
golden: "testdata/busybox-with-lockfile.json.golden",
golden: goldenBusyboxWithLockfile,
},
{
name: "scan pox.xml with repo command in client/server mode",
@@ -269,7 +276,7 @@ func TestClientServer(t *testing.T) {
RemoteAddrOption: "--server",
Target: "testdata/fixtures/repo/pom/",
},
golden: "testdata/pom.json.golden",
golden: goldenPom,
},
{
name: "scan package-lock.json with repo command in client/server mode",
@@ -279,7 +286,7 @@ func TestClientServer(t *testing.T) {
Target: "testdata/fixtures/repo/npm/",
ListAllPackages: true,
},
golden: "testdata/npm.json.golden",
golden: goldenNPM,
},
{
name: "scan package-lock.json with severity from `ubuntu` in client/server mode",
@@ -292,7 +299,7 @@ func TestClientServer(t *testing.T) {
"ubuntu",
},
},
golden: "testdata/npm-ubuntu-severity.json.golden",
golden: goldenNPMUbuntuSeverity,
},
{
name: "scan sample.pem with repo command in client/server mode",
@@ -302,7 +309,7 @@ func TestClientServer(t *testing.T) {
secretConfig: "testdata/fixtures/repo/secrets/trivy-secret.yaml",
Target: "testdata/fixtures/repo/secrets/",
},
golden: "testdata/secrets.json.golden",
golden: goldenSecrets,
},
{
name: "scan remote repository with repo command in client/server mode",
@@ -311,12 +318,7 @@ func TestClientServer(t *testing.T) {
RemoteAddrOption: "--server",
Target: "https://github.com/knqyf263/trivy-ci-test",
},
golden: "testdata/test-repo.json.golden",
override: func(_ *testing.T, want, _ *types.Report) {
want.ArtifactName = "https://github.com/knqyf263/trivy-ci-test"
// Repository scans use commit hash for cache key (not random UUID), so ReportID becomes UUID #1
want.ReportID = "3ff14136-e09f-4df9-80ea-000000000001"
},
golden: goldenTestRepo,
},
}
@@ -330,7 +332,7 @@ func TestClientServer(t *testing.T) {
osArgs = append(osArgs, "--secret-config", tt.args.secretConfig)
}
runTest(t, osArgs, tt.golden, "", types.FormatJSON, runOptions{
runTest(t, osArgs, tt.golden, types.FormatJSON, runOptions{
override: overrideFuncs(overrideUID, tt.override),
fakeUUID: "3ff14136-e09f-4df9-80ea-%012d",
})
@@ -338,6 +340,11 @@ func TestClientServer(t *testing.T) {
}
}
// TestClientServerWithFormat tests the client-server mode with various output formats.
//
// NOTE: Unlike TestClientServer, this test CAN update golden files with the -update flag
// because the golden files used here are not shared with other tests. These format-specific
// golden files (GitLab, SARIF, ASFF, etc.) are unique to this test and should be updated here.
func TestClientServerWithFormat(t *testing.T) {
tests := []struct {
name string
@@ -351,7 +358,7 @@ func TestClientServerWithFormat(t *testing.T) {
TemplatePath: "@../contrib/gitlab.tpl",
Input: "testdata/fixtures/images/alpine-310.tar.gz",
},
golden: "testdata/alpine-310.gitlab.golden",
golden: goldenAlpine310GitLab,
},
{
name: "scan package-lock.json with gitlab template (Unknown os and image)",
@@ -362,7 +369,7 @@ func TestClientServerWithFormat(t *testing.T) {
Target: "testdata/fixtures/repo/npm/",
ListAllPackages: true,
},
golden: "testdata/npm.gitlab.golden",
golden: goldenNPMGitLab,
},
{
name: "alpine 3.10 with gitlab-codequality template",
@@ -371,7 +378,7 @@ func TestClientServerWithFormat(t *testing.T) {
TemplatePath: "@../contrib/gitlab-codequality.tpl",
Input: "testdata/fixtures/images/alpine-310.tar.gz",
},
golden: "testdata/alpine-310.gitlab-codequality.golden",
golden: goldenAlpine310GitLabCodeQuality,
},
{
name: "alpine 3.10 with sarif format",
@@ -379,7 +386,7 @@ func TestClientServerWithFormat(t *testing.T) {
Format: "sarif",
Input: "testdata/fixtures/images/alpine-310.tar.gz",
},
golden: "testdata/alpine-310.sarif.golden",
golden: goldenAlpine310SARIF,
},
{
name: "alpine 3.10 with ASFF template",
@@ -388,7 +395,7 @@ func TestClientServerWithFormat(t *testing.T) {
TemplatePath: "@../contrib/asff.tpl",
Input: "testdata/fixtures/images/alpine-310.tar.gz",
},
golden: "testdata/alpine-310.asff.golden",
golden: goldenAlpine310ASFF,
},
{
name: "scan secrets with ASFF template",
@@ -399,7 +406,7 @@ func TestClientServerWithFormat(t *testing.T) {
TemplatePath: "@../contrib/asff.tpl",
Target: "testdata/fixtures/repo/secrets/",
},
golden: "testdata/secrets.asff.golden",
golden: goldenSecretsASFF,
},
{
name: "alpine 3.10 with html template",
@@ -408,7 +415,7 @@ func TestClientServerWithFormat(t *testing.T) {
TemplatePath: "@../contrib/html.tpl",
Input: "testdata/fixtures/images/alpine-310.tar.gz",
},
golden: "testdata/alpine-310.html.golden",
golden: goldenAlpine310HTML,
},
{
name: "alpine 3.10 with junit template",
@@ -417,7 +424,7 @@ func TestClientServerWithFormat(t *testing.T) {
TemplatePath: "@../contrib/junit.tpl",
Input: "testdata/fixtures/images/alpine-310.tar.gz",
},
golden: "testdata/alpine-310.junit.golden",
golden: goldenAlpine310JUnit,
},
{
name: "alpine 3.10 with github dependency snapshots format",
@@ -425,7 +432,7 @@ func TestClientServerWithFormat(t *testing.T) {
Format: "github",
Input: "testdata/fixtures/images/alpine-310.tar.gz",
},
golden: "testdata/alpine-310.gsbom.golden",
golden: goldenAlpine310GSBOM,
},
}
@@ -458,14 +465,19 @@ func TestClientServerWithFormat(t *testing.T) {
t.Setenv("AWS_ACCOUNT_ID", "123456789012")
osArgs := setupClient(t, tt.args, addr, cacheDir)
runTest(t, osArgs, tt.golden, "", tt.args.Format, runOptions{
override: overrideUID,
runTest(t, osArgs, tt.golden, tt.args.Format, runOptions{
fakeUUID: "3ff14136-e09f-4df9-80ea-%012d",
override: nil, // Do not use overrides - golden files are generated from this test as the canonical source
})
})
}
}
// TestClientServerWithCycloneDX tests the client-server mode with CycloneDX format.
//
// NOTE: This test CAN update golden files with the -update flag because the golden files
// used here are not shared with other tests. These format-specific golden files should be
// updated here.
func TestClientServerWithCycloneDX(t *testing.T) {
tests := []struct {
name string
@@ -478,7 +490,7 @@ func TestClientServerWithCycloneDX(t *testing.T) {
Format: "cyclonedx",
Input: "testdata/fixtures/images/fluentd-multiple-lockfiles.tar.gz",
},
golden: "testdata/fluentd-multiple-lockfiles.cdx.json.golden",
golden: goldenFluentdMultipleLockfilesCDX,
},
}
@@ -486,14 +498,22 @@ func TestClientServerWithCycloneDX(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
osArgs := setupClient(t, tt.args, addr, cacheDir)
runTest(t, osArgs, tt.golden, "", types.FormatCycloneDX, runOptions{
runTest(t, osArgs, tt.golden, types.FormatCycloneDX, runOptions{
fakeUUID: "3ff14136-e09f-4df9-80ea-%012d",
override: nil, // Do not use overrides - golden files are generated from this test as the canonical source
})
})
}
}
// TestClientServerWithCustomOptions tests the client-server mode with custom options.
//
// Golden files are shared with TestTar or TestRepository.
func TestClientServerWithCustomOptions(t *testing.T) {
if *update {
t.Skipf("Skipping TestClientServerWithCustomOptions when -update flag is set. Golden files should be updated via TestTar or TestRepository.")
}
token := "token"
tokenHeader := "Trivy-Token"
pathPrefix := "prefix"
@@ -512,7 +532,7 @@ func TestClientServerWithCustomOptions(t *testing.T) {
ClientTokenHeader: tokenHeader,
PathPrefix: pathPrefix,
},
golden: "testdata/alpine-39.json.golden",
golden: goldenAlpine39,
},
{
name: "invalid token",
@@ -555,7 +575,7 @@ func TestClientServerWithCustomOptions(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
osArgs := setupClient(t, tt.args, addr, cacheDir)
runTest(t, osArgs, tt.golden, "", types.FormatJSON, runOptions{
runTest(t, osArgs, tt.golden, types.FormatJSON, runOptions{
override: overrideUID,
wantErr: tt.wantErr,
fakeUUID: "3ff14136-e09f-4df9-80ea-%012d",
@@ -564,7 +584,14 @@ func TestClientServerWithCustomOptions(t *testing.T) {
}
}
// TestClientServerWithRedis tests the client-server mode with Redis cache backend.
//
// Golden files are shared with TestTar or TestRepository.
func TestClientServerWithRedis(t *testing.T) {
if *update {
t.Skipf("Skipping TestClientServerWithRedis when -update flag is set. Golden files should be updated via TestTar or TestRepository.")
}
// Set up a Redis container
ctx := t.Context()
// This test includes 2 checks
@@ -579,13 +606,13 @@ func TestClientServerWithRedis(t *testing.T) {
testArgs := csArgs{
Input: "testdata/fixtures/images/alpine-39.tar.gz",
}
golden := "testdata/alpine-39.json.golden"
golden := goldenAlpine39
t.Run("alpine 3.9", func(t *testing.T) {
osArgs := setupClient(t, testArgs, addr, cacheDir)
// Run Trivy client
runTest(t, osArgs, golden, "", types.FormatJSON, runOptions{
runTest(t, osArgs, golden, types.FormatJSON, runOptions{
override: overrideUID,
fakeUUID: "3ff14136-e09f-4df9-80ea-%012d",
})
@@ -598,7 +625,7 @@ func TestClientServerWithRedis(t *testing.T) {
osArgs := setupClient(t, testArgs, addr, cacheDir)
// Run Trivy client
runTest(t, osArgs, "", "", types.FormatJSON, runOptions{
runTest(t, osArgs, "", types.FormatJSON, runOptions{
wantErr: "unable to store cache",
})
})
@@ -674,6 +701,7 @@ func setupClient(t *testing.T, c csArgs, addr, cacheDir string) []string {
c.Command,
c.RemoteAddrOption,
"http://" + addr,
"--quiet",
}
if c.Format != "" {

View File

@@ -13,8 +13,14 @@ import (
"github.com/aquasecurity/trivy/pkg/types"
)
// TestConfiguration tests the configuration of the CLI flags, environmental variables, and config file
// TestConfiguration tests the configuration of the CLI flags, environmental variables, and config file.
//
// Golden files are shared with TestRepository.
func TestConfiguration(t *testing.T) {
if *update {
t.Skipf("Skipping TestConfiguration when -update flag is set. Golden files should be updated via TestRepository.")
}
type args struct {
input string
flags map[string]string
@@ -50,7 +56,7 @@ scan:
- testdata/fixtures/repo/gomod/submod2/go.mod
`,
},
golden: "testdata/gomod-skip.json.golden",
golden: goldenGoModSkip,
},
{
name: "dockerfile with custom file pattern",
@@ -78,7 +84,7 @@ rego:
- testing
`,
},
golden: "testdata/dockerfile_file_pattern.json.golden",
golden: goldenDockerfileFilePattern,
},
{
name: "key alias", // "--scanners" vs "--security-checks"
@@ -96,7 +102,7 @@ scan:
- vuln
`,
},
golden: "testdata/gomod.json.golden",
golden: goldenGoMod,
},
{
name: "value alias", // "--scanners vuln" vs "--scanners vulnerability"
@@ -114,7 +120,7 @@ scan:
- vulnerability
`,
},
golden: "testdata/gomod.json.golden",
golden: goldenGoMod,
},
{
name: "invalid value",
@@ -147,6 +153,9 @@ severity:
// Set a temp dir so that modules will not be loaded
t.Setenv("XDG_DATA_HOME", cacheDir)
// Disable Go license detection
t.Setenv("GOPATH", cacheDir)
for _, tt := range tests {
command := "repo"
@@ -166,21 +175,13 @@ severity:
osArgs = append(osArgs, "--"+key, value)
}
// Set up the output file
outputFile := filepath.Join(t.TempDir(), "output.json")
osArgs = append(osArgs, "--output", outputFile)
runTest(t, osArgs, tt.golden, outputFile, types.FormatJSON, runOptions{
runTest(t, osArgs, tt.golden, types.FormatJSON, runOptions{
wantErr: tt.wantErr,
fakeUUID: "3ff14136-e09f-4df9-80ea-%012d",
})
})
t.Run(tt.name+" with environmental variables", func(t *testing.T) {
// Set up the output file
outputFile := filepath.Join(t.TempDir(), "output.json")
t.Setenv("TRIVY_OUTPUT", outputFile)
t.Setenv("TRIVY_FORMAT", "json")
t.Setenv("TRIVY_LIST_ALL_PKGS", "false")
t.Setenv("TRIVY_CACHE_DIR", cacheDir)
@@ -195,26 +196,22 @@ severity:
tt.args.input,
}
runTest(t, osArgs, tt.golden, outputFile, types.FormatJSON, runOptions{
runTest(t, osArgs, tt.golden, types.FormatJSON, runOptions{
wantErr: tt.wantErr,
fakeUUID: "3ff14136-e09f-4df9-80ea-%012d",
})
})
t.Run(tt.name+" with config file", func(t *testing.T) {
// Set up the output file
outputFile := filepath.Join(t.TempDir(), "output.json")
configFile := tt.args.configFile
configFile += fmt.Sprintf(`
format: json
list-all-pkgs: false
output: %s
cache:
dir: %s
db:
skip-update: true
`, outputFile, cacheDir)
`, cacheDir)
configPath := filepath.Join(t.TempDir(), "trivy.yaml")
err := os.WriteFile(configPath, []byte(configFile), 0o444)
@@ -227,7 +224,7 @@ db:
tt.args.input,
}
runTest(t, osArgs, tt.golden, outputFile, types.FormatJSON, runOptions{
runTest(t, osArgs, tt.golden, types.FormatJSON, runOptions{
wantErr: tt.wantErr,
fakeUUID: "3ff14136-e09f-4df9-80ea-%012d",
})

View File

@@ -3,12 +3,16 @@
package integration
import (
"path/filepath"
"testing"
"github.com/aquasecurity/trivy/pkg/types"
)
// TestConvert tests the convert command with various output formats.
//
// NOTE: This test CAN update golden files with the -update flag because the golden files
// used here are not shared with other tests. These format conversion golden files are unique
// to this test and should be updated here.
func TestConvert(t *testing.T) {
type args struct {
input string
@@ -18,18 +22,17 @@ func TestConvert(t *testing.T) {
listAllPkgs bool
}
tests := []struct {
name string
args args
golden string
override OverrideFunc
name string
args args
golden string
}{
{
name: "npm",
args: args{
input: "testdata/npm.json.golden",
input: goldenNPM,
format: "cyclonedx",
},
golden: "testdata/npm-cyclonedx.json.golden",
golden: goldenNPMCycloneDX,
},
{
name: "npm without package UID",
@@ -37,17 +40,17 @@ func TestConvert(t *testing.T) {
input: "testdata/fixtures/convert/npm.json.golden",
format: "cyclonedx",
},
golden: "testdata/npm-cyclonedx.json.golden",
golden: goldenNPMCycloneDX,
},
{
name: "npm with suppressed vulnerability",
args: args{
input: "testdata/fixtures/convert/npm-with-suppressed.json.golden",
input: goldenConvertNPMWithSuppressed,
format: "json",
showSuppressed: true,
listAllPkgs: true,
},
golden: "testdata/fixtures/convert/npm-with-suppressed.json.golden",
golden: goldenConvertNPMWithSuppressed,
},
}
@@ -55,6 +58,7 @@ func TestConvert(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
osArgs := []string{
"convert",
tt.args.input,
"--cache-dir",
t.TempDir(),
"-q",
@@ -70,17 +74,10 @@ func TestConvert(t *testing.T) {
osArgs = append(osArgs, "--list-all-pkgs=false")
}
// Set up the output file
outputFile := filepath.Join(t.TempDir(), "output.json")
if *update {
outputFile = tt.golden
}
osArgs = append(osArgs, "--output", outputFile, tt.args.input)
// Run "trivy convert"
runTest(t, osArgs, tt.golden, outputFile, types.Format(tt.args.format), runOptions{
runTest(t, osArgs, tt.golden, types.Format(tt.args.format), runOptions{
fakeUUID: "3ff14136-e09f-4df9-80ea-%012d",
override: nil, // Do not use overrides - golden files are generated from this test as the canonical source
})
})
}

View File

@@ -14,10 +14,14 @@ import (
"github.com/aquasecurity/trivy/pkg/types"
)
// TestDockerEngine tests scanning images via Docker Engine API.
//
// Golden files are shared with TestTar.
func TestDockerEngine(t *testing.T) {
if *update {
t.Skipf("This test doesn't update golden files")
t.Skipf("Skipping TestDockerEngine when -update flag is set. Golden files should be updated via TestTar.")
}
tests := []struct {
name string
invalidImage bool
@@ -33,13 +37,13 @@ func TestDockerEngine(t *testing.T) {
{
name: "alpine:3.9",
input: "testdata/fixtures/images/alpine-39.tar.gz",
golden: "testdata/alpine-39.json.golden",
golden: goldenAlpine39,
},
{
name: "alpine:3.9, with max image size",
maxImageSize: "100mb",
input: "testdata/fixtures/images/alpine-39.tar.gz",
golden: "testdata/alpine-39.json.golden",
golden: goldenAlpine39,
},
{
name: "alpine:3.9, with high and critical severity",
@@ -48,7 +52,7 @@ func TestDockerEngine(t *testing.T) {
"CRITICAL",
},
input: "testdata/fixtures/images/alpine-39.tar.gz",
golden: "testdata/alpine-39-high-critical.json.golden",
golden: goldenAlpine39HighCritical,
},
{
name: "alpine:3.9, with .trivyignore",
@@ -57,144 +61,144 @@ func TestDockerEngine(t *testing.T) {
"CVE-2019-14697",
},
input: "testdata/fixtures/images/alpine-39.tar.gz",
golden: "testdata/alpine-39-ignore-cveids.json.golden",
golden: goldenAlpine39IgnoreCVEIDs,
},
{
name: "alpine:3.10",
input: "testdata/fixtures/images/alpine-310.tar.gz",
golden: "testdata/alpine-310.json.golden",
golden: goldenAlpine310JSON,
},
{
name: "amazonlinux:1",
input: "testdata/fixtures/images/amazon-1.tar.gz",
golden: "testdata/amazon-1.json.golden",
golden: goldenAmazon1,
},
{
name: "amazonlinux:2",
input: "testdata/fixtures/images/amazon-2.tar.gz",
golden: "testdata/amazon-2.json.golden",
golden: goldenAmazon2,
},
{
name: "almalinux 8",
input: "testdata/fixtures/images/almalinux-8.tar.gz",
golden: "testdata/almalinux-8.json.golden",
golden: goldenAlmaLinux8,
},
{
name: "rocky linux 8",
input: "testdata/fixtures/images/rockylinux-8.tar.gz",
golden: "testdata/rockylinux-8.json.golden",
golden: goldenRockyLinux8,
},
{
name: "centos 6",
input: "testdata/fixtures/images/centos-6.tar.gz",
golden: "testdata/centos-6.json.golden",
golden: goldenCentOS6,
},
{
name: "centos 7",
input: "testdata/fixtures/images/centos-7.tar.gz",
golden: "testdata/centos-7.json.golden",
golden: goldenCentOS7,
},
{
name: "centos 7, with --ignore-unfixed option",
ignoreUnfixed: true,
input: "testdata/fixtures/images/centos-7.tar.gz",
golden: "testdata/centos-7-ignore-unfixed.json.golden",
golden: goldenCentOS7IgnoreUnfixed,
},
{
name: "centos 7, with --ignore-status option",
ignoreStatus: []string{"will_not_fix"},
input: "testdata/fixtures/images/centos-7.tar.gz",
golden: "testdata/centos-7-ignore-unfixed.json.golden",
golden: goldenCentOS7IgnoreUnfixed,
},
{
name: "centos 7, with --ignore-unfixed option, with medium severity",
ignoreUnfixed: true,
severity: []string{"MEDIUM"},
input: "testdata/fixtures/images/centos-7.tar.gz",
golden: "testdata/centos-7-medium.json.golden",
golden: goldenCentOS7Medium,
},
{
name: "registry.redhat.io/ubi7",
input: "testdata/fixtures/images/ubi-7.tar.gz",
golden: "testdata/ubi-7.json.golden",
golden: goldenUBI7,
},
{
name: "debian buster/10",
input: "testdata/fixtures/images/debian-buster.tar.gz",
golden: "testdata/debian-buster.json.golden",
golden: goldenDebianBuster,
},
{
name: "debian buster/10, with --ignore-unfixed option",
ignoreUnfixed: true,
input: "testdata/fixtures/images/debian-buster.tar.gz",
golden: "testdata/debian-buster-ignore-unfixed.json.golden",
golden: goldenDebianBusterIgnoreUnfixed,
},
{
name: "debian buster/10, with --ignore-status option",
ignoreStatus: []string{"affected"},
input: "testdata/fixtures/images/debian-buster.tar.gz",
golden: "testdata/debian-buster-ignore-unfixed.json.golden",
golden: goldenDebianBusterIgnoreUnfixed,
},
{
name: "debian stretch/9",
input: "testdata/fixtures/images/debian-stretch.tar.gz",
golden: "testdata/debian-stretch.json.golden",
golden: goldenDebianStretch,
},
{
name: "distroless base",
input: "testdata/fixtures/images/distroless-base.tar.gz",
golden: "testdata/distroless-base.json.golden",
golden: goldenDistrolessBase,
},
{
name: "distroless python2.7",
input: "testdata/fixtures/images/distroless-python27.tar.gz",
golden: "testdata/distroless-python27.json.golden",
golden: goldenDistrolessPython27,
},
{
name: "oracle linux 8",
input: "testdata/fixtures/images/oraclelinux-8.tar.gz",
golden: "testdata/oraclelinux-8.json.golden",
golden: goldenOracleLinux8,
},
{
name: "ubuntu 18.04",
input: "testdata/fixtures/images/ubuntu-1804.tar.gz",
golden: "testdata/ubuntu-1804.json.golden",
golden: goldenUbuntu1804,
},
{
name: "ubuntu 18.04, with --ignore-unfixed option",
ignoreUnfixed: true,
input: "testdata/fixtures/images/ubuntu-1804.tar.gz",
golden: "testdata/ubuntu-1804-ignore-unfixed.json.golden",
golden: goldenUbuntu1804IgnoreUnfixed,
},
{
name: "opensuse leap 15.1",
input: "testdata/fixtures/images/opensuse-leap-151.tar.gz",
golden: "testdata/opensuse-leap-151.json.golden",
golden: goldenOpenSUSELeap151,
},
{
name: "opensuse tumbleweed",
input: "testdata/fixtures/images/opensuse-tumbleweed.tar.gz",
golden: "testdata/opensuse-tumbleweed.json.golden",
golden: goldenOpenSUSETumbleweed,
},
{
name: "sle micro rancher 5.4",
input: "testdata/fixtures/images/sle-micro-rancher-5.4_ndb.tar.gz",
golden: "testdata/sl-micro-rancher5.4.json.golden",
golden: goldenSLMicroRancher54,
},
{
name: "photon 3.0",
input: "testdata/fixtures/images/photon-30.tar.gz",
golden: "testdata/photon-30.json.golden",
golden: goldenPhoton30,
},
{
name: "CBL-Mariner 1.0",
input: "testdata/fixtures/images/mariner-1.0.tar.gz",
golden: "testdata/mariner-1.0.json.golden",
golden: goldenMariner10,
},
{
name: "busybox with Cargo.lock",
input: "testdata/fixtures/images/busybox-with-lockfile.tar.gz",
golden: "testdata/busybox-with-lockfile.json.golden",
golden: goldenBusyboxWithLockfile,
},
{
name: "sad path, invalid image",
@@ -246,7 +250,8 @@ func TestDockerEngine(t *testing.T) {
"--cache-dir",
cacheDir,
"image",
"--skip-update",
"--quiet",
"--skip-db-update",
"--format=json",
"--list-all-pkgs=false",
"--image-src=docker",
@@ -289,7 +294,7 @@ func TestDockerEngine(t *testing.T) {
osArgs = append(osArgs, tt.input)
// Run Trivy
runTest(t, osArgs, tt.golden, "", types.FormatJSON, runOptions{
runTest(t, osArgs, tt.golden, types.FormatJSON, runOptions{
wantErr: tt.wantErr,
fakeUUID: "3ff14136-e09f-4df9-80ea-%012d",
// Image config fields were removed

View File

@@ -43,6 +43,123 @@ var update = flag.Bool("update", false, "update golden files")
const SPDXSchema = "https://raw.githubusercontent.com/spdx/spdx-spec/support/v%s/schemas/spdx-schema.json"
// Golden file paths
const (
// Container image tests (docker_engine_test.go, client_server_test.go, standalone_tar_test.go, registry_test.go)
goldenAlmaLinux8 = "testdata/almalinux-8.json.golden"
goldenAlpine39 = "testdata/alpine-39.json.golden"
goldenAlpine39HighCritical = "testdata/alpine-39-high-critical.json.golden"
goldenAlpine39IgnoreCVEIDs = "testdata/alpine-39-ignore-cveids.json.golden"
goldenAlpine39Skip = "testdata/alpine-39-skip.json.golden"
goldenAlpine310JSON = "testdata/alpine-310.json.golden"
goldenAlpine310ASFF = "testdata/alpine-310.asff.golden"
goldenAlpine310GitLab = "testdata/alpine-310.gitlab.golden"
goldenAlpine310GitLabCodeQuality = "testdata/alpine-310.gitlab-codequality.golden"
goldenAlpine310GSBOM = "testdata/alpine-310.gsbom.golden"
goldenAlpine310HTML = "testdata/alpine-310.html.golden"
goldenAlpine310JUnit = "testdata/alpine-310.junit.golden"
goldenAlpine310SARIF = "testdata/alpine-310.sarif.golden"
goldenAlpineDistroless = "testdata/alpine-distroless.json.golden"
goldenAmazon1 = "testdata/amazon-1.json.golden"
goldenAmazon2 = "testdata/amazon-2.json.golden"
goldenBusyboxWithLockfile = "testdata/busybox-with-lockfile.json.golden"
goldenCentOS6 = "testdata/centos-6.json.golden"
goldenCentOS7 = "testdata/centos-7.json.golden"
goldenCentOS7IgnoreUnfixed = "testdata/centos-7-ignore-unfixed.json.golden"
goldenCentOS7Medium = "testdata/centos-7-medium.json.golden"
goldenDebianBuster = "testdata/debian-buster.json.golden"
goldenDebianBusterIgnoreUnfixed = "testdata/debian-buster-ignore-unfixed.json.golden"
goldenDebianStretch = "testdata/debian-stretch.json.golden"
goldenDistrolessBase = "testdata/distroless-base.json.golden"
goldenDistrolessPython27 = "testdata/distroless-python27.json.golden"
goldenFluentdGems = "testdata/fluentd-gems.json.golden"
goldenFluentdMultipleLockfilesCDX = "testdata/fluentd-multiple-lockfiles.cdx.json.golden"
goldenMariner10 = "testdata/mariner-1.0.json.golden"
goldenNPM = "testdata/npm.json.golden"
goldenNPMGitLab = "testdata/npm.gitlab.golden"
goldenNPMUbuntuSeverity = "testdata/npm-ubuntu-severity.json.golden"
goldenOpenSUSELeap151 = "testdata/opensuse-leap-151.json.golden"
goldenOpenSUSETumbleweed = "testdata/opensuse-tumbleweed.json.golden"
goldenOracleLinux8 = "testdata/oraclelinux-8.json.golden"
goldenPhoton30 = "testdata/photon-30.json.golden"
goldenPom = "testdata/pom.json.golden"
goldenRockyLinux8 = "testdata/rockylinux-8.json.golden"
goldenSecrets = "testdata/secrets.json.golden"
goldenSecretsASFF = "testdata/secrets.asff.golden"
goldenSLMicroRancher54 = "testdata/sl-micro-rancher5.4.json.golden"
goldenTestRepo = "testdata/test-repo.json.golden"
goldenUBI7 = "testdata/ubi-7.json.golden"
goldenUBI7Comprehensive = "testdata/ubi-7-comprehensive.json.golden"
goldenUbuntu1804 = "testdata/ubuntu-1804.json.golden"
goldenUbuntu1804IgnoreUnfixed = "testdata/ubuntu-1804-ignore-unfixed.json.golden"
// Repository/Filesystem tests (repo_test.go, config_test.go)
goldenBun = "testdata/bun.json.golden"
goldenCargoLock = "testdata/cargo.lock.json.golden"
goldenCocoaPods = "testdata/cocoapods.json.golden"
goldenComposerLock = "testdata/composer.lock.json.golden"
goldenComposerVendor = "testdata/composer.vendor.json.golden"
goldenConan = "testdata/conan.json.golden"
goldenCondaCycloneDX = "testdata/conda-cyclonedx.json.golden"
goldenCondaEnvironmentCycloneDX = "testdata/conda-environment-cyclonedx.json.golden"
goldenCondaSPDX = "testdata/conda-spdx.json.golden"
goldenDockerfile = "testdata/dockerfile.json.golden"
goldenDockerfileCustomPolicies = "testdata/dockerfile-custom-policies.json.golden"
goldenDockerfileFilePattern = "testdata/dockerfile_file_pattern.json.golden"
goldenDotNet = "testdata/dotnet.json.golden"
goldenGoMod = "testdata/gomod.json.golden"
goldenGoModSkip = "testdata/gomod-skip.json.golden"
goldenGoModVEX = "testdata/gomod-vex.json.golden"
goldenGradle = "testdata/gradle.json.golden"
goldenHelm = "testdata/helm.json.golden"
goldenHelmBadName = "testdata/helm_badname.json.golden"
goldenHelmTestChart = "testdata/helm_testchart.json.golden"
goldenHelmTestChartOverridden = "testdata/helm_testchart.overridden.json.golden"
goldenJuliaSPDX = "testdata/julia-spdx.json.golden"
goldenMixLock = "testdata/mix.lock.json.golden"
goldenNPMWithDev = "testdata/npm-with-dev.json.golden"
goldenNuGet = "testdata/nuget.json.golden"
goldenPackagesProps = "testdata/packagesprops.json.golden"
goldenPip = "testdata/pip.json.golden"
goldenPipenv = "testdata/pipenv.json.golden"
goldenPnpm = "testdata/pnpm.json.golden"
goldenPoetry = "testdata/poetry.json.golden"
goldenPomCycloneDX = "testdata/pom-cyclonedx.json.golden"
goldenPubspecLock = "testdata/pubspec.lock.json.golden"
goldenSBT = "testdata/sbt.json.golden"
goldenSwift = "testdata/swift.json.golden"
goldenTerraformExcludeMisconfigsRemoteModule = "testdata/terraform-exclude-misconfs-remote-module.json.golden"
goldenTerraformOpenTofuRegistry = "testdata/terraform-opentofu-registry.json.golden"
goldenTerraformRemoteModule = "testdata/terraform-remote-module.json.golden"
goldenTerraformRemoteModuleInChild = "testdata/terraform-remote-module-in-child.json.golden"
goldenTerraformRemoteSubmodule = "testdata/terraform-remote-submodule.json.golden"
goldenTerraformTerraformRegistry = "testdata/terraform-terraform-registry.json.golden"
goldenUV = "testdata/uv.json.golden"
goldenYarn = "testdata/yarn.json.golden"
// SBOM tests (sbom_test.go)
goldenFluentdMultipleLockfiles = "testdata/fluentd-multiple-lockfiles.json.golden"
goldenFluentdMultipleLockfilesShortCDX = "testdata/fluentd-multiple-lockfiles-short.cdx.json.golden"
goldenLicenseCycloneDX = "testdata/license-cyclonedx.json.golden"
goldenMinikubeKBOM = "testdata/minikube-kbom.json.golden"
// Convert tests (convert_test.go)
goldenNPMCycloneDX = "testdata/npm-cyclonedx.json.golden"
goldenConvertNPMWithSuppressed = "testdata/fixtures/convert/npm-with-suppressed.json.golden"
// VM tests (vm_test.go)
goldenAmazonLinux2GP2X86VM = "testdata/amazonlinux2-gp2-x86-vm.json.golden"
goldenUbuntuGP2X86VM = "testdata/ubuntu-gp2-x86-vm.json.golden"
// Module tests (module_test.go)
goldenSpring4ShellJRE8 = "testdata/spring4shell-jre8.json.golden"
goldenSpring4ShellJRE11 = "testdata/spring4shell-jre11.json.golden"
// Plugin tests (plugin_test.go)
goldenCountPlugin020 = "testdata/count-0.2.0-plugin.txt.golden"
goldenCountPlugin010WithBeforeFlag = "testdata/count-0.1.0-plugin-with-before-flag.txt.golden"
)
func initDB(t *testing.T) string {
fixtureDir := filepath.Join("testdata", "fixtures", "db")
entries, err := os.ReadDir(fixtureDir)
@@ -235,19 +352,23 @@ type runOptions struct {
}
// runTest runs Trivy with the given args and compares the output with the golden file.
// If outputFile is empty, the output file is created in a temporary directory.
// If update is true, the golden file is updated.
func runTest(t *testing.T, osArgs []string, wantFile, outputFile string, format types.Format, opts runOptions) {
// The output file is created in a temporary directory, unless -update flag is set, in which case
// the golden file is updated directly.
func runTest(t *testing.T, osArgs []string, wantFile string, format types.Format, opts runOptions) {
// Ensure that tests updating golden files don't use override functions
// as overrides would modify the golden file output
if *update && opts.override != nil {
require.Fail(t, "invalid test configuration", "cannot use override functions when -update is set")
}
if opts.fakeUUID != "" {
uuid.SetFakeUUID(t, opts.fakeUUID)
}
if outputFile == "" {
// Set up the output file
outputFile = filepath.Join(t.TempDir(), "output.json")
if *update && opts.override == nil {
outputFile = wantFile
}
// Set up the output file
outputFile := filepath.Join(t.TempDir(), "output.json")
if *update {
outputFile = wantFile
}
osArgs = append(osArgs, "--output", outputFile)

View File

@@ -10,6 +10,7 @@ import (
"testing"
cdx "github.com/CycloneDX/cyclonedx-go"
"github.com/aquasecurity/trivy/pkg/k8s/report"
"github.com/aquasecurity/trivy/pkg/types"
@@ -18,9 +19,11 @@ import (
"github.com/stretchr/testify/require"
)
// Note: the test required k8s (kind) cluster installed.
// "mage test:k8s" will run this test.
// TestK8s tests Kubernetes cluster scanning.
//
// NOTE: This test CAN update golden files with the -update flag. The K8s-specific golden files
// are unique to this test and not shared with other tests.
// Requires k8s (kind) cluster installed. Run with "mage test:k8s".
func TestK8s(t *testing.T) {
// Set up testing DB
cacheDir := initDB(t)
@@ -31,15 +34,21 @@ func TestK8s(t *testing.T) {
// it uses a fixed version of trivy-checks bundle - v1.11.2
// its hash is sha256:f3ea8227f838a985f0c884909e9d226362f5fc5ab6021310a179fbb24c5b57fd
osArgs := []string{
"--cache-dir", cacheDir,
"--cache-dir",
cacheDir,
"k8s",
"kind-kind-test",
"--report", "summary",
"--checks-bundle-repository", "mirror.gcr.io/aquasec/trivy-checks:1.11.2@sha256:f3ea8227f838a985f0c884909e9d226362f5fc5ab6021310a179fbb24c5b57fd",
"--report",
"summary",
"--checks-bundle-repository",
"mirror.gcr.io/aquasec/trivy-checks:1.11.2@sha256:f3ea8227f838a985f0c884909e9d226362f5fc5ab6021310a179fbb24c5b57fd",
"-q",
"--timeout", "5m0s",
"--format", "json",
"--output", outputFile,
"--timeout",
"5m0s",
"--format",
"json",
"--output",
outputFile,
}
// Run Trivy
@@ -146,13 +155,15 @@ func TestK8s(t *testing.T) {
cacheDir,
"k8s",
"limitedcontext",
"--kubeconfig", "limitedconfig",
"--kubeconfig",
"limitedconfig",
"--report",
"summary",
"-q",
"--timeout",
"5m0s",
"--include-namespaces", "limitedns",
"--include-namespaces",
"limitedns",
"--format",
"json",
"--output",

View File

@@ -11,6 +11,11 @@ import (
"github.com/aquasecurity/trivy/pkg/types"
)
// TestModule tests Trivy with Wasm modules.
//
// NOTE: This test CAN update golden files with the -update flag because the golden files
// used here are not shared with other tests. These module-specific golden files are unique
// to this test and should be updated here.
func TestModule(t *testing.T) {
tests := []struct {
name string
@@ -20,12 +25,12 @@ func TestModule(t *testing.T) {
{
name: "spring4shell jre 8, severity update",
input: "testdata/fixtures/images/spring4shell-jre8.tar.gz",
golden: "testdata/spring4shell-jre8.json.golden",
golden: goldenSpring4ShellJRE8,
},
{
name: "spring4shell jre 11, no severity update",
input: "testdata/fixtures/images/spring4shell-jre11.tar.gz",
golden: "testdata/spring4shell-jre11.json.golden",
golden: goldenSpring4ShellJRE11,
},
}
@@ -57,8 +62,9 @@ func TestModule(t *testing.T) {
})
// Run Trivy
runTest(t, osArgs, tt.golden, "", types.FormatJSON, runOptions{
runTest(t, osArgs, tt.golden, types.FormatJSON, runOptions{
fakeUUID: "3ff14136-e09f-4df9-80ea-%012d",
override: nil, // Do not use overrides - golden files are generated from this test as the canonical source
})
})
}

View File

@@ -13,6 +13,11 @@ import (
"github.com/aquasecurity/trivy/pkg/utils/fsutils"
)
// TestPlugin tests Trivy plugins.
//
// NOTE: This test CAN update golden files with the -update flag because the golden files
// used here are not shared with other tests. These plugin-specific golden files are unique
// to this test and should be updated here.
func TestPlugin(t *testing.T) {
tests := []struct {
name string
@@ -23,13 +28,13 @@ func TestPlugin(t *testing.T) {
{
name: "count plugin installed from `index`",
plugin: "count@v0.2.0",
golden: "testdata/count-0.2.0-plugin.txt.golden",
golden: goldenCountPlugin020,
},
{
name: "count plugin installed from github archive",
plugin: "https://github.com/aquasecurity/trivy-plugin-count/archive/refs/tags/v0.1.0.zip",
pluginArgs: "--published-before=2020-01-01",
golden: "testdata/count-0.1.0-plugin-with-before-flag.txt.golden",
golden: goldenCountPlugin010WithBeforeFlag,
},
}

View File

@@ -120,7 +120,14 @@ type registryOption struct {
AuthLogin bool
}
// TestRegistry tests scanning images from a container registry.
//
// Golden files are shared with TestTar.
func TestRegistry(t *testing.T) {
if *update {
t.Skipf("Skipping TestRegistry when -update flag is set. Golden files should be updated via TestTar.")
}
ctx := t.Context()
baseDir, err := filepath.Abs(".")
@@ -168,7 +175,7 @@ func TestRegistry(t *testing.T) {
Username: authUsername,
Password: authPassword,
},
golden: "testdata/alpine-310.json.golden",
golden: goldenAlpine310JSON,
},
{
name: "authenticate with registry token",
@@ -181,7 +188,7 @@ func TestRegistry(t *testing.T) {
Password: authPassword,
RegistryToken: true,
},
golden: "testdata/alpine-310.json.golden",
golden: goldenAlpine310JSON,
},
{
name: "authenticate with 'trivy registry login'",
@@ -193,7 +200,7 @@ func TestRegistry(t *testing.T) {
Password: authPassword,
AuthLogin: true,
},
golden: "testdata/alpine-310.json.golden",
golden: goldenAlpine310JSON,
},
{
name: "amazonlinux 2",
@@ -204,7 +211,7 @@ func TestRegistry(t *testing.T) {
Username: authUsername,
Password: authPassword,
},
golden: "testdata/amazon-2.json.golden",
golden: goldenAmazon2,
},
{
name: "debian buster",
@@ -215,7 +222,7 @@ func TestRegistry(t *testing.T) {
Username: authUsername,
Password: authPassword,
},
golden: "testdata/debian-buster.json.golden",
golden: goldenDebianBuster,
},
{
name: "sad path",
@@ -239,7 +246,7 @@ func TestRegistry(t *testing.T) {
require.NoError(t, err)
// Run Trivy
runTest(t, osArgs, tt.golden, "", types.FormatJSON, runOptions{
runTest(t, osArgs, tt.golden, types.FormatJSON, runOptions{
wantErr: tt.wantErr,
fakeUUID: "3ff14136-e09f-4df9-80ea-%012d",
override: overrideFuncs(overrideUID, func(_ *testing.T, want, _ *types.Report) {

View File

@@ -3,6 +3,7 @@
package integration
import (
"cmp"
"os"
"path/filepath"
"strconv"
@@ -37,14 +38,18 @@ type repoTestArgs struct {
tfExcludeDownloadedModules bool
}
// TestRepository tests `trivy repo` with the local code repositories
// TestRepository tests `trivy repo` with the local code repositories.
//
// NOTE: This test CAN update golden files with the -update flag.
// This is the canonical source for repository/filesystem scanning golden files.
// Golden files generated here may be shared with other tests like TestRepositoryWithOverride,
// TestConfiguration, and TestClientServerWithRedis (when scanning repositories).
func TestRepository(t *testing.T) {
t.Setenv("NUGET_PACKAGES", t.TempDir())
tests := []struct {
name string
args repoTestArgs
golden string
override func(t *testing.T, want, got *types.Report)
name string
args repoTestArgs
golden string
}{
{
name: "gomod",
@@ -52,7 +57,7 @@ func TestRepository(t *testing.T) {
scanner: types.VulnerabilityScanner,
input: "testdata/fixtures/repo/gomod",
},
golden: "testdata/gomod.json.golden",
golden: goldenGoMod,
},
{
name: "gomod with skip files",
@@ -61,7 +66,7 @@ func TestRepository(t *testing.T) {
input: "testdata/fixtures/repo/gomod",
skipFiles: []string{"testdata/fixtures/repo/gomod/submod2/go.mod"},
},
golden: "testdata/gomod-skip.json.golden",
golden: goldenGoModSkip,
},
{
name: "gomod with skip dirs",
@@ -70,7 +75,7 @@ func TestRepository(t *testing.T) {
input: "testdata/fixtures/repo/gomod",
skipDirs: []string{"testdata/fixtures/repo/gomod/submod2"},
},
golden: "testdata/gomod-skip.json.golden",
golden: goldenGoModSkip,
},
{
name: "gomod in series",
@@ -79,7 +84,7 @@ func TestRepository(t *testing.T) {
input: "testdata/fixtures/repo/gomod",
parallel: 1,
},
golden: "testdata/gomod.json.golden",
golden: goldenGoMod,
},
{
name: "gomod with local VEX file",
@@ -88,7 +93,7 @@ func TestRepository(t *testing.T) {
input: "testdata/fixtures/repo/gomod",
vex: "testdata/fixtures/vex/file/openvex.json",
},
golden: "testdata/gomod-vex.json.golden",
golden: goldenGoModVEX,
},
{
name: "gomod with VEX repository",
@@ -97,7 +102,7 @@ func TestRepository(t *testing.T) {
input: "testdata/fixtures/repo/gomod",
vex: "repo",
},
golden: "testdata/gomod-vex.json.golden",
golden: goldenGoModVEX,
},
{
name: "npm",
@@ -106,7 +111,7 @@ func TestRepository(t *testing.T) {
input: "testdata/fixtures/repo/npm",
listAllPkgs: true,
},
golden: "testdata/npm.json.golden",
golden: goldenNPM,
},
{
name: "npm with severity from ubuntu",
@@ -118,7 +123,7 @@ func TestRepository(t *testing.T) {
"ubuntu",
},
},
golden: "testdata/npm-ubuntu-severity.json.golden",
golden: goldenNPMUbuntuSeverity,
},
{
name: "npm with dev deps",
@@ -128,7 +133,7 @@ func TestRepository(t *testing.T) {
listAllPkgs: true,
includeDevDeps: true,
},
golden: "testdata/npm-with-dev.json.golden",
golden: goldenNPMWithDev,
},
{
name: "yarn",
@@ -137,7 +142,7 @@ func TestRepository(t *testing.T) {
input: "testdata/fixtures/repo/yarn",
listAllPkgs: true,
},
golden: "testdata/yarn.json.golden",
golden: goldenYarn,
},
{
name: "pnpm",
@@ -146,7 +151,7 @@ func TestRepository(t *testing.T) {
input: "testdata/fixtures/repo/pnpm",
listAllPkgs: true,
},
golden: "testdata/pnpm.json.golden",
golden: goldenPnpm,
},
{
name: "bun",
@@ -155,7 +160,7 @@ func TestRepository(t *testing.T) {
input: "testdata/fixtures/repo/bun",
listAllPkgs: true,
},
golden: "testdata/bun.json.golden",
golden: goldenBun,
},
{
name: "pip",
@@ -164,7 +169,7 @@ func TestRepository(t *testing.T) {
listAllPkgs: true,
input: "testdata/fixtures/repo/pip",
},
golden: "testdata/pip.json.golden",
golden: goldenPip,
},
{
name: "pipenv",
@@ -173,7 +178,7 @@ func TestRepository(t *testing.T) {
listAllPkgs: true,
input: "testdata/fixtures/repo/pipenv",
},
golden: "testdata/pipenv.json.golden",
golden: goldenPipenv,
},
{
name: "poetry",
@@ -182,7 +187,7 @@ func TestRepository(t *testing.T) {
listAllPkgs: true,
input: "testdata/fixtures/repo/poetry",
},
golden: "testdata/poetry.json.golden",
golden: goldenPoetry,
},
{
name: "uv",
@@ -191,7 +196,7 @@ func TestRepository(t *testing.T) {
listAllPkgs: true,
input: "testdata/fixtures/repo/uv",
},
golden: "testdata/uv.json.golden",
golden: goldenUV,
},
{
name: "pom",
@@ -199,7 +204,7 @@ func TestRepository(t *testing.T) {
scanner: types.VulnerabilityScanner,
input: "testdata/fixtures/repo/pom",
},
golden: "testdata/pom.json.golden",
golden: goldenPom,
},
{
name: "gradle",
@@ -207,7 +212,7 @@ func TestRepository(t *testing.T) {
scanner: types.VulnerabilityScanner,
input: "testdata/fixtures/repo/gradle",
},
golden: "testdata/gradle.json.golden",
golden: goldenGradle,
},
{
name: "sbt",
@@ -215,7 +220,7 @@ func TestRepository(t *testing.T) {
scanner: types.VulnerabilityScanner,
input: "testdata/fixtures/repo/sbt",
},
golden: "testdata/sbt.json.golden",
golden: goldenSBT,
},
{
name: "conan",
@@ -224,7 +229,7 @@ func TestRepository(t *testing.T) {
listAllPkgs: true,
input: "testdata/fixtures/repo/conan",
},
golden: "testdata/conan.json.golden",
golden: goldenConan,
},
{
name: "nuget",
@@ -233,7 +238,7 @@ func TestRepository(t *testing.T) {
listAllPkgs: true,
input: "testdata/fixtures/repo/nuget",
},
golden: "testdata/nuget.json.golden",
golden: goldenNuGet,
},
{
name: "dotnet",
@@ -242,7 +247,7 @@ func TestRepository(t *testing.T) {
listAllPkgs: true,
input: "testdata/fixtures/repo/dotnet",
},
golden: "testdata/dotnet.json.golden",
golden: goldenDotNet,
},
{
name: "packages-props",
@@ -251,7 +256,7 @@ func TestRepository(t *testing.T) {
listAllPkgs: true,
input: "testdata/fixtures/repo/packagesprops",
},
golden: "testdata/packagesprops.json.golden",
golden: goldenPackagesProps,
},
{
name: "swift",
@@ -260,7 +265,7 @@ func TestRepository(t *testing.T) {
listAllPkgs: true,
input: "testdata/fixtures/repo/swift",
},
golden: "testdata/swift.json.golden",
golden: goldenSwift,
},
{
name: "cocoapods",
@@ -269,7 +274,7 @@ func TestRepository(t *testing.T) {
listAllPkgs: true,
input: "testdata/fixtures/repo/cocoapods",
},
golden: "testdata/cocoapods.json.golden",
golden: goldenCocoaPods,
},
{
name: "pubspec.lock",
@@ -278,7 +283,7 @@ func TestRepository(t *testing.T) {
listAllPkgs: true,
input: "testdata/fixtures/repo/pubspec",
},
golden: "testdata/pubspec.lock.json.golden",
golden: goldenPubspecLock,
},
{
name: "mix.lock",
@@ -287,7 +292,7 @@ func TestRepository(t *testing.T) {
listAllPkgs: true,
input: "testdata/fixtures/repo/mixlock",
},
golden: "testdata/mix.lock.json.golden",
golden: goldenMixLock,
},
{
name: "composer.lock",
@@ -296,7 +301,7 @@ func TestRepository(t *testing.T) {
listAllPkgs: true,
input: "testdata/fixtures/repo/composer",
},
golden: "testdata/composer.lock.json.golden",
golden: goldenComposerLock,
},
{
name: "cargo.lock",
@@ -305,20 +310,7 @@ func TestRepository(t *testing.T) {
listAllPkgs: true,
input: "testdata/fixtures/repo/cargo",
},
golden: "testdata/cargo.lock.json.golden",
},
{
name: "multiple lockfiles",
args: repoTestArgs{
scanner: types.VulnerabilityScanner,
input: "testdata/fixtures/repo/trivy-ci-test",
},
golden: "testdata/test-repo.json.golden",
override: func(_ *testing.T, want, _ *types.Report) {
// Clear all metadata as this is a local directory scan without git info
want.ArtifactID = ""
want.Metadata = types.Metadata{}
},
golden: goldenCargoLock,
},
{
name: "installed.json",
@@ -328,7 +320,7 @@ func TestRepository(t *testing.T) {
listAllPkgs: true,
input: "testdata/fixtures/repo/composer-vendor",
},
golden: "testdata/composer.vendor.json.golden",
golden: goldenComposerVendor,
},
{
name: "dockerfile",
@@ -337,7 +329,7 @@ func TestRepository(t *testing.T) {
input: "testdata/fixtures/repo/dockerfile",
namespaces: []string{"testing"},
},
golden: "testdata/dockerfile.json.golden",
golden: goldenDockerfile,
},
{
name: "dockerfile with custom file pattern",
@@ -347,7 +339,7 @@ func TestRepository(t *testing.T) {
namespaces: []string{"testing"},
filePatterns: []string{"dockerfile:Customfile"},
},
golden: "testdata/dockerfile_file_pattern.json.golden",
golden: goldenDockerfileFilePattern,
},
{
name: "dockerfile with custom policies",
@@ -357,7 +349,7 @@ func TestRepository(t *testing.T) {
namespaces: []string{"user"},
input: "testdata/fixtures/repo/custom-policy",
},
golden: "testdata/dockerfile-custom-policies.json.golden",
golden: goldenDockerfileCustomPolicies,
},
{
name: "tarball helm chart scanning with builtin policies",
@@ -365,7 +357,7 @@ func TestRepository(t *testing.T) {
scanner: types.MisconfigScanner,
input: "testdata/fixtures/repo/helm",
},
golden: "testdata/helm.json.golden",
golden: goldenHelm,
},
{
name: "helm chart directory scanning with builtin policies",
@@ -373,7 +365,7 @@ func TestRepository(t *testing.T) {
scanner: types.MisconfigScanner,
input: "testdata/fixtures/repo/helm_testchart",
},
golden: "testdata/helm_testchart.json.golden",
golden: goldenHelmTestChart,
},
{
name: "helm chart directory scanning with value overrides using set",
@@ -382,7 +374,7 @@ func TestRepository(t *testing.T) {
input: "testdata/fixtures/repo/helm_testchart",
helmSet: []string{"securityContext.runAsUser=0"},
},
golden: "testdata/helm_testchart.overridden.json.golden",
golden: goldenHelmTestChartOverridden,
},
{
name: "helm chart directory scanning with value overrides using value file",
@@ -391,7 +383,7 @@ func TestRepository(t *testing.T) {
input: "testdata/fixtures/repo/helm_testchart",
helmValuesFile: []string{"testdata/fixtures/repo/helm_values/values.yaml"},
},
golden: "testdata/helm_testchart.overridden.json.golden",
golden: goldenHelmTestChartOverridden,
},
{
name: "helm chart directory scanning with builtin policies and non string Chart name",
@@ -399,7 +391,7 @@ func TestRepository(t *testing.T) {
scanner: types.MisconfigScanner,
input: "testdata/fixtures/repo/helm_badname",
},
golden: "testdata/helm_badname.json.golden",
golden: goldenHelmBadName,
},
{
name: "terraform config with remote module",
@@ -407,7 +399,7 @@ func TestRepository(t *testing.T) {
scanner: types.MisconfigScanner,
input: "testdata/fixtures/repo/terraform/remote-module",
},
golden: "testdata/terraform-remote-module.json.golden",
golden: goldenTerraformRemoteModule,
},
{
name: "terraform config with remote submodule",
@@ -415,7 +407,7 @@ func TestRepository(t *testing.T) {
scanner: types.MisconfigScanner,
input: "testdata/fixtures/repo/terraform/remote-submodule",
},
golden: "testdata/terraform-remote-submodule.json.golden",
golden: goldenTerraformRemoteSubmodule,
},
{
name: "terraform config with remote module in child local module",
@@ -423,7 +415,7 @@ func TestRepository(t *testing.T) {
scanner: types.MisconfigScanner,
input: "testdata/fixtures/repo/terraform/remote-module-in-child",
},
golden: "testdata/terraform-remote-module-in-child.json.golden",
golden: goldenTerraformRemoteModuleInChild,
},
{
name: "exclude misconfigurations for remote module",
@@ -432,7 +424,7 @@ func TestRepository(t *testing.T) {
input: "testdata/fixtures/repo/terraform/remote-module",
tfExcludeDownloadedModules: true,
},
golden: "testdata/terraform-exclude-misconfs-remote-module.json.golden",
golden: goldenTerraformExcludeMisconfigsRemoteModule,
},
{
name: "module from Terraform registry",
@@ -440,7 +432,7 @@ func TestRepository(t *testing.T) {
scanner: types.MisconfigScanner,
input: "testdata/fixtures/repo/terraform/opentofu-registry",
},
golden: "testdata/terraform-terraform-registry.json.golden",
golden: goldenTerraformTerraformRegistry,
},
{
name: "module from OpenTofu registry",
@@ -448,7 +440,7 @@ func TestRepository(t *testing.T) {
scanner: types.MisconfigScanner,
input: "testdata/fixtures/repo/terraform/opentofu-registry",
},
golden: "testdata/terraform-opentofu-registry.json.golden",
golden: goldenTerraformOpenTofuRegistry,
},
{
name: "secrets",
@@ -457,7 +449,7 @@ func TestRepository(t *testing.T) {
input: "testdata/fixtures/repo/secrets",
secretConfig: "testdata/fixtures/repo/secrets/trivy-secret.yaml",
},
golden: "testdata/secrets.json.golden",
golden: goldenSecrets,
},
{
name: "conda generating CycloneDX SBOM",
@@ -466,7 +458,7 @@ func TestRepository(t *testing.T) {
format: "cyclonedx",
input: "testdata/fixtures/repo/conda",
},
golden: "testdata/conda-cyclonedx.json.golden",
golden: goldenCondaCycloneDX,
},
{
name: "conda environment.yaml generating CycloneDX SBOM",
@@ -475,7 +467,7 @@ func TestRepository(t *testing.T) {
format: "cyclonedx",
input: "testdata/fixtures/repo/conda-environment",
},
golden: "testdata/conda-environment-cyclonedx.json.golden",
golden: goldenCondaEnvironmentCycloneDX,
},
{
name: "pom.xml generating CycloneDX SBOM (with vulnerabilities)",
@@ -485,7 +477,7 @@ func TestRepository(t *testing.T) {
format: "cyclonedx",
input: "testdata/fixtures/repo/pom",
},
golden: "testdata/pom-cyclonedx.json.golden",
golden: goldenPomCycloneDX,
},
{
name: "conda generating SPDX SBOM",
@@ -494,34 +486,7 @@ func TestRepository(t *testing.T) {
format: "spdx-json",
input: "testdata/fixtures/repo/conda",
},
golden: "testdata/conda-spdx.json.golden",
},
{
name: "gomod with fs subcommand",
args: repoTestArgs{
command: "fs",
scanner: types.VulnerabilityScanner,
input: "testdata/fixtures/repo/gomod",
skipFiles: []string{"testdata/fixtures/repo/gomod/submod2/go.mod"},
},
golden: "testdata/gomod-skip.json.golden",
override: func(_ *testing.T, want, _ *types.Report) {
want.ArtifactType = ftypes.TypeFilesystem
},
},
{
name: "dockerfile with fs subcommand and an alias scanner",
args: repoTestArgs{
command: "fs",
scanner: "config", // for backward compatibility
policyPaths: []string{"testdata/fixtures/repo/custom-policy/policy"},
namespaces: []string{"user"},
input: "testdata/fixtures/repo/custom-policy",
},
golden: "testdata/dockerfile-custom-policies.json.golden",
override: func(_ *testing.T, want, _ *types.Report) {
want.ArtifactType = ftypes.TypeFilesystem
},
golden: goldenCondaSPDX,
},
{
name: "julia generating SPDX SBOM",
@@ -530,7 +495,15 @@ func TestRepository(t *testing.T) {
format: "spdx-json",
input: "testdata/fixtures/repo/julia",
},
golden: "testdata/julia-spdx.json.golden",
golden: goldenJuliaSPDX,
},
{
name: "multiple lockfiles",
args: repoTestArgs{
scanner: types.VulnerabilityScanner,
input: "https://github.com/knqyf263/trivy-ci-test",
},
golden: goldenTestRepo,
},
}
@@ -546,6 +519,73 @@ func TestRepository(t *testing.T) {
// Disable Go license detection
t.Setenv("GOPATH", cacheDir)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
command := cmp.Or(tt.args.command, "repo")
format := cmp.Or(tt.args.format, types.FormatJSON)
osArgs := buildArgs(t, cacheDir, command, format, tt.args)
runTest(t, osArgs, tt.golden, format, runOptions{
fakeUUID: "3ff14136-e09f-4df9-80ea-%012d",
override: nil, // Do not use overrides - golden files are generated from this test as the canonical source
})
})
}
}
// TestRepositoryWithOverride tests `trivy repo` with override functions for specific edge cases.
//
// IMPORTANT: Golden files used in this test cannot be updated with the -update flag
// because the golden files are shared with TestRepository.
// If golden files need to be updated, they should be generated from TestRepository.
//
// All golden files used in TestRepositoryWithOverride MUST also be used in TestRepository
// to ensure they can be properly updated when needed.
func TestRepositoryWithOverride(t *testing.T) {
if *update {
t.Skipf("Skipping TestRepositoryWithOverride when -update flag is set. Golden files should be updated via TestRepository.")
}
t.Setenv("NUGET_PACKAGES", t.TempDir())
tests := []struct {
name string
args repoTestArgs
golden string
override func(t *testing.T, want, got *types.Report)
}{
{
name: "gomod with fs subcommand",
args: repoTestArgs{
command: "fs",
scanner: types.VulnerabilityScanner,
input: "testdata/fixtures/repo/gomod",
skipFiles: []string{"testdata/fixtures/repo/gomod/submod2/go.mod"},
},
golden: goldenGoModSkip,
override: func(_ *testing.T, want, _ *types.Report) {
want.ArtifactType = ftypes.TypeFilesystem
},
},
{
name: "dockerfile with fs subcommand and an alias scanner",
args: repoTestArgs{
command: "fs",
scanner: "config", // for backward compatibility
policyPaths: []string{"testdata/fixtures/repo/custom-policy/policy"},
namespaces: []string{"user"},
input: "testdata/fixtures/repo/custom-policy",
},
golden: goldenDockerfileCustomPolicies,
override: func(_ *testing.T, want, _ *types.Report) {
want.ArtifactType = ftypes.TypeFilesystem
},
},
}
// Set up testing DB
cacheDir := initDB(t)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
command := "repo"
@@ -560,9 +600,9 @@ func TestRepository(t *testing.T) {
osArgs := buildArgs(t, cacheDir, command, format, tt.args)
runTest(t, osArgs, tt.golden, "", format, runOptions{
runTest(t, osArgs, tt.golden, format, runOptions{
fakeUUID: "3ff14136-e09f-4df9-80ea-%012d",
override: tt.override,
override: overrideFuncs(overrideUID, tt.override),
})
})
}

View File

@@ -13,6 +13,11 @@ import (
"github.com/aquasecurity/trivy/pkg/types"
)
// TestSBOM tests scanning SBOM files (CycloneDX, SPDX).
//
// NOTE: This test CAN update golden files with the -update flag because the golden files
// used here are not shared with other tests. These SBOM-specific golden files are unique
// to this test and should be updated here.
func TestSBOM(t *testing.T) {
type args struct {
input string
@@ -21,41 +26,10 @@ func TestSBOM(t *testing.T) {
scanners string
}
tests := []struct {
name string
args args
golden string
fakeUUID string
override OverrideFunc
name string
args args
golden string
}{
{
name: "centos7 cyclonedx",
args: args{
input: "testdata/fixtures/sbom/centos-7-cyclonedx.json",
format: "json",
artifactType: "cyclonedx",
},
golden: "testdata/centos-7.json.golden",
fakeUUID: "3ff14136-e09f-4df9-80ea-%012d",
override: func(t *testing.T, want, got *types.Report) {
want.ArtifactName = "testdata/fixtures/sbom/centos-7-cyclonedx.json"
want.ArtifactType = ftypes.TypeCycloneDX
require.Len(t, got.Results, 1)
want.Results[0].Target = "testdata/fixtures/sbom/centos-7-cyclonedx.json (centos 7.6.1810)"
require.Len(t, got.Results[0].Vulnerabilities, 3)
want.Results[0].Vulnerabilities[0].PkgIdentifier.BOMRef = "pkg:rpm/centos/bash@4.2.46-31.el7?arch=x86_64&distro=centos-7.6.1810"
want.Results[0].Vulnerabilities[1].PkgIdentifier.BOMRef = "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810"
want.Results[0].Vulnerabilities[2].PkgIdentifier.BOMRef = "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810"
// SBOM file doesn't contain info about layers
want.Metadata.Size = 0
want.Metadata.Layers = nil
// SBOM parsing consumes UUIDs #1-#4 for components, so ReportID becomes #5
want.ReportID = "3ff14136-e09f-4df9-80ea-000000000005"
},
},
{
name: "fluentd-multiple-lockfiles cyclonedx",
args: args{
@@ -63,8 +37,7 @@ func TestSBOM(t *testing.T) {
format: "json",
artifactType: "cyclonedx",
},
golden: "testdata/fluentd-multiple-lockfiles.json.golden",
fakeUUID: "3ff14136-e09f-4df9-80ea-%012d",
golden: goldenFluentdMultipleLockfiles,
},
{
name: "scan SBOM into SBOM",
@@ -73,8 +46,7 @@ func TestSBOM(t *testing.T) {
format: "cyclonedx",
artifactType: "cyclonedx",
},
fakeUUID: "3ff14136-e09f-4df9-80ea-%012d",
golden: "testdata/fluentd-multiple-lockfiles-short.cdx.json.golden",
golden: goldenFluentdMultipleLockfilesShortCDX,
},
{
name: "minikube KBOM",
@@ -83,85 +55,7 @@ func TestSBOM(t *testing.T) {
format: "json",
artifactType: "cyclonedx",
},
golden: "testdata/minikube-kbom.json.golden",
fakeUUID: "3ff14136-e09f-4df9-80ea-%012d",
},
{
name: "centos7 in in-toto attestation",
args: args{
input: "testdata/fixtures/sbom/centos-7-cyclonedx.intoto.jsonl",
format: "json",
artifactType: "cyclonedx",
},
golden: "testdata/centos-7.json.golden",
fakeUUID: "3ff14136-e09f-4df9-80ea-%012d",
override: func(t *testing.T, want, got *types.Report) {
want.ArtifactName = "testdata/fixtures/sbom/centos-7-cyclonedx.intoto.jsonl"
want.ArtifactType = ftypes.TypeCycloneDX
require.Len(t, got.Results, 1)
want.Results[0].Target = "testdata/fixtures/sbom/centos-7-cyclonedx.intoto.jsonl (centos 7.6.1810)"
require.Len(t, got.Results[0].Vulnerabilities, 3)
want.Results[0].Vulnerabilities[0].PkgIdentifier.BOMRef = "pkg:rpm/centos/bash@4.2.46-31.el7?arch=x86_64&distro=centos-7.6.1810"
want.Results[0].Vulnerabilities[1].PkgIdentifier.BOMRef = "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810"
want.Results[0].Vulnerabilities[2].PkgIdentifier.BOMRef = "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810"
// SBOM file doesn't contain info about layers
want.Metadata.Size = 0
want.Metadata.Layers = nil
// SBOM parsing consumes UUIDs #1-#4 for components, so ReportID becomes #5
want.ReportID = "3ff14136-e09f-4df9-80ea-000000000005"
},
},
{
name: "centos7 spdx tag-value",
args: args{
input: "testdata/fixtures/sbom/centos-7-spdx.txt",
format: "json",
artifactType: "spdx",
},
golden: "testdata/centos-7.json.golden",
fakeUUID: "3ff14136-e09f-4df9-80ea-%012d",
override: func(t *testing.T, want, got *types.Report) {
want.ArtifactName = "testdata/fixtures/sbom/centos-7-spdx.txt"
want.ArtifactType = ftypes.TypeSPDX
require.Len(t, got.Results, 1)
want.Results[0].Target = "testdata/fixtures/sbom/centos-7-spdx.txt (centos 7.6.1810)"
// SBOM file doesn't contain info about layers
want.Metadata.Size = 0
want.Metadata.Layers = nil
// SBOM parsing consumes UUIDs #1-#4 for components, so ReportID becomes #5
want.ReportID = "3ff14136-e09f-4df9-80ea-000000000005"
},
},
{
name: "centos7 spdx json",
args: args{
input: "testdata/fixtures/sbom/centos-7-spdx.json",
format: "json",
artifactType: "spdx",
},
golden: "testdata/centos-7.json.golden",
fakeUUID: "3ff14136-e09f-4df9-80ea-%012d",
override: func(t *testing.T, want, got *types.Report) {
want.ArtifactName = "testdata/fixtures/sbom/centos-7-spdx.json"
want.ArtifactType = ftypes.TypeSPDX
require.Len(t, got.Results, 1)
want.Results[0].Target = "testdata/fixtures/sbom/centos-7-spdx.json (centos 7.6.1810)"
// SBOM file doesn't contain info about layers
want.Metadata.Size = 0
want.Metadata.Layers = nil
// SBOM parsing consumes UUIDs #1-#4 for components, so ReportID becomes #5
want.ReportID = "3ff14136-e09f-4df9-80ea-000000000005"
},
golden: goldenMinikubeKBOM,
},
{
name: "license check cyclonedx json",
@@ -171,8 +65,7 @@ func TestSBOM(t *testing.T) {
artifactType: "cyclonedx",
scanners: "license",
},
golden: "testdata/license-cyclonedx.json.golden",
fakeUUID: "3ff14136-e09f-4df9-80ea-%012d",
golden: goldenLicenseCycloneDX,
},
}
@@ -187,9 +80,9 @@ func TestSBOM(t *testing.T) {
}
osArgs := []string{
"sbom",
"--cache-dir",
cacheDir,
"sbom",
"-q",
"--skip-db-update",
"--format",
@@ -197,20 +90,161 @@ func TestSBOM(t *testing.T) {
"--scanners",
scanners,
"--list-all-pkgs=false",
tt.args.input,
}
// Set up the output file
outputFile := filepath.Join(t.TempDir(), "output.json")
if *update {
outputFile = tt.golden
}
osArgs = append(osArgs, "--output", outputFile, tt.args.input)
// Run "trivy sbom"
runTest(t, osArgs, tt.golden, outputFile, types.Format(tt.args.format), runOptions{
runTest(t, osArgs, tt.golden, types.Format(tt.args.format), runOptions{
fakeUUID: "3ff14136-e09f-4df9-80ea-%012d",
override: nil, // Do not use overrides - golden files are generated from this test as the canonical source
})
})
}
}
// TestSBOMEquivalence tests that scanning an SBOM produces equivalent results to scanning the original artifact.
//
// This test verifies that scanning an image through SBOM:
//
// trivy image centos:7 -f cyclonedx -o centos7.cdx.json && trivy sbom centos7.cdx.json
//
// produces the same vulnerability results as direct image scanning:
//
// trivy image centos:7
//
// IMPORTANT: Golden files used in this test cannot be updated with the -update flag
// because the golden files are shared with TestTar.
// If golden files need to be updated, they should be generated from TestTar.
//
// All golden files used in TestSBOMEquivalence MUST also be used in TestTar
// to ensure they can be properly updated when needed.
func TestSBOMEquivalence(t *testing.T) {
if *update {
t.Skipf("Skipping TestSBOMEquivalence when -update flag is set. Golden files should be updated via TestTar.")
}
type args struct {
input string
format string
artifactType string
}
tests := []struct {
name string
args args
golden string
override OverrideFunc
}{
{
name: "centos7 cyclonedx",
args: args{
input: "testdata/fixtures/sbom/centos-7-cyclonedx.json",
format: "json",
artifactType: "cyclonedx",
},
golden: goldenCentOS7,
override: func(t *testing.T, want, got *types.Report) {
want.ArtifactName = "testdata/fixtures/sbom/centos-7-cyclonedx.json"
want.ArtifactType = ftypes.TypeCycloneDX
require.Len(t, got.Results, 1)
want.Results[0].Target = "testdata/fixtures/sbom/centos-7-cyclonedx.json (centos 7.6.1810)"
require.Len(t, got.Results[0].Vulnerabilities, 3)
want.Results[0].Vulnerabilities[0].PkgIdentifier.BOMRef = "pkg:rpm/centos/bash@4.2.46-31.el7?arch=x86_64&distro=centos-7.6.1810"
want.Results[0].Vulnerabilities[1].PkgIdentifier.BOMRef = "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810"
want.Results[0].Vulnerabilities[2].PkgIdentifier.BOMRef = "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810"
// SBOM parsing consumes UUIDs #1-#4 for components, so ReportID becomes #5
want.ReportID = "3ff14136-e09f-4df9-80ea-000000000005"
},
},
{
name: "centos7 spdx tag-value",
args: args{
input: "testdata/fixtures/sbom/centos-7-spdx.txt",
format: "json",
artifactType: "spdx",
},
golden: goldenCentOS7,
override: func(t *testing.T, want, got *types.Report) {
want.ArtifactName = "testdata/fixtures/sbom/centos-7-spdx.txt"
want.ArtifactType = ftypes.TypeSPDX
require.Len(t, got.Results, 1)
want.Results[0].Target = "testdata/fixtures/sbom/centos-7-spdx.txt (centos 7.6.1810)"
// SBOM parsing consumes UUIDs #1-#4 for components, so ReportID becomes #5
want.ReportID = "3ff14136-e09f-4df9-80ea-000000000005"
},
},
{
name: "centos7 spdx json",
args: args{
input: "testdata/fixtures/sbom/centos-7-spdx.json",
format: "json",
artifactType: "spdx",
},
golden: goldenCentOS7,
override: func(t *testing.T, want, got *types.Report) {
want.ArtifactName = "testdata/fixtures/sbom/centos-7-spdx.json"
want.ArtifactType = ftypes.TypeSPDX
require.Len(t, got.Results, 1)
want.Results[0].Target = "testdata/fixtures/sbom/centos-7-spdx.json (centos 7.6.1810)"
// SBOM parsing consumes UUIDs #1-#4 for components, so ReportID becomes #5
want.ReportID = "3ff14136-e09f-4df9-80ea-000000000005"
},
},
{
name: "centos7 in in-toto attestation",
args: args{
input: "testdata/fixtures/sbom/centos-7-cyclonedx.intoto.jsonl",
format: "json",
artifactType: "cyclonedx",
},
golden: goldenCentOS7,
override: func(t *testing.T, want, got *types.Report) {
want.ArtifactName = "testdata/fixtures/sbom/centos-7-cyclonedx.intoto.jsonl"
want.ArtifactType = ftypes.TypeCycloneDX
require.Len(t, got.Results, 1)
want.Results[0].Target = "testdata/fixtures/sbom/centos-7-cyclonedx.intoto.jsonl (centos 7.6.1810)"
require.Len(t, got.Results[0].Vulnerabilities, 3)
want.Results[0].Vulnerabilities[0].PkgIdentifier.BOMRef = "pkg:rpm/centos/bash@4.2.46-31.el7?arch=x86_64&distro=centos-7.6.1810"
want.Results[0].Vulnerabilities[1].PkgIdentifier.BOMRef = "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810"
want.Results[0].Vulnerabilities[2].PkgIdentifier.BOMRef = "pkg:rpm/centos/openssl-libs@1.0.2k-16.el7?arch=x86_64&epoch=1&distro=centos-7.6.1810"
// SBOM parsing consumes UUIDs #1-#4 for components, so ReportID becomes #5
want.ReportID = "3ff14136-e09f-4df9-80ea-000000000005"
},
},
}
// Set up testing DB
cacheDir := initDB(t)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
osArgs := []string{
"sbom",
"--cache-dir",
cacheDir,
"-q",
"--skip-db-update",
"--format",
tt.args.format,
"--scanners",
"vuln",
"--list-all-pkgs=false",
tt.args.input,
}
// Run "trivy sbom"
runTest(t, osArgs, tt.golden, types.Format(tt.args.format), runOptions{
override: overrideFuncs(overrideSBOMReport, overrideUID, tt.override),
fakeUUID: tt.fakeUUID,
fakeUUID: "3ff14136-e09f-4df9-80ea-%012d",
})
})
}
@@ -220,6 +254,10 @@ func overrideSBOMReport(_ *testing.T, want, got *types.Report) {
want.ArtifactID = ""
want.Metadata.ImageConfig = v1.ConfigFile{}
// SBOM file doesn't contain info about layers
want.Metadata.Size = 0
want.Metadata.Layers = nil
// when running on Windows FS
got.ArtifactName = filepath.ToSlash(filepath.Clean(got.ArtifactName))
for i, result := range got.Results {

View File

@@ -14,6 +14,12 @@ import (
"github.com/aquasecurity/trivy/pkg/types"
)
// TestTar tests `trivy image --input` with tar archives of container images.
//
// NOTE: This test CAN update golden files with the -update flag.
// This is the canonical source for container image scanning golden files.
// Golden files generated here may be shared with other tests like TestClientServer,
// TestDockerEngine, TestRegistry, and TestClientServerWithRedis (when scanning images).
func TestTar(t *testing.T) {
type args struct {
IgnoreUnfixed bool
@@ -24,13 +30,11 @@ func TestTar(t *testing.T) {
SkipDirs []string
SkipFiles []string
DetectionPriority ftypes.DetectionPriority
Distro string
}
tests := []struct {
name string
args args
golden string
override func(t *testing.T, want, got *types.Report)
name string
args args
golden string
}{
{
name: "alpine 3.9",
@@ -38,7 +42,7 @@ func TestTar(t *testing.T) {
Format: types.FormatJSON,
Input: "testdata/fixtures/images/alpine-39.tar.gz",
},
golden: "testdata/alpine-39.json.golden",
golden: goldenAlpine39,
},
{
name: "alpine 3.9 with skip dirs",
@@ -49,7 +53,7 @@ func TestTar(t *testing.T) {
"/etc",
},
},
golden: "testdata/alpine-39-skip.json.golden",
golden: goldenAlpine39Skip,
},
{
name: "alpine 3.9 with skip files",
@@ -133,7 +137,7 @@ func TestTar(t *testing.T) {
"/etc/udhcpd.conf",
},
},
golden: "testdata/alpine-39-skip.json.golden",
golden: goldenAlpine39Skip,
},
{
name: "alpine 3.9 with high and critical severity",
@@ -146,7 +150,7 @@ func TestTar(t *testing.T) {
Format: types.FormatJSON,
Input: "testdata/fixtures/images/alpine-39.tar.gz",
},
golden: "testdata/alpine-39-high-critical.json.golden",
golden: goldenAlpine39HighCritical,
},
{
name: "alpine 3.9 with .trivyignore",
@@ -159,20 +163,7 @@ func TestTar(t *testing.T) {
Format: types.FormatJSON,
Input: "testdata/fixtures/images/alpine-39.tar.gz",
},
golden: "testdata/alpine-39-ignore-cveids.json.golden",
},
{
name: "alpine 3.9 as alpine 3.10",
args: args{
Format: types.FormatJSON,
Input: "testdata/fixtures/images/alpine-39.tar.gz",
Distro: "alpine/3.10",
},
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)"
},
golden: "testdata/alpine-39.json.golden",
golden: goldenAlpine39IgnoreCVEIDs,
},
{
name: "alpine 3.10",
@@ -180,7 +171,7 @@ func TestTar(t *testing.T) {
Format: types.FormatJSON,
Input: "testdata/fixtures/images/alpine-310.tar.gz",
},
golden: "testdata/alpine-310.json.golden",
golden: goldenAlpine310JSON,
},
{
name: "alpine distroless",
@@ -188,7 +179,7 @@ func TestTar(t *testing.T) {
Format: types.FormatJSON,
Input: "testdata/fixtures/images/alpine-distroless.tar.gz",
},
golden: "testdata/alpine-distroless.json.golden",
golden: goldenAlpineDistroless,
},
{
name: "amazon linux 1",
@@ -196,7 +187,7 @@ func TestTar(t *testing.T) {
Format: types.FormatJSON,
Input: "testdata/fixtures/images/amazon-1.tar.gz",
},
golden: "testdata/amazon-1.json.golden",
golden: goldenAmazon1,
},
{
name: "amazon linux 2",
@@ -204,7 +195,7 @@ func TestTar(t *testing.T) {
Format: types.FormatJSON,
Input: "testdata/fixtures/images/amazon-2.tar.gz",
},
golden: "testdata/amazon-2.json.golden",
golden: goldenAmazon2,
},
{
name: "debian buster/10",
@@ -212,7 +203,7 @@ func TestTar(t *testing.T) {
Format: types.FormatJSON,
Input: "testdata/fixtures/images/debian-buster.tar.gz",
},
golden: "testdata/debian-buster.json.golden",
golden: goldenDebianBuster,
},
{
name: "debian buster/10 with --ignore-unfixed option",
@@ -221,7 +212,7 @@ func TestTar(t *testing.T) {
Format: types.FormatJSON,
Input: "testdata/fixtures/images/debian-buster.tar.gz",
},
golden: "testdata/debian-buster-ignore-unfixed.json.golden",
golden: goldenDebianBusterIgnoreUnfixed,
},
{
name: "debian stretch/9",
@@ -229,7 +220,7 @@ func TestTar(t *testing.T) {
Format: types.FormatJSON,
Input: "testdata/fixtures/images/debian-stretch.tar.gz",
},
golden: "testdata/debian-stretch.json.golden",
golden: goldenDebianStretch,
},
{
name: "ubuntu 18.04",
@@ -237,7 +228,7 @@ func TestTar(t *testing.T) {
Format: types.FormatJSON,
Input: "testdata/fixtures/images/ubuntu-1804.tar.gz",
},
golden: "testdata/ubuntu-1804.json.golden",
golden: goldenUbuntu1804,
},
{
name: "ubuntu 18.04 with --ignore-unfixed option",
@@ -246,7 +237,7 @@ func TestTar(t *testing.T) {
Format: types.FormatJSON,
Input: "testdata/fixtures/images/ubuntu-1804.tar.gz",
},
golden: "testdata/ubuntu-1804-ignore-unfixed.json.golden",
golden: goldenUbuntu1804IgnoreUnfixed,
},
{
name: "centos 7",
@@ -254,7 +245,7 @@ func TestTar(t *testing.T) {
Format: types.FormatJSON,
Input: "testdata/fixtures/images/centos-7.tar.gz",
},
golden: "testdata/centos-7.json.golden",
golden: goldenCentOS7,
},
{
name: "centos 7 with --ignore-unfixed option",
@@ -263,7 +254,7 @@ func TestTar(t *testing.T) {
Format: types.FormatJSON,
Input: "testdata/fixtures/images/centos-7.tar.gz",
},
golden: "testdata/centos-7-ignore-unfixed.json.golden",
golden: goldenCentOS7IgnoreUnfixed,
},
{
name: "centos 7 with medium severity",
@@ -273,7 +264,7 @@ func TestTar(t *testing.T) {
Format: types.FormatJSON,
Input: "testdata/fixtures/images/centos-7.tar.gz",
},
golden: "testdata/centos-7-medium.json.golden",
golden: goldenCentOS7Medium,
},
{
name: "centos 6",
@@ -281,7 +272,7 @@ func TestTar(t *testing.T) {
Format: types.FormatJSON,
Input: "testdata/fixtures/images/centos-6.tar.gz",
},
golden: "testdata/centos-6.json.golden",
golden: goldenCentOS6,
},
{
name: "ubi 7",
@@ -289,7 +280,7 @@ func TestTar(t *testing.T) {
Format: types.FormatJSON,
Input: "testdata/fixtures/images/ubi-7.tar.gz",
},
golden: "testdata/ubi-7.json.golden",
golden: goldenUBI7,
},
{
name: "ubi 7 with comprehensive priority",
@@ -298,7 +289,7 @@ func TestTar(t *testing.T) {
Input: "testdata/fixtures/images/ubi-7.tar.gz",
DetectionPriority: ftypes.PriorityComprehensive,
},
golden: "testdata/ubi-7-comprehensive.json.golden",
golden: goldenUBI7Comprehensive,
},
{
name: "almalinux 8",
@@ -306,7 +297,7 @@ func TestTar(t *testing.T) {
Format: types.FormatJSON,
Input: "testdata/fixtures/images/almalinux-8.tar.gz",
},
golden: "testdata/almalinux-8.json.golden",
golden: goldenAlmaLinux8,
},
{
name: "rocky linux 8",
@@ -314,7 +305,7 @@ func TestTar(t *testing.T) {
Format: types.FormatJSON,
Input: "testdata/fixtures/images/rockylinux-8.tar.gz",
},
golden: "testdata/rockylinux-8.json.golden",
golden: goldenRockyLinux8,
},
{
name: "distroless base",
@@ -322,7 +313,7 @@ func TestTar(t *testing.T) {
Format: types.FormatJSON,
Input: "testdata/fixtures/images/distroless-base.tar.gz",
},
golden: "testdata/distroless-base.json.golden",
golden: goldenDistrolessBase,
},
{
name: "distroless python27",
@@ -330,7 +321,7 @@ func TestTar(t *testing.T) {
Format: types.FormatJSON,
Input: "testdata/fixtures/images/distroless-python27.tar.gz",
},
golden: "testdata/distroless-python27.json.golden",
golden: goldenDistrolessPython27,
},
{
name: "oracle linux 8",
@@ -338,7 +329,7 @@ func TestTar(t *testing.T) {
Format: types.FormatJSON,
Input: "testdata/fixtures/images/oraclelinux-8.tar.gz",
},
golden: "testdata/oraclelinux-8.json.golden",
golden: goldenOracleLinux8,
},
{
name: "opensuse leap 15.1",
@@ -346,7 +337,7 @@ func TestTar(t *testing.T) {
Format: types.FormatJSON,
Input: "testdata/fixtures/images/opensuse-leap-151.tar.gz",
},
golden: "testdata/opensuse-leap-151.json.golden",
golden: goldenOpenSUSELeap151,
},
{
name: "opensuse tumbleweed",
@@ -354,7 +345,7 @@ func TestTar(t *testing.T) {
Format: types.FormatJSON,
Input: "testdata/fixtures/images/opensuse-tumbleweed.tar.gz",
},
golden: "testdata/opensuse-tumbleweed.json.golden",
golden: goldenOpenSUSETumbleweed,
},
{
name: "sle micro rancher 5.4",
@@ -362,7 +353,7 @@ func TestTar(t *testing.T) {
Format: types.FormatJSON,
Input: "testdata/fixtures/images/sle-micro-rancher-5.4_ndb.tar.gz",
},
golden: "testdata/sl-micro-rancher5.4.json.golden",
golden: goldenSLMicroRancher54,
},
{
name: "photon 3.0",
@@ -370,7 +361,7 @@ func TestTar(t *testing.T) {
Format: types.FormatJSON,
Input: "testdata/fixtures/images/photon-30.tar.gz",
},
golden: "testdata/photon-30.json.golden",
golden: goldenPhoton30,
},
{
name: "CBL-Mariner 1.0",
@@ -378,7 +369,7 @@ func TestTar(t *testing.T) {
Format: types.FormatJSON,
Input: "testdata/fixtures/images/mariner-1.0.tar.gz",
},
golden: "testdata/mariner-1.0.json.golden",
golden: goldenMariner10,
},
{
name: "busybox with Cargo.lock integration",
@@ -386,7 +377,7 @@ func TestTar(t *testing.T) {
Format: types.FormatJSON,
Input: "testdata/fixtures/images/busybox-with-lockfile.tar.gz",
},
golden: "testdata/busybox-with-lockfile.json.golden",
golden: goldenBusyboxWithLockfile,
},
{
name: "fluentd with RubyGems",
@@ -395,7 +386,7 @@ func TestTar(t *testing.T) {
Format: types.FormatJSON,
Input: "testdata/fixtures/images/fluentd-multiple-lockfiles.tar.gz",
},
golden: "testdata/fluentd-gems.json.golden",
golden: goldenFluentdGems,
},
}
@@ -450,12 +441,70 @@ func TestTar(t *testing.T) {
osArgs = append(osArgs, "--detection-priority", string(tt.args.DetectionPriority))
}
if tt.args.Distro != "" {
osArgs = append(osArgs, "--distro", tt.args.Distro)
// Run Trivy
runTest(t, osArgs, tt.golden, tt.args.Format, runOptions{
fakeUUID: "3ff14136-e09f-4df9-80ea-%012d",
override: nil, // Do not use overrides - golden files are generated from this test as the canonical source
})
})
}
}
// TestTarWithOverride tests container image scanning with overrides applied.
//
// Golden files are shared with TestTar.
func TestTarWithOverride(t *testing.T) {
if *update {
t.Skipf("Skipping TestTarWithOverride when -update flag is set. Golden files should be updated via TestTar.")
}
type args struct {
input string
distro string
}
tests := []struct {
name string
args args
golden string
override OverrideFunc
}{
{
name: "alpine 3.9 as alpine 3.10",
args: args{
input: "testdata/fixtures/images/alpine-39.tar.gz",
distro: "alpine/3.10",
},
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)"
},
golden: goldenAlpine39,
},
}
// Set up testing DB
cacheDir := initDB(t)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
osArgs := []string{
"--cache-dir",
cacheDir,
"image",
"--format",
"json",
"--skip-db-update",
"--list-all-pkgs=false",
"--input",
tt.args.input,
}
if tt.args.distro != "" {
osArgs = append(osArgs, "--distro", tt.args.distro)
}
// Run Trivy
runTest(t, osArgs, tt.golden, "", tt.args.Format, runOptions{
runTest(t, osArgs, tt.golden, types.FormatJSON, runOptions{
fakeUUID: "3ff14136-e09f-4df9-80ea-%012d",
override: overrideFuncs(overrideUID, tt.override),
})
@@ -463,7 +512,14 @@ func TestTar(t *testing.T) {
}
}
// TestTarWithEnv tests container image scanning with environment variables.
//
// Golden files are shared with TestTar.
func TestTarWithEnv(t *testing.T) {
if *update {
t.Skipf("Skipping TestTarWithEnv when -update flag is set. Golden files should be updated via TestTar.")
}
type args struct {
IgnoreUnfixed bool
Severity []string
@@ -485,7 +541,7 @@ func TestTarWithEnv(t *testing.T) {
"/etc",
},
},
golden: "testdata/alpine-39-skip.json.golden",
golden: goldenAlpine39Skip,
},
{
name: "alpine 3.9 with high and critical severity",
@@ -498,7 +554,7 @@ func TestTarWithEnv(t *testing.T) {
Format: "json",
Input: "testdata/fixtures/images/alpine-39.tar.gz",
},
golden: "testdata/alpine-39-high-critical.json.golden",
golden: goldenAlpine39HighCritical,
},
{
name: "debian buster/10 with --ignore-unfixed option",
@@ -507,7 +563,7 @@ func TestTarWithEnv(t *testing.T) {
Format: "json",
Input: "testdata/fixtures/images/debian-buster.tar.gz",
},
golden: "testdata/debian-buster-ignore-unfixed.json.golden",
golden: goldenDebianBusterIgnoreUnfixed,
},
}
@@ -540,14 +596,21 @@ func TestTarWithEnv(t *testing.T) {
}
// Run Trivy
runTest(t, []string{"image"}, tt.golden, "", types.FormatJSON, runOptions{
runTest(t, []string{"image"}, tt.golden, types.FormatJSON, runOptions{
fakeUUID: "3ff14136-e09f-4df9-80ea-%012d",
})
})
}
}
// TestTarWithConfigFile tests container image scanning with config files.
//
// Golden files are shared with TestTar.
func TestTarWithConfigFile(t *testing.T) {
if *update {
t.Skipf("Skipping TestTarWithConfigFile when -update flag is set. Golden files should be updated via TestTar.")
}
tests := []struct {
name string
input string
@@ -569,7 +632,7 @@ vulnerability:
cache:
dir: /should/be/overwritten
`,
golden: "testdata/alpine-39-high-critical.json.golden",
golden: goldenAlpine39HighCritical,
},
{
name: "debian buster/10 with --ignore-unfixed option",
@@ -582,7 +645,7 @@ vulnerability:
cache:
dir: /should/be/overwritten
`,
golden: "testdata/debian-buster-ignore-unfixed.json.golden",
golden: goldenDebianBusterIgnoreUnfixed,
},
}
@@ -610,7 +673,7 @@ cache:
}
// Run Trivy
runTest(t, osArgs, tt.golden, "", types.FormatJSON, runOptions{
runTest(t, osArgs, tt.golden, types.FormatJSON, runOptions{
fakeUUID: "3ff14136-e09f-4df9-80ea-%012d",
})
})

View File

@@ -1,10 +1,10 @@
{
"SchemaVersion": 2,
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"CreatedAt": "2021-08-25T12:20:30.000000005Z",
"ArtifactID": "sha256:4ca63ce1d8a90da2ed4f2d5e93e8e9db2f32d0fabf0718a2edebbe0e70826622",
"ArtifactName": "testdata/fixtures/images/almalinux-8.tar.gz",
"ArtifactType": "container_image",
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"Metadata": {
"Size": 204637184,
"OS": {

View File

@@ -1,10 +1,10 @@
{
"SchemaVersion": 2,
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"CreatedAt": "2021-08-25T12:20:30.000000005Z",
"ArtifactID": "sha256:961769676411f082461f9ef46626dd7a2d1e2b2a38e6a44364bcbecf51e66dd4",
"ArtifactName": "testdata/fixtures/images/alpine-310.tar.gz",
"ArtifactType": "container_image",
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"Metadata": {
"Size": 5843968,
"OS": {
@@ -73,7 +73,7 @@
"PkgName": "libcrypto1.1",
"PkgIdentifier": {
"PURL": "pkg:apk/alpine/libcrypto1.1@1.1.1c-r0?arch=x86_64\u0026distro=3.10.2",
"UID": "c6c116a4441ec6de"
"UID": "2fdf6d39693d0b83"
},
"InstalledVersion": "1.1.1c-r0",
"FixedVersion": "1.1.1d-r0",
@@ -146,7 +146,7 @@
"PkgName": "libcrypto1.1",
"PkgIdentifier": {
"PURL": "pkg:apk/alpine/libcrypto1.1@1.1.1c-r0?arch=x86_64\u0026distro=3.10.2",
"UID": "c6c116a4441ec6de"
"UID": "2fdf6d39693d0b83"
},
"InstalledVersion": "1.1.1c-r0",
"FixedVersion": "1.1.1d-r2",
@@ -229,7 +229,7 @@
"PkgName": "libssl1.1",
"PkgIdentifier": {
"PURL": "pkg:apk/alpine/libssl1.1@1.1.1c-r0?arch=x86_64\u0026distro=3.10.2",
"UID": "e132dcfcc51772ef"
"UID": "d57bb696f7371159"
},
"InstalledVersion": "1.1.1c-r0",
"FixedVersion": "1.1.1d-r0",
@@ -302,7 +302,7 @@
"PkgName": "libssl1.1",
"PkgIdentifier": {
"PURL": "pkg:apk/alpine/libssl1.1@1.1.1c-r0?arch=x86_64\u0026distro=3.10.2",
"UID": "e132dcfcc51772ef"
"UID": "d57bb696f7371159"
},
"InstalledVersion": "1.1.1c-r0",
"FixedVersion": "1.1.1d-r2",

View File

@@ -1,10 +1,10 @@
{
"SchemaVersion": 2,
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"CreatedAt": "2021-08-25T12:20:30.000000005Z",
"ArtifactID": "sha256:055936d3920576da37aa9bc460d70c5f212028bda1c08c0879aedf03d7a66ea1",
"ArtifactName": "testdata/fixtures/images/alpine-39.tar.gz",
"ArtifactType": "container_image",
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"Metadata": {
"Size": 5796352,
"OS": {
@@ -73,7 +73,7 @@
"PkgName": "libcrypto1.1",
"PkgIdentifier": {
"PURL": "pkg:apk/alpine/libcrypto1.1@1.1.1b-r1?arch=x86_64\u0026distro=3.9.4",
"UID": "d2c46e721bca75d3"
"UID": "6ab2c6870b0dc22c"
},
"InstalledVersion": "1.1.1b-r1",
"FixedVersion": "1.1.1d-r2",
@@ -156,7 +156,7 @@
"PkgName": "libssl1.1",
"PkgIdentifier": {
"PURL": "pkg:apk/alpine/libssl1.1@1.1.1b-r1?arch=x86_64\u0026distro=3.9.4",
"UID": "e39a91b0fefcbb1d"
"UID": "68dcd92c977c18d3"
},
"InstalledVersion": "1.1.1b-r1",
"FixedVersion": "1.1.1d-r2",

View File

@@ -1,10 +1,10 @@
{
"SchemaVersion": 2,
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"CreatedAt": "2021-08-25T12:20:30.000000005Z",
"ArtifactID": "sha256:055936d3920576da37aa9bc460d70c5f212028bda1c08c0879aedf03d7a66ea1",
"ArtifactName": "testdata/fixtures/images/alpine-39.tar.gz",
"ArtifactType": "container_image",
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"Metadata": {
"Size": 5796352,
"OS": {
@@ -73,7 +73,7 @@
"PkgName": "libcrypto1.1",
"PkgIdentifier": {
"PURL": "pkg:apk/alpine/libcrypto1.1@1.1.1b-r1?arch=x86_64\u0026distro=3.9.4",
"UID": "d2c46e721bca75d3"
"UID": "6ab2c6870b0dc22c"
},
"InstalledVersion": "1.1.1b-r1",
"FixedVersion": "1.1.1d-r0",
@@ -146,7 +146,7 @@
"PkgName": "libcrypto1.1",
"PkgIdentifier": {
"PURL": "pkg:apk/alpine/libcrypto1.1@1.1.1b-r1?arch=x86_64\u0026distro=3.9.4",
"UID": "d2c46e721bca75d3"
"UID": "6ab2c6870b0dc22c"
},
"InstalledVersion": "1.1.1b-r1",
"FixedVersion": "1.1.1d-r2",
@@ -229,7 +229,7 @@
"PkgName": "libssl1.1",
"PkgIdentifier": {
"PURL": "pkg:apk/alpine/libssl1.1@1.1.1b-r1?arch=x86_64\u0026distro=3.9.4",
"UID": "e39a91b0fefcbb1d"
"UID": "68dcd92c977c18d3"
},
"InstalledVersion": "1.1.1b-r1",
"FixedVersion": "1.1.1d-r0",
@@ -302,7 +302,7 @@
"PkgName": "libssl1.1",
"PkgIdentifier": {
"PURL": "pkg:apk/alpine/libssl1.1@1.1.1b-r1?arch=x86_64\u0026distro=3.9.4",
"UID": "e39a91b0fefcbb1d"
"UID": "68dcd92c977c18d3"
},
"InstalledVersion": "1.1.1b-r1",
"FixedVersion": "1.1.1d-r2",

View File

@@ -1,10 +1,10 @@
{
"SchemaVersion": 2,
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"CreatedAt": "2021-08-25T12:20:30.000000005Z",
"ArtifactID": "sha256:22848737c0d272ad5d7c7369d8ca830a62929e63e38edcb22085139a6ae0688d",
"ArtifactName": "testdata/fixtures/images/alpine-distroless.tar.gz",
"ArtifactType": "container_image",
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"Metadata": {
"Size": 35812864,
"OS": {
@@ -68,7 +68,7 @@
"PkgName": "git",
"PkgIdentifier": {
"PURL": "pkg:apk/alpine/git@2.35.1-r2?arch=x86_64\u0026distro=3.16",
"UID": "2999d822f6cae40c"
"UID": "c6eb6e6e6823b430"
},
"InstalledVersion": "2.35.1-r2",
"FixedVersion": "2.35.2-r0",

View File

@@ -1,10 +1,10 @@
{
"SchemaVersion": 2,
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"CreatedAt": "2021-08-25T12:20:30.000000005Z",
"ArtifactID": "sha256:961c4ee06269351d858969ea0426878675ed708d3a140246eabbc0bfc352bffa",
"ArtifactName": "testdata/fixtures/images/amazon-1.tar.gz",
"ArtifactType": "container_image",
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"Metadata": {
"Size": 172655616,
"OS": {

View File

@@ -1,10 +1,10 @@
{
"SchemaVersion": 2,
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"CreatedAt": "2021-08-25T12:20:30.000000005Z",
"ArtifactID": "sha256:b94321659aca6a89cb7650a5b864bc8ec4bf62c620b8f1a01530c2e90a88c391",
"ArtifactName": "testdata/fixtures/images/amazon-2.tar.gz",
"ArtifactType": "container_image",
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"Metadata": {
"Size": 168852480,
"OS": {

View File

@@ -1,10 +1,10 @@
{
"SchemaVersion": 2,
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"CreatedAt": "2021-08-25T12:20:30.000000005Z",
"ArtifactID": "sha256:88702f6b6133bf06cc46af48437d0c0fc661239155548757c65916504a0e5eee",
"ArtifactName": "testdata/fixtures/images/busybox-with-lockfile.tar.gz",
"ArtifactType": "container_image",
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"Metadata": {
"Size": 1491456,
"ImageID": "sha256:88702f6b6133bf06cc46af48437d0c0fc661239155548757c65916504a0e5eee",

View File

@@ -1,10 +1,10 @@
{
"SchemaVersion": 2,
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"CreatedAt": "2021-08-25T12:20:30.000000005Z",
"ArtifactID": "sha256:5bf9684f472089d6d5cb636041d3d6dc748dbde39f1aefc374bbd367bd2aabbf",
"ArtifactName": "testdata/fixtures/images/centos-6.tar.gz",
"ArtifactType": "container_image",
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"Metadata": {
"Size": 201540608,
"OS": {

View File

@@ -1,10 +1,10 @@
{
"SchemaVersion": 2,
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"CreatedAt": "2021-08-25T12:20:30.000000005Z",
"ArtifactID": "sha256:f1cb7c7d58b73eac859c395882eec49d50651244e342cd6c68a5c7809785f427",
"ArtifactName": "testdata/fixtures/images/centos-7.tar.gz",
"ArtifactType": "container_image",
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"Metadata": {
"Size": 209451008,
"OS": {

View File

@@ -1,10 +1,10 @@
{
"SchemaVersion": 2,
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"CreatedAt": "2021-08-25T12:20:30.000000005Z",
"ArtifactID": "sha256:f1cb7c7d58b73eac859c395882eec49d50651244e342cd6c68a5c7809785f427",
"ArtifactName": "testdata/fixtures/images/centos-7.tar.gz",
"ArtifactType": "container_image",
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"Metadata": {
"Size": 209451008,
"OS": {

View File

@@ -1,10 +1,10 @@
{
"SchemaVersion": 2,
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"CreatedAt": "2021-08-25T12:20:30.000000005Z",
"ArtifactID": "sha256:f1cb7c7d58b73eac859c395882eec49d50651244e342cd6c68a5c7809785f427",
"ArtifactName": "testdata/fixtures/images/centos-7.tar.gz",
"ArtifactType": "container_image",
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"Metadata": {
"Size": 209451008,
"OS": {

View File

@@ -3,7 +3,7 @@
"dataLicense": "CC0-1.0",
"SPDXID": "SPDXRef-DOCUMENT",
"name": "testdata/fixtures/repo/conda",
"documentNamespace": "http://trivy.dev/filesystem/testdata/fixtures/repo/conda-3ff14136-e09f-4df9-80ea-000000000005",
"documentNamespace": "http://trivy.dev/filesystem/testdata/fixtures/repo/conda-3ff14136-e09f-4df9-80ea-000000000006",
"creationInfo": {
"creators": [
"Organization: aquasecurity",

View File

@@ -1,10 +1,10 @@
{
"SchemaVersion": 2,
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"CreatedAt": "2021-08-25T12:20:30.000000005Z",
"ArtifactID": "sha256:c2c03a296d2329a4f3ab72a7bf38b78a8a80108204d326b0139d6af700e152d1",
"ArtifactName": "testdata/fixtures/images/debian-buster.tar.gz",
"ArtifactType": "container_image",
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"Metadata": {
"Size": 119199744,
"OS": {
@@ -72,7 +72,7 @@
"PkgName": "bash",
"PkgIdentifier": {
"PURL": "pkg:deb/debian/bash@5.0-4?arch=amd64\u0026distro=debian-10.1",
"UID": "d45ab8ae65ffe67"
"UID": "170e4e5a30145f9c"
},
"InstalledVersion": "5.0-4",
"Status": "affected",
@@ -139,7 +139,7 @@
"PkgName": "libidn2-0",
"PkgIdentifier": {
"PURL": "pkg:deb/debian/libidn2-0@2.0.5-1?arch=amd64\u0026distro=debian-10.1",
"UID": "473f5eb9e3d4a2f2"
"UID": "24f9b08969c58720"
},
"InstalledVersion": "2.0.5-1",
"FixedVersion": "2.0.5-1+deb10u1",

View File

@@ -1,10 +1,10 @@
{
"SchemaVersion": 2,
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"CreatedAt": "2021-08-25T12:20:30.000000005Z",
"ArtifactID": "sha256:f26939cc87ef44a6fc554eedd0a976ab30b5bc2769d65d2e986b6c5f1fd4053d",
"ArtifactName": "testdata/fixtures/images/debian-stretch.tar.gz",
"ArtifactType": "container_image",
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"Metadata": {
"Size": 105582080,
"OS": {
@@ -72,7 +72,7 @@
"PkgName": "bash",
"PkgIdentifier": {
"PURL": "pkg:deb/debian/bash@4.4-5?arch=amd64\u0026distro=debian-9.9",
"UID": "6100d09336f565a0"
"UID": "17a77561513a84ba"
},
"InstalledVersion": "4.4-5",
"Status": "end_of_life",
@@ -139,7 +139,7 @@
"PkgName": "e2fslibs",
"PkgIdentifier": {
"PURL": "pkg:deb/debian/e2fslibs@1.43.4-2?arch=amd64\u0026distro=debian-9.9",
"UID": "656652ce5818f7b6"
"UID": "f7397849f56886cf"
},
"InstalledVersion": "1.43.4-2",
"FixedVersion": "1.43.4-2+deb9u1",
@@ -213,7 +213,7 @@
"PkgName": "e2fsprogs",
"PkgIdentifier": {
"PURL": "pkg:deb/debian/e2fsprogs@1.43.4-2?arch=amd64\u0026distro=debian-9.9",
"UID": "3d19fd957338dc06"
"UID": "84536029ca820a6c"
},
"InstalledVersion": "1.43.4-2",
"FixedVersion": "1.43.4-2+deb9u1",
@@ -287,7 +287,7 @@
"PkgName": "libcomerr2",
"PkgIdentifier": {
"PURL": "pkg:deb/debian/libcomerr2@1.43.4-2?arch=amd64\u0026distro=debian-9.9",
"UID": "6ba1fac685a0c068"
"UID": "d911133b560d334c"
},
"InstalledVersion": "1.43.4-2",
"FixedVersion": "1.43.4-2+deb9u1",
@@ -361,7 +361,7 @@
"PkgName": "libss2",
"PkgIdentifier": {
"PURL": "pkg:deb/debian/libss2@1.43.4-2?arch=amd64\u0026distro=debian-9.9",
"UID": "e507c185f61cd2e8"
"UID": "d9396c7f91558633"
},
"InstalledVersion": "1.43.4-2",
"FixedVersion": "1.43.4-2+deb9u1",

View File

@@ -1,10 +1,10 @@
{
"SchemaVersion": 2,
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"CreatedAt": "2021-08-25T12:20:30.000000005Z",
"ArtifactID": "sha256:7f04a8d247173b1f2546d22913af637bbab4e7411e00ae6207da8d94c445750d",
"ArtifactName": "testdata/fixtures/images/distroless-base.tar.gz",
"ArtifactType": "container_image",
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"Metadata": {
"Size": 18503680,
"OS": {

View File

@@ -1,10 +1,10 @@
{
"SchemaVersion": 2,
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"CreatedAt": "2021-08-25T12:20:30.000000005Z",
"ArtifactID": "sha256:6fcac2cc8a710f21577b5bbd534e0bfc841c0cca569b57182ba19054696cddda",
"ArtifactName": "testdata/fixtures/images/distroless-python27.tar.gz",
"ArtifactType": "container_image",
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"Metadata": {
"Size": 48271360,
"OS": {

View File

@@ -1,10 +1,10 @@
{
"SchemaVersion": 2,
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"CreatedAt": "2021-08-25T12:20:30.000000005Z",
"ArtifactID": "sha256:5a992077baba51b97f27591a10d54d2f2723dc9c81a3fe419e261023f2554933",
"ArtifactName": "testdata/fixtures/images/fluentd-multiple-lockfiles.tar.gz",
"ArtifactType": "container_image",
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"Metadata": {
"Size": 157340160,
"OS": {

View File

@@ -3,7 +3,7 @@
"dataLicense": "CC0-1.0",
"SPDXID": "SPDXRef-DOCUMENT",
"name": "testdata/fixtures/repo/julia",
"documentNamespace": "http://trivy.dev/filesystem/testdata/fixtures/repo/julia-3ff14136-e09f-4df9-80ea-000000000007",
"documentNamespace": "http://trivy.dev/filesystem/testdata/fixtures/repo/julia-3ff14136-e09f-4df9-80ea-000000000008",
"creationInfo": {
"creators": [
"Organization: aquasecurity",

View File

@@ -1,10 +1,10 @@
{
"SchemaVersion": 2,
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"CreatedAt": "2021-08-25T12:20:30.000000005Z",
"ArtifactID": "sha256:8cdcbf18341ed8afa5322e7b0077f8ef3f46896882c921df5f97c51b369f6767",
"ArtifactName": "testdata/fixtures/images/mariner-1.0.tar.gz",
"ArtifactType": "container_image",
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"Metadata": {
"Size": 177582080,
"OS": {

View File

@@ -1,10 +1,10 @@
{
"SchemaVersion": 2,
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"CreatedAt": "2021-08-25T12:20:30.000000005Z",
"ArtifactID": "sha256:fef5ad254f6378f08071cfa2daaf05a1ce9857141c944b67a40742e63e65cecc",
"ArtifactName": "testdata/fixtures/images/opensuse-leap-151.tar.gz",
"ArtifactType": "container_image",
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"Metadata": {
"Size": 105899520,
"OS": {

View File

@@ -1,10 +1,10 @@
{
"SchemaVersion": 2,
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"CreatedAt": "2021-08-25T12:20:30.000000005Z",
"ArtifactID": "sha256:580e73f5c823232e6587136e9f5428a89afdf77a123bb8575d08208e0cc34b12",
"ArtifactName": "testdata/fixtures/images/opensuse-tumbleweed.tar.gz",
"ArtifactType": "container_image",
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"Metadata": {
"Size": 115281408,
"OS": {

View File

@@ -1,10 +1,10 @@
{
"SchemaVersion": 2,
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"CreatedAt": "2021-08-25T12:20:30.000000005Z",
"ArtifactID": "sha256:8988c7081e1f7b6c2928cbc4832b8a05968bb589d45d444ca1e3027c68f97f56",
"ArtifactName": "testdata/fixtures/images/oraclelinux-8.tar.gz",
"ArtifactType": "container_image",
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"Metadata": {
"Size": 416893952,
"OS": {

View File

@@ -1,10 +1,10 @@
{
"SchemaVersion": 2,
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"CreatedAt": "2021-08-25T12:20:30.000000005Z",
"ArtifactID": "sha256:5ccb5186b75cd13ff0d028f5b5b2bdf7ef7ca2b3d56eb2c6eb6c136077a6991a",
"ArtifactName": "testdata/fixtures/images/photon-30.tar.gz",
"ArtifactType": "container_image",
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"Metadata": {
"Size": 34946560,
"OS": {

View File

@@ -1,10 +1,10 @@
{
"SchemaVersion": 2,
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"CreatedAt": "2021-08-25T12:20:30.000000005Z",
"ArtifactID": "sha256:210996f98b856d7cd00496ddbe9412e73f1c714c95de09661e07b4e43648f9ab",
"ArtifactName": "testdata/fixtures/images/rockylinux-8.tar.gz",
"ArtifactType": "container_image",
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"Metadata": {
"Size": 211280384,
"OS": {

View File

@@ -1,10 +1,10 @@
{
"SchemaVersion": 2,
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"CreatedAt": "2021-08-25T12:20:30.000000005Z",
"ArtifactID": "sha256:c45ec974938acac29c893b5d273d73e4ebdd7e6a97b6fa861dfbd8dd430b9016",
"ArtifactName": "testdata/fixtures/images/sle-micro-rancher-5.4_ndb.tar.gz",
"ArtifactType": "container_image",
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"Metadata": {
"Size": 709748736,
"OS": {

View File

@@ -1,10 +1,10 @@
{
"SchemaVersion": 2,
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"CreatedAt": "2021-08-25T12:20:30.000000005Z",
"ArtifactID": "sha256:ed8f0747d483b60657982f0ef1ba74482aed08795cf0eb774b00bc53022a8351",
"ArtifactName": "testdata/fixtures/images/spring4shell-jre11.tar.gz",
"ArtifactType": "container_image",
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"Metadata": {
"Size": 270418944,
"OS": {
@@ -26,7 +26,6 @@
"RepoTags": [
"ghcr.io/aquasecurity/trivy-test-images:spring4shell-jre11"
],
"RepoDigests": null,
"ImageConfig": {
"architecture": "amd64",
"created": "2022-06-07T03:41:13.228952Z",

View File

@@ -1,10 +1,10 @@
{
"SchemaVersion": 2,
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"CreatedAt": "2021-08-25T12:20:30.000000005Z",
"ArtifactID": "sha256:b88bc3d2f0b5aacf1d36efa498f427d923b01c854dac090acf5368c55ac04fda",
"ArtifactName": "testdata/fixtures/images/spring4shell-jre8.tar.gz",
"ArtifactType": "container_image",
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"Metadata": {
"Size": 236810240,
"OS": {
@@ -26,7 +26,6 @@
"RepoTags": [
"ghcr.io/aquasecurity/trivy-test-images:spring4shell-jre8"
],
"RepoDigests": null,
"ImageConfig": {
"architecture": "amd64",
"created": "2022-06-06T13:51:57.120019Z",
@@ -309,15 +308,6 @@
"Target": "",
"Class": "custom",
"CustomResources": [
{
"Type": "spring4shell/java-major-version",
"FilePath": "/usr/local/openjdk-8/release",
"Layer": {
"Digest": "sha256:d7b564a873af313eb2dbcb1ed0d393c57543e3666bdedcbe5d75841d72b1f791",
"DiffID": "sha256:ba40706eccba610401e4942e29f50bdf36807f8638942ce20805b359ae3ac1c1"
},
"Data": "1.8.0_322"
},
{
"Type": "spring4shell/tomcat-version",
"FilePath": "/usr/local/tomcat/RELEASE-NOTES",
@@ -326,6 +316,15 @@
"DiffID": "sha256:85595543df2b1115a18284a8ef62d0b235c4bc29e3d33b55f89b54ee1eadf4c6"
},
"Data": "8.5.77"
},
{
"Type": "spring4shell/java-major-version",
"FilePath": "/usr/local/openjdk-8/release",
"Layer": {
"Digest": "sha256:d7b564a873af313eb2dbcb1ed0d393c57543e3666bdedcbe5d75841d72b1f791",
"DiffID": "sha256:ba40706eccba610401e4942e29f50bdf36807f8638942ce20805b359ae3ac1c1"
},
"Data": "1.8.0_322"
}
]
}

View File

@@ -1,27 +1,17 @@
{
"SchemaVersion": 2,
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"CreatedAt": "2021-08-25T12:20:30.000000005Z",
"ArtifactID": "sha256:4f8b4cb139bdac63ad60b7382a80cd0414c55018e2f80d4163f59e40f71766cc",
"ArtifactName": "testdata/fixtures/repo/trivy-ci-test",
"ArtifactName": "https://github.com/knqyf263/trivy-ci-test",
"ArtifactType": "repository",
"ReportID": "3ff14136-e09f-4df9-80ea-000000000002",
"Metadata": {
"ImageConfig": {
"architecture": "",
"created": "0001-01-01T00:00:00Z",
"os": "",
"rootfs": {
"type": "",
"diff_ids": null
},
"config": {}
},
"RepoURL": "https://github.com/knqyf263/trivy-ci-test",
"Branch": "master",
"Commit": "5ae342eb2802672402d9b2c26f09e2051bbd91b8",
"CommitMsg": "Use COPY instead of ADD in Dockerfile (#4)",
"Author": "gy741 <gy741.kim@gmail.com>",
"Committer": "knqyf263 <knqyf263@gmail.com>"
"Author": "gy741 \u003cgy741.kim@gmail.com\u003e",
"Committer": "knqyf263 \u003cknqyf263@gmail.com\u003e"
},
"Results": [
{
@@ -40,7 +30,6 @@
"InstalledVersion": "1.9.0",
"FixedVersion": "\u003e= 2.1.0",
"Status": "fixed",
"Layer": {},
"SeveritySource": "nvd",
"PrimaryURL": "https://avd.aquasec.com/nvd/cve-2019-15542",
"DataSource": {
@@ -83,7 +72,6 @@
"InstalledVersion": "1.9.0",
"FixedVersion": "\u003e= 3.1.0, \u003e= 2.1.3, \u003c 3.0.0",
"Status": "fixed",
"Layer": {},
"SeveritySource": "nvd",
"PrimaryURL": "https://avd.aquasec.com/nvd/cve-2021-38193",
"DataSource": {

View File

@@ -1,10 +1,10 @@
{
"SchemaVersion": 2,
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"CreatedAt": "2021-08-25T12:20:30.000000005Z",
"ArtifactID": "sha256:6fecccc91c83e11ae4fede6793e9410841221d4779520c2b9e9fb7f7b3830264",
"ArtifactName": "testdata/fixtures/images/ubi-7.tar.gz",
"ArtifactType": "container_image",
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"Metadata": {
"Size": 215162880,
"OS": {

View File

@@ -1,10 +1,10 @@
{
"SchemaVersion": 2,
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"CreatedAt": "2021-08-25T12:20:30.000000005Z",
"ArtifactID": "sha256:6fecccc91c83e11ae4fede6793e9410841221d4779520c2b9e9fb7f7b3830264",
"ArtifactName": "testdata/fixtures/images/ubi-7.tar.gz",
"ArtifactType": "container_image",
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"Metadata": {
"Size": 215162880,
"OS": {

View File

@@ -1,10 +1,10 @@
{
"SchemaVersion": 2,
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"CreatedAt": "2021-08-25T12:20:30.000000005Z",
"ArtifactID": "sha256:a2a15febcdf362f6115e801d37b5e60d6faaeedcb9896155e5fe9d754025be12",
"ArtifactName": "testdata/fixtures/images/ubuntu-1804.tar.gz",
"ArtifactType": "container_image",
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"Metadata": {
"Size": 66571264,
"OS": {
@@ -105,7 +105,7 @@
"PkgName": "e2fsprogs",
"PkgIdentifier": {
"PURL": "pkg:deb/ubuntu/e2fsprogs@1.44.1-1ubuntu1.1?arch=amd64\u0026distro=ubuntu-18.04",
"UID": "ae80ec86b8816b6c"
"UID": "f43bbfe1f933f718"
},
"InstalledVersion": "1.44.1-1ubuntu1.1",
"FixedVersion": "1.44.1-1ubuntu1.2",
@@ -176,7 +176,7 @@
"PkgName": "libcom-err2",
"PkgIdentifier": {
"PURL": "pkg:deb/ubuntu/libcom-err2@1.44.1-1ubuntu1.1?arch=amd64\u0026distro=ubuntu-18.04",
"UID": "3c28244e063693a2"
"UID": "e7d11d906afeb678"
},
"InstalledVersion": "1.44.1-1ubuntu1.1",
"FixedVersion": "1.44.1-1ubuntu1.2",
@@ -247,7 +247,7 @@
"PkgName": "libext2fs2",
"PkgIdentifier": {
"PURL": "pkg:deb/ubuntu/libext2fs2@1.44.1-1ubuntu1.1?arch=amd64\u0026distro=ubuntu-18.04",
"UID": "937ce6e3021ed568"
"UID": "19d89bf66d83962e"
},
"InstalledVersion": "1.44.1-1ubuntu1.1",
"FixedVersion": "1.44.1-1ubuntu1.2",
@@ -318,7 +318,7 @@
"PkgName": "libss2",
"PkgIdentifier": {
"PURL": "pkg:deb/ubuntu/libss2@1.44.1-1ubuntu1.1?arch=amd64\u0026distro=ubuntu-18.04",
"UID": "7a50c6bc4279c93b"
"UID": "231804324b8f13c6"
},
"InstalledVersion": "1.44.1-1ubuntu1.1",
"FixedVersion": "1.44.1-1ubuntu1.2",

View File

@@ -1,10 +1,10 @@
{
"SchemaVersion": 2,
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"CreatedAt": "2021-08-25T12:20:30.000000005Z",
"ArtifactID": "sha256:a2a15febcdf362f6115e801d37b5e60d6faaeedcb9896155e5fe9d754025be12",
"ArtifactName": "testdata/fixtures/images/ubuntu-1804.tar.gz",
"ArtifactType": "container_image",
"ReportID": "3ff14136-e09f-4df9-80ea-000000000001",
"Metadata": {
"Size": 66571264,
"OS": {
@@ -105,7 +105,7 @@
"PkgName": "bash",
"PkgIdentifier": {
"PURL": "pkg:deb/ubuntu/bash@4.4.18-2ubuntu1.2?arch=amd64\u0026distro=ubuntu-18.04",
"UID": "da318bd19a304cc0"
"UID": "55652e248d848fa2"
},
"InstalledVersion": "4.4.18-2ubuntu1.2",
"Status": "affected",
@@ -168,7 +168,7 @@
"PkgName": "e2fsprogs",
"PkgIdentifier": {
"PURL": "pkg:deb/ubuntu/e2fsprogs@1.44.1-1ubuntu1.1?arch=amd64\u0026distro=ubuntu-18.04",
"UID": "ae80ec86b8816b6c"
"UID": "f43bbfe1f933f718"
},
"InstalledVersion": "1.44.1-1ubuntu1.1",
"FixedVersion": "1.44.1-1ubuntu1.2",
@@ -239,7 +239,7 @@
"PkgName": "libcom-err2",
"PkgIdentifier": {
"PURL": "pkg:deb/ubuntu/libcom-err2@1.44.1-1ubuntu1.1?arch=amd64\u0026distro=ubuntu-18.04",
"UID": "3c28244e063693a2"
"UID": "e7d11d906afeb678"
},
"InstalledVersion": "1.44.1-1ubuntu1.1",
"FixedVersion": "1.44.1-1ubuntu1.2",
@@ -310,7 +310,7 @@
"PkgName": "libext2fs2",
"PkgIdentifier": {
"PURL": "pkg:deb/ubuntu/libext2fs2@1.44.1-1ubuntu1.1?arch=amd64\u0026distro=ubuntu-18.04",
"UID": "937ce6e3021ed568"
"UID": "19d89bf66d83962e"
},
"InstalledVersion": "1.44.1-1ubuntu1.1",
"FixedVersion": "1.44.1-1ubuntu1.2",
@@ -381,7 +381,7 @@
"PkgName": "libss2",
"PkgIdentifier": {
"PURL": "pkg:deb/ubuntu/libss2@1.44.1-1ubuntu1.1?arch=amd64\u0026distro=ubuntu-18.04",
"UID": "7a50c6bc4279c93b"
"UID": "231804324b8f13c6"
},
"InstalledVersion": "1.44.1-1ubuntu1.1",
"FixedVersion": "1.44.1-1ubuntu1.2",

View File

@@ -11,7 +11,17 @@ import (
"github.com/aquasecurity/trivy/pkg/types"
)
// TestVM tests scanning VM images (VMDK, disk images).
//
// TODO: Golden files cannot be updated with the -update flag currently because
// ArtifactName contains random file paths from t.TempDir() and Target contains full paths.
// This test applies overrides to normalize these values for comparison, but those overrides
// would not be applied to golden files in update mode.
// For now, golden files must be updated manually.
func TestVM(t *testing.T) {
if *update {
t.Fatal("TestVM does not support -update flag. Golden files must be updated manually. See TODO comment above.")
}
type args struct {
input string
format string
@@ -30,7 +40,7 @@ func TestVM(t *testing.T) {
format: "json",
artifactType: "vm",
},
golden: "testdata/amazonlinux2-gp2-x86-vm.json.golden",
golden: goldenAmazonLinux2GP2X86VM,
},
{
name: "amazon linux 2 in Snapshot, filesystem XFS",
@@ -39,7 +49,7 @@ func TestVM(t *testing.T) {
format: "json",
artifactType: "vm",
},
golden: "testdata/amazonlinux2-gp2-x86-vm.json.golden",
golden: goldenAmazonLinux2GP2X86VM,
},
{
name: "Ubuntu in Snapshot, filesystem EXT4",
@@ -48,7 +58,7 @@ func TestVM(t *testing.T) {
format: "json",
artifactType: "vm",
},
golden: "testdata/ubuntu-gp2-x86-vm.json.golden",
golden: goldenUbuntuGP2X86VM,
},
{
name: "Ubuntu in VMDK, filesystem EXT4",
@@ -57,7 +67,7 @@ func TestVM(t *testing.T) {
format: "json",
artifactType: "vm",
},
golden: "testdata/ubuntu-gp2-x86-vm.json.golden",
golden: goldenUbuntuGP2X86VM,
},
}
@@ -88,7 +98,7 @@ func TestVM(t *testing.T) {
osArgs = append(osArgs, imagePath)
// Run "trivy vm"
runTest(t, osArgs, tt.golden, "", types.FormatJSON, runOptions{
runTest(t, osArgs, tt.golden, types.FormatJSON, runOptions{
override: overrideFuncs(overrideUID, func(t *testing.T, _, got *types.Report) {
got.ArtifactName = "disk.img"
for i := range got.Results {

View File

@@ -3,6 +3,7 @@ package main
import (
"context"
"encoding/json"
"errors"
"fmt"
"log/slog"
"os"
@@ -322,8 +323,9 @@ func (t Test) VM() error {
// UpdateVMGolden updates golden files for integration tests
func (t Test) UpdateVMGolden() error {
mg.Deps(t.FixtureVMImages)
return sh.RunWithV(ENV, "go", "test", "-v", "-tags=vm_integration", "./integration/...", "-update")
return errors.New("`mage test:updateVMGolden` is currently not supported. See TestVM function comments in integration/vm_test.go for details")
// mg.Deps(t.FixtureVMImages)
// return sh.RunWithV(ENV, "go", "test", "-v", "-tags=vm_integration", "./integration/...", "-update")
}
// E2e runs E2E tests using testscript framework

View File

@@ -715,6 +715,9 @@ func localImageTestWithNamespace(t *testing.T, namespace string) {
got, err := a.ApplyLayers(ctx, ref.ID, ref.BlobIDs)
require.NoError(t, err)
// Clear package detail fields
clearPackageDetailFields(got.Packages)
tag := strings.Split(tt.imageName, ":")[1]
goldenFile := fmt.Sprintf("testdata/goldens/packages/%s.json.golden", tag)
@@ -853,6 +856,9 @@ func TestContainerd_PullImage(t *testing.T) {
err = json.NewDecoder(golden).Decode(&wantPkgs)
require.NoError(t, err)
// Clear package detail fields for comparison
clearPackageDetailFields(got.Packages)
// Assert
assert.Equal(t, wantPkgs, got.Packages)
})

View File

@@ -228,10 +228,29 @@ func commonChecks(t *testing.T, detail types.ArtifactDetail, tc testCase) {
checkLangPkgs(detail, t, tc)
}
// clearPackageDetailFields clears package detail fields to keep golden files manageable.
// Fields cleared: Identifier (UID, PURL, BOMRef), Layer, InstalledFiles, DependsOn, Digest
// Fields kept for comparison: ID, Name, Version, Epoch, Release, Arch, SrcName, SrcEpoch, SrcVersion, SrcRelease, Licenses, Maintainer, Modularitylabel, Indirect
func clearPackageDetailFields(packages []types.Package) {
for i := range packages {
packages[i].Identifier = types.PkgIdentifier{} // Clear entire Identifier (UID, PURL, BOMRef)
packages[i].Layer = types.Layer{}
packages[i].InstalledFiles = nil
packages[i].DependsOn = nil
packages[i].Digest = ""
}
}
func checkOSPackages(t *testing.T, detail types.ArtifactDetail, tc testCase) {
// Sort OS packages for consistency
sort.Sort(detail.Packages)
// Clear package detail fields to keep golden files manageable in size.
// Cleared fields: Identifier.UID, Layer, InstalledFiles, DependsOn, Digest
// These fields are either too large (InstalledFiles, Layer) or not critical for comparison (UID, Digest, DependsOn).
// All other fields including ID, Name, Version, Licenses, Maintainer, etc. are compared.
clearPackageDetailFields(detail.Packages)
goldenFile := fmt.Sprintf("testdata/goldens/packages/%s.json.golden", tc.imageTag)
if *update {
@@ -244,18 +263,14 @@ func checkOSPackages(t *testing.T, detail types.ArtifactDetail, tc testCase) {
data, err := os.ReadFile(goldenFile)
require.NoError(t, err, tc.name)
var expectedPkgs []types.Package
var expectedPkgs types.Packages
err = json.Unmarshal(data, &expectedPkgs)
require.NoError(t, err)
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)
sort.Sort(expectedPkgs)
for i := 0; i < len(expectedPkgs); i++ {
require.Equal(t, expectedPkgs[i].Name, detail.Packages[i].Name, tc.name)
require.Equal(t, expectedPkgs[i].Version, detail.Packages[i].Version, tc.name)
}
assert.Equal(t, expectedPkgs, detail.Packages, tc.name)
}
func checkLangPkgs(detail types.ArtifactDetail, t *testing.T, tc testCase) {

View File

@@ -2,10 +2,6 @@
{
"ID": "alpine-baselayout@3.1.2-r0",
"Name": "alpine-baselayout",
"Identifier": {
"PURL": "pkg:apk/alpine/alpine-baselayout@3.1.2-r0?arch=x86_64\u0026distro=3.10.2",
"UID": "6d6ce35c691e934f"
},
"Version": "3.1.2-r0",
"Arch": "x86_64",
"SrcName": "alpine-baselayout",
@@ -13,51 +9,11 @@
"Licenses": [
"GPL-2.0-only"
],
"Maintainer": "Natanael Copa \u003cncopa@alpinelinux.org\u003e",
"DependsOn": [
"busybox@1.30.1-r2",
"musl@1.1.22-r3"
],
"Layer": {
"Digest": "sha256:9d48c3bd43c520dc2784e868a780e976b207cbf493eaff8c6596eb871cbd9609",
"DiffID": "sha256:03901b4a2ea88eeaad62dbe59b072b28b6efa00491962b8741081c5df50c65e0"
},
"Digest": "sha1:574d490311b68db01c0a3e44f5491be0cdc79250",
"InstalledFiles": [
"etc/hosts",
"etc/sysctl.conf",
"etc/group",
"etc/protocols",
"etc/fstab",
"etc/mtab",
"etc/profile",
"etc/shells",
"etc/motd",
"etc/inittab",
"etc/hostname",
"etc/modules",
"etc/services",
"etc/shadow",
"etc/passwd",
"etc/profile.d/color_prompt",
"etc/sysctl.d/00-alpine.conf",
"etc/modprobe.d/i386.conf",
"etc/modprobe.d/blacklist.conf",
"etc/modprobe.d/aliases.conf",
"etc/modprobe.d/kms.conf",
"etc/crontabs/root",
"sbin/mkmntdirs",
"var/run",
"var/spool/cron/crontabs"
]
"Maintainer": "Natanael Copa \u003cncopa@alpinelinux.org\u003e"
},
{
"ID": "alpine-keys@2.1-r2",
"Name": "alpine-keys",
"Identifier": {
"PURL": "pkg:apk/alpine/alpine-keys@2.1-r2?arch=x86_64\u0026distro=3.10.2",
"UID": "f85995d82b77fe17"
},
"Version": "2.1-r2",
"Arch": "x86_64",
"SrcName": "alpine-keys",
@@ -65,40 +21,11 @@
"Licenses": [
"MIT"
],
"Maintainer": "Natanael Copa \u003cncopa@alpinelinux.org\u003e",
"Layer": {
"Digest": "sha256:9d48c3bd43c520dc2784e868a780e976b207cbf493eaff8c6596eb871cbd9609",
"DiffID": "sha256:03901b4a2ea88eeaad62dbe59b072b28b6efa00491962b8741081c5df50c65e0"
},
"Digest": "sha1:6dd672e2dabc14aa324cf9cd4553e98b69a769c1",
"InstalledFiles": [
"etc/apk/keys/alpine-devel@lists.alpinelinux.org-5243ef4b.rsa.pub",
"etc/apk/keys/alpine-devel@lists.alpinelinux.org-5261cecb.rsa.pub",
"etc/apk/keys/alpine-devel@lists.alpinelinux.org-4a6a0840.rsa.pub",
"usr/share/apk/keys/alpine-devel@lists.alpinelinux.org-524d27bb.rsa.pub",
"usr/share/apk/keys/alpine-devel@lists.alpinelinux.org-5243ef4b.rsa.pub",
"usr/share/apk/keys/alpine-devel@lists.alpinelinux.org-5261cecb.rsa.pub",
"usr/share/apk/keys/alpine-devel@lists.alpinelinux.org-58cbb476.rsa.pub",
"usr/share/apk/keys/alpine-devel@lists.alpinelinux.org-58199dcc.rsa.pub",
"usr/share/apk/keys/alpine-devel@lists.alpinelinux.org-4a6a0840.rsa.pub",
"usr/share/apk/keys/alpine-devel@lists.alpinelinux.org-58e4f17d.rsa.pub",
"usr/share/apk/keys/aarch64/alpine-devel@lists.alpinelinux.org-58199dcc.rsa.pub",
"usr/share/apk/keys/ppc64le/alpine-devel@lists.alpinelinux.org-58cbb476.rsa.pub",
"usr/share/apk/keys/x86/alpine-devel@lists.alpinelinux.org-5243ef4b.rsa.pub",
"usr/share/apk/keys/x86/alpine-devel@lists.alpinelinux.org-4a6a0840.rsa.pub",
"usr/share/apk/keys/s390x/alpine-devel@lists.alpinelinux.org-58e4f17d.rsa.pub",
"usr/share/apk/keys/armhf/alpine-devel@lists.alpinelinux.org-524d27bb.rsa.pub",
"usr/share/apk/keys/x86_64/alpine-devel@lists.alpinelinux.org-5261cecb.rsa.pub",
"usr/share/apk/keys/x86_64/alpine-devel@lists.alpinelinux.org-4a6a0840.rsa.pub"
]
"Maintainer": "Natanael Copa \u003cncopa@alpinelinux.org\u003e"
},
{
"ID": "apk-tools@2.10.4-r2",
"Name": "apk-tools",
"Identifier": {
"PURL": "pkg:apk/alpine/apk-tools@2.10.4-r2?arch=x86_64\u0026distro=3.10.2",
"UID": "e85c589338bc6551"
},
"Version": "2.10.4-r2",
"Arch": "x86_64",
"SrcName": "apk-tools",
@@ -106,29 +33,11 @@
"Licenses": [
"GPL-2.0-only"
],
"Maintainer": "Natanael Copa \u003cncopa@alpinelinux.org\u003e",
"DependsOn": [
"libcrypto1.1@1.1.1c-r0",
"libssl1.1@1.1.1c-r0",
"musl@1.1.22-r3",
"zlib@1.2.11-r1"
],
"Layer": {
"Digest": "sha256:9d48c3bd43c520dc2784e868a780e976b207cbf493eaff8c6596eb871cbd9609",
"DiffID": "sha256:03901b4a2ea88eeaad62dbe59b072b28b6efa00491962b8741081c5df50c65e0"
},
"Digest": "sha1:e6393c9419776955346cddd70ad4ec66082a2705",
"InstalledFiles": [
"sbin/apk"
]
"Maintainer": "Natanael Copa \u003cncopa@alpinelinux.org\u003e"
},
{
"ID": "busybox@1.30.1-r2",
"Name": "busybox",
"Identifier": {
"PURL": "pkg:apk/alpine/busybox@1.30.1-r2?arch=x86_64\u0026distro=3.10.2",
"UID": "1ae96e9b05861c6e"
},
"Version": "1.30.1-r2",
"Arch": "x86_64",
"SrcName": "busybox",
@@ -136,31 +45,11 @@
"Licenses": [
"GPL-2.0-only"
],
"Maintainer": "Natanael Copa \u003cncopa@alpinelinux.org\u003e",
"DependsOn": [
"musl@1.1.22-r3"
],
"Layer": {
"Digest": "sha256:9d48c3bd43c520dc2784e868a780e976b207cbf493eaff8c6596eb871cbd9609",
"DiffID": "sha256:03901b4a2ea88eeaad62dbe59b072b28b6efa00491962b8741081c5df50c65e0"
},
"Digest": "sha1:9c244d7f4909bffcef4c67380b6aed145c41a232",
"InstalledFiles": [
"bin/busybox",
"bin/sh",
"etc/securetty",
"etc/udhcpd.conf",
"etc/logrotate.d/acpid",
"etc/network/if-up.d/dad"
]
"Maintainer": "Natanael Copa \u003cncopa@alpinelinux.org\u003e"
},
{
"ID": "ca-certificates-cacert@20190108-r0",
"Name": "ca-certificates-cacert",
"Identifier": {
"PURL": "pkg:apk/alpine/ca-certificates-cacert@20190108-r0?arch=x86_64\u0026distro=3.10.2",
"UID": "a848273c1a749619"
},
"Version": "20190108-r0",
"Arch": "x86_64",
"SrcName": "ca-certificates",
@@ -169,23 +58,11 @@
"MPL-2.0",
"GPL-2.0-or-later"
],
"Maintainer": "Natanael Copa \u003cncopa@alpinelinux.org\u003e",
"Layer": {
"Digest": "sha256:9d48c3bd43c520dc2784e868a780e976b207cbf493eaff8c6596eb871cbd9609",
"DiffID": "sha256:03901b4a2ea88eeaad62dbe59b072b28b6efa00491962b8741081c5df50c65e0"
},
"Digest": "sha1:0d69933c7cd071e82acb24c6e4268e4752f7a3f7",
"InstalledFiles": [
"etc/ssl/cert.pem"
]
"Maintainer": "Natanael Copa \u003cncopa@alpinelinux.org\u003e"
},
{
"ID": "libc-utils@0.7.1-r0",
"Name": "libc-utils",
"Identifier": {
"PURL": "pkg:apk/alpine/libc-utils@0.7.1-r0?arch=x86_64\u0026distro=3.10.2",
"UID": "217c3efd50863e03"
},
"Version": "0.7.1-r0",
"Arch": "x86_64",
"SrcName": "libc-dev",
@@ -193,23 +70,11 @@
"Licenses": [
"BSD-3-Clause"
],
"Maintainer": "Natanael Copa \u003cncopa@alpinelinux.org\u003e",
"DependsOn": [
"musl-utils@1.1.22-r3"
],
"Layer": {
"Digest": "sha256:9d48c3bd43c520dc2784e868a780e976b207cbf493eaff8c6596eb871cbd9609",
"DiffID": "sha256:03901b4a2ea88eeaad62dbe59b072b28b6efa00491962b8741081c5df50c65e0"
},
"Digest": "sha1:1ff2cf7a0a53c1e83c8649f27b95aaa07bd4a83e"
"Maintainer": "Natanael Copa \u003cncopa@alpinelinux.org\u003e"
},
{
"ID": "libcrypto1.1@1.1.1c-r0",
"Name": "libcrypto1.1",
"Identifier": {
"PURL": "pkg:apk/alpine/libcrypto1.1@1.1.1c-r0?arch=x86_64\u0026distro=3.10.2",
"UID": "2fdf6d39693d0b83"
},
"Version": "1.1.1c-r0",
"Arch": "x86_64",
"SrcName": "openssl",
@@ -217,37 +82,11 @@
"Licenses": [
"OpenSSL"
],
"Maintainer": "Timo Teras \u003ctimo.teras@iki.fi\u003e",
"DependsOn": [
"musl@1.1.22-r3"
],
"Layer": {
"Digest": "sha256:9d48c3bd43c520dc2784e868a780e976b207cbf493eaff8c6596eb871cbd9609",
"DiffID": "sha256:03901b4a2ea88eeaad62dbe59b072b28b6efa00491962b8741081c5df50c65e0"
},
"Digest": "sha1:547053af84ac3667548b11b990d7b80ef23b9a3f",
"InstalledFiles": [
"etc/ssl/openssl.cnf.dist",
"etc/ssl/ct_log_list.cnf",
"etc/ssl/ct_log_list.cnf.dist",
"etc/ssl/openssl.cnf",
"etc/ssl/misc/CA.pl",
"etc/ssl/misc/tsget.pl",
"etc/ssl/misc/tsget",
"lib/libcrypto.so.1.1",
"usr/lib/libcrypto.so.1.1",
"usr/lib/engines-1.1/capi.so",
"usr/lib/engines-1.1/padlock.so",
"usr/lib/engines-1.1/afalg.so"
]
"Maintainer": "Timo Teras \u003ctimo.teras@iki.fi\u003e"
},
{
"ID": "libssl1.1@1.1.1c-r0",
"Name": "libssl1.1",
"Identifier": {
"PURL": "pkg:apk/alpine/libssl1.1@1.1.1c-r0?arch=x86_64\u0026distro=3.10.2",
"UID": "d57bb696f7371159"
},
"Version": "1.1.1c-r0",
"Arch": "x86_64",
"SrcName": "openssl",
@@ -255,58 +94,22 @@
"Licenses": [
"OpenSSL"
],
"Maintainer": "Timo Teras \u003ctimo.teras@iki.fi\u003e",
"DependsOn": [
"libcrypto1.1@1.1.1c-r0",
"musl@1.1.22-r3"
],
"Layer": {
"Digest": "sha256:9d48c3bd43c520dc2784e868a780e976b207cbf493eaff8c6596eb871cbd9609",
"DiffID": "sha256:03901b4a2ea88eeaad62dbe59b072b28b6efa00491962b8741081c5df50c65e0"
},
"Digest": "sha1:6f37a428d6f8de036a523d42e6b0c99288153c38",
"InstalledFiles": [
"lib/libssl.so.1.1",
"usr/lib/libssl.so.1.1"
]
"Maintainer": "Timo Teras \u003ctimo.teras@iki.fi\u003e"
},
{
"ID": "libtls-standalone@2.9.1-r0",
"Name": "libtls-standalone",
"Identifier": {
"PURL": "pkg:apk/alpine/libtls-standalone@2.9.1-r0?arch=x86_64\u0026distro=3.10.2",
"UID": "578e2c441f445479"
},
"Version": "2.9.1-r0",
"Arch": "x86_64",
"SrcName": "libtls-standalone",
"SrcVersion": "2.9.1-r0",
"Licenses": [
"ISC"
],
"DependsOn": [
"ca-certificates-cacert@20190108-r0",
"libcrypto1.1@1.1.1c-r0",
"libssl1.1@1.1.1c-r0",
"musl@1.1.22-r3"
],
"Layer": {
"Digest": "sha256:9d48c3bd43c520dc2784e868a780e976b207cbf493eaff8c6596eb871cbd9609",
"DiffID": "sha256:03901b4a2ea88eeaad62dbe59b072b28b6efa00491962b8741081c5df50c65e0"
},
"Digest": "sha1:f149b608e1e33cfad61fbcf9e3fdb6494f7d691a",
"InstalledFiles": [
"usr/lib/libtls-standalone.so.1.0.0",
"usr/lib/libtls-standalone.so.1"
]
},
{
"ID": "musl@1.1.22-r3",
"Name": "musl",
"Identifier": {
"PURL": "pkg:apk/alpine/musl@1.1.22-r3?arch=x86_64\u0026distro=3.10.2",
"UID": "b4c2daf4a121c758"
},
"Version": "1.1.22-r3",
"Arch": "x86_64",
"SrcName": "musl",
@@ -314,24 +117,11 @@
"Licenses": [
"MIT"
],
"Maintainer": "Timo Teräs \u003ctimo.teras@iki.fi\u003e",
"Layer": {
"Digest": "sha256:9d48c3bd43c520dc2784e868a780e976b207cbf493eaff8c6596eb871cbd9609",
"DiffID": "sha256:03901b4a2ea88eeaad62dbe59b072b28b6efa00491962b8741081c5df50c65e0"
},
"Digest": "sha1:d489e0f3fbb5548758f5ccd2c5a0cef70260ef62",
"InstalledFiles": [
"lib/libc.musl-x86_64.so.1",
"lib/ld-musl-x86_64.so.1"
]
"Maintainer": "Timo Teräs \u003ctimo.teras@iki.fi\u003e"
},
{
"ID": "musl-utils@1.1.22-r3",
"Name": "musl-utils",
"Identifier": {
"PURL": "pkg:apk/alpine/musl-utils@1.1.22-r3?arch=x86_64\u0026distro=3.10.2",
"UID": "98c7d8944c5f13a4"
},
"Version": "1.1.22-r3",
"Arch": "x86_64",
"SrcName": "musl",
@@ -341,31 +131,11 @@
"BSD-3-Clause",
"GPL-2.0-or-later"
],
"Maintainer": "Timo Teräs \u003ctimo.teras@iki.fi\u003e",
"DependsOn": [
"musl@1.1.22-r3",
"scanelf@1.2.3-r0"
],
"Layer": {
"Digest": "sha256:9d48c3bd43c520dc2784e868a780e976b207cbf493eaff8c6596eb871cbd9609",
"DiffID": "sha256:03901b4a2ea88eeaad62dbe59b072b28b6efa00491962b8741081c5df50c65e0"
},
"Digest": "sha1:8bb14c727be819d07a1e9d8b998dc94bde989205",
"InstalledFiles": [
"sbin/ldconfig",
"usr/bin/iconv",
"usr/bin/ldd",
"usr/bin/getconf",
"usr/bin/getent"
]
"Maintainer": "Timo Teräs \u003ctimo.teras@iki.fi\u003e"
},
{
"ID": "scanelf@1.2.3-r0",
"Name": "scanelf",
"Identifier": {
"PURL": "pkg:apk/alpine/scanelf@1.2.3-r0?arch=x86_64\u0026distro=3.10.2",
"UID": "1ca987fe564f5102"
},
"Version": "1.2.3-r0",
"Arch": "x86_64",
"SrcName": "pax-utils",
@@ -373,26 +143,11 @@
"Licenses": [
"GPL-2.0-only"
],
"Maintainer": "Natanael Copa \u003cncopa@alpinelinux.org\u003e",
"DependsOn": [
"musl@1.1.22-r3"
],
"Layer": {
"Digest": "sha256:9d48c3bd43c520dc2784e868a780e976b207cbf493eaff8c6596eb871cbd9609",
"DiffID": "sha256:03901b4a2ea88eeaad62dbe59b072b28b6efa00491962b8741081c5df50c65e0"
},
"Digest": "sha1:cb3059ce358cea0f5f78a0220a2980e6c4916a94",
"InstalledFiles": [
"usr/bin/scanelf"
]
"Maintainer": "Natanael Copa \u003cncopa@alpinelinux.org\u003e"
},
{
"ID": "ssl_client@1.30.1-r2",
"Name": "ssl_client",
"Identifier": {
"PURL": "pkg:apk/alpine/ssl_client@1.30.1-r2?arch=x86_64\u0026distro=3.10.2",
"UID": "433659d244b0b632"
},
"Version": "1.30.1-r2",
"Arch": "x86_64",
"SrcName": "busybox",
@@ -400,27 +155,11 @@
"Licenses": [
"GPL-2.0-only"
],
"Maintainer": "Natanael Copa \u003cncopa@alpinelinux.org\u003e",
"DependsOn": [
"libtls-standalone@2.9.1-r0",
"musl@1.1.22-r3"
],
"Layer": {
"Digest": "sha256:9d48c3bd43c520dc2784e868a780e976b207cbf493eaff8c6596eb871cbd9609",
"DiffID": "sha256:03901b4a2ea88eeaad62dbe59b072b28b6efa00491962b8741081c5df50c65e0"
},
"Digest": "sha1:1f7afca8301f00cef8a9797124721d9f8c16f586",
"InstalledFiles": [
"usr/bin/ssl_client"
]
"Maintainer": "Natanael Copa \u003cncopa@alpinelinux.org\u003e"
},
{
"ID": "zlib@1.2.11-r1",
"Name": "zlib",
"Identifier": {
"PURL": "pkg:apk/alpine/zlib@1.2.11-r1?arch=x86_64\u0026distro=3.10.2",
"UID": "4eb417f1df4f2172"
},
"Version": "1.2.11-r1",
"Arch": "x86_64",
"SrcName": "zlib",
@@ -428,18 +167,6 @@
"Licenses": [
"Zlib"
],
"Maintainer": "Natanael Copa \u003cncopa@alpinelinux.org\u003e",
"DependsOn": [
"musl@1.1.22-r3"
],
"Layer": {
"Digest": "sha256:9d48c3bd43c520dc2784e868a780e976b207cbf493eaff8c6596eb871cbd9609",
"DiffID": "sha256:03901b4a2ea88eeaad62dbe59b072b28b6efa00491962b8741081c5df50c65e0"
},
"Digest": "sha1:bacb380dfa6f2f5e8dc366144f09b3181001cf76",
"InstalledFiles": [
"lib/libz.so.1.2.11",
"lib/libz.so.1"
]
"Maintainer": "Natanael Copa \u003cncopa@alpinelinux.org\u003e"
}
]

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,6 @@
[
{
"ID": "bash@4.4.18-1.ph3.x86_64",
"Name": "bash",
"Version": "4.4.18",
"Release": "1.ph3",
@@ -7,13 +8,13 @@
"SrcName": "bash",
"SrcVersion": "4.4.18",
"SrcRelease": "1.ph3",
"License": "GPLv3",
"Layer": {
"Digest": "sha256:675aead3dff5e25094cb9f4d7cc64f05e9f04a3f3397d5d45bfbc1c8a99c3a73",
"DiffID": "sha256:0f379947a276b7b051643960392fa66c2f0cb493bc1dcd471abb5545005949fd"
}
"Licenses": [
"GPLv3"
],
"Maintainer": "VMware, Inc."
},
{
"ID": "bzip2-libs@1.0.6-10.ph3.x86_64",
"Name": "bzip2-libs",
"Version": "1.0.6",
"Release": "10.ph3",
@@ -21,13 +22,13 @@
"SrcName": "bzip2",
"SrcVersion": "1.0.6",
"SrcRelease": "10.ph3",
"License": "BSD",
"Layer": {
"Digest": "sha256:675aead3dff5e25094cb9f4d7cc64f05e9f04a3f3397d5d45bfbc1c8a99c3a73",
"DiffID": "sha256:0f379947a276b7b051643960392fa66c2f0cb493bc1dcd471abb5545005949fd"
}
"Licenses": [
"BSD"
],
"Maintainer": "VMware, Inc."
},
{
"ID": "ca-certificates@20190521-1.ph3.x86_64",
"Name": "ca-certificates",
"Version": "20190521",
"Release": "1.ph3",
@@ -35,13 +36,13 @@
"SrcName": "ca-certificates",
"SrcVersion": "20190521",
"SrcRelease": "1.ph3",
"License": "Custom",
"Layer": {
"Digest": "sha256:675aead3dff5e25094cb9f4d7cc64f05e9f04a3f3397d5d45bfbc1c8a99c3a73",
"DiffID": "sha256:0f379947a276b7b051643960392fa66c2f0cb493bc1dcd471abb5545005949fd"
}
"Licenses": [
"Custom"
],
"Maintainer": "VMware, Inc."
},
{
"ID": "ca-certificates-pki@20190521-1.ph3.x86_64",
"Name": "ca-certificates-pki",
"Version": "20190521",
"Release": "1.ph3",
@@ -49,13 +50,13 @@
"SrcName": "ca-certificates",
"SrcVersion": "20190521",
"SrcRelease": "1.ph3",
"License": "Custom",
"Layer": {
"Digest": "sha256:675aead3dff5e25094cb9f4d7cc64f05e9f04a3f3397d5d45bfbc1c8a99c3a73",
"DiffID": "sha256:0f379947a276b7b051643960392fa66c2f0cb493bc1dcd471abb5545005949fd"
}
"Licenses": [
"Custom"
],
"Maintainer": "VMware, Inc."
},
{
"ID": "curl@7.61.1-4.ph3.x86_64",
"Name": "curl",
"Version": "7.61.1",
"Release": "4.ph3",
@@ -63,13 +64,13 @@
"SrcName": "curl",
"SrcVersion": "7.61.1",
"SrcRelease": "4.ph3",
"License": "MIT",
"Layer": {
"Digest": "sha256:675aead3dff5e25094cb9f4d7cc64f05e9f04a3f3397d5d45bfbc1c8a99c3a73",
"DiffID": "sha256:0f379947a276b7b051643960392fa66c2f0cb493bc1dcd471abb5545005949fd"
}
"Licenses": [
"MIT"
],
"Maintainer": "VMware, Inc."
},
{
"ID": "curl-libs@7.61.1-4.ph3.x86_64",
"Name": "curl-libs",
"Version": "7.61.1",
"Release": "4.ph3",
@@ -77,13 +78,13 @@
"SrcName": "curl",
"SrcVersion": "7.61.1",
"SrcRelease": "4.ph3",
"License": "MIT",
"Layer": {
"Digest": "sha256:675aead3dff5e25094cb9f4d7cc64f05e9f04a3f3397d5d45bfbc1c8a99c3a73",
"DiffID": "sha256:0f379947a276b7b051643960392fa66c2f0cb493bc1dcd471abb5545005949fd"
}
"Licenses": [
"MIT"
],
"Maintainer": "VMware, Inc."
},
{
"ID": "e2fsprogs-libs@1.44.3-2.ph3.x86_64",
"Name": "e2fsprogs-libs",
"Version": "1.44.3",
"Release": "2.ph3",
@@ -91,13 +92,13 @@
"SrcName": "e2fsprogs",
"SrcVersion": "1.44.3",
"SrcRelease": "2.ph3",
"License": "GPLv2+",
"Layer": {
"Digest": "sha256:675aead3dff5e25094cb9f4d7cc64f05e9f04a3f3397d5d45bfbc1c8a99c3a73",
"DiffID": "sha256:0f379947a276b7b051643960392fa66c2f0cb493bc1dcd471abb5545005949fd"
}
"Licenses": [
"GPLv2+"
],
"Maintainer": "VMware, Inc."
},
{
"ID": "elfutils-libelf@0.176-1.ph3.x86_64",
"Name": "elfutils-libelf",
"Version": "0.176",
"Release": "1.ph3",
@@ -105,13 +106,13 @@
"SrcName": "elfutils",
"SrcVersion": "0.176",
"SrcRelease": "1.ph3",
"License": "GPLv2+ or LGPLv3+",
"Layer": {
"Digest": "sha256:675aead3dff5e25094cb9f4d7cc64f05e9f04a3f3397d5d45bfbc1c8a99c3a73",
"DiffID": "sha256:0f379947a276b7b051643960392fa66c2f0cb493bc1dcd471abb5545005949fd"
}
"Licenses": [
"GPLv2+ or LGPLv3+"
],
"Maintainer": "VMware, Inc."
},
{
"ID": "expat-libs@2.2.6-2.ph3.x86_64",
"Name": "expat-libs",
"Version": "2.2.6",
"Release": "2.ph3",
@@ -119,13 +120,13 @@
"SrcName": "expat",
"SrcVersion": "2.2.6",
"SrcRelease": "2.ph3",
"License": "MIT",
"Layer": {
"Digest": "sha256:675aead3dff5e25094cb9f4d7cc64f05e9f04a3f3397d5d45bfbc1c8a99c3a73",
"DiffID": "sha256:0f379947a276b7b051643960392fa66c2f0cb493bc1dcd471abb5545005949fd"
}
"Licenses": [
"MIT"
],
"Maintainer": "VMware, Inc."
},
{
"ID": "filesystem@1.1-4.ph3.x86_64",
"Name": "filesystem",
"Version": "1.1",
"Release": "4.ph3",
@@ -133,13 +134,13 @@
"SrcName": "filesystem",
"SrcVersion": "1.1",
"SrcRelease": "4.ph3",
"License": "GPLv3",
"Layer": {
"Digest": "sha256:675aead3dff5e25094cb9f4d7cc64f05e9f04a3f3397d5d45bfbc1c8a99c3a73",
"DiffID": "sha256:0f379947a276b7b051643960392fa66c2f0cb493bc1dcd471abb5545005949fd"
}
"Licenses": [
"GPLv3"
],
"Maintainer": "VMware, Inc."
},
{
"ID": "glibc@2.28-3.ph3.x86_64",
"Name": "glibc",
"Version": "2.28",
"Release": "3.ph3",
@@ -147,24 +148,23 @@
"SrcName": "glibc",
"SrcVersion": "2.28",
"SrcRelease": "3.ph3",
"License": "LGPLv2+",
"Layer": {
"Digest": "sha256:675aead3dff5e25094cb9f4d7cc64f05e9f04a3f3397d5d45bfbc1c8a99c3a73",
"DiffID": "sha256:0f379947a276b7b051643960392fa66c2f0cb493bc1dcd471abb5545005949fd"
}
"Licenses": [
"LGPLv2+"
],
"Maintainer": "VMware, Inc."
},
{
"ID": "gpg-pubkey@66fd4949-4803fe57.",
"Name": "gpg-pubkey",
"Version": "66fd4949",
"Release": "4803fe57",
"Arch": "None",
"License": "pubkey",
"Layer": {
"Digest": "sha256:675aead3dff5e25094cb9f4d7cc64f05e9f04a3f3397d5d45bfbc1c8a99c3a73",
"DiffID": "sha256:0f379947a276b7b051643960392fa66c2f0cb493bc1dcd471abb5545005949fd"
}
"Licenses": [
"pubkey"
]
},
{
"ID": "krb5@1.17-1.ph3.x86_64",
"Name": "krb5",
"Version": "1.17",
"Release": "1.ph3",
@@ -172,13 +172,13 @@
"SrcName": "krb5",
"SrcVersion": "1.17",
"SrcRelease": "1.ph3",
"License": "MIT",
"Layer": {
"Digest": "sha256:675aead3dff5e25094cb9f4d7cc64f05e9f04a3f3397d5d45bfbc1c8a99c3a73",
"DiffID": "sha256:0f379947a276b7b051643960392fa66c2f0cb493bc1dcd471abb5545005949fd"
}
"Licenses": [
"MIT"
],
"Maintainer": "VMware, Inc."
},
{
"ID": "libcap@2.25-8.ph3.x86_64",
"Name": "libcap",
"Version": "2.25",
"Release": "8.ph3",
@@ -186,13 +186,13 @@
"SrcName": "libcap",
"SrcVersion": "2.25",
"SrcRelease": "8.ph3",
"License": "GPLv2+",
"Layer": {
"Digest": "sha256:675aead3dff5e25094cb9f4d7cc64f05e9f04a3f3397d5d45bfbc1c8a99c3a73",
"DiffID": "sha256:0f379947a276b7b051643960392fa66c2f0cb493bc1dcd471abb5545005949fd"
}
"Licenses": [
"GPLv2+"
],
"Maintainer": "VMware, Inc."
},
{
"ID": "libdb@5.3.28-2.ph3.x86_64",
"Name": "libdb",
"Version": "5.3.28",
"Release": "2.ph3",
@@ -200,13 +200,13 @@
"SrcName": "libdb",
"SrcVersion": "5.3.28",
"SrcRelease": "2.ph3",
"License": "BSD and LGPLv2 and Sleepycat",
"Layer": {
"Digest": "sha256:675aead3dff5e25094cb9f4d7cc64f05e9f04a3f3397d5d45bfbc1c8a99c3a73",
"DiffID": "sha256:0f379947a276b7b051643960392fa66c2f0cb493bc1dcd471abb5545005949fd"
}
"Licenses": [
"BSD and LGPLv2 and Sleepycat"
],
"Maintainer": "VMware, Inc."
},
{
"ID": "libgcc@7.3.0-4.ph3.x86_64",
"Name": "libgcc",
"Version": "7.3.0",
"Release": "4.ph3",
@@ -214,13 +214,13 @@
"SrcName": "gcc",
"SrcVersion": "7.3.0",
"SrcRelease": "4.ph3",
"License": "GPLv2+",
"Layer": {
"Digest": "sha256:675aead3dff5e25094cb9f4d7cc64f05e9f04a3f3397d5d45bfbc1c8a99c3a73",
"DiffID": "sha256:0f379947a276b7b051643960392fa66c2f0cb493bc1dcd471abb5545005949fd"
}
"Licenses": [
"GPLv2+"
],
"Maintainer": "VMware, Inc."
},
{
"ID": "libsolv@0.6.26-5.ph3.x86_64",
"Name": "libsolv",
"Version": "0.6.26",
"Release": "5.ph3",
@@ -228,13 +228,13 @@
"SrcName": "libsolv",
"SrcVersion": "0.6.26",
"SrcRelease": "5.ph3",
"License": "BSD",
"Layer": {
"Digest": "sha256:675aead3dff5e25094cb9f4d7cc64f05e9f04a3f3397d5d45bfbc1c8a99c3a73",
"DiffID": "sha256:0f379947a276b7b051643960392fa66c2f0cb493bc1dcd471abb5545005949fd"
}
"Licenses": [
"BSD"
],
"Maintainer": "VMware, Inc."
},
{
"ID": "libssh2@1.9.0-1.ph3.x86_64",
"Name": "libssh2",
"Version": "1.9.0",
"Release": "1.ph3",
@@ -242,13 +242,13 @@
"SrcName": "libssh2",
"SrcVersion": "1.9.0",
"SrcRelease": "1.ph3",
"License": "BSD",
"Layer": {
"Digest": "sha256:675aead3dff5e25094cb9f4d7cc64f05e9f04a3f3397d5d45bfbc1c8a99c3a73",
"DiffID": "sha256:0f379947a276b7b051643960392fa66c2f0cb493bc1dcd471abb5545005949fd"
}
"Licenses": [
"BSD"
],
"Maintainer": "VMware, Inc."
},
{
"ID": "ncurses-libs@6.1-1.ph3.x86_64",
"Name": "ncurses-libs",
"Version": "6.1",
"Release": "1.ph3",
@@ -256,13 +256,13 @@
"SrcName": "ncurses",
"SrcVersion": "6.1",
"SrcRelease": "1.ph3",
"License": "MIT",
"Layer": {
"Digest": "sha256:675aead3dff5e25094cb9f4d7cc64f05e9f04a3f3397d5d45bfbc1c8a99c3a73",
"DiffID": "sha256:0f379947a276b7b051643960392fa66c2f0cb493bc1dcd471abb5545005949fd"
}
"Licenses": [
"MIT"
],
"Maintainer": "VMware, Inc."
},
{
"ID": "nspr@4.21-1.ph3.x86_64",
"Name": "nspr",
"Version": "4.21",
"Release": "1.ph3",
@@ -270,13 +270,13 @@
"SrcName": "nspr",
"SrcVersion": "4.21",
"SrcRelease": "1.ph3",
"License": "MPLv2.0",
"Layer": {
"Digest": "sha256:675aead3dff5e25094cb9f4d7cc64f05e9f04a3f3397d5d45bfbc1c8a99c3a73",
"DiffID": "sha256:0f379947a276b7b051643960392fa66c2f0cb493bc1dcd471abb5545005949fd"
}
"Licenses": [
"MPLv2.0"
],
"Maintainer": "VMware, Inc."
},
{
"ID": "nss-libs@3.44-2.ph3.x86_64",
"Name": "nss-libs",
"Version": "3.44",
"Release": "2.ph3",
@@ -284,13 +284,13 @@
"SrcName": "nss",
"SrcVersion": "3.44",
"SrcRelease": "2.ph3",
"License": "MPLv2.0",
"Layer": {
"Digest": "sha256:675aead3dff5e25094cb9f4d7cc64f05e9f04a3f3397d5d45bfbc1c8a99c3a73",
"DiffID": "sha256:0f379947a276b7b051643960392fa66c2f0cb493bc1dcd471abb5545005949fd"
}
"Licenses": [
"MPLv2.0"
],
"Maintainer": "VMware, Inc."
},
{
"ID": "openssl@1.0.2s-1.ph3.x86_64",
"Name": "openssl",
"Version": "1.0.2s",
"Release": "1.ph3",
@@ -298,13 +298,13 @@
"SrcName": "openssl",
"SrcVersion": "1.0.2s",
"SrcRelease": "1.ph3",
"License": "OpenSSL",
"Layer": {
"Digest": "sha256:675aead3dff5e25094cb9f4d7cc64f05e9f04a3f3397d5d45bfbc1c8a99c3a73",
"DiffID": "sha256:0f379947a276b7b051643960392fa66c2f0cb493bc1dcd471abb5545005949fd"
}
"Licenses": [
"OpenSSL"
],
"Maintainer": "VMware, Inc."
},
{
"ID": "photon-release@3.0-3.ph3.noarch",
"Name": "photon-release",
"Version": "3.0",
"Release": "3.ph3",
@@ -312,13 +312,13 @@
"SrcName": "photon-release",
"SrcVersion": "3.0",
"SrcRelease": "3.ph3",
"License": "Apache License",
"Layer": {
"Digest": "sha256:675aead3dff5e25094cb9f4d7cc64f05e9f04a3f3397d5d45bfbc1c8a99c3a73",
"DiffID": "sha256:0f379947a276b7b051643960392fa66c2f0cb493bc1dcd471abb5545005949fd"
}
"Licenses": [
"Apache License"
],
"Maintainer": "VMware, Inc."
},
{
"ID": "photon-repos@3.0-3.ph3.noarch",
"Name": "photon-repos",
"Version": "3.0",
"Release": "3.ph3",
@@ -326,13 +326,13 @@
"SrcName": "photon-repos",
"SrcVersion": "3.0",
"SrcRelease": "3.ph3",
"License": "Apache License",
"Layer": {
"Digest": "sha256:675aead3dff5e25094cb9f4d7cc64f05e9f04a3f3397d5d45bfbc1c8a99c3a73",
"DiffID": "sha256:0f379947a276b7b051643960392fa66c2f0cb493bc1dcd471abb5545005949fd"
}
"Licenses": [
"Apache License"
],
"Maintainer": "VMware, Inc."
},
{
"ID": "popt@1.16-5.ph3.x86_64",
"Name": "popt",
"Version": "1.16",
"Release": "5.ph3",
@@ -340,13 +340,13 @@
"SrcName": "popt",
"SrcVersion": "1.16",
"SrcRelease": "5.ph3",
"License": "MIT",
"Layer": {
"Digest": "sha256:675aead3dff5e25094cb9f4d7cc64f05e9f04a3f3397d5d45bfbc1c8a99c3a73",
"DiffID": "sha256:0f379947a276b7b051643960392fa66c2f0cb493bc1dcd471abb5545005949fd"
}
"Licenses": [
"MIT"
],
"Maintainer": "VMware, Inc."
},
{
"ID": "readline@7.0-2.ph3.x86_64",
"Name": "readline",
"Version": "7.0",
"Release": "2.ph3",
@@ -354,13 +354,13 @@
"SrcName": "readline",
"SrcVersion": "7.0",
"SrcRelease": "2.ph3",
"License": "GPLv3+",
"Layer": {
"Digest": "sha256:675aead3dff5e25094cb9f4d7cc64f05e9f04a3f3397d5d45bfbc1c8a99c3a73",
"DiffID": "sha256:0f379947a276b7b051643960392fa66c2f0cb493bc1dcd471abb5545005949fd"
}
"Licenses": [
"GPLv3+"
],
"Maintainer": "VMware, Inc."
},
{
"ID": "rpm-libs@4.14.2-4.ph3.x86_64",
"Name": "rpm-libs",
"Version": "4.14.2",
"Release": "4.ph3",
@@ -368,13 +368,13 @@
"SrcName": "rpm",
"SrcVersion": "4.14.2",
"SrcRelease": "4.ph3",
"License": "GPLv2+",
"Layer": {
"Digest": "sha256:675aead3dff5e25094cb9f4d7cc64f05e9f04a3f3397d5d45bfbc1c8a99c3a73",
"DiffID": "sha256:0f379947a276b7b051643960392fa66c2f0cb493bc1dcd471abb5545005949fd"
}
"Licenses": [
"GPLv2+"
],
"Maintainer": "VMware, Inc."
},
{
"ID": "sqlite-libs@3.27.2-3.ph3.x86_64",
"Name": "sqlite-libs",
"Version": "3.27.2",
"Release": "3.ph3",
@@ -382,13 +382,13 @@
"SrcName": "sqlite",
"SrcVersion": "3.27.2",
"SrcRelease": "3.ph3",
"License": "Public Domain",
"Layer": {
"Digest": "sha256:675aead3dff5e25094cb9f4d7cc64f05e9f04a3f3397d5d45bfbc1c8a99c3a73",
"DiffID": "sha256:0f379947a276b7b051643960392fa66c2f0cb493bc1dcd471abb5545005949fd"
}
"Licenses": [
"Public Domain"
],
"Maintainer": "VMware, Inc."
},
{
"ID": "tdnf@2.0.0-10.ph3.x86_64",
"Name": "tdnf",
"Version": "2.0.0",
"Release": "10.ph3",
@@ -396,13 +396,13 @@
"SrcName": "tdnf",
"SrcVersion": "2.0.0",
"SrcRelease": "10.ph3",
"License": "LGPLv2.1,GPLv2",
"Layer": {
"Digest": "sha256:675aead3dff5e25094cb9f4d7cc64f05e9f04a3f3397d5d45bfbc1c8a99c3a73",
"DiffID": "sha256:0f379947a276b7b051643960392fa66c2f0cb493bc1dcd471abb5545005949fd"
}
"Licenses": [
"LGPLv2.1,GPLv2"
],
"Maintainer": "VMware, Inc."
},
{
"ID": "tdnf-cli-libs@2.0.0-10.ph3.x86_64",
"Name": "tdnf-cli-libs",
"Version": "2.0.0",
"Release": "10.ph3",
@@ -410,13 +410,13 @@
"SrcName": "tdnf",
"SrcVersion": "2.0.0",
"SrcRelease": "10.ph3",
"License": "LGPLv2.1,GPLv2",
"Layer": {
"Digest": "sha256:675aead3dff5e25094cb9f4d7cc64f05e9f04a3f3397d5d45bfbc1c8a99c3a73",
"DiffID": "sha256:0f379947a276b7b051643960392fa66c2f0cb493bc1dcd471abb5545005949fd"
}
"Licenses": [
"LGPLv2.1,GPLv2"
],
"Maintainer": "VMware, Inc."
},
{
"ID": "toybox@0.7.7-1.ph3.x86_64",
"Name": "toybox",
"Version": "0.7.7",
"Release": "1.ph3",
@@ -424,13 +424,13 @@
"SrcName": "toybox",
"SrcVersion": "0.7.7",
"SrcRelease": "1.ph3",
"License": "BSD",
"Layer": {
"Digest": "sha256:675aead3dff5e25094cb9f4d7cc64f05e9f04a3f3397d5d45bfbc1c8a99c3a73",
"DiffID": "sha256:0f379947a276b7b051643960392fa66c2f0cb493bc1dcd471abb5545005949fd"
}
"Licenses": [
"BSD"
],
"Maintainer": "VMware, Inc."
},
{
"ID": "xz-libs@5.2.4-1.ph3.x86_64",
"Name": "xz-libs",
"Version": "5.2.4",
"Release": "1.ph3",
@@ -438,13 +438,13 @@
"SrcName": "xz",
"SrcVersion": "5.2.4",
"SrcRelease": "1.ph3",
"License": "GPLv2+ and GPLv3+ and LGPLv2+",
"Layer": {
"Digest": "sha256:675aead3dff5e25094cb9f4d7cc64f05e9f04a3f3397d5d45bfbc1c8a99c3a73",
"DiffID": "sha256:0f379947a276b7b051643960392fa66c2f0cb493bc1dcd471abb5545005949fd"
}
"Licenses": [
"GPLv2+ and GPLv3+ and LGPLv2+"
],
"Maintainer": "VMware, Inc."
},
{
"ID": "zlib@1.2.11-1.ph3.x86_64",
"Name": "zlib",
"Version": "1.2.11",
"Release": "1.ph3",
@@ -452,10 +452,9 @@
"SrcName": "zlib",
"SrcVersion": "1.2.11",
"SrcRelease": "1.ph3",
"License": "zlib",
"Layer": {
"Digest": "sha256:675aead3dff5e25094cb9f4d7cc64f05e9f04a3f3397d5d45bfbc1c8a99c3a73",
"DiffID": "sha256:0f379947a276b7b051643960392fa66c2f0cb493bc1dcd471abb5545005949fd"
}
"Licenses": [
"zlib"
],
"Maintainer": "VMware, Inc."
}
]

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff