Class ProtoDevice
One typed device a suite talks to - a charger, a meter, a sensor. Derive from it, add the domain
methods your scenario reads (BootAsync, PlugInAsync), and compose the protected
protocol primitives; the instance is created per test by
Proto.Context.Devices().For<TDevice>("id") and released with the test.
public abstract class ProtoDevice
- Inheritance
-
ProtoDevice
- Inherited Members
- Extension Methods
Remarks
Concurrency: one device instance is one conversation. Connection creation is single-flight and sends
are serialized, so concurrent sends share one connection instead of opening one each. One receive may
be in flight at a time - a second concurrent receive fails fast with an error naming the device,
because it would steal frames from the first. A send that races a disconnect fails with the same
named device error instead of a disposed-socket exception. Sends and receives may run concurrently
(one in each direction), and the test's end disconnects the device, records
device.connected = false and emits the same device.disconnect an explicit call does.
Properties
Exchange
A readable log of the frames exchanged so far, for failure messages.
protected IReadOnlyList<string> Exchange { get; }
Property Value
Id
Gets the device id, as registered and as the trace records it.
public string Id { get; }
Property Value
Methods
ConnectAsync(CancellationToken)
Connects the device if it is not connected yet; the transport connects lazily anyway.
protected ValueTask ConnectAsync(CancellationToken cancellationToken = default)
Parameters
cancellationTokenCancellationToken
Returns
DisconnectAsync(CancellationToken)
Closes the connection; the device can connect again afterwards.
protected ValueTask DisconnectAsync(CancellationToken cancellationToken = default)
Parameters
cancellationTokenCancellationToken
Returns
ExpectAsync(string, Func<DeviceFrame, bool>, TimeSpan?, CancellationToken)
Waits for a frame matching match and records the wait as an asserted
device.command: a match contributes device coverage, a timeout fails with the description
and the frames seen so far.
protected ValueTask<DeviceFrame> ExpectAsync(string description, Func<DeviceFrame, bool> match, TimeSpan? timeout = null, CancellationToken cancellationToken = default)
Parameters
descriptionstringmatchFunc<DeviceFrame, bool>timeoutTimeSpan?cancellationTokenCancellationToken
Returns
ExpectMessageAsync<TMessage>(Func<TMessage, bool>?, string?, TimeSpan?, CancellationToken)
Waits for a frame that reads as TMessage and, when given, satisfies
match; frames that are not that message are skipped. The wait is recorded like
ExpectAsync(string, Func<DeviceFrame, bool>, TimeSpan?, CancellationToken), named after the message type unless description says otherwise.
protected ValueTask<TMessage> ExpectMessageAsync<TMessage>(Func<TMessage, bool>? match = null, string? description = null, TimeSpan? timeout = null, CancellationToken cancellationToken = default)
Parameters
matchFunc<TMessage, bool>descriptionstringtimeoutTimeSpan?cancellationTokenCancellationToken
Returns
- ValueTask<TMessage>
Type Parameters
TMessage
ListenAsync(CancellationToken)
Starts listening for the device to connect to the test and returns the address to hand the system
under test, with the port the operating system chose. Only a listening transport supports it, such
as a client registered with AddTcpListener; the first send or receive waits for the connection.
protected ValueTask<string> ListenAsync(CancellationToken cancellationToken = default)
Parameters
cancellationTokenCancellationToken
Returns
ReceiveAsync(CancellationToken)
Receives the next frame and records it as a device.receive operation.
protected ValueTask<DeviceFrame> ReceiveAsync(CancellationToken cancellationToken = default)
Parameters
cancellationTokenCancellationToken
Returns
SendAsync(DeviceFrame, CancellationToken)
Sends one frame and records it as a device.send operation.
protected ValueTask SendAsync(DeviceFrame frame, CancellationToken cancellationToken = default)
Parameters
frameDeviceFramecancellationTokenCancellationToken
Returns
SendMessageAsync<TMessage>(TMessage, CancellationToken)
Sends a message type as the frame a device sends: its data string, or its bytes for a binary message.
protected ValueTask SendMessageAsync<TMessage>(TMessage message, CancellationToken cancellationToken = default) where TMessage : notnull
Parameters
messageTMessagecancellationTokenCancellationToken
Returns
Type Parameters
TMessage
SendTextAsync(string, CancellationToken)
Sends one text frame.
protected ValueTask SendTextAsync(string text, CancellationToken cancellationToken = default)
Parameters
textstringcancellationTokenCancellationToken