using NATS.Server; using Shouldly; namespace NATS.Server.Core.Tests; /// /// Tests for per-client trace delivery and echo control. /// Go reference: server/client.go — c.trace, c.echo fields and TraceMsgDelivery / deliverMsg logic. /// public class ClientTraceTests { // 1. TraceEnabled defaults to false [Fact] public void TraceEnabled_defaults_to_false() { var info = new ClientTraceInfo(); info.TraceEnabled.ShouldBeFalse(); } // 2. EchoEnabled defaults to true [Fact] public void EchoEnabled_defaults_to_true() { var info = new ClientTraceInfo(); info.EchoEnabled.ShouldBeTrue(); } // 3. TraceMsgDelivery records when enabled [Fact] public void TraceMsgDelivery_records_when_enabled() { var info = new ClientTraceInfo(); info.TraceEnabled = true; info.TraceMsgDelivery("foo.bar", "client-1", 42); info.TraceLogCount.ShouldBe(1); } // 4. TraceMsgDelivery skips when disabled [Fact] public void TraceMsgDelivery_skips_when_disabled() { var info = new ClientTraceInfo(); // TraceEnabled is false by default info.TraceMsgDelivery("foo.bar", "client-1", 42); info.TraceLogCount.ShouldBe(0); } // 5. TraceMsgDelivery captures subject, destination and payload size correctly [Fact] public void TraceMsgDelivery_captures_subject_destination_size() { var info = new ClientTraceInfo(); info.TraceEnabled = true; var before = DateTime.UtcNow; info.TraceMsgDelivery("orders.new", "client-42", 128); var records = info.DrainTraceLog(); records.Count.ShouldBe(1); var rec = records[0]; rec.Subject.ShouldBe("orders.new"); rec.Destination.ShouldBe("client-42"); rec.PayloadSize.ShouldBe(128); rec.TimestampUtc.ShouldBeGreaterThanOrEqualTo(before); rec.TimestampUtc.ShouldBeLessThanOrEqualTo(DateTime.UtcNow); } // 6. ShouldEcho returns true when echo is enabled (same client) [Fact] public void ShouldEcho_true_when_echo_enabled() { var info = new ClientTraceInfo(); info.EchoEnabled = true; info.ShouldEcho("client-1", "client-1").ShouldBeTrue(); } // 7. ShouldEcho returns false when echo is disabled and same client [Fact] public void ShouldEcho_false_when_echo_disabled_same_client() { var info = new ClientTraceInfo(); info.EchoEnabled = false; info.ShouldEcho("client-1", "client-1").ShouldBeFalse(); } // 8. ShouldEcho returns true when echo is disabled but different client [Fact] public void ShouldEcho_true_when_echo_disabled_different_client() { var info = new ClientTraceInfo(); info.EchoEnabled = false; info.ShouldEcho("client-1", "client-2").ShouldBeTrue(); } // 9. DrainTraceLog returns records and clears the log [Fact] public void DrainTraceLog_returns_and_clears() { var info = new ClientTraceInfo(); info.TraceEnabled = true; info.TraceMsgDelivery("a", "dest-a", 10); info.TraceMsgDelivery("b", "dest-b", 20); var drained = info.DrainTraceLog(); drained.Count.ShouldBe(2); info.TraceLogCount.ShouldBe(0); } // 10. TraceLogCount reflects current entries before and after drain [Fact] public void TraceLogCount_reflects_current_entries() { var info = new ClientTraceInfo(); info.TraceEnabled = true; info.TraceLogCount.ShouldBe(0); info.TraceMsgDelivery("x", "dest-x", 5); info.TraceMsgDelivery("y", "dest-y", 15); info.TraceMsgDelivery("z", "dest-z", 25); info.TraceLogCount.ShouldBe(3); info.DrainTraceLog(); info.TraceLogCount.ShouldBe(0); } }