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
4 changes: 4 additions & 0 deletions rust/cargo_fuzztest/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ rust_library(
edition = "2024",
visibility = ["@com_google_fuzztest//rust:__subpackages__"],
deps = [
"@com_google_fuzztest//rust/options:fuzztest_options",
"@crate_index//:anyhow", # v1
"@crate_index//:clap", # v4
"@crate_index//:serde", # v1
Expand All @@ -36,13 +37,15 @@ rust_binary(
visibility = ["@com_google_fuzztest//rust:__subpackages__"],
deps = [
":cargo_fuzztest",
"@com_google_fuzztest//rust/options:fuzztest_options",
"@crate_index//:anyhow", # v1
"@crate_index//:clap", # v4
],
)

rust_test(
name = "cargo_fuzztest_lib_test",
args = ["--test-threads=1"],
crate = ":cargo_fuzztest",
edition = "2024",
deps = [
Expand Down Expand Up @@ -81,6 +84,7 @@ rust_test(
edition = "2024",
deps = [
":cargo_fuzztest",
"@com_google_fuzztest//rust/options:fuzztest_options",
"@crate_index//:anyhow", # v1
"@crate_index//:googletest",
],
Expand Down
35 changes: 19 additions & 16 deletions rust/cargo_fuzztest/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

use anyhow::{Context, Result};
use clap::Parser;
pub use fuzztest_options::{ExecutionMode, FuzzTestOptions};
use std::env;
use std::ffi::OsString;
use std::path::{Path, PathBuf};
Expand All @@ -28,31 +29,27 @@ fn get_cargo_bin() -> String {

#[derive(Parser, Debug, Clone, Default)]
pub struct CargoFuzzTestOptions {
#[command(flatten)]
pub fuzztest_options: FuzzTestOptions,

/// List all fuzz tests in the crate without running them.
#[arg(long)]
pub list: bool,
}

impl CargoFuzzTestOptions {
/// Returns the active domain `ExecutionMode` derived from CLI options.
/// Returns the `ExecutionMode` derived from CLI options.
pub fn execution_mode(&self) -> ExecutionMode {
if self.list {
return ExecutionMode::ListFuzzTests;
}

// TODO(the-shank): add support for other modes.
ExecutionMode::SmokeTest
}
}

/// Domain execution mode for `cargo-fuzztest`.
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ExecutionMode {
/// List all discovered fuzz tests without running them.
ListFuzzTests,

SmokeTest,
}

/// Queries cargo via `cargo -vV` to discover the default host target triple (e.g. `x86_64-unknown-linux-gnu`).
/// Queries Cargo via `cargo -vV` to discover the default host target triple (e.g. `x86_64-unknown-linux-gnu`).
pub fn get_host_target_triple() -> anyhow::Result<String> {
let cargo_bin = get_cargo_bin();
let output = Command::new(&cargo_bin)
Expand Down Expand Up @@ -141,8 +138,11 @@ impl FuzztestRunner {
continue;
}
if let Ok(val) = serde_json::from_str::<serde_json::Value>(trimmed) {
let is_compiler_artifact = val["reason"] == "compiler-artifact";
let is_test_profile = val["profile"]["test"].as_bool().unwrap_or(false);
let is_compiler_artifact =
val.get("reason").and_then(|r| r.as_str()) == Some("compiler-artifact");
let is_test_profile =
val.get("profile").and_then(|p| p.get("test")).and_then(|t| t.as_bool())
== Some(true);

if is_compiler_artifact
&& is_test_profile
Expand Down Expand Up @@ -178,6 +178,9 @@ impl FuzztestRunner {
ExecutionMode::SmokeTest => {
// nothing to be done
}
_ => {
// TODO(the-shank): add support for other modes.
}
}

cmd
Expand Down Expand Up @@ -253,7 +256,7 @@ mod tests {

#[gtest]
fn test_build_run_command_list() {
let options = CargoFuzzTestOptions { list: true };
let options = CargoFuzzTestOptions { list: true, ..Default::default() };
let runner = FuzztestRunner::new("sample-host-triple".to_string(), options);
let cmd = runner.build_run_command(Path::new("/tmp/test_bin"));
let args: Vec<String> = cmd.get_args().map(|a| a.to_string_lossy().to_string()).collect();
Expand All @@ -262,13 +265,13 @@ mod tests {

#[gtest]
fn test_execution_mode_smoke_test() {
let options = CargoFuzzTestOptions { list: false };
let options = CargoFuzzTestOptions { list: false, ..Default::default() };
assert_eq!(options.execution_mode(), ExecutionMode::SmokeTest);
}

#[gtest]
fn test_execution_mode_list_fuzz_tests() {
let options = CargoFuzzTestOptions { list: true };
let options = CargoFuzzTestOptions { list: true, ..Default::default() };
assert_eq!(options.execution_mode(), ExecutionMode::ListFuzzTests);
}

Expand Down
3 changes: 1 addition & 2 deletions rust/cargo_fuzztest/tests/runner_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ fn test_runner_execution() {
assert!(binary_path.exists(), "Sample fuzz binary does not exist at {}", binary_path.display());

let options = CargoFuzzTestOptions::default();

let runner = FuzztestRunner::new("sample-host-triple".to_string(), options);

let mut cmd = runner.build_run_command(&binary_path);
Expand All @@ -26,7 +25,7 @@ fn test_runner_list_command() {

assert!(binary_path.exists(), "Sample fuzz binary does not exist at {}", binary_path.display());

let options = CargoFuzzTestOptions { list: true };
let options = CargoFuzzTestOptions { list: true, ..Default::default() };

let runner = FuzztestRunner::new("sample-host-triple".to_string(), options);

Expand Down
4 changes: 4 additions & 0 deletions rust/options/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ pub enum ExecutionMode {

/// Replay corpus inputs for a specified duration.
ReplayCorpus(ReplayCorpusOptions),

/// List all discovered fuzz tests without running them.
/// Currently only supported via `cargo-fuzztest`.
ListFuzzTests,
}

impl ExecutionMode {
Expand Down
4 changes: 4 additions & 0 deletions rust/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ impl ExecutionModeExt for ExecutionMode {
.context("while attempting to build CentipedeArgs for replay all crashes mode")?;
Ok(ExecutionAction::ReplayAllCrashes { args: centipede_args, list_file })
}
ExecutionMode::ListFuzzTests => {
anyhow::bail!("ListFuzzTest mode is supported only in cargo-fuzztest");
}
}
}
}
Expand Down Expand Up @@ -254,6 +257,7 @@ impl CentipedeArgs {
add_arg(format!("--fuzztest_time_limit_per_test={time_limit}"))?;
}
ExecutionMode::SmokeTest => unreachable!(),
ExecutionMode::ListFuzzTests => unreachable!(),
}

Ok(Some(Self::new(args, opt_workdir)))
Expand Down
Loading