Repository navigation
Troubleshooting
Another server or program is using the port. Use port 0 and read server.Port after Start(); see
Ports and Lifecycle. Also make sure every server is disposed (using var server = ...).
UdpServer binds when it is created, so for UDP the error comes from the constructor.
-
SocketException"Address already in use": the socket file already exists, for example left behind by a crashed run. The server never deletes a file it did not create; delete it yourself or use a new path. -
ArgumentOutOfRangeException: the path is longer than about 104 bytes. Use a short path such as/tmp/my.sock. -
PlatformNotSupportedException: Unix domain sockets are not available on this system. See Unix domain sockets.
Since 1.0, TCP connections stay open after a response. A client that reads until the server closes the connection will wait forever. Either:
- set
KeepAlive = falseon the server:new TcpServer(0) { KeepAlive = false }, or - add
.AndDisconnect()to the responses after which the server should close.
- The client may send a line ending or terminator, such as
"PING\r\n". Configure framing (MessageFraming.Delimiter("\r\n")) so it is removed before matching, or match on the full text. - Check what actually arrived:
server.ReceivedRequestsor a failingserver.Should().HaveReceived(...)lists every request. Binary data is shown as hex. - Two requests sent quickly can arrive together and be treated as one. Use framing so they are split correctly.
TCP doesn't keep message boundaries, so the client may receive two responses in one read. Use framing on the server and read by message on the client: up to the delimiter, or by length.
-
Turn on the log first:
server.Log = output.WriteLine;(orConsole.WriteLine). It shows every request, the rule it matched, the response and any error. See Logging and Diagnostics. - Is the request matched?
server.Mock.UnmatchedRequestslists requests without a response. Over TCP, an unmatched request closes the connection. - Did a
Receive(...)function throw? The response is then empty, and over TCP nothing is sent. The log shows the exception. - Is the request matched in the right state? The log shows the state of every request.
- Is a delimiter expected? With
MessageFraming.Delimiter, it is appended to responses for you. Without framing, include it in the response yourself. - Was the server started? Call
server.Start().
The log shows the server-side error, for example connection from 127.0.0.1:50125 failed: AuthenticationException: ....
- When you pass a certificate object, it must have a private key (
certificate.HasPrivateKey).TestCertificate.CreateSelfSigned()does this for you; for your own, see SSL and TLS. - When you pass a certificate name, a certificate with that subject name and a readable private key must exist in the
CurrentUserorLocalMachine"My" store. If none is found, the server can't complete the handshake and closes the connection. Passing a certificate object avoids this. - The client must trust the certificate; see Trusting the certificate.
- The host name the client validates (
AuthenticateAsClientAsync("localhost")) must match the certificate.
With RequireClientCertificate = true a client that sends no certificate, or one that your ClientCertificateValidator refuses,
fails the handshake. The log shows why ("the client sent no certificate" or the validator's decision) and ConnectionFailed is raised.
The client may notice only on its first read or write, depending on the system and the TLS version: wait on the server side
(see Mutual TLS and Known Issues).
- With
MaxBufferedBytesset (servers from a configuration file: 16 MiB), a connection that buffers more bytes than the limit without a complete message is closed and logged (InvalidDataException). Check the framing: a delimiter that never arrives is the usual cause. - A length-prefixed message with an invalid length (smaller than the prefix, or negative) closes that connection too.
The message starts with the place of the mistake, such as rules[1]: unknown property "replys". Unknown properties are errors on purpose, so typos
are found. See the error list. The same message is printed by rony run and rony validate.
Exit code 1 is a runtime failure (for example Error: Address already in use for a port that is taken),
2 a usage error, an invalid or missing file, or a bad Unix socket path (the message names the file and the place). Details in Standalone Server.
The lambda fits both the text and the byte overloads. Give it a type: Receive((byte[] x) => x) or Receive((string x) => x).
Both libraries define Times. Use Rony.Net.Times.Once(), or add using Times = Rony.Net.Times; in files that only verify Rony.Net requests.
The request may still be on its way, for example when your code sends in the background. Use
await server.Mock.WaitForRequestAsync(...) before verifying.
- Use short timeouts in the client under test.
- Don't wait for real timeouts with
NoReply()longer than you need to; make the client's timeout configurable. - Replace
Thread.SleepwithWaitForRequestAsync.
Check the known issues and limitations first.
Open an issue with a small test that shows the problem.