Skip to content

Commit e0fc064

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 1ba5def commit e0fc064

File tree

2 files changed

+45
-3
lines changed

2 files changed

+45
-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
@@ -268,6 +274,11 @@ jobs:
268274
cargo clean
269275
- name: Run fuzzers
270276
run: cd fuzz && ./ci-fuzz.sh && cd ..
277+
- name: Upload honggfuzz corpus
278+
uses: actions/upload-artifact@v4
279+
with:
280+
name: hfuzz-corpus
281+
path: fuzz/hfuzz_workspace
271282

272283
linting:
273284
runs-on: ubuntu-latest

contrib/generate_fuzz_coverage.sh

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -62,9 +62,40 @@ 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
6867

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+
find "$target_dir" -maxdepth 2 -type f \
79+
\( -path "$target_dir/CORPUS/*" -o -path "$target_dir/INPUT/*" -o -path "$target_dir/NEW/*" -o -path "$target_dir/input/*" \) \
80+
-print0 | xargs -0 -I{} cp -n {} "test_cases/$dest/" 2>/dev/null || true
81+
done
82+
done
83+
# Check if any files were actually imported
84+
if [ -n "$(find test_cases -type f -print -quit 2>/dev/null)" ]; then
85+
imported=1
86+
fi
87+
fi
6988

89+
# Generate coverage based on whether a corpus was imported.
90+
if [ "$imported" = "1" ]; then
91+
echo "Replaying imported corpus via tests to generate coverage..."
92+
cargo llvm-cov -j8 --codecov --ignore-filename-regex "fuzz/" \
93+
--output-path "$OUTPUT_DIR/fuzz-codecov.json" --tests
94+
else
95+
echo "No corpus found; generating no-corpus coverage JSON..."
96+
cargo llvm-cov -j8 --codecov --ignore-filename-regex "fuzz/" \
97+
--output-path "$OUTPUT_DIR/fuzz-codecov.json" --no-run
98+
fi
7099

100+
echo "Fuzz codecov report available at $OUTPUT_DIR/fuzz-codecov.json"
101+
fi

0 commit comments

Comments
 (0)