refactor(rust): use txtar format for cargo analyzer test data (#10104)

This commit is contained in:
Teppei Fukuda
2026-01-30 16:13:18 +04:00
committed by GitHub
parent 1a72b326bb
commit 65e151fab0
24 changed files with 266 additions and 149 deletions

View File

@@ -1,12 +1,12 @@
package cargo
import (
"os"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/aquasecurity/trivy/internal/testutil"
"github.com/aquasecurity/trivy/pkg/detector/library/compare"
"github.com/aquasecurity/trivy/pkg/fanal/analyzer"
"github.com/aquasecurity/trivy/pkg/fanal/types"
@@ -15,12 +15,12 @@ import (
func Test_cargoAnalyzer_Analyze(t *testing.T) {
tests := []struct {
name string
dir string
file string
want *analyzer.AnalysisResult
}{
{
name: "happy path",
dir: "testdata/happy",
file: "testdata/happy.txtar",
want: &analyzer.AnalysisResult{
Applications: []types.Application{
{
@@ -163,7 +163,7 @@ func Test_cargoAnalyzer_Analyze(t *testing.T) {
},
{
name: "Cargo.toml doesn't include `Dependencies` field",
dir: "testdata/toml-only-workspace-deps",
file: "testdata/toml-only-workspace-deps.txtar",
want: &analyzer.AnalysisResult{
Applications: []types.Application{
{
@@ -205,7 +205,7 @@ func Test_cargoAnalyzer_Analyze(t *testing.T) {
},
{
name: "no Cargo.toml",
dir: "testdata/no-cargo-toml",
file: "testdata/no-cargo-toml.txtar",
want: &analyzer.AnalysisResult{
Applications: []types.Application{
{
@@ -392,7 +392,7 @@ func Test_cargoAnalyzer_Analyze(t *testing.T) {
},
{
name: "wrong Cargo.toml",
dir: "testdata/wrong-cargo-toml",
file: "testdata/wrong-cargo-toml.txtar",
want: &analyzer.AnalysisResult{
Applications: []types.Application{
{
@@ -433,12 +433,12 @@ func Test_cargoAnalyzer_Analyze(t *testing.T) {
},
{
name: "broken Cargo.lock",
dir: "testdata/sad",
file: "testdata/sad.txtar",
want: &analyzer.AnalysisResult{},
},
{
name: "version.workspace = true inherits from workspace.package.version",
dir: "testdata/version-workspace-inherit",
file: "testdata/version-workspace-inherit.txtar",
want: &analyzer.AnalysisResult{
Applications: []types.Application{
{
@@ -487,7 +487,7 @@ func Test_cargoAnalyzer_Analyze(t *testing.T) {
},
{
name: "workspace members",
dir: "testdata/toml-workspace-members",
file: "testdata/toml-workspace-members.txtar",
want: &analyzer.AnalysisResult{
Applications: []types.Application{
{
@@ -659,7 +659,7 @@ func Test_cargoAnalyzer_Analyze(t *testing.T) {
},
{
name: "workspace members",
dir: "testdata/toml-workspace-glob",
file: "testdata/toml-workspace-glob.txtar",
want: &analyzer.AnalysisResult{
Applications: []types.Application{
{
@@ -837,7 +837,7 @@ func Test_cargoAnalyzer_Analyze(t *testing.T) {
require.NoError(t, err)
got, err := a.PostAnalyze(t.Context(), analyzer.PostAnalysisInput{
FS: os.DirFS(tt.dir),
FS: testutil.TxtarToFS(t, tt.file),
})
require.NoError(t, err)

View File

@@ -1,3 +1,17 @@
Happy path test case for Cargo analyzer.
This test verifies that the analyzer correctly parses a standard Rust project with:
- Direct dependencies (regex, memchr, regex-syntax) from [dependencies], [target] and [workspace.dependencies]
- Dev dependencies (winapi)
- Transitive dependencies (aho-corasick, libc, ucd-util, etc.)
Expected behavior:
- Root package "app" should have RelationshipRoot
- Direct dependencies should have RelationshipDirect
- Transitive dependencies should have RelationshipIndirect with Indirect=true
- All packages should have correct version, ID, and location information
-- Cargo.lock --
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
@@ -92,4 +106,23 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
-- Cargo.toml --
[package]
name = "app"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
regex = "=1.7.3"
[target.'cfg(not(target_os = "windows"))'.dependencies]
memchr = { version = "1.*", optional = true }
[workspace.dependencies]
regex-syntax = { version = "<0.6"}
[dev-dependencies]
winapi = "*"

View File

@@ -1,18 +0,0 @@
[package]
name = "app"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
regex = "=1.7.3"
[target.'cfg(not(target_os = "windows"))'.dependencies]
memchr = { version = "1.*", optional = true }
[workspace.dependencies]
regex-syntax = { version = "<0.6"}
[dev-dependencies]
winapi = "*"

View File

@@ -1,3 +1,14 @@
Test case: Cargo.lock without Cargo.toml.
This test verifies that the analyzer works when only Cargo.lock is present
(e.g., scanning a container image where Cargo.toml was not included).
Expected behavior:
- All packages should have RelationshipUnknown (cannot determine direct vs indirect)
- Indirect field should be false for all packages
- Package information should still be correctly parsed from Cargo.lock
-- Cargo.lock --
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
@@ -92,4 +103,4 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

View File

@@ -0,0 +1,11 @@
Test case: Broken/malformed Cargo.lock file.
This test verifies that the analyzer gracefully handles a corrupted Cargo.lock file.
The file contains only "[" which is invalid TOML.
Expected behavior:
- Return empty AnalysisResult (no error, just empty result)
- Do not crash or panic
-- Cargo.lock --
[

View File

@@ -1 +0,0 @@
[

View File

@@ -0,0 +1,36 @@
Test case: Cargo.toml with only [workspace.dependencies] section (no [dependencies]).
This test verifies that the analyzer handles projects where:
- Cargo.toml has [workspace.dependencies] but no [dependencies] section
- Dependencies are still resolved correctly from Cargo.lock
Expected behavior:
- Root package "app" should have RelationshipRoot
- memchr should have RelationshipDirect (resolved from workspace.dependencies)
-- Cargo.lock --
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "app"
version = "0.1.0"
dependencies = [
"memchr 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "memchr"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
-- Cargo.toml --
[package]
name = "app"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[workspace.dependencies]
memchr = "2.5"

View File

@@ -1,15 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "app"
version = "0.1.0"
dependencies = [
"memchr 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "memchr"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"

View File

@@ -1,9 +0,0 @@
[package]
name = "app"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[workspace.dependencies]
memchr = "2.5"

View File

@@ -1,3 +1,20 @@
Test case: Cargo workspace with glob pattern in members.
This test verifies that the analyzer correctly handles Cargo workspaces where
members are specified using glob patterns (e.g., members = ["member*"]).
Structure:
- Root Cargo.toml: defines members = ["member*"] (glob pattern)
- member1/Cargo.toml: depends on gdb-command
- member2/Cargo.toml: uses { workspace = true } for regex dependency
Expected behavior:
- Same as explicit member list - glob should be expanded
- Virtual workspace root should have RelationshipRoot
- member1 and member2 should have RelationshipWorkspace
- Direct dependencies (gdb-command, regex) should have RelationshipDirect
-- Cargo.lock --
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
@@ -84,3 +101,30 @@ checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6"
dependencies = [
"libc",
]
-- Cargo.toml --
[workspace.package]
name = "toml-workspace-members"
version = "0.1.0"
[workspace]
resolver = "2"
members = ["member*"]
[workspace.dependencies]
regex = "1"
-- member1/Cargo.toml --
[package]
name = "member1"
version = "0.1.0"
edition = "2021"
[dependencies]
gdb-command = "0.7"
-- member2/Cargo.toml --
[package]
edition = "2021"
name = "member2"
version = "0.1.0"
[dependencies]
regex = { workspace = true}

View File

@@ -1,10 +0,0 @@
[workspace.package]
name = "toml-workspace-members"
version = "0.1.0"
[workspace]
resolver = "2"
members = ["member*"]
[workspace.dependencies]
regex = "1"

View File

@@ -1,7 +0,0 @@
[package]
name = "member1"
version = "0.1.0"
edition = "2021"
[dependencies]
gdb-command = "0.7"

View File

@@ -1,7 +0,0 @@
[package]
edition = "2021"
name = "member2"
version = "0.1.0"
[dependencies]
regex = { workspace = true}

View File

@@ -1,3 +1,20 @@
Test case: Cargo workspace with explicit member list.
This test verifies that the analyzer correctly handles Cargo workspaces with
explicitly listed members in [workspace].members.
Structure:
- Root Cargo.toml: defines members = ["member", "member2"]
- member/Cargo.toml: depends on gdb-command
- member2/Cargo.toml: uses { workspace = true } for regex dependency
Expected behavior:
- Virtual workspace root should have RelationshipRoot
- member and member2 should have RelationshipWorkspace
- gdb-command and regex should have RelationshipDirect
- Transitive dependencies should have RelationshipIndirect
-- Cargo.lock --
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
@@ -84,3 +101,30 @@ checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6"
dependencies = [
"libc",
]
-- Cargo.toml --
[workspace.package]
name = "toml-workspace-members"
version = "0.1.0"
[workspace]
resolver = "2"
members = ["member", "member2"]
[workspace.dependencies]
regex = "1"
-- member/Cargo.toml --
[package]
name = "member"
version = "0.1.0"
edition = "2021"
[dependencies]
gdb-command = "0.7"
-- member2/Cargo.toml --
[package]
edition = "2021"
name = "member2"
version = "0.1.0"
[dependencies]
regex = { workspace = true}

View File

@@ -1,10 +0,0 @@
[workspace.package]
name = "toml-workspace-members"
version = "0.1.0"
[workspace]
resolver = "2"
members = ["member", "member2"]
[workspace.dependencies]
regex = "1"

View File

@@ -1,7 +0,0 @@
[package]
name = "member"
version = "0.1.0"
edition = "2021"
[dependencies]
gdb-command = "0.7"

View File

@@ -1,7 +0,0 @@
[package]
edition = "2021"
name = "member2"
version = "0.1.0"
[dependencies]
regex = { workspace = true}

View File

@@ -0,0 +1,45 @@
Test case: Workspace with version.workspace = true inheritance.
This test verifies that the analyzer correctly handles Cargo workspaces where
member packages inherit version from [workspace.package].
Structure:
- Root Cargo.toml: defines [workspace.package] with version = "2.0.0"
- app/Cargo.toml: member package using version.workspace = true
Expected behavior:
- Virtual workspace root should have RelationshipRoot with no name/version
- myapp should have RelationshipWorkspace with version "2.0.0" (inherited)
- serde should have RelationshipDirect
-- Cargo.lock --
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "myapp"
version = "2.0.0"
dependencies = [
"serde",
]
[[package]]
name = "serde"
version = "1.0.195"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02"
-- Cargo.toml --
[workspace.package]
version = "2.0.0"
[workspace]
members = ["app"]
-- app/Cargo.toml --
[package]
name = "myapp"
version.workspace = true
edition = "2021"
[dependencies]
serde = "1.0"

View File

@@ -1,16 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "myapp"
version = "2.0.0"
dependencies = [
"serde",
]
[[package]]
name = "serde"
version = "1.0.195"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02"

View File

@@ -1,5 +0,0 @@
[workspace.package]
version = "2.0.0"
[workspace]
members = ["app"]

View File

@@ -1,7 +0,0 @@
[package]
name = "myapp"
version.workspace = true
edition = "2021"
[dependencies]
serde = "1.0"

View File

@@ -0,0 +1,29 @@
Test case: Malformed Cargo.toml with valid Cargo.lock.
This test verifies that the analyzer handles a corrupted Cargo.toml file gracefully.
The Cargo.toml contains only "[" which is invalid TOML, but Cargo.lock is valid.
Expected behavior:
- Fall back to parsing only Cargo.lock
- All packages should have RelationshipUnknown (cannot determine relationships)
- Package information should still be extracted from Cargo.lock
-- Cargo.lock --
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "app"
version = "0.1.0"
dependencies = [
"memchr 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "memchr"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
-- Cargo.toml --
[

View File

@@ -1,16 +0,0 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "app"
version = "0.1.0"
dependencies = [
"memchr 2.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "memchr"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"