using System.Net; using System.Net.Sockets; using System.Text; using NATS.Server.Routes; using NATS.Server.Subscriptions; namespace NATS.Server.Clustering.Tests.Routes; public class RouteBatchProtoParityBatch3Tests { [Fact] public async Task SendRouteSubProtosAsync_writes_batched_rs_plus_frames() { var (connection, peer) = CreateRoutePair(); try { await connection.SendRouteSubProtosAsync( [ new RemoteSubscription("orders.*", null, "r1", Account: "A"), new RemoteSubscription("orders.q", "workers", "r1", Account: "A", QueueWeight: 2), ], CancellationToken.None); var data = ReadFromPeer(peer); data.ShouldContain("RS+ A orders.*"); data.ShouldContain("RS+ A orders.q workers 2"); } finally { await connection.DisposeAsync(); peer.Dispose(); } } [Fact] public async Task SendRouteUnSubProtosAsync_writes_batched_rs_minus_frames() { var (connection, peer) = CreateRoutePair(); try { await connection.SendRouteUnSubProtosAsync( [ new RemoteSubscription("orders.*", null, "r1", Account: "A"), new RemoteSubscription("orders.q", "workers", "r1", Account: "A"), ], CancellationToken.None); var data = ReadFromPeer(peer); data.ShouldContain("RS- A orders.*"); data.ShouldContain("RS- A orders.q workers"); } finally { await connection.DisposeAsync(); peer.Dispose(); } } [Fact] public async Task SendRouteSubOrUnSubProtosAsync_skips_empty_lines_and_flushes_once() { var (connection, peer) = CreateRoutePair(); try { await connection.SendRouteSubOrUnSubProtosAsync( ["RS+ A foo.bar", "", " ", "RS- A foo.bar"], CancellationToken.None); var data = ReadFromPeer(peer); data.ShouldContain("RS+ A foo.bar"); data.ShouldContain("RS- A foo.bar"); data.ShouldNotContain("\r\n\r\n"); } finally { await connection.DisposeAsync(); peer.Dispose(); } } private static (RouteConnection Route, Socket Peer) CreateRoutePair() { var listener = new TcpListener(IPAddress.Loopback, 0); listener.Start(); var endpoint = (IPEndPoint)listener.LocalEndpoint; var client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); client.Connect(endpoint); var server = listener.AcceptSocket(); listener.Stop(); return (new RouteConnection(client), server); } private static string ReadFromPeer(Socket peer) { peer.ReceiveTimeout = 2_000; var buffer = new byte[4096]; var read = peer.Receive(buffer); return Encoding.ASCII.GetString(buffer, 0, read); } }