Skip to content
Open
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
9 changes: 8 additions & 1 deletion rust/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
load("@rules_rust//rust:defs.bzl", "rust_clippy", "rust_library", "rust_test")

licenses(["notice"])

Expand Down Expand Up @@ -57,3 +57,10 @@ rust_test(
"@crate_index//:googletest",
],
)

rust_clippy(
name = "fuzztest_clippy",
deps = [
":fuzztest",
],
)
109 changes: 97 additions & 12 deletions rust/cargo_fuzztest/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
use anyhow::{Context, Result};
use clap::Parser;
pub use fuzztest_options::{
ExecutionMode, FuzzFor, FuzzOptions, FuzzTestOptions, ListCrashIdsOptions, ReplayCorpusOptions,
ReplayCrashOptions, TimeBudgetType,
ExecutionMode, FuzzOptions, FuzzTestOptions, ListCrashIdsOptions, ReplayCorpusOptions,
ReplayCrashOptions, RunDuration, TimeBudgetType,
};
use std::env;
use std::ffi::OsString;
Expand Down Expand Up @@ -95,7 +95,10 @@ impl CargoFuzzTestOptions {
if self.test_path.is_some() {
self.check_centipede_binary_path_is_set()?;
ExecutionMode::Fuzz(FuzzOptions {
fuzz_for: self.fuzztest_options.fuzz_for.unwrap_or(FuzzFor::Indefinitely),
fuzz_for: self
.fuzztest_options
.fuzz_for
.unwrap_or(RunDuration::Indefinitely),
jobs: self.fuzztest_options.jobs,
})
} else {
Expand Down Expand Up @@ -246,14 +249,7 @@ impl FuzztestRunner {

ExecutionMode::Fuzz(fuzz_options) => {
let FuzzOptions { fuzz_for, jobs } = fuzz_options;
match fuzz_for {
FuzzFor::Indefinitely => {
cmd.env("FUZZTEST_FUZZ_FOR", "inf");
}
FuzzFor::Duration(duration) => {
cmd.env("FUZZTEST_FUZZ_FOR", duration.to_string());
}
}
cmd.env("FUZZTEST_FUZZ_FOR", fuzz_for.to_string());
if let Some(jobs) = jobs {
cmd.env("FUZZTEST_JOBS", jobs.to_string());
}
Expand Down Expand Up @@ -610,7 +606,60 @@ mod tests {
assert_eq!(
mode,
ExecutionMode::ReplayCorpus(ReplayCorpusOptions {
replay_corpus_for: "10s".parse().unwrap(),
replay_corpus_for: "10s".parse().expect("valid duration string"),
time_budget_type: TimeBudgetType::PerTest,
jobs: None,
})
);
}

#[gtest]
fn test_cli_option_parsing_replay_corpus_for_inf() {
let parsed = CargoFuzzTestOptions::try_parse_from([
"cargo-fuzztest",
"--replay-corpus-for",
"inf",
"--corpus-db",
"/tmp/corpus_db",
"--centipede-binary-path",
"/custom/centipede",
])
.expect("valid replay-corpus-for inf should parse successfully");

assert_eq!(parsed.fuzztest_options.replay_corpus_for, Some(RunDuration::Indefinitely));
assert_eq!(parsed.fuzztest_options.time_budget_type, TimeBudgetType::PerTest);
assert_eq!(parsed.fuzztest_options.corpus_db.as_deref(), Some("/tmp/corpus_db"));

let mode = parsed.execution_mode().expect("valid execution mode");
assert_eq!(
mode,
ExecutionMode::ReplayCorpus(ReplayCorpusOptions {
replay_corpus_for: RunDuration::Indefinitely,
time_budget_type: TimeBudgetType::PerTest,
jobs: None,
})
);
}

#[gtest]
fn test_cli_option_parsing_replay_corpus_for_infinity() {
let parsed = CargoFuzzTestOptions::try_parse_from([
"cargo-fuzztest",
"--replay-corpus-for",
"infinity",
"--corpus-db",
"/tmp/corpus_db",
"--centipede-binary-path",
"/custom/centipede",
])
.expect("valid replay-corpus-for infinity should parse successfully");

assert_eq!(parsed.fuzztest_options.replay_corpus_for, Some(RunDuration::Indefinitely));
let mode = parsed.execution_mode().expect("valid execution mode");
assert_eq!(
mode,
ExecutionMode::ReplayCorpus(ReplayCorpusOptions {
replay_corpus_for: RunDuration::Indefinitely,
time_budget_type: TimeBudgetType::PerTest,
jobs: None,
})
Expand Down Expand Up @@ -794,4 +843,40 @@ mod tests {
Some("/custom/centipede".to_string())
)));
}

#[gtest]
fn test_build_run_command_replay_corpus_indefinite() {
let options = CargoFuzzTestOptions {
fuzztest_options: FuzzTestOptions {
replay_corpus_for: Some(RunDuration::Indefinitely),
time_budget_type: TimeBudgetType::Total,
corpus_db: Some("/tmp/corpus_db".to_string()),
..Default::default()
},
centipede_binary_path: Some("/custom/centipede".to_string()),
..Default::default()
};
let runner = FuzztestRunner::new("x86_64-unknown-linux-gnu".to_string(), options);
let cmd =
runner.build_run_command(Path::new("/tmp/test_bin")).expect("should build run command");

let envs: Vec<(String, Option<String>)> = cmd
.get_envs()
.map(|(k, v)| {
(k.to_string_lossy().to_string(), v.map(|s| s.to_string_lossy().to_string()))
})
.collect();

assert!(envs.contains(&("FUZZTEST_REPLAY_CORPUS_FOR".to_string(), Some("inf".to_string()))));
assert!(
envs.contains(&("FUZZTEST_TIME_BUDGET_TYPE".to_string(), Some("total".to_string())))
);
assert!(
envs.contains(&("FUZZTEST_CORPUS_DB".to_string(), Some("/tmp/corpus_db".to_string())))
);
assert!(envs.contains(&(
"FUZZTEST_CENTIPEDE_BINARY_PATH".to_string(),
Some("/custom/centipede".to_string())
)));
}
}
11 changes: 7 additions & 4 deletions rust/cargo_fuzztest/tests/e2e_cli_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ fn test_cargo_fuzztest_e2e_replay_corpus_total_budget() {
// 2. Run cargo-fuzztest CLI with --replay-corpus-for and --time-budget-type total.
let mut cmd = setup_cargo_fuzztest_command(&sample_crate_path, temp_target_dir.path());
cmd.arg("__fuzztest_mod__sample_fuzztest_target::sample_fuzztest_target")
.arg("--replay-corpus-for=3s")
.arg("--replay-corpus-for=4.5s")
.arg("--time-budget-type=total")
.arg("--corpus-db")
.arg(temp_db_dir.path())
Expand All @@ -376,12 +376,15 @@ fn test_cargo_fuzztest_e2e_replay_corpus_total_budget() {
let stderr_str = String::from_utf8_lossy(&output.stderr);
let stdout_str = String::from_utf8_lossy(&output.stdout);

eprintln!("tmp:: stderr:\n{stderr_str}");
eprintln!("tmp:: stdout:\n{stdout_str}");

expect_true!(output.status.success());
expect_true!(
stderr_str.contains(
"Replaying __fuzztest_mod__sample_fuzztest_target.sample_fuzztest_target for 1s"
"Replaying __fuzztest_mod__sample_fuzztest_target.sample_fuzztest_target for 1.5s"
) || stdout_str.contains(
"Replaying __fuzztest_mod__sample_fuzztest_target.sample_fuzztest_target for 1s"
"Replaying __fuzztest_mod__sample_fuzztest_target.sample_fuzztest_target for 1.5s"
)
);
}
Expand Down Expand Up @@ -409,7 +412,7 @@ fn test_cargo_fuzztest_e2e_list_crash_ids() {
let mut cmd = setup_cargo_fuzztest_command(&sample_crate_path, temp_target_dir.path());
cmd.arg(test_target)
.arg("--fuzz-for=5s")
.env_remove("CENTIPEDE_BINARY_PATH")
.env_remove("FUZZTEST_CENTIPEDE_BINARY_PATH")
.arg("--centipede-binary-path")
.arg(&centipede_bin)
.arg("--corpus-db")
Expand Down
49 changes: 42 additions & 7 deletions rust/cargo_fuzztest/tests/runner_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ mod common;

use cargo_fuzztest::{CargoFuzzTestOptions, FuzztestRunner};
use common::get_sample_test_bin_path;
use fuzztest_options::{FuzzFor, FuzzTestOptions, TimeBudgetType};
use fuzztest_options::{FuzzTestOptions, RunDuration, TimeBudgetType};
use googletest::prelude::*;

#[gtest]
Expand Down Expand Up @@ -45,10 +45,8 @@ fn test_runner_build_run_command_with_target() {
#[gtest]
fn test_runner_build_run_command_with_duration() {
let binary_path = get_sample_test_bin_path("sample_fuzz_crate");
let fuzztest_options = FuzzTestOptions {
fuzz_for: Some(FuzzFor::Duration("5s".parse().unwrap())),
..Default::default()
};
let fuzztest_options =
FuzzTestOptions { fuzz_for: Some("5s".parse().unwrap()), ..Default::default() };
let options = CargoFuzzTestOptions {
fuzztest_options,
centipede_binary_path: Some("/custom/path/to/centipede".to_string()),
Expand All @@ -68,7 +66,7 @@ fn test_runner_build_run_command_with_duration() {
fn test_runner_build_run_command_with_indefinitely() {
let binary_path = get_sample_test_bin_path("sample_fuzz_crate");
let fuzztest_options =
FuzzTestOptions { fuzz_for: Some(FuzzFor::Indefinitely), ..Default::default() };
FuzzTestOptions { fuzz_for: Some(RunDuration::Indefinitely), ..Default::default() };
let options = CargoFuzzTestOptions {
fuzztest_options,
centipede_binary_path: Some("/custom/path/to/centipede".to_string()),
Expand Down Expand Up @@ -109,7 +107,7 @@ fn test_runner_build_run_command_with_jobs() {
let binary_path = get_sample_test_bin_path("sample_fuzz_crate");
let fuzztest_options = FuzzTestOptions {
jobs: Some(4),
fuzz_for: Some(FuzzFor::Duration("10s".parse().expect("static valid duration string"))),
fuzz_for: Some("10s".parse().expect("static valid duration string")),
..Default::default()
};
let options = CargoFuzzTestOptions {
Expand Down Expand Up @@ -288,6 +286,43 @@ fn test_runner_build_run_command_with_replay_corpus() {
)));
}

#[gtest]
fn test_runner_build_run_command_with_replay_corpus_indefinitely() {
let binary_path = get_sample_test_bin_path("sample_fuzz_crate");
let fuzztest_options = FuzzTestOptions {
replay_corpus_for: Some(RunDuration::Indefinitely),
time_budget_type: TimeBudgetType::Total,
corpus_db: Some("/custom/path/to/corpus_db".to_string()),
..Default::default()
};
let options = CargoFuzzTestOptions {
fuzztest_options,
centipede_binary_path: Some("/custom/path/to/centipede".to_string()),
..Default::default()
};
let runner = FuzztestRunner::new("x86_64-unknown-linux-gnu".to_string(), options);
let cmd = runner.build_run_command(&binary_path).expect("valid run command");

let envs: Vec<(String, Option<String>)> = cmd
.get_envs()
.map(|(k, v)| (k.to_string_lossy().to_string(), v.map(|s| s.to_string_lossy().to_string())))
.collect();
expect_true!(
envs.contains(&("FUZZTEST_REPLAY_CORPUS_FOR".to_string(), Some("inf".to_string())))
);
expect_true!(
envs.contains(&("FUZZTEST_TIME_BUDGET_TYPE".to_string(), Some("total".to_string())))
);
expect_true!(envs.contains(&(
"FUZZTEST_CORPUS_DB".to_string(),
Some("/custom/path/to/corpus_db".to_string())
)));
expect_true!(envs.contains(&(
"FUZZTEST_CENTIPEDE_BINARY_PATH".to_string(),
Some("/custom/path/to/centipede".to_string())
)));
}

#[gtest]
fn test_execution_mode_replay_corpus_missing_centipede_binary_path_errors() {
let fuzztest_options = FuzzTestOptions {
Expand Down
9 changes: 8 additions & 1 deletion rust/coverage/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
load("@rules_rust//rust:defs.bzl", "rust_clippy", "rust_library", "rust_test")

licenses(["notice"])

Expand Down Expand Up @@ -48,3 +48,10 @@ rust_test(
"@crate_index//:googletest",
],
)

rust_clippy(
name = "coverage_clippy",
deps = [
":coverage",
],
)
9 changes: 8 additions & 1 deletion rust/engine/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

load("@rules_rust//rust:defs.bzl", "rust_library")
load("@rules_rust//rust:defs.bzl", "rust_clippy", "rust_library")

licenses(["notice"])

Expand All @@ -30,3 +30,10 @@ rust_library(
"@com_google_fuzztest//centipede:engine_worker",
],
)

rust_clippy(
name = "engine_clippy",
deps = [
":engine",
],
)
5 changes: 1 addition & 4 deletions rust/engine/src/engine_ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -185,10 +185,7 @@ impl FuzzTestUint64sView {
if self.data.is_null() {
&[]
} else {
ptr::slice_from_raw_parts(
self.data as *const u8,
self.size * core::mem::size_of::<u64>(),
)
ptr::slice_from_raw_parts(self.data as *const u8, self.size * size_of::<u64>())
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions rust/engine/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.

#![deny(clippy::absolute_paths)]
#![deny(unused_imports)]

pub mod engine_ffi;

use std::marker::PhantomData;
Expand Down
9 changes: 8 additions & 1 deletion rust/options/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.

load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
load("@rules_rust//rust:defs.bzl", "rust_clippy", "rust_library", "rust_test")

licenses(["notice"])

Expand Down Expand Up @@ -42,3 +42,10 @@ rust_test(
"@crate_index//:googletest",
],
)

rust_clippy(
name = "fuzztest_options_clippy",
deps = [
":fuzztest_options",
],
)
Loading