No public description

PiperOrigin-RevId: 952854556
diff --git a/e2e_tests/functional_test.cc b/e2e_tests/functional_test.cc
index 6133473..3327a38 100644
--- a/e2e_tests/functional_test.cc
+++ b/e2e_tests/functional_test.cc
@@ -1525,7 +1525,9 @@
   EXPECT_THAT_LOG(std_err,
                   HasSubstr("Skipping SkippedTestFixturePerTest.SkippedTest"));
   EXPECT_THAT_LOG(std_err, Not(HasSubstr("SkippedTest should not be run")));
-  EXPECT_THAT(status, Eq(ExitCode(0)));
+#ifdef FUZZTEST_USE_CENTIPEDE
+  EXPECT_THAT_LOG(std_err, HasSubstr("SETUP FAILURE: Test is skipped"));
+#endif
 }
 
 TEST_P(FuzzingModeFixtureTest,
diff --git a/fuzztest/internal/centipede_adaptor.cc b/fuzztest/internal/centipede_adaptor.cc
index 0072126..9c3813c 100644
--- a/fuzztest/internal/centipede_adaptor.cc
+++ b/fuzztest/internal/centipede_adaptor.cc
@@ -510,14 +510,19 @@
       absl::FPrintF(GetStderr(),
                     "[.] Skipping %s per request from the test setup.\n",
                     fuzzer_impl_.test_.full_name());
-      CentipedeSetFailureDescription("SKIPPED TEST: Requested from setup");
-      return true;
+      if (const char* indicator =
+              std::getenv("FUZZTEST_SKIPPED_TEST_INDICATOR_FILE");
+          indicator != nullptr) {
+        absl::FPrintF(GetStderr(), "[.] Touching the indicator file %s\n",
+                      indicator);
+        WriteFile(indicator, "");
+      }
+      CentipedeSetFailureDescription("SETUP FAILURE: Test is skipped");
+      return false;
     }
     if (runtime_.termination_requested()) {
       absl::FPrintF(GetStderr(),
-                    "[.] Termination requested - exiting without executing "
-                    "further inputs.\n");
-      CentipedeSetFailureDescription("IGNORED FAILURE: Termination requested");
+                    "[.] Termination requested - not executing input.\n");
       return false;
     }
     // We should avoid doing anything other than executing the input here so
@@ -963,16 +968,27 @@
   }
   // Run as the fuzzing engine.
   int result = EXIT_FAILURE;
+  TempDir temp_dir;
+  const std::string skipped_test_indicator_file =
+      temp_dir.path() / "skipped_test";
+  std::error_code ec;
+  runtime_.SetShouldTerminateOnNonFatalFailure(false);
+
   [&] {
-    runtime_.SetShouldTerminateOnNonFatalFailure(false);
-    std::unique_ptr<TempDir> workdir;
-    if (configuration.corpus_database.empty() ||
-        (mode == RunMode::kUnitTest && configuration.workdir_root.empty())) {
-      workdir = std::make_unique<TempDir>("fuzztest_workdir");
-    }
-    const std::string workdir_path = workdir ? workdir->path() : "";
-    const auto env = CreateCentipedeEnvironmentFromConfiguration(
-        configuration, workdir_path, test_.full_name(), mode);
+    const auto env = [&] {
+      std::string workdir_path;
+      if (configuration.corpus_database.empty() ||
+          (mode == RunMode::kUnitTest && configuration.workdir_root.empty())) {
+        workdir_path = temp_dir.path() / "workdir";
+      }
+      auto env = CreateCentipedeEnvironmentFromConfiguration(
+          configuration, workdir_path, test_.full_name(), mode);
+      env.env_diff_for_binaries.push_back(
+          absl::StrCat("FUZZTEST_SKIPPED_TEST_INDICATOR_FILE=",
+                       skipped_test_indicator_file));
+      return env;
+    }();
+
     if (const char* minimize_dir_chars =
             std::getenv("FUZZTEST_MINIMIZE_TESTSUITE_DIR")) {
       const std::string minimize_dir = minimize_dir_chars;
@@ -994,17 +1010,25 @@
       replay_env.corpus_dir = {"", minimize_dir};
       replay_env.load_shards_only = true;
       replay_env.report_crash_summary = false;
-      FUZZTEST_CHECK(
-          RunCentipede(replay_env, configuration.centipede_command) == 0)
-          << "Failed to replaying the testsuite for minimization";
+      result = RunCentipede(replay_env, configuration.centipede_command);
+      if (std::filesystem::exists(skipped_test_indicator_file, ec)) {
+        return;
+      }
+      if (result != 0) {
+        absl::FPrintF(GetStderr(),
+                      "[!] Failed to replaying the corpus for minimization");
+        return;
+      }
       absl::FPrintF(GetStderr(), "[.] Imported the corpus from %s.\n",
                     minimize_dir);
       // 2. Run Centipede distillation on the shard.
       auto distill_env = env;
       distill_env.distill = true;
-      FUZZTEST_CHECK(
-          RunCentipede(distill_env, configuration.centipede_command) == 0)
-          << "Failed to minimize the testsuite";
+      result = RunCentipede(distill_env, configuration.centipede_command);
+      if (result != 0) {
+        absl::FPrintF(GetStderr(), "[!] Failed to minimize the testsuite");
+        return;
+      }
       absl::FPrintF(GetStderr(),
                     "[.] Minimized the corpus using Centipede distillation.\n");
       // 3. Replace the shard corpus data with the distillation result.
@@ -1017,9 +1041,13 @@
       // 4. Export the corpus of the shard.
       auto export_env = env;
       export_env.corpus_to_files = corpus_out_dir;
-      FUZZTEST_CHECK(
-          RunCentipede(export_env, configuration.centipede_command) == 0)
-          << "Failed to export the corpus to FUZZTEST_MINIMIZE_TESTSUITE_DIR";
+      result = RunCentipede(export_env, configuration.centipede_command);
+      if (result != 0) {
+        absl::FPrintF(
+            GetStderr(),
+            "Failed to export the corpus to FUZZTEST_MINIMIZE_TESTSUITE_DIR");
+        return;
+      }
       absl::FPrintF(GetStderr(),
                     "[.] Exported the minimized the corpus to %s.\n",
                     corpus_out_dir);
@@ -1027,6 +1055,9 @@
       return;
     }
     result = RunCentipede(env, configuration.centipede_command);
+    if (std::filesystem::exists(skipped_test_indicator_file, ec)) {
+      return;
+    }
     if (!env.workdir.empty()) {
       if (runtime_.termination_requested()) {
         absl::FPrintF(
@@ -1045,6 +1076,13 @@
       }
     }
   }();
+  if (std::filesystem::exists(skipped_test_indicator_file, ec)) {
+    absl::FPrintF(
+        GetStderr(),
+        "[.] Indicator file for skipped test found - ignoring any failures.\n");
+    runtime_.SetSkippingRequested(true);
+    return true;
+  }
   return result == 0;
 }
 
diff --git a/fuzztest/internal/googletest_adaptor.h b/fuzztest/internal/googletest_adaptor.h
index 4571781..2a2d2b5 100644
--- a/fuzztest/internal/googletest_adaptor.h
+++ b/fuzztest/internal/googletest_adaptor.h
@@ -85,17 +85,22 @@
         EXPECT_TRUE(false) << "Death test is not supported.";
 #endif
       } else {
-        EXPECT_TRUE(test->RunInUnitTestMode(configuration_))
+        EXPECT_TRUE(test->RunInUnitTestMode(configuration_) ||
+                    Runtime::instance().skipping_requested())
             << "Failure(s) found in the unit-test mode - please see the test "
                "log for more details.";
       }
     } else {
       // TODO(b/245753736): Consider using `tolerate_failure` when FuzzTest can
       // tolerate crashes in fuzzing mode.
-      EXPECT_TRUE(test->RunInFuzzingMode(argc_, argv_, configuration_))
+      EXPECT_TRUE(test->RunInFuzzingMode(argc_, argv_, configuration_) ||
+                  Runtime::instance().skipping_requested())
           << "Failure(s) found in the fuzzing mode - please see the test log "
              "for more details.";
     }
+    if (Runtime::instance().skipping_requested()) {
+      GTEST_SKIP() << "Test was skipped";
+    }
   }
 
   static void SetUpTestSuite() {