Skip to content

test(fuzz): revive the fuzz target and run it nightly in CI#281

Merged
stormslowly merged 10 commits into
mainfrom
fuzz/revive-target-and-nightly-ci
Jun 17, 2026
Merged

test(fuzz): revive the fuzz target and run it nightly in CI#281
stormslowly merged 10 commits into
mainfrom
fuzz/revive-target-and-nightly-ci

Conversation

@stormslowly

Copy link
Copy Markdown
Collaborator

Why

The fuzz target silently stopped testing anything. When resolve became
async, the target's let _ = resolver.resolve(...) began dropping the
returned future instead of awaiting it — Rust futures are lazy, so the
resolution algorithm never ran. Each iteration only built a Resolver and
read cwd. It was also never wired into CI, so the regression went unnoticed.

What

  • Drive the future with futures::executor::block_on so the resolver actually
    runs (no tokio runtime needed — the FS layer uses std::fs).
  • Derive a few resolver options from the input byte (condition names
    import/require, extension sets, optional alias, symlinks) for wider coverage
    instead of default options only.
  • Add .github/workflows/fuzz.yml: a nightly (03:00 UTC) short run plus manual
    dispatch, on the nightly toolchain via cargo-binstall cargo-fuzz, with a
    persisted corpus cache and crash-artifact upload on failure.

The fuzz target silently became a no-op when `resolve` turned async:
the returned future was dropped instead of awaited, so the resolution
algorithm never ran. Drive it with `block_on`, vary a few resolver
options (condition names, extensions, alias, symlinks) from the input
for wider coverage, and run it nightly via a scheduled workflow.
Copilot AI review requested due to automatic review settings June 17, 2026 01:49
@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The pull request makes two related changes to the fuzzing setup. The fuzz target (fuzz/fuzz_targets/resolver.rs) is rewritten to split raw input into a configuration bitmask (first byte) and a UTF-8 specifier (remaining bytes); the bitmask drives ResolveOptions fields such as conditions, extensions, aliases, and symlink handling. Because resolve is now async, the target uses futures::executor::block_on, and futures = "0.3" is added to fuzz/Cargo.toml. A new GitHub Actions workflow (.github/workflows/fuzz.yml) runs nightly at 03:00 UTC, supports manual dispatch with a configurable max_total_time, caches and restores the fuzz corpus, runs cargo +nightly fuzz run with ASCII-only input, and uploads crash artifacts on failure. On scheduled failures, the workflow opens a GitHub issue to report the crash if one is not already open.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the main changes: reviving a non-functional fuzz target and integrating it into nightly CI execution.
Description check ✅ Passed The description clearly explains why the fuzz target broke (async transition), what fixes were applied, and provides good context for understanding the changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fuzz/revive-target-and-nightly-ci

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/fuzz.yml:
- Around line 9-12: The max_total_time workflow input is vulnerable to command
injection when passed directly to a shell command. Change the input type from
the default string to number type in the input definition for max_total_time to
enforce numeric constraints at the GitHub Actions level. Additionally, before
the shell command at line 50 that uses the max_total_time input, add validation
logic to ensure the input is a valid positive integer and reject or use a safe
default value if the validation fails. This prevents arbitrary shell command
injection through the workflow input expansion.

In `@fuzz/fuzz_targets/resolver.rs`:
- Line 41: The `unwrap()` call on `std::env::current_dir()` at line 41 in the
fuzz harness can cause panics during environment setup failures, leading to
false-positive fuzz crashes. Replace the `unwrap()` with proper error handling
that uses a match statement or the `?` operator to return early from the harness
function if current_dir fails, allowing the fuzzer to skip that input gracefully
instead of crashing.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 606452ed-0f9b-490d-b242-aa6686ff895f

📥 Commits

Reviewing files that changed from the base of the PR and between 208a3f1 and d0bb614.

📒 Files selected for processing (3)
  • .github/workflows/fuzz.yml
  • fuzz/Cargo.toml
  • fuzz/fuzz_targets/resolver.rs

Comment thread .github/workflows/fuzz.yml
Comment thread fuzz/fuzz_targets/resolver.rs

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Revives the cargo-fuzz resolver harness so it actually executes the async resolution logic, and adds a scheduled GitHub Actions workflow to run fuzzing nightly to catch regressions earlier.

Changes:

  • Drive the async Resolver::resolve future to completion in the fuzz target and expand coverage by varying several ResolveOptions based on input bytes.
  • Add futures as a dependency of the fuzz crate to enable futures::executor::block_on.
  • Introduce a nightly CI workflow to run cargo fuzz on a schedule (and via manual dispatch), with corpus caching and crash artifact upload.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
fuzz/fuzz_targets/resolver.rs Fixes the harness to actually run the async resolver and broadens option coverage per input.
fuzz/Cargo.toml Adds the futures dependency needed to synchronously drive the async resolve call.
.github/workflows/fuzz.yml Adds nightly/manual fuzzing in CI with caching and artifact upload.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread .github/workflows/fuzz.yml
@codspeed-hq

codspeed-hq Bot commented Jun 17, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 12 untouched benchmarks


Comparing fuzz/revive-target-and-nightly-ci (80221dd) with main (6418a03)

Open in CodSpeed

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d0bb614965

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/workflows/fuzz.yml
GitHub's built-in failure notification for scheduled workflows only
pings the user who last edited the cron, subject to their personal
settings, so a nightly fuzz crash can go unnoticed. File a GitHub issue
on scheduled-run failure instead (deduped against an already-open one).
Manual workflow_dispatch failures are excluded.
Tag the auto-filed crash issue with a fuzz-crash label for filtering,
and use that label as the dedup key. The step creates the label
idempotently (--force) so it works without pre-creating it in the repo.
Lets this PR exercise the Fuzz job in real Actions before merge, since
workflow_dispatch/schedule only work once the file is on the default
branch. To be removed before merge so the workflow stays nightly-only.
cargo-binstall ships a musl binary, so `cargo binstall cargo-fuzz`
installed the musl build, which defaults its build target to
x86_64-unknown-linux-musl — whose std isn't on the gnu runner, failing
with "can't find crate for core". Build cargo-fuzz from source instead.
The PR-triggered run validated the workflow end-to-end (cargo-fuzz
install, instrumented build, 300s fuzz, failure-only steps skipping
on success). Revert to nightly schedule + manual dispatch only.
The harness resolves against std::env::current_dir(). With
working-directory: fuzz that was the near-empty fuzz crate, so the
campaign barely exercised real resolution. Running from the repo root
(cargo fuzz auto-discovers fuzz/) raised corpus-replay edge coverage
from 1156 to 1368. Corpus/artifact paths stay under fuzz/.
Measured the cwd effect rigorously (same binary, same corpus): repo
root gives identical coverage to fuzz/ (~1369 edges) but ~14% lower
throughput, because random specifiers rarely form valid paths/package
names, so the fs-dependent code is unreached regardless of the tree.
Keep working-directory: fuzz. Restores the validated-green workflow.
@stormslowly stormslowly merged commit c2364c1 into main Jun 17, 2026
25 checks passed
@stormslowly stormslowly deleted the fuzz/revive-target-and-nightly-ci branch June 17, 2026 03:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants