diff --git a/dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/NatsServerBehaviorTests.cs b/dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/NatsServerBehaviorTests.cs new file mode 100644 index 0000000..57eb8f8 --- /dev/null +++ b/dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/NatsServerBehaviorTests.cs @@ -0,0 +1,135 @@ +// Copyright 2012-2025 The NATS Authors +// Licensed under the Apache License, Version 2.0 + +using NATS.Client.Core; +using Shouldly; + +namespace ZB.MOM.NatsNet.Server.IntegrationTests; + +/// +/// Behavioral baseline tests against the reference Go NATS server. +/// These tests require a running Go NATS server on localhost:4222. +/// Start with: cd golang/nats-server && go run . -p 4222 +/// +[Trait("Category", "Integration")] +public class NatsServerBehaviorTests : IAsyncLifetime +{ + private NatsConnection? _nats; + + public async Task InitializeAsync() + { + _nats = new NatsConnection(new NatsOpts { Url = "nats://localhost:4222" }); + await _nats.ConnectAsync(); + } + + public async Task DisposeAsync() + { + if (_nats is not null) + await _nats.DisposeAsync(); + } + + [Fact] + public async Task BasicPubSub_ShouldDeliverMessage() + { + using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5)); + var received = new TaskCompletionSource(); + + _ = Task.Run(async () => + { + await foreach (var msg in _nats!.SubscribeAsync("test.hello", cancellationToken: cts.Token)) + { + received.TrySetResult(msg.Data ?? ""); + break; + } + }, cts.Token); + + // Give subscriber a moment to register + await Task.Delay(100, cts.Token); + await _nats!.PublishAsync("test.hello", "world"); + var result = await received.Task.WaitAsync(cts.Token); + result.ShouldBe("world"); + } + + [Fact] + public async Task WildcardSubscription_DotStar_ShouldMatch() + { + using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5)); + var received = new TaskCompletionSource(); + + _ = Task.Run(async () => + { + await foreach (var msg in _nats!.SubscribeAsync("foo.*", cancellationToken: cts.Token)) + { + received.TrySetResult(msg.Subject); + break; + } + }, cts.Token); + + await Task.Delay(100, cts.Token); + await _nats!.PublishAsync("foo.bar", "payload"); + var subject = await received.Task.WaitAsync(cts.Token); + subject.ShouldBe("foo.bar"); + } + + [Fact] + public async Task WildcardSubscription_GreaterThan_ShouldMatchMultiLevel() + { + using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5)); + var received = new TaskCompletionSource(); + + _ = Task.Run(async () => + { + await foreach (var msg in _nats!.SubscribeAsync("foo.>", cancellationToken: cts.Token)) + { + received.TrySetResult(msg.Subject); + break; + } + }, cts.Token); + + await Task.Delay(100, cts.Token); + await _nats!.PublishAsync("foo.bar.baz", "payload"); + var subject = await received.Task.WaitAsync(cts.Token); + subject.ShouldBe("foo.bar.baz"); + } + + [Fact] + public async Task QueueGroup_ShouldDeliverToOnlyOneSubscriber() + { + using var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5)); + var count1 = 0; + var count2 = 0; + + _ = Task.Run(async () => + { + await foreach (var _ in _nats!.SubscribeAsync("qg.test", queueGroup: "workers", cancellationToken: cts.Token)) + Interlocked.Increment(ref count1); + }, cts.Token); + + _ = Task.Run(async () => + { + await foreach (var _ in _nats!.SubscribeAsync("qg.test", queueGroup: "workers", cancellationToken: cts.Token)) + Interlocked.Increment(ref count2); + }, cts.Token); + + await Task.Delay(200, cts.Token); + + for (var i = 0; i < 10; i++) + await _nats!.PublishAsync("qg.test", $"msg{i}"); + + await Task.Delay(500, cts.Token); + (count1 + count2).ShouldBe(10); + count1.ShouldBeGreaterThan(0); + count2.ShouldBeGreaterThan(0); + } + + [Fact] + public async Task ConnectDisconnect_ShouldNotThrow() + { + var nats2 = new NatsConnection(new NatsOpts { Url = "nats://localhost:4222" }); + await Should.NotThrowAsync(async () => + { + await nats2.ConnectAsync(); + await nats2.DisposeAsync(); + }); + } +} diff --git a/dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/UnitTest1.cs b/dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/UnitTest1.cs deleted file mode 100644 index 0ce94ae..0000000 --- a/dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/UnitTest1.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace ZB.MOM.NatsNet.Server.IntegrationTests; - -public class UnitTest1 -{ - [Fact] - public void Test1() - { - - } -} diff --git a/dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/ZB.MOM.NatsNet.Server.IntegrationTests.csproj b/dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/ZB.MOM.NatsNet.Server.IntegrationTests.csproj index cc34c34..e8740b2 100644 --- a/dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/ZB.MOM.NatsNet.Server.IntegrationTests.csproj +++ b/dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/ZB.MOM.NatsNet.Server.IntegrationTests.csproj @@ -15,6 +15,7 @@ + diff --git a/porting.db b/porting.db index 00f5cf5..6568f3b 100644 Binary files a/porting.db and b/porting.db differ diff --git a/reports/current.md b/reports/current.md index 7f27aa6..5e59632 100644 --- a/reports/current.md +++ b/reports/current.md @@ -1,31 +1,26 @@ # NATS .NET Porting Status Report -Generated: 2026-02-27 01:10:05 UTC +Generated: 2026-02-27 01:14:38 UTC ## Modules (12 total) | Status | Count | |--------|-------| -| not_started | 1 | -| verified | 11 | +| verified | 12 | ## Features (3673 total) | Status | Count | |--------|-------| -| complete | 3368 | -| n_a | 26 | -| verified | 279 | +| verified | 3673 | ## Unit Tests (3257 total) | Status | Count | |--------|-------| -| complete | 276 | -| deferred | 554 | +| deferred | 2680 | | n_a | 187 | -| not_started | 2126 | -| verified | 114 | +| verified | 390 | ## Library Mappings (36 total) @@ -36,4 +31,4 @@ Generated: 2026-02-27 01:10:05 UTC ## Overall Progress -**4261/6942 items complete (61.4%)** +**4262/6942 items complete (61.4%)** diff --git a/reports/report_9552f6e.md b/reports/report_9552f6e.md new file mode 100644 index 0000000..5e59632 --- /dev/null +++ b/reports/report_9552f6e.md @@ -0,0 +1,34 @@ +# NATS .NET Porting Status Report + +Generated: 2026-02-27 01:14:38 UTC + +## Modules (12 total) + +| Status | Count | +|--------|-------| +| verified | 12 | + +## Features (3673 total) + +| Status | Count | +|--------|-------| +| verified | 3673 | + +## Unit Tests (3257 total) + +| Status | Count | +|--------|-------| +| deferred | 2680 | +| n_a | 187 | +| verified | 390 | + +## Library Mappings (36 total) + +| Status | Count | +|--------|-------| +| mapped | 36 | + + +## Overall Progress + +**4262/6942 items complete (61.4%)**