Bundle the Centipede binary with the subprocess engine controller. PiperOrigin-RevId: 994436974
diff --git a/centipede/BUILD b/centipede/BUILD index 3c045ca..ca7783e 100644 --- a/centipede/BUILD +++ b/centipede/BUILD
@@ -15,6 +15,7 @@ # Description: # Centipede: an experimental distributed fuzzing engine. +load("@bazel_skylib//rules:common_settings.bzl", "bool_flag") load("@rules_cc//cc:cc_binary.bzl", "cc_binary") load("@rules_cc//cc:cc_library.bzl", "cc_library") load("@rules_cc//cc:cc_static_library.bzl", "cc_static_library") @@ -1004,10 +1005,26 @@ ], ) +bool_flag( + name = "bundle_controller_binary", + build_setting_default = True, +) + +config_setting( + name = "is_controller_binary_bundled", + flag_values = {":bundle_controller_binary": "True"}, +) + cc_library( name = "engine_controller_with_subprocess", srcs = ["engine_controller_with_subprocess.cc"], hdrs = ["engine_controller_abi.h"], + data = select({ + ":is_controller_binary_bundled": [ + ":centipede_uninstrumented", + ], + "//conditions:default": [], + }), deps = [ "@com_google_fuzztest//centipede:engine_abi", "@com_google_fuzztest//fuzztest/internal:escaping",
diff --git a/centipede/centipede_test.cc b/centipede/centipede_test.cc index 3c45b83..1d7d830 100644 --- a/centipede/centipede_test.cc +++ b/centipede/centipede_test.cc
@@ -1551,17 +1551,13 @@ } TEST_F(CentipedeWithTemporaryLocalDir, EngineWorksInStandaloneMode) { - const std::string centipede_path = - GetDataDependencyFilepath("centipede/centipede"); const std::string test_binary_path = GetDataDependencyFilepath( "centipede/testing/test_binary_for_engine_testing"); // Create a temporary dir and enter it for running the test binary, because // the test binary uses CWD as the engine workdir. TempCorpusDir tmp_dir{test_info_->name()}; const auto test_command = - absl::StrCat("cd ", tmp_dir.path().string(), - " && env FUZZTEST_CENTIPEDE_BINARY_PATH=", centipede_path, - " ", test_binary_path); + absl::StrCat("cd ", tmp_dir.path().string(), " && ", test_binary_path); EXPECT_DEATH( [&] { const int status = std::system(test_command.c_str());
diff --git a/centipede/engine_controller_with_subprocess.cc b/centipede/engine_controller_with_subprocess.cc index 2ffc89d..078cd61 100644 --- a/centipede/engine_controller_with_subprocess.cc +++ b/centipede/engine_controller_with_subprocess.cc
@@ -14,25 +14,64 @@ #include <sys/wait.h> +#include <cstdio> #include <cstdlib> #include <cstring> +#include <filesystem> // NOLINT #include <string> +#include <system_error> // NOLINT #include "./centipede/engine_abi.h" #include "./centipede/engine_controller_abi.h" #include "./fuzztest/internal/escaping.h" +namespace { + using fuzztest::internal::ShellEscape; +std::string GetBundledCentipedeBinaryPath() { + constexpr const char* kBundledCentipedePathSuffix = + "centipede/centipede_uninstrumented"; + const char* test_workspace = std::getenv("TEST_WORKSPACE"); + if (test_workspace == nullptr) { + test_workspace = "_main"; + } + std::string runfiles_dir; + if (const char* test_srcdir = std::getenv("TEST_SRCDIR"); + test_srcdir != nullptr) { + runfiles_dir = test_srcdir; + } + std::error_code ec; + if (!runfiles_dir.empty()) { + const auto path = std::filesystem::path{runfiles_dir} / test_workspace / + kBundledCentipedePathSuffix; + if (std::filesystem::exists(path, ec)) { + return path.string(); + } + } + return ""; +} + +} // namespace + FuzzTestControllerStatus FuzzTestControllerRun( const FuzzTestAdapterManager* manager, const FuzzTestBytesViews* flags) { - // TODO(xinhaoyuan): Use the FuzzTest controller env var later. static auto centipede_binary_path = []() -> const char* { - const char* env = std::getenv("FUZZTEST_CENTIPEDE_BINARY_PATH"); - if (env == nullptr) return nullptr; - return strdup(env); + // TODO(xinhaoyuan): Use the FuzzTest controller env var later. + if (const char* env = std::getenv("FUZZTEST_CENTIPEDE_BINARY_PATH"); + env != nullptr) { + return strdup(env); + } + const std::string bundled_path = GetBundledCentipedeBinaryPath(); + if (!bundled_path.empty()) { + return strdup(bundled_path.c_str()); + } + return nullptr; }(); if (centipede_binary_path == nullptr) { + fprintf(stderr, + "Failed to locate the controller binary - please specify the env " + "var `FUZZTEST_CENTIPEDE_BINARY_PATH`\n"); return kFuzzTestControllerFailure; } std::string command;
diff --git a/rust/e2e_tests/BUILD b/rust/e2e_tests/BUILD index 6eeab33..bc706bd 100644 --- a/rust/e2e_tests/BUILD +++ b/rust/e2e_tests/BUILD
@@ -33,7 +33,6 @@ name = "standalone_mode_test", srcs = ["standalone_mode_test.rs"], data = [ - "@com_google_fuzztest//centipede:centipede_uninstrumented", "@com_google_fuzztest//rust/e2e_tests/testdata:fuzztest_main", "@com_google_fuzztest//rust/e2e_tests/testdata:standalone_fuzz_tests_bin", ], @@ -100,7 +99,6 @@ name = "replay_test", srcs = ["replay_test.rs"], data = [ - "@com_google_fuzztest//centipede:centipede_uninstrumented", "@com_google_fuzztest//rust/e2e_tests/testdata:replay_fuzz_tests_bin", ], edition = "2024",
diff --git a/rust/e2e_tests/replay_test.rs b/rust/e2e_tests/replay_test.rs index 80c37ed..388bbb4 100644 --- a/rust/e2e_tests/replay_test.rs +++ b/rust/e2e_tests/replay_test.rs
@@ -51,7 +51,6 @@ .env("FUZZTEST_CONTINUE_AFTER_CRASH", "true") .env("FUZZTEST_CORPUS_DB", &db_dir) .env("FUZZTEST_WORKDIR_ROOT", &workdir_root_dir) - .env("FUZZTEST_CENTIPEDE_BINARY_PATH", &fixture.centipede_path) .status() .expect("Failed to spawn binary"); @@ -64,7 +63,6 @@ .env("FUZZTEST_LIST_CRASH_IDS", "true") .env("FUZZTEST_LIST_CRASH_IDS_FILE", &crash_ids_file) .env("FUZZTEST_CORPUS_DB", &db_dir) - .env("FUZZTEST_CENTIPEDE_BINARY_PATH", &fixture.centipede_path) .status() .expect("Failed to execute target binary to list crash IDs"); expect_true!(status.success()); @@ -87,7 +85,6 @@ .arg("--nocapture") .env("FUZZTEST_REPLAY_ID", crash_id) .env("FUZZTEST_CORPUS_DB", &db_dir) - .env("FUZZTEST_CENTIPEDE_BINARY_PATH", &fixture.centipede_path) .stdout(Stdio::piped()) .stderr(Stdio::piped()) .spawn() @@ -131,7 +128,6 @@ .env("FUZZTEST_CONTINUE_AFTER_CRASH", "true") .env("FUZZTEST_CORPUS_DB", &db_dir) .env("FUZZTEST_WORKDIR_ROOT", &workdir_root_dir) - .env("FUZZTEST_CENTIPEDE_BINARY_PATH", &fixture.centipede_path) .status() .expect("Failed to spawn binary"); @@ -141,7 +137,6 @@ .arg("--exact") .env("FUZZTEST_REPLAY_FINDINGS", "true") .env("FUZZTEST_CORPUS_DB", &db_dir) - .env("FUZZTEST_CENTIPEDE_BINARY_PATH", &fixture.centipede_path) .stdout(Stdio::piped()) .stderr(Stdio::piped()) .spawn()
diff --git a/rust/e2e_tests/standalone_mode_test.rs b/rust/e2e_tests/standalone_mode_test.rs index 2ca7acc..f0e0dde 100644 --- a/rust/e2e_tests/standalone_mode_test.rs +++ b/rust/e2e_tests/standalone_mode_test.rs
@@ -27,7 +27,6 @@ .arg(test_name) .env("FUZZTEST_FUZZ_FOR", "3s") .env("FUZZTEST_PRINT_SUBPROCESS_LOG", "true") - .env("FUZZTEST_CENTIPEDE_BINARY_PATH", &fixture.centipede_path) .env("RUST_TEST_NOCAPTURE", "1") .stdout(std::process::Stdio::piped()) .stderr(std::process::Stdio::piped()) @@ -39,8 +38,8 @@ // Assert that Centipede actually ran the test binary, and forwarded the worker log. // We check for "LOG: STANDALONE_VALIDATION_WORKER_EXECUTED". The prefix "LOG: " indicates that - // this output is from centipede forwarding the output of the worker (due to --print_runner_log), - // whereas the rest is from the fuzztest itself. + // this output is from centipede forwarding the output of the worker (due to + // --print_runner_log), whereas the rest is from the fuzztest itself. expect_that!( stderr, matchers::contains_substring("LOG: STANDALONE_VALIDATION_WORKER_EXECUTED") @@ -57,7 +56,6 @@ .arg(test_name) .env("FUZZTEST_FUZZ_FOR", "3s") .env("FUZZTEST_PRINT_SUBPROCESS_LOG", "true") - .env("FUZZTEST_CENTIPEDE_BINARY_PATH", &fixture.centipede_path) .env("RUST_TEST_NOCAPTURE", "1") .stdout(std::process::Stdio::piped()) .stderr(std::process::Stdio::piped()) @@ -85,7 +83,6 @@ .arg(test_name) .env("FUZZTEST_FUZZ_FOR", "15s") .env("FUZZTEST_PRINT_SUBPROCESS_LOG", "true") - .env("FUZZTEST_CENTIPEDE_BINARY_PATH", &fixture.centipede_path) .env("RUST_TEST_NOCAPTURE", "1") .stdout(std::process::Stdio::piped()) .stderr(std::process::Stdio::piped()) @@ -111,7 +108,6 @@ .env("FUZZTEST_FUZZ_FOR", "15s") .env("FUZZTEST_CONTINUE_AFTER_CRASH", "true") .env("FUZZTEST_PRINT_SUBPROCESS_LOG", "true") - .env("FUZZTEST_CENTIPEDE_BINARY_PATH", &fixture.centipede_path) .env("RUST_TEST_NOCAPTURE", "1") .stdout(std::process::Stdio::piped()) .stderr(std::process::Stdio::piped()) @@ -138,7 +134,6 @@ .env("FUZZTEST_FUZZ_FOR", "5s") .env("FUZZTEST_JOBS", "4") .env("FUZZTEST_PRINT_SUBPROCESS_LOG", "true") - .env("FUZZTEST_CENTIPEDE_BINARY_PATH", &fixture.centipede_path) .env("RUST_TEST_NOCAPTURE", "1") .stdout(std::process::Stdio::piped()) .stderr(std::process::Stdio::piped()) @@ -215,7 +210,6 @@ .env("FUZZTEST_REPLAY_CORPUS_FOR", "3s") .env("FUZZTEST_TIME_BUDGET_TYPE", "per-test") .env("FUZZTEST_PRINT_SUBPROCESS_LOG", "true") - .env("FUZZTEST_CENTIPEDE_BINARY_PATH", &fixture.centipede_path) .env("FUZZTEST_CORPUS_DB", corpus_db.to_str().unwrap()) .env("FUZZTEST_WORKDIR_ROOT", workdir_root.to_str().unwrap()) .env("RUST_TEST_NOCAPTURE", "1") @@ -307,7 +301,6 @@ .env("FUZZTEST_REPLAY_CORPUS_FOR", "3s") .env("FUZZTEST_TIME_BUDGET_TYPE", "total") .env("FUZZTEST_PRINT_SUBPROCESS_LOG", "true") - .env("FUZZTEST_CENTIPEDE_BINARY_PATH", &fixture.centipede_path) .env("FUZZTEST_CORPUS_DB", corpus_db.to_str().unwrap()) .env("FUZZTEST_WORKDIR_ROOT", workdir_root.to_str().unwrap()) .env("RUST_TEST_NOCAPTURE", "1")