diff --git a/docs/plans/2026-03-12-test-project-split-design.md b/docs/plans/2026-03-12-test-project-split-design.md new file mode 100644 index 0000000..1da6cca --- /dev/null +++ b/docs/plans/2026-03-12-test-project-split-design.md @@ -0,0 +1,222 @@ +# 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 definitions +- `LeafFixture` — consolidated from 3 duplicate definitions + +### Parity utilities (non-test) +- `NatsCapabilityInventory.cs` +- `ParityRowInspector.cs` +- `JetStreamParityTruthMatrix.cs` + +### TestData +- `TestData/*.conf` files (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: + +```xml + + + false + + + + + + + + + + + + + + + + + + + + + +``` + +**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: + +```xml + + + false + + + + + + + + + + + + + + + + +``` + +## Migration Strategy + +### Phase 1: Create TestUtilities +- Create `NATS.Server.TestUtilities` project +- Extract `GetFreePort()`, `ReadUntilAsync()` into shared helper classes +- Move `JetStreamApiFixture`, consolidated `JetStreamClusterFixture`, consolidated `LeafFixture` +- Move parity utility files (non-test) and TestData +- Update the original `NATS.Server.Tests` to reference TestUtilities +- Verify build + all tests pass + +### Phase 2: Split projects one at a time (smallest first) +1. Transport.Tests (~25 files) +2. Mqtt.Tests (~30 files) +3. Gateways.Tests (~25 files) +4. LeafNodes.Tests (~30 files) +5. Clustering.Tests (~30 files) +6. Raft.Tests (~45 files) +7. Monitoring.Tests (~35 files) +8. Auth.Tests (~50 files) +9. JetStream.Tests (~220 files) +10. Core.Tests (rename remaining original project) + +Each step: +- Create the new `.csproj` +- Move files with `git mv` to 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.Tests` project (now empty) +- Verify `dotnet test` from 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)