Fix E2E test gaps and add comprehensive E2E + parity test suites
- Fix pull consumer fetch: send original stream subject in HMSG (not inbox) so NATS client distinguishes data messages from control messages - Fix MaxAge expiry: add background timer in StreamManager for periodic pruning - Fix JetStream wire format: Go-compatible anonymous objects with string enums, proper offset-based pagination for stream/consumer list APIs - Add 42 E2E black-box tests (core messaging, auth, TLS, accounts, JetStream) - Add ~1000 parity tests across all subsystems (gaps closure) - Update gap inventory docs to reflect implementation status
This commit is contained in:
@@ -0,0 +1,91 @@
|
||||
using System.Text;
|
||||
using NATS.Server.Mqtt;
|
||||
|
||||
namespace NATS.Server.Tests.Mqtt;
|
||||
|
||||
public class MqttProtocolConstantsParityBatch2Tests
|
||||
{
|
||||
[Fact]
|
||||
public void Extended_constants_match_go_reference_values()
|
||||
{
|
||||
MqttProtocolConstants.MultiLevelSidSuffix.ShouldBe(" fwc");
|
||||
MqttProtocolConstants.Prefix.ShouldBe("$MQTT.");
|
||||
MqttProtocolConstants.SubPrefix.ShouldBe("$MQTT.sub.");
|
||||
|
||||
MqttProtocolConstants.StreamName.ShouldBe("$MQTT_msgs");
|
||||
MqttProtocolConstants.StreamSubjectPrefix.ShouldBe("$MQTT.msgs.");
|
||||
MqttProtocolConstants.RetainedMsgsStreamName.ShouldBe("$MQTT_rmsgs");
|
||||
MqttProtocolConstants.RetainedMsgsStreamSubject.ShouldBe("$MQTT.rmsgs.");
|
||||
MqttProtocolConstants.SessStreamName.ShouldBe("$MQTT_sess");
|
||||
MqttProtocolConstants.SessStreamSubjectPrefix.ShouldBe("$MQTT.sess.");
|
||||
MqttProtocolConstants.SessionsStreamNamePrefix.ShouldBe("$MQTT_sess_");
|
||||
MqttProtocolConstants.QoS2IncomingMsgsStreamName.ShouldBe("$MQTT_qos2in");
|
||||
MqttProtocolConstants.QoS2IncomingMsgsStreamSubjectPrefix.ShouldBe("$MQTT.qos2.in.");
|
||||
|
||||
MqttProtocolConstants.OutStreamName.ShouldBe("$MQTT_out");
|
||||
MqttProtocolConstants.OutSubjectPrefix.ShouldBe("$MQTT.out.");
|
||||
MqttProtocolConstants.PubRelSubjectPrefix.ShouldBe("$MQTT.out.pubrel.");
|
||||
MqttProtocolConstants.PubRelDeliverySubjectPrefix.ShouldBe("$MQTT.deliver.pubrel.");
|
||||
MqttProtocolConstants.PubRelConsumerDurablePrefix.ShouldBe("$MQTT_PUBREL_");
|
||||
|
||||
MqttProtocolConstants.JSARepliesPrefix.ShouldBe("$MQTT.JSA.");
|
||||
MqttProtocolConstants.JSAIdTokenPos.ShouldBe(3);
|
||||
MqttProtocolConstants.JSATokenPos.ShouldBe(4);
|
||||
MqttProtocolConstants.JSAClientIDPos.ShouldBe(5);
|
||||
MqttProtocolConstants.JSAStreamCreate.ShouldBe("SC");
|
||||
MqttProtocolConstants.JSAStreamUpdate.ShouldBe("SU");
|
||||
MqttProtocolConstants.JSAStreamLookup.ShouldBe("SL");
|
||||
MqttProtocolConstants.JSAStreamDel.ShouldBe("SD");
|
||||
MqttProtocolConstants.JSAConsumerCreate.ShouldBe("CC");
|
||||
MqttProtocolConstants.JSAConsumerLookup.ShouldBe("CL");
|
||||
MqttProtocolConstants.JSAConsumerDel.ShouldBe("CD");
|
||||
MqttProtocolConstants.JSAMsgStore.ShouldBe("MS");
|
||||
MqttProtocolConstants.JSAMsgLoad.ShouldBe("ML");
|
||||
MqttProtocolConstants.JSAMsgDelete.ShouldBe("MD");
|
||||
MqttProtocolConstants.JSASessPersist.ShouldBe("SP");
|
||||
MqttProtocolConstants.JSARetainedMsgDel.ShouldBe("RD");
|
||||
MqttProtocolConstants.JSAStreamNames.ShouldBe("SN");
|
||||
|
||||
MqttProtocolConstants.SparkbNBirth.ShouldBe("NBIRTH");
|
||||
MqttProtocolConstants.SparkbDBirth.ShouldBe("DBIRTH");
|
||||
MqttProtocolConstants.SparkbNDeath.ShouldBe("NDEATH");
|
||||
MqttProtocolConstants.SparkbDDeath.ShouldBe("DDEATH");
|
||||
Encoding.ASCII.GetString(MqttProtocolConstants.SparkbNamespaceTopicPrefix).ShouldBe("spBv1.0/");
|
||||
Encoding.ASCII.GetString(MqttProtocolConstants.SparkbCertificatesTopicPrefix).ShouldBe("$sparkplug/certificates/");
|
||||
|
||||
MqttProtocolConstants.NatsHeaderPublish.ShouldBe("Nmqtt-Pub");
|
||||
MqttProtocolConstants.NatsRetainedMessageTopic.ShouldBe("Nmqtt-RTopic");
|
||||
MqttProtocolConstants.NatsRetainedMessageOrigin.ShouldBe("Nmqtt-ROrigin");
|
||||
MqttProtocolConstants.NatsRetainedMessageFlags.ShouldBe("Nmqtt-RFlags");
|
||||
MqttProtocolConstants.NatsRetainedMessageSource.ShouldBe("Nmqtt-RSource");
|
||||
MqttProtocolConstants.NatsPubRelHeader.ShouldBe("Nmqtt-PubRel");
|
||||
MqttProtocolConstants.NatsHeaderSubject.ShouldBe("Nmqtt-Subject");
|
||||
MqttProtocolConstants.NatsHeaderMapped.ShouldBe("Nmqtt-Mapped");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WriteString_writes_length_prefixed_utf8()
|
||||
{
|
||||
var encoded = MqttPacketWriter.WriteString("MQTT");
|
||||
|
||||
encoded.Length.ShouldBe(6);
|
||||
encoded[0].ShouldBe((byte)0x00);
|
||||
encoded[1].ShouldBe((byte)0x04);
|
||||
Encoding.UTF8.GetString(encoded.AsSpan(2)).ShouldBe("MQTT");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WriteBytes_writes_length_prefixed_binary_payload()
|
||||
{
|
||||
var encoded = MqttPacketWriter.WriteBytes(new byte[] { 0xAA, 0xBB, 0xCC });
|
||||
|
||||
encoded.ShouldBe(new byte[] { 0x00, 0x03, 0xAA, 0xBB, 0xCC });
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void WriteBytes_rejects_payload_larger_than_uint16()
|
||||
{
|
||||
var payload = new byte[ushort.MaxValue + 1];
|
||||
Should.Throw<ArgumentOutOfRangeException>(() => MqttPacketWriter.WriteBytes(payload));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user