whiskers-conformance
The in-memory reference adapter for whiskers-ports, and the conformance suite
that every adapter of those ports must pass.
memory.rsis every port held in aMutexand nothing else (MemBackend). It is the simplest honest implementation: it shows what each port means, it is whatwhiskers-service's tests run on, and the suite is proven against it before it is allowed to judge another adapter. The outbound ports (Judge,Embedder,Voice,Thinker) are scripted: a test says what they answer and reads how often they were asked.suite/fixture.rsselects laws by capability: one fixture trait per capability (MemoryFixture,JournalFixture, ...) and aSuitewhose method for a capability's laws applies only to a harness with that fixture, so an adapter runs exactly the laws for what it has and a law for a capability it lacks cannot be selected (thecompile_failexample onSuite).Suite::completeruns every law and needs every fixture;MemFixturesis the in-memory adapter's.suite/is the contracts as functions generic over an adapter: hubs (convergent merge is order-independent and idempotent, a forgotten fact wins), the journal (device-scoped alignment, pull since a cursor, the rebuild-if-longer rule, the page bound, stored bytes), pictures (never replaced, byte-exact, names that could reach a path cannot be written), the allowance (the rolling thinking window, reserve and settle of the daily voice cap, frees-up-at), secrets (absent is not empty), the outbound ports with nothing to call with, and the timed voice (suite::timing: the laws ofLineTimingandTimedAudio, andspeaks_timedfor a voice that may be asked to speak, which a paid adapter runs only when its operator agrees to the spend).
An adapter's own tests implement the fixture trait of each capability it has (a way to make a fresh port and, for the durable ones, to restart one on the same storage) and select its laws:
impl MemoryFixture for MyHarness { type Port = MyMemoryHub; fn fresh(&self) -> MyMemoryHub { .. } fn restart(&self, h: MyMemoryHub) -> MyMemoryHub { h.reopen() } }
Suite::new(MyHarness).memory();
The law functions under suite:: are public and unchanged for a harness that must run them one at a time (backend/http-conformance runs each
law under its own catch_unwind over HTTP).
The native adapters in whiskersd are held to it in crates/whiskersd/tests/conformance.rs. A Worker
adapter will run the same laws from its own harness. The suite uses no thread, clock or file, so it builds for
wasm32-unknown-unknown as well.