Exit peacefully when custom mutator fails. PiperOrigin-RevId: 768049765
diff --git a/centipede/centipede.cc b/centipede/centipede.cc index 66499d0..e30d548 100644 --- a/centipede/centipede.cc +++ b/centipede/centipede.cc
@@ -832,6 +832,8 @@ const std::vector<ByteArray> mutants = user_callbacks_.Mutate(mutation_inputs, batch_size); + if (ShouldStop()) break; + bool gained_new_coverage = RunBatch(mutants, corpus_file.get(), features_file.get(), nullptr); new_runs += mutants.size();
diff --git a/centipede/centipede_default_callbacks.cc b/centipede/centipede_default_callbacks.cc index 559812d..20b2efa 100644 --- a/centipede/centipede_default_callbacks.cc +++ b/centipede/centipede_default_callbacks.cc
@@ -107,8 +107,9 @@ // Returning whatever mutants we got before the failure. return std::move(result).mutants(); } else { - // TODO(b/398261908): Exit with failure instead of crashing. - LOG(FATAL) << "Test binary failed when asked to mutate inputs."; + LOG(ERROR) << "Test binary failed when asked to mutate inputs - exiting."; + RequestEarlyStop(EXIT_FAILURE); + return {}; } } // Fall back to the internal mutator.
diff --git a/centipede/centipede_test.cc b/centipede/centipede_test.cc index 948159a..59826f4 100644 --- a/centipede/centipede_test.cc +++ b/centipede/centipede_test.cc
@@ -1144,9 +1144,11 @@ const std::vector<ByteArray> inputs = {{1}, {2}, {3}, {4}, {5}, {6}}; // Previous stop condition could interfere here. ClearEarlyStopRequestAndSetStopTime(absl::InfiniteFuture()); - EXPECT_DEATH(callbacks.Mutate(GetMutationInputRefsFromDataInputs(inputs), - inputs.size()), - "Custom mutator failed"); + EXPECT_THAT(callbacks.Mutate(GetMutationInputRefsFromDataInputs(inputs), + inputs.size()), + IsEmpty()); + EXPECT_TRUE(EarlyStopRequested()); + EXPECT_EQ(ExitCode(), EXIT_FAILURE); } TEST_F(CentipedeWithTemporaryLocalDir,
diff --git a/e2e_tests/functional_test.cc b/e2e_tests/functional_test.cc index 4dc7432..9ee676e 100644 --- a/e2e_tests/functional_test.cc +++ b/e2e_tests/functional_test.cc
@@ -480,8 +480,7 @@ TEST_F(UnitTestModeTest, DetectsRecursiveStructureIfOptionalsSetByDefault) { auto [status, std_out, std_err] = Run("MySuite.FailsIfCantInitializeProto"); - // TODO: b/398261908 - Change to `ExpectTargetAbort` once the bug is fixed. - EXPECT_THAT(status, Eq(Signal(SIGABRT))); + ExpectTargetAbort(status, std_err); EXPECT_THAT(std_err, HasSubstr("recursive fields")); } @@ -516,8 +515,7 @@ TEST_F(UnitTestModeTest, FailsWhenRepeatedFieldsSizeRangeIsInvalid) { auto [status, std_out, std_err] = Run("MySuite.FailsToInitializeIfRepeatedFieldsSizeRangeIsInvalid"); - // TODO: b/398261908 - Change to `ExpectTargetAbort` once the bug is fixed. - EXPECT_THAT(status, Eq(Signal(SIGABRT))); + ExpectTargetAbort(status, std_err); EXPECT_THAT(std_err, HasSubstr("size range is not valid")); } @@ -530,8 +528,7 @@ TEST_F(UnitTestModeTest, ChecksTypeOfProvidedDefaultDomainForProtos) { auto [status, std_out, std_err] = Run("MySuite.FailsWhenWrongDefaultProtobufDomainIsProvided"); - // TODO: b/398261908 - Change to `ExpectTargetAbort` once the bug is fixed. - EXPECT_THAT(status, Eq(Signal(SIGABRT))); + ExpectTargetAbort(status, std_err); EXPECT_THAT(std_err, HasSubstr("does not match the expected message type")); }