Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

blockwatcher-stellar-testkit

blockwatcher-stellar-testkit is a scripted JSON-RPC mock node blockwatcher-stellar’s own tests share, so that no test in that crate has to run against a live stellar-rpc endpoint. Its crate doc states why the mock is a crate rather than a #[cfg(test)] module: “Consumed exclusively via [dev-dependencies]: nothing here ever reaches a production binary. Its crate boundary exists so this mock can be shared by both a unit test module (#[cfg(test)] code inside src/) and any number of tests/*.rs integration binaries, without duplicating it or tripping the dead-code lint on whichever MockReply variants one particular consumer happens not to construct” (crates/blockwatcher-stellar-testkit/src/lib.rs). See Workspace map § Verifying the rings for how scripts/check-dep-graph.sh checks the dev-dependency-only half of that by name, the same way it checks blockwatcher-testkit and blockwatcher-evm-testkit.

It declares no workspace crate in [dependencies]: the mock is a self-contained axum listener. There is no production cycle with blockwatcher-stellar; that crate reaches this one only as a [dev-dependencies] edge.

The harness and the system under test line up like this: a scripted node on one side, a real stellar-rpc source on the other, meeting over the same JSON-RPC wire a real node would speak:

flowchart LR
    mock["mock_node<br/>scripted json-rpc"] --> src["stellar-rpc source<br/>blockwatcher-stellar"]
    src --> test["test asserts on<br/>decoded events, cursors"]

Its production dependencies:

  • axum: the HTTP server mock_node binds
  • reqwest: the HTTP client this crate’s own unit test dials
  • serde_json: the JSON-RPC request/response shapes handle_request builds
  • tokio (net/rt-multi-thread/sync/time features): the listener and DelayedResult’s wait run on
  • url: parsing the bound address into MockNode::url

Key takeaways

  • blockwatcher-stellar-testkit is a scripted JSON-RPC mock node blockwatcher-stellar’s own tests share, so no test needs a live stellar-rpc endpoint.
  • It is consumed exclusively via [dev-dependencies]; it declares no workspace crate in [dependencies].
  • A scripted node stands in for a real node on one side, and a real stellar-rpc source runs unmodified on the other, meeting over the same wire protocol.

Responsibilities

  • Runs a scripted JSON-RPC node on an ephemeral loopback port: mock_node takes a handler closure over (method, params) and answers whatever MockReply it returns, so a test swaps behavior by the closure it passes rather than by editing this crate (lib.rs). mock_stellar_rpc is the same constructor, returning (url, node) together.
  • Dispatches a JSON-RPC batch (an array body) through that same handler in request order and answers with the members’ replies as an array. MockNode::bodies is the raw POST body of every request the node received, which is how a test tells one batched request from several single ones — the handler alone cannot, since it sees a batch member exactly as it sees a lone request (lib.rs).
  • Provides CallLog, which records every JSON-RPC call a mock node’s handler observed, method and params rather than just method, so a test can assert not only call order but which ledger a specific call named (lib.rs).

Not this crate’s job: implementing stellar-rpc itself (blockwatcher-stellar owns the source; this crate only mocks the wire it speaks to), standing in for a chain-agnostic port directly (blockwatcher-portsfakes feature does that; this crate mocks one family’s wire protocol underneath a real module, not the port trait above it), or building a Pool<StellarEndpoint> (blockwatcher-stellar’s tests assemble that against MockNode::url). It has no in-memory chain fixture and no WebSocket mock: stellar-rpc polls HTTP JSON-RPC for closed ledgers.

Key types and functions

NameKindRole
mock_nodeasync fnStarts a scripted HTTP JSON-RPC node on an ephemeral port, returning once it accepts connections (lib.rs)
mock_stellar_rpcasync fnmock_node, returning (url, node) together (lib.rs)
MockNodestructThe running node’s handle; url is where to point an endpoint, bodies() is every raw POST body in arrival order, and dropping it aborts the listener task (lib.rs)
MockReplyenumOne scripted answer: Result, Error, Status, StatusWithHeaders, RawBody, Hang, or DelayedResult (lib.rs)
CallLogstructRecords every call a handler observed, method and params, in order (lib.rs)

The mock JSON-RPC node

mock_node‘s handler sees each request’s method and params and returns a MockReply. A JSON object body is one call. A JSON array body is a batch: each member is dispatched through the same handler in request order, and the HTTP response is the members’ JSON-RPC replies as an array.

RawBody, Hang, StatusWithHeaders, and DelayedResult exist for shapes Result, Error, and Status cannot express: a body missing both result and error, one carrying both, a well-formed JSON-RPC error wrapped in a non-2xx status, a quota window named in a Retry-After header rather than a body, a node that accepts the connection and never answers (so the caller’s own timeout ends the call), and a successful result held open for after so overlapping in-flight calls stay in flight.

The crate doc names the mock liberties a batch test must not lean on:

Deliberate mock liberties a batch test must not lean on: a member reply
that is not a per-member body — a bare status, a raw body, or a hang —
answers the whole batch, and the members after it are never dispatched,
where a real node has no such coupling between one member and the
response's status line. There is no partial-batch reply at all.

(crates/blockwatcher-stellar-testkit/src/lib.rs)

Neighbours

This crate depends on no workspace crate in production. The following crate depends on it, under [dev-dependencies] only (per the dependency table, and checked by name per Workspace map § Verifying the rings):

  • blockwatcher-stellar: MockNode, MockReply, CallLog, and mock_node, imported inside #[cfg(test)] in source/run.rs

Reading the source

  1. lib.rs’s crate doc comment: the crate-boundary rationale, the ephemeral-port binding rule, batch dispatch, and the mock liberties, before any of the code that implements them.
  2. MockReply, mock_node, MockNode, handle_request, dispatch (lib.rs): the HTTP JSON-RPC mock.
  3. CallLog (lib.rs): the call-recording type source/run.rs asserts against.
  4. The crate’s own mock_stellar_rpc_answers_jsonrpc test: the smallest proof the listener speaks JSON-RPC.