Namespace ProtoTest.Messaging

Classes

MessagingAssertionException

Represents a failed assertion on a consumed message; the message names the destination it was made against. A shape failure keeps the shared matcher exception as its inner exception, so the mismatch list stays inspectable.

MessagingAttachmentOptions

Controls whether published and received message payloads are captured as test attachments. Payloads are redacted through JsonDiagnosticSanitizer and capped at MaxDiagnosticBodyLength. Non-Json payloads are captured as plain text. Binds from ConfigurationSectionName.

MessagingOptions

Messaging defaults, layered from ProtoTest:Messaging over the code-based registration.

MessagingShapeMatchData

Shape-match data attached to a messaging.contract.shape observation.

ProtoDestination

The messaging destination addressing forms. An exchange destination is the bare name the surface has always spoken: publishing sends to that exchange and awaiting binds the test's tap to it. A queue destination is queue:{name}: it names the queue itself, and an adapter whose broker owns queues consumes the queue directly instead of binding a tap - the form a dead-letter queue is read with.

ProtoExecutionContextExtensions
ProtoHostBuilderExtensions
ProtoMessage

A message observed on or sent to a broker. Adapters map their technology's message onto this shape; the test-side API and the trace never see a broker-specific type.

ProtoMessageAssertions

The shape assertions of one consumed message, reached through Should. Shape has no negated form, so the facade is positive-only. MatchShape(object, JsonSerializerOptions?) returns the message, so assertions chain.

ProtoMessageAwaitQueue

One consumer's await machinery, shared by the in-memory, RabbitMQ and MassTransit adapters: awaits on the consumer serialize in call order, only messages at or after the consumer's position can match, a matched message is consumed exactly once per destination, and a message that matched no awaited predicate stays in the source for a later await. Consumption is scoped by destination: each destination's deliveries form their own position space, so a position alone does not identify a delivery across destinations. The scan runs before every wait and again when the wait returns at the deadline, so a delivery assigned at the same instant as the timeout still wins. An adapter contributes an IProtoMessageAwaitSource over its own storage and owns one queue per consumer; it never implements its own await loop, gate, position or consumed set.

ProtoMessageClient

The test-side messaging API over the configured broker. Publishes and awaits are traced as messaging.publish and messaging.await operations with the payload as a section, and recorded as observations for the trace and for a collector a suite registers; the package itself ships no collector and aggregates no destinations.

ProtoMessageConsumerBase

The base every messaging adapter's consumer derives from. It owns the one await queue: waits on a consumer serialize in call order, only deliveries at or after the consumer's position can match, a matched delivery is consumed exactly once, a delivery that matched no awaited predicate stays for a later await, and the source is scanned once more when the wait returns at the deadline, so a delivery assigned at the same instant as the timeout still wins. An adapter implements AwaitAsync(string, Func<ProtoMessage, bool>, TimeSpan, CancellationToken) by resolving its IProtoMessageAwaitSource and calling the protected AwaitAsync(…, sourceFactory) overload: it supplies a source (snapshot + wait), never its own await loop, gate, position or consumed set.

ProtoMessagingAssertions

Shape assertions for consumed messages, reusing the Json shape matcher the REST, GraphQL and gRPC integrations use. A message payload is Json by convention, so an expected anonymous shape reads the same way as elsewhere.

ProtoMessagingBuilder

Structs

ProtoMessageAwaitEntry

One delivery a consumer can await over, with the position it occupies in its source's arrival order. Positions must be unique and increasing; a consumer only ever matches entries at or after its own position.

ProtoMessageAwaitSnapshot

One scan of a consumer's source: the candidate deliveries at or after the awaited position, and the wake-up the scan arms for the deliveries that arrive after it. A source whose deliveries are already held - a log the consumer reads itself - leaves Changed null, because its next wait watches that storage directly.

Interfaces

IProtoMessageAwaitSource

The ordered deliveries one consumer awaits over, plus the wait that wakes its scan. An adapter implements it over its own storage: the in-memory broker and the MassTransit harness over their published history, the RabbitMQ tap over its log and channel. The consumer owns a ProtoMessageAwaitQueue and supplies this source; the queue enforces the serialized, consumed-once semantics.

IProtoMessageBroker

The broker capability's adapter contract. The capability owns the broker resource and the trace-facing API; an adapter owns the client technology (RabbitMQ today, others later). One broker is shared by the whole run and may publish concurrently, while every test gets its own IProtoMessageConsumer.

IProtoMessageConsumer

One test's view of a broker, created by CreateConsumerAsync(CancellationToken) during setup and disposed with the test's teardown. A consumer belongs to exactly one test: it must never be shared, and its disposal removes whatever the adapter declared for the test (queues, in RabbitMQ's case). Each test gets its own tap on an exchange destination, so parallel tests cannot steal each other's messages there. A queue destination is shared: tests awaiting the same queue compete for it.