Skip to content

Commit dc493c2

Browse files
committed
Upload CI generated fuzz corpus coverage to codecov
Because each CI job runs on a fresh runner and can't share data between jobs. We rely on Github Actions upload-artifact and download-artifact to share the CI generated fuzz corpus, then replay them in the `contrib/generate_fuzz_coverage.sh` script to generate the coverage report.
1 parent 7439528 commit dc493c2

File tree

2 files changed

+55
-3
lines changed

2 files changed

+55
-3
lines changed

.github/workflows/build.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ jobs:
110110
run: CI_ENV=1 CI_MINIMIZE_DISK_USAGE=1 ./ci/ci-tx-sync-tests.sh
111111

112112
coverage:
113+
needs: fuzz
113114
strategy:
114115
fail-fast: false
115116
runs-on: self-hosted
@@ -133,6 +134,11 @@ jobs:
133134
# Maybe if codecov wasn't broken we wouldn't need to do this...
134135
./codecov --verbose upload-process --disable-search --fail-on-error -f target/codecov.json -t "f421b687-4dc2-4387-ac3d-dc3b2528af57" -F 'tests'
135136
cargo clean
137+
- name: Download honggfuzz corpus
138+
uses: actions/download-artifact@v4
139+
with:
140+
name: hfuzz-corpus
141+
path: fuzz/hfuzz_workspace
136142
- name: Run fuzz coverage generation
137143
run: |
138144
./contrib/generate_fuzz_coverage.sh --output-dir `pwd` --output-codecov-json
@@ -254,6 +260,11 @@ jobs:
254260
cargo clean
255261
- name: Run fuzzers
256262
run: cd fuzz && ./ci-fuzz.sh && cd ..
263+
- name: Upload honggfuzz corpus
264+
uses: actions/upload-artifact@v4
265+
with:
266+
name: hfuzz-corpus
267+
path: fuzz/hfuzz_workspace
257268

258269
linting:
259270
runs-on: ubuntu-latest

contrib/generate_fuzz_coverage.sh

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,50 @@ if [ "$OUTPUT_CODECOV_JSON" = "0" ]; then
6262
cargo llvm-cov --html --ignore-filename-regex "fuzz/" --output-dir "$OUTPUT_DIR"
6363
echo "Coverage report generated in $OUTPUT_DIR/html/index.html"
6464
else
65-
cargo llvm-cov -j8 --codecov --ignore-filename-regex "fuzz/" --output-path "$OUTPUT_DIR/fuzz-codecov.json"
66-
echo "Fuzz codecov report available at $OUTPUT_DIR/fuzz-codecov.json"
67-
fi
65+
# Clean previous coverage artifacts to ensure a fresh run.
66+
cargo llvm-cov clean --workspace
67+
68+
# Import honggfuzz corpus if the artifact was downloaded.
69+
imported=0
70+
if [ -d "hfuzz_workspace" ]; then
71+
echo "Importing corpus from hfuzz_workspace..."
72+
for target_dir in hfuzz_workspace/*; do
73+
[ -d "$target_dir" ] || continue
74+
src_name="$(basename "$target_dir")"
75+
for dest in "$src_name" "${src_name%_target}"; do
76+
mkdir -p "test_cases/$dest"
77+
# Copy corpus files into the test_cases directory
78+
if [ -d "$target_dir/input" ]; then
79+
find "$target_dir/input" -maxdepth 1 -type f -print0 2>/dev/null | \
80+
xargs -0 -I{} cp -n {} "test_cases/$dest/" 2>/dev/null || true
81+
fi
82+
done
83+
done
84+
# Check if any files were actually imported
85+
if [ -n "$(find test_cases -type f -print -quit 2>/dev/null)" ]; then
86+
imported=1
87+
fi
88+
fi
6889

90+
# Generate coverage based on whether a corpus was imported.
91+
if [ "$imported" = "1" ]; then
92+
echo "Replaying imported corpus to generate coverage..."
93+
for corpus_dir in test_cases/*; do
94+
[ -d "$corpus_dir" ] || continue
95+
target_name=$(basename "$corpus_dir")
96+
echo "Replaying corpus for target: $target_name"
97+
cargo llvm-cov run --features libfuzzer_fuzz --bin "$target_name" -- "$corpus_dir" || true
98+
done
6999

100+
# Merge all the raw data from the runs above into a final report.
101+
echo "Generating final Codecov report from all corpus replays..."
102+
cargo llvm-cov report -j8 --codecov --ignore-filename-regex "fuzz/" --output-path "$OUTPUT_DIR/fuzz-codecov.json"
70103

104+
else
105+
# When no corpus artifact is found.
106+
echo "No corpus found; generating no-corpus coverage report..."
107+
cargo llvm-cov -j8 --codecov --ignore-filename-regex "fuzz/" --output-path "$OUTPUT_DIR/fuzz-codecov.json" --no-run
108+
fi
109+
110+
echo "Fuzz codecov report available at $OUTPUT_DIR/fuzz-codecov.json"
111+
fi

0 commit comments

Comments
 (0)