Add verification note documenting memory ceiling implementation for fuzz and proptest harnesses. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
88 lines
3.3 KiB
Markdown
88 lines
3.3 KiB
Markdown
# bf-5dnh1: Memory ceiling for fuzz and proptests
|
|
|
|
## Summary
|
|
|
|
Implemented local memory ceiling enforcement for property tests to coordinate with the CI memory-ceiling gate (bf-1g1fd).
|
|
|
|
## Work Completed
|
|
|
|
### 1. Created `scripts/run-proptest-with-limits.sh`
|
|
|
|
A bash script that runs proptest modules under cgroup MemoryMax, providing local development parity with CI enforcement.
|
|
|
|
**Features:**
|
|
- Cgroup v2 MemoryMax support (preferred) with fallback to cgroup v1
|
|
- Configurable memory limit (default: 2048 MB)
|
|
- Per-module or full test suite execution
|
|
- Proptest seed configuration for reproducibility
|
|
- Clean failure mode (allocation errors, not host OOM)
|
|
|
|
**Usage:**
|
|
```bash
|
|
# Run all proptests with 2 GB limit
|
|
scripts/run-proptest-with-limits.sh
|
|
|
|
# Run single module
|
|
scripts/run-proptest-with-limits.sh lexer
|
|
|
|
# Custom memory limit
|
|
MEMORY_MAX_MB=4096 scripts/run-proptest-with-limits.sh
|
|
```
|
|
|
|
### 2. Created `scripts/README.md`
|
|
|
|
Documentation for the scripts directory, including:
|
|
- Memory ceiling enforcement explanation
|
|
- Fuzz and proptest script usage
|
|
- Environment variable configuration
|
|
- Rationale for memory ceilings
|
|
|
|
### 3. Verified existing protections
|
|
|
|
**Fuzz tests** (already in place from bf-1g1fd):
|
|
- CI: `.ci/argo-workflows/pdftract-nightly-fuzz.yaml` has cgroup MemoryMax (1536 MB) + libfuzzer RSS limits (1024 MB)
|
|
- Local: `scripts/run-fuzz-with-limits.sh` provides equivalent enforcement
|
|
|
|
**Proptests** (now complete):
|
|
- CI: `.ci/argo-workflows/pdftract-ci.yaml` has cgroup MemoryMax (6 GB glibc, 4 GB musl)
|
|
- Local: `scripts/run-proptest-with-limits.sh` provides equivalent enforcement
|
|
|
|
**Input size caps** (already in place):
|
|
- Lexer/object parser: `0..10_000` bytes
|
|
- Xref/stream parsers: `0..100_000` bytes
|
|
- Nested structures: depth-limited (e.g., 500 for parser depth checks)
|
|
|
|
## Acceptance Criteria
|
|
|
|
| Criterion | Status | Notes |
|
|
|-----------|--------|-------|
|
|
| Fuzz tests run under memory ceiling | PASS | Already in place from bf-1g1fd |
|
|
| Proptests run under memory ceiling | PASS | New script provides local enforcement |
|
|
| Per-process memory limit enforced | PASS | Cgroup MemoryMax wrapper |
|
|
| Proptest input sizes capped | PASS | Existing bounds in proptest code |
|
|
| Coordinated with bf-1g1fd | PASS | References bf-1g1fd in commit and docs |
|
|
|
|
## Retrospective
|
|
|
|
**What worked:**
|
|
- Leveraged existing cgroup patterns from `run-fuzz-with-limits.sh`
|
|
- Clean separation between CI (k8s cgroup) and local (system cgroup) enforcement
|
|
- Documentation in `scripts/README.md` provides clear rationale
|
|
|
|
**What didn't:**
|
|
- Initial attempt to use `setrlimit RLIMIT_AS` per the bead description was not practical for Rust's proptest harness (no easy hook point)
|
|
- Cgroup wrapper is more portable and aligns with existing bf-1g1fd implementation
|
|
|
|
**Surprise:**
|
|
- The fuzz job already had comprehensive memory limits from bf-1g1fd; this bead primarily needed to add local proptest parity
|
|
|
|
**Reusable pattern:**
|
|
- For future test harnesses that need memory limits: use cgroup v2 MemoryMax with cgroup v1 fallback, disable OOM killer for clean failures
|
|
- Document both CI and local invocation in a central README
|
|
|
|
## Commit
|
|
|
|
`test(bf-5dnh1): add memory ceiling enforcement for proptests`
|
|
|
|
- `scripts/run-proptest-with-limits.sh`: Cgroup wrapper for proptest execution
|
|
- `scripts/README.md`: Documentation for memory ceiling enforcement
|