Skip to content

Add fuzz testing for device-connect-edge#14

Merged
soupat merged 6 commits intomainfrom
fuzz-testing
Apr 10, 2026
Merged

Add fuzz testing for device-connect-edge#14
soupat merged 6 commits intomainfrom
fuzz-testing

Conversation

@soupat
Copy link
Copy Markdown
Collaborator

@soupat soupat commented Apr 6, 2026

Summary

Add coverage-guided fuzz testing across all three packages using Hypothesis (property-based, pytest-integrated) and Atheris (libFuzzer-based). Fuzz dependencies are optional extras — pip install users are not affected.

Coverage

Package Hypothesis Tests Atheris Targets What's tested
device-connect-edge 11 tests 4 targets JSON-RPC command parsing, NATS .creds parsing, Pydantic model validation, JSON credentials loading
device-connect-server 5 tests 2 targets CredentialsLoader JSON/regex parsing, PIN parsing
device-connect-agent-tools 5 tests 2 targets MCP tool name parsing, JSON-RPC message parsing

CI

  • Single fuzz-tests-hypothesis job and single fuzz-tests-atheris job covering all 3 packages
  • Combined findings report published to GitHub Actions job summary
  • Crash artifacts uploaded and retained for 30 days

Bugs found and fixed

  • MessagingConfig._load_credentials_file(): TypeError crash when JSON file contains a non-dict value (e.g. b'0'json.loads returns int, then if "nats" in data fails). Fixed with isinstance(data, dict) guard.
  • MessagingConfig._parse_nats_creds_file(): Carriage return (\r) in content gets silently normalized during .strip() extraction. Low severity — documented.

What's included

Component Location
Hypothesis tests packages/*/fuzz/test_fuzz_*.py
Atheris harnesses packages/*/fuzz/fuzz_*.py
Seed corpus packages/*/fuzz/corpus/
Unified atheris runner packages/device-connect-edge/fuzz/run_atheris.py
Hypothesis report script packages/device-connect-edge/fuzz/report_hypothesis.py
CI workflow .github/workflows/ci.yml
Setup docs packages/*/fuzz/README.md

Test plan

  • Hypothesis: 21 tests pass locally across all packages
  • Atheris: 8 targets run clean locally across all packages
  • Lint: ruff check passes on all fuzz directories
  • Report scripts produce readable markdown summaries
  • CI jobs run green on this PR

soupat added 4 commits April 6, 2026 12:44
Add coverage-guided fuzz testing using Hypothesis (property-based,
pytest-integrated) and Atheris (libFuzzer-based). Four fuzz targets
cover the main input parsing surfaces: JSON-RPC command handling,
NATS .creds file parsing, Pydantic model validation, and JSON
credentials loading.

Includes seed corpus, CI jobs with findings published to GitHub
Actions job summary, and initial findings documenting two bugs
in MessagingConfig (TypeError on non-dict JSON, carriage return
handling in creds parser).
…pollution

Atheris writes new corpus entries into the corpus directory as it discovers
coverage paths. Copy seeds into a temp dir for each run and clean up after,
keeping the seed corpus directory unchanged.
- Fix TypeError in _load_credentials_file when JSON file contains a
  non-dict value (e.g. bare integer) by adding isinstance guard
- Fix ruff lint errors: unused variables, extraneous f-string prefixes
- Fix nats creds roundtrip test assertion for \r handling
- Add .DS_Store to gitignore
- Remove local findings from tracking (added to gitignore)
Add hypothesis and atheris fuzz targets for device-connect-server
(CredentialsLoader JSON/regex parsing, PIN parsing) and
device-connect-agent-tools (MCP tool name parsing, JSON-RPC message
parsing).

CI now runs a single hypothesis job and single atheris job covering
all three packages, producing one combined report each in the GitHub
Actions job summary.

Fuzz dependencies (hypothesis, atheris) are optional extras in
pyproject.toml. The fuzz/ directories are excluded from pip packages
via setuptools include filters — pip install users are not affected.
@soupat soupat requested a review from atsyplikhin April 8, 2026 17:24
… attribution

Move fuzz/ directories under tests/fuzz/ in each package to reduce visual
clutter. Extract JSON-RPC parsing logic from connection.py into importable
helpers (parse_buffered_payload, parse_event_payload) so fuzz tests exercise
real production code instead of duplicated simulations — this immediately
caught two non-dict payload bugs (b'0' → int). Fix crash file attribution
race in run_atheris.py by snapshotting before/after each target. Remove
unused fuzz-atheris optional extra from edge pyproject.toml.
…error

The unit test jobs install [dev] extras only, not [fuzz]. After relocating
fuzz tests under tests/, pytest now discovers them during unit test
collection and fails on the missing hypothesis import. Add --ignore flags
to skip tests/fuzz/ in the edge and server unit test jobs.
Copy link
Copy Markdown
Collaborator

@atsyplikhin atsyplikhin left a comment

Choose a reason for hiding this comment

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

All checks passing. Reviewed the full diff — fuzz coverage is solid across all three packages, the bug fixes are correct, and the review fixes address the issues I flagged:

  • Fuzz tests now live under tests/fuzz/ (less clutter)
  • Agent-tools JSON-RPC fuzz tests import real production code via extracted parse_buffered_payload/parse_event_payload helpers — and immediately caught two non-dict payload bugs
  • Crash file attribution race in run_atheris.py is fixed
  • Unused fuzz-atheris extra removed

LGTM.

@soupat soupat merged commit 1668858 into main Apr 10, 2026
9 checks passed
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