Splits the 609-file monolithic test project into 10 subsystem test projects plus a shared TestUtilities library for developer ergonomics.
9.2 KiB
Test Project Split Design
Date: 2026-03-12
Goal: Split NATS.Server.Tests (609 files) into feature-focused test projects for developer ergonomics — easier to run just the tests for the subsystem you're working on.
Project Structure
tests/
NATS.Server.TestUtilities/ # Shared helpers, fixtures, parity tools (class library)
NATS.Server.Core.Tests/ # Client, server, parser, config, subscriptions, protocol
NATS.Server.Auth.Tests/ # Auth, accounts, permissions, JWT, NKeys
NATS.Server.JetStream.Tests/ # JetStream API, streams, consumers, storage, cluster
NATS.Server.Raft.Tests/ # RAFT consensus
NATS.Server.Clustering.Tests/ # Routes, cluster topology, inter-server protocol
NATS.Server.Gateways.Tests/ # Gateway connections, interest modes
NATS.Server.LeafNodes.Tests/ # Leaf node connections, hub-spoke
NATS.Server.Mqtt.Tests/ # MQTT protocol bridge
NATS.Server.Monitoring.Tests/ # Monitor endpoints, events, system events
NATS.Server.Transport.Tests/ # WebSocket, TLS, OCSP, IO
NATS.E2E.Tests/ # (existing, unchanged)
TestUtilities Contents
NATS.Server.TestUtilities is a class library (not a test project).
Shared helpers (deduplicated)
TestPortAllocator—GetFreePort()(currently duplicated in ~51 files)SocketTestHelper—ReadUntilAsync(), raw socket connect/read patterns (~25 files)ServerTestHelper— common server startup/teardown patterns
Shared fixtures
JetStreamApiFixture— moved from root (used by 52 JetStream test files)JetStreamClusterFixture— consolidated from 2 duplicate definitionsLeafFixture— consolidated from 3 duplicate definitions
Parity utilities (non-test)
NatsCapabilityInventory.csParityRowInspector.csJetStreamParityTruthMatrix.cs
TestData
TestData/*.conffiles (copied to output directory)
File-to-Project Mapping
NATS.Server.Core.Tests (~75 files)
Root-level: ClientClosedReasonTests, ClientFlagsTests, ClientHeaderTests, ClientKindCommandMatrixTests, ClientKindProtocolRoutingTests, ClientKindTests, ClientLifecycleTests, ClientProtocolParityTests, ClientPubSubTests, ClientServerGoParityTests, ClientSlowConsumerTests, ClientTests, ClientTraceModeTests, ClientTraceTests, ClientUnsubTests, ConfigIntegrationTests, ConfigProcessorTests, ConfigReloadTests, ConfigRuntimeParityTests, FlushCoalescingTests, IntegrationTests, InternalClientTests, LoggingTests, MessageTraceTests, MsgTraceGoParityTests, NatsConfLexerTests, NatsConfParserTests, NatsHeaderParserTests, NatsOptionsTests, NoRespondersTests, ParserTests, ResponseRoutingTests, ResponseTrackerTests, RttTests, ServerConfigTests, ServerStatsTests, ServerTests, SignalHandlerTests, SlopwatchSuppressAttribute, SlowConsumerStallGateTests, StallGateTests, SubjectMatchTests, SubjectTransformIntegrationTests, SubjectTransformTests, SubListTests, VerboseModeTests, WriteLoopTests, WriteTimeoutTests, ConcurrencyStressTests
Subfolders: Configuration/ (14), Internal/ (8), IO/ (4), Protocol/ (7), Server/ (7), SubList/ (6), Subscriptions/ (6), Stress/ (3)
Parity test files (from Parity/ folder): NatsStrictCapabilityInventoryTests, JetStreamParityTruthMatrixTests, GoParityRunnerTests, InfrastructureGoParityTests, DifferencesParityClosureTests
NATS.Server.Auth.Tests (~50 files)
Root-level: AccountIsolationTests, AccountResolverTests, AccountStatsTests, AccountTests, AuthConfigTests, AuthIntegrationTests, AuthProtocolTests, AuthServiceTests, ClientPermissionsTests, JwtAuthenticatorTests, JwtTests, NKeyAuthenticatorTests, NKeyIntegrationTests, PermissionIntegrationTests, PermissionLruCacheTests, PermissionTemplateTests, SimpleUserPasswordAuthenticatorTests, TokenAuthenticatorTests, UserPasswordAuthenticatorTests, ImportExportTests
Subfolders: Auth/ (25), Accounts/ (5)
NATS.Server.JetStream.Tests (~220 files)
Root-level:
All JetStream* files at root (~55), plus FileStoreTests, FileStoreEncryptionTests, MemStoreTests, StreamStoreContractTests, MirrorSourceRetryTests, ClusterJetStreamConfigProcessorTests
Subfolders: JetStream/ and all sub-folders (163 files)
NATS.Server.Raft.Tests (~45 files)
Root-level: RaftConsensusAdvancedParityTests, RaftElectionTests, RaftMembershipParityTests, RaftReplicationTests, RaftSafetyContractTests, RaftSnapshotCatchupTests, RaftSnapshotTransferParityTests, RaftTransportPersistenceTests
Subfolders: Raft/ (36)
NATS.Server.Clustering.Tests (~30 files)
Root-level: RouteHandshakeTests, RoutePoolTests, RouteRmsgForwardingTests, RouteSubscriptionPropagationTests, RouteWireSubscriptionProtocolTests, ImplicitDiscoveryTests, InterServerAccountProtocolTests
Subfolders: Routes/ (21), Route/ (1)
NATS.Server.Gateways.Tests (~25 files)
Root-level: GatewayAdvancedRemapRuntimeTests, GatewayAdvancedSemanticsTests, GatewayLeafBootstrapTests, GatewayProtocolTests
Subfolders: Gateways/ (21)
NATS.Server.LeafNodes.Tests (~30 files)
Root-level: LeafAdvancedSemanticsTests, LeafProtocolTests
Subfolders: LeafNodes/ (26), LeafNode/ (1)
NATS.Server.Mqtt.Tests (~30 files)
Root-level: MqttPersistenceTests
Subfolders: Mqtt/ (28)
NATS.Server.Monitoring.Tests (~35 files)
Root-level: EventSystemTests, JszMonitorTests, MonitorClusterEndpointTests, MonitorModelTests, MonitorTests, SubszTests, SystemEventsTests, SystemRequestReplyTests
Subfolders: Monitoring/ (21), Events/ (10)
NATS.Server.Transport.Tests (~25 files)
Root-level: OcspConfigTests, OcspStaplingTests, TlsConnectionWrapperTests, TlsHelperTests, TlsMapAuthenticatorTests, TlsOcspParityBatch1Tests, TlsOcspParityBatch2Tests, TlsRateLimiterTests, TlsServerTests
Subfolders: WebSocket/ (15), Networking/ (1)
Project File Template
Each test project follows the same base pattern:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" />
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="NSubstitute" />
<PackageReference Include="Shouldly" />
<PackageReference Include="xunit" />
<PackageReference Include="xunit.runner.visualstudio" />
</ItemGroup>
<ItemGroup>
<Using Include="Xunit" />
<Using Include="Shouldly" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\NATS.Server\NATS.Server.csproj" />
<ProjectReference Include="..\NATS.Server.TestUtilities\NATS.Server.TestUtilities.csproj" />
</ItemGroup>
</Project>
Project-specific package additions:
| Project | Extra packages |
|---|---|
| Auth.Tests | NATS.NKeys |
| JetStream.Tests | NATS.Client.Core, JETSTREAM_INTEGRATION_MATRIX define constant |
| Transport.Tests | Serilog.Sinks.File (if TLS tests use it) |
| Core.Tests | NATS.Client.Core, Serilog.Sinks.File |
| Monitoring.Tests | NATS.Client.Core |
TestUtilities is a plain class library:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="NATS.Client.Core" />
<PackageReference Include="Shouldly" />
<PackageReference Include="xunit" /> <!-- for IAsyncLifetime fixtures -->
</ItemGroup>
<ItemGroup>
<None Update="TestData\**\*" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\NATS.Server\NATS.Server.csproj" />
</ItemGroup>
</Project>
Migration Strategy
Phase 1: Create TestUtilities
- Create
NATS.Server.TestUtilitiesproject - Extract
GetFreePort(),ReadUntilAsync()into shared helper classes - Move
JetStreamApiFixture, consolidatedJetStreamClusterFixture, consolidatedLeafFixture - Move parity utility files (non-test) and TestData
- Update the original
NATS.Server.Teststo reference TestUtilities - Verify build + all tests pass
Phase 2: Split projects one at a time (smallest first)
- Transport.Tests (~25 files)
- Mqtt.Tests (~30 files)
- Gateways.Tests (~25 files)
- LeafNodes.Tests (~30 files)
- Clustering.Tests (~30 files)
- Raft.Tests (~45 files)
- Monitoring.Tests (~35 files)
- Auth.Tests (~50 files)
- JetStream.Tests (~220 files)
- Core.Tests (rename remaining original project)
Each step:
- Create the new
.csproj - Move files with
git mvto preserve history - Update namespaces to match new project name
- Add to solution file
- Remove files from old project
- Build + test
Phase 3: Cleanup
- Delete the original
NATS.Server.Testsproject (now empty) - Verify
dotnet testfrom solution root runs all projects - Verify CI still works
Decisions
- Namespaces updated to match new project names (e.g.,
NATS.Server.Auth.Tests) - Root-level files sorted into matching subsystem projects by prefix/topic
- Storage files (FileStore, MemStore, StreamStore) → JetStream project
- ImportExportTests → Auth project
- InternalClientTests → Core project
- Parity test files → Core.Tests; parity utility classes → TestUtilities
- Stress test files → Core.Tests (only 3-4 files, not worth a separate project)
- Trace files → Core.Tests (tracing is a core feature)