Skip to content

Support fuzz configuration via env variables#952

Merged
tomusdrw merged 1 commit into
mainfrom
td-fuzz-env
May 7, 2026
Merged

Support fuzz configuration via env variables#952
tomusdrw merged 1 commit into
mainfrom
td-fuzz-env

Conversation

@tomusdrw
Copy link
Copy Markdown
Member

@tomusdrw tomusdrw commented May 6, 2026

No description provided.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 6, 2026

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Added fuzz mode support to the jam CLI with environment-based configuration
  • Documentation

    • Added fuzz-target packaging documentation including required environment variables and setup guidance
  • Tests

    • Added comprehensive test suite for fuzz environment parsing and validation
  • Chores

    • Updated Docker base image to specify platform for multi-arch builds

Walkthrough

This PR introduces fuzzing mode support to the jam CLI by adding a new fuzz-env module that reads and validates fuzzing environment variables (JAM_FUZZ, JAM_FUZZ_SPEC, JAM_FUZZ_SOCK_PATH, JAM_FUZZ_DATA_PATH, JAM_FUZZ_LOG_LEVEL). It includes comprehensive tests for the module, documentation of the environment variables and their usage, and integration into the CLI entry point. The PR also updates the Docker base image to explicitly specify linux/amd64 platform for multi-arch builds.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested reviewers

  • skoszuta
  • mateuszsikora
  • DrEverr

Poem

🐰 Fuzzing hops into the JAM,
Environment vars, a fuzzy dam,
Tiny and Full specs take their flight,
Docker's platform, locked just right,
Tests hopping far, logic spins,
The fuzz mode adventure begins!

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ❓ Inconclusive No description was provided by the author. Add a pull request description explaining the motivation, implementation details, and testing approach for the fuzz environment variable support.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding support for fuzz configuration through environment variables, which is the core focus of the new fuzz-env module and integration.
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 td-fuzz-env

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

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (3)
bin/jam/fuzz-env.test.ts (1)

136-154: ⚡ Quick win

Add one regression case for whitespace-padded env inputs.

Given env values often come from shells/templating, a single case like " TRACE " / " /tmp/s " will guard normalization behavior and prevent regressions.

🤖 Prompt for 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.

In `@bin/jam/fuzz-env.test.ts` around lines 136 - 154, Add a regression case that
verifies readFuzzEnv normalizes whitespace-padded env values: in the "parses
each documented log level" test (fuzz-env.test.ts) add an input case where
JAM_FUZZ_LOG_LEVEL is padded (e.g. " TRACE ") and/or other env strings like
JAM_FUZZ_SOCK_PATH/JAM_FUZZ_DATA_PATH include trailing/leading spaces, then call
readFuzzEnv with those padded env vars and assert the returned result.logLevel
equals the expected Level (use the same Level.TRACE expected symbol); this
ensures readFuzzEnv trims whitespace and prevents regressions.
bin/jam/index.ts (1)

26-28: ⚡ Quick win

Use repo validation helper instead of direct throw for CLI-arg rejection.

This keeps error semantics consistent with the rest of the codebase’s validation style in command entrypoints.

As per coding guidelines: "Use ensure/check to validate values; prefer Result types over exceptions; avoid subclassing Error."

🤖 Prompt for 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.

In `@bin/jam/index.ts` around lines 26 - 28, Replace the direct throw in the CLI
arg guard (the process.argv length check that throws new Error("When JAM_FUZZ is
set, command-line arguments are not accepted.")) with the repo validation helper
used elsewhere (e.g., ensure or check) so error semantics match the codebase;
call the helper with a clear message and the same condition (process.argv.length
> 2) so the validation path and Result-style handling are used instead of
throwing an Error directly.
bin/jam/fuzz-env.ts (1)

36-63: 🏗️ Heavy lift

Prefer repo-standard validation primitives over throwing generic Error in parser paths.

The new validation path currently throws directly. Converting this to the repo’s ensure/check + Result-style flow would better match existing error-handling conventions and make this utility easier to compose/test upstream.

As per coding guidelines: "Use ensure/check to validate values; prefer Result types over exceptions; avoid subclassing Error."

🤖 Prompt for 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.

In `@bin/jam/fuzz-env.ts` around lines 36 - 63, Replace the direct throws in the
parser with the repo-standard ensure/check + Result pattern: in the
REQUIRED_VARS loop use the ensure/check primitive to assert non-empty values for
each env[name] (referencing REQUIRED_VARS, env, JAM_FUZZ), convert the
JAM_FUZZ_SPEC parsing (specRaw, KnownChainSpec) to validate via ensure/check and
return a Result.err message instead of throwing, and likewise validate
rawLogLevel against LOG_LEVELS (rawLogLevel, LOG_LEVELS, JAM_FUZZ_LOG_LEVEL)
using ensure/check and return a Result.err when parsing fails; ensure the
function returns a Result.ok with the parsed spec/log level (Level) on success
so callers can handle errors without exceptions.
🤖 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 `@bin/jam/fuzz-env.ts`:
- Around line 43-71: The env values are not being trimmed, so leading/trailing
whitespace can make valid inputs fail later; trim JAM_FUZZ_SPEC and
JAM_FUZZ_LOG_LEVEL before comparing to KnownChainSpec and looking up LOG_LEVELS
(use the trimmed string in error messages too), and return trimmed socketPath
and dataPath (trim env[JAM_FUZZ_SOCK_PATH] and env[JAM_FUZZ_DATA_PATH] before
returning) so callers get normalized paths; update references to specRaw and
rawLogLevel in the parsing logic and to the returned socketPath/dataPath to use
the trimmed values.

---

Nitpick comments:
In `@bin/jam/fuzz-env.test.ts`:
- Around line 136-154: Add a regression case that verifies readFuzzEnv
normalizes whitespace-padded env values: in the "parses each documented log
level" test (fuzz-env.test.ts) add an input case where JAM_FUZZ_LOG_LEVEL is
padded (e.g. " TRACE ") and/or other env strings like
JAM_FUZZ_SOCK_PATH/JAM_FUZZ_DATA_PATH include trailing/leading spaces, then call
readFuzzEnv with those padded env vars and assert the returned result.logLevel
equals the expected Level (use the same Level.TRACE expected symbol); this
ensures readFuzzEnv trims whitespace and prevents regressions.

In `@bin/jam/fuzz-env.ts`:
- Around line 36-63: Replace the direct throws in the parser with the
repo-standard ensure/check + Result pattern: in the REQUIRED_VARS loop use the
ensure/check primitive to assert non-empty values for each env[name]
(referencing REQUIRED_VARS, env, JAM_FUZZ), convert the JAM_FUZZ_SPEC parsing
(specRaw, KnownChainSpec) to validate via ensure/check and return a Result.err
message instead of throwing, and likewise validate rawLogLevel against
LOG_LEVELS (rawLogLevel, LOG_LEVELS, JAM_FUZZ_LOG_LEVEL) using ensure/check and
return a Result.err when parsing fails; ensure the function returns a Result.ok
with the parsed spec/log level (Level) on success so callers can handle errors
without exceptions.

In `@bin/jam/index.ts`:
- Around line 26-28: Replace the direct throw in the CLI arg guard (the
process.argv length check that throws new Error("When JAM_FUZZ is set,
command-line arguments are not accepted.")) with the repo validation helper used
elsewhere (e.g., ensure or check) so error semantics match the codebase; call
the helper with a clear message and the same condition (process.argv.length > 2)
so the validation path and Result-style handling are used instead of throwing an
Error directly.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f2236eb4-d38d-443a-9393-bc664698f790

📥 Commits

Reviewing files that changed from the base of the PR and between bfd4e60 and fb44269.

📒 Files selected for processing (5)
  • Dockerfile
  • bin/jam/README.md
  • bin/jam/fuzz-env.test.ts
  • bin/jam/fuzz-env.ts
  • bin/jam/index.ts

Comment thread bin/jam/fuzz-env.ts
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 6, 2026

View all
File Benchmark Ops
bytes/hex-from.ts[0] parse hex using Number with NaN checking 77270.05 ±0.76% 82.79% slower
bytes/hex-from.ts[1] parse hex from char codes 449107.22 ±0.67% fastest ✅
bytes/hex-from.ts[2] parse hex from string nibbles 256363.99 ±0.45% 42.92% slower
bytes/hex-to.ts[0] number toString + padding 87512.38 ±0.79% fastest ✅
bytes/hex-to.ts[1] manual 7491.04 ±0.65% 91.44% slower
codec/bigint.compare.ts[0] compare custom 90799599.48 ±3.57% 0.36% slower
codec/bigint.compare.ts[1] compare bigint 91123328.58 ±3.87% fastest ✅
codec/bigint.decode.ts[0] decode custom 67536240.68 ±3.68% 24.86% slower
codec/bigint.decode.ts[1] decode bigint 89878500.16 ±4.17% fastest ✅
codec/decoding.ts[0] manual decode 9040495.01 ±1.61% 85.51% slower
codec/decoding.ts[1] int32array decode 62062733.75 ±3.03% 0.53% slower
codec/decoding.ts[2] dataview decode 62395300.36 ±4.74% fastest ✅
codec/encoding.ts[0] manual encode 1342031.35 ±0.82% 16.03% slower
codec/encoding.ts[1] int32array encode 1598263.34 ±0.6% fastest ✅
codec/encoding.ts[2] dataview encode 1563884.11 ±0.53% 2.15% slower
collections/map-set.ts[0] 2 gets + conditional set 91969.96 ±0.41% fastest ✅
collections/map-set.ts[1] 1 get 1 set 66373.31 ±0.47% 27.83% slower
logger/index.ts[0] console.log with string concat 5865723.65 ±19.28% fastest ✅
logger/index.ts[1] console.log with args 1069807.89 ±73.53% 81.76% slower
math/add_one_overflow.ts[0] add and take modulus 58591872.87 ±62.91% 34.24% slower
math/add_one_overflow.ts[1] condition before calculation 89105285.86 ±4.78% fastest ✅
math/count-bits-u32.ts[0] standard method 38954084.72 ±1.73% 52.12% slower
math/count-bits-u32.ts[1] magic 81359348.99 ±4.24% fastest ✅
math/count-bits-u64.ts[0] standard method 4523996.23 ±0.59% 88% slower
math/count-bits-u64.ts[1] magic 37707573.33 ±1.73% fastest ✅
math/mul_overflow.ts[0] multiply and bring back to u32 89952963.67 ±4.97% 6.74% slower
math/mul_overflow.ts[1] multiply and take modulus 96454630.27 ±3.83% fastest ✅
math/switch.ts[0] switch 97366816.3 ±3.76% fastest ✅
math/switch.ts[1] if 93499207.11 ±4.36% 3.97% slower
hash/index.ts[0] hash with numeric representation 64.93 ±0.61% 31.04% slower
hash/index.ts[1] hash with string representation 39.94 ±2.09% 57.58% slower
hash/index.ts[2] hash with symbol representation 63.14 ±0.6% 32.94% slower
hash/index.ts[3] hash with uint8 representation 73.52 ±0.53% 21.91% slower
hash/index.ts[4] hash with packed representation 94.15 ±0.56% fastest ✅
hash/index.ts[5] hash with bigint representation 68.27 ±0.71% 27.49% slower
hash/index.ts[6] hash with uint32 representation 87.47 ±0.64% 7.1% slower
bytes/bytes-to-number.ts[0] Conversion with bitops 3516.31 ±5.43% fastest ✅
bytes/bytes-to-number.ts[1] Conversion without bitops 2776.79 ±3.54% 21.03% slower
bytes/compare.ts[0] Comparing Uint32 bytes 12223.7 ±0.21% fastest ✅
bytes/compare.ts[1] Comparing raw bytes 11902.09 ±0.37% 2.63% slower
codec/view_vs_collection.ts[0] Get first element from Decoded 14999.15 ±0.59% 56.99% slower
codec/view_vs_collection.ts[1] Get first element from View 34873.77 ±1.03% fastest ✅
codec/view_vs_collection.ts[2] Get 50th element from Decoded 15245.14 ±1.01% 56.28% slower
codec/view_vs_collection.ts[3] Get 50th element from View 19050.21 ±0.92% 45.37% slower
codec/view_vs_collection.ts[4] Get last element from Decoded 15476.09 ±0.53% 55.62% slower
codec/view_vs_collection.ts[5] Get last element from View 13369.36 ±0.75% 61.66% slower
codec/view_vs_object.ts[0] Get the first field from Decoded 206475.86 ±0.66% fastest ✅
codec/view_vs_object.ts[1] Get the first field from View 52192.23 ±0.68% 74.72% slower
codec/view_vs_object.ts[2] Get the first field as view from View 53340.33 ±0.56% 74.17% slower
codec/view_vs_object.ts[3] Get two fields from Decoded 206366.77 ±0.78% 0.05% slower
codec/view_vs_object.ts[4] Get two fields from View 42128.34 ±0.75% 79.6% slower
codec/view_vs_object.ts[5] Get two fields from materialized from View 87448.17 ±0.53% 57.65% slower
codec/view_vs_object.ts[6] Get two fields as views from View 41601.79 ±0.66% 79.85% slower
codec/view_vs_object.ts[7] Get only third field from Decoded 202748.37 ±0.61% 1.81% slower
codec/view_vs_object.ts[8] Get only third field from View 27417.98 ±91.12% 86.72% slower
codec/view_vs_object.ts[9] Get only third field as view from View 52250.75 ±0.48% 74.69% slower
collections/map_vs_sorted.ts[0] Map 131045.33 ±0.81% fastest ✅
collections/map_vs_sorted.ts[1] Map-array 45026.96 ±0.56% 65.64% slower
collections/map_vs_sorted.ts[2] Array 53025.71 ±0.53% 59.54% slower
collections/map_vs_sorted.ts[3] SortedArray 69799.08 ±3.25% 46.74% slower
collections/hash-dict-vs-blob-dict_delete.ts[0] StringHashDictionary 2470.72 ±0.6% 4.21% slower
collections/hash-dict-vs-blob-dict_delete.ts[1] BlobDictionary(1) 2517.38 ±0.78% 2.41% slower
collections/hash-dict-vs-blob-dict_delete.ts[2] BlobDictionary(2) 2579.42 ±0.39% fastest ✅
collections/hash-dict-vs-blob-dict_delete.ts[3] BlobDictionary(3) 2540.83 ±0.64% 1.5% slower
collections/hash-dict-vs-blob-dict_delete.ts[4] BlobDictionary(4) 2470.67 ±0.93% 4.22% slower
collections/hash-dict-vs-blob-dict_delete.ts[5] BlobDictionary(5) 2569.16 ±0.46% 0.4% slower
collections/hash-dict-vs-blob-dict_get.ts[0] StringHashDictionary 2844.55 ±0.62% 1.04% slower
collections/hash-dict-vs-blob-dict_get.ts[1] BlobDictionary(1) 2870.04 ±0.61% 0.15% slower
collections/hash-dict-vs-blob-dict_get.ts[2] BlobDictionary(2) 2837.42 ±0.84% 1.29% slower
collections/hash-dict-vs-blob-dict_get.ts[3] BlobDictionary(3) 2808.45 ±0.65% 2.29% slower
collections/hash-dict-vs-blob-dict_get.ts[4] BlobDictionary(4) 2782.91 ±0.79% 3.18% slower
collections/hash-dict-vs-blob-dict_get.ts[5] BlobDictionary(5) 2874.4 ±0.62% fastest ✅
collections/hash-dict-vs-blob-dict_set.ts[0] StringHashDictionary 2254.29 ±0.63% fastest ✅
collections/hash-dict-vs-blob-dict_set.ts[1] BlobDictionary(1) 2222.28 ±0.65% 1.42% slower
collections/hash-dict-vs-blob-dict_set.ts[2] BlobDictionary(2) 2244.01 ±0.69% 0.46% slower
collections/hash-dict-vs-blob-dict_set.ts[3] BlobDictionary(3) 2215.98 ±0.65% 1.7% slower
collections/hash-dict-vs-blob-dict_set.ts[4] BlobDictionary(4) 2233 ±0.72% 0.94% slower
collections/hash-dict-vs-blob-dict_set.ts[5] BlobDictionary(5) 2240.89 ±0.68% 0.59% slower
hash/blake2b.ts[0] our hasher 1.03 ±1.94% fastest ✅
hash/blake2b.ts[1] blake2b js 0.03 ±0.61% 97.09% slower
crypto/ed25519.ts[0] native crypto 5.88 ±0.89% fastest ✅
crypto/ed25519.ts[1] wasm lib 2.74 ±2.04% 53.4% slower
crypto/ed25519.ts[2] wasm lib batch 2.78 ±1.99% 52.72% slower

Benchmarks summary: 83/83 OK ✅

@tomusdrw tomusdrw merged commit 019e542 into main May 7, 2026
14 checks passed
@tomusdrw tomusdrw deleted the td-fuzz-env branch May 7, 2026 07:06
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.

1 participant