# testLibrary

Shared regression test suite for `zfs_utils` — covers `ZFS_Utils.pm`, `sneakernet`, `validateBackup`, and `YAMLPatch.pm`. Most tests need no real ZFS: a fake `zfs`/`zpool`/`ssh` on `PATH`, or a hand-built fixture, stands in for it. A few (the `Harness_*` files, and the harness itself under `sneakernet/testing/`) exercise a real ZFS sandbox and are meant to run on a test host, not a dev workstation.

## Running a test

Each `test_*.pl` is a standalone script: `perl test_foo.pl`. Output is a `PASS`/`FAIL` line per assertion plus a summary; exit status is `0` if everything passed, nonzero otherwise. There is no aggregate "run everything" script in this directory — `sneakernet/testing/run-tests` is the closest thing, and it runs the `Documentation/TESTING.md` catalogue against a real sandbox, not the unit tests below.

Since `sneakernet` and `validateBackup` are scripts with unguarded top-level code (not requireable modules), most of their tests copy the function under test verbatim into the test file rather than `use`-ing the script directly — this project's "extract-and-stub" convention. When the real function changes, update the copy in the test too.

## ZFS_Utils.pm / sneakernet

- `test_zfs_utils.pl` — smoke tests of `ZFS_Utils.pm`'s functions; dry-run safe with no arguments, or processes real snapshot-list files if given two or more.
- `test_findCommonBaseSnapshot.pl` — the incremental-base-selection fallback added to `makeReplicateCommands` in `ZFS_Utils.pm` v1.5.0 (see `sneakernet/problem/RepairPlan.md` for the incident that motivated it).
- `test_parseSnapshotDateTime.pl` — `parseSnapshotDateTime` directly.
- `test_parseSnapshotDateTime_import.pl` — confirms `parseSnapshotDateTime` is correctly exported from `ZFS_Utils`.
- `test_parseSnapshotDateTime_seconds_fix.pl` — regression for a `HH.MM.SS` → `HH:MM.SS` (should be `HH:MM:SS`) parsing bug.
- `test_getLatestSnapshots.pl` — snapshot selection across various date formats.
- `test_cleanSnaps.pl` — the standalone `cleanSnaps/` tool at the repo's top level (a sibling of `testLibrary/`), not `sneakernet/cleanupScripts/cleanSnaps`.
- `test_checkSizeAgainstTransport.pl` — regression for `checkSizeAgainstTransport()`'s `df`-parsing bug, found running the real harness against a clean folder-based-transport sandbox.
- `test_sendIsIncremental.pl` — `sendIsIncremental()`, `ensureScratchVerifyDataset()`, and the `doSourceReplication` call-site logic added in sneakernet v1.10.6.
- `test_redactSecrets.pl` — `redactSecrets()` (log/report redaction of `transport.encryptionKey`), added per `sneakernet/allowKeyRotation.md` Part 1.
- `test_updateConfigKeys.pl` — `cleanupScripts/updateConfigKeys` after its migration from a raw YAML::Tiny read-modify-write cycle to `YAMLPatch`.
- `test_updateTarget_missingDatasetDir.pl` — regression for `updateTarget()`'s crash on a missing transport-datasets directory, found running the real harness against a target-role sandbox.
- `test_target_initialization_advanced.pl` — runtime issues in sneakernet target-mode initialization.
- `test_target_uninitialized.pl` — uninitialized-variable access in sneakernet target mode.
- `test_snapShotReport.pl` — report generation logic for various snapshot scenarios.
- `testSneakernet.pl` — runs `sneakernet` itself in dry-run mode at maximum verbosity, validating configuration and command generation without making changes.

## validateBackup

- `test_mergeJoinListings.pl` — the merge-join comparison engine: record parsing, malformed-record detection, join pairing, the `mtimeSlack`/age-band logic, and the `find -s`-vs-`sort` ordering trap as a regression guard.
- `test_selectChecksumSample.pl` — `randFile` 0/1/N>1 sampling (including the `rand(0)==rand(1)` guard) and `maxSampleFileSize`'s boundary.
- `test_readChecksumOutput.pl` — parsing for all three supported `digestCommand` shapes, and path-keyed (never positional) correlation between the two sides' digest output.
- `test_findSharedSnapshot.pl` — shared-snapshot selection by `creation` time, `excludeSnap`, and same-second tie-breaking.
- `test_resolveSnapshotRoot.pl` — every dataset state (zvol, `mountpoint=none`, `mounted=no`, legacy mountpoint) and the project's first `ssh` PATH shim, exercising `sshCommand()`'s remote-host branch.

## sneakernet test harness (real ZFS sandbox)

Backs `sneakernet/testing/run-tests`, which runs `sneakernet/Documentation/TESTING.md`'s 19-part manual plan deterministically against a real sandbox. See `sneakernet/Documentation/TESTING_automation.md` for the full design.

- `test_Harness_Safe.pl` — `Harness::Safe`, the sandbox-enforcement layer; no real ZFS or test host needed, all exec calls are intercepted.
- `test_Harness_Containment.pl` — `Harness::Containment`, the config containment gate; pure YAMLPatch-level testing.
- `test_Harness_Catalogue.pl` — `Harness::Catalogue` against a small fixture catalogue, not the real 19-part one.
- `test_Harness_Runner.pl` — `Harness::Runner` against a small fixture catalogue; `zfs` calls go through `$Harness::Safe::EXEC_OVERRIDE`.
- `test_Harness_Report.pl` — `Harness::Report`, exercised end-to-end against `Harness::Runner`'s real result shape rather than hand-typed fixtures, to catch schema drift.
- `test_catalogue_coverage.pl` — structural coverage checks over the full 19-part catalogue (no raw `/tmp` paths, every destructive `zfs` call maps to an allow-listed primitive, etc.).
- `test_run_tests_cli.pl` — `run-tests`' own CLI argument parsing; shells out to the real script since it's a thin wrapper with no dedicated module.

## YAMLPatch.pm

- `test_YAMLPatch.pl` — the path-addressed, formatting-preserving YAML editor: parsing, every mutator, relaxation flags, commit gates, and round-trip fidelity.
- `test_yamlpatch_cli.pl` — equivalence between `utilities/yamlpatch` (the CLI) and the `YAMLPatch.pm` API it wraps.

## Support scripts and fixtures

- `fake_zfs.sh` — a trivial `zfs` PATH shim (`cat mysnaps`) used by some of the older sneakernet tests.
- `mysnaps` — a real-world-shaped snapshot listing, read by `fake_zfs.sh`.
- `resetSnapshots.pl` — resets a dataset to a previous snapshot state; a sandbox-maintenance tool, not a test itself.
- `README` — this file.

**Snapshot-listing fixture pairs** (`<dataset>.source.test.data` / `<dataset>.target.test.data`), used by the older `ZFS_Utils.pm`/sneakernet tests to simulate a source and target pool's snapshots without real ZFS. Correctly processing them should produce the `zfs send` commands needed to bring target up to date with source:

- `files_share` — has child datasets, with **inconsistent** snapshots (`storage/files_share/nfs` has no snapshots for `12/14` or `12/15`), so it should generate a separate send per child dataset.
- `iscsi` — no child datasets.
- `nextcloud` — has child datasets, but is **fully consistent**, so it should generate a single `zfs send -R`.
