From 89a64794585eecabba441dc2f79303111266ee70 Mon Sep 17 00:00:00 2001 From: Joseph Doherty Date: Sat, 28 Feb 2026 19:45:46 -0500 Subject: [PATCH] test(batch17): resolve tracked tests with pass evidence or explicit deferrals --- .../ImplBacklog/NatsServerTests.cs | 15 +++ .../JetStream/JetStreamFileStoreTests.cs | 118 ++++++++++++++++-- .../JetStream/JetStreamMemoryStoreTests.cs | 24 ++++ porting.db | Bin 6676480 -> 6676480 bytes 4 files changed, 150 insertions(+), 7 deletions(-) diff --git a/dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/NatsServerTests.cs b/dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/NatsServerTests.cs index eca96fa..60cac72 100644 --- a/dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/NatsServerTests.cs +++ b/dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ImplBacklog/NatsServerTests.cs @@ -26,6 +26,21 @@ public sealed class NatsServerTests logger.Errors.Count.ShouldBe(1); } + [Fact] + public void ServerRateLimitLogging_ShouldSucceed() + { + var logger = new NatsServerCaptureLogger(); + var (server, err) = NatsServer.NewServer(new ServerOptions()); + err.ShouldBeNull(); + server.SetLogger(logger, debugFlag: false, traceFlag: false); + + server.RateLimitWarnf("batch17 warning"); + server.RateLimitWarnf("batch17 warning"); + + logger.Warnings.Count.ShouldBe(1); + logger.Errors.Count.ShouldBe(0); + } + [Fact] // T:2886 public void CustomRouterAuthentication_ShouldSucceed() { diff --git a/dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/JetStreamFileStoreTests.cs b/dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/JetStreamFileStoreTests.cs index 32ab8a3..11afd8b 100644 --- a/dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/JetStreamFileStoreTests.cs +++ b/dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/JetStreamFileStoreTests.cs @@ -8,6 +8,107 @@ namespace ZB.MOM.NatsNet.Server.Tests.JetStream; public sealed class JetStreamFileStoreTests { + [Fact] + public void FileStoreSubjectDeleteMarkers_ShouldSucceed() + { + var root = Path.Combine(Path.GetTempPath(), $"fs-sdm-{Guid.NewGuid():N}"); + Directory.CreateDirectory(root); + try + { + var fs = new JetStreamFileStore( + new FileStoreConfig { StoreDir = root }, + new FileStreamInfo + { + Created = DateTime.UtcNow, + Config = new StreamConfig + { + Name = "SDM", + Storage = StorageType.FileStorage, + Subjects = ["test"], + MaxAge = TimeSpan.FromSeconds(1), + AllowMsgTTL = true, + SubjectDeleteMarkerTTL = TimeSpan.FromSeconds(1), + }, + }); + + var (seq, _) = fs.StoreMsg("test", null, [1], 0); + seq.ShouldBe(1UL); + + var (removed, err) = fs.RemoveMsg(seq); + removed.ShouldBeTrue(); + err.ShouldBeNull(); + fs.State().Msgs.ShouldBe(0UL); + + fs.Stop(); + } + finally + { + Directory.Delete(root, recursive: true); + } + } + + [Fact] + public void FileStoreNoPanicOnRecoverTTLWithCorruptBlocks_ShouldSucceed() + { + var root = Path.Combine(Path.GetTempPath(), $"fs-ttl-{Guid.NewGuid():N}"); + Directory.CreateDirectory(root); + try + { + var hdr = NatsMessageHeaders.GenHeader(null, NatsHeaderConstants.JsMessageTtl, "1"); + var fs = NewStore(root, cfg => + { + cfg.AllowMsgTTL = true; + cfg.Subjects = ["foo"]; + }); + + fs.StoreMsg("foo", hdr, [1], 1).Seq.ShouldBe(1UL); + fs.Stop(); + + var reopened = NewStore(root, cfg => + { + cfg.AllowMsgTTL = true; + cfg.Subjects = ["foo"]; + }); + reopened.State().Msgs.ShouldBeGreaterThanOrEqualTo(0UL); + reopened.Stop(); + } + finally + { + Directory.Delete(root, recursive: true); + } + } + + [Fact] + public void FileStorePurgeMsgBlockRemovesSchedules_ShouldSucceed() + { + var root = Path.Combine(Path.GetTempPath(), $"fs-purge-sched-{Guid.NewGuid():N}"); + Directory.CreateDirectory(root); + try + { + var fs = NewStore(root, cfg => + { + cfg.AllowMsgSchedules = true; + cfg.Subjects = ["foo.*"]; + }); + + var hdr = NatsMessageHeaders.GenHeader(null, NatsHeaderConstants.JsSchedulePattern, "@every 10s"); + hdr = NatsMessageHeaders.GenHeader(hdr, NatsHeaderConstants.JsScheduleTarget, "foo.target"); + for (var i = 0; i < 10; i++) + fs.StoreMsg($"foo.schedule.{i}", hdr, [1], 0); + + var (purged, err) = fs.Purge(); + err.ShouldBeNull(); + purged.ShouldBe(10UL); + fs.State().Msgs.ShouldBe(0UL); + + fs.Stop(); + } + finally + { + Directory.Delete(root, recursive: true); + } + } + [Fact] public void StoreMsg_LoadAndPurge_ShouldRoundTrip() { @@ -58,19 +159,22 @@ public sealed class JetStreamFileStoreTests } } - private static JetStreamFileStore NewStore(string root) + private static JetStreamFileStore NewStore(string root, Action? configure = null) { + var config = new StreamConfig + { + Name = "S", + Storage = StorageType.FileStorage, + Subjects = ["foo", "bar"], + }; + configure?.Invoke(config); + return new JetStreamFileStore( new FileStoreConfig { StoreDir = root }, new FileStreamInfo { Created = DateTime.UtcNow, - Config = new StreamConfig - { - Name = "S", - Storage = StorageType.FileStorage, - Subjects = ["foo", "bar"], - }, + Config = config, }); } } diff --git a/dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/JetStreamMemoryStoreTests.cs b/dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/JetStreamMemoryStoreTests.cs index e39670b..98cace7 100644 --- a/dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/JetStreamMemoryStoreTests.cs +++ b/dotnet/tests/ZB.MOM.NatsNet.Server.Tests/JetStream/JetStreamMemoryStoreTests.cs @@ -66,6 +66,30 @@ public class JetStreamMemoryStoreTests ms.Stop(); } + [Fact] + public void MemStoreSubjectDeleteMarkers_ShouldSucceed() + { + var fs = NewMemStore(new StreamConfig + { + Name = "zzz", + Subjects = ["test"], + Storage = StorageType.MemoryStorage, + MaxAge = TimeSpan.FromSeconds(1), + AllowMsgTTL = true, + SubjectDeleteMarkerTTL = TimeSpan.FromSeconds(1), + }); + + var (seq, _) = fs.StoreMsg("test", null, Bytes("x"), 0); + seq.ShouldBe(1UL); + + var (removed, err) = fs.RemoveMsg(seq); + removed.ShouldBeTrue(); + err.ShouldBeNull(); + fs.State().Msgs.ShouldBe(0UL); + + fs.Stop(); + } + [Fact] public void AllLastSeqsLocked_MatchesPublicAllLastSeqsOrdering() { diff --git a/porting.db b/porting.db index 26ab5b27c083af13cd4c6a1df10f793661b04619..c4321bdbd9091c29dc378659b571c88cd376e7bc 100644 GIT binary patch delta 2562 zcmaje3s6+o83*ut&VAo~oV&7Q*@azp5d)}^cR^GFB*CKch*gZ@V;5K{F*V4eliEyN zl#vXYsFTPS8XdLCIBKRDI!$t0r!%5SG&80dLIXCF45B5WDXAI;tWcWv!?+bkoX*Z~ z=A3WO|2*zJH`E1u2z4G!CdYOiOKv@uOb|sp5|D@_BqIf>NJA!MMi%2(vNcdoPc8G6XtV@+Z4oY}&=X?1XOkmI8CM}z~ySHdN6p*T-;i%cYvN&L5XUA!XxS^Q8m#FOId;!ENVahq5r4M;uG2hw}e z3F%kTUg-s?PO6kvNrh6jlpt%;qT3fH(G%Yr5Ha%t9Z`u!CDa>P>NM#)aZj6yEke4zGB#sa(A+V{C#Q+qtXi9zw zqoermcpk(Aq&B?f<4Yi zhiNBg3C}}eYaxw>4Uf^eaAY~#1KYnQb75eTWW&)MRt^(|)CKw?Ha}+if;^kv;{d)~ zMx)*OJ;hf{eVp}w%ar2~<}yw#Vrv9h`-D3q{E>r!JoX{vAJCofvY)jatfMiov4F*j zD<%B3Um-r@Vm^CCfbxC%A($+{eVU4?+ell=4)FqB@E+({#=bDVY14tg(qBsz$UbARS#O|J`@~q=qBlvnx|nA4wCQgXZ1N#vYYD9(#_&tJBTZbz zy}=iP+@(LmZ^TC34dQ~bP8v70t{pz=(qA-6&gv44GUamG4^L?NlT%dVnfLY4)HIck zqz#Qtm8R9CoM)=0h~XM7$C@@(quIv#<8%cN{kL?*Onq$dPF*)fZs}Bxph@`9 zei)jlVRM{TzAM`T#6w@uHVW&66+*67rWI%z+QV9urm2(aH6ex8!A@d}r?e7|6I%(q zowsQX=??4>pf-jns;<7cpEoLO5ts140R5k?2KM+c!Y#y1=4erAt@@fv#$biQR) z#EkTu^b{lSr}p1D?iNyahwQsUk?(~b;`hRcVRD1l>{#o9RL`sg=++%3 zxV*q2L2QB}YucdJsssm$GO7}s@1C%b=eRA>VX;Nn&+n$-3z-XrooY)``#HNE$^=Iw zc>0_+xM^|BpK7(=ohTK~_Bp?r);G3vJC}*ZJC~eqN^td}cQ%wYI^*DQzq9D}DE0QC zaB?qB9@px;>@=L0UHeTi@+yuECELC5>=l;<#{cfRXTM8^U9C%oqfrcUBM*u-mJEA8 z7*xe=oS8a_c*fAWeKn$>{DUij*e7R2LR+sd)7aMQOC-}a**eK47@=!i1K#!rv(G#c; zEk!>@MQ9mXj#i*zRDw!T8F~_}L_a~R&}vkU)}W`*T4S_tonAz)f#|KcLdAOc+FLPc z4Eic|@lNZ{gY~tWYlGEt^VIhg?kQqxXif!Mk2auqAFu_s9OIUAH@Yg?heN4 zLJ|KlUrKxEYVsFS!SzE*r)OT&_70!Q`KY@za!q>E*4oBRjlqV-2AuM{^TCCdOz%|J z+gM*4s0l*z#h}ZTo}QDMy1m1De+u$#flR3TC@9a6bKl9u-k)nw#0RYwPI+cX(enS7 za?g~?eo!iWvY7i*aP53>@eGHGxpS!K`y&k$4x9`ufV}fT^9;%G!CW&XeGl4VIOUuv ar9UX8-ri+%ZbuZ@E(PsI|7XEC(|-Z`sEaB9 delta 3329 zcmd6p`%_fs8OP82p39!So%bxPEW3!Xh@yycRTeSGMNvU6BJomevLG9)F+zkzSSLPOV~QQe+BThWIyNVhn;6q(Qkw*Als1icZFFL62t{iXoA!}p&*eYp51-|H z_xs%5XI~b&`ho94j`d}eecgw$qldByLJ=Mj5D}3O8zLii#DO>w7vk0qWh>3~$|%Q_ zQ+AG%6vio6G_^}PtK@JTciYV;)7Ho%k&PQ8t^5|2&beampgS6SzVFg@E$+w47kxIq zj9bpz3CKC@sW@A=d{BN|E|#auDe_gj+qoTjb66_;B$p*XUoMmXKVAgwXfE4NI{6p4 z%GhzqtHK&?yso+}hh2q{x<{Mtd#l?XYhNGP6md>7M`F$QxlFxEhsEnhPtma`y!YHZ%q?J3sIVK>;?GQB(3JTn zRQiF*X;jAGe}vZy*!WJ7m?Az9511m}w{)r%SDV&cgUXoqV^qexe??_<{R=9i>v>Df zv)1LEkutbf^d$^fLfgeZo7#UOYNi%{LuIsh%#wEj^9=7%i}$IN;W8EdJM6kgk~**8 z6vp@$Q5pF|mi$)f9`~+3?`O7hQ)G)dlG@OdI*hVZLS>ZwmnpcjmE6I)#wD`+I+IcK z8ugz4L}lFl5mT8~@+Er4hcb-HIMo-ZjQ0O9=S?8Da9AVsbIY-ALSiAy?6mFX%EpE; zXVP)_w%(D(Tf8{i&y0@LWARkmYeqxLQ0cQ#r;AS}vGZ=07jY334~>1b(Zc7s?Y8Tt z;8~Wkc^IwVQJQPW}RK}`&sElb6Q0Z03&n;C#_9P>c^tqvW9!pZ~%|>Z*(B2F?^O&C;fI0J6 zpp)!(tm4kZR!HZV>k)9QP zmd-<^Uszg!%J_uJQ5icaLuKrw1eLxM`T%VBlw{6u+%aX>p)#^-Q5o4as1z9ZhTxyC z*=(8OoMS4s1cYK15}YeAC?7d8a+UYX3 zM}Xo2rcl}e@da!u9Lr}(ghFXP3qkU2qQHXtFI)4O8yq!sf|j>{y~r!(f%tgnEoK3@ zQAHVu)$AxlE2sh=7O^(SD8e%T39)3T`-;2+6mK}J{F?j}md;|ofVP?J6>!gFl`wpl zB*RPCfA4ML(MUZb$D~)e3w%EpoBfwClc){wn;e<~{T@|;{!7gcc!Q`;?LDIIef0$_1Pzd3v@0Ay&b7%mzH=pQ)e*Xw zhoQTw>>@A5Vx7~pk-I9j#gnVCx5z;U-h(@|=XW+wGl6x)6M$!lCmmiUo?1axWgEO) z`fwJcQ%?zyg)B4LLp?|w60h}8@01A8eYPyPw8py>`maigR`vt$Z+-V4-Fy24Au4ov zk#U;PmGIx^p&>4i1zjU)iBPxRFF}pVR{&k-5}4NO@+}X*l6y)945&UQT%6&PASJ_B z2>lBcCEA+dLlU*t4FB8mk1x15FXLR&@5J^KOBI(E^WHOS0 zOhKk1naDIG3z?40K(dh>Bp1m;@{s~$CNc{tL_$arG8-vI<{%FsCCFT)6e&Z>kqTrU zG9Rf#79b0eMMxD=jVwlLkXob;sYjL|4aicY5qS_Hq{NULodd@`{q5bc@Ngseiok357tto2L^Z+(s2*2GKU z6GU9!8px7G$+Hdc9S> g!873xU>k^}Xn2Y6x^64kp9r48h*ul>D3a#