silk.testing.exchange.
The binary plan and receipt formats that let silk test control the test runner.
When to use#
silk.testing.runner uses this module. The host (the silk test driver) writes a plan file, and
the runner writes a receipt file. You do not call it from normal code.
Details#
A plan starts with the magic SLKTPLN1, a version (1), a mode, and a 32-byte nonce. All
integers are little-endian. There are two modes:
Per-test mode (
1). The plan has the count of discovered tests, then one catalog entry per test: ordinal, declaration name, execution identity, and action (0run,1cached). The receipt has one result per selected test. Its disposition is0cached,1passed, or2failed.Uncached mode (
2). The plan is exactly 256 bytes. It holds a SHA-256 digest of the catalog (seeupdateCatalogDigest) and the test count, then zero padding. The receipt is also padded to 256 bytes.
A receipt starts with the magic SLKTRCP1, the version, the mode, the nonce of the plan, and
the SHA-256 of the complete plan. It ends with the counts and the status.
A progress record lets the host continue a run after a test traps. It is exactly 48 bytes: the
magic SLKTPRG1, the ordinal of the test that is starting, then the cached, executed, passed
and failed counts before that test. The runner writes one before each test body runs, so after
an abnormal exit the record names the test that stopped the process.
Gotchas#
A
Plandoes not stop at the first error. After a failure it reads as empty, andfailedstays true. Checkfailedor theboolresults before a test body runs.Test output goes to the inherited stdout and stderr. Only the receipt decides the result.
Import as TestExchange with import silk.testing.exchange as TestExchange.
Public declarations: 21.
Plan#
pub struct Plan<'a>A cursor over one borrowed plan file that the silk test driver wrote.
Gotchas#
It does not stop at the first error. After a failure it reads as empty, and failed
stays true. Check failed or the bool results before a test body runs.
Entry#
pub struct Entry<'a>One borrowed per-test catalog entry.
Progress#
pub struct ProgressA run's position when a test started: the catalog ordinal of that test and the counts before it.
Details#
The runner writes it with progressRecord before each test body runs. After the process
stops abnormally, readProgress reads it back, and a new runner continues after that test.
Field ordinal#
pub ordinal: u64The catalog ordinal of the test that was starting.
Field cachedCount#
pub cachedCount: u64The cached passes before that test.
Field executed#
pub executed: u64The tests executed before that test.
Field passed#
pub passed: u64The tests that passed before that test, cached passes included.
Field failedCount#
pub failedCount: u64The tests that failed before that test.
Receipt#
pub struct ReceiptAn owned receipt under construction. Start it with beginReceipt.
openPlan#
pub fn openPlan<'a>(bytes: &'a [u8]) -> Plan<'a>Opens a plan and checks its magic, version, mode and nonce framing.
If a check fails, the returned plan is already rejected: it reads as empty, and failed
returns true.
isPerTest#
pub fn isPerTest(plan: &Plan) -> boolReturns true for a per-test plan (mode 1).
isUncached#
pub fn isUncached(plan: &Plan) -> boolReturns true for an uncached plan of 256 bytes (mode 2).
failed#
pub fn failed(plan: &Plan) -> boolReturns true after a check on the plan fails. It does not become false again.
beginPerTest#
pub fn beginPerTest(plan: &mut Plan, expectedDiscovered: u64) -> boolReads the test count of a per-test plan, and checks it and the size bound of the file.
The count must equal expectedDiscovered. Call it before any test body runs.
readEntry#
pub fn readEntry<'a>(
plan: &mut Plan<'a>,
expectedOrdinal: u64,
expectedDeclaration: &[u8],
) -> Entry<'a>Reads and checks the next catalog entry.
The ordinal and declaration name must match the expected values, and a cached entry must have an
execution identity. For an uncached plan, it returns uncachedEntry and reads nothing.
cached#
pub fn cached(entry: &Entry) -> boolReturns true for a valid entry that the host marked as a cache hit.
executionIdentity#
pub fn executionIdentity<'a>(entry: &Entry<'a>) -> &'a [u8]Borrows the opaque execution identity of an entry.
uncachedEntry#
pub fn uncachedEntry<'a>(bytes: &'a [u8]) -> Entry<'a>Returns the empty entry that is not cached, for uncached mode.
finishPerTest#
pub fn finishPerTest(plan: &mut Plan) -> boolChecks that a per-test plan ends exactly after the catalog.
validateUncached#
pub fn validateUncached(
plan: &mut Plan,
expectedCatalogDigest: &[u8],
expectedDiscovered: u64,
) -> boolChecks an uncached plan: exactly 256 bytes, the catalog digest, the test count, and zero padding.
updateCatalogDigest#
pub fn updateCatalogDigest(state: &mut Sha256, ordinal: u64, identity: &[u8]) -> ()Adds one catalog identity to the digest of an uncached plan.
It hashes the ordinal and the identity length as 8-byte little-endian values, then the identity.
beginReceipt#
pub effect fn beginReceipt(
plan: &[u8],
perTest: bool,
selected: u64,
) -> Receipt ! OutOfMemoryError ? &mut AllocatorStarts a receipt for plan. It copies the nonce and hashes the complete plan.
selected is the number of results that follow in per-test mode.
appendResult#
pub effect fn appendResult(
receipt: &mut Receipt,
ordinal: u64,
declaration: &[u8],
execution: &[u8],
disposition: u8,
) -> () ! OutOfMemoryError ? &mut AllocatorAppends one per-test result. Append results in ordinal order.
Gotchas#
It traps if the receipt is not per-test, or if disposition is more than 2.
finishReceipt#
pub effect fn finishReceipt(
receipt: Receipt,
discovered: u64,
selected: u64,
cachedCount: u64,
executed: u64,
passed: u64,
failedCount: u64,
status: u32,
) -> Bytes ! OutOfMemoryError ? &mut AllocatorAppends the counts and the status, and returns the receipt bytes.
In uncached mode the receipt is padded to exactly 256 bytes.
progressRecord#
pub effect fn progressRecord(progress: &Progress) -> Bytes ! OutOfMemoryError ? &mut AllocatorReturns the 48-byte progress record of progress.
Details#
The record is the magic SLKTPRG1, then the ordinal and the four counts as 8-byte
little-endian integers.
readProgress#
pub fn readProgress(bytes: &[u8]) -> Option<Progress>Reads a progress record that progressRecord wrote.
Details#
It returns None unless bytes is exactly one record with the SLKTPRG1 magic.
Category: Testing.
Profiles: aarch64-apple-darwin, aarch64-unknown-linux-gnu, aarch64-unknown-linux-gnu-no-libc, x86_64-unknown-linux-gnu, x86_64-unknown-linux-gnu-no-libc, wasm32-unknown-unknown, wasm32-wasip1, wasm32-wasip2.