test(base64-rs): add GNU differential parity harness
Runs both binaries over 154 cases and compares stdout, stderr and exit code: encoding at every wrap width, decode round-trips, canonical-tail rules, padding placement, concatenated streams, every prefix of a known encoding, usage errors and file operands. Locates a genuine GNU base64 rather than trusting /usr/bin/base64, since distributions increasingly ship uutils there and it disagrees with GNU on most malformed input — running against it fails 51 of the 154 cases, which doubles as a negative control for the harness itself. The three known differences are asserted as expected rather than ignored.
This commit is contained in:
+10
-1
@@ -48,7 +48,7 @@ Long options accept unambiguous abbreviations (`--dec`), short options cluster (
|
||||
|
||||
## Behaviour
|
||||
|
||||
Verified against GNU coreutils 9.7 with a 153-case differential test covering encoding at every wrap width, decode round-trips, malformed padding, truncated input, garbage handling, all the usage errors and file operands. Output, exit codes and error messages match, including the fiddly parts:
|
||||
Verified against GNU coreutils 9.7 with a 154-case differential test ([tests/parity.py](tests/parity.py)) covering encoding at every wrap width, decode round-trips, malformed padding, truncated input, garbage handling, all the usage errors and file operands. Output, exit codes and error messages match, including the fiddly parts:
|
||||
|
||||
- **Partial output on failure.** Bytes are emitted as soon as enough bits are available, so a stream that goes bad halfway still writes the valid prefix before the error — same as coreutils.
|
||||
- **Unpadded input is accepted** when the encoding is canonical, i.e. the leftover bits are zero. `aGVsbG8` decodes to `hello`; `aGV` is rejected because `V` carries stray bits.
|
||||
@@ -64,6 +64,15 @@ Verified against GNU coreutils 9.7 with a 153-case differential test covering en
|
||||
| `--help` omits GNU's support URLs | This isn't GNU coreutils; pointing at their bug tracker would be wrong. |
|
||||
| Error messages quote with `'ASCII'` | GNU uses `'…'` in a UTF-8 locale. Windows consoles are frequently cp437/cp1252, where those bytes render as mojibake. |
|
||||
|
||||
## Running the tests
|
||||
|
||||
```bash
|
||||
cargo build --release
|
||||
python3 tests/parity.py
|
||||
```
|
||||
|
||||
Linux-only — it diffs against a real GNU `base64`, so it can't run on the Windows box this tool targets. Note that many distributions now ship **uutils** coreutils as `/usr/bin/base64`; it disagrees with GNU on most malformed-input cases, so the script hunts for a genuine GNU build and refuses to run against anything else. On Ubuntu with `coreutils-from-uutils` installed, the GNU one is `gnubase64`.
|
||||
|
||||
## Notes
|
||||
|
||||
- Roughly 2× slower than GNU on large inputs (100 MB encodes in ~0.35s vs ~0.18s). GNU uses hand-tuned routines; this is plain portable Rust and fast enough that the difference is invisible for normal use.
|
||||
|
||||
Reference in New Issue
Block a user