Tests fixes, audit progress, UI completions
This commit is contained in:
@@ -195,18 +195,16 @@ public sealed class ConnectionFailureTests : IDisposable
|
||||
{
|
||||
// This test verifies the frame protocol handles connection drops
|
||||
|
||||
// Arrange - Set up a minimal server that accepts and immediately closes
|
||||
using var serverSocket = await _listener!.AcceptTcpClientAsync();
|
||||
|
||||
// Get the network stream
|
||||
var serverStream = serverSocket.GetStream();
|
||||
// Arrange - accept in background so connect can proceed.
|
||||
var acceptTask = _listener!.AcceptTcpClientAsync();
|
||||
|
||||
// Close the server side
|
||||
serverSocket.Close();
|
||||
|
||||
// Try to read from closed stream - should handle gracefully
|
||||
using var clientForTest = new TcpClient();
|
||||
await clientForTest.ConnectAsync(IPAddress.Loopback, _port);
|
||||
|
||||
using var serverSocket = await acceptTask;
|
||||
|
||||
// Close the server side immediately after accept.
|
||||
serverSocket.Close();
|
||||
|
||||
// The server immediately closed, so client reads should fail gracefully
|
||||
// This is testing the pattern used in the transport client
|
||||
@@ -279,12 +277,16 @@ public sealed class ConnectionFailureTests : IDisposable
|
||||
var incompleteHeader = new byte[] { 0x00, 0x00 }; // Only 2 of 4 header bytes
|
||||
using var ms = new MemoryStream(incompleteHeader);
|
||||
|
||||
// Act
|
||||
var frame = await FrameProtocol.ReadFrameAsync(ms, 65536, CancellationToken.None);
|
||||
|
||||
// Assert - Should return null or handle gracefully
|
||||
// The exact behavior depends on implementation
|
||||
// Either null or exception is acceptable
|
||||
// Act/Assert - Accept either a null result or an InvalidOperationException.
|
||||
try
|
||||
{
|
||||
var frame = await FrameProtocol.ReadFrameAsync(ms, 65536, CancellationToken.None);
|
||||
frame.Should().BeNull();
|
||||
}
|
||||
catch (InvalidOperationException)
|
||||
{
|
||||
// Acceptable: protocol rejects incomplete length prefix.
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Text;
|
||||
using System.Buffers.Binary;
|
||||
using StellaOps.Router.Common.Enums;
|
||||
using StellaOps.Router.Common.Frames;
|
||||
using StellaOps.Router.Common.Models;
|
||||
@@ -13,6 +14,16 @@ namespace StellaOps.Router.Transport.Tcp.Tests;
|
||||
/// </summary>
|
||||
public sealed class TcpTransportComplianceTests
|
||||
{
|
||||
private static string CorrelationIdFromSeed(int seed)
|
||||
{
|
||||
Span<byte> bytes = stackalloc byte[16];
|
||||
BinaryPrimitives.WriteInt32LittleEndian(bytes, seed);
|
||||
BinaryPrimitives.WriteInt32LittleEndian(bytes[4..], unchecked(seed ^ (int)0x9E3779B9));
|
||||
BinaryPrimitives.WriteInt32LittleEndian(bytes[8..], seed * 397);
|
||||
BinaryPrimitives.WriteInt32LittleEndian(bytes[12..], ~seed);
|
||||
return new Guid(bytes).ToString("N");
|
||||
}
|
||||
|
||||
#region Protocol Roundtrip Tests
|
||||
|
||||
[Trait("Category", TestCategories.Unit)]
|
||||
@@ -25,7 +36,7 @@ public sealed class TcpTransportComplianceTests
|
||||
var request = new RequestFrame
|
||||
{
|
||||
RequestId = "req-tcp-12345",
|
||||
CorrelationId = "corr-tcp-67890",
|
||||
CorrelationId = CorrelationIdFromSeed(1),
|
||||
Method = "POST",
|
||||
Path = "/api/tcp-test",
|
||||
Headers = new Dictionary<string, string>
|
||||
@@ -110,7 +121,7 @@ public sealed class TcpTransportComplianceTests
|
||||
var frame = new Frame
|
||||
{
|
||||
Type = FrameType.Request,
|
||||
CorrelationId = "binary-tcp",
|
||||
CorrelationId = CorrelationIdFromSeed(2),
|
||||
Payload = binaryPayload
|
||||
};
|
||||
|
||||
@@ -145,7 +156,7 @@ public sealed class TcpTransportComplianceTests
|
||||
var frame = new Frame
|
||||
{
|
||||
Type = FrameType.Request,
|
||||
CorrelationId = $"size-{payloadSize}",
|
||||
CorrelationId = CorrelationIdFromSeed(payloadSize),
|
||||
Payload = payload
|
||||
};
|
||||
|
||||
@@ -207,7 +218,7 @@ public sealed class TcpTransportComplianceTests
|
||||
.Select(i => new Frame
|
||||
{
|
||||
Type = FrameType.Request,
|
||||
CorrelationId = $"order-{i:D5}",
|
||||
CorrelationId = CorrelationIdFromSeed(i),
|
||||
Payload = BitConverter.GetBytes(i)
|
||||
})
|
||||
.ToList();
|
||||
@@ -230,7 +241,7 @@ public sealed class TcpTransportComplianceTests
|
||||
// Assert - Order preserved
|
||||
for (int i = 0; i < frameCount; i++)
|
||||
{
|
||||
receivedIds[i].Should().Be($"order-{i + 1:D5}");
|
||||
receivedIds[i].Should().Be(CorrelationIdFromSeed(i + 1));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,11 +254,11 @@ public sealed class TcpTransportComplianceTests
|
||||
|
||||
var frames = new[]
|
||||
{
|
||||
new Frame { Type = FrameType.Hello, CorrelationId = "1", Payload = Array.Empty<byte>() },
|
||||
new Frame { Type = FrameType.Request, CorrelationId = "2", Payload = new byte[] { 1 } },
|
||||
new Frame { Type = FrameType.Response, CorrelationId = "3", Payload = new byte[] { 2 } },
|
||||
new Frame { Type = FrameType.Heartbeat, CorrelationId = "4", Payload = Array.Empty<byte>() },
|
||||
new Frame { Type = FrameType.Cancel, CorrelationId = "5", Payload = Array.Empty<byte>() }
|
||||
new Frame { Type = FrameType.Hello, CorrelationId = CorrelationIdFromSeed(1), Payload = Array.Empty<byte>() },
|
||||
new Frame { Type = FrameType.Request, CorrelationId = CorrelationIdFromSeed(2), Payload = new byte[] { 1 } },
|
||||
new Frame { Type = FrameType.Response, CorrelationId = CorrelationIdFromSeed(3), Payload = new byte[] { 2 } },
|
||||
new Frame { Type = FrameType.Heartbeat, CorrelationId = CorrelationIdFromSeed(4), Payload = Array.Empty<byte>() },
|
||||
new Frame { Type = FrameType.Cancel, CorrelationId = CorrelationIdFromSeed(5), Payload = Array.Empty<byte>() }
|
||||
};
|
||||
|
||||
// Act - Write all
|
||||
@@ -469,7 +480,7 @@ public sealed class TcpTransportComplianceTests
|
||||
var frame = new Frame
|
||||
{
|
||||
Type = FrameType.Request,
|
||||
CorrelationId = "deterministic-bytes",
|
||||
CorrelationId = CorrelationIdFromSeed(42),
|
||||
Payload = new byte[] { 1, 2, 3, 4, 5 }
|
||||
};
|
||||
|
||||
@@ -544,7 +555,7 @@ public sealed class TcpTransportComplianceTests
|
||||
};
|
||||
|
||||
// Act & Assert
|
||||
await Assert.ThrowsAsync<OperationCanceledException>(
|
||||
await Assert.ThrowsAnyAsync<OperationCanceledException>(
|
||||
() => FrameProtocol.WriteFrameAsync(stream, frame, cts.Token));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user