Move 25 gateway-related test files from NATS.Server.Tests into a dedicated NATS.Server.Gateways.Tests project. Update namespaces, replace private ReadUntilAsync with SocketTestHelper from TestUtilities, inline TestServerFactory usage, add InternalsVisibleTo, and register the project in the solution file. All 261 tests pass.
100 lines
3.4 KiB
C#
100 lines
3.4 KiB
C#
using System.Text;
|
|
using NATS.Server.Gateways;
|
|
using Shouldly;
|
|
|
|
namespace NATS.Server.Gateways.Tests.Gateways;
|
|
|
|
// Go reference: gateway.go:90-120 — gateway protocol constants and command formatting.
|
|
|
|
public class GatewayCommandTests
|
|
{
|
|
[Fact]
|
|
public void FormatSub_produces_correct_wire_format()
|
|
{
|
|
// Go reference: gateway.go — RS+ propagation, sendGatewaySubsToGateway
|
|
var bytes = GatewayCommands.FormatSub("$G", "orders.>");
|
|
var line = Encoding.UTF8.GetString(bytes);
|
|
line.ShouldBe("GS+ $G orders.>\r\n");
|
|
}
|
|
|
|
[Fact]
|
|
public void FormatUnsub_produces_correct_wire_format()
|
|
{
|
|
// Go reference: gateway.go — RS- propagation, sendGatewayUnsubToGateway
|
|
var bytes = GatewayCommands.FormatUnsub("$G", "orders.>");
|
|
var line = Encoding.UTF8.GetString(bytes);
|
|
line.ShouldBe("GS- $G orders.>\r\n");
|
|
}
|
|
|
|
[Fact]
|
|
public void FormatMode_optimistic_produces_O()
|
|
{
|
|
// Go reference: gateway.go — GMODE command, "O" = Optimistic mode
|
|
var bytes = GatewayCommands.FormatMode("$G", GatewayInterestMode.Optimistic);
|
|
var line = Encoding.UTF8.GetString(bytes);
|
|
line.ShouldBe("GMODE $G O\r\n");
|
|
}
|
|
|
|
[Fact]
|
|
public void FormatMode_interest_only_produces_I()
|
|
{
|
|
// Go reference: gateway.go — GMODE command, "I" = InterestOnly mode
|
|
var bytes = GatewayCommands.FormatMode("$G", GatewayInterestMode.InterestOnly);
|
|
var line = Encoding.UTF8.GetString(bytes);
|
|
line.ShouldBe("GMODE $G I\r\n");
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseCommandType_identifies_sub()
|
|
{
|
|
// Go reference: gateway.go — processGatewayMsg dispatch on GS+
|
|
var line = Encoding.UTF8.GetBytes("GS+ ACC foo.bar\r\n");
|
|
var result = GatewayCommands.ParseCommandType(line);
|
|
result.ShouldBe(GatewayCommandType.Sub);
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseCommandType_identifies_unsub()
|
|
{
|
|
// Go reference: gateway.go — processGatewayMsg dispatch on GS-
|
|
var line = Encoding.UTF8.GetBytes("GS- ACC foo.bar\r\n");
|
|
var result = GatewayCommands.ParseCommandType(line);
|
|
result.ShouldBe(GatewayCommandType.Unsub);
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseCommandType_identifies_ping()
|
|
{
|
|
// Go reference: gateway.go — keepalive GPING command
|
|
var result = GatewayCommands.ParseCommandType(GatewayCommands.Ping);
|
|
result.ShouldBe(GatewayCommandType.Ping);
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseCommandType_identifies_pong()
|
|
{
|
|
// Go reference: gateway.go — keepalive GPONG response
|
|
var result = GatewayCommands.ParseCommandType(GatewayCommands.Pong);
|
|
result.ShouldBe(GatewayCommandType.Pong);
|
|
}
|
|
|
|
[Fact]
|
|
public void ParseCommandType_returns_null_for_unknown()
|
|
{
|
|
// Unrecognized commands should return null for graceful handling
|
|
var line = Encoding.UTF8.GetBytes("UNKNOWN something\r\n");
|
|
var result = GatewayCommands.ParseCommandType(line);
|
|
result.ShouldBeNull();
|
|
}
|
|
|
|
[Fact]
|
|
public void Wire_format_constants_end_correctly()
|
|
{
|
|
// Go reference: gateway.go — all gateway commands use CRLF line endings
|
|
var crlf = new byte[] { (byte)'\r', (byte)'\n' };
|
|
GatewayCommands.Ping.TakeLast(2).ShouldBe(crlf);
|
|
GatewayCommands.Pong.TakeLast(2).ShouldBe(crlf);
|
|
GatewayCommands.Crlf.ShouldBe(crlf);
|
|
}
|
|
}
|