Add the replay engine as a new cc_fuzzing engine. (#111)

* Add the replay engine as a new cc_fuzzing engine.

Also make this engine the default //fuzzing:cc_engine value, and update our regression tests to run on {replay,libfuzzer,honggfuzz} configurations.

* Fix typo in bazel_test.yml.
diff --git a/.bazelrc b/.bazelrc
index ff98ead..f9ed7d2 100644
--- a/.bazelrc
+++ b/.bazelrc
@@ -45,6 +45,11 @@
 build:msan-honggfuzz --@rules_fuzzing//fuzzing:cc_engine_instrumentation=honggfuzz
 build:msan-honggfuzz --@rules_fuzzing//fuzzing:cc_engine_sanitizer=msan
 
+# Replay + ASAN
+build:asan-replay --//fuzzing:cc_engine=//fuzzing/engines:replay
+build:asan-replay --@rules_fuzzing//fuzzing:cc_engine_instrumentation=none
+build:asan-replay --@rules_fuzzing//fuzzing:cc_engine_sanitizer=asan
+
 build:oss-fuzz --//fuzzing:cc_engine=@rules_fuzzing_oss_fuzz//:oss_fuzz_engine
 build:oss-fuzz --@rules_fuzzing//fuzzing:cc_engine_instrumentation=oss-fuzz
 build:oss-fuzz --@rules_fuzzing//fuzzing:cc_engine_sanitizer=none
diff --git a/.github/workflows/bazel_test.yml b/.github/workflows/bazel_test.yml
index ec05a8e..ba991b1 100644
--- a/.github/workflows/bazel_test.yml
+++ b/.github/workflows/bazel_test.yml
@@ -18,7 +18,7 @@
 
 jobs:
   unit_tests:
-    name: All project tests
+    name: All unit tests
     runs-on: ubuntu-latest
     timeout-minutes: 30
     steps:
@@ -30,11 +30,8 @@
       - name: Run Address Sanitizer tests
         run: |
           bazel test --test_tag_filters=-fuzz-test --build_tests_only --config=asan //...
-      - name: Run fuzz test regressions
-        run: |
-          bazel test --verbose_failures --build_tag_filters=fuzz-test --config=asan-libfuzzer //examples/...
-  smoke_tests:
-    name: Smoke tests on fuzz targets
+  fuzzer_run_tests:
+    name: Brief fuzz test runs
     runs-on: ubuntu-latest
     timeout-minutes: 30
     strategy:
@@ -53,3 +50,20 @@
       - name: Run smoke test
         run: |
           bazel run ${{ matrix.target }} --config=${{ matrix.config }} -- --clean --timeout_secs=5
+  regression_tests:
+    name: Regression tests
+    runs-on: ubuntu-latest
+    timeout-minutes: 30
+    strategy:
+      matrix:
+        config: ["asan-replay", "asan-libfuzzer", "asan-honggfuzz"]
+    steps:
+      - name: Checkout repository
+        uses: actions/checkout@v2
+      - name: Install dependencies
+        run: sudo apt-get update && sudo apt-get install -yq libunwind-dev libblocksruntime-dev
+      - name: Run regression tests
+        run: |
+          bazel test --verbose_failures --test_output=all \
+              --build_tag_filters=fuzz-test --config=${{ matrix.config }} \
+              //examples/...
diff --git a/fuzzing/BUILD b/fuzzing/BUILD
index 55aeb13..9053349 100644
--- a/fuzzing/BUILD
+++ b/fuzzing/BUILD
@@ -16,7 +16,7 @@
 
 label_flag(
     name = "cc_engine",
-    build_setting_default = "//fuzzing/engines:libfuzzer",
+    build_setting_default = "//fuzzing/engines:replay",
     visibility = ["//visibility:public"],
 )
 
diff --git a/fuzzing/engines/BUILD b/fuzzing/engines/BUILD
index 63d781b..eeee47e 100644
--- a/fuzzing/engines/BUILD
+++ b/fuzzing/engines/BUILD
@@ -49,3 +49,14 @@
     library = "@honggfuzz//:honggfuzz_engine",
     visibility = ["//visibility:public"],
 )
+
+# The replay engine specification.
+##################################
+
+cc_fuzzing_engine(
+    name = "replay",
+    display_name = "Replay",
+    launcher = "replay_launcher.sh",
+    library = "//fuzzing/replay:replay_main",
+    visibility = ["//visibility:public"],
+)
diff --git a/fuzzing/engines/replay_launcher.sh b/fuzzing/engines/replay_launcher.sh
new file mode 100755
index 0000000..f26c52f
--- /dev/null
+++ b/fuzzing/engines/replay_launcher.sh
@@ -0,0 +1,24 @@
+# Copyright 2020 Google LLC
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+if (( ! FUZZER_IS_REGRESSION )); then
+    echo "NOTE: Non-regression mode is not supported by the replay engine."
+fi
+
+command_line=("${FUZZER_BINARY}")
+if [[ -n "${FUZZER_SEED_CORPUS_DIR}" ]]; then
+    command_line+=("${FUZZER_SEED_CORPUS_DIR}")
+fi
+
+exec "${command_line[@]}"