FilesystemCorpus
Rasuvaeff\PropertyTesting\Runner\FilesystemCorpus
Class — Package: property-testing-core — Source — Version: v1.0.0-1-g88fdee2
Implements: Runner\Corpus, Runner\SearchCorpus
Opt-in on-disk corpus of a property's past failures, replayed before the random phase so a fixed bug stays fixed (fast regression replay).
A failure is recorded as its minimised input whenever Internal\ValueCodec can represent every argument as data — such an entry replays as a single run and survives changes to the generation sequence. Inputs that cannot be represented (objects, closures, in-body Gen::draw() pseudo-arguments) fall back to storing the run's seed, which reproduces the failure only while the generation sequence is unchanged; Runner\SEQUENCE_EPOCH fences those entries off when it is not.
Takes the directory to write under; it reads no environment of its own, like the rest of the engine. Adapters resolve PROPERTY_DB into a corpus through Runner\CorpusFactory::fromDsn(), which picks this class or Runner\RedisCorpus by the value's scheme. One file per property (<sha1(id)>.json) keeps the directory gitignore-friendly.
Constants
| Constant | Type | Value | Description |
|---|---|---|---|
FORMAT_VERSION | int | 1 | On-disk layout version. A file written by a different version is ignored wholesale rather than guessed at. |
SEQUENCE_EPOCH | int | 2 | Generation-sequence epoch. Seed entries reproduce a failure only while the seed→values mapping holds, so bump this in any release that shifts the generated sequence (new boundary bias, changed draw order, a rewritten arbitrary) — older seed entries are then dropped instead of replaying a different input under the guise of a regression. Values entries carry the input itself and are unaffected. |
Constructor
__construct(
string $directory,
)| Parameter | Type | Default | Description |
|---|---|---|---|
$directory | string | required | The directory the documents live in; created on the first write. |
Methods
recall()
recall(string $id, list<string> $parameterNames): arrayThe usable entries recorded for $id, cheapest first (values before seeds, most recently recorded first within each kind).
$parameterNames— The property method's current parameters, in order.
Unusable entries are silently skipped: a corrupt file, a foreign format version, a value the codec can no longer decode (renamed enum), a seed from a superseded Runner\SEQUENCE_EPOCH, or a values entry whose argument names no longer match $parameterNames (the property's signature changed, so replaying it would feed the body a different input).
remember()
remember(
string $id,
CounterExample $counterExample,
list<string> $parameterNames,
): voidRecords $counterExample as the newest entry for $id, preferring its minimised arguments over the bare seed.
$parameterNames— The property method's current parameters, in order.
Throws:
RuntimeException— When the document could not be written.
Either the document is on disk when this returns, or it throws: a write that could not complete — the lock file replaced by a link, the temp path occupied, a short write on a full disk, a failed rename, a document held by another format version — is reported, never skipped in silence. The runner turns the exception into a Event\CorpusFailed event and goes on without the corpus; the property's outcome is untouched, but nobody is told a counterexample was recorded when it was not.
prune()
prune(string $id, Runner\CorpusEntry $entry): voidDrops $entry from $id's corpus — the replay no longer fails, so the regression is fixed and the entry has served its purpose.
Throws:
RuntimeException— When the entry cannot be re-encoded to the key that identifies it, or when the document could not be written.
recallTargets()
recallTargets(string $id, list<string> $parameterNames): arrayThe best inputs recorded for $id's targets — the search document, apart from the regression document, so neither reader mistakes the other's entries for its own.
$id— The property id.$parameterNames— The property method's current parameters, in order.
rememberTargets()
rememberTargets(
string $id,
\Runner\Targets $targets,
list<string> $parameterNames,
): voidReplaces the search document of $id, under the same lock and with the same atomic write as the regression document; an empty pool removes it.
$id— The property id.$targets— The pool, by label.$parameterNames— The property method's current parameters, in order.
Throws:
RuntimeException— When the document could not be written.