Skip to content

fix(fuzz): fall back to fs operator so fuzz targets produce real coverage#7723

Merged
erickguan merged 5 commits into
apache:mainfrom
tonghuaroot:fix-fuzz-noop
Jun 15, 2026
Merged

fix(fuzz): fall back to fs operator so fuzz targets produce real coverage#7723
erickguan merged 5 commits into
apache:mainfrom
tonghuaroot:fix-fuzz-noop

Conversation

@tonghuaroot

Copy link
Copy Markdown
Contributor

Which issue does this PR close?

Closes #7722.

Rationale for this change

All OSS-Fuzz targets exit immediately when OPENDAL_TEST is unset because init_test_service() returns None. OSS-Fuzz never sets this variable, so coverage has been stuck at 0.26% (harness startup only) since integration.

What changes are included in this PR?

  • fuzz_reader.rs / fuzz_writer.rs: replace the if let Some(op) early-return with a LazyLock<Operator> that falls back to a local Fs operator in a temp directory when no test service is configured.
  • fuzz/Cargo.toml: enable services-fs feature so the fallback compiles.
  • New fuzz_path.rs target: feeds arbitrary strings as paths through write/stat/list/copy/rename/delete — already found a real bug (fix(services/fs): preserve backslash in filenames on Unix during list #7721) within 2 minutes of running.

Are there any user-facing changes?

No. Changes are limited to the core/fuzz/ directory which is only used by cargo fuzz and OSS-Fuzz.

AI Usage Statement

Claude was used for assistance with fuzz target development.

@tonghuaroot tonghuaroot requested a review from Xuanwo as a code owner June 10, 2026 10:14
@dosubot dosubot Bot added size:L This PR changes 100-499 lines, ignoring generated files. releases-note/fix The PR fixes a bug or has a title that begins with "fix" labels Jun 10, 2026
Comment thread core/fuzz/Cargo.toml
log = { workspace = true }
logforth = { workspace = true }
opendal = { path = "..", features = ["tests"] }
opendal = { path = "..", features = ["tests", "services-fs"] }

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Good find! Do we need a fallback since we could always exit 1 and warn the user in fuzzer test? Because a test failure will force us to check CI status.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Thanks @erickguan! Good question. The fallback is deliberately scoped to the unconfigured case only:

  • init_test_service() returns Ok(None) when OPENDAL_TEST is unset, Ok(Some(op)) when a service is selected and inits, and Err(..) when a selected service fails to init.
  • So init_test_service().expect("operator init must succeed") still panics loudly if someone explicitly sets e.g. OPENDAL_TEST=s3 and it fails to init — a genuine misconfiguration does fail the run and shows up in CI, exactly as you want. The fs fallback only kicks in for the Ok(None) (nothing selected) case.

The reason we fall back instead of exit 1 in that unconfigured case is OSS-Fuzz: it runs these binaries continuously with no OPENDAL_TEST env set (that's the root cause of the zero coverage in #7722). If the target exited 1 / panicked when unconfigured, OSS-Fuzz would just record every run as an immediate crash and we'd still get no useful coverage — the same dead state we're fixing, only louder. Falling back to fs (which needs no external setup beyond a temp dir, and exercises OpenDAL's real path-handling code) gives the fuzzer something concrete to drive, while local/CI runs can still target any specific service via OPENDAL_TEST.

Happy to switch the unconfigured default to memory instead if you'd prefer to avoid filesystem side effects — just let me know which you'd like.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Added a log::warn! on the unconfigured fallback per your suggestion (pushed in 1468565) so it's visible in logs. PTAL!

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks for the context. I understand the problem much better.

If the target exited 1 / panicked when unconfigured, OSS-Fuzz would just record every run as an immediate crash and we'd still get no useful coverage — the same dead state we're fixing, only louder

Indeed true. Having a silent fallback to fs works to bring back fuzz coverage. This would be a good fix.
Now considering a maintenance perspective, if Ok(None) panics, any maintainers would be able to tell something requires for a fix. It might be stringent to understand fuzz setup but that would help someone else to jump in.
Nevertheless, I would be happy to see we are getting fuzz coverage. So your call.

@tonghuaroot

Copy link
Copy Markdown
Contributor Author

For reviewers' context: this also unblocks the OSS-Fuzz side — google/oss-fuzz#15648 updates the build to pull these four targets and fixes the moved repo URL, and is just waiting on this to land. CI here is green; happy to address any feedback. Addresses #7722.

@erickguan erickguan self-requested a review June 12, 2026 17:24

@erickguan erickguan left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

See inline comment. I would be happier to see a panic test without env. Also happy to see the ball gets rolling.

@dosubot dosubot Bot added the lgtm This PR has been approved by a maintainer label Jun 12, 2026
@erickguan

Copy link
Copy Markdown
Member

Also thanks for taking care of oss-fuzz!

@erickguan erickguan merged commit c4a6d48 into apache:main Jun 15, 2026
106 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lgtm This PR has been approved by a maintainer releases-note/fix The PR fixes a bug or has a title that begins with "fix" size:L This PR changes 100-499 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: OSS-Fuzz targets have had no effective coverage since integration

2 participants