@@ -68,8 +68,8 @@ class CentipedeMock : public CentipedeCallbacks {
6868 // Doesn't execute anything
6969 // Sets `batch_result.results()` based on the values of `inputs`:
7070 // Collects various stats about the inputs, to be checked in tests.
71- bool Execute (std::string_view binary, const std::vector<ByteArray> & inputs,
72- BatchResult & batch_result) override {
71+ bool Execute (std::string_view binary, const std::vector<ByteArray>& inputs,
72+ BatchResult& batch_result, absl::Time deadline ) override {
7373 batch_result.results ().clear ();
7474 // For every input, we create a 256-element array `counters`, where
7575 // i-th element is the number of bytes with the value 'i' in the input.
@@ -356,8 +356,8 @@ class MutateCallbacks : public CentipedeCallbacks {
356356 public:
357357 explicit MutateCallbacks (const Environment &env) : CentipedeCallbacks(env) {}
358358 // Will not be called.
359- bool Execute (std::string_view binary, const std::vector<ByteArray> & inputs,
360- BatchResult & batch_result) override {
359+ bool Execute (std::string_view binary, const std::vector<ByteArray>& inputs,
360+ BatchResult& batch_result, absl::Time deadline ) override {
361361 FUZZTEST_LOG (FATAL);
362362 return false ;
363363 }
@@ -499,8 +499,8 @@ class MergeMock : public CentipedeCallbacks {
499499 // Doesn't execute anything.
500500 // All inputs are 1-byte long.
501501 // For an input {X}, the feature output is {X}.
502- bool Execute (std::string_view binary, const std::vector<ByteArray> & inputs,
503- BatchResult & batch_result) override {
502+ bool Execute (std::string_view binary, const std::vector<ByteArray>& inputs,
503+ BatchResult& batch_result, absl::Time deadline ) override {
504504 batch_result.results ().resize (inputs.size ());
505505 for (size_t i = 0 , n = inputs.size (); i < n; ++i) {
506506 FUZZTEST_CHECK_EQ (inputs[i].size (), 1 );
@@ -588,10 +588,10 @@ class FunctionFilterMock : public CentipedeCallbacks {
588588 }
589589
590590 // Executes the target in the normal way.
591- bool Execute (std::string_view binary, const std::vector<ByteArray> & inputs,
592- BatchResult & batch_result) override {
593- return ExecuteCentipedeSancovBinaryWithShmem (env_. binary , inputs,
594- batch_result) == EXIT_SUCCESS;
591+ bool Execute (std::string_view binary, const std::vector<ByteArray>& inputs,
592+ BatchResult& batch_result, absl::Time deadline ) override {
593+ return ExecuteCentipedeSancovBinaryWithShmem (
594+ env_. binary , inputs, batch_result, deadline ) == EXIT_SUCCESS;
595595 }
596596
597597 // Sets the inputs to one of 3 pre-defined values.
@@ -696,8 +696,8 @@ class ExtraBinariesMock : public CentipedeCallbacks {
696696
697697 // Doesn't execute anything.
698698 // On certain combinations of {binary,input} returns false.
699- bool Execute (std::string_view binary, const std::vector<ByteArray> & inputs,
700- BatchResult & batch_result) override {
699+ bool Execute (std::string_view binary, const std::vector<ByteArray>& inputs,
700+ BatchResult& batch_result, absl::Time deadline ) override {
701701 bool res = true ;
702702 for (const auto &input : inputs) {
703703 if (input.size () != 1 ) continue ;
@@ -814,8 +814,8 @@ class UndetectedCrashingInputMock : public CentipedeCallbacks {
814814 // Doesn't execute anything.
815815 // Crash when 0th char of input to binary b1 equals `crashing_input_idx_`, but
816816 // only on 1st exec.
817- bool Execute (std::string_view binary, const std::vector<ByteArray> & inputs,
818- BatchResult & batch_result) override {
817+ bool Execute (std::string_view binary, const std::vector<ByteArray>& inputs,
818+ BatchResult& batch_result, absl::Time deadline ) override {
819819 batch_result.ClearAndResize (inputs.size ());
820820 bool res = true ;
821821 if (!first_pass_) {
@@ -982,7 +982,8 @@ TEST_F(CentipedeWithTemporaryLocalDir, CleansUpMetadataAfterStartup) {
982982
983983 BatchResult batch_result;
984984 const std::vector<ByteArray> inputs = {{0 }};
985- ASSERT_TRUE (callbacks.Execute (env.binary , inputs, batch_result));
985+ ASSERT_TRUE (callbacks.Execute (env.binary , inputs, batch_result,
986+ /* deadline=*/ absl::InfiniteFuture ()));
986987 ASSERT_EQ (batch_result.results ().size (), 1 );
987988 bool found_startup_cmp_entry = false ;
988989 batch_result.results ()[0 ].metadata ().ForEachCmpEntry (
@@ -999,8 +1000,8 @@ class FakeCentipedeCallbacksForThreadChecking : public CentipedeCallbacks {
9991000 std::thread::id execute_thread_id)
10001001 : CentipedeCallbacks(env), execute_thread_id_(execute_thread_id) {}
10011002
1002- bool Execute (std::string_view binary, const std::vector<ByteArray> & inputs,
1003- BatchResult & batch_result) override {
1003+ bool Execute (std::string_view binary, const std::vector<ByteArray>& inputs,
1004+ BatchResult& batch_result, absl::Time deadline ) override {
10041005 batch_result.ClearAndResize (inputs.size ());
10051006 thread_check_passed_ = thread_check_passed_ &&
10061007 std::this_thread::get_id () == execute_thread_id_;
@@ -1044,7 +1045,8 @@ TEST_F(CentipedeWithTemporaryLocalDir, DetectsStackOverflow) {
10441045 BatchResult batch_result;
10451046 const std::vector<ByteArray> inputs = {ByteArray{' s' , ' t' , ' k' }};
10461047
1047- ASSERT_FALSE (callbacks.Execute (env.binary , inputs, batch_result));
1048+ ASSERT_FALSE (callbacks.Execute (env.binary , inputs, batch_result,
1049+ /* deadline=*/ absl::InfiniteFuture ()));
10481050 EXPECT_THAT (batch_result.log (), HasSubstr (" Stack limit exceeded" ));
10491051 EXPECT_EQ (batch_result.failure_description (), " stack-limit-exceeded" );
10501052}
@@ -1053,8 +1055,8 @@ class SetupFailureCallbacks : public CentipedeCallbacks {
10531055 public:
10541056 using CentipedeCallbacks::CentipedeCallbacks;
10551057
1056- bool Execute (std::string_view binary, const std::vector<ByteArray> & inputs,
1057- BatchResult & batch_result) override {
1058+ bool Execute (std::string_view binary, const std::vector<ByteArray>& inputs,
1059+ BatchResult& batch_result, absl::Time deadline ) override {
10581060 ++execute_count_;
10591061 batch_result.ClearAndResize (inputs.size ());
10601062 batch_result.exit_code () = EXIT_FAILURE;
@@ -1090,8 +1092,8 @@ class SkippedTestCallbacks : public CentipedeCallbacks {
10901092 public:
10911093 using CentipedeCallbacks::CentipedeCallbacks;
10921094
1093- bool Execute (std::string_view binary, const std::vector<ByteArray> & inputs,
1094- BatchResult & batch_result) override {
1095+ bool Execute (std::string_view binary, const std::vector<ByteArray>& inputs,
1096+ BatchResult& batch_result, absl::Time deadline ) override {
10951097 ++execute_count_;
10961098 batch_result.ClearAndResize (inputs.size ());
10971099 batch_result.exit_code () = EXIT_FAILURE;
@@ -1128,8 +1130,8 @@ class IgnoredFailureCallbacks : public CentipedeCallbacks {
11281130 public:
11291131 using CentipedeCallbacks::CentipedeCallbacks;
11301132
1131- bool Execute (std::string_view binary, const std::vector<ByteArray> & inputs,
1132- BatchResult & batch_result) override {
1133+ bool Execute (std::string_view binary, const std::vector<ByteArray>& inputs,
1134+ BatchResult& batch_result, absl::Time daedline ) override {
11331135 ++execute_count_;
11341136 batch_result.ClearAndResize (inputs.size ());
11351137 batch_result.exit_code () = EXIT_FAILURE;
@@ -1224,7 +1226,24 @@ TEST_F(CentipedeWithTemporaryLocalDir, HangingFuzzTargetExitsAfterTimeout) {
12241226 env.fork_server = false ;
12251227
12261228 // Test that the process does not get stuck and exits promptly.
1227- EXPECT_FALSE (callbacks.Execute (env.binary , {{0 }}, batch_result));
1229+ EXPECT_FALSE (callbacks.Execute (env.binary , {{0 }}, batch_result,
1230+ /* deadline=*/ absl::InfiniteFuture ()));
1231+ }
1232+
1233+ TEST_F (CentipedeWithTemporaryLocalDir, RunnerExitsAfterFirstCustomFailure) {
1234+ Environment env;
1235+ env.binary = GetDataDependencyFilepath (" centipede/testing/test_fuzz_target" );
1236+ CentipedeDefaultCallbacks callbacks (env);
1237+ BatchResult result;
1238+ std::vector<ByteArray> inputs = {
1239+ {' c' , ' u' , ' s' , ' t' , ' o' , ' m' },
1240+ {' c' , ' u' , ' s' , ' t' , ' o' , ' m' },
1241+ };
1242+ EXPECT_FALSE (callbacks.Execute (env.binary , inputs, result,
1243+ /* deadline=*/ absl::InfiniteFuture ()));
1244+ EXPECT_THAT (result.failure_description (), HasSubstr (" custom" ));
1245+ EXPECT_THAT (result.log (), AllOf (HasSubstr (" custom failure 0" ),
1246+ Not (HasSubstr (" custom failure 1" ))));
12281247}
12291248
12301249} // namespace
0 commit comments