docs: add implementation plan for test project split
13 tasks: create TestUtilities, extract 9 subsystem test projects, rename remainder to Core.Tests, final verification.
This commit is contained in:
616
docs/plans/2026-03-12-test-project-split-plan.md
Normal file
616
docs/plans/2026-03-12-test-project-split-plan.md
Normal file
@@ -0,0 +1,616 @@
|
|||||||
|
# Test Project Split Implementation Plan
|
||||||
|
|
||||||
|
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers-extended-cc:executing-plans to implement this plan task-by-task.
|
||||||
|
|
||||||
|
**Goal:** Split the monolithic `NATS.Server.Tests` (609 files) into 10 feature-focused test projects + 1 shared test utilities library.
|
||||||
|
|
||||||
|
**Architecture:** Create `NATS.Server.TestUtilities` as a class library with deduplicated helpers and shared fixtures. Then extract test files into subsystem-specific test projects one at a time, smallest first. Each extraction creates a new `.csproj`, moves files with `git mv`, updates namespaces, adds to the solution, and verifies build+test before proceeding to the next.
|
||||||
|
|
||||||
|
**Tech Stack:** .NET 10, xUnit 3, Shouldly, NSubstitute, Central Package Management
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 0: Create NATS.Server.TestUtilities project
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Create: `tests/NATS.Server.TestUtilities/NATS.Server.TestUtilities.csproj`
|
||||||
|
- Create: `tests/NATS.Server.TestUtilities/TestPortAllocator.cs`
|
||||||
|
- Create: `tests/NATS.Server.TestUtilities/SocketTestHelper.cs`
|
||||||
|
- Modify: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj` (add ProjectReference)
|
||||||
|
- Modify: `NatsDotNet.slnx` (add project)
|
||||||
|
|
||||||
|
**Step 1: Create the TestUtilities csproj**
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<!-- tests/NATS.Server.TestUtilities/NATS.Server.TestUtilities.csproj -->
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="NATS.Client.Core" />
|
||||||
|
<PackageReference Include="NATS.NKeys" />
|
||||||
|
<PackageReference Include="Shouldly" />
|
||||||
|
<PackageReference Include="xunit" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Update="TestData\**\*" CopyToOutputDirectory="PreserveNewest" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\src\NATS.Server\NATS.Server.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2: Create TestPortAllocator.cs**
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// tests/NATS.Server.TestUtilities/TestPortAllocator.cs
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
|
||||||
|
namespace NATS.Server.TestUtilities;
|
||||||
|
|
||||||
|
public static class TestPortAllocator
|
||||||
|
{
|
||||||
|
public static int GetFreePort()
|
||||||
|
{
|
||||||
|
using var sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
|
||||||
|
sock.Bind(new IPEndPoint(IPAddress.Loopback, 0));
|
||||||
|
return ((IPEndPoint)sock.LocalEndPoint!).Port;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 3: Create SocketTestHelper.cs**
|
||||||
|
|
||||||
|
```csharp
|
||||||
|
// tests/NATS.Server.TestUtilities/SocketTestHelper.cs
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace NATS.Server.TestUtilities;
|
||||||
|
|
||||||
|
public static class SocketTestHelper
|
||||||
|
{
|
||||||
|
public static async Task<string> ReadUntilAsync(Socket sock, string expected, int timeoutMs = 5000)
|
||||||
|
{
|
||||||
|
using var cts = new CancellationTokenSource(timeoutMs);
|
||||||
|
var sb = new StringBuilder();
|
||||||
|
var buf = new byte[4096];
|
||||||
|
while (!sb.ToString().Contains(expected, StringComparison.Ordinal))
|
||||||
|
{
|
||||||
|
var n = await sock.ReceiveAsync(buf, SocketFlags.None, cts.Token);
|
||||||
|
if (n == 0) break;
|
||||||
|
sb.Append(Encoding.ASCII.GetString(buf, 0, n));
|
||||||
|
}
|
||||||
|
return sb.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 4: Add ProjectReference to existing NATS.Server.Tests**
|
||||||
|
|
||||||
|
Add to `tests/NATS.Server.Tests/NATS.Server.Tests.csproj` inside the `<ItemGroup>` with `ProjectReference`:
|
||||||
|
```xml
|
||||||
|
<ProjectReference Include="..\NATS.Server.TestUtilities\NATS.Server.TestUtilities.csproj" />
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 5: Add TestUtilities to solution file**
|
||||||
|
|
||||||
|
In `NatsDotNet.slnx`, inside `<Folder Name="/tests/">` add:
|
||||||
|
```xml
|
||||||
|
<Project Path="tests/NATS.Server.TestUtilities/NATS.Server.TestUtilities.csproj" />
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 6: Build to verify**
|
||||||
|
|
||||||
|
Run: `dotnet build`
|
||||||
|
Expected: SUCCESS — TestUtilities compiles, NATS.Server.Tests still compiles.
|
||||||
|
|
||||||
|
**Step 7: Commit**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add tests/NATS.Server.TestUtilities/ NatsDotNet.slnx tests/NATS.Server.Tests/NATS.Server.Tests.csproj
|
||||||
|
git commit -m "feat: create NATS.Server.TestUtilities with shared helpers"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 1: Move shared fixtures and parity utilities to TestUtilities
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Move: `tests/NATS.Server.Tests/JetStreamApiFixture.cs` → `tests/NATS.Server.TestUtilities/JetStreamApiFixture.cs`
|
||||||
|
- Move: `tests/NATS.Server.Tests/JetStream/Cluster/JetStreamClusterFixture.cs` → `tests/NATS.Server.TestUtilities/JetStreamClusterFixture.cs`
|
||||||
|
- Move: `tests/NATS.Server.Tests/LeafNodes/LeafFixture.cs` → `tests/NATS.Server.TestUtilities/LeafFixture.cs`
|
||||||
|
- Move: `tests/NATS.Server.Tests/Parity/NatsCapabilityInventory.cs` → `tests/NATS.Server.TestUtilities/Parity/NatsCapabilityInventory.cs`
|
||||||
|
- Move: `tests/NATS.Server.Tests/Parity/ParityRowInspector.cs` → `tests/NATS.Server.TestUtilities/Parity/ParityRowInspector.cs`
|
||||||
|
- Move: `tests/NATS.Server.Tests/Parity/JetStreamParityTruthMatrix.cs` → `tests/NATS.Server.TestUtilities/Parity/JetStreamParityTruthMatrix.cs`
|
||||||
|
- Move: `tests/NATS.Server.Tests/TestData/*` → `tests/NATS.Server.TestUtilities/TestData/*`
|
||||||
|
|
||||||
|
**Step 1: Move files with git mv**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd tests
|
||||||
|
git mv NATS.Server.Tests/JetStreamApiFixture.cs NATS.Server.TestUtilities/
|
||||||
|
git mv NATS.Server.Tests/JetStream/Cluster/JetStreamClusterFixture.cs NATS.Server.TestUtilities/
|
||||||
|
git mv NATS.Server.Tests/LeafNodes/LeafFixture.cs NATS.Server.TestUtilities/
|
||||||
|
mkdir -p NATS.Server.TestUtilities/Parity
|
||||||
|
git mv NATS.Server.Tests/Parity/NatsCapabilityInventory.cs NATS.Server.TestUtilities/Parity/
|
||||||
|
git mv NATS.Server.Tests/Parity/ParityRowInspector.cs NATS.Server.TestUtilities/Parity/
|
||||||
|
git mv NATS.Server.Tests/Parity/JetStreamParityTruthMatrix.cs NATS.Server.TestUtilities/Parity/
|
||||||
|
mkdir -p NATS.Server.TestUtilities/TestData
|
||||||
|
git mv NATS.Server.Tests/TestData/* NATS.Server.TestUtilities/TestData/
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2: Update namespaces in moved files**
|
||||||
|
|
||||||
|
Change `namespace NATS.Server.Tests;` → `namespace NATS.Server.TestUtilities;` in each moved file.
|
||||||
|
For parity files: `namespace NATS.Server.TestUtilities.Parity;`
|
||||||
|
For fixtures in subfolders that had sub-namespaces (e.g. `NATS.Server.Tests.JetStream.Cluster`), update to `NATS.Server.TestUtilities;`.
|
||||||
|
|
||||||
|
**Step 3: Make fixture classes public**
|
||||||
|
|
||||||
|
The moved fixtures (`JetStreamApiFixture`, `JetStreamClusterFixture`, `LeafFixture`) are likely `internal`. Change them to `public` so test projects can access them.
|
||||||
|
|
||||||
|
**Step 4: Add `using NATS.Server.TestUtilities;` to files that reference moved fixtures**
|
||||||
|
|
||||||
|
All files that reference `JetStreamApiFixture`, `JetStreamClusterFixture`, `LeafFixture`, or parity utilities need the new using directive. This is ~52 files for JetStreamApiFixture, ~20 for cluster fixture, ~5 for LeafFixture.
|
||||||
|
|
||||||
|
**Step 5: Remove TestData entry from NATS.Server.Tests.csproj**
|
||||||
|
|
||||||
|
Remove the `<None Update="TestData\**\*" ...>` item since TestData moved to TestUtilities.
|
||||||
|
|
||||||
|
**Step 6: Build and run tests**
|
||||||
|
|
||||||
|
Run: `dotnet build && dotnet test tests/NATS.Server.Tests --no-build`
|
||||||
|
Expected: All tests pass — fixtures resolved from TestUtilities.
|
||||||
|
|
||||||
|
**Step 7: Commit**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add -A
|
||||||
|
git commit -m "refactor: move shared fixtures and parity utilities to TestUtilities"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 2: Extract NATS.Server.Transport.Tests (~25 files)
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Create: `tests/NATS.Server.Transport.Tests/NATS.Server.Transport.Tests.csproj`
|
||||||
|
- Move: Root files: OcspConfigTests.cs, OcspStaplingTests.cs, TlsConnectionWrapperTests.cs, TlsHelperTests.cs, TlsMapAuthenticatorTests.cs, TlsOcspParityBatch1Tests.cs, TlsOcspParityBatch2Tests.cs, TlsRateLimiterTests.cs, TlsServerTests.cs
|
||||||
|
- Move: `WebSocket/` folder (15 files)
|
||||||
|
- Move: `Networking/` folder (1 file)
|
||||||
|
- Modify: `NatsDotNet.slnx`
|
||||||
|
|
||||||
|
**Step 1: Create the csproj**
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<!-- tests/NATS.Server.Transport.Tests/NATS.Server.Transport.Tests.csproj -->
|
||||||
|
<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" />
|
||||||
|
<PackageReference Include="Serilog.Sinks.File" />
|
||||||
|
</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>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2: Move files with git mv**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd tests
|
||||||
|
mkdir -p NATS.Server.Transport.Tests
|
||||||
|
git mv NATS.Server.Tests/OcspConfigTests.cs NATS.Server.Transport.Tests/
|
||||||
|
git mv NATS.Server.Tests/OcspStaplingTests.cs NATS.Server.Transport.Tests/
|
||||||
|
git mv NATS.Server.Tests/TlsConnectionWrapperTests.cs NATS.Server.Transport.Tests/
|
||||||
|
git mv NATS.Server.Tests/TlsHelperTests.cs NATS.Server.Transport.Tests/
|
||||||
|
git mv NATS.Server.Tests/TlsMapAuthenticatorTests.cs NATS.Server.Transport.Tests/
|
||||||
|
git mv NATS.Server.Tests/TlsOcspParityBatch1Tests.cs NATS.Server.Transport.Tests/
|
||||||
|
git mv NATS.Server.Tests/TlsOcspParityBatch2Tests.cs NATS.Server.Transport.Tests/
|
||||||
|
git mv NATS.Server.Tests/TlsRateLimiterTests.cs NATS.Server.Transport.Tests/
|
||||||
|
git mv NATS.Server.Tests/TlsServerTests.cs NATS.Server.Transport.Tests/
|
||||||
|
git mv NATS.Server.Tests/WebSocket NATS.Server.Transport.Tests/WebSocket
|
||||||
|
git mv NATS.Server.Tests/Networking NATS.Server.Transport.Tests/Networking
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 3: Update namespaces**
|
||||||
|
|
||||||
|
In all moved files, change:
|
||||||
|
- `namespace NATS.Server.Tests;` → `namespace NATS.Server.Transport.Tests;`
|
||||||
|
- `namespace NATS.Server.Tests.WebSocket;` → `namespace NATS.Server.Transport.Tests.WebSocket;`
|
||||||
|
- `namespace NATS.Server.Tests.Networking;` → `namespace NATS.Server.Transport.Tests.Networking;`
|
||||||
|
|
||||||
|
**Step 4: Replace private GetFreePort/ReadUntilAsync with TestUtilities calls**
|
||||||
|
|
||||||
|
In each moved file that has `private static int GetFreePort()` or `private static async Task<string> ReadUntilAsync(...)`:
|
||||||
|
- Delete the private method
|
||||||
|
- Add `using NATS.Server.TestUtilities;`
|
||||||
|
- Replace `GetFreePort()` → `TestPortAllocator.GetFreePort()`
|
||||||
|
- Replace `ReadUntilAsync(` → `SocketTestHelper.ReadUntilAsync(`
|
||||||
|
|
||||||
|
**Step 5: Add to solution file**
|
||||||
|
|
||||||
|
In `NatsDotNet.slnx`, inside `/tests/`:
|
||||||
|
```xml
|
||||||
|
<Project Path="tests/NATS.Server.Transport.Tests/NATS.Server.Transport.Tests.csproj" />
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 6: Build and test**
|
||||||
|
|
||||||
|
Run: `dotnet build && dotnet test tests/NATS.Server.Transport.Tests --no-build`
|
||||||
|
Expected: All Transport tests pass.
|
||||||
|
|
||||||
|
Run: `dotnet test tests/NATS.Server.Tests --no-build`
|
||||||
|
Expected: Remaining tests still pass.
|
||||||
|
|
||||||
|
**Step 7: Commit**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add -A
|
||||||
|
git commit -m "refactor: extract NATS.Server.Transport.Tests project"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 3: Extract NATS.Server.Mqtt.Tests (~30 files)
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Create: `tests/NATS.Server.Mqtt.Tests/NATS.Server.Mqtt.Tests.csproj`
|
||||||
|
- Move: Root file: MqttPersistenceTests.cs
|
||||||
|
- Move: `Mqtt/` folder (28 files)
|
||||||
|
|
||||||
|
**Step 1: Create csproj** (same template as Transport, no Serilog needed)
|
||||||
|
|
||||||
|
**Step 2: Move files**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd tests
|
||||||
|
mkdir -p NATS.Server.Mqtt.Tests
|
||||||
|
git mv NATS.Server.Tests/MqttPersistenceTests.cs NATS.Server.Mqtt.Tests/
|
||||||
|
git mv NATS.Server.Tests/Mqtt NATS.Server.Mqtt.Tests/Mqtt
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 3: Update namespaces**
|
||||||
|
|
||||||
|
- `namespace NATS.Server.Tests;` → `namespace NATS.Server.Mqtt.Tests;`
|
||||||
|
- `namespace NATS.Server.Tests.Mqtt;` → `namespace NATS.Server.Mqtt.Tests.Mqtt;`
|
||||||
|
|
||||||
|
**Step 4: Replace duplicated helpers with TestUtilities calls** (same pattern as Task 2)
|
||||||
|
|
||||||
|
**Step 5: Add to solution file**
|
||||||
|
|
||||||
|
**Step 6: Build and test**
|
||||||
|
|
||||||
|
Run: `dotnet build && dotnet test tests/NATS.Server.Mqtt.Tests --no-build`
|
||||||
|
|
||||||
|
**Step 7: Commit**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add -A
|
||||||
|
git commit -m "refactor: extract NATS.Server.Mqtt.Tests project"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 4: Extract NATS.Server.Gateways.Tests (~25 files)
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Create: `tests/NATS.Server.Gateways.Tests/NATS.Server.Gateways.Tests.csproj`
|
||||||
|
- Move: Root files: GatewayAdvancedRemapRuntimeTests.cs, GatewayAdvancedSemanticsTests.cs, GatewayLeafBootstrapTests.cs, GatewayProtocolTests.cs
|
||||||
|
- Move: `Gateways/` folder (21 files)
|
||||||
|
|
||||||
|
**Steps:** Same pattern as Tasks 2-3.
|
||||||
|
|
||||||
|
Namespace changes:
|
||||||
|
- `namespace NATS.Server.Tests;` → `namespace NATS.Server.Gateways.Tests;`
|
||||||
|
- `namespace NATS.Server.Tests.Gateways;` → `namespace NATS.Server.Gateways.Tests.Gateways;`
|
||||||
|
|
||||||
|
May need `NATS.Client.Core` package if any gateway test uses `NatsConnection`.
|
||||||
|
|
||||||
|
**Commit:** `git commit -m "refactor: extract NATS.Server.Gateways.Tests project"`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 5: Extract NATS.Server.LeafNodes.Tests (~30 files)
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Create: `tests/NATS.Server.LeafNodes.Tests/NATS.Server.LeafNodes.Tests.csproj`
|
||||||
|
- Move: Root files: LeafAdvancedSemanticsTests.cs, LeafProtocolTests.cs
|
||||||
|
- Move: `LeafNodes/` folder (26 files) — note: `LeafFixture.cs` already moved to TestUtilities
|
||||||
|
- Move: `LeafNode/` folder (1 file)
|
||||||
|
|
||||||
|
**Steps:** Same pattern. The `LeafFixture` reference now comes from TestUtilities — add `using NATS.Server.TestUtilities;`.
|
||||||
|
|
||||||
|
Namespace changes:
|
||||||
|
- `namespace NATS.Server.Tests;` → `namespace NATS.Server.LeafNodes.Tests;`
|
||||||
|
- `namespace NATS.Server.Tests.LeafNodes;` → `namespace NATS.Server.LeafNodes.Tests.LeafNodes;`
|
||||||
|
- `namespace NATS.Server.Tests.LeafNode;` → `namespace NATS.Server.LeafNodes.Tests.LeafNode;`
|
||||||
|
|
||||||
|
**Commit:** `git commit -m "refactor: extract NATS.Server.LeafNodes.Tests project"`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 6: Extract NATS.Server.Clustering.Tests (~30 files)
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Create: `tests/NATS.Server.Clustering.Tests/NATS.Server.Clustering.Tests.csproj`
|
||||||
|
- Move: Root files: RouteHandshakeTests.cs, RoutePoolTests.cs, RouteRmsgForwardingTests.cs, RouteSubscriptionPropagationTests.cs, RouteWireSubscriptionProtocolTests.cs, ImplicitDiscoveryTests.cs, InterServerAccountProtocolTests.cs
|
||||||
|
- Move: `Routes/` folder (21 files)
|
||||||
|
- Move: `Route/` folder (1 file)
|
||||||
|
|
||||||
|
**Steps:** Same pattern.
|
||||||
|
|
||||||
|
Namespace changes:
|
||||||
|
- `namespace NATS.Server.Tests;` → `namespace NATS.Server.Clustering.Tests;`
|
||||||
|
- `namespace NATS.Server.Tests.Routes;` → `namespace NATS.Server.Clustering.Tests.Routes;`
|
||||||
|
- `namespace NATS.Server.Tests.Route;` → `namespace NATS.Server.Clustering.Tests.Route;`
|
||||||
|
|
||||||
|
**Commit:** `git commit -m "refactor: extract NATS.Server.Clustering.Tests project"`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 7: Extract NATS.Server.Raft.Tests (~45 files)
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Create: `tests/NATS.Server.Raft.Tests/NATS.Server.Raft.Tests.csproj`
|
||||||
|
- Move: Root files: RaftConsensusAdvancedParityTests.cs, RaftElectionTests.cs, RaftMembershipParityTests.cs, RaftReplicationTests.cs, RaftSafetyContractTests.cs, RaftSnapshotCatchupTests.cs, RaftSnapshotTransferParityTests.cs, RaftTransportPersistenceTests.cs
|
||||||
|
- Move: `Raft/` folder (36 files)
|
||||||
|
|
||||||
|
**Steps:** Same pattern.
|
||||||
|
|
||||||
|
Namespace changes:
|
||||||
|
- `namespace NATS.Server.Tests;` → `namespace NATS.Server.Raft.Tests;`
|
||||||
|
- `namespace NATS.Server.Tests.Raft;` → `namespace NATS.Server.Raft.Tests.Raft;`
|
||||||
|
|
||||||
|
**Commit:** `git commit -m "refactor: extract NATS.Server.Raft.Tests project"`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 8: Extract NATS.Server.Monitoring.Tests (~35 files)
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Create: `tests/NATS.Server.Monitoring.Tests/NATS.Server.Monitoring.Tests.csproj`
|
||||||
|
- Move: Root files: EventSystemTests.cs, JszMonitorTests.cs, MonitorClusterEndpointTests.cs, MonitorModelTests.cs, MonitorTests.cs, SubszTests.cs, SystemEventsTests.cs, SystemRequestReplyTests.cs
|
||||||
|
- Move: `Monitoring/` folder (21 files)
|
||||||
|
- Move: `Events/` folder (10 files)
|
||||||
|
|
||||||
|
**Steps:** Same pattern. Needs `NATS.Client.Core` package for integration tests.
|
||||||
|
|
||||||
|
Namespace changes:
|
||||||
|
- `namespace NATS.Server.Tests;` → `namespace NATS.Server.Monitoring.Tests;`
|
||||||
|
- `namespace NATS.Server.Tests.Monitoring;` → `namespace NATS.Server.Monitoring.Tests.Monitoring;`
|
||||||
|
- `namespace NATS.Server.Tests.Events;` → `namespace NATS.Server.Monitoring.Tests.Events;`
|
||||||
|
|
||||||
|
**Commit:** `git commit -m "refactor: extract NATS.Server.Monitoring.Tests project"`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 9: Extract NATS.Server.Auth.Tests (~50 files)
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Create: `tests/NATS.Server.Auth.Tests/NATS.Server.Auth.Tests.csproj`
|
||||||
|
- Move: Root files: AccountIsolationTests.cs, AccountResolverTests.cs, AccountStatsTests.cs, AccountTests.cs, AuthConfigTests.cs, AuthIntegrationTests.cs, AuthProtocolTests.cs, AuthServiceTests.cs, ClientPermissionsTests.cs, JwtAuthenticatorTests.cs, JwtTests.cs, NKeyAuthenticatorTests.cs, NKeyIntegrationTests.cs, PermissionIntegrationTests.cs, PermissionLruCacheTests.cs, PermissionTemplateTests.cs, SimpleUserPasswordAuthenticatorTests.cs, TokenAuthenticatorTests.cs, UserPasswordAuthenticatorTests.cs, ImportExportTests.cs
|
||||||
|
- Move: `Auth/` folder (25 files)
|
||||||
|
- Move: `Accounts/` folder (5 files)
|
||||||
|
|
||||||
|
**Steps:** Same pattern. Needs `NATS.NKeys` and `NATS.Client.Core` packages.
|
||||||
|
|
||||||
|
Namespace changes:
|
||||||
|
- `namespace NATS.Server.Tests;` → `namespace NATS.Server.Auth.Tests;`
|
||||||
|
- `namespace NATS.Server.Tests.Auth;` → `namespace NATS.Server.Auth.Tests.Auth;`
|
||||||
|
- `namespace NATS.Server.Tests.Accounts;` → `namespace NATS.Server.Auth.Tests.Accounts;`
|
||||||
|
|
||||||
|
**Commit:** `git commit -m "refactor: extract NATS.Server.Auth.Tests project"`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 10: Extract NATS.Server.JetStream.Tests (~220 files)
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Create: `tests/NATS.Server.JetStream.Tests/NATS.Server.JetStream.Tests.csproj`
|
||||||
|
- Move: All root `JetStream*` files (~55 files)
|
||||||
|
- Move: Root storage files: FileStoreTests.cs, FileStoreEncryptionTests.cs, MemStoreTests.cs, StreamStoreContractTests.cs, MirrorSourceRetryTests.cs, ClusterJetStreamConfigProcessorTests.cs
|
||||||
|
- Move: `JetStream/` folder and all sub-folders (163 files) — note: `JetStreamClusterFixture.cs` already in TestUtilities
|
||||||
|
|
||||||
|
**Step 1: Create csproj with JetStream-specific additions**
|
||||||
|
|
||||||
|
```xml
|
||||||
|
<!-- tests/NATS.Server.JetStream.Tests/NATS.Server.JetStream.Tests.csproj -->
|
||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
<DefineConstants>$(DefineConstants);JETSTREAM_INTEGRATION_MATRIX</DefineConstants>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="coverlet.collector" />
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" />
|
||||||
|
<PackageReference Include="NATS.Client.Core" />
|
||||||
|
<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>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2: Move files** — this is the largest move. Use a script:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd tests
|
||||||
|
mkdir -p NATS.Server.JetStream.Tests
|
||||||
|
|
||||||
|
# Move JetStream subfolder (preserves internal structure)
|
||||||
|
git mv NATS.Server.Tests/JetStream NATS.Server.JetStream.Tests/JetStream
|
||||||
|
|
||||||
|
# Move root JetStream* files
|
||||||
|
for f in NATS.Server.Tests/JetStream*.cs; do
|
||||||
|
git mv "$f" NATS.Server.JetStream.Tests/
|
||||||
|
done
|
||||||
|
|
||||||
|
# Move storage-related root files
|
||||||
|
git mv NATS.Server.Tests/FileStoreTests.cs NATS.Server.JetStream.Tests/
|
||||||
|
git mv NATS.Server.Tests/FileStoreEncryptionTests.cs NATS.Server.JetStream.Tests/
|
||||||
|
git mv NATS.Server.Tests/MemStoreTests.cs NATS.Server.JetStream.Tests/
|
||||||
|
git mv NATS.Server.Tests/StreamStoreContractTests.cs NATS.Server.JetStream.Tests/
|
||||||
|
git mv NATS.Server.Tests/MirrorSourceRetryTests.cs NATS.Server.JetStream.Tests/
|
||||||
|
git mv NATS.Server.Tests/ClusterJetStreamConfigProcessorTests.cs NATS.Server.JetStream.Tests/
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 3: Update namespaces**
|
||||||
|
|
||||||
|
- `namespace NATS.Server.Tests;` → `namespace NATS.Server.JetStream.Tests;` (root files)
|
||||||
|
- `namespace NATS.Server.Tests.JetStream;` → `namespace NATS.Server.JetStream.Tests.JetStream;`
|
||||||
|
- All JetStream sub-namespaces follow the pattern (e.g., `NATS.Server.Tests.JetStream.Cluster` → `NATS.Server.JetStream.Tests.JetStream.Cluster`)
|
||||||
|
|
||||||
|
**Step 4: Update fixture references**
|
||||||
|
|
||||||
|
Files using `JetStreamApiFixture` or `JetStreamClusterFixture` need `using NATS.Server.TestUtilities;` since the fixtures moved there in Task 1.
|
||||||
|
|
||||||
|
**Step 5: Replace duplicated helpers with TestUtilities calls**
|
||||||
|
|
||||||
|
**Step 6: Add to solution, build, test**
|
||||||
|
|
||||||
|
Run: `dotnet build && dotnet test tests/NATS.Server.JetStream.Tests --no-build`
|
||||||
|
|
||||||
|
**Step 7: Commit**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add -A
|
||||||
|
git commit -m "refactor: extract NATS.Server.JetStream.Tests project"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 11: Rename remaining project to NATS.Server.Core.Tests
|
||||||
|
|
||||||
|
**Files:**
|
||||||
|
- Rename: `tests/NATS.Server.Tests/` → `tests/NATS.Server.Core.Tests/`
|
||||||
|
- Rename: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj` → `tests/NATS.Server.Core.Tests/NATS.Server.Core.Tests.csproj`
|
||||||
|
- Modify: `NatsDotNet.slnx` (update path)
|
||||||
|
|
||||||
|
**Step 1: Rename directory and csproj**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd tests
|
||||||
|
git mv NATS.Server.Tests NATS.Server.Core.Tests
|
||||||
|
cd NATS.Server.Core.Tests
|
||||||
|
git mv NATS.Server.Tests.csproj NATS.Server.Core.Tests.csproj
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 2: Update solution file**
|
||||||
|
|
||||||
|
Replace `tests/NATS.Server.Tests/NATS.Server.Tests.csproj` with `tests/NATS.Server.Core.Tests/NATS.Server.Core.Tests.csproj`.
|
||||||
|
|
||||||
|
**Step 3: Clean up csproj**
|
||||||
|
|
||||||
|
Remove the `JETSTREAM_INTEGRATION_MATRIX` DefineConstants (that moved to JetStream.Tests). Remove any package references only needed by extracted projects (e.g., `NATS.NKeys` if only auth tests needed it). Keep `NATS.Client.Core` and `Serilog.Sinks.File`.
|
||||||
|
|
||||||
|
**Step 4: Update namespaces**
|
||||||
|
|
||||||
|
Change `namespace NATS.Server.Tests;` → `namespace NATS.Server.Core.Tests;` in all remaining files.
|
||||||
|
Update sub-namespaces: `NATS.Server.Tests.Configuration` → `NATS.Server.Core.Tests.Configuration`, etc.
|
||||||
|
|
||||||
|
**Step 5: Replace duplicated helpers with TestUtilities calls**
|
||||||
|
|
||||||
|
**Step 6: Build and test all projects**
|
||||||
|
|
||||||
|
Run: `dotnet build && dotnet test`
|
||||||
|
Expected: All projects build and all tests pass.
|
||||||
|
|
||||||
|
**Step 7: Commit**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add -A
|
||||||
|
git commit -m "refactor: rename remaining tests to NATS.Server.Core.Tests"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Task 12: Final verification and cleanup
|
||||||
|
|
||||||
|
**Step 1: Run full test suite**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
dotnet test -v normal 2>&1 | tail -20
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: All test projects discovered and run. Total test count should match original (~6,409 parameterized tests).
|
||||||
|
|
||||||
|
**Step 2: Verify each project runs independently**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
dotnet test tests/NATS.Server.Core.Tests
|
||||||
|
dotnet test tests/NATS.Server.Auth.Tests
|
||||||
|
dotnet test tests/NATS.Server.JetStream.Tests
|
||||||
|
dotnet test tests/NATS.Server.Raft.Tests
|
||||||
|
dotnet test tests/NATS.Server.Clustering.Tests
|
||||||
|
dotnet test tests/NATS.Server.Gateways.Tests
|
||||||
|
dotnet test tests/NATS.Server.LeafNodes.Tests
|
||||||
|
dotnet test tests/NATS.Server.Mqtt.Tests
|
||||||
|
dotnet test tests/NATS.Server.Monitoring.Tests
|
||||||
|
dotnet test tests/NATS.Server.Transport.Tests
|
||||||
|
dotnet test tests/NATS.E2E.Tests
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 3: Verify solution structure**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
dotnet sln NatsDotNet.slnx list
|
||||||
|
```
|
||||||
|
|
||||||
|
Expected: 13 projects listed (2 src + 11 test).
|
||||||
|
|
||||||
|
**Step 4: Check for orphaned files**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
find tests/NATS.Server.Core.Tests -name "*.cs" -not -path "*/obj/*" -not -path "*/bin/*" | wc -l
|
||||||
|
```
|
||||||
|
|
||||||
|
Should be ~75 files. Any file that doesn't belong in Core should be moved to its correct project.
|
||||||
|
|
||||||
|
**Step 5: Clean build artifacts and rebuild from scratch**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
dotnet clean && dotnet build && dotnet test
|
||||||
|
```
|
||||||
|
|
||||||
|
**Step 6: Commit any cleanup**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git add -A
|
||||||
|
git commit -m "chore: final cleanup after test project split"
|
||||||
|
```
|
||||||
19
docs/plans/2026-03-12-test-project-split-plan.md.tasks.json
Normal file
19
docs/plans/2026-03-12-test-project-split-plan.md.tasks.json
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
{
|
||||||
|
"planPath": "docs/plans/2026-03-12-test-project-split-plan.md",
|
||||||
|
"tasks": [
|
||||||
|
{"id": 0, "subject": "Task 0: Create NATS.Server.TestUtilities project", "status": "pending"},
|
||||||
|
{"id": 1, "subject": "Task 1: Move shared fixtures and parity utilities to TestUtilities", "status": "pending", "blockedBy": [0]},
|
||||||
|
{"id": 2, "subject": "Task 2: Extract NATS.Server.Transport.Tests (~25 files)", "status": "pending", "blockedBy": [1]},
|
||||||
|
{"id": 3, "subject": "Task 3: Extract NATS.Server.Mqtt.Tests (~30 files)", "status": "pending", "blockedBy": [1]},
|
||||||
|
{"id": 4, "subject": "Task 4: Extract NATS.Server.Gateways.Tests (~25 files)", "status": "pending", "blockedBy": [1]},
|
||||||
|
{"id": 5, "subject": "Task 5: Extract NATS.Server.LeafNodes.Tests (~30 files)", "status": "pending", "blockedBy": [1]},
|
||||||
|
{"id": 6, "subject": "Task 6: Extract NATS.Server.Clustering.Tests (~30 files)", "status": "pending", "blockedBy": [1]},
|
||||||
|
{"id": 7, "subject": "Task 7: Extract NATS.Server.Raft.Tests (~45 files)", "status": "pending", "blockedBy": [1]},
|
||||||
|
{"id": 8, "subject": "Task 8: Extract NATS.Server.Monitoring.Tests (~35 files)", "status": "pending", "blockedBy": [1]},
|
||||||
|
{"id": 9, "subject": "Task 9: Extract NATS.Server.Auth.Tests (~50 files)", "status": "pending", "blockedBy": [1]},
|
||||||
|
{"id": 10, "subject": "Task 10: Extract NATS.Server.JetStream.Tests (~220 files)", "status": "pending", "blockedBy": [1]},
|
||||||
|
{"id": 11, "subject": "Task 11: Rename remaining to NATS.Server.Core.Tests", "status": "pending", "blockedBy": [2, 3, 4, 5, 6, 7, 8, 9, 10]},
|
||||||
|
{"id": 12, "subject": "Task 12: Final verification and cleanup", "status": "pending", "blockedBy": [11]}
|
||||||
|
],
|
||||||
|
"lastUpdated": "2026-03-12T00:00:00Z"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user