Testing
Real I/O is a poor foundation for unit tests. Network operations are slow,
non-deterministic, and do not fail on demand — so error-handling paths go
untested until production breaks them. Capy ships a self-contained toolkit
that replaces the transport with in-memory mocks, drives coroutines to
completion on the calling thread, and injects failures at every
maybe_fail() site so that every error branch is exercised automatically.
Because each mock satisfies the same concept as its production counterpart,
test code reads the same as production code — the only difference is the
type of the stream or source you pass in.
What This Section Covers
-
Driving Tests —
run_blockingdrives a coroutine to completion on the calling thread without a real executor;fuseruns the test body repeatedly, injecting an error at eachmaybe_fail()site in turn until every failure path has been covered; and thethread_nameheader’sset_current_thread_namefunction labels worker threads so that failures in multi-threaded tests are easier to attribute. -
Mock Streams —
read_stream,write_stream, andstream(a connected pair) implement the partial-I/O concepts from Streams. Use them to test protocol logic that callsread_someandwrite_somewithout touching a socket. -
Mock Sources and Sinks —
read_sourceandwrite_sinkimplement the complete-I/O concepts from Sources and Sinks. Unlike the stream mocks, they loop internally until the buffer is fully filled or drained, andwrite_sinkaccepts an explicit EOF signal. -
Mock Buffer Sources and Sinks —
buffer_sourceandbuffer_sinkimplement the buffer concepts from Buffer Sources and Sinks.buffer_sourceexposes staged bytes via a pull interface;buffer_sinkprovides callee-owned storage that the algorithm writes into directly. -
Buffer Inspection —
bufgrinditerates every split point of a buffer sequence, exercising every chunk-boundary condition;buffer_to_stringconcatenates buffer sequences into astd::stringfor easy assertion.
How the Pieces Fit
A typical test constructs one or more mocks, arms a fuse, and hands the
mocks to the code under test inside a run_blocking call. The fuse
repeats the test body automatically — once for each failure site and once
in exception mode — while run_blocking keeps the whole thing on the
calling thread. Buffer utilities such as bufgrind and buffer_to_string
wrap the mock data for assertions, letting you verify that every split of
an input buffer produces the same correct output.
Continue to Driving Tests to begin.