Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions crates/socket-patch-cli/tests/cli_global_args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ fn global_flag_cases_cover_every_global_field() {
/// shipped unguarded). Derive the long-flag set from clap itself and demand a
/// case for each — this cannot drift.
#[test]
#[serial_test::parallel]
fn global_flag_cases_cover_every_global_long_flag() {
use clap::CommandFactory;

Expand Down Expand Up @@ -273,6 +274,7 @@ fn global_flag_cases_cover_every_global_long_flag() {
/// `GlobalArgs`, or forgets to add it here), this fails loudly instead of
/// silently leaving the new command untested.
#[test]
#[serial_test::parallel]
fn all_subcommands_are_covered() {
use clap::CommandFactory;

Expand Down
29 changes: 29 additions & 0 deletions crates/socket-patch-core/tests/crawler_cargo_e2e.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ async fn stage_vendor_crate(src: &Path, name: &str, version: &str) -> std::path:
// ── parse_cargo_toml_name_version ──────────────────────────────

#[test]
#[serial_test::parallel]
fn parse_cargo_toml_well_formed() {
let toml = "[package]\nname = \"serde\"\nversion = \"1.0.200\"\nedition = \"2021\"\n";
assert_eq!(
Expand All @@ -53,18 +54,21 @@ fn parse_cargo_toml_well_formed() {
}

#[test]
#[serial_test::parallel]
fn parse_cargo_toml_missing_name_returns_none() {
let toml = "[package]\nversion = \"1.0.200\"\n";
assert_eq!(parse_cargo_toml_name_version(toml), None);
}

#[test]
#[serial_test::parallel]
fn parse_cargo_toml_missing_version_returns_none() {
let toml = "[package]\nname = \"serde\"\n";
assert_eq!(parse_cargo_toml_name_version(toml), None);
}

#[test]
#[serial_test::parallel]
fn parse_cargo_toml_malformed_returns_none() {
let toml = "this is not toml at all";
assert_eq!(parse_cargo_toml_name_version(toml), None);
Expand All @@ -75,6 +79,7 @@ fn parse_cargo_toml_malformed_returns_none() {
/// picked up. Covers the "left package section" early-break arm
/// (cargo_crawler.rs:34-36).
#[test]
#[serial_test::parallel]
fn parse_cargo_toml_stops_at_next_section() {
let toml = "[package]\nname = \"foo\"\nversion = \"1.0.0\"\n\n[dependencies]\nname = \"bar\"\n";
assert_eq!(
Expand All @@ -86,6 +91,7 @@ fn parse_cargo_toml_stops_at_next_section() {
/// Parser must ignore key=value lines that appear BEFORE [package]
/// (e.g. inside an earlier [profile.release] table).
#[test]
#[serial_test::parallel]
fn parse_cargo_toml_ignores_lines_before_package_section() {
let toml =
"[profile.release]\nname = \"wrong\"\n\n[package]\nname = \"foo\"\nversion = \"1.0.0\"\n";
Expand All @@ -98,6 +104,7 @@ fn parse_cargo_toml_ignores_lines_before_package_section() {
/// CargoCrawler's `Default` impl forwards to `new`. Exercise both
/// for symmetry.
#[test]
#[serial_test::parallel]
fn cargo_crawler_default_and_new_construct_cleanly() {
let _a = CargoCrawler;
let _b = CargoCrawler::new();
Expand Down Expand Up @@ -153,6 +160,7 @@ async fn cargo_home_fallback_to_home_dot_cargo() {
// ── find_by_purls ──────────────────────────────────────────────

#[tokio::test]
#[serial_test::parallel]
async fn find_by_purls_registry_layout_finds_crate() {
let tmp = tempfile::tempdir().unwrap();
let pkg = stage_registry_crate(tmp.path(), "serde", "1.0.200").await;
Expand All @@ -172,6 +180,7 @@ async fn find_by_purls_registry_layout_finds_crate() {
}

#[tokio::test]
#[serial_test::parallel]
async fn find_by_purls_vendor_layout_finds_crate() {
let tmp = tempfile::tempdir().unwrap();
let pkg = stage_vendor_crate(tmp.path(), "serde", "1.0.200").await;
Expand All @@ -192,6 +201,7 @@ async fn find_by_purls_vendor_layout_finds_crate() {
}

#[tokio::test]
#[serial_test::parallel]
async fn find_by_purls_vendor_version_mismatch_returns_empty() {
let tmp = tempfile::tempdir().unwrap();
stage_vendor_crate(tmp.path(), "serde", "1.0.200").await;
Expand All @@ -205,6 +215,7 @@ async fn find_by_purls_vendor_version_mismatch_returns_empty() {
}

#[tokio::test]
#[serial_test::parallel]
async fn find_by_purls_no_match_returns_empty() {
let tmp = tempfile::tempdir().unwrap();
let crawler = CargoCrawler;
Expand All @@ -216,6 +227,7 @@ async fn find_by_purls_no_match_returns_empty() {
}

#[tokio::test]
#[serial_test::parallel]
async fn find_by_purls_invalid_purl_skipped() {
let tmp = tempfile::tempdir().unwrap();
let crawler = CargoCrawler;
Expand All @@ -229,6 +241,7 @@ async fn find_by_purls_invalid_purl_skipped() {
// ── crawl_all ─────────────────────────────────────────────────

#[tokio::test]
#[serial_test::parallel]
async fn crawl_all_via_registry_layout() {
let tmp = tempfile::tempdir().unwrap();
stage_registry_crate(tmp.path(), "serde", "1.0.200").await;
Expand Down Expand Up @@ -267,6 +280,7 @@ async fn crawl_all_via_registry_layout() {
}

#[tokio::test]
#[serial_test::parallel]
async fn crawl_all_empty_src_returns_empty() {
let tmp = tempfile::tempdir().unwrap();
let crawler = CargoCrawler;
Expand All @@ -282,6 +296,7 @@ async fn crawl_all_empty_src_returns_empty() {
// ── get_crate_source_paths ─────────────────────────────────────

#[tokio::test]
#[serial_test::parallel]
async fn get_crate_source_paths_with_global_prefix_passthrough() {
let tmp = tempfile::tempdir().unwrap();
let crawler = CargoCrawler;
Expand All @@ -295,6 +310,7 @@ async fn get_crate_source_paths_with_global_prefix_passthrough() {
}

#[tokio::test]
#[serial_test::parallel]
async fn get_crate_source_paths_with_vendor_dir_returns_vendor() {
let tmp = tempfile::tempdir().unwrap();
let vendor = tmp.path().join("vendor");
Expand All @@ -321,6 +337,7 @@ async fn get_crate_source_paths_with_vendor_dir_returns_vendor() {
/// manifest (e.g. a Composer/Go project) must NOT be claimed by the
/// cargo crawler.
#[tokio::test]
#[serial_test::parallel]
async fn get_crate_source_paths_vendor_without_cargo_manifest_is_empty() {
let tmp = tempfile::tempdir().unwrap();
tokio::fs::create_dir(tmp.path().join("vendor"))
Expand All @@ -339,6 +356,7 @@ async fn get_crate_source_paths_vendor_without_cargo_manifest_is_empty() {
}

#[tokio::test]
#[serial_test::parallel]
async fn get_crate_source_paths_no_cargo_project_returns_empty() {
let tmp = tempfile::tempdir().unwrap();
// No Cargo.toml, no Cargo.lock, no vendor.
Expand All @@ -357,6 +375,7 @@ async fn get_crate_source_paths_no_cargo_project_returns_empty() {
/// parsing `<name>-<version>` from the directory name. Exercises
/// `parse_dir_name_version` (cargo_crawler.rs:357-372).
#[tokio::test]
#[serial_test::parallel]
async fn crawl_all_falls_back_to_dir_name_when_workspace_version() {
let tmp = tempfile::tempdir().unwrap();
// <name>-<version> directory; Cargo.toml has workspace version.
Expand All @@ -382,6 +401,7 @@ async fn crawl_all_falls_back_to_dir_name_when_workspace_version() {
}

#[tokio::test]
#[serial_test::parallel]
async fn crawl_all_skips_dir_without_cargo_toml() {
let tmp = tempfile::tempdir().unwrap();
// Directory shaped like a crate but no Cargo.toml — must be skipped.
Expand All @@ -402,6 +422,7 @@ async fn crawl_all_skips_dir_without_cargo_toml() {
/// version, find_by_purls compares dir name. Exercises the
/// fallback arm in `verify_crate_at_path` (L335-L348).
#[tokio::test]
#[serial_test::parallel]
async fn find_by_purls_verify_fallback_via_dir_name() {
let tmp = tempfile::tempdir().unwrap();
let pkg = tmp.path().join("workspace-crate-0.1.0");
Expand Down Expand Up @@ -434,6 +455,7 @@ async fn find_by_purls_verify_fallback_via_dir_name() {
/// parsing — but `parse_cargo_toml_name_version` itself must return
/// None up front.
#[test]
#[serial_test::parallel]
fn parse_cargo_toml_version_workspace_returns_none() {
let toml = "[package]\nname = \"foo\"\nversion.workspace = true\n";
assert_eq!(parse_cargo_toml_name_version(toml), None);
Expand All @@ -448,6 +470,7 @@ fn parse_cargo_toml_version_workspace_returns_none() {
/// Exercises the `n == name && v == version` false arm
/// (cargo_crawler.rs:349).
#[tokio::test]
#[serial_test::parallel]
async fn find_by_purls_verify_fallback_dir_name_mismatch_returns_empty() {
let tmp = tempfile::tempdir().unwrap();
let pkg = tmp.path().join("sha-1");
Expand All @@ -472,6 +495,7 @@ async fn find_by_purls_verify_fallback_dir_name_mismatch_returns_empty() {
/// Hidden directory entries inside the crate source root must be
/// skipped by `scan_crate_source` (line 274).
#[tokio::test]
#[serial_test::parallel]
async fn crawl_all_skips_hidden_dirs() {
let tmp = tempfile::tempdir().unwrap();
// Stage a hidden dir that looks like a registry crate — must be skipped.
Expand Down Expand Up @@ -505,6 +529,7 @@ async fn crawl_all_skips_hidden_dirs() {
/// been recorded in `seen` (line 310-311). Drive this by staging two
/// registry dirs for the same crate — the second one is deduped.
#[tokio::test]
#[serial_test::parallel]
async fn crawl_all_dedups_same_purl() {
let tmp = tempfile::tempdir().unwrap();
// Two physical dirs with identical Cargo.toml -> same purl.
Expand Down Expand Up @@ -572,6 +597,7 @@ async fn get_crate_source_paths_local_cargo_toml_falls_back_to_registry() {
/// `scan_crate_source` must skip plain-file entries inside the source
/// path — covers `!ft.is_dir()` continue arm (cargo_crawler.rs:266).
#[tokio::test]
#[serial_test::parallel]
async fn crawl_all_skips_top_level_files() {
let tmp = tempfile::tempdir().unwrap();
stage_registry_crate(tmp.path(), "real-crate", "1.0.0").await;
Expand All @@ -596,6 +622,7 @@ async fn crawl_all_skips_top_level_files() {
/// followed by digit), so the chain short-circuits at line 304 and
/// the package is silently skipped.
#[tokio::test]
#[serial_test::parallel]
async fn crawl_all_skips_crate_with_unparseable_toml_and_no_version_dir_name() {
let tmp = tempfile::tempdir().unwrap();
let bad = tmp.path().join("no-version-suffix");
Expand Down Expand Up @@ -625,6 +652,7 @@ mod common;
/// it. Skipped under root because chmod has no effect on uid 0.
#[cfg(unix)]
#[tokio::test]
#[serial_test::parallel]
async fn crawl_all_handles_unreadable_src_path() {
if common::uid_is_root() {
eprintln!("SKIP: chmod 000 is a no-op under root");
Expand Down Expand Up @@ -658,6 +686,7 @@ async fn crawl_all_handles_unreadable_src_path() {
/// dir-name-fallback `is_some_and` short-circuit on `None`
/// (cargo_crawler.rs:346-349).
#[tokio::test]
#[serial_test::parallel]
async fn find_by_purls_verify_fails_when_both_parsers_fail() {
let tmp = tempfile::tempdir().unwrap();
let bad = tmp.path().join("foo");
Expand Down
16 changes: 16 additions & 0 deletions crates/socket-patch-core/tests/crawler_composer_e2e.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,14 @@ use socket_patch_core::crawlers::types::CrawlerOptions;
use socket_patch_core::crawlers::ComposerCrawler;

#[test]
#[serial_test::parallel]
fn parse_composer_home_output_well_formed() {
let p = parse_composer_home_output("/Users/foo/.composer\n").unwrap();
assert_eq!(p, std::path::PathBuf::from("/Users/foo/.composer"));
}

#[test]
#[serial_test::parallel]
fn parse_composer_home_output_empty_returns_none() {
assert_eq!(parse_composer_home_output(""), None);
assert_eq!(parse_composer_home_output(" \n "), None);
Expand Down Expand Up @@ -65,6 +67,7 @@ async fn stage_composer_project(root: &Path, vendor_name: &str, pkg_name: &str,
// ── find_by_purls ──────────────────────────────────────────────

#[tokio::test]
#[serial_test::parallel]
async fn find_by_purls_finds_package_in_vendor() {
let tmp = tempfile::tempdir().unwrap();
stage_composer_project(tmp.path(), "monolog", "monolog", "3.5.0").await;
Expand All @@ -89,6 +92,7 @@ async fn find_by_purls_finds_package_in_vendor() {
}

#[tokio::test]
#[serial_test::parallel]
async fn find_by_purls_no_installed_json_returns_empty() {
let tmp = tempfile::tempdir().unwrap();
let vendor = tmp.path().join("vendor");
Expand Down Expand Up @@ -133,6 +137,7 @@ async fn find_by_purls_no_installed_json_returns_empty() {
}

#[tokio::test]
#[serial_test::parallel]
async fn find_by_purls_invalid_purl_skipped() {
let tmp = tempfile::tempdir().unwrap();
stage_composer_project(tmp.path(), "monolog", "monolog", "3.5.0").await;
Expand All @@ -149,6 +154,7 @@ async fn find_by_purls_invalid_purl_skipped() {
}

#[tokio::test]
#[serial_test::parallel]
async fn find_by_purls_version_mismatch_returns_empty() {
let tmp = tempfile::tempdir().unwrap();
stage_composer_project(tmp.path(), "monolog", "monolog", "3.5.0").await;
Expand All @@ -167,6 +173,7 @@ async fn find_by_purls_version_mismatch_returns_empty() {
// ── crawl_all ─────────────────────────────────────────────────

#[tokio::test]
#[serial_test::parallel]
async fn crawl_all_via_installed_json_returns_packages() {
let tmp = tempfile::tempdir().unwrap();
stage_composer_project(tmp.path(), "monolog", "monolog", "3.5.0").await;
Expand All @@ -190,6 +197,7 @@ async fn crawl_all_via_installed_json_returns_packages() {
}

#[tokio::test]
#[serial_test::parallel]
async fn crawl_all_with_corrupt_installed_json_returns_empty() {
let tmp = tempfile::tempdir().unwrap();
let vendor = tmp.path().join("vendor");
Expand Down Expand Up @@ -238,6 +246,7 @@ async fn crawl_all_with_corrupt_installed_json_returns_empty() {
// ── get_vendor_paths ──────────────────────────────────────────

#[tokio::test]
#[serial_test::parallel]
async fn get_vendor_paths_with_global_prefix_passthrough() {
let tmp = tempfile::tempdir().unwrap();
let crawler = ComposerCrawler;
Expand All @@ -251,6 +260,7 @@ async fn get_vendor_paths_with_global_prefix_passthrough() {
}

#[tokio::test]
#[serial_test::parallel]
async fn get_vendor_paths_local_no_vendor_returns_empty() {
let tmp = tempfile::tempdir().unwrap();
let crawler = ComposerCrawler;
Expand All @@ -262,6 +272,7 @@ async fn get_vendor_paths_local_no_vendor_returns_empty() {
}

#[tokio::test]
#[serial_test::parallel]
async fn get_vendor_paths_local_no_installed_json_returns_empty() {
let tmp = tempfile::tempdir().unwrap();
let vendor = tmp.path().join("vendor");
Expand All @@ -283,6 +294,7 @@ async fn get_vendor_paths_local_no_installed_json_returns_empty() {
}

#[tokio::test]
#[serial_test::parallel]
async fn get_vendor_paths_local_no_composer_marker_returns_empty() {
let tmp = tempfile::tempdir().unwrap();
let vendor = tmp.path().join("vendor");
Expand All @@ -305,6 +317,7 @@ async fn get_vendor_paths_local_no_composer_marker_returns_empty() {
}

#[tokio::test]
#[serial_test::parallel]
async fn get_vendor_paths_local_full_setup_returns_vendor() {
let tmp = tempfile::tempdir().unwrap();
let vendor = tmp.path().join("vendor");
Expand Down Expand Up @@ -581,6 +594,7 @@ mod common;
/// rather than panicking.
#[cfg(unix)]
#[tokio::test]
#[serial_test::parallel]
async fn find_by_purls_handles_unreadable_installed_json() {
if common::uid_is_root() {
eprintln!("SKIP: chmod 000 is a no-op under root");
Expand Down Expand Up @@ -635,6 +649,7 @@ async fn find_by_purls_handles_unreadable_installed_json() {
/// vendor paths sharing the same installed package — exercises the
/// `seen.contains` early-continue arm.
#[tokio::test]
#[serial_test::parallel]
async fn crawl_all_dedups_across_vendor_paths() {
let tmp = tempfile::tempdir().unwrap();
let custom_vendor = tmp.path().join("custom-vendor");
Expand Down Expand Up @@ -668,6 +683,7 @@ async fn crawl_all_dedups_across_vendor_paths() {
}

#[tokio::test]
#[serial_test::parallel]
async fn get_vendor_paths_local_with_lock_marker_also_works() {
let tmp = tempfile::tempdir().unwrap();
let vendor = tmp.path().join("vendor");
Expand Down
Loading
Loading