feat(batch2): verify parser remainder features

This commit is contained in:
Joseph Doherty
2026-02-28 07:06:09 -05:00
parent f17d6c6bfb
commit 3ace39d606
3 changed files with 159 additions and 1 deletions

View File

@@ -13,6 +13,7 @@
using System.Text;
using Shouldly;
using ZB.MOM.NatsNet.Server;
using ZB.MOM.NatsNet.Server.Internal;
using ZB.MOM.NatsNet.Server.Protocol;
@@ -754,6 +755,110 @@ public class ProtocolParserTests
}
}
[Fact]
public void ParsePub_SplitPayload_ClonesPubArgAndCompletesMessage()
{
var c = DummyClient();
var h = DummyHandler();
var first = "PUB foo 5\r\nhe"u8.ToArray();
ProtocolParser.Parse(c, h, first).ShouldBeNull();
c.State.ShouldBe(ParserState.MsgPayload);
c.ArgBuf.ShouldNotBeNull();
Encoding.ASCII.GetString(c.ArgBuf!).ShouldBe("foo 5");
c.MsgBuf.ShouldNotBeNull();
Encoding.ASCII.GetString(c.MsgBuf!).ShouldBe("he");
h.InboundMessages.Count.ShouldBe(0);
var second = "llo\r\n"u8.ToArray();
ProtocolParser.Parse(c, h, second).ShouldBeNull();
c.State.ShouldBe(ParserState.OpStart);
h.InboundMessages.Count.ShouldBe(1);
Encoding.ASCII.GetString(h.InboundMessages[0]).ShouldBe("hello\r\n");
}
[Fact]
public void ClonePubArg_ClientBranch_ReprocessesPubArgs()
{
var c = DummyClient();
var h = DummyHandler();
c.Pa.Arg = "foo 5"u8.ToArray();
c.Pa.HeaderSize = -1;
var err = ProtocolParser.ClonePubArg(c, h, lmsg: false);
err.ShouldBeNull();
c.ArgBuf.ShouldNotBeNull();
Encoding.ASCII.GetString(c.ArgBuf!).ShouldBe("foo 5");
Encoding.ASCII.GetString(c.Pa.Subject!).ShouldBe("foo");
c.Pa.Size.ShouldBe(5);
}
[Fact]
public void ClonePubArg_RouterLmsgBranch_ReprocessesRoutedOriginArgs()
{
var c = DummyRouteClient();
var h = DummyHandler();
c.Pa.Arg = "$G foo 5"u8.ToArray();
c.Pa.HeaderSize = -1;
var err = ProtocolParser.ClonePubArg(c, h, lmsg: true);
err.ShouldBeNull();
c.ArgBuf.ShouldNotBeNull();
Encoding.ASCII.GetString(c.ArgBuf!).ShouldBe("$G foo 5");
Encoding.ASCII.GetString(c.Pa.Account!).ShouldBe("$G");
Encoding.ASCII.GetString(c.Pa.Subject!).ShouldBe("foo");
c.Pa.Size.ShouldBe(5);
}
[Fact]
public void ClonePubArg_LeafHeaderBranch_ReprocessesLeafHeaderArgs()
{
var c = new ParseContext { Kind = ClientKind.Leaf, MaxPayload = -1 };
var h = DummyHandler();
c.Pa.Arg = "$G foo 2 5"u8.ToArray();
c.Pa.HeaderSize = 2;
var err = ProtocolParser.ClonePubArg(c, h, lmsg: false);
err.ShouldBeNull();
c.ArgBuf.ShouldNotBeNull();
Encoding.ASCII.GetString(c.ArgBuf!).ShouldBe("$G foo 2 5");
Encoding.ASCII.GetString(c.Pa.Account!).ShouldBe("$G");
Encoding.ASCII.GetString(c.Pa.Subject!).ShouldBe("foo");
c.Pa.HeaderSize.ShouldBe(2);
c.Pa.Size.ShouldBe(5);
}
[Fact]
public void ClientConnection_ExposesParserCompatibilityMethods()
{
var flags = System.Reflection.BindingFlags.Instance
| System.Reflection.BindingFlags.NonPublic
| System.Reflection.BindingFlags.Public;
var methods = typeof(ClientConnection).GetMethods(flags);
methods.Any(method =>
method.Name == "Parse" &&
method.GetParameters().Length == 2 &&
method.GetParameters()[0].ParameterType == typeof(byte[]) &&
method.GetParameters()[1].ParameterType == typeof(IProtocolHandler)).ShouldBeTrue();
methods.Any(method =>
method.Name == "OverMaxControlLineLimit" &&
method.GetParameters().Length == 3 &&
method.GetParameters()[0].ParameterType == typeof(byte[]) &&
method.GetParameters()[1].ParameterType == typeof(int) &&
method.GetParameters()[2].ParameterType == typeof(IProtocolHandler)).ShouldBeTrue();
methods.Any(method =>
method.Name == "ClonePubArg" &&
method.GetParameters().Length == 2 &&
method.GetParameters()[0].ParameterType == typeof(IProtocolHandler) &&
method.GetParameters()[1].ParameterType == typeof(bool)).ShouldBeTrue();
}
// =====================================================================
// TestProtocolHandler — stub handler for tests
// =====================================================================
@@ -770,6 +875,7 @@ public class ProtocolParserTests
public int PingCount { get; private set; }
public int PongCount { get; private set; }
public byte[]? ConnectArgs { get; private set; }
public List<byte[]> InboundMessages { get; } = [];
public Exception? ProcessConnect(byte[] arg) { ConnectArgs = arg; return null; }
public Exception? ProcessInfo(byte[] arg) => null;
@@ -786,7 +892,7 @@ public class ProtocolParserTests
public Exception? ProcessLeafUnsub(byte[] arg) => null;
public Exception? ProcessAccountSub(byte[] arg) => null;
public void ProcessAccountUnsub(byte[] arg) { }
public void ProcessInboundMsg(byte[] msg) { }
public void ProcessInboundMsg(byte[] msg) => InboundMessages.Add(msg);
public bool SelectMappedSubject() => false;
public void TraceInOp(string name, byte[]? arg) { }
public void TraceMsg(byte[] msg) { }