Fix E2E test gaps and add comprehensive E2E + parity test suites
- Fix pull consumer fetch: send original stream subject in HMSG (not inbox) so NATS client distinguishes data messages from control messages - Fix MaxAge expiry: add background timer in StreamManager for periodic pruning - Fix JetStream wire format: Go-compatible anonymous objects with string enums, proper offset-based pagination for stream/consumer list APIs - Add 42 E2E black-box tests (core messaging, auth, TLS, accounts, JetStream) - Add ~1000 parity tests across all subsystems (gaps closure) - Update gap inventory docs to reflect implementation status
This commit is contained in:
85
docs/plans/2026-02-25-gap-port-auth-and-accounts-design.md
Normal file
85
docs/plans/2026-02-25-gap-port-auth-and-accounts-design.md
Normal file
@@ -0,0 +1,85 @@
|
||||
# Auth & Accounts Full Parity Design
|
||||
|
||||
**Date:** 2026-02-25
|
||||
**Category:** `auth-and-accounts`
|
||||
**Gap Inventory:** `gaps/auth-and-accounts.md`
|
||||
**Target Outcome:** Full Go-to-.NET behavioral parity for this category.
|
||||
|
||||
## Assumptions
|
||||
- Full parity is the required outcome.
|
||||
- No additional requirements gathering is needed for this pass.
|
||||
- Existing public .NET APIs are preserved unless parity requires targeted, documented adjustments.
|
||||
|
||||
## Current State Snapshot
|
||||
- `MISSING`: 128
|
||||
- `PARTIAL`: 38
|
||||
- `PORTED`: 64
|
||||
- `NOT_APPLICABLE`: 9
|
||||
- `DEFERRED`: 0
|
||||
- **Open parity work items:** 166
|
||||
|
||||
## Approaches Considered
|
||||
1. **Symbol-first closure (Recommended):** execute directly against each `MISSING` and `PARTIAL` row in `gaps/auth-and-accounts.md`, closing items in deterministic order.
|
||||
Trade-off: strongest traceability and auditability, but can require broad context switching.
|
||||
2. **Test-first closure:** derive all work from Go test scenarios first, then backfill missing symbols.
|
||||
Trade-off: maximizes behavioral confidence, but can miss non-test-covered API and helper parity.
|
||||
3. **Vertical runtime slices:** port connect/auth/pubsub/cluster flows end-to-end before moving to next slice.
|
||||
Trade-off: smoother integration validation, but weaker one-to-one mapping against inventory rows.
|
||||
|
||||
## Recommended Design
|
||||
### Architecture
|
||||
Use the gap inventory as the authoritative backlog. For each row, implement or complete the .NET equivalent, then attach test evidence and update the inventory status. Keep implementation inside existing category boundaries and only refactor when needed to match Go behavior.
|
||||
|
||||
### Components
|
||||
- **Backlog driver:** `gaps/auth-and-accounts.md` (row-level tracking for all parity items).
|
||||
- **Implementation surface:** category-specific .NET source files.
|
||||
- **Verification surface:** category-specific .NET tests plus cross-module regression tests.
|
||||
- **Parity bookkeeping:** updates to `gaps/auth-and-accounts.md` and `gaps/stillmissing.md` after each closure batch.
|
||||
|
||||
### Data Flow
|
||||
1. Read one `MISSING` or `PARTIAL` row from `gaps/auth-and-accounts.md`.
|
||||
2. Inspect referenced Go implementation and tests.
|
||||
3. Add/adjust .NET implementation in listed category files.
|
||||
4. Add failing .NET tests that reproduce the missing/partial behavior, then make them pass.
|
||||
5. Re-run targeted and regression tests.
|
||||
6. Update the row to `PORTED` (or keep `PARTIAL` with explicit residual notes).
|
||||
|
||||
### Error Handling and Risk Controls
|
||||
- Avoid broad rewrites; prefer narrow patches tied to specific inventory rows.
|
||||
- Preserve protocol and timing semantics when replacing Go concurrency constructs with .NET async patterns.
|
||||
- Treat edge cases in Go tests as mandatory parity requirements unless explicitly marked `NOT_APPLICABLE`.
|
||||
- Require evidence (tests + inventory status updates) before declaring row completion.
|
||||
|
||||
### Testing Strategy
|
||||
- Add or expand tests for each row moved from `MISSING`/`PARTIAL` toward `PORTED`.
|
||||
- Prioritize wire/protocol compatibility, lifecycle transitions, auth boundaries, and backpressure/timeout behavior.
|
||||
- Keep category-targeted tests fast; run full `NATS.Server.Tests` regression before closure.
|
||||
|
||||
### Definition of Done
|
||||
- All category rows are either `PORTED` or explicitly justified `NOT_APPLICABLE`/`DEFERRED`.
|
||||
- No unresolved `MISSING` or unqualified `PARTIAL` rows remain for this category.
|
||||
- Relevant .NET tests pass locally and parity evidence is written into inventory notes.
|
||||
|
||||
## Implementation Scope Inputs
|
||||
### Go Source Files
|
||||
- `golang/nats-server/server/auth.go`
|
||||
- `golang/nats-server/server/auth_callout.go`
|
||||
- `golang/nats-server/server/nkey.go`
|
||||
- `golang/nats-server/server/jwt.go`
|
||||
- `golang/nats-server/server/accounts.go`
|
||||
|
||||
### Go Test Files
|
||||
- `golang/nats-server/server/auth_test.go`
|
||||
- `golang/nats-server/server/auth_callout_test.go`
|
||||
- `golang/nats-server/server/nkey_test.go`
|
||||
- `golang/nats-server/server/jwt_test.go`
|
||||
- `golang/nats-server/server/accounts_test.go`
|
||||
- `golang/nats-server/server/trust_test.go`
|
||||
|
||||
### .NET Source Files
|
||||
- `src/NATS.Server/Auth/ (all files including Jwt/ subdirectory)`
|
||||
- `src/NATS.Server/Imports/ (account import/export)`
|
||||
|
||||
### .NET Test Files
|
||||
- `tests/NATS.Server.Tests/Auth/`
|
||||
- `tests/NATS.Server.Tests/Accounts/`
|
||||
103
docs/plans/2026-02-25-gap-port-auth-and-accounts-plan.md
Normal file
103
docs/plans/2026-02-25-gap-port-auth-and-accounts-plan.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# Auth & Accounts Gap Port Implementation Plan
|
||||
|
||||
> **For Codex:** REQUIRED SUB-SKILL: Use `executeplan` to implement this plan task-by-task.
|
||||
|
||||
**Goal:** Port all remaining `auth-and-accounts` gap inventory items to achieve full behavior parity with Go.
|
||||
|
||||
**Architecture:** Use the category gap inventory as the execution backlog. Drive work row-by-row from `MISSING` and `PARTIAL` toward `PORTED`, with test-first validation and explicit parity evidence in notes.
|
||||
|
||||
**Tech Stack:** .NET 10, C#, xUnit, existing `NATS.Server` runtime modules, Go NATS server reference source.
|
||||
|
||||
---
|
||||
|
||||
## Category Inputs
|
||||
- Gap Inventory: `gaps/auth-and-accounts.md`
|
||||
- Primary .NET Source Anchor: `src/NATS.Server/Auth/ (all files including Jwt/ subdirectory)`
|
||||
- Primary .NET Test Anchor: `tests/NATS.Server.Tests/Auth/`
|
||||
- Full .NET test project: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
## Task 1: Freeze Row-Level Backlog
|
||||
|
||||
**Files:**
|
||||
- Modify: `gaps/auth-and-accounts.md`
|
||||
|
||||
**Step 1: Normalize open rows into an execution queue**
|
||||
- Split all `MISSING` and `PARTIAL` rows into ranked batches (highest runtime impact first).
|
||||
|
||||
**Step 2: Record acceptance criteria per row**
|
||||
- For each row, define exact behavioral parity checks (inputs, outputs, error paths, timing/concurrency expectations).
|
||||
|
||||
**Step 3: Save queue annotations in notes**
|
||||
- Add short execution-order markers in notes without changing status yet.
|
||||
|
||||
## Task 2: Write Failing Tests for Batch 1
|
||||
|
||||
**Files:**
|
||||
- Modify: `tests/NATS.Server.Tests/Auth/`
|
||||
- Test: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
**Step 1: Add failing tests for first open row batch**
|
||||
- Create tests that reproduce the exact missing/partial Go behavior.
|
||||
|
||||
**Step 2: Run tests to confirm failure**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: FAIL in newly added tests only.
|
||||
|
||||
## Task 3: Implement Minimal Parity for Batch 1
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/NATS.Server/Auth/ (all files including Jwt/ subdirectory)`
|
||||
- Modify: additional category files listed in `gaps/auth-and-accounts.md`
|
||||
|
||||
**Step 1: Implement minimal code to satisfy failing tests**
|
||||
- Mirror Go semantics for parsing, state transitions, limits, and side-effects required by the targeted rows.
|
||||
|
||||
**Step 2: Re-run tests for validation**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: PASS for batch-1 tests; no new regressions.
|
||||
|
||||
## Task 4: Close Remaining Batches Iteratively
|
||||
|
||||
**Files:**
|
||||
- Modify: category .NET source and test files referenced in `gaps/auth-and-accounts.md`
|
||||
- Modify: `gaps/auth-and-accounts.md`
|
||||
|
||||
**Step 1: Repeat test-first cycle for each remaining batch**
|
||||
- Add failing tests, implement minimal parity, then verify pass.
|
||||
|
||||
**Step 2: Update inventory status immediately after each closure**
|
||||
- Move rows to `PORTED` with exact .NET file:line references.
|
||||
- Keep `PARTIAL` only if explicit residual behavior remains.
|
||||
|
||||
## Task 5: Cross-Module Regression and Hardening
|
||||
|
||||
**Files:**
|
||||
- Test: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
**Step 1: Run full regression suite**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: PASS.
|
||||
|
||||
**Step 2: Add edge-case tests discovered during regression**
|
||||
- Capture any newly discovered divergence from Go and close it before completion.
|
||||
|
||||
## Task 6: Finalize Parity Bookkeeping
|
||||
|
||||
**Files:**
|
||||
- Modify: `gaps/auth-and-accounts.md`
|
||||
- Modify: `gaps/stillmissing.md`
|
||||
|
||||
**Step 1: Ensure final status correctness**
|
||||
- Verify no unresolved `MISSING` rows remain for `auth-and-accounts`.
|
||||
|
||||
**Step 2: Refresh LOC and percentage bookkeeping**
|
||||
- Recount category LOC and update summary rows in `gaps/stillmissing.md`.
|
||||
|
||||
**Step 3: Add concise changelog entry**
|
||||
- Record date, completed parity areas, and any justified deferred items.
|
||||
|
||||
## Completion Checklist
|
||||
- [ ] All prioritized `auth-and-accounts` rows are `PORTED` or explicitly justified as `NOT_APPLICABLE`/`DEFERRED`.
|
||||
- [ ] New/updated tests demonstrate parity for all previously open rows.
|
||||
- [ ] `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release` passes.
|
||||
- [ ] `gaps/auth-and-accounts.md` and `gaps/stillmissing.md` are fully synchronized.
|
||||
83
docs/plans/2026-02-25-gap-port-configuration-design.md
Normal file
83
docs/plans/2026-02-25-gap-port-configuration-design.md
Normal file
@@ -0,0 +1,83 @@
|
||||
# Configuration Full Parity Design
|
||||
|
||||
**Date:** 2026-02-25
|
||||
**Category:** `configuration`
|
||||
**Gap Inventory:** `gaps/configuration.md`
|
||||
**Target Outcome:** Full Go-to-.NET behavioral parity for this category.
|
||||
|
||||
## Assumptions
|
||||
- Full parity is the required outcome.
|
||||
- No additional requirements gathering is needed for this pass.
|
||||
- Existing public .NET APIs are preserved unless parity requires targeted, documented adjustments.
|
||||
|
||||
## Current State Snapshot
|
||||
- `MISSING`: 12
|
||||
- `PARTIAL`: 8
|
||||
- `PORTED`: 108
|
||||
- `NOT_APPLICABLE`: 3
|
||||
- `DEFERRED`: 0
|
||||
- **Open parity work items:** 20
|
||||
|
||||
## Approaches Considered
|
||||
1. **Symbol-first closure (Recommended):** execute directly against each `MISSING` and `PARTIAL` row in `gaps/configuration.md`, closing items in deterministic order.
|
||||
Trade-off: strongest traceability and auditability, but can require broad context switching.
|
||||
2. **Test-first closure:** derive all work from Go test scenarios first, then backfill missing symbols.
|
||||
Trade-off: maximizes behavioral confidence, but can miss non-test-covered API and helper parity.
|
||||
3. **Vertical runtime slices:** port connect/auth/pubsub/cluster flows end-to-end before moving to next slice.
|
||||
Trade-off: smoother integration validation, but weaker one-to-one mapping against inventory rows.
|
||||
|
||||
## Recommended Design
|
||||
### Architecture
|
||||
Use the gap inventory as the authoritative backlog. For each row, implement or complete the .NET equivalent, then attach test evidence and update the inventory status. Keep implementation inside existing category boundaries and only refactor when needed to match Go behavior.
|
||||
|
||||
### Components
|
||||
- **Backlog driver:** `gaps/configuration.md` (row-level tracking for all parity items).
|
||||
- **Implementation surface:** category-specific .NET source files.
|
||||
- **Verification surface:** category-specific .NET tests plus cross-module regression tests.
|
||||
- **Parity bookkeeping:** updates to `gaps/configuration.md` and `gaps/stillmissing.md` after each closure batch.
|
||||
|
||||
### Data Flow
|
||||
1. Read one `MISSING` or `PARTIAL` row from `gaps/configuration.md`.
|
||||
2. Inspect referenced Go implementation and tests.
|
||||
3. Add/adjust .NET implementation in listed category files.
|
||||
4. Add failing .NET tests that reproduce the missing/partial behavior, then make them pass.
|
||||
5. Re-run targeted and regression tests.
|
||||
6. Update the row to `PORTED` (or keep `PARTIAL` with explicit residual notes).
|
||||
|
||||
### Error Handling and Risk Controls
|
||||
- Avoid broad rewrites; prefer narrow patches tied to specific inventory rows.
|
||||
- Preserve protocol and timing semantics when replacing Go concurrency constructs with .NET async patterns.
|
||||
- Treat edge cases in Go tests as mandatory parity requirements unless explicitly marked `NOT_APPLICABLE`.
|
||||
- Require evidence (tests + inventory status updates) before declaring row completion.
|
||||
|
||||
### Testing Strategy
|
||||
- Add or expand tests for each row moved from `MISSING`/`PARTIAL` toward `PORTED`.
|
||||
- Prioritize wire/protocol compatibility, lifecycle transitions, auth boundaries, and backpressure/timeout behavior.
|
||||
- Keep category-targeted tests fast; run full `NATS.Server.Tests` regression before closure.
|
||||
|
||||
### Definition of Done
|
||||
- All category rows are either `PORTED` or explicitly justified `NOT_APPLICABLE`/`DEFERRED`.
|
||||
- No unresolved `MISSING` or unqualified `PARTIAL` rows remain for this category.
|
||||
- Relevant .NET tests pass locally and parity evidence is written into inventory notes.
|
||||
|
||||
## Implementation Scope Inputs
|
||||
### Go Source Files
|
||||
- `golang/nats-server/conf/lex.go`
|
||||
- `golang/nats-server/conf/parse.go`
|
||||
- `golang/nats-server/conf/token.go`
|
||||
|
||||
### Go Test Files
|
||||
- `golang/nats-server/conf/lex_test.go`
|
||||
- `golang/nats-server/conf/parse_test.go`
|
||||
- `golang/nats-server/server/config_check_test.go`
|
||||
|
||||
### .NET Source Files
|
||||
- `src/NATS.Server/Configuration/NatsConfLexer.cs`
|
||||
- `src/NATS.Server/Configuration/NatsConfParser.cs`
|
||||
- `src/NATS.Server/Configuration/NatsConfToken.cs`
|
||||
- `src/NATS.Server/Configuration/ConfigProcessor.cs`
|
||||
- `src/NATS.Server/Configuration/ConfigReloader.cs`
|
||||
- `All other files in src/NATS.Server/Configuration/`
|
||||
|
||||
### .NET Test Files
|
||||
- `tests/NATS.Server.Tests/Configuration/`
|
||||
103
docs/plans/2026-02-25-gap-port-configuration-plan.md
Normal file
103
docs/plans/2026-02-25-gap-port-configuration-plan.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# Configuration Gap Port Implementation Plan
|
||||
|
||||
> **For Codex:** REQUIRED SUB-SKILL: Use `executeplan` to implement this plan task-by-task.
|
||||
|
||||
**Goal:** Port all remaining `configuration` gap inventory items to achieve full behavior parity with Go.
|
||||
|
||||
**Architecture:** Use the category gap inventory as the execution backlog. Drive work row-by-row from `MISSING` and `PARTIAL` toward `PORTED`, with test-first validation and explicit parity evidence in notes.
|
||||
|
||||
**Tech Stack:** .NET 10, C#, xUnit, existing `NATS.Server` runtime modules, Go NATS server reference source.
|
||||
|
||||
---
|
||||
|
||||
## Category Inputs
|
||||
- Gap Inventory: `gaps/configuration.md`
|
||||
- Primary .NET Source Anchor: `src/NATS.Server/Configuration/NatsConfLexer.cs`
|
||||
- Primary .NET Test Anchor: `tests/NATS.Server.Tests/Configuration/`
|
||||
- Full .NET test project: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
## Task 1: Freeze Row-Level Backlog
|
||||
|
||||
**Files:**
|
||||
- Modify: `gaps/configuration.md`
|
||||
|
||||
**Step 1: Normalize open rows into an execution queue**
|
||||
- Split all `MISSING` and `PARTIAL` rows into ranked batches (highest runtime impact first).
|
||||
|
||||
**Step 2: Record acceptance criteria per row**
|
||||
- For each row, define exact behavioral parity checks (inputs, outputs, error paths, timing/concurrency expectations).
|
||||
|
||||
**Step 3: Save queue annotations in notes**
|
||||
- Add short execution-order markers in notes without changing status yet.
|
||||
|
||||
## Task 2: Write Failing Tests for Batch 1
|
||||
|
||||
**Files:**
|
||||
- Modify: `tests/NATS.Server.Tests/Configuration/`
|
||||
- Test: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
**Step 1: Add failing tests for first open row batch**
|
||||
- Create tests that reproduce the exact missing/partial Go behavior.
|
||||
|
||||
**Step 2: Run tests to confirm failure**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: FAIL in newly added tests only.
|
||||
|
||||
## Task 3: Implement Minimal Parity for Batch 1
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/NATS.Server/Configuration/NatsConfLexer.cs`
|
||||
- Modify: additional category files listed in `gaps/configuration.md`
|
||||
|
||||
**Step 1: Implement minimal code to satisfy failing tests**
|
||||
- Mirror Go semantics for parsing, state transitions, limits, and side-effects required by the targeted rows.
|
||||
|
||||
**Step 2: Re-run tests for validation**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: PASS for batch-1 tests; no new regressions.
|
||||
|
||||
## Task 4: Close Remaining Batches Iteratively
|
||||
|
||||
**Files:**
|
||||
- Modify: category .NET source and test files referenced in `gaps/configuration.md`
|
||||
- Modify: `gaps/configuration.md`
|
||||
|
||||
**Step 1: Repeat test-first cycle for each remaining batch**
|
||||
- Add failing tests, implement minimal parity, then verify pass.
|
||||
|
||||
**Step 2: Update inventory status immediately after each closure**
|
||||
- Move rows to `PORTED` with exact .NET file:line references.
|
||||
- Keep `PARTIAL` only if explicit residual behavior remains.
|
||||
|
||||
## Task 5: Cross-Module Regression and Hardening
|
||||
|
||||
**Files:**
|
||||
- Test: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
**Step 1: Run full regression suite**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: PASS.
|
||||
|
||||
**Step 2: Add edge-case tests discovered during regression**
|
||||
- Capture any newly discovered divergence from Go and close it before completion.
|
||||
|
||||
## Task 6: Finalize Parity Bookkeeping
|
||||
|
||||
**Files:**
|
||||
- Modify: `gaps/configuration.md`
|
||||
- Modify: `gaps/stillmissing.md`
|
||||
|
||||
**Step 1: Ensure final status correctness**
|
||||
- Verify no unresolved `MISSING` rows remain for `configuration`.
|
||||
|
||||
**Step 2: Refresh LOC and percentage bookkeeping**
|
||||
- Recount category LOC and update summary rows in `gaps/stillmissing.md`.
|
||||
|
||||
**Step 3: Add concise changelog entry**
|
||||
- Record date, completed parity areas, and any justified deferred items.
|
||||
|
||||
## Completion Checklist
|
||||
- [ ] All prioritized `configuration` rows are `PORTED` or explicitly justified as `NOT_APPLICABLE`/`DEFERRED`.
|
||||
- [ ] New/updated tests demonstrate parity for all previously open rows.
|
||||
- [ ] `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release` passes.
|
||||
- [ ] `gaps/configuration.md` and `gaps/stillmissing.md` are fully synchronized.
|
||||
98
docs/plans/2026-02-25-gap-port-core-server-design.md
Normal file
98
docs/plans/2026-02-25-gap-port-core-server-design.md
Normal file
@@ -0,0 +1,98 @@
|
||||
# Core Server Full Parity Design
|
||||
|
||||
**Date:** 2026-02-25
|
||||
**Category:** `core-server`
|
||||
**Gap Inventory:** `gaps/core-server.md`
|
||||
**Target Outcome:** Full Go-to-.NET behavioral parity for this category.
|
||||
|
||||
## Assumptions
|
||||
- Full parity is the required outcome.
|
||||
- No additional requirements gathering is needed for this pass.
|
||||
- Existing public .NET APIs are preserved unless parity requires targeted, documented adjustments.
|
||||
|
||||
## Current State Snapshot
|
||||
- `MISSING`: 55
|
||||
- `PARTIAL`: 30
|
||||
- `PORTED`: 123
|
||||
- `NOT_APPLICABLE`: 14
|
||||
- `DEFERRED`: 0
|
||||
- **Open parity work items:** 85
|
||||
|
||||
## Approaches Considered
|
||||
1. **Symbol-first closure (Recommended):** execute directly against each `MISSING` and `PARTIAL` row in `gaps/core-server.md`, closing items in deterministic order.
|
||||
Trade-off: strongest traceability and auditability, but can require broad context switching.
|
||||
2. **Test-first closure:** derive all work from Go test scenarios first, then backfill missing symbols.
|
||||
Trade-off: maximizes behavioral confidence, but can miss non-test-covered API and helper parity.
|
||||
3. **Vertical runtime slices:** port connect/auth/pubsub/cluster flows end-to-end before moving to next slice.
|
||||
Trade-off: smoother integration validation, but weaker one-to-one mapping against inventory rows.
|
||||
|
||||
## Recommended Design
|
||||
### Architecture
|
||||
Use the gap inventory as the authoritative backlog. For each row, implement or complete the .NET equivalent, then attach test evidence and update the inventory status. Keep implementation inside existing category boundaries and only refactor when needed to match Go behavior.
|
||||
|
||||
### Components
|
||||
- **Backlog driver:** `gaps/core-server.md` (row-level tracking for all parity items).
|
||||
- **Implementation surface:** category-specific .NET source files.
|
||||
- **Verification surface:** category-specific .NET tests plus cross-module regression tests.
|
||||
- **Parity bookkeeping:** updates to `gaps/core-server.md` and `gaps/stillmissing.md` after each closure batch.
|
||||
|
||||
### Data Flow
|
||||
1. Read one `MISSING` or `PARTIAL` row from `gaps/core-server.md`.
|
||||
2. Inspect referenced Go implementation and tests.
|
||||
3. Add/adjust .NET implementation in listed category files.
|
||||
4. Add failing .NET tests that reproduce the missing/partial behavior, then make them pass.
|
||||
5. Re-run targeted and regression tests.
|
||||
6. Update the row to `PORTED` (or keep `PARTIAL` with explicit residual notes).
|
||||
|
||||
### Error Handling and Risk Controls
|
||||
- Avoid broad rewrites; prefer narrow patches tied to specific inventory rows.
|
||||
- Preserve protocol and timing semantics when replacing Go concurrency constructs with .NET async patterns.
|
||||
- Treat edge cases in Go tests as mandatory parity requirements unless explicitly marked `NOT_APPLICABLE`.
|
||||
- Require evidence (tests + inventory status updates) before declaring row completion.
|
||||
|
||||
### Testing Strategy
|
||||
- Add or expand tests for each row moved from `MISSING`/`PARTIAL` toward `PORTED`.
|
||||
- Prioritize wire/protocol compatibility, lifecycle transitions, auth boundaries, and backpressure/timeout behavior.
|
||||
- Keep category-targeted tests fast; run full `NATS.Server.Tests` regression before closure.
|
||||
|
||||
### Definition of Done
|
||||
- All category rows are either `PORTED` or explicitly justified `NOT_APPLICABLE`/`DEFERRED`.
|
||||
- No unresolved `MISSING` or unqualified `PARTIAL` rows remain for this category.
|
||||
- Relevant .NET tests pass locally and parity evidence is written into inventory notes.
|
||||
|
||||
## Implementation Scope Inputs
|
||||
### Go Source Files
|
||||
- `golang/nats-server/server/server.go`
|
||||
- `golang/nats-server/server/client.go`
|
||||
- `golang/nats-server/server/opts.go`
|
||||
- `golang/nats-server/server/reload.go`
|
||||
- `golang/nats-server/server/service.go`
|
||||
- `golang/nats-server/server/signal.go`
|
||||
- `golang/nats-server/main.go`
|
||||
|
||||
### Go Test Files
|
||||
- `golang/nats-server/server/server_test.go`
|
||||
- `golang/nats-server/server/client_test.go`
|
||||
- `golang/nats-server/server/opts_test.go`
|
||||
- `golang/nats-server/server/reload_test.go`
|
||||
- `golang/nats-server/server/signal_test.go`
|
||||
- `golang/nats-server/server/test_test.go (test helpers)`
|
||||
|
||||
### .NET Source Files
|
||||
- `src/NATS.Server/NatsServer.cs`
|
||||
- `src/NATS.Server/NatsClient.cs`
|
||||
- `src/NATS.Server/NatsOptions.cs`
|
||||
- `src/NATS.Server/ClientFlags.cs`
|
||||
- `src/NATS.Server/ClientKind.cs`
|
||||
- `src/NATS.Server/ClientClosedReason.cs`
|
||||
- `src/NATS.Server/ClientTraceInfo.cs`
|
||||
- `src/NATS.Server/ClosedState.cs`
|
||||
- `src/NATS.Server/INatsClient.cs`
|
||||
- `src/NATS.Server/InternalClient.cs`
|
||||
- `src/NATS.Server/ServerStats.cs`
|
||||
- `src/NATS.Server/SlowConsumerTracker.cs`
|
||||
- `src/NATS.Server/MqttOptions.cs`
|
||||
- `src/NATS.Server.Host/Program.cs`
|
||||
|
||||
### .NET Test Files
|
||||
- `tests/NATS.Server.Tests/ (root-level test files)`
|
||||
103
docs/plans/2026-02-25-gap-port-core-server-plan.md
Normal file
103
docs/plans/2026-02-25-gap-port-core-server-plan.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# Core Server Gap Port Implementation Plan
|
||||
|
||||
> **For Codex:** REQUIRED SUB-SKILL: Use `executeplan` to implement this plan task-by-task.
|
||||
|
||||
**Goal:** Port all remaining `core-server` gap inventory items to achieve full behavior parity with Go.
|
||||
|
||||
**Architecture:** Use the category gap inventory as the execution backlog. Drive work row-by-row from `MISSING` and `PARTIAL` toward `PORTED`, with test-first validation and explicit parity evidence in notes.
|
||||
|
||||
**Tech Stack:** .NET 10, C#, xUnit, existing `NATS.Server` runtime modules, Go NATS server reference source.
|
||||
|
||||
---
|
||||
|
||||
## Category Inputs
|
||||
- Gap Inventory: `gaps/core-server.md`
|
||||
- Primary .NET Source Anchor: `src/NATS.Server/NatsServer.cs`
|
||||
- Primary .NET Test Anchor: `tests/NATS.Server.Tests/ (root-level test files)`
|
||||
- Full .NET test project: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
## Task 1: Freeze Row-Level Backlog
|
||||
|
||||
**Files:**
|
||||
- Modify: `gaps/core-server.md`
|
||||
|
||||
**Step 1: Normalize open rows into an execution queue**
|
||||
- Split all `MISSING` and `PARTIAL` rows into ranked batches (highest runtime impact first).
|
||||
|
||||
**Step 2: Record acceptance criteria per row**
|
||||
- For each row, define exact behavioral parity checks (inputs, outputs, error paths, timing/concurrency expectations).
|
||||
|
||||
**Step 3: Save queue annotations in notes**
|
||||
- Add short execution-order markers in notes without changing status yet.
|
||||
|
||||
## Task 2: Write Failing Tests for Batch 1
|
||||
|
||||
**Files:**
|
||||
- Modify: `tests/NATS.Server.Tests/ (root-level test files)`
|
||||
- Test: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
**Step 1: Add failing tests for first open row batch**
|
||||
- Create tests that reproduce the exact missing/partial Go behavior.
|
||||
|
||||
**Step 2: Run tests to confirm failure**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: FAIL in newly added tests only.
|
||||
|
||||
## Task 3: Implement Minimal Parity for Batch 1
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/NATS.Server/NatsServer.cs`
|
||||
- Modify: additional category files listed in `gaps/core-server.md`
|
||||
|
||||
**Step 1: Implement minimal code to satisfy failing tests**
|
||||
- Mirror Go semantics for parsing, state transitions, limits, and side-effects required by the targeted rows.
|
||||
|
||||
**Step 2: Re-run tests for validation**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: PASS for batch-1 tests; no new regressions.
|
||||
|
||||
## Task 4: Close Remaining Batches Iteratively
|
||||
|
||||
**Files:**
|
||||
- Modify: category .NET source and test files referenced in `gaps/core-server.md`
|
||||
- Modify: `gaps/core-server.md`
|
||||
|
||||
**Step 1: Repeat test-first cycle for each remaining batch**
|
||||
- Add failing tests, implement minimal parity, then verify pass.
|
||||
|
||||
**Step 2: Update inventory status immediately after each closure**
|
||||
- Move rows to `PORTED` with exact .NET file:line references.
|
||||
- Keep `PARTIAL` only if explicit residual behavior remains.
|
||||
|
||||
## Task 5: Cross-Module Regression and Hardening
|
||||
|
||||
**Files:**
|
||||
- Test: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
**Step 1: Run full regression suite**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: PASS.
|
||||
|
||||
**Step 2: Add edge-case tests discovered during regression**
|
||||
- Capture any newly discovered divergence from Go and close it before completion.
|
||||
|
||||
## Task 6: Finalize Parity Bookkeeping
|
||||
|
||||
**Files:**
|
||||
- Modify: `gaps/core-server.md`
|
||||
- Modify: `gaps/stillmissing.md`
|
||||
|
||||
**Step 1: Ensure final status correctness**
|
||||
- Verify no unresolved `MISSING` rows remain for `core-server`.
|
||||
|
||||
**Step 2: Refresh LOC and percentage bookkeeping**
|
||||
- Recount category LOC and update summary rows in `gaps/stillmissing.md`.
|
||||
|
||||
**Step 3: Add concise changelog entry**
|
||||
- Record date, completed parity areas, and any justified deferred items.
|
||||
|
||||
## Completion Checklist
|
||||
- [ ] All prioritized `core-server` rows are `PORTED` or explicitly justified as `NOT_APPLICABLE`/`DEFERRED`.
|
||||
- [ ] New/updated tests demonstrate parity for all previously open rows.
|
||||
- [ ] `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release` passes.
|
||||
- [ ] `gaps/core-server.md` and `gaps/stillmissing.md` are fully synchronized.
|
||||
76
docs/plans/2026-02-25-gap-port-events-design.md
Normal file
76
docs/plans/2026-02-25-gap-port-events-design.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# Events Full Parity Design
|
||||
|
||||
**Date:** 2026-02-25
|
||||
**Category:** `events`
|
||||
**Gap Inventory:** `gaps/events.md`
|
||||
**Target Outcome:** Full Go-to-.NET behavioral parity for this category.
|
||||
|
||||
## Assumptions
|
||||
- Full parity is the required outcome.
|
||||
- No additional requirements gathering is needed for this pass.
|
||||
- Existing public .NET APIs are preserved unless parity requires targeted, documented adjustments.
|
||||
|
||||
## Current State Snapshot
|
||||
- `MISSING`: 154
|
||||
- `PARTIAL`: 20
|
||||
- `PORTED`: 42
|
||||
- `NOT_APPLICABLE`: 23
|
||||
- `DEFERRED`: 0
|
||||
- **Open parity work items:** 174
|
||||
|
||||
## Approaches Considered
|
||||
1. **Symbol-first closure (Recommended):** execute directly against each `MISSING` and `PARTIAL` row in `gaps/events.md`, closing items in deterministic order.
|
||||
Trade-off: strongest traceability and auditability, but can require broad context switching.
|
||||
2. **Test-first closure:** derive all work from Go test scenarios first, then backfill missing symbols.
|
||||
Trade-off: maximizes behavioral confidence, but can miss non-test-covered API and helper parity.
|
||||
3. **Vertical runtime slices:** port connect/auth/pubsub/cluster flows end-to-end before moving to next slice.
|
||||
Trade-off: smoother integration validation, but weaker one-to-one mapping against inventory rows.
|
||||
|
||||
## Recommended Design
|
||||
### Architecture
|
||||
Use the gap inventory as the authoritative backlog. For each row, implement or complete the .NET equivalent, then attach test evidence and update the inventory status. Keep implementation inside existing category boundaries and only refactor when needed to match Go behavior.
|
||||
|
||||
### Components
|
||||
- **Backlog driver:** `gaps/events.md` (row-level tracking for all parity items).
|
||||
- **Implementation surface:** category-specific .NET source files.
|
||||
- **Verification surface:** category-specific .NET tests plus cross-module regression tests.
|
||||
- **Parity bookkeeping:** updates to `gaps/events.md` and `gaps/stillmissing.md` after each closure batch.
|
||||
|
||||
### Data Flow
|
||||
1. Read one `MISSING` or `PARTIAL` row from `gaps/events.md`.
|
||||
2. Inspect referenced Go implementation and tests.
|
||||
3. Add/adjust .NET implementation in listed category files.
|
||||
4. Add failing .NET tests that reproduce the missing/partial behavior, then make them pass.
|
||||
5. Re-run targeted and regression tests.
|
||||
6. Update the row to `PORTED` (or keep `PARTIAL` with explicit residual notes).
|
||||
|
||||
### Error Handling and Risk Controls
|
||||
- Avoid broad rewrites; prefer narrow patches tied to specific inventory rows.
|
||||
- Preserve protocol and timing semantics when replacing Go concurrency constructs with .NET async patterns.
|
||||
- Treat edge cases in Go tests as mandatory parity requirements unless explicitly marked `NOT_APPLICABLE`.
|
||||
- Require evidence (tests + inventory status updates) before declaring row completion.
|
||||
|
||||
### Testing Strategy
|
||||
- Add or expand tests for each row moved from `MISSING`/`PARTIAL` toward `PORTED`.
|
||||
- Prioritize wire/protocol compatibility, lifecycle transitions, auth boundaries, and backpressure/timeout behavior.
|
||||
- Keep category-targeted tests fast; run full `NATS.Server.Tests` regression before closure.
|
||||
|
||||
### Definition of Done
|
||||
- All category rows are either `PORTED` or explicitly justified `NOT_APPLICABLE`/`DEFERRED`.
|
||||
- No unresolved `MISSING` or unqualified `PARTIAL` rows remain for this category.
|
||||
- Relevant .NET tests pass locally and parity evidence is written into inventory notes.
|
||||
|
||||
## Implementation Scope Inputs
|
||||
### Go Source Files
|
||||
- `golang/nats-server/server/events.go`
|
||||
- `golang/nats-server/server/msgtrace.go`
|
||||
|
||||
### Go Test Files
|
||||
- `golang/nats-server/server/events_test.go`
|
||||
- `golang/nats-server/server/msgtrace_test.go`
|
||||
|
||||
### .NET Source Files
|
||||
- `src/NATS.Server/Events/ (all files)`
|
||||
|
||||
### .NET Test Files
|
||||
- `tests/NATS.Server.Tests/Events/`
|
||||
103
docs/plans/2026-02-25-gap-port-events-plan.md
Normal file
103
docs/plans/2026-02-25-gap-port-events-plan.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# Events Gap Port Implementation Plan
|
||||
|
||||
> **For Codex:** REQUIRED SUB-SKILL: Use `executeplan` to implement this plan task-by-task.
|
||||
|
||||
**Goal:** Port all remaining `events` gap inventory items to achieve full behavior parity with Go.
|
||||
|
||||
**Architecture:** Use the category gap inventory as the execution backlog. Drive work row-by-row from `MISSING` and `PARTIAL` toward `PORTED`, with test-first validation and explicit parity evidence in notes.
|
||||
|
||||
**Tech Stack:** .NET 10, C#, xUnit, existing `NATS.Server` runtime modules, Go NATS server reference source.
|
||||
|
||||
---
|
||||
|
||||
## Category Inputs
|
||||
- Gap Inventory: `gaps/events.md`
|
||||
- Primary .NET Source Anchor: `src/NATS.Server/Events/ (all files)`
|
||||
- Primary .NET Test Anchor: `tests/NATS.Server.Tests/Events/`
|
||||
- Full .NET test project: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
## Task 1: Freeze Row-Level Backlog
|
||||
|
||||
**Files:**
|
||||
- Modify: `gaps/events.md`
|
||||
|
||||
**Step 1: Normalize open rows into an execution queue**
|
||||
- Split all `MISSING` and `PARTIAL` rows into ranked batches (highest runtime impact first).
|
||||
|
||||
**Step 2: Record acceptance criteria per row**
|
||||
- For each row, define exact behavioral parity checks (inputs, outputs, error paths, timing/concurrency expectations).
|
||||
|
||||
**Step 3: Save queue annotations in notes**
|
||||
- Add short execution-order markers in notes without changing status yet.
|
||||
|
||||
## Task 2: Write Failing Tests for Batch 1
|
||||
|
||||
**Files:**
|
||||
- Modify: `tests/NATS.Server.Tests/Events/`
|
||||
- Test: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
**Step 1: Add failing tests for first open row batch**
|
||||
- Create tests that reproduce the exact missing/partial Go behavior.
|
||||
|
||||
**Step 2: Run tests to confirm failure**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: FAIL in newly added tests only.
|
||||
|
||||
## Task 3: Implement Minimal Parity for Batch 1
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/NATS.Server/Events/ (all files)`
|
||||
- Modify: additional category files listed in `gaps/events.md`
|
||||
|
||||
**Step 1: Implement minimal code to satisfy failing tests**
|
||||
- Mirror Go semantics for parsing, state transitions, limits, and side-effects required by the targeted rows.
|
||||
|
||||
**Step 2: Re-run tests for validation**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: PASS for batch-1 tests; no new regressions.
|
||||
|
||||
## Task 4: Close Remaining Batches Iteratively
|
||||
|
||||
**Files:**
|
||||
- Modify: category .NET source and test files referenced in `gaps/events.md`
|
||||
- Modify: `gaps/events.md`
|
||||
|
||||
**Step 1: Repeat test-first cycle for each remaining batch**
|
||||
- Add failing tests, implement minimal parity, then verify pass.
|
||||
|
||||
**Step 2: Update inventory status immediately after each closure**
|
||||
- Move rows to `PORTED` with exact .NET file:line references.
|
||||
- Keep `PARTIAL` only if explicit residual behavior remains.
|
||||
|
||||
## Task 5: Cross-Module Regression and Hardening
|
||||
|
||||
**Files:**
|
||||
- Test: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
**Step 1: Run full regression suite**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: PASS.
|
||||
|
||||
**Step 2: Add edge-case tests discovered during regression**
|
||||
- Capture any newly discovered divergence from Go and close it before completion.
|
||||
|
||||
## Task 6: Finalize Parity Bookkeeping
|
||||
|
||||
**Files:**
|
||||
- Modify: `gaps/events.md`
|
||||
- Modify: `gaps/stillmissing.md`
|
||||
|
||||
**Step 1: Ensure final status correctness**
|
||||
- Verify no unresolved `MISSING` rows remain for `events`.
|
||||
|
||||
**Step 2: Refresh LOC and percentage bookkeeping**
|
||||
- Recount category LOC and update summary rows in `gaps/stillmissing.md`.
|
||||
|
||||
**Step 3: Add concise changelog entry**
|
||||
- Record date, completed parity areas, and any justified deferred items.
|
||||
|
||||
## Completion Checklist
|
||||
- [ ] All prioritized `events` rows are `PORTED` or explicitly justified as `NOT_APPLICABLE`/`DEFERRED`.
|
||||
- [ ] New/updated tests demonstrate parity for all previously open rows.
|
||||
- [ ] `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release` passes.
|
||||
- [ ] `gaps/events.md` and `gaps/stillmissing.md` are fully synchronized.
|
||||
75
docs/plans/2026-02-25-gap-port-gateways-design.md
Normal file
75
docs/plans/2026-02-25-gap-port-gateways-design.md
Normal file
@@ -0,0 +1,75 @@
|
||||
# Gateways Full Parity Design
|
||||
|
||||
**Date:** 2026-02-25
|
||||
**Category:** `gateways`
|
||||
**Gap Inventory:** `gaps/gateways.md`
|
||||
**Target Outcome:** Full Go-to-.NET behavioral parity for this category.
|
||||
|
||||
## Assumptions
|
||||
- Full parity is the required outcome.
|
||||
- No additional requirements gathering is needed for this pass.
|
||||
- Existing public .NET APIs are preserved unless parity requires targeted, documented adjustments.
|
||||
|
||||
## Current State Snapshot
|
||||
- `MISSING`: 57
|
||||
- `PARTIAL`: 37
|
||||
- `PORTED`: 10
|
||||
- `NOT_APPLICABLE`: 4
|
||||
- `DEFERRED`: 0
|
||||
- **Open parity work items:** 94
|
||||
|
||||
## Approaches Considered
|
||||
1. **Symbol-first closure (Recommended):** execute directly against each `MISSING` and `PARTIAL` row in `gaps/gateways.md`, closing items in deterministic order.
|
||||
Trade-off: strongest traceability and auditability, but can require broad context switching.
|
||||
2. **Test-first closure:** derive all work from Go test scenarios first, then backfill missing symbols.
|
||||
Trade-off: maximizes behavioral confidence, but can miss non-test-covered API and helper parity.
|
||||
3. **Vertical runtime slices:** port connect/auth/pubsub/cluster flows end-to-end before moving to next slice.
|
||||
Trade-off: smoother integration validation, but weaker one-to-one mapping against inventory rows.
|
||||
|
||||
## Recommended Design
|
||||
### Architecture
|
||||
Use the gap inventory as the authoritative backlog. For each row, implement or complete the .NET equivalent, then attach test evidence and update the inventory status. Keep implementation inside existing category boundaries and only refactor when needed to match Go behavior.
|
||||
|
||||
### Components
|
||||
- **Backlog driver:** `gaps/gateways.md` (row-level tracking for all parity items).
|
||||
- **Implementation surface:** category-specific .NET source files.
|
||||
- **Verification surface:** category-specific .NET tests plus cross-module regression tests.
|
||||
- **Parity bookkeeping:** updates to `gaps/gateways.md` and `gaps/stillmissing.md` after each closure batch.
|
||||
|
||||
### Data Flow
|
||||
1. Read one `MISSING` or `PARTIAL` row from `gaps/gateways.md`.
|
||||
2. Inspect referenced Go implementation and tests.
|
||||
3. Add/adjust .NET implementation in listed category files.
|
||||
4. Add failing .NET tests that reproduce the missing/partial behavior, then make them pass.
|
||||
5. Re-run targeted and regression tests.
|
||||
6. Update the row to `PORTED` (or keep `PARTIAL` with explicit residual notes).
|
||||
|
||||
### Error Handling and Risk Controls
|
||||
- Avoid broad rewrites; prefer narrow patches tied to specific inventory rows.
|
||||
- Preserve protocol and timing semantics when replacing Go concurrency constructs with .NET async patterns.
|
||||
- Treat edge cases in Go tests as mandatory parity requirements unless explicitly marked `NOT_APPLICABLE`.
|
||||
- Require evidence (tests + inventory status updates) before declaring row completion.
|
||||
|
||||
### Testing Strategy
|
||||
- Add or expand tests for each row moved from `MISSING`/`PARTIAL` toward `PORTED`.
|
||||
- Prioritize wire/protocol compatibility, lifecycle transitions, auth boundaries, and backpressure/timeout behavior.
|
||||
- Keep category-targeted tests fast; run full `NATS.Server.Tests` regression before closure.
|
||||
|
||||
### Definition of Done
|
||||
- All category rows are either `PORTED` or explicitly justified `NOT_APPLICABLE`/`DEFERRED`.
|
||||
- No unresolved `MISSING` or unqualified `PARTIAL` rows remain for this category.
|
||||
- Relevant .NET tests pass locally and parity evidence is written into inventory notes.
|
||||
|
||||
## Implementation Scope Inputs
|
||||
### Go Source Files
|
||||
- `golang/nats-server/server/gateway.go`
|
||||
|
||||
### Go Test Files
|
||||
- `golang/nats-server/server/gateway_test.go`
|
||||
- `golang/nats-server/test/gateway_test.go (integration)`
|
||||
|
||||
### .NET Source Files
|
||||
- `src/NATS.Server/Gateways/ (all files)`
|
||||
|
||||
### .NET Test Files
|
||||
- `tests/NATS.Server.Tests/Gateways/`
|
||||
103
docs/plans/2026-02-25-gap-port-gateways-plan.md
Normal file
103
docs/plans/2026-02-25-gap-port-gateways-plan.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# Gateways Gap Port Implementation Plan
|
||||
|
||||
> **For Codex:** REQUIRED SUB-SKILL: Use `executeplan` to implement this plan task-by-task.
|
||||
|
||||
**Goal:** Port all remaining `gateways` gap inventory items to achieve full behavior parity with Go.
|
||||
|
||||
**Architecture:** Use the category gap inventory as the execution backlog. Drive work row-by-row from `MISSING` and `PARTIAL` toward `PORTED`, with test-first validation and explicit parity evidence in notes.
|
||||
|
||||
**Tech Stack:** .NET 10, C#, xUnit, existing `NATS.Server` runtime modules, Go NATS server reference source.
|
||||
|
||||
---
|
||||
|
||||
## Category Inputs
|
||||
- Gap Inventory: `gaps/gateways.md`
|
||||
- Primary .NET Source Anchor: `src/NATS.Server/Gateways/ (all files)`
|
||||
- Primary .NET Test Anchor: `tests/NATS.Server.Tests/Gateways/`
|
||||
- Full .NET test project: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
## Task 1: Freeze Row-Level Backlog
|
||||
|
||||
**Files:**
|
||||
- Modify: `gaps/gateways.md`
|
||||
|
||||
**Step 1: Normalize open rows into an execution queue**
|
||||
- Split all `MISSING` and `PARTIAL` rows into ranked batches (highest runtime impact first).
|
||||
|
||||
**Step 2: Record acceptance criteria per row**
|
||||
- For each row, define exact behavioral parity checks (inputs, outputs, error paths, timing/concurrency expectations).
|
||||
|
||||
**Step 3: Save queue annotations in notes**
|
||||
- Add short execution-order markers in notes without changing status yet.
|
||||
|
||||
## Task 2: Write Failing Tests for Batch 1
|
||||
|
||||
**Files:**
|
||||
- Modify: `tests/NATS.Server.Tests/Gateways/`
|
||||
- Test: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
**Step 1: Add failing tests for first open row batch**
|
||||
- Create tests that reproduce the exact missing/partial Go behavior.
|
||||
|
||||
**Step 2: Run tests to confirm failure**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: FAIL in newly added tests only.
|
||||
|
||||
## Task 3: Implement Minimal Parity for Batch 1
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/NATS.Server/Gateways/ (all files)`
|
||||
- Modify: additional category files listed in `gaps/gateways.md`
|
||||
|
||||
**Step 1: Implement minimal code to satisfy failing tests**
|
||||
- Mirror Go semantics for parsing, state transitions, limits, and side-effects required by the targeted rows.
|
||||
|
||||
**Step 2: Re-run tests for validation**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: PASS for batch-1 tests; no new regressions.
|
||||
|
||||
## Task 4: Close Remaining Batches Iteratively
|
||||
|
||||
**Files:**
|
||||
- Modify: category .NET source and test files referenced in `gaps/gateways.md`
|
||||
- Modify: `gaps/gateways.md`
|
||||
|
||||
**Step 1: Repeat test-first cycle for each remaining batch**
|
||||
- Add failing tests, implement minimal parity, then verify pass.
|
||||
|
||||
**Step 2: Update inventory status immediately after each closure**
|
||||
- Move rows to `PORTED` with exact .NET file:line references.
|
||||
- Keep `PARTIAL` only if explicit residual behavior remains.
|
||||
|
||||
## Task 5: Cross-Module Regression and Hardening
|
||||
|
||||
**Files:**
|
||||
- Test: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
**Step 1: Run full regression suite**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: PASS.
|
||||
|
||||
**Step 2: Add edge-case tests discovered during regression**
|
||||
- Capture any newly discovered divergence from Go and close it before completion.
|
||||
|
||||
## Task 6: Finalize Parity Bookkeeping
|
||||
|
||||
**Files:**
|
||||
- Modify: `gaps/gateways.md`
|
||||
- Modify: `gaps/stillmissing.md`
|
||||
|
||||
**Step 1: Ensure final status correctness**
|
||||
- Verify no unresolved `MISSING` rows remain for `gateways`.
|
||||
|
||||
**Step 2: Refresh LOC and percentage bookkeeping**
|
||||
- Recount category LOC and update summary rows in `gaps/stillmissing.md`.
|
||||
|
||||
**Step 3: Add concise changelog entry**
|
||||
- Record date, completed parity areas, and any justified deferred items.
|
||||
|
||||
## Completion Checklist
|
||||
- [ ] All prioritized `gateways` rows are `PORTED` or explicitly justified as `NOT_APPLICABLE`/`DEFERRED`.
|
||||
- [ ] New/updated tests demonstrate parity for all previously open rows.
|
||||
- [ ] `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release` passes.
|
||||
- [ ] `gaps/gateways.md` and `gaps/stillmissing.md` are fully synchronized.
|
||||
86
docs/plans/2026-02-25-gap-port-internal-ds-design.md
Normal file
86
docs/plans/2026-02-25-gap-port-internal-ds-design.md
Normal file
@@ -0,0 +1,86 @@
|
||||
# Internal Data Structures Full Parity Design
|
||||
|
||||
**Date:** 2026-02-25
|
||||
**Category:** `internal-ds`
|
||||
**Gap Inventory:** `gaps/internal-ds.md`
|
||||
**Target Outcome:** Full Go-to-.NET behavioral parity for this category.
|
||||
|
||||
## Assumptions
|
||||
- Full parity is the required outcome.
|
||||
- No additional requirements gathering is needed for this pass.
|
||||
- Existing public .NET APIs are preserved unless parity requires targeted, documented adjustments.
|
||||
|
||||
## Current State Snapshot
|
||||
- `MISSING`: 10
|
||||
- `PARTIAL`: 4
|
||||
- `PORTED`: 157
|
||||
- `NOT_APPLICABLE`: 8
|
||||
- `DEFERRED`: 0
|
||||
- **Open parity work items:** 14
|
||||
|
||||
## Approaches Considered
|
||||
1. **Symbol-first closure (Recommended):** execute directly against each `MISSING` and `PARTIAL` row in `gaps/internal-ds.md`, closing items in deterministic order.
|
||||
Trade-off: strongest traceability and auditability, but can require broad context switching.
|
||||
2. **Test-first closure:** derive all work from Go test scenarios first, then backfill missing symbols.
|
||||
Trade-off: maximizes behavioral confidence, but can miss non-test-covered API and helper parity.
|
||||
3. **Vertical runtime slices:** port connect/auth/pubsub/cluster flows end-to-end before moving to next slice.
|
||||
Trade-off: smoother integration validation, but weaker one-to-one mapping against inventory rows.
|
||||
|
||||
## Recommended Design
|
||||
### Architecture
|
||||
Use the gap inventory as the authoritative backlog. For each row, implement or complete the .NET equivalent, then attach test evidence and update the inventory status. Keep implementation inside existing category boundaries and only refactor when needed to match Go behavior.
|
||||
|
||||
### Components
|
||||
- **Backlog driver:** `gaps/internal-ds.md` (row-level tracking for all parity items).
|
||||
- **Implementation surface:** category-specific .NET source files.
|
||||
- **Verification surface:** category-specific .NET tests plus cross-module regression tests.
|
||||
- **Parity bookkeeping:** updates to `gaps/internal-ds.md` and `gaps/stillmissing.md` after each closure batch.
|
||||
|
||||
### Data Flow
|
||||
1. Read one `MISSING` or `PARTIAL` row from `gaps/internal-ds.md`.
|
||||
2. Inspect referenced Go implementation and tests.
|
||||
3. Add/adjust .NET implementation in listed category files.
|
||||
4. Add failing .NET tests that reproduce the missing/partial behavior, then make them pass.
|
||||
5. Re-run targeted and regression tests.
|
||||
6. Update the row to `PORTED` (or keep `PARTIAL` with explicit residual notes).
|
||||
|
||||
### Error Handling and Risk Controls
|
||||
- Avoid broad rewrites; prefer narrow patches tied to specific inventory rows.
|
||||
- Preserve protocol and timing semantics when replacing Go concurrency constructs with .NET async patterns.
|
||||
- Treat edge cases in Go tests as mandatory parity requirements unless explicitly marked `NOT_APPLICABLE`.
|
||||
- Require evidence (tests + inventory status updates) before declaring row completion.
|
||||
|
||||
### Testing Strategy
|
||||
- Add or expand tests for each row moved from `MISSING`/`PARTIAL` toward `PORTED`.
|
||||
- Prioritize wire/protocol compatibility, lifecycle transitions, auth boundaries, and backpressure/timeout behavior.
|
||||
- Keep category-targeted tests fast; run full `NATS.Server.Tests` regression before closure.
|
||||
|
||||
### Definition of Done
|
||||
- All category rows are either `PORTED` or explicitly justified `NOT_APPLICABLE`/`DEFERRED`.
|
||||
- No unresolved `MISSING` or unqualified `PARTIAL` rows remain for this category.
|
||||
- Relevant .NET tests pass locally and parity evidence is written into inventory notes.
|
||||
|
||||
## Implementation Scope Inputs
|
||||
### Go Source Files
|
||||
- `golang/nats-server/server/avl/seqset.go`
|
||||
- `golang/nats-server/server/stree/`
|
||||
- `golang/nats-server/server/thw/thw.go`
|
||||
- `golang/nats-server/server/gsl/gsl.go`
|
||||
- `golang/nats-server/server/pse/`
|
||||
- `golang/nats-server/server/sysmem/`
|
||||
|
||||
### Go Test Files
|
||||
- `golang/nats-server/server/avl/seqset_test.go`
|
||||
- `golang/nats-server/server/stree/stree_test.go`
|
||||
- `golang/nats-server/server/thw/thw_test.go`
|
||||
- `golang/nats-server/server/gsl/gsl_test.go`
|
||||
|
||||
### .NET Source Files
|
||||
- `src/NATS.Server/Internal/ (all files including subdirectories)`
|
||||
- `src/NATS.Server/Internal/Avl/`
|
||||
- `src/NATS.Server/Internal/Gsl/`
|
||||
- `src/NATS.Server/Internal/SubjectTree/`
|
||||
- `src/NATS.Server/Internal/TimeHashWheel/`
|
||||
|
||||
### .NET Test Files
|
||||
- `tests/NATS.Server.Tests/Internal/ (all subdirectories)`
|
||||
103
docs/plans/2026-02-25-gap-port-internal-ds-plan.md
Normal file
103
docs/plans/2026-02-25-gap-port-internal-ds-plan.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# Internal Data Structures Gap Port Implementation Plan
|
||||
|
||||
> **For Codex:** REQUIRED SUB-SKILL: Use `executeplan` to implement this plan task-by-task.
|
||||
|
||||
**Goal:** Port all remaining `internal-ds` gap inventory items to achieve full behavior parity with Go.
|
||||
|
||||
**Architecture:** Use the category gap inventory as the execution backlog. Drive work row-by-row from `MISSING` and `PARTIAL` toward `PORTED`, with test-first validation and explicit parity evidence in notes.
|
||||
|
||||
**Tech Stack:** .NET 10, C#, xUnit, existing `NATS.Server` runtime modules, Go NATS server reference source.
|
||||
|
||||
---
|
||||
|
||||
## Category Inputs
|
||||
- Gap Inventory: `gaps/internal-ds.md`
|
||||
- Primary .NET Source Anchor: `src/NATS.Server/Internal/ (all files including subdirectories)`
|
||||
- Primary .NET Test Anchor: `tests/NATS.Server.Tests/Internal/ (all subdirectories)`
|
||||
- Full .NET test project: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
## Task 1: Freeze Row-Level Backlog
|
||||
|
||||
**Files:**
|
||||
- Modify: `gaps/internal-ds.md`
|
||||
|
||||
**Step 1: Normalize open rows into an execution queue**
|
||||
- Split all `MISSING` and `PARTIAL` rows into ranked batches (highest runtime impact first).
|
||||
|
||||
**Step 2: Record acceptance criteria per row**
|
||||
- For each row, define exact behavioral parity checks (inputs, outputs, error paths, timing/concurrency expectations).
|
||||
|
||||
**Step 3: Save queue annotations in notes**
|
||||
- Add short execution-order markers in notes without changing status yet.
|
||||
|
||||
## Task 2: Write Failing Tests for Batch 1
|
||||
|
||||
**Files:**
|
||||
- Modify: `tests/NATS.Server.Tests/Internal/ (all subdirectories)`
|
||||
- Test: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
**Step 1: Add failing tests for first open row batch**
|
||||
- Create tests that reproduce the exact missing/partial Go behavior.
|
||||
|
||||
**Step 2: Run tests to confirm failure**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: FAIL in newly added tests only.
|
||||
|
||||
## Task 3: Implement Minimal Parity for Batch 1
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/NATS.Server/Internal/ (all files including subdirectories)`
|
||||
- Modify: additional category files listed in `gaps/internal-ds.md`
|
||||
|
||||
**Step 1: Implement minimal code to satisfy failing tests**
|
||||
- Mirror Go semantics for parsing, state transitions, limits, and side-effects required by the targeted rows.
|
||||
|
||||
**Step 2: Re-run tests for validation**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: PASS for batch-1 tests; no new regressions.
|
||||
|
||||
## Task 4: Close Remaining Batches Iteratively
|
||||
|
||||
**Files:**
|
||||
- Modify: category .NET source and test files referenced in `gaps/internal-ds.md`
|
||||
- Modify: `gaps/internal-ds.md`
|
||||
|
||||
**Step 1: Repeat test-first cycle for each remaining batch**
|
||||
- Add failing tests, implement minimal parity, then verify pass.
|
||||
|
||||
**Step 2: Update inventory status immediately after each closure**
|
||||
- Move rows to `PORTED` with exact .NET file:line references.
|
||||
- Keep `PARTIAL` only if explicit residual behavior remains.
|
||||
|
||||
## Task 5: Cross-Module Regression and Hardening
|
||||
|
||||
**Files:**
|
||||
- Test: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
**Step 1: Run full regression suite**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: PASS.
|
||||
|
||||
**Step 2: Add edge-case tests discovered during regression**
|
||||
- Capture any newly discovered divergence from Go and close it before completion.
|
||||
|
||||
## Task 6: Finalize Parity Bookkeeping
|
||||
|
||||
**Files:**
|
||||
- Modify: `gaps/internal-ds.md`
|
||||
- Modify: `gaps/stillmissing.md`
|
||||
|
||||
**Step 1: Ensure final status correctness**
|
||||
- Verify no unresolved `MISSING` rows remain for `internal-ds`.
|
||||
|
||||
**Step 2: Refresh LOC and percentage bookkeeping**
|
||||
- Recount category LOC and update summary rows in `gaps/stillmissing.md`.
|
||||
|
||||
**Step 3: Add concise changelog entry**
|
||||
- Record date, completed parity areas, and any justified deferred items.
|
||||
|
||||
## Completion Checklist
|
||||
- [ ] All prioritized `internal-ds` rows are `PORTED` or explicitly justified as `NOT_APPLICABLE`/`DEFERRED`.
|
||||
- [ ] New/updated tests demonstrate parity for all previously open rows.
|
||||
- [ ] `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release` passes.
|
||||
- [ ] `gaps/internal-ds.md` and `gaps/stillmissing.md` are fully synchronized.
|
||||
121
docs/plans/2026-02-25-gap-port-jetstream-design.md
Normal file
121
docs/plans/2026-02-25-gap-port-jetstream-design.md
Normal file
@@ -0,0 +1,121 @@
|
||||
# JetStream Full Parity Design
|
||||
|
||||
**Date:** 2026-02-25
|
||||
**Category:** `jetstream`
|
||||
**Gap Inventory:** `gaps/jetstream.md`
|
||||
**Target Outcome:** Full Go-to-.NET behavioral parity for this category.
|
||||
|
||||
## Assumptions
|
||||
- Full parity is the required outcome.
|
||||
- No additional requirements gathering is needed for this pass.
|
||||
- Existing public .NET APIs are preserved unless parity requires targeted, documented adjustments.
|
||||
|
||||
## Current State Snapshot
|
||||
- `MISSING`: 787
|
||||
- `PARTIAL`: 313
|
||||
- `PORTED`: 309
|
||||
- `NOT_APPLICABLE`: 55
|
||||
- `DEFERRED`: 0
|
||||
- **Open parity work items:** 1100
|
||||
|
||||
## Approaches Considered
|
||||
1. **Symbol-first closure (Recommended):** execute directly against each `MISSING` and `PARTIAL` row in `gaps/jetstream.md`, closing items in deterministic order.
|
||||
Trade-off: strongest traceability and auditability, but can require broad context switching.
|
||||
2. **Test-first closure:** derive all work from Go test scenarios first, then backfill missing symbols.
|
||||
Trade-off: maximizes behavioral confidence, but can miss non-test-covered API and helper parity.
|
||||
3. **Vertical runtime slices:** port connect/auth/pubsub/cluster flows end-to-end before moving to next slice.
|
||||
Trade-off: smoother integration validation, but weaker one-to-one mapping against inventory rows.
|
||||
|
||||
## Recommended Design
|
||||
### Architecture
|
||||
Use the gap inventory as the authoritative backlog. For each row, implement or complete the .NET equivalent, then attach test evidence and update the inventory status. Keep implementation inside existing category boundaries and only refactor when needed to match Go behavior.
|
||||
|
||||
### Components
|
||||
- **Backlog driver:** `gaps/jetstream.md` (row-level tracking for all parity items).
|
||||
- **Implementation surface:** category-specific .NET source files.
|
||||
- **Verification surface:** category-specific .NET tests plus cross-module regression tests.
|
||||
- **Parity bookkeeping:** updates to `gaps/jetstream.md` and `gaps/stillmissing.md` after each closure batch.
|
||||
|
||||
### Data Flow
|
||||
1. Read one `MISSING` or `PARTIAL` row from `gaps/jetstream.md`.
|
||||
2. Inspect referenced Go implementation and tests.
|
||||
3. Add/adjust .NET implementation in listed category files.
|
||||
4. Add failing .NET tests that reproduce the missing/partial behavior, then make them pass.
|
||||
5. Re-run targeted and regression tests.
|
||||
6. Update the row to `PORTED` (or keep `PARTIAL` with explicit residual notes).
|
||||
|
||||
### Error Handling and Risk Controls
|
||||
- Avoid broad rewrites; prefer narrow patches tied to specific inventory rows.
|
||||
- Preserve protocol and timing semantics when replacing Go concurrency constructs with .NET async patterns.
|
||||
- Treat edge cases in Go tests as mandatory parity requirements unless explicitly marked `NOT_APPLICABLE`.
|
||||
- Require evidence (tests + inventory status updates) before declaring row completion.
|
||||
|
||||
### Testing Strategy
|
||||
- Add or expand tests for each row moved from `MISSING`/`PARTIAL` toward `PORTED`.
|
||||
- Prioritize wire/protocol compatibility, lifecycle transitions, auth boundaries, and backpressure/timeout behavior.
|
||||
- Keep category-targeted tests fast; run full `NATS.Server.Tests` regression before closure.
|
||||
|
||||
### Definition of Done
|
||||
- All category rows are either `PORTED` or explicitly justified `NOT_APPLICABLE`/`DEFERRED`.
|
||||
- No unresolved `MISSING` or unqualified `PARTIAL` rows remain for this category.
|
||||
- Relevant .NET tests pass locally and parity evidence is written into inventory notes.
|
||||
|
||||
## Implementation Scope Inputs
|
||||
### Go Source Files
|
||||
- `golang/nats-server/server/jetstream.go`
|
||||
- `golang/nats-server/server/jetstream_api.go`
|
||||
- `golang/nats-server/server/jetstream_events.go`
|
||||
- `golang/nats-server/server/jetstream_errors.go`
|
||||
- `golang/nats-server/server/jetstream_errors_generated.go`
|
||||
- `golang/nats-server/server/jetstream_batching.go`
|
||||
- `golang/nats-server/server/jetstream_versioning.go`
|
||||
- `golang/nats-server/server/stream.go`
|
||||
- `golang/nats-server/server/consumer.go`
|
||||
- `golang/nats-server/server/store.go`
|
||||
- `golang/nats-server/server/filestore.go`
|
||||
- `golang/nats-server/server/memstore.go`
|
||||
- `golang/nats-server/server/dirstore.go`
|
||||
- `golang/nats-server/server/disk_avail.go`
|
||||
- `golang/nats-server/server/jetstream_cluster.go`
|
||||
|
||||
### Go Test Files
|
||||
- `golang/nats-server/server/jetstream_test.go`
|
||||
- `golang/nats-server/server/jetstream_consumer_test.go`
|
||||
- `golang/nats-server/server/jetstream_errors_test.go`
|
||||
- `golang/nats-server/server/jetstream_batching_test.go`
|
||||
- `golang/nats-server/server/jetstream_versioning_test.go`
|
||||
- `golang/nats-server/server/jetstream_helpers_test.go`
|
||||
- `golang/nats-server/server/jetstream_jwt_test.go`
|
||||
- `golang/nats-server/server/jetstream_tpm_test.go`
|
||||
- `golang/nats-server/server/jetstream_sourcing_scaling_test.go`
|
||||
- `golang/nats-server/server/jetstream_benchmark_test.go`
|
||||
- `golang/nats-server/server/filestore_test.go`
|
||||
- `golang/nats-server/server/memstore_test.go`
|
||||
- `golang/nats-server/server/dirstore_test.go`
|
||||
- `golang/nats-server/server/store_test.go`
|
||||
- `golang/nats-server/server/jetstream_cluster_1_test.go through _4_test.go`
|
||||
- `golang/nats-server/server/jetstream_super_cluster_test.go`
|
||||
- `golang/nats-server/server/jetstream_leafnode_test.go`
|
||||
- `golang/nats-server/server/jetstream_cluster_long_test.go`
|
||||
|
||||
### .NET Source Files
|
||||
- `src/NATS.Server/JetStream/`
|
||||
- `src/NATS.Server/JetStream/Api/`
|
||||
- `src/NATS.Server/JetStream/Consumers/`
|
||||
- `src/NATS.Server/JetStream/Models/`
|
||||
- `src/NATS.Server/JetStream/MirrorSource/`
|
||||
- `src/NATS.Server/JetStream/Publish/`
|
||||
- `src/NATS.Server/JetStream/Snapshots/`
|
||||
- `src/NATS.Server/JetStream/Validation/`
|
||||
- `src/NATS.Server/JetStream/Storage/`
|
||||
- `src/NATS.Server/JetStream/Cluster/`
|
||||
|
||||
### .NET Test Files
|
||||
- `tests/NATS.Server.Tests/JetStream/`
|
||||
- `tests/NATS.Server.Tests/JetStream/Api/`
|
||||
- `tests/NATS.Server.Tests/JetStream/Cluster/`
|
||||
- `tests/NATS.Server.Tests/JetStream/Consumers/`
|
||||
- `tests/NATS.Server.Tests/JetStream/MirrorSource/`
|
||||
- `tests/NATS.Server.Tests/JetStream/Snapshots/`
|
||||
- `tests/NATS.Server.Tests/JetStream/Storage/`
|
||||
- `tests/NATS.Server.Tests/JetStream/Streams/`
|
||||
103
docs/plans/2026-02-25-gap-port-jetstream-plan.md
Normal file
103
docs/plans/2026-02-25-gap-port-jetstream-plan.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# JetStream Gap Port Implementation Plan
|
||||
|
||||
> **For Codex:** REQUIRED SUB-SKILL: Use `executeplan` to implement this plan task-by-task.
|
||||
|
||||
**Goal:** Port all remaining `jetstream` gap inventory items to achieve full behavior parity with Go.
|
||||
|
||||
**Architecture:** Use the category gap inventory as the execution backlog. Drive work row-by-row from `MISSING` and `PARTIAL` toward `PORTED`, with test-first validation and explicit parity evidence in notes.
|
||||
|
||||
**Tech Stack:** .NET 10, C#, xUnit, existing `NATS.Server` runtime modules, Go NATS server reference source.
|
||||
|
||||
---
|
||||
|
||||
## Category Inputs
|
||||
- Gap Inventory: `gaps/jetstream.md`
|
||||
- Primary .NET Source Anchor: `src/NATS.Server/JetStream/`
|
||||
- Primary .NET Test Anchor: `tests/NATS.Server.Tests/JetStream/`
|
||||
- Full .NET test project: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
## Task 1: Freeze Row-Level Backlog
|
||||
|
||||
**Files:**
|
||||
- Modify: `gaps/jetstream.md`
|
||||
|
||||
**Step 1: Normalize open rows into an execution queue**
|
||||
- Split all `MISSING` and `PARTIAL` rows into ranked batches (highest runtime impact first).
|
||||
|
||||
**Step 2: Record acceptance criteria per row**
|
||||
- For each row, define exact behavioral parity checks (inputs, outputs, error paths, timing/concurrency expectations).
|
||||
|
||||
**Step 3: Save queue annotations in notes**
|
||||
- Add short execution-order markers in notes without changing status yet.
|
||||
|
||||
## Task 2: Write Failing Tests for Batch 1
|
||||
|
||||
**Files:**
|
||||
- Modify: `tests/NATS.Server.Tests/JetStream/`
|
||||
- Test: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
**Step 1: Add failing tests for first open row batch**
|
||||
- Create tests that reproduce the exact missing/partial Go behavior.
|
||||
|
||||
**Step 2: Run tests to confirm failure**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: FAIL in newly added tests only.
|
||||
|
||||
## Task 3: Implement Minimal Parity for Batch 1
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/NATS.Server/JetStream/`
|
||||
- Modify: additional category files listed in `gaps/jetstream.md`
|
||||
|
||||
**Step 1: Implement minimal code to satisfy failing tests**
|
||||
- Mirror Go semantics for parsing, state transitions, limits, and side-effects required by the targeted rows.
|
||||
|
||||
**Step 2: Re-run tests for validation**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: PASS for batch-1 tests; no new regressions.
|
||||
|
||||
## Task 4: Close Remaining Batches Iteratively
|
||||
|
||||
**Files:**
|
||||
- Modify: category .NET source and test files referenced in `gaps/jetstream.md`
|
||||
- Modify: `gaps/jetstream.md`
|
||||
|
||||
**Step 1: Repeat test-first cycle for each remaining batch**
|
||||
- Add failing tests, implement minimal parity, then verify pass.
|
||||
|
||||
**Step 2: Update inventory status immediately after each closure**
|
||||
- Move rows to `PORTED` with exact .NET file:line references.
|
||||
- Keep `PARTIAL` only if explicit residual behavior remains.
|
||||
|
||||
## Task 5: Cross-Module Regression and Hardening
|
||||
|
||||
**Files:**
|
||||
- Test: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
**Step 1: Run full regression suite**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: PASS.
|
||||
|
||||
**Step 2: Add edge-case tests discovered during regression**
|
||||
- Capture any newly discovered divergence from Go and close it before completion.
|
||||
|
||||
## Task 6: Finalize Parity Bookkeeping
|
||||
|
||||
**Files:**
|
||||
- Modify: `gaps/jetstream.md`
|
||||
- Modify: `gaps/stillmissing.md`
|
||||
|
||||
**Step 1: Ensure final status correctness**
|
||||
- Verify no unresolved `MISSING` rows remain for `jetstream`.
|
||||
|
||||
**Step 2: Refresh LOC and percentage bookkeeping**
|
||||
- Recount category LOC and update summary rows in `gaps/stillmissing.md`.
|
||||
|
||||
**Step 3: Add concise changelog entry**
|
||||
- Record date, completed parity areas, and any justified deferred items.
|
||||
|
||||
## Completion Checklist
|
||||
- [ ] All prioritized `jetstream` rows are `PORTED` or explicitly justified as `NOT_APPLICABLE`/`DEFERRED`.
|
||||
- [ ] New/updated tests demonstrate parity for all previously open rows.
|
||||
- [ ] `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release` passes.
|
||||
- [ ] `gaps/jetstream.md` and `gaps/stillmissing.md` are fully synchronized.
|
||||
76
docs/plans/2026-02-25-gap-port-leaf-nodes-design.md
Normal file
76
docs/plans/2026-02-25-gap-port-leaf-nodes-design.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# Leaf Nodes Full Parity Design
|
||||
|
||||
**Date:** 2026-02-25
|
||||
**Category:** `leaf-nodes`
|
||||
**Gap Inventory:** `gaps/leaf-nodes.md`
|
||||
**Target Outcome:** Full Go-to-.NET behavioral parity for this category.
|
||||
|
||||
## Assumptions
|
||||
- Full parity is the required outcome.
|
||||
- No additional requirements gathering is needed for this pass.
|
||||
- Existing public .NET APIs are preserved unless parity requires targeted, documented adjustments.
|
||||
|
||||
## Current State Snapshot
|
||||
- `MISSING`: 55
|
||||
- `PARTIAL`: 23
|
||||
- `PORTED`: 5
|
||||
- `NOT_APPLICABLE`: 1
|
||||
- `DEFERRED`: 0
|
||||
- **Open parity work items:** 78
|
||||
|
||||
## Approaches Considered
|
||||
1. **Symbol-first closure (Recommended):** execute directly against each `MISSING` and `PARTIAL` row in `gaps/leaf-nodes.md`, closing items in deterministic order.
|
||||
Trade-off: strongest traceability and auditability, but can require broad context switching.
|
||||
2. **Test-first closure:** derive all work from Go test scenarios first, then backfill missing symbols.
|
||||
Trade-off: maximizes behavioral confidence, but can miss non-test-covered API and helper parity.
|
||||
3. **Vertical runtime slices:** port connect/auth/pubsub/cluster flows end-to-end before moving to next slice.
|
||||
Trade-off: smoother integration validation, but weaker one-to-one mapping against inventory rows.
|
||||
|
||||
## Recommended Design
|
||||
### Architecture
|
||||
Use the gap inventory as the authoritative backlog. For each row, implement or complete the .NET equivalent, then attach test evidence and update the inventory status. Keep implementation inside existing category boundaries and only refactor when needed to match Go behavior.
|
||||
|
||||
### Components
|
||||
- **Backlog driver:** `gaps/leaf-nodes.md` (row-level tracking for all parity items).
|
||||
- **Implementation surface:** category-specific .NET source files.
|
||||
- **Verification surface:** category-specific .NET tests plus cross-module regression tests.
|
||||
- **Parity bookkeeping:** updates to `gaps/leaf-nodes.md` and `gaps/stillmissing.md` after each closure batch.
|
||||
|
||||
### Data Flow
|
||||
1. Read one `MISSING` or `PARTIAL` row from `gaps/leaf-nodes.md`.
|
||||
2. Inspect referenced Go implementation and tests.
|
||||
3. Add/adjust .NET implementation in listed category files.
|
||||
4. Add failing .NET tests that reproduce the missing/partial behavior, then make them pass.
|
||||
5. Re-run targeted and regression tests.
|
||||
6. Update the row to `PORTED` (or keep `PARTIAL` with explicit residual notes).
|
||||
|
||||
### Error Handling and Risk Controls
|
||||
- Avoid broad rewrites; prefer narrow patches tied to specific inventory rows.
|
||||
- Preserve protocol and timing semantics when replacing Go concurrency constructs with .NET async patterns.
|
||||
- Treat edge cases in Go tests as mandatory parity requirements unless explicitly marked `NOT_APPLICABLE`.
|
||||
- Require evidence (tests + inventory status updates) before declaring row completion.
|
||||
|
||||
### Testing Strategy
|
||||
- Add or expand tests for each row moved from `MISSING`/`PARTIAL` toward `PORTED`.
|
||||
- Prioritize wire/protocol compatibility, lifecycle transitions, auth boundaries, and backpressure/timeout behavior.
|
||||
- Keep category-targeted tests fast; run full `NATS.Server.Tests` regression before closure.
|
||||
|
||||
### Definition of Done
|
||||
- All category rows are either `PORTED` or explicitly justified `NOT_APPLICABLE`/`DEFERRED`.
|
||||
- No unresolved `MISSING` or unqualified `PARTIAL` rows remain for this category.
|
||||
- Relevant .NET tests pass locally and parity evidence is written into inventory notes.
|
||||
|
||||
## Implementation Scope Inputs
|
||||
### Go Source Files
|
||||
- `golang/nats-server/server/leafnode.go`
|
||||
|
||||
### Go Test Files
|
||||
- `golang/nats-server/server/leafnode_test.go`
|
||||
- `golang/nats-server/server/leafnode_proxy_test.go`
|
||||
- `golang/nats-server/test/leafnode_test.go (integration)`
|
||||
|
||||
### .NET Source Files
|
||||
- `src/NATS.Server/LeafNodes/ (all files)`
|
||||
|
||||
### .NET Test Files
|
||||
- `tests/NATS.Server.Tests/LeafNodes/`
|
||||
103
docs/plans/2026-02-25-gap-port-leaf-nodes-plan.md
Normal file
103
docs/plans/2026-02-25-gap-port-leaf-nodes-plan.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# Leaf Nodes Gap Port Implementation Plan
|
||||
|
||||
> **For Codex:** REQUIRED SUB-SKILL: Use `executeplan` to implement this plan task-by-task.
|
||||
|
||||
**Goal:** Port all remaining `leaf-nodes` gap inventory items to achieve full behavior parity with Go.
|
||||
|
||||
**Architecture:** Use the category gap inventory as the execution backlog. Drive work row-by-row from `MISSING` and `PARTIAL` toward `PORTED`, with test-first validation and explicit parity evidence in notes.
|
||||
|
||||
**Tech Stack:** .NET 10, C#, xUnit, existing `NATS.Server` runtime modules, Go NATS server reference source.
|
||||
|
||||
---
|
||||
|
||||
## Category Inputs
|
||||
- Gap Inventory: `gaps/leaf-nodes.md`
|
||||
- Primary .NET Source Anchor: `src/NATS.Server/LeafNodes/ (all files)`
|
||||
- Primary .NET Test Anchor: `tests/NATS.Server.Tests/LeafNodes/`
|
||||
- Full .NET test project: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
## Task 1: Freeze Row-Level Backlog
|
||||
|
||||
**Files:**
|
||||
- Modify: `gaps/leaf-nodes.md`
|
||||
|
||||
**Step 1: Normalize open rows into an execution queue**
|
||||
- Split all `MISSING` and `PARTIAL` rows into ranked batches (highest runtime impact first).
|
||||
|
||||
**Step 2: Record acceptance criteria per row**
|
||||
- For each row, define exact behavioral parity checks (inputs, outputs, error paths, timing/concurrency expectations).
|
||||
|
||||
**Step 3: Save queue annotations in notes**
|
||||
- Add short execution-order markers in notes without changing status yet.
|
||||
|
||||
## Task 2: Write Failing Tests for Batch 1
|
||||
|
||||
**Files:**
|
||||
- Modify: `tests/NATS.Server.Tests/LeafNodes/`
|
||||
- Test: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
**Step 1: Add failing tests for first open row batch**
|
||||
- Create tests that reproduce the exact missing/partial Go behavior.
|
||||
|
||||
**Step 2: Run tests to confirm failure**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: FAIL in newly added tests only.
|
||||
|
||||
## Task 3: Implement Minimal Parity for Batch 1
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/NATS.Server/LeafNodes/ (all files)`
|
||||
- Modify: additional category files listed in `gaps/leaf-nodes.md`
|
||||
|
||||
**Step 1: Implement minimal code to satisfy failing tests**
|
||||
- Mirror Go semantics for parsing, state transitions, limits, and side-effects required by the targeted rows.
|
||||
|
||||
**Step 2: Re-run tests for validation**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: PASS for batch-1 tests; no new regressions.
|
||||
|
||||
## Task 4: Close Remaining Batches Iteratively
|
||||
|
||||
**Files:**
|
||||
- Modify: category .NET source and test files referenced in `gaps/leaf-nodes.md`
|
||||
- Modify: `gaps/leaf-nodes.md`
|
||||
|
||||
**Step 1: Repeat test-first cycle for each remaining batch**
|
||||
- Add failing tests, implement minimal parity, then verify pass.
|
||||
|
||||
**Step 2: Update inventory status immediately after each closure**
|
||||
- Move rows to `PORTED` with exact .NET file:line references.
|
||||
- Keep `PARTIAL` only if explicit residual behavior remains.
|
||||
|
||||
## Task 5: Cross-Module Regression and Hardening
|
||||
|
||||
**Files:**
|
||||
- Test: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
**Step 1: Run full regression suite**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: PASS.
|
||||
|
||||
**Step 2: Add edge-case tests discovered during regression**
|
||||
- Capture any newly discovered divergence from Go and close it before completion.
|
||||
|
||||
## Task 6: Finalize Parity Bookkeeping
|
||||
|
||||
**Files:**
|
||||
- Modify: `gaps/leaf-nodes.md`
|
||||
- Modify: `gaps/stillmissing.md`
|
||||
|
||||
**Step 1: Ensure final status correctness**
|
||||
- Verify no unresolved `MISSING` rows remain for `leaf-nodes`.
|
||||
|
||||
**Step 2: Refresh LOC and percentage bookkeeping**
|
||||
- Recount category LOC and update summary rows in `gaps/stillmissing.md`.
|
||||
|
||||
**Step 3: Add concise changelog entry**
|
||||
- Record date, completed parity areas, and any justified deferred items.
|
||||
|
||||
## Completion Checklist
|
||||
- [ ] All prioritized `leaf-nodes` rows are `PORTED` or explicitly justified as `NOT_APPLICABLE`/`DEFERRED`.
|
||||
- [ ] New/updated tests demonstrate parity for all previously open rows.
|
||||
- [ ] `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release` passes.
|
||||
- [ ] `gaps/leaf-nodes.md` and `gaps/stillmissing.md` are fully synchronized.
|
||||
80
docs/plans/2026-02-25-gap-port-logging-design.md
Normal file
80
docs/plans/2026-02-25-gap-port-logging-design.md
Normal file
@@ -0,0 +1,80 @@
|
||||
# Logging Full Parity Design
|
||||
|
||||
**Date:** 2026-02-25
|
||||
**Category:** `logging`
|
||||
**Gap Inventory:** `gaps/logging.md`
|
||||
**Target Outcome:** Full Go-to-.NET behavioral parity for this category.
|
||||
|
||||
## Assumptions
|
||||
- Full parity is the required outcome.
|
||||
- No additional requirements gathering is needed for this pass.
|
||||
- Existing public .NET APIs are preserved unless parity requires targeted, documented adjustments.
|
||||
|
||||
## Current State Snapshot
|
||||
- `MISSING`: 0
|
||||
- `PARTIAL`: 4
|
||||
- `PORTED`: 54
|
||||
- `NOT_APPLICABLE`: 7
|
||||
- `DEFERRED`: 11
|
||||
- **Open parity work items:** 4
|
||||
|
||||
## Approaches Considered
|
||||
1. **Symbol-first closure (Recommended):** execute directly against each `MISSING` and `PARTIAL` row in `gaps/logging.md`, closing items in deterministic order.
|
||||
Trade-off: strongest traceability and auditability, but can require broad context switching.
|
||||
2. **Test-first closure:** derive all work from Go test scenarios first, then backfill missing symbols.
|
||||
Trade-off: maximizes behavioral confidence, but can miss non-test-covered API and helper parity.
|
||||
3. **Vertical runtime slices:** port connect/auth/pubsub/cluster flows end-to-end before moving to next slice.
|
||||
Trade-off: smoother integration validation, but weaker one-to-one mapping against inventory rows.
|
||||
|
||||
## Recommended Design
|
||||
### Architecture
|
||||
Use the gap inventory as the authoritative backlog. For each row, implement or complete the .NET equivalent, then attach test evidence and update the inventory status. Keep implementation inside existing category boundaries and only refactor when needed to match Go behavior.
|
||||
|
||||
### Components
|
||||
- **Backlog driver:** `gaps/logging.md` (row-level tracking for all parity items).
|
||||
- **Implementation surface:** category-specific .NET source files.
|
||||
- **Verification surface:** category-specific .NET tests plus cross-module regression tests.
|
||||
- **Parity bookkeeping:** updates to `gaps/logging.md` and `gaps/stillmissing.md` after each closure batch.
|
||||
|
||||
### Data Flow
|
||||
1. Read one `MISSING` or `PARTIAL` row from `gaps/logging.md`.
|
||||
2. Inspect referenced Go implementation and tests.
|
||||
3. Add/adjust .NET implementation in listed category files.
|
||||
4. Add failing .NET tests that reproduce the missing/partial behavior, then make them pass.
|
||||
5. Re-run targeted and regression tests.
|
||||
6. Update the row to `PORTED` (or keep `PARTIAL` with explicit residual notes).
|
||||
|
||||
### Error Handling and Risk Controls
|
||||
- Avoid broad rewrites; prefer narrow patches tied to specific inventory rows.
|
||||
- Preserve protocol and timing semantics when replacing Go concurrency constructs with .NET async patterns.
|
||||
- Treat edge cases in Go tests as mandatory parity requirements unless explicitly marked `NOT_APPLICABLE`.
|
||||
- Require evidence (tests + inventory status updates) before declaring row completion.
|
||||
|
||||
### Testing Strategy
|
||||
- Add or expand tests for each row moved from `MISSING`/`PARTIAL` toward `PORTED`.
|
||||
- Prioritize wire/protocol compatibility, lifecycle transitions, auth boundaries, and backpressure/timeout behavior.
|
||||
- Keep category-targeted tests fast; run full `NATS.Server.Tests` regression before closure.
|
||||
|
||||
### Definition of Done
|
||||
- All category rows are either `PORTED` or explicitly justified `NOT_APPLICABLE`/`DEFERRED`.
|
||||
- No unresolved `MISSING` or unqualified `PARTIAL` rows remain for this category.
|
||||
- Relevant .NET tests pass locally and parity evidence is written into inventory notes.
|
||||
|
||||
## Implementation Scope Inputs
|
||||
### Go Source Files
|
||||
- `golang/nats-server/server/log.go`
|
||||
- `golang/nats-server/logger/log.go`
|
||||
- `golang/nats-server/logger/syslog.go`
|
||||
- `golang/nats-server/logger/syslog_windows.go`
|
||||
|
||||
### Go Test Files
|
||||
- `golang/nats-server/server/log_test.go`
|
||||
- `golang/nats-server/logger/log_test.go`
|
||||
- `golang/nats-server/logger/syslog_test.go`
|
||||
- `golang/nats-server/logger/syslog_windows_test.go`
|
||||
|
||||
### .NET Source Files
|
||||
- `(none`
|
||||
|
||||
### .NET Test Files
|
||||
- `(none`
|
||||
103
docs/plans/2026-02-25-gap-port-logging-plan.md
Normal file
103
docs/plans/2026-02-25-gap-port-logging-plan.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# Logging Gap Port Implementation Plan
|
||||
|
||||
> **For Codex:** REQUIRED SUB-SKILL: Use `executeplan` to implement this plan task-by-task.
|
||||
|
||||
**Goal:** Port all remaining `logging` gap inventory items to achieve full behavior parity with Go.
|
||||
|
||||
**Architecture:** Use the category gap inventory as the execution backlog. Drive work row-by-row from `MISSING` and `PARTIAL` toward `PORTED`, with test-first validation and explicit parity evidence in notes.
|
||||
|
||||
**Tech Stack:** .NET 10, C#, xUnit, existing `NATS.Server` runtime modules, Go NATS server reference source.
|
||||
|
||||
---
|
||||
|
||||
## Category Inputs
|
||||
- Gap Inventory: `gaps/logging.md`
|
||||
- Primary .NET Source Anchor: `(none`
|
||||
- Primary .NET Test Anchor: `(none`
|
||||
- Full .NET test project: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
## Task 1: Freeze Row-Level Backlog
|
||||
|
||||
**Files:**
|
||||
- Modify: `gaps/logging.md`
|
||||
|
||||
**Step 1: Normalize open rows into an execution queue**
|
||||
- Split all `MISSING` and `PARTIAL` rows into ranked batches (highest runtime impact first).
|
||||
|
||||
**Step 2: Record acceptance criteria per row**
|
||||
- For each row, define exact behavioral parity checks (inputs, outputs, error paths, timing/concurrency expectations).
|
||||
|
||||
**Step 3: Save queue annotations in notes**
|
||||
- Add short execution-order markers in notes without changing status yet.
|
||||
|
||||
## Task 2: Write Failing Tests for Batch 1
|
||||
|
||||
**Files:**
|
||||
- Modify: `(none`
|
||||
- Test: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
**Step 1: Add failing tests for first open row batch**
|
||||
- Create tests that reproduce the exact missing/partial Go behavior.
|
||||
|
||||
**Step 2: Run tests to confirm failure**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: FAIL in newly added tests only.
|
||||
|
||||
## Task 3: Implement Minimal Parity for Batch 1
|
||||
|
||||
**Files:**
|
||||
- Modify: `(none`
|
||||
- Modify: additional category files listed in `gaps/logging.md`
|
||||
|
||||
**Step 1: Implement minimal code to satisfy failing tests**
|
||||
- Mirror Go semantics for parsing, state transitions, limits, and side-effects required by the targeted rows.
|
||||
|
||||
**Step 2: Re-run tests for validation**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: PASS for batch-1 tests; no new regressions.
|
||||
|
||||
## Task 4: Close Remaining Batches Iteratively
|
||||
|
||||
**Files:**
|
||||
- Modify: category .NET source and test files referenced in `gaps/logging.md`
|
||||
- Modify: `gaps/logging.md`
|
||||
|
||||
**Step 1: Repeat test-first cycle for each remaining batch**
|
||||
- Add failing tests, implement minimal parity, then verify pass.
|
||||
|
||||
**Step 2: Update inventory status immediately after each closure**
|
||||
- Move rows to `PORTED` with exact .NET file:line references.
|
||||
- Keep `PARTIAL` only if explicit residual behavior remains.
|
||||
|
||||
## Task 5: Cross-Module Regression and Hardening
|
||||
|
||||
**Files:**
|
||||
- Test: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
**Step 1: Run full regression suite**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: PASS.
|
||||
|
||||
**Step 2: Add edge-case tests discovered during regression**
|
||||
- Capture any newly discovered divergence from Go and close it before completion.
|
||||
|
||||
## Task 6: Finalize Parity Bookkeeping
|
||||
|
||||
**Files:**
|
||||
- Modify: `gaps/logging.md`
|
||||
- Modify: `gaps/stillmissing.md`
|
||||
|
||||
**Step 1: Ensure final status correctness**
|
||||
- Verify no unresolved `MISSING` rows remain for `logging`.
|
||||
|
||||
**Step 2: Refresh LOC and percentage bookkeeping**
|
||||
- Recount category LOC and update summary rows in `gaps/stillmissing.md`.
|
||||
|
||||
**Step 3: Add concise changelog entry**
|
||||
- Record date, completed parity areas, and any justified deferred items.
|
||||
|
||||
## Completion Checklist
|
||||
- [ ] All prioritized `logging` rows are `PORTED` or explicitly justified as `NOT_APPLICABLE`/`DEFERRED`.
|
||||
- [ ] New/updated tests demonstrate parity for all previously open rows.
|
||||
- [ ] `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release` passes.
|
||||
- [ ] `gaps/logging.md` and `gaps/stillmissing.md` are fully synchronized.
|
||||
84
docs/plans/2026-02-25-gap-port-misc-uncategorized-design.md
Normal file
84
docs/plans/2026-02-25-gap-port-misc-uncategorized-design.md
Normal file
@@ -0,0 +1,84 @@
|
||||
# Misc / Uncategorized Full Parity Design
|
||||
|
||||
**Date:** 2026-02-25
|
||||
**Category:** `misc-uncategorized`
|
||||
**Gap Inventory:** `gaps/misc-uncategorized.md`
|
||||
**Target Outcome:** Full Go-to-.NET behavioral parity for this category.
|
||||
|
||||
## Assumptions
|
||||
- Full parity is the required outcome.
|
||||
- No additional requirements gathering is needed for this pass.
|
||||
- Existing public .NET APIs are preserved unless parity requires targeted, documented adjustments.
|
||||
|
||||
## Current State Snapshot
|
||||
- `MISSING`: 8
|
||||
- `PARTIAL`: 13
|
||||
- `PORTED`: 2
|
||||
- `NOT_APPLICABLE`: 6
|
||||
- `DEFERRED`: 2
|
||||
- **Open parity work items:** 21
|
||||
|
||||
## Approaches Considered
|
||||
1. **Symbol-first closure (Recommended):** execute directly against each `MISSING` and `PARTIAL` row in `gaps/misc-uncategorized.md`, closing items in deterministic order.
|
||||
Trade-off: strongest traceability and auditability, but can require broad context switching.
|
||||
2. **Test-first closure:** derive all work from Go test scenarios first, then backfill missing symbols.
|
||||
Trade-off: maximizes behavioral confidence, but can miss non-test-covered API and helper parity.
|
||||
3. **Vertical runtime slices:** port connect/auth/pubsub/cluster flows end-to-end before moving to next slice.
|
||||
Trade-off: smoother integration validation, but weaker one-to-one mapping against inventory rows.
|
||||
|
||||
## Recommended Design
|
||||
### Architecture
|
||||
Use the gap inventory as the authoritative backlog. For each row, implement or complete the .NET equivalent, then attach test evidence and update the inventory status. Keep implementation inside existing category boundaries and only refactor when needed to match Go behavior.
|
||||
|
||||
### Components
|
||||
- **Backlog driver:** `gaps/misc-uncategorized.md` (row-level tracking for all parity items).
|
||||
- **Implementation surface:** category-specific .NET source files.
|
||||
- **Verification surface:** category-specific .NET tests plus cross-module regression tests.
|
||||
- **Parity bookkeeping:** updates to `gaps/misc-uncategorized.md` and `gaps/stillmissing.md` after each closure batch.
|
||||
|
||||
### Data Flow
|
||||
1. Read one `MISSING` or `PARTIAL` row from `gaps/misc-uncategorized.md`.
|
||||
2. Inspect referenced Go implementation and tests.
|
||||
3. Add/adjust .NET implementation in listed category files.
|
||||
4. Add failing .NET tests that reproduce the missing/partial behavior, then make them pass.
|
||||
5. Re-run targeted and regression tests.
|
||||
6. Update the row to `PORTED` (or keep `PARTIAL` with explicit residual notes).
|
||||
|
||||
### Error Handling and Risk Controls
|
||||
- Avoid broad rewrites; prefer narrow patches tied to specific inventory rows.
|
||||
- Preserve protocol and timing semantics when replacing Go concurrency constructs with .NET async patterns.
|
||||
- Treat edge cases in Go tests as mandatory parity requirements unless explicitly marked `NOT_APPLICABLE`.
|
||||
- Require evidence (tests + inventory status updates) before declaring row completion.
|
||||
|
||||
### Testing Strategy
|
||||
- Add or expand tests for each row moved from `MISSING`/`PARTIAL` toward `PORTED`.
|
||||
- Prioritize wire/protocol compatibility, lifecycle transitions, auth boundaries, and backpressure/timeout behavior.
|
||||
- Keep category-targeted tests fast; run full `NATS.Server.Tests` regression before closure.
|
||||
|
||||
### Definition of Done
|
||||
- All category rows are either `PORTED` or explicitly justified `NOT_APPLICABLE`/`DEFERRED`.
|
||||
- No unresolved `MISSING` or unqualified `PARTIAL` rows remain for this category.
|
||||
- Relevant .NET tests pass locally and parity evidence is written into inventory notes.
|
||||
|
||||
## Implementation Scope Inputs
|
||||
### Go Source Files
|
||||
- `Files not fitting into other categories`
|
||||
- `Small Go source files that don't belong to a major subsystem`
|
||||
- `Platform-specific stubs or build-tag-only files`
|
||||
|
||||
### Go Test Files
|
||||
- `golang/nats-server/server/ping_test.go`
|
||||
- `golang/nats-server/server/closed_conns_test.go`
|
||||
- `golang/nats-server/server/norace_1_test.go`
|
||||
- `golang/nats-server/server/norace_2_test.go`
|
||||
- `golang/nats-server/server/benchmark_publish_test.go`
|
||||
- `golang/nats-server/server/core_benchmarks_test.go`
|
||||
- `Various integration tests in golang/nats-server/test/`
|
||||
|
||||
### .NET Source Files
|
||||
- `Any .NET source files not covered by other category files`
|
||||
|
||||
### .NET Test Files
|
||||
- `tests/NATS.Server.Tests/Stress/`
|
||||
- `tests/NATS.Server.Tests/Parity/`
|
||||
- `Other root-level test files`
|
||||
103
docs/plans/2026-02-25-gap-port-misc-uncategorized-plan.md
Normal file
103
docs/plans/2026-02-25-gap-port-misc-uncategorized-plan.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# Misc / Uncategorized Gap Port Implementation Plan
|
||||
|
||||
> **For Codex:** REQUIRED SUB-SKILL: Use `executeplan` to implement this plan task-by-task.
|
||||
|
||||
**Goal:** Port all remaining `misc-uncategorized` gap inventory items to achieve full behavior parity with Go.
|
||||
|
||||
**Architecture:** Use the category gap inventory as the execution backlog. Drive work row-by-row from `MISSING` and `PARTIAL` toward `PORTED`, with test-first validation and explicit parity evidence in notes.
|
||||
|
||||
**Tech Stack:** .NET 10, C#, xUnit, existing `NATS.Server` runtime modules, Go NATS server reference source.
|
||||
|
||||
---
|
||||
|
||||
## Category Inputs
|
||||
- Gap Inventory: `gaps/misc-uncategorized.md`
|
||||
- Primary .NET Source Anchor: `Any .NET source files not covered by other category files`
|
||||
- Primary .NET Test Anchor: `tests/NATS.Server.Tests/Stress/`
|
||||
- Full .NET test project: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
## Task 1: Freeze Row-Level Backlog
|
||||
|
||||
**Files:**
|
||||
- Modify: `gaps/misc-uncategorized.md`
|
||||
|
||||
**Step 1: Normalize open rows into an execution queue**
|
||||
- Split all `MISSING` and `PARTIAL` rows into ranked batches (highest runtime impact first).
|
||||
|
||||
**Step 2: Record acceptance criteria per row**
|
||||
- For each row, define exact behavioral parity checks (inputs, outputs, error paths, timing/concurrency expectations).
|
||||
|
||||
**Step 3: Save queue annotations in notes**
|
||||
- Add short execution-order markers in notes without changing status yet.
|
||||
|
||||
## Task 2: Write Failing Tests for Batch 1
|
||||
|
||||
**Files:**
|
||||
- Modify: `tests/NATS.Server.Tests/Stress/`
|
||||
- Test: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
**Step 1: Add failing tests for first open row batch**
|
||||
- Create tests that reproduce the exact missing/partial Go behavior.
|
||||
|
||||
**Step 2: Run tests to confirm failure**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: FAIL in newly added tests only.
|
||||
|
||||
## Task 3: Implement Minimal Parity for Batch 1
|
||||
|
||||
**Files:**
|
||||
- Modify: `Any .NET source files not covered by other category files`
|
||||
- Modify: additional category files listed in `gaps/misc-uncategorized.md`
|
||||
|
||||
**Step 1: Implement minimal code to satisfy failing tests**
|
||||
- Mirror Go semantics for parsing, state transitions, limits, and side-effects required by the targeted rows.
|
||||
|
||||
**Step 2: Re-run tests for validation**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: PASS for batch-1 tests; no new regressions.
|
||||
|
||||
## Task 4: Close Remaining Batches Iteratively
|
||||
|
||||
**Files:**
|
||||
- Modify: category .NET source and test files referenced in `gaps/misc-uncategorized.md`
|
||||
- Modify: `gaps/misc-uncategorized.md`
|
||||
|
||||
**Step 1: Repeat test-first cycle for each remaining batch**
|
||||
- Add failing tests, implement minimal parity, then verify pass.
|
||||
|
||||
**Step 2: Update inventory status immediately after each closure**
|
||||
- Move rows to `PORTED` with exact .NET file:line references.
|
||||
- Keep `PARTIAL` only if explicit residual behavior remains.
|
||||
|
||||
## Task 5: Cross-Module Regression and Hardening
|
||||
|
||||
**Files:**
|
||||
- Test: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
**Step 1: Run full regression suite**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: PASS.
|
||||
|
||||
**Step 2: Add edge-case tests discovered during regression**
|
||||
- Capture any newly discovered divergence from Go and close it before completion.
|
||||
|
||||
## Task 6: Finalize Parity Bookkeeping
|
||||
|
||||
**Files:**
|
||||
- Modify: `gaps/misc-uncategorized.md`
|
||||
- Modify: `gaps/stillmissing.md`
|
||||
|
||||
**Step 1: Ensure final status correctness**
|
||||
- Verify no unresolved `MISSING` rows remain for `misc-uncategorized`.
|
||||
|
||||
**Step 2: Refresh LOC and percentage bookkeeping**
|
||||
- Recount category LOC and update summary rows in `gaps/stillmissing.md`.
|
||||
|
||||
**Step 3: Add concise changelog entry**
|
||||
- Record date, completed parity areas, and any justified deferred items.
|
||||
|
||||
## Completion Checklist
|
||||
- [ ] All prioritized `misc-uncategorized` rows are `PORTED` or explicitly justified as `NOT_APPLICABLE`/`DEFERRED`.
|
||||
- [ ] New/updated tests demonstrate parity for all previously open rows.
|
||||
- [ ] `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release` passes.
|
||||
- [ ] `gaps/misc-uncategorized.md` and `gaps/stillmissing.md` are fully synchronized.
|
||||
88
docs/plans/2026-02-25-gap-port-monitoring-design.md
Normal file
88
docs/plans/2026-02-25-gap-port-monitoring-design.md
Normal file
@@ -0,0 +1,88 @@
|
||||
# Monitoring Full Parity Design
|
||||
|
||||
**Date:** 2026-02-25
|
||||
**Category:** `monitoring`
|
||||
**Gap Inventory:** `gaps/monitoring.md`
|
||||
**Target Outcome:** Full Go-to-.NET behavioral parity for this category.
|
||||
|
||||
## Assumptions
|
||||
- Full parity is the required outcome.
|
||||
- No additional requirements gathering is needed for this pass.
|
||||
- Existing public .NET APIs are preserved unless parity requires targeted, documented adjustments.
|
||||
|
||||
## Current State Snapshot
|
||||
- `MISSING`: 61
|
||||
- `PARTIAL`: 42
|
||||
- `PORTED`: 63
|
||||
- `NOT_APPLICABLE`: 3
|
||||
- `DEFERRED`: 0
|
||||
- **Open parity work items:** 103
|
||||
|
||||
## Approaches Considered
|
||||
1. **Symbol-first closure (Recommended):** execute directly against each `MISSING` and `PARTIAL` row in `gaps/monitoring.md`, closing items in deterministic order.
|
||||
Trade-off: strongest traceability and auditability, but can require broad context switching.
|
||||
2. **Test-first closure:** derive all work from Go test scenarios first, then backfill missing symbols.
|
||||
Trade-off: maximizes behavioral confidence, but can miss non-test-covered API and helper parity.
|
||||
3. **Vertical runtime slices:** port connect/auth/pubsub/cluster flows end-to-end before moving to next slice.
|
||||
Trade-off: smoother integration validation, but weaker one-to-one mapping against inventory rows.
|
||||
|
||||
## Recommended Design
|
||||
### Architecture
|
||||
Use the gap inventory as the authoritative backlog. For each row, implement or complete the .NET equivalent, then attach test evidence and update the inventory status. Keep implementation inside existing category boundaries and only refactor when needed to match Go behavior.
|
||||
|
||||
### Components
|
||||
- **Backlog driver:** `gaps/monitoring.md` (row-level tracking for all parity items).
|
||||
- **Implementation surface:** category-specific .NET source files.
|
||||
- **Verification surface:** category-specific .NET tests plus cross-module regression tests.
|
||||
- **Parity bookkeeping:** updates to `gaps/monitoring.md` and `gaps/stillmissing.md` after each closure batch.
|
||||
|
||||
### Data Flow
|
||||
1. Read one `MISSING` or `PARTIAL` row from `gaps/monitoring.md`.
|
||||
2. Inspect referenced Go implementation and tests.
|
||||
3. Add/adjust .NET implementation in listed category files.
|
||||
4. Add failing .NET tests that reproduce the missing/partial behavior, then make them pass.
|
||||
5. Re-run targeted and regression tests.
|
||||
6. Update the row to `PORTED` (or keep `PARTIAL` with explicit residual notes).
|
||||
|
||||
### Error Handling and Risk Controls
|
||||
- Avoid broad rewrites; prefer narrow patches tied to specific inventory rows.
|
||||
- Preserve protocol and timing semantics when replacing Go concurrency constructs with .NET async patterns.
|
||||
- Treat edge cases in Go tests as mandatory parity requirements unless explicitly marked `NOT_APPLICABLE`.
|
||||
- Require evidence (tests + inventory status updates) before declaring row completion.
|
||||
|
||||
### Testing Strategy
|
||||
- Add or expand tests for each row moved from `MISSING`/`PARTIAL` toward `PORTED`.
|
||||
- Prioritize wire/protocol compatibility, lifecycle transitions, auth boundaries, and backpressure/timeout behavior.
|
||||
- Keep category-targeted tests fast; run full `NATS.Server.Tests` regression before closure.
|
||||
|
||||
### Definition of Done
|
||||
- All category rows are either `PORTED` or explicitly justified `NOT_APPLICABLE`/`DEFERRED`.
|
||||
- No unresolved `MISSING` or unqualified `PARTIAL` rows remain for this category.
|
||||
- Relevant .NET tests pass locally and parity evidence is written into inventory notes.
|
||||
|
||||
## Implementation Scope Inputs
|
||||
### Go Source Files
|
||||
- `golang/nats-server/server/monitor.go`
|
||||
- `golang/nats-server/server/monitor_sort_opts.go`
|
||||
|
||||
### Go Test Files
|
||||
- `golang/nats-server/server/monitor_test.go`
|
||||
- `golang/nats-server/test/monitor_test.go (integration)`
|
||||
|
||||
### .NET Source Files
|
||||
- `src/NATS.Server/Monitoring/MonitorServer.cs`
|
||||
- `src/NATS.Server/Monitoring/Varz.cs`
|
||||
- `src/NATS.Server/Monitoring/Subsz.cs`
|
||||
- `src/NATS.Server/Monitoring/VarzHandler.cs`
|
||||
- `src/NATS.Server/Monitoring/SubszHandler.cs`
|
||||
- `src/NATS.Server/Monitoring/JszHandler.cs`
|
||||
- `src/NATS.Server/Monitoring/AccountzHandler.cs`
|
||||
- `src/NATS.Server/Monitoring/GatewayzHandler.cs`
|
||||
- `src/NATS.Server/Monitoring/LeafzHandler.cs`
|
||||
- `src/NATS.Server/Monitoring/RoutezHandler.cs`
|
||||
- `src/NATS.Server/Monitoring/PprofHandler.cs`
|
||||
- `src/NATS.Server/Monitoring/ClosedClient.cs`
|
||||
- `All other files in src/NATS.Server/Monitoring/`
|
||||
|
||||
### .NET Test Files
|
||||
- `tests/NATS.Server.Tests/Monitoring/`
|
||||
103
docs/plans/2026-02-25-gap-port-monitoring-plan.md
Normal file
103
docs/plans/2026-02-25-gap-port-monitoring-plan.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# Monitoring Gap Port Implementation Plan
|
||||
|
||||
> **For Codex:** REQUIRED SUB-SKILL: Use `executeplan` to implement this plan task-by-task.
|
||||
|
||||
**Goal:** Port all remaining `monitoring` gap inventory items to achieve full behavior parity with Go.
|
||||
|
||||
**Architecture:** Use the category gap inventory as the execution backlog. Drive work row-by-row from `MISSING` and `PARTIAL` toward `PORTED`, with test-first validation and explicit parity evidence in notes.
|
||||
|
||||
**Tech Stack:** .NET 10, C#, xUnit, existing `NATS.Server` runtime modules, Go NATS server reference source.
|
||||
|
||||
---
|
||||
|
||||
## Category Inputs
|
||||
- Gap Inventory: `gaps/monitoring.md`
|
||||
- Primary .NET Source Anchor: `src/NATS.Server/Monitoring/MonitorServer.cs`
|
||||
- Primary .NET Test Anchor: `tests/NATS.Server.Tests/Monitoring/`
|
||||
- Full .NET test project: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
## Task 1: Freeze Row-Level Backlog
|
||||
|
||||
**Files:**
|
||||
- Modify: `gaps/monitoring.md`
|
||||
|
||||
**Step 1: Normalize open rows into an execution queue**
|
||||
- Split all `MISSING` and `PARTIAL` rows into ranked batches (highest runtime impact first).
|
||||
|
||||
**Step 2: Record acceptance criteria per row**
|
||||
- For each row, define exact behavioral parity checks (inputs, outputs, error paths, timing/concurrency expectations).
|
||||
|
||||
**Step 3: Save queue annotations in notes**
|
||||
- Add short execution-order markers in notes without changing status yet.
|
||||
|
||||
## Task 2: Write Failing Tests for Batch 1
|
||||
|
||||
**Files:**
|
||||
- Modify: `tests/NATS.Server.Tests/Monitoring/`
|
||||
- Test: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
**Step 1: Add failing tests for first open row batch**
|
||||
- Create tests that reproduce the exact missing/partial Go behavior.
|
||||
|
||||
**Step 2: Run tests to confirm failure**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: FAIL in newly added tests only.
|
||||
|
||||
## Task 3: Implement Minimal Parity for Batch 1
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/NATS.Server/Monitoring/MonitorServer.cs`
|
||||
- Modify: additional category files listed in `gaps/monitoring.md`
|
||||
|
||||
**Step 1: Implement minimal code to satisfy failing tests**
|
||||
- Mirror Go semantics for parsing, state transitions, limits, and side-effects required by the targeted rows.
|
||||
|
||||
**Step 2: Re-run tests for validation**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: PASS for batch-1 tests; no new regressions.
|
||||
|
||||
## Task 4: Close Remaining Batches Iteratively
|
||||
|
||||
**Files:**
|
||||
- Modify: category .NET source and test files referenced in `gaps/monitoring.md`
|
||||
- Modify: `gaps/monitoring.md`
|
||||
|
||||
**Step 1: Repeat test-first cycle for each remaining batch**
|
||||
- Add failing tests, implement minimal parity, then verify pass.
|
||||
|
||||
**Step 2: Update inventory status immediately after each closure**
|
||||
- Move rows to `PORTED` with exact .NET file:line references.
|
||||
- Keep `PARTIAL` only if explicit residual behavior remains.
|
||||
|
||||
## Task 5: Cross-Module Regression and Hardening
|
||||
|
||||
**Files:**
|
||||
- Test: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
**Step 1: Run full regression suite**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: PASS.
|
||||
|
||||
**Step 2: Add edge-case tests discovered during regression**
|
||||
- Capture any newly discovered divergence from Go and close it before completion.
|
||||
|
||||
## Task 6: Finalize Parity Bookkeeping
|
||||
|
||||
**Files:**
|
||||
- Modify: `gaps/monitoring.md`
|
||||
- Modify: `gaps/stillmissing.md`
|
||||
|
||||
**Step 1: Ensure final status correctness**
|
||||
- Verify no unresolved `MISSING` rows remain for `monitoring`.
|
||||
|
||||
**Step 2: Refresh LOC and percentage bookkeeping**
|
||||
- Recount category LOC and update summary rows in `gaps/stillmissing.md`.
|
||||
|
||||
**Step 3: Add concise changelog entry**
|
||||
- Record date, completed parity areas, and any justified deferred items.
|
||||
|
||||
## Completion Checklist
|
||||
- [ ] All prioritized `monitoring` rows are `PORTED` or explicitly justified as `NOT_APPLICABLE`/`DEFERRED`.
|
||||
- [ ] New/updated tests demonstrate parity for all previously open rows.
|
||||
- [ ] `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release` passes.
|
||||
- [ ] `gaps/monitoring.md` and `gaps/stillmissing.md` are fully synchronized.
|
||||
76
docs/plans/2026-02-25-gap-port-mqtt-design.md
Normal file
76
docs/plans/2026-02-25-gap-port-mqtt-design.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# MQTT Full Parity Design
|
||||
|
||||
**Date:** 2026-02-25
|
||||
**Category:** `mqtt`
|
||||
**Gap Inventory:** `gaps/mqtt.md`
|
||||
**Target Outcome:** Full Go-to-.NET behavioral parity for this category.
|
||||
|
||||
## Assumptions
|
||||
- Full parity is the required outcome.
|
||||
- No additional requirements gathering is needed for this pass.
|
||||
- Existing public .NET APIs are preserved unless parity requires targeted, documented adjustments.
|
||||
|
||||
## Current State Snapshot
|
||||
- `MISSING`: 119
|
||||
- `PARTIAL`: 57
|
||||
- `PORTED`: 14
|
||||
- `NOT_APPLICABLE`: 5
|
||||
- `DEFERRED`: 0
|
||||
- **Open parity work items:** 176
|
||||
|
||||
## Approaches Considered
|
||||
1. **Symbol-first closure (Recommended):** execute directly against each `MISSING` and `PARTIAL` row in `gaps/mqtt.md`, closing items in deterministic order.
|
||||
Trade-off: strongest traceability and auditability, but can require broad context switching.
|
||||
2. **Test-first closure:** derive all work from Go test scenarios first, then backfill missing symbols.
|
||||
Trade-off: maximizes behavioral confidence, but can miss non-test-covered API and helper parity.
|
||||
3. **Vertical runtime slices:** port connect/auth/pubsub/cluster flows end-to-end before moving to next slice.
|
||||
Trade-off: smoother integration validation, but weaker one-to-one mapping against inventory rows.
|
||||
|
||||
## Recommended Design
|
||||
### Architecture
|
||||
Use the gap inventory as the authoritative backlog. For each row, implement or complete the .NET equivalent, then attach test evidence and update the inventory status. Keep implementation inside existing category boundaries and only refactor when needed to match Go behavior.
|
||||
|
||||
### Components
|
||||
- **Backlog driver:** `gaps/mqtt.md` (row-level tracking for all parity items).
|
||||
- **Implementation surface:** category-specific .NET source files.
|
||||
- **Verification surface:** category-specific .NET tests plus cross-module regression tests.
|
||||
- **Parity bookkeeping:** updates to `gaps/mqtt.md` and `gaps/stillmissing.md` after each closure batch.
|
||||
|
||||
### Data Flow
|
||||
1. Read one `MISSING` or `PARTIAL` row from `gaps/mqtt.md`.
|
||||
2. Inspect referenced Go implementation and tests.
|
||||
3. Add/adjust .NET implementation in listed category files.
|
||||
4. Add failing .NET tests that reproduce the missing/partial behavior, then make them pass.
|
||||
5. Re-run targeted and regression tests.
|
||||
6. Update the row to `PORTED` (or keep `PARTIAL` with explicit residual notes).
|
||||
|
||||
### Error Handling and Risk Controls
|
||||
- Avoid broad rewrites; prefer narrow patches tied to specific inventory rows.
|
||||
- Preserve protocol and timing semantics when replacing Go concurrency constructs with .NET async patterns.
|
||||
- Treat edge cases in Go tests as mandatory parity requirements unless explicitly marked `NOT_APPLICABLE`.
|
||||
- Require evidence (tests + inventory status updates) before declaring row completion.
|
||||
|
||||
### Testing Strategy
|
||||
- Add or expand tests for each row moved from `MISSING`/`PARTIAL` toward `PORTED`.
|
||||
- Prioritize wire/protocol compatibility, lifecycle transitions, auth boundaries, and backpressure/timeout behavior.
|
||||
- Keep category-targeted tests fast; run full `NATS.Server.Tests` regression before closure.
|
||||
|
||||
### Definition of Done
|
||||
- All category rows are either `PORTED` or explicitly justified `NOT_APPLICABLE`/`DEFERRED`.
|
||||
- No unresolved `MISSING` or unqualified `PARTIAL` rows remain for this category.
|
||||
- Relevant .NET tests pass locally and parity evidence is written into inventory notes.
|
||||
|
||||
## Implementation Scope Inputs
|
||||
### Go Source Files
|
||||
- `golang/nats-server/server/mqtt.go`
|
||||
|
||||
### Go Test Files
|
||||
- `golang/nats-server/server/mqtt_test.go`
|
||||
- `golang/nats-server/server/mqtt_ex_test_test.go`
|
||||
- `golang/nats-server/server/mqtt_ex_bench_test.go`
|
||||
|
||||
### .NET Source Files
|
||||
- `src/NATS.Server/Mqtt/ (all files)`
|
||||
|
||||
### .NET Test Files
|
||||
- `tests/NATS.Server.Tests/Mqtt/`
|
||||
103
docs/plans/2026-02-25-gap-port-mqtt-plan.md
Normal file
103
docs/plans/2026-02-25-gap-port-mqtt-plan.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# MQTT Gap Port Implementation Plan
|
||||
|
||||
> **For Codex:** REQUIRED SUB-SKILL: Use `executeplan` to implement this plan task-by-task.
|
||||
|
||||
**Goal:** Port all remaining `mqtt` gap inventory items to achieve full behavior parity with Go.
|
||||
|
||||
**Architecture:** Use the category gap inventory as the execution backlog. Drive work row-by-row from `MISSING` and `PARTIAL` toward `PORTED`, with test-first validation and explicit parity evidence in notes.
|
||||
|
||||
**Tech Stack:** .NET 10, C#, xUnit, existing `NATS.Server` runtime modules, Go NATS server reference source.
|
||||
|
||||
---
|
||||
|
||||
## Category Inputs
|
||||
- Gap Inventory: `gaps/mqtt.md`
|
||||
- Primary .NET Source Anchor: `src/NATS.Server/Mqtt/ (all files)`
|
||||
- Primary .NET Test Anchor: `tests/NATS.Server.Tests/Mqtt/`
|
||||
- Full .NET test project: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
## Task 1: Freeze Row-Level Backlog
|
||||
|
||||
**Files:**
|
||||
- Modify: `gaps/mqtt.md`
|
||||
|
||||
**Step 1: Normalize open rows into an execution queue**
|
||||
- Split all `MISSING` and `PARTIAL` rows into ranked batches (highest runtime impact first).
|
||||
|
||||
**Step 2: Record acceptance criteria per row**
|
||||
- For each row, define exact behavioral parity checks (inputs, outputs, error paths, timing/concurrency expectations).
|
||||
|
||||
**Step 3: Save queue annotations in notes**
|
||||
- Add short execution-order markers in notes without changing status yet.
|
||||
|
||||
## Task 2: Write Failing Tests for Batch 1
|
||||
|
||||
**Files:**
|
||||
- Modify: `tests/NATS.Server.Tests/Mqtt/`
|
||||
- Test: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
**Step 1: Add failing tests for first open row batch**
|
||||
- Create tests that reproduce the exact missing/partial Go behavior.
|
||||
|
||||
**Step 2: Run tests to confirm failure**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: FAIL in newly added tests only.
|
||||
|
||||
## Task 3: Implement Minimal Parity for Batch 1
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/NATS.Server/Mqtt/ (all files)`
|
||||
- Modify: additional category files listed in `gaps/mqtt.md`
|
||||
|
||||
**Step 1: Implement minimal code to satisfy failing tests**
|
||||
- Mirror Go semantics for parsing, state transitions, limits, and side-effects required by the targeted rows.
|
||||
|
||||
**Step 2: Re-run tests for validation**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: PASS for batch-1 tests; no new regressions.
|
||||
|
||||
## Task 4: Close Remaining Batches Iteratively
|
||||
|
||||
**Files:**
|
||||
- Modify: category .NET source and test files referenced in `gaps/mqtt.md`
|
||||
- Modify: `gaps/mqtt.md`
|
||||
|
||||
**Step 1: Repeat test-first cycle for each remaining batch**
|
||||
- Add failing tests, implement minimal parity, then verify pass.
|
||||
|
||||
**Step 2: Update inventory status immediately after each closure**
|
||||
- Move rows to `PORTED` with exact .NET file:line references.
|
||||
- Keep `PARTIAL` only if explicit residual behavior remains.
|
||||
|
||||
## Task 5: Cross-Module Regression and Hardening
|
||||
|
||||
**Files:**
|
||||
- Test: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
**Step 1: Run full regression suite**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: PASS.
|
||||
|
||||
**Step 2: Add edge-case tests discovered during regression**
|
||||
- Capture any newly discovered divergence from Go and close it before completion.
|
||||
|
||||
## Task 6: Finalize Parity Bookkeeping
|
||||
|
||||
**Files:**
|
||||
- Modify: `gaps/mqtt.md`
|
||||
- Modify: `gaps/stillmissing.md`
|
||||
|
||||
**Step 1: Ensure final status correctness**
|
||||
- Verify no unresolved `MISSING` rows remain for `mqtt`.
|
||||
|
||||
**Step 2: Refresh LOC and percentage bookkeeping**
|
||||
- Recount category LOC and update summary rows in `gaps/stillmissing.md`.
|
||||
|
||||
**Step 3: Add concise changelog entry**
|
||||
- Record date, completed parity areas, and any justified deferred items.
|
||||
|
||||
## Completion Checklist
|
||||
- [ ] All prioritized `mqtt` rows are `PORTED` or explicitly justified as `NOT_APPLICABLE`/`DEFERRED`.
|
||||
- [ ] New/updated tests demonstrate parity for all previously open rows.
|
||||
- [ ] `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release` passes.
|
||||
- [ ] `gaps/mqtt.md` and `gaps/stillmissing.md` are fully synchronized.
|
||||
85
docs/plans/2026-02-25-gap-port-protocol-design.md
Normal file
85
docs/plans/2026-02-25-gap-port-protocol-design.md
Normal file
@@ -0,0 +1,85 @@
|
||||
# Protocol Full Parity Design
|
||||
|
||||
**Date:** 2026-02-25
|
||||
**Category:** `protocol`
|
||||
**Gap Inventory:** `gaps/protocol.md`
|
||||
**Target Outcome:** Full Go-to-.NET behavioral parity for this category.
|
||||
|
||||
## Assumptions
|
||||
- Full parity is the required outcome.
|
||||
- No additional requirements gathering is needed for this pass.
|
||||
- Existing public .NET APIs are preserved unless parity requires targeted, documented adjustments.
|
||||
|
||||
## Current State Snapshot
|
||||
- `MISSING`: 48
|
||||
- `PARTIAL`: 8
|
||||
- `PORTED`: 15
|
||||
- `NOT_APPLICABLE`: 12
|
||||
- `DEFERRED`: 0
|
||||
- **Open parity work items:** 56
|
||||
|
||||
## Approaches Considered
|
||||
1. **Symbol-first closure (Recommended):** execute directly against each `MISSING` and `PARTIAL` row in `gaps/protocol.md`, closing items in deterministic order.
|
||||
Trade-off: strongest traceability and auditability, but can require broad context switching.
|
||||
2. **Test-first closure:** derive all work from Go test scenarios first, then backfill missing symbols.
|
||||
Trade-off: maximizes behavioral confidence, but can miss non-test-covered API and helper parity.
|
||||
3. **Vertical runtime slices:** port connect/auth/pubsub/cluster flows end-to-end before moving to next slice.
|
||||
Trade-off: smoother integration validation, but weaker one-to-one mapping against inventory rows.
|
||||
|
||||
## Recommended Design
|
||||
### Architecture
|
||||
Use the gap inventory as the authoritative backlog. For each row, implement or complete the .NET equivalent, then attach test evidence and update the inventory status. Keep implementation inside existing category boundaries and only refactor when needed to match Go behavior.
|
||||
|
||||
### Components
|
||||
- **Backlog driver:** `gaps/protocol.md` (row-level tracking for all parity items).
|
||||
- **Implementation surface:** category-specific .NET source files.
|
||||
- **Verification surface:** category-specific .NET tests plus cross-module regression tests.
|
||||
- **Parity bookkeeping:** updates to `gaps/protocol.md` and `gaps/stillmissing.md` after each closure batch.
|
||||
|
||||
### Data Flow
|
||||
1. Read one `MISSING` or `PARTIAL` row from `gaps/protocol.md`.
|
||||
2. Inspect referenced Go implementation and tests.
|
||||
3. Add/adjust .NET implementation in listed category files.
|
||||
4. Add failing .NET tests that reproduce the missing/partial behavior, then make them pass.
|
||||
5. Re-run targeted and regression tests.
|
||||
6. Update the row to `PORTED` (or keep `PARTIAL` with explicit residual notes).
|
||||
|
||||
### Error Handling and Risk Controls
|
||||
- Avoid broad rewrites; prefer narrow patches tied to specific inventory rows.
|
||||
- Preserve protocol and timing semantics when replacing Go concurrency constructs with .NET async patterns.
|
||||
- Treat edge cases in Go tests as mandatory parity requirements unless explicitly marked `NOT_APPLICABLE`.
|
||||
- Require evidence (tests + inventory status updates) before declaring row completion.
|
||||
|
||||
### Testing Strategy
|
||||
- Add or expand tests for each row moved from `MISSING`/`PARTIAL` toward `PORTED`.
|
||||
- Prioritize wire/protocol compatibility, lifecycle transitions, auth boundaries, and backpressure/timeout behavior.
|
||||
- Keep category-targeted tests fast; run full `NATS.Server.Tests` regression before closure.
|
||||
|
||||
### Definition of Done
|
||||
- All category rows are either `PORTED` or explicitly justified `NOT_APPLICABLE`/`DEFERRED`.
|
||||
- No unresolved `MISSING` or unqualified `PARTIAL` rows remain for this category.
|
||||
- Relevant .NET tests pass locally and parity evidence is written into inventory notes.
|
||||
|
||||
## Implementation Scope Inputs
|
||||
### Go Source Files
|
||||
- `golang/nats-server/server/parser.go`
|
||||
- `golang/nats-server/server/proto.go`
|
||||
- `golang/nats-server/server/const.go`
|
||||
|
||||
### Go Test Files
|
||||
- `golang/nats-server/server/parser_test.go`
|
||||
- `golang/nats-server/server/parser_fuzz_test.go`
|
||||
- `golang/nats-server/server/server_fuzz_test.go`
|
||||
- `golang/nats-server/server/subject_fuzz_test.go`
|
||||
- `golang/nats-server/server/split_test.go`
|
||||
|
||||
### .NET Source Files
|
||||
- `src/NATS.Server/Protocol/NatsParser.cs`
|
||||
- `src/NATS.Server/Protocol/NatsProtocol.cs`
|
||||
- `src/NATS.Server/Protocol/NatsHeaderParser.cs`
|
||||
- `src/NATS.Server/Protocol/ClientCommandMatrix.cs`
|
||||
- `src/NATS.Server/Protocol/MessageTraceContext.cs`
|
||||
- `src/NATS.Server/Protocol/ProxyProtocol.cs`
|
||||
|
||||
### .NET Test Files
|
||||
- `tests/NATS.Server.Tests/Protocol/`
|
||||
103
docs/plans/2026-02-25-gap-port-protocol-plan.md
Normal file
103
docs/plans/2026-02-25-gap-port-protocol-plan.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# Protocol Gap Port Implementation Plan
|
||||
|
||||
> **For Codex:** REQUIRED SUB-SKILL: Use `executeplan` to implement this plan task-by-task.
|
||||
|
||||
**Goal:** Port all remaining `protocol` gap inventory items to achieve full behavior parity with Go.
|
||||
|
||||
**Architecture:** Use the category gap inventory as the execution backlog. Drive work row-by-row from `MISSING` and `PARTIAL` toward `PORTED`, with test-first validation and explicit parity evidence in notes.
|
||||
|
||||
**Tech Stack:** .NET 10, C#, xUnit, existing `NATS.Server` runtime modules, Go NATS server reference source.
|
||||
|
||||
---
|
||||
|
||||
## Category Inputs
|
||||
- Gap Inventory: `gaps/protocol.md`
|
||||
- Primary .NET Source Anchor: `src/NATS.Server/Protocol/NatsParser.cs`
|
||||
- Primary .NET Test Anchor: `tests/NATS.Server.Tests/Protocol/`
|
||||
- Full .NET test project: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
## Task 1: Freeze Row-Level Backlog
|
||||
|
||||
**Files:**
|
||||
- Modify: `gaps/protocol.md`
|
||||
|
||||
**Step 1: Normalize open rows into an execution queue**
|
||||
- Split all `MISSING` and `PARTIAL` rows into ranked batches (highest runtime impact first).
|
||||
|
||||
**Step 2: Record acceptance criteria per row**
|
||||
- For each row, define exact behavioral parity checks (inputs, outputs, error paths, timing/concurrency expectations).
|
||||
|
||||
**Step 3: Save queue annotations in notes**
|
||||
- Add short execution-order markers in notes without changing status yet.
|
||||
|
||||
## Task 2: Write Failing Tests for Batch 1
|
||||
|
||||
**Files:**
|
||||
- Modify: `tests/NATS.Server.Tests/Protocol/`
|
||||
- Test: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
**Step 1: Add failing tests for first open row batch**
|
||||
- Create tests that reproduce the exact missing/partial Go behavior.
|
||||
|
||||
**Step 2: Run tests to confirm failure**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: FAIL in newly added tests only.
|
||||
|
||||
## Task 3: Implement Minimal Parity for Batch 1
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/NATS.Server/Protocol/NatsParser.cs`
|
||||
- Modify: additional category files listed in `gaps/protocol.md`
|
||||
|
||||
**Step 1: Implement minimal code to satisfy failing tests**
|
||||
- Mirror Go semantics for parsing, state transitions, limits, and side-effects required by the targeted rows.
|
||||
|
||||
**Step 2: Re-run tests for validation**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: PASS for batch-1 tests; no new regressions.
|
||||
|
||||
## Task 4: Close Remaining Batches Iteratively
|
||||
|
||||
**Files:**
|
||||
- Modify: category .NET source and test files referenced in `gaps/protocol.md`
|
||||
- Modify: `gaps/protocol.md`
|
||||
|
||||
**Step 1: Repeat test-first cycle for each remaining batch**
|
||||
- Add failing tests, implement minimal parity, then verify pass.
|
||||
|
||||
**Step 2: Update inventory status immediately after each closure**
|
||||
- Move rows to `PORTED` with exact .NET file:line references.
|
||||
- Keep `PARTIAL` only if explicit residual behavior remains.
|
||||
|
||||
## Task 5: Cross-Module Regression and Hardening
|
||||
|
||||
**Files:**
|
||||
- Test: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
**Step 1: Run full regression suite**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: PASS.
|
||||
|
||||
**Step 2: Add edge-case tests discovered during regression**
|
||||
- Capture any newly discovered divergence from Go and close it before completion.
|
||||
|
||||
## Task 6: Finalize Parity Bookkeeping
|
||||
|
||||
**Files:**
|
||||
- Modify: `gaps/protocol.md`
|
||||
- Modify: `gaps/stillmissing.md`
|
||||
|
||||
**Step 1: Ensure final status correctness**
|
||||
- Verify no unresolved `MISSING` rows remain for `protocol`.
|
||||
|
||||
**Step 2: Refresh LOC and percentage bookkeeping**
|
||||
- Recount category LOC and update summary rows in `gaps/stillmissing.md`.
|
||||
|
||||
**Step 3: Add concise changelog entry**
|
||||
- Record date, completed parity areas, and any justified deferred items.
|
||||
|
||||
## Completion Checklist
|
||||
- [ ] All prioritized `protocol` rows are `PORTED` or explicitly justified as `NOT_APPLICABLE`/`DEFERRED`.
|
||||
- [ ] New/updated tests demonstrate parity for all previously open rows.
|
||||
- [ ] `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release` passes.
|
||||
- [ ] `gaps/protocol.md` and `gaps/stillmissing.md` are fully synchronized.
|
||||
76
docs/plans/2026-02-25-gap-port-raft-design.md
Normal file
76
docs/plans/2026-02-25-gap-port-raft-design.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# RAFT Full Parity Design
|
||||
|
||||
**Date:** 2026-02-25
|
||||
**Category:** `raft`
|
||||
**Gap Inventory:** `gaps/raft.md`
|
||||
**Target Outcome:** Full Go-to-.NET behavioral parity for this category.
|
||||
|
||||
## Assumptions
|
||||
- Full parity is the required outcome.
|
||||
- No additional requirements gathering is needed for this pass.
|
||||
- Existing public .NET APIs are preserved unless parity requires targeted, documented adjustments.
|
||||
|
||||
## Current State Snapshot
|
||||
- `MISSING`: 99
|
||||
- `PARTIAL`: 38
|
||||
- `PORTED`: 46
|
||||
- `NOT_APPLICABLE`: 13
|
||||
- `DEFERRED`: 0
|
||||
- **Open parity work items:** 137
|
||||
|
||||
## Approaches Considered
|
||||
1. **Symbol-first closure (Recommended):** execute directly against each `MISSING` and `PARTIAL` row in `gaps/raft.md`, closing items in deterministic order.
|
||||
Trade-off: strongest traceability and auditability, but can require broad context switching.
|
||||
2. **Test-first closure:** derive all work from Go test scenarios first, then backfill missing symbols.
|
||||
Trade-off: maximizes behavioral confidence, but can miss non-test-covered API and helper parity.
|
||||
3. **Vertical runtime slices:** port connect/auth/pubsub/cluster flows end-to-end before moving to next slice.
|
||||
Trade-off: smoother integration validation, but weaker one-to-one mapping against inventory rows.
|
||||
|
||||
## Recommended Design
|
||||
### Architecture
|
||||
Use the gap inventory as the authoritative backlog. For each row, implement or complete the .NET equivalent, then attach test evidence and update the inventory status. Keep implementation inside existing category boundaries and only refactor when needed to match Go behavior.
|
||||
|
||||
### Components
|
||||
- **Backlog driver:** `gaps/raft.md` (row-level tracking for all parity items).
|
||||
- **Implementation surface:** category-specific .NET source files.
|
||||
- **Verification surface:** category-specific .NET tests plus cross-module regression tests.
|
||||
- **Parity bookkeeping:** updates to `gaps/raft.md` and `gaps/stillmissing.md` after each closure batch.
|
||||
|
||||
### Data Flow
|
||||
1. Read one `MISSING` or `PARTIAL` row from `gaps/raft.md`.
|
||||
2. Inspect referenced Go implementation and tests.
|
||||
3. Add/adjust .NET implementation in listed category files.
|
||||
4. Add failing .NET tests that reproduce the missing/partial behavior, then make them pass.
|
||||
5. Re-run targeted and regression tests.
|
||||
6. Update the row to `PORTED` (or keep `PARTIAL` with explicit residual notes).
|
||||
|
||||
### Error Handling and Risk Controls
|
||||
- Avoid broad rewrites; prefer narrow patches tied to specific inventory rows.
|
||||
- Preserve protocol and timing semantics when replacing Go concurrency constructs with .NET async patterns.
|
||||
- Treat edge cases in Go tests as mandatory parity requirements unless explicitly marked `NOT_APPLICABLE`.
|
||||
- Require evidence (tests + inventory status updates) before declaring row completion.
|
||||
|
||||
### Testing Strategy
|
||||
- Add or expand tests for each row moved from `MISSING`/`PARTIAL` toward `PORTED`.
|
||||
- Prioritize wire/protocol compatibility, lifecycle transitions, auth boundaries, and backpressure/timeout behavior.
|
||||
- Keep category-targeted tests fast; run full `NATS.Server.Tests` regression before closure.
|
||||
|
||||
### Definition of Done
|
||||
- All category rows are either `PORTED` or explicitly justified `NOT_APPLICABLE`/`DEFERRED`.
|
||||
- No unresolved `MISSING` or unqualified `PARTIAL` rows remain for this category.
|
||||
- Relevant .NET tests pass locally and parity evidence is written into inventory notes.
|
||||
|
||||
## Implementation Scope Inputs
|
||||
### Go Source Files
|
||||
- `golang/nats-server/server/raft.go`
|
||||
|
||||
### Go Test Files
|
||||
- `golang/nats-server/server/raft_test.go`
|
||||
- `golang/nats-server/server/raft_helpers_test.go`
|
||||
- `golang/nats-server/server/raft_chain_of_blocks_helpers_test.go`
|
||||
|
||||
### .NET Source Files
|
||||
- `src/NATS.Server/Raft/ (all 20 files)`
|
||||
|
||||
### .NET Test Files
|
||||
- `tests/NATS.Server.Tests/Raft/`
|
||||
103
docs/plans/2026-02-25-gap-port-raft-plan.md
Normal file
103
docs/plans/2026-02-25-gap-port-raft-plan.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# RAFT Gap Port Implementation Plan
|
||||
|
||||
> **For Codex:** REQUIRED SUB-SKILL: Use `executeplan` to implement this plan task-by-task.
|
||||
|
||||
**Goal:** Port all remaining `raft` gap inventory items to achieve full behavior parity with Go.
|
||||
|
||||
**Architecture:** Use the category gap inventory as the execution backlog. Drive work row-by-row from `MISSING` and `PARTIAL` toward `PORTED`, with test-first validation and explicit parity evidence in notes.
|
||||
|
||||
**Tech Stack:** .NET 10, C#, xUnit, existing `NATS.Server` runtime modules, Go NATS server reference source.
|
||||
|
||||
---
|
||||
|
||||
## Category Inputs
|
||||
- Gap Inventory: `gaps/raft.md`
|
||||
- Primary .NET Source Anchor: `src/NATS.Server/Raft/ (all 20 files)`
|
||||
- Primary .NET Test Anchor: `tests/NATS.Server.Tests/Raft/`
|
||||
- Full .NET test project: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
## Task 1: Freeze Row-Level Backlog
|
||||
|
||||
**Files:**
|
||||
- Modify: `gaps/raft.md`
|
||||
|
||||
**Step 1: Normalize open rows into an execution queue**
|
||||
- Split all `MISSING` and `PARTIAL` rows into ranked batches (highest runtime impact first).
|
||||
|
||||
**Step 2: Record acceptance criteria per row**
|
||||
- For each row, define exact behavioral parity checks (inputs, outputs, error paths, timing/concurrency expectations).
|
||||
|
||||
**Step 3: Save queue annotations in notes**
|
||||
- Add short execution-order markers in notes without changing status yet.
|
||||
|
||||
## Task 2: Write Failing Tests for Batch 1
|
||||
|
||||
**Files:**
|
||||
- Modify: `tests/NATS.Server.Tests/Raft/`
|
||||
- Test: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
**Step 1: Add failing tests for first open row batch**
|
||||
- Create tests that reproduce the exact missing/partial Go behavior.
|
||||
|
||||
**Step 2: Run tests to confirm failure**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: FAIL in newly added tests only.
|
||||
|
||||
## Task 3: Implement Minimal Parity for Batch 1
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/NATS.Server/Raft/ (all 20 files)`
|
||||
- Modify: additional category files listed in `gaps/raft.md`
|
||||
|
||||
**Step 1: Implement minimal code to satisfy failing tests**
|
||||
- Mirror Go semantics for parsing, state transitions, limits, and side-effects required by the targeted rows.
|
||||
|
||||
**Step 2: Re-run tests for validation**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: PASS for batch-1 tests; no new regressions.
|
||||
|
||||
## Task 4: Close Remaining Batches Iteratively
|
||||
|
||||
**Files:**
|
||||
- Modify: category .NET source and test files referenced in `gaps/raft.md`
|
||||
- Modify: `gaps/raft.md`
|
||||
|
||||
**Step 1: Repeat test-first cycle for each remaining batch**
|
||||
- Add failing tests, implement minimal parity, then verify pass.
|
||||
|
||||
**Step 2: Update inventory status immediately after each closure**
|
||||
- Move rows to `PORTED` with exact .NET file:line references.
|
||||
- Keep `PARTIAL` only if explicit residual behavior remains.
|
||||
|
||||
## Task 5: Cross-Module Regression and Hardening
|
||||
|
||||
**Files:**
|
||||
- Test: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
**Step 1: Run full regression suite**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: PASS.
|
||||
|
||||
**Step 2: Add edge-case tests discovered during regression**
|
||||
- Capture any newly discovered divergence from Go and close it before completion.
|
||||
|
||||
## Task 6: Finalize Parity Bookkeeping
|
||||
|
||||
**Files:**
|
||||
- Modify: `gaps/raft.md`
|
||||
- Modify: `gaps/stillmissing.md`
|
||||
|
||||
**Step 1: Ensure final status correctness**
|
||||
- Verify no unresolved `MISSING` rows remain for `raft`.
|
||||
|
||||
**Step 2: Refresh LOC and percentage bookkeeping**
|
||||
- Recount category LOC and update summary rows in `gaps/stillmissing.md`.
|
||||
|
||||
**Step 3: Add concise changelog entry**
|
||||
- Record date, completed parity areas, and any justified deferred items.
|
||||
|
||||
## Completion Checklist
|
||||
- [ ] All prioritized `raft` rows are `PORTED` or explicitly justified as `NOT_APPLICABLE`/`DEFERRED`.
|
||||
- [ ] New/updated tests demonstrate parity for all previously open rows.
|
||||
- [ ] `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release` passes.
|
||||
- [ ] `gaps/raft.md` and `gaps/stillmissing.md` are fully synchronized.
|
||||
76
docs/plans/2026-02-25-gap-port-routes-design.md
Normal file
76
docs/plans/2026-02-25-gap-port-routes-design.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# Routes Full Parity Design
|
||||
|
||||
**Date:** 2026-02-25
|
||||
**Category:** `routes`
|
||||
**Gap Inventory:** `gaps/routes.md`
|
||||
**Target Outcome:** Full Go-to-.NET behavioral parity for this category.
|
||||
|
||||
## Assumptions
|
||||
- Full parity is the required outcome.
|
||||
- No additional requirements gathering is needed for this pass.
|
||||
- Existing public .NET APIs are preserved unless parity requires targeted, documented adjustments.
|
||||
|
||||
## Current State Snapshot
|
||||
- `MISSING`: 33
|
||||
- `PARTIAL`: 21
|
||||
- `PORTED`: 4
|
||||
- `NOT_APPLICABLE`: 9
|
||||
- `DEFERRED`: 0
|
||||
- **Open parity work items:** 54
|
||||
|
||||
## Approaches Considered
|
||||
1. **Symbol-first closure (Recommended):** execute directly against each `MISSING` and `PARTIAL` row in `gaps/routes.md`, closing items in deterministic order.
|
||||
Trade-off: strongest traceability and auditability, but can require broad context switching.
|
||||
2. **Test-first closure:** derive all work from Go test scenarios first, then backfill missing symbols.
|
||||
Trade-off: maximizes behavioral confidence, but can miss non-test-covered API and helper parity.
|
||||
3. **Vertical runtime slices:** port connect/auth/pubsub/cluster flows end-to-end before moving to next slice.
|
||||
Trade-off: smoother integration validation, but weaker one-to-one mapping against inventory rows.
|
||||
|
||||
## Recommended Design
|
||||
### Architecture
|
||||
Use the gap inventory as the authoritative backlog. For each row, implement or complete the .NET equivalent, then attach test evidence and update the inventory status. Keep implementation inside existing category boundaries and only refactor when needed to match Go behavior.
|
||||
|
||||
### Components
|
||||
- **Backlog driver:** `gaps/routes.md` (row-level tracking for all parity items).
|
||||
- **Implementation surface:** category-specific .NET source files.
|
||||
- **Verification surface:** category-specific .NET tests plus cross-module regression tests.
|
||||
- **Parity bookkeeping:** updates to `gaps/routes.md` and `gaps/stillmissing.md` after each closure batch.
|
||||
|
||||
### Data Flow
|
||||
1. Read one `MISSING` or `PARTIAL` row from `gaps/routes.md`.
|
||||
2. Inspect referenced Go implementation and tests.
|
||||
3. Add/adjust .NET implementation in listed category files.
|
||||
4. Add failing .NET tests that reproduce the missing/partial behavior, then make them pass.
|
||||
5. Re-run targeted and regression tests.
|
||||
6. Update the row to `PORTED` (or keep `PARTIAL` with explicit residual notes).
|
||||
|
||||
### Error Handling and Risk Controls
|
||||
- Avoid broad rewrites; prefer narrow patches tied to specific inventory rows.
|
||||
- Preserve protocol and timing semantics when replacing Go concurrency constructs with .NET async patterns.
|
||||
- Treat edge cases in Go tests as mandatory parity requirements unless explicitly marked `NOT_APPLICABLE`.
|
||||
- Require evidence (tests + inventory status updates) before declaring row completion.
|
||||
|
||||
### Testing Strategy
|
||||
- Add or expand tests for each row moved from `MISSING`/`PARTIAL` toward `PORTED`.
|
||||
- Prioritize wire/protocol compatibility, lifecycle transitions, auth boundaries, and backpressure/timeout behavior.
|
||||
- Keep category-targeted tests fast; run full `NATS.Server.Tests` regression before closure.
|
||||
|
||||
### Definition of Done
|
||||
- All category rows are either `PORTED` or explicitly justified `NOT_APPLICABLE`/`DEFERRED`.
|
||||
- No unresolved `MISSING` or unqualified `PARTIAL` rows remain for this category.
|
||||
- Relevant .NET tests pass locally and parity evidence is written into inventory notes.
|
||||
|
||||
## Implementation Scope Inputs
|
||||
### Go Source Files
|
||||
- `golang/nats-server/server/route.go`
|
||||
|
||||
### Go Test Files
|
||||
- `golang/nats-server/server/routes_test.go`
|
||||
- `golang/nats-server/test/routes_test.go (integration)`
|
||||
- `golang/nats-server/test/new_routes_test.go (integration)`
|
||||
|
||||
### .NET Source Files
|
||||
- `src/NATS.Server/Routes/ (all files)`
|
||||
|
||||
### .NET Test Files
|
||||
- `tests/NATS.Server.Tests/Routes/`
|
||||
103
docs/plans/2026-02-25-gap-port-routes-plan.md
Normal file
103
docs/plans/2026-02-25-gap-port-routes-plan.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# Routes Gap Port Implementation Plan
|
||||
|
||||
> **For Codex:** REQUIRED SUB-SKILL: Use `executeplan` to implement this plan task-by-task.
|
||||
|
||||
**Goal:** Port all remaining `routes` gap inventory items to achieve full behavior parity with Go.
|
||||
|
||||
**Architecture:** Use the category gap inventory as the execution backlog. Drive work row-by-row from `MISSING` and `PARTIAL` toward `PORTED`, with test-first validation and explicit parity evidence in notes.
|
||||
|
||||
**Tech Stack:** .NET 10, C#, xUnit, existing `NATS.Server` runtime modules, Go NATS server reference source.
|
||||
|
||||
---
|
||||
|
||||
## Category Inputs
|
||||
- Gap Inventory: `gaps/routes.md`
|
||||
- Primary .NET Source Anchor: `src/NATS.Server/Routes/ (all files)`
|
||||
- Primary .NET Test Anchor: `tests/NATS.Server.Tests/Routes/`
|
||||
- Full .NET test project: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
## Task 1: Freeze Row-Level Backlog
|
||||
|
||||
**Files:**
|
||||
- Modify: `gaps/routes.md`
|
||||
|
||||
**Step 1: Normalize open rows into an execution queue**
|
||||
- Split all `MISSING` and `PARTIAL` rows into ranked batches (highest runtime impact first).
|
||||
|
||||
**Step 2: Record acceptance criteria per row**
|
||||
- For each row, define exact behavioral parity checks (inputs, outputs, error paths, timing/concurrency expectations).
|
||||
|
||||
**Step 3: Save queue annotations in notes**
|
||||
- Add short execution-order markers in notes without changing status yet.
|
||||
|
||||
## Task 2: Write Failing Tests for Batch 1
|
||||
|
||||
**Files:**
|
||||
- Modify: `tests/NATS.Server.Tests/Routes/`
|
||||
- Test: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
**Step 1: Add failing tests for first open row batch**
|
||||
- Create tests that reproduce the exact missing/partial Go behavior.
|
||||
|
||||
**Step 2: Run tests to confirm failure**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: FAIL in newly added tests only.
|
||||
|
||||
## Task 3: Implement Minimal Parity for Batch 1
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/NATS.Server/Routes/ (all files)`
|
||||
- Modify: additional category files listed in `gaps/routes.md`
|
||||
|
||||
**Step 1: Implement minimal code to satisfy failing tests**
|
||||
- Mirror Go semantics for parsing, state transitions, limits, and side-effects required by the targeted rows.
|
||||
|
||||
**Step 2: Re-run tests for validation**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: PASS for batch-1 tests; no new regressions.
|
||||
|
||||
## Task 4: Close Remaining Batches Iteratively
|
||||
|
||||
**Files:**
|
||||
- Modify: category .NET source and test files referenced in `gaps/routes.md`
|
||||
- Modify: `gaps/routes.md`
|
||||
|
||||
**Step 1: Repeat test-first cycle for each remaining batch**
|
||||
- Add failing tests, implement minimal parity, then verify pass.
|
||||
|
||||
**Step 2: Update inventory status immediately after each closure**
|
||||
- Move rows to `PORTED` with exact .NET file:line references.
|
||||
- Keep `PARTIAL` only if explicit residual behavior remains.
|
||||
|
||||
## Task 5: Cross-Module Regression and Hardening
|
||||
|
||||
**Files:**
|
||||
- Test: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
**Step 1: Run full regression suite**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: PASS.
|
||||
|
||||
**Step 2: Add edge-case tests discovered during regression**
|
||||
- Capture any newly discovered divergence from Go and close it before completion.
|
||||
|
||||
## Task 6: Finalize Parity Bookkeeping
|
||||
|
||||
**Files:**
|
||||
- Modify: `gaps/routes.md`
|
||||
- Modify: `gaps/stillmissing.md`
|
||||
|
||||
**Step 1: Ensure final status correctness**
|
||||
- Verify no unresolved `MISSING` rows remain for `routes`.
|
||||
|
||||
**Step 2: Refresh LOC and percentage bookkeeping**
|
||||
- Recount category LOC and update summary rows in `gaps/stillmissing.md`.
|
||||
|
||||
**Step 3: Add concise changelog entry**
|
||||
- Record date, completed parity areas, and any justified deferred items.
|
||||
|
||||
## Completion Checklist
|
||||
- [ ] All prioritized `routes` rows are `PORTED` or explicitly justified as `NOT_APPLICABLE`/`DEFERRED`.
|
||||
- [ ] New/updated tests demonstrate parity for all previously open rows.
|
||||
- [ ] `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release` passes.
|
||||
- [ ] `gaps/routes.md` and `gaps/stillmissing.md` are fully synchronized.
|
||||
81
docs/plans/2026-02-25-gap-port-subscriptions-design.md
Normal file
81
docs/plans/2026-02-25-gap-port-subscriptions-design.md
Normal file
@@ -0,0 +1,81 @@
|
||||
# Subscriptions Full Parity Design
|
||||
|
||||
**Date:** 2026-02-25
|
||||
**Category:** `subscriptions`
|
||||
**Gap Inventory:** `gaps/subscriptions.md`
|
||||
**Target Outcome:** Full Go-to-.NET behavioral parity for this category.
|
||||
|
||||
## Assumptions
|
||||
- Full parity is the required outcome.
|
||||
- No additional requirements gathering is needed for this pass.
|
||||
- Existing public .NET APIs are preserved unless parity requires targeted, documented adjustments.
|
||||
|
||||
## Current State Snapshot
|
||||
- `MISSING`: 22
|
||||
- `PARTIAL`: 6
|
||||
- `PORTED`: 49
|
||||
- `NOT_APPLICABLE`: 27
|
||||
- `DEFERRED`: 0
|
||||
- **Open parity work items:** 28
|
||||
|
||||
## Approaches Considered
|
||||
1. **Symbol-first closure (Recommended):** execute directly against each `MISSING` and `PARTIAL` row in `gaps/subscriptions.md`, closing items in deterministic order.
|
||||
Trade-off: strongest traceability and auditability, but can require broad context switching.
|
||||
2. **Test-first closure:** derive all work from Go test scenarios first, then backfill missing symbols.
|
||||
Trade-off: maximizes behavioral confidence, but can miss non-test-covered API and helper parity.
|
||||
3. **Vertical runtime slices:** port connect/auth/pubsub/cluster flows end-to-end before moving to next slice.
|
||||
Trade-off: smoother integration validation, but weaker one-to-one mapping against inventory rows.
|
||||
|
||||
## Recommended Design
|
||||
### Architecture
|
||||
Use the gap inventory as the authoritative backlog. For each row, implement or complete the .NET equivalent, then attach test evidence and update the inventory status. Keep implementation inside existing category boundaries and only refactor when needed to match Go behavior.
|
||||
|
||||
### Components
|
||||
- **Backlog driver:** `gaps/subscriptions.md` (row-level tracking for all parity items).
|
||||
- **Implementation surface:** category-specific .NET source files.
|
||||
- **Verification surface:** category-specific .NET tests plus cross-module regression tests.
|
||||
- **Parity bookkeeping:** updates to `gaps/subscriptions.md` and `gaps/stillmissing.md` after each closure batch.
|
||||
|
||||
### Data Flow
|
||||
1. Read one `MISSING` or `PARTIAL` row from `gaps/subscriptions.md`.
|
||||
2. Inspect referenced Go implementation and tests.
|
||||
3. Add/adjust .NET implementation in listed category files.
|
||||
4. Add failing .NET tests that reproduce the missing/partial behavior, then make them pass.
|
||||
5. Re-run targeted and regression tests.
|
||||
6. Update the row to `PORTED` (or keep `PARTIAL` with explicit residual notes).
|
||||
|
||||
### Error Handling and Risk Controls
|
||||
- Avoid broad rewrites; prefer narrow patches tied to specific inventory rows.
|
||||
- Preserve protocol and timing semantics when replacing Go concurrency constructs with .NET async patterns.
|
||||
- Treat edge cases in Go tests as mandatory parity requirements unless explicitly marked `NOT_APPLICABLE`.
|
||||
- Require evidence (tests + inventory status updates) before declaring row completion.
|
||||
|
||||
### Testing Strategy
|
||||
- Add or expand tests for each row moved from `MISSING`/`PARTIAL` toward `PORTED`.
|
||||
- Prioritize wire/protocol compatibility, lifecycle transitions, auth boundaries, and backpressure/timeout behavior.
|
||||
- Keep category-targeted tests fast; run full `NATS.Server.Tests` regression before closure.
|
||||
|
||||
### Definition of Done
|
||||
- All category rows are either `PORTED` or explicitly justified `NOT_APPLICABLE`/`DEFERRED`.
|
||||
- No unresolved `MISSING` or unqualified `PARTIAL` rows remain for this category.
|
||||
- Relevant .NET tests pass locally and parity evidence is written into inventory notes.
|
||||
|
||||
## Implementation Scope Inputs
|
||||
### Go Source Files
|
||||
- `golang/nats-server/server/sublist.go`
|
||||
- `golang/nats-server/server/subject_transform.go`
|
||||
|
||||
### Go Test Files
|
||||
- `golang/nats-server/server/sublist_test.go`
|
||||
- `golang/nats-server/server/subject_transform_test.go`
|
||||
|
||||
### .NET Source Files
|
||||
- `src/NATS.Server/Subscriptions/SubjectMatch.cs`
|
||||
- `src/NATS.Server/Subscriptions/SubList.cs`
|
||||
- `src/NATS.Server/Subscriptions/SubListResult.cs`
|
||||
- `src/NATS.Server/Subscriptions/Subscription.cs`
|
||||
- `All other files in src/NATS.Server/Subscriptions/`
|
||||
|
||||
### .NET Test Files
|
||||
- `tests/NATS.Server.Tests/Subscriptions/`
|
||||
- `tests/NATS.Server.Tests/SubList/`
|
||||
103
docs/plans/2026-02-25-gap-port-subscriptions-plan.md
Normal file
103
docs/plans/2026-02-25-gap-port-subscriptions-plan.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# Subscriptions Gap Port Implementation Plan
|
||||
|
||||
> **For Codex:** REQUIRED SUB-SKILL: Use `executeplan` to implement this plan task-by-task.
|
||||
|
||||
**Goal:** Port all remaining `subscriptions` gap inventory items to achieve full behavior parity with Go.
|
||||
|
||||
**Architecture:** Use the category gap inventory as the execution backlog. Drive work row-by-row from `MISSING` and `PARTIAL` toward `PORTED`, with test-first validation and explicit parity evidence in notes.
|
||||
|
||||
**Tech Stack:** .NET 10, C#, xUnit, existing `NATS.Server` runtime modules, Go NATS server reference source.
|
||||
|
||||
---
|
||||
|
||||
## Category Inputs
|
||||
- Gap Inventory: `gaps/subscriptions.md`
|
||||
- Primary .NET Source Anchor: `src/NATS.Server/Subscriptions/SubjectMatch.cs`
|
||||
- Primary .NET Test Anchor: `tests/NATS.Server.Tests/Subscriptions/`
|
||||
- Full .NET test project: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
## Task 1: Freeze Row-Level Backlog
|
||||
|
||||
**Files:**
|
||||
- Modify: `gaps/subscriptions.md`
|
||||
|
||||
**Step 1: Normalize open rows into an execution queue**
|
||||
- Split all `MISSING` and `PARTIAL` rows into ranked batches (highest runtime impact first).
|
||||
|
||||
**Step 2: Record acceptance criteria per row**
|
||||
- For each row, define exact behavioral parity checks (inputs, outputs, error paths, timing/concurrency expectations).
|
||||
|
||||
**Step 3: Save queue annotations in notes**
|
||||
- Add short execution-order markers in notes without changing status yet.
|
||||
|
||||
## Task 2: Write Failing Tests for Batch 1
|
||||
|
||||
**Files:**
|
||||
- Modify: `tests/NATS.Server.Tests/Subscriptions/`
|
||||
- Test: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
**Step 1: Add failing tests for first open row batch**
|
||||
- Create tests that reproduce the exact missing/partial Go behavior.
|
||||
|
||||
**Step 2: Run tests to confirm failure**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: FAIL in newly added tests only.
|
||||
|
||||
## Task 3: Implement Minimal Parity for Batch 1
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/NATS.Server/Subscriptions/SubjectMatch.cs`
|
||||
- Modify: additional category files listed in `gaps/subscriptions.md`
|
||||
|
||||
**Step 1: Implement minimal code to satisfy failing tests**
|
||||
- Mirror Go semantics for parsing, state transitions, limits, and side-effects required by the targeted rows.
|
||||
|
||||
**Step 2: Re-run tests for validation**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: PASS for batch-1 tests; no new regressions.
|
||||
|
||||
## Task 4: Close Remaining Batches Iteratively
|
||||
|
||||
**Files:**
|
||||
- Modify: category .NET source and test files referenced in `gaps/subscriptions.md`
|
||||
- Modify: `gaps/subscriptions.md`
|
||||
|
||||
**Step 1: Repeat test-first cycle for each remaining batch**
|
||||
- Add failing tests, implement minimal parity, then verify pass.
|
||||
|
||||
**Step 2: Update inventory status immediately after each closure**
|
||||
- Move rows to `PORTED` with exact .NET file:line references.
|
||||
- Keep `PARTIAL` only if explicit residual behavior remains.
|
||||
|
||||
## Task 5: Cross-Module Regression and Hardening
|
||||
|
||||
**Files:**
|
||||
- Test: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
**Step 1: Run full regression suite**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: PASS.
|
||||
|
||||
**Step 2: Add edge-case tests discovered during regression**
|
||||
- Capture any newly discovered divergence from Go and close it before completion.
|
||||
|
||||
## Task 6: Finalize Parity Bookkeeping
|
||||
|
||||
**Files:**
|
||||
- Modify: `gaps/subscriptions.md`
|
||||
- Modify: `gaps/stillmissing.md`
|
||||
|
||||
**Step 1: Ensure final status correctness**
|
||||
- Verify no unresolved `MISSING` rows remain for `subscriptions`.
|
||||
|
||||
**Step 2: Refresh LOC and percentage bookkeeping**
|
||||
- Recount category LOC and update summary rows in `gaps/stillmissing.md`.
|
||||
|
||||
**Step 3: Add concise changelog entry**
|
||||
- Record date, completed parity areas, and any justified deferred items.
|
||||
|
||||
## Completion Checklist
|
||||
- [ ] All prioritized `subscriptions` rows are `PORTED` or explicitly justified as `NOT_APPLICABLE`/`DEFERRED`.
|
||||
- [ ] New/updated tests demonstrate parity for all previously open rows.
|
||||
- [ ] `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release` passes.
|
||||
- [ ] `gaps/subscriptions.md` and `gaps/stillmissing.md` are fully synchronized.
|
||||
95
docs/plans/2026-02-25-gap-port-tls-security-design.md
Normal file
95
docs/plans/2026-02-25-gap-port-tls-security-design.md
Normal file
@@ -0,0 +1,95 @@
|
||||
# TLS / Security Full Parity Design
|
||||
|
||||
**Date:** 2026-02-25
|
||||
**Category:** `tls-security`
|
||||
**Gap Inventory:** `gaps/tls-security.md`
|
||||
**Target Outcome:** Full Go-to-.NET behavioral parity for this category.
|
||||
|
||||
## Assumptions
|
||||
- Full parity is the required outcome.
|
||||
- No additional requirements gathering is needed for this pass.
|
||||
- Existing public .NET APIs are preserved unless parity requires targeted, documented adjustments.
|
||||
|
||||
## Current State Snapshot
|
||||
- `MISSING`: 70
|
||||
- `PARTIAL`: 10
|
||||
- `PORTED`: 20
|
||||
- `NOT_APPLICABLE`: 45
|
||||
- `DEFERRED`: 0
|
||||
- **Open parity work items:** 80
|
||||
|
||||
## Approaches Considered
|
||||
1. **Symbol-first closure (Recommended):** execute directly against each `MISSING` and `PARTIAL` row in `gaps/tls-security.md`, closing items in deterministic order.
|
||||
Trade-off: strongest traceability and auditability, but can require broad context switching.
|
||||
2. **Test-first closure:** derive all work from Go test scenarios first, then backfill missing symbols.
|
||||
Trade-off: maximizes behavioral confidence, but can miss non-test-covered API and helper parity.
|
||||
3. **Vertical runtime slices:** port connect/auth/pubsub/cluster flows end-to-end before moving to next slice.
|
||||
Trade-off: smoother integration validation, but weaker one-to-one mapping against inventory rows.
|
||||
|
||||
## Recommended Design
|
||||
### Architecture
|
||||
Use the gap inventory as the authoritative backlog. For each row, implement or complete the .NET equivalent, then attach test evidence and update the inventory status. Keep implementation inside existing category boundaries and only refactor when needed to match Go behavior.
|
||||
|
||||
### Components
|
||||
- **Backlog driver:** `gaps/tls-security.md` (row-level tracking for all parity items).
|
||||
- **Implementation surface:** category-specific .NET source files.
|
||||
- **Verification surface:** category-specific .NET tests plus cross-module regression tests.
|
||||
- **Parity bookkeeping:** updates to `gaps/tls-security.md` and `gaps/stillmissing.md` after each closure batch.
|
||||
|
||||
### Data Flow
|
||||
1. Read one `MISSING` or `PARTIAL` row from `gaps/tls-security.md`.
|
||||
2. Inspect referenced Go implementation and tests.
|
||||
3. Add/adjust .NET implementation in listed category files.
|
||||
4. Add failing .NET tests that reproduce the missing/partial behavior, then make them pass.
|
||||
5. Re-run targeted and regression tests.
|
||||
6. Update the row to `PORTED` (or keep `PARTIAL` with explicit residual notes).
|
||||
|
||||
### Error Handling and Risk Controls
|
||||
- Avoid broad rewrites; prefer narrow patches tied to specific inventory rows.
|
||||
- Preserve protocol and timing semantics when replacing Go concurrency constructs with .NET async patterns.
|
||||
- Treat edge cases in Go tests as mandatory parity requirements unless explicitly marked `NOT_APPLICABLE`.
|
||||
- Require evidence (tests + inventory status updates) before declaring row completion.
|
||||
|
||||
### Testing Strategy
|
||||
- Add or expand tests for each row moved from `MISSING`/`PARTIAL` toward `PORTED`.
|
||||
- Prioritize wire/protocol compatibility, lifecycle transitions, auth boundaries, and backpressure/timeout behavior.
|
||||
- Keep category-targeted tests fast; run full `NATS.Server.Tests` regression before closure.
|
||||
|
||||
### Definition of Done
|
||||
- All category rows are either `PORTED` or explicitly justified `NOT_APPLICABLE`/`DEFERRED`.
|
||||
- No unresolved `MISSING` or unqualified `PARTIAL` rows remain for this category.
|
||||
- Relevant .NET tests pass locally and parity evidence is written into inventory notes.
|
||||
|
||||
## Implementation Scope Inputs
|
||||
### Go Source Files
|
||||
- `golang/nats-server/server/ocsp.go`
|
||||
- `golang/nats-server/server/ocsp_peer.go`
|
||||
- `golang/nats-server/server/ocsp_responsecache.go`
|
||||
- `golang/nats-server/server/ciphersuites.go`
|
||||
- `golang/nats-server/server/client_proxyproto.go`
|
||||
- `golang/nats-server/server/certidp/certidp.go`
|
||||
- `golang/nats-server/server/certidp/messages.go`
|
||||
- `golang/nats-server/server/certidp/ocsp_responder.go`
|
||||
- `golang/nats-server/server/certstore/certstore.go`
|
||||
- `golang/nats-server/server/certstore/certstore_other.go`
|
||||
- `golang/nats-server/server/certstore/certstore_windows.go`
|
||||
- `golang/nats-server/server/certstore/errors.go`
|
||||
|
||||
### Go Test Files
|
||||
- `golang/nats-server/test/ocsp_test.go (integration)`
|
||||
- `golang/nats-server/test/ocsp_peer_test.go (integration)`
|
||||
- `golang/nats-server/test/tls_test.go (integration)`
|
||||
- `golang/nats-server/server/certstore/certstore_windows_test.go`
|
||||
- `golang/nats-server/server/certidp/*_test.go`
|
||||
|
||||
### .NET Source Files
|
||||
- `src/NATS.Server/Tls/TlsHelper.cs`
|
||||
- `src/NATS.Server/Tls/TlsCertificateProvider.cs`
|
||||
- `src/NATS.Server/Tls/TlsConnectionState.cs`
|
||||
- `src/NATS.Server/Tls/TlsConnectionWrapper.cs`
|
||||
- `src/NATS.Server/Tls/TlsRateLimiter.cs`
|
||||
- `src/NATS.Server/Tls/PeekableStream.cs`
|
||||
- `src/NATS.Server/Tls/OcspConfig.cs`
|
||||
|
||||
### .NET Test Files
|
||||
- `tests/NATS.Server.Tests/ (TLS-related test files in root)`
|
||||
103
docs/plans/2026-02-25-gap-port-tls-security-plan.md
Normal file
103
docs/plans/2026-02-25-gap-port-tls-security-plan.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# TLS / Security Gap Port Implementation Plan
|
||||
|
||||
> **For Codex:** REQUIRED SUB-SKILL: Use `executeplan` to implement this plan task-by-task.
|
||||
|
||||
**Goal:** Port all remaining `tls-security` gap inventory items to achieve full behavior parity with Go.
|
||||
|
||||
**Architecture:** Use the category gap inventory as the execution backlog. Drive work row-by-row from `MISSING` and `PARTIAL` toward `PORTED`, with test-first validation and explicit parity evidence in notes.
|
||||
|
||||
**Tech Stack:** .NET 10, C#, xUnit, existing `NATS.Server` runtime modules, Go NATS server reference source.
|
||||
|
||||
---
|
||||
|
||||
## Category Inputs
|
||||
- Gap Inventory: `gaps/tls-security.md`
|
||||
- Primary .NET Source Anchor: `src/NATS.Server/Tls/TlsHelper.cs`
|
||||
- Primary .NET Test Anchor: `tests/NATS.Server.Tests/ (TLS-related test files in root)`
|
||||
- Full .NET test project: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
## Task 1: Freeze Row-Level Backlog
|
||||
|
||||
**Files:**
|
||||
- Modify: `gaps/tls-security.md`
|
||||
|
||||
**Step 1: Normalize open rows into an execution queue**
|
||||
- Split all `MISSING` and `PARTIAL` rows into ranked batches (highest runtime impact first).
|
||||
|
||||
**Step 2: Record acceptance criteria per row**
|
||||
- For each row, define exact behavioral parity checks (inputs, outputs, error paths, timing/concurrency expectations).
|
||||
|
||||
**Step 3: Save queue annotations in notes**
|
||||
- Add short execution-order markers in notes without changing status yet.
|
||||
|
||||
## Task 2: Write Failing Tests for Batch 1
|
||||
|
||||
**Files:**
|
||||
- Modify: `tests/NATS.Server.Tests/ (TLS-related test files in root)`
|
||||
- Test: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
**Step 1: Add failing tests for first open row batch**
|
||||
- Create tests that reproduce the exact missing/partial Go behavior.
|
||||
|
||||
**Step 2: Run tests to confirm failure**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: FAIL in newly added tests only.
|
||||
|
||||
## Task 3: Implement Minimal Parity for Batch 1
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/NATS.Server/Tls/TlsHelper.cs`
|
||||
- Modify: additional category files listed in `gaps/tls-security.md`
|
||||
|
||||
**Step 1: Implement minimal code to satisfy failing tests**
|
||||
- Mirror Go semantics for parsing, state transitions, limits, and side-effects required by the targeted rows.
|
||||
|
||||
**Step 2: Re-run tests for validation**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: PASS for batch-1 tests; no new regressions.
|
||||
|
||||
## Task 4: Close Remaining Batches Iteratively
|
||||
|
||||
**Files:**
|
||||
- Modify: category .NET source and test files referenced in `gaps/tls-security.md`
|
||||
- Modify: `gaps/tls-security.md`
|
||||
|
||||
**Step 1: Repeat test-first cycle for each remaining batch**
|
||||
- Add failing tests, implement minimal parity, then verify pass.
|
||||
|
||||
**Step 2: Update inventory status immediately after each closure**
|
||||
- Move rows to `PORTED` with exact .NET file:line references.
|
||||
- Keep `PARTIAL` only if explicit residual behavior remains.
|
||||
|
||||
## Task 5: Cross-Module Regression and Hardening
|
||||
|
||||
**Files:**
|
||||
- Test: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
**Step 1: Run full regression suite**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: PASS.
|
||||
|
||||
**Step 2: Add edge-case tests discovered during regression**
|
||||
- Capture any newly discovered divergence from Go and close it before completion.
|
||||
|
||||
## Task 6: Finalize Parity Bookkeeping
|
||||
|
||||
**Files:**
|
||||
- Modify: `gaps/tls-security.md`
|
||||
- Modify: `gaps/stillmissing.md`
|
||||
|
||||
**Step 1: Ensure final status correctness**
|
||||
- Verify no unresolved `MISSING` rows remain for `tls-security`.
|
||||
|
||||
**Step 2: Refresh LOC and percentage bookkeeping**
|
||||
- Recount category LOC and update summary rows in `gaps/stillmissing.md`.
|
||||
|
||||
**Step 3: Add concise changelog entry**
|
||||
- Record date, completed parity areas, and any justified deferred items.
|
||||
|
||||
## Completion Checklist
|
||||
- [ ] All prioritized `tls-security` rows are `PORTED` or explicitly justified as `NOT_APPLICABLE`/`DEFERRED`.
|
||||
- [ ] New/updated tests demonstrate parity for all previously open rows.
|
||||
- [ ] `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release` passes.
|
||||
- [ ] `gaps/tls-security.md` and `gaps/stillmissing.md` are fully synchronized.
|
||||
93
docs/plans/2026-02-25-gap-port-utilities-and-other-design.md
Normal file
93
docs/plans/2026-02-25-gap-port-utilities-and-other-design.md
Normal file
@@ -0,0 +1,93 @@
|
||||
# Utilities & Other Full Parity Design
|
||||
|
||||
**Date:** 2026-02-25
|
||||
**Category:** `utilities-and-other`
|
||||
**Gap Inventory:** `gaps/utilities-and-other.md`
|
||||
**Target Outcome:** Full Go-to-.NET behavioral parity for this category.
|
||||
|
||||
## Assumptions
|
||||
- Full parity is the required outcome.
|
||||
- No additional requirements gathering is needed for this pass.
|
||||
- Existing public .NET APIs are preserved unless parity requires targeted, documented adjustments.
|
||||
|
||||
## Current State Snapshot
|
||||
- `MISSING`: 62
|
||||
- `PARTIAL`: 10
|
||||
- `PORTED`: 92
|
||||
- `NOT_APPLICABLE`: 47
|
||||
- `DEFERRED`: 9
|
||||
- **Open parity work items:** 72
|
||||
|
||||
## Approaches Considered
|
||||
1. **Symbol-first closure (Recommended):** execute directly against each `MISSING` and `PARTIAL` row in `gaps/utilities-and-other.md`, closing items in deterministic order.
|
||||
Trade-off: strongest traceability and auditability, but can require broad context switching.
|
||||
2. **Test-first closure:** derive all work from Go test scenarios first, then backfill missing symbols.
|
||||
Trade-off: maximizes behavioral confidence, but can miss non-test-covered API and helper parity.
|
||||
3. **Vertical runtime slices:** port connect/auth/pubsub/cluster flows end-to-end before moving to next slice.
|
||||
Trade-off: smoother integration validation, but weaker one-to-one mapping against inventory rows.
|
||||
|
||||
## Recommended Design
|
||||
### Architecture
|
||||
Use the gap inventory as the authoritative backlog. For each row, implement or complete the .NET equivalent, then attach test evidence and update the inventory status. Keep implementation inside existing category boundaries and only refactor when needed to match Go behavior.
|
||||
|
||||
### Components
|
||||
- **Backlog driver:** `gaps/utilities-and-other.md` (row-level tracking for all parity items).
|
||||
- **Implementation surface:** category-specific .NET source files.
|
||||
- **Verification surface:** category-specific .NET tests plus cross-module regression tests.
|
||||
- **Parity bookkeeping:** updates to `gaps/utilities-and-other.md` and `gaps/stillmissing.md` after each closure batch.
|
||||
|
||||
### Data Flow
|
||||
1. Read one `MISSING` or `PARTIAL` row from `gaps/utilities-and-other.md`.
|
||||
2. Inspect referenced Go implementation and tests.
|
||||
3. Add/adjust .NET implementation in listed category files.
|
||||
4. Add failing .NET tests that reproduce the missing/partial behavior, then make them pass.
|
||||
5. Re-run targeted and regression tests.
|
||||
6. Update the row to `PORTED` (or keep `PARTIAL` with explicit residual notes).
|
||||
|
||||
### Error Handling and Risk Controls
|
||||
- Avoid broad rewrites; prefer narrow patches tied to specific inventory rows.
|
||||
- Preserve protocol and timing semantics when replacing Go concurrency constructs with .NET async patterns.
|
||||
- Treat edge cases in Go tests as mandatory parity requirements unless explicitly marked `NOT_APPLICABLE`.
|
||||
- Require evidence (tests + inventory status updates) before declaring row completion.
|
||||
|
||||
### Testing Strategy
|
||||
- Add or expand tests for each row moved from `MISSING`/`PARTIAL` toward `PORTED`.
|
||||
- Prioritize wire/protocol compatibility, lifecycle transitions, auth boundaries, and backpressure/timeout behavior.
|
||||
- Keep category-targeted tests fast; run full `NATS.Server.Tests` regression before closure.
|
||||
|
||||
### Definition of Done
|
||||
- All category rows are either `PORTED` or explicitly justified `NOT_APPLICABLE`/`DEFERRED`.
|
||||
- No unresolved `MISSING` or unqualified `PARTIAL` rows remain for this category.
|
||||
- Relevant .NET tests pass locally and parity evidence is written into inventory notes.
|
||||
|
||||
## Implementation Scope Inputs
|
||||
### Go Source Files
|
||||
- `golang/nats-server/server/util.go`
|
||||
- `golang/nats-server/server/ring.go`
|
||||
- `golang/nats-server/server/rate_counter.go`
|
||||
- `golang/nats-server/server/sendq.go`
|
||||
- `golang/nats-server/server/ipqueue.go`
|
||||
- `golang/nats-server/server/errors.go`
|
||||
- `golang/nats-server/server/errors_gen.go`
|
||||
- `golang/nats-server/server/sdm.go`
|
||||
- `golang/nats-server/server/scheduler.go`
|
||||
- `golang/nats-server/server/ats/ats.go`
|
||||
- `golang/nats-server/server/elastic/elastic.go`
|
||||
- `golang/nats-server/server/tpm/js_ek_tpm_windows.go`
|
||||
- `golang/nats-server/server/tpm/js_ek_tpm_other.go`
|
||||
- `golang/nats-server/internal/`
|
||||
|
||||
### Go Test Files
|
||||
- `golang/nats-server/server/util_test.go`
|
||||
- `golang/nats-server/server/ring_test.go`
|
||||
- `golang/nats-server/server/rate_counter_test.go`
|
||||
- `golang/nats-server/server/ipqueue_test.go`
|
||||
- `golang/nats-server/server/errors_test.go`
|
||||
|
||||
### .NET Source Files
|
||||
- `src/NATS.Server/IO/OutboundBufferPool.cs`
|
||||
- `src/NATS.Server/IO/AdaptiveReadBuffer.cs`
|
||||
- `src/NATS.Server/Server/AcceptLoopErrorHandler.cs`
|
||||
|
||||
### .NET Test Files
|
||||
- `tests/NATS.Server.Tests/IO/`
|
||||
103
docs/plans/2026-02-25-gap-port-utilities-and-other-plan.md
Normal file
103
docs/plans/2026-02-25-gap-port-utilities-and-other-plan.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# Utilities & Other Gap Port Implementation Plan
|
||||
|
||||
> **For Codex:** REQUIRED SUB-SKILL: Use `executeplan` to implement this plan task-by-task.
|
||||
|
||||
**Goal:** Port all remaining `utilities-and-other` gap inventory items to achieve full behavior parity with Go.
|
||||
|
||||
**Architecture:** Use the category gap inventory as the execution backlog. Drive work row-by-row from `MISSING` and `PARTIAL` toward `PORTED`, with test-first validation and explicit parity evidence in notes.
|
||||
|
||||
**Tech Stack:** .NET 10, C#, xUnit, existing `NATS.Server` runtime modules, Go NATS server reference source.
|
||||
|
||||
---
|
||||
|
||||
## Category Inputs
|
||||
- Gap Inventory: `gaps/utilities-and-other.md`
|
||||
- Primary .NET Source Anchor: `src/NATS.Server/IO/OutboundBufferPool.cs`
|
||||
- Primary .NET Test Anchor: `tests/NATS.Server.Tests/IO/`
|
||||
- Full .NET test project: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
## Task 1: Freeze Row-Level Backlog
|
||||
|
||||
**Files:**
|
||||
- Modify: `gaps/utilities-and-other.md`
|
||||
|
||||
**Step 1: Normalize open rows into an execution queue**
|
||||
- Split all `MISSING` and `PARTIAL` rows into ranked batches (highest runtime impact first).
|
||||
|
||||
**Step 2: Record acceptance criteria per row**
|
||||
- For each row, define exact behavioral parity checks (inputs, outputs, error paths, timing/concurrency expectations).
|
||||
|
||||
**Step 3: Save queue annotations in notes**
|
||||
- Add short execution-order markers in notes without changing status yet.
|
||||
|
||||
## Task 2: Write Failing Tests for Batch 1
|
||||
|
||||
**Files:**
|
||||
- Modify: `tests/NATS.Server.Tests/IO/`
|
||||
- Test: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
**Step 1: Add failing tests for first open row batch**
|
||||
- Create tests that reproduce the exact missing/partial Go behavior.
|
||||
|
||||
**Step 2: Run tests to confirm failure**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: FAIL in newly added tests only.
|
||||
|
||||
## Task 3: Implement Minimal Parity for Batch 1
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/NATS.Server/IO/OutboundBufferPool.cs`
|
||||
- Modify: additional category files listed in `gaps/utilities-and-other.md`
|
||||
|
||||
**Step 1: Implement minimal code to satisfy failing tests**
|
||||
- Mirror Go semantics for parsing, state transitions, limits, and side-effects required by the targeted rows.
|
||||
|
||||
**Step 2: Re-run tests for validation**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: PASS for batch-1 tests; no new regressions.
|
||||
|
||||
## Task 4: Close Remaining Batches Iteratively
|
||||
|
||||
**Files:**
|
||||
- Modify: category .NET source and test files referenced in `gaps/utilities-and-other.md`
|
||||
- Modify: `gaps/utilities-and-other.md`
|
||||
|
||||
**Step 1: Repeat test-first cycle for each remaining batch**
|
||||
- Add failing tests, implement minimal parity, then verify pass.
|
||||
|
||||
**Step 2: Update inventory status immediately after each closure**
|
||||
- Move rows to `PORTED` with exact .NET file:line references.
|
||||
- Keep `PARTIAL` only if explicit residual behavior remains.
|
||||
|
||||
## Task 5: Cross-Module Regression and Hardening
|
||||
|
||||
**Files:**
|
||||
- Test: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
**Step 1: Run full regression suite**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: PASS.
|
||||
|
||||
**Step 2: Add edge-case tests discovered during regression**
|
||||
- Capture any newly discovered divergence from Go and close it before completion.
|
||||
|
||||
## Task 6: Finalize Parity Bookkeeping
|
||||
|
||||
**Files:**
|
||||
- Modify: `gaps/utilities-and-other.md`
|
||||
- Modify: `gaps/stillmissing.md`
|
||||
|
||||
**Step 1: Ensure final status correctness**
|
||||
- Verify no unresolved `MISSING` rows remain for `utilities-and-other`.
|
||||
|
||||
**Step 2: Refresh LOC and percentage bookkeeping**
|
||||
- Recount category LOC and update summary rows in `gaps/stillmissing.md`.
|
||||
|
||||
**Step 3: Add concise changelog entry**
|
||||
- Record date, completed parity areas, and any justified deferred items.
|
||||
|
||||
## Completion Checklist
|
||||
- [ ] All prioritized `utilities-and-other` rows are `PORTED` or explicitly justified as `NOT_APPLICABLE`/`DEFERRED`.
|
||||
- [ ] New/updated tests demonstrate parity for all previously open rows.
|
||||
- [ ] `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release` passes.
|
||||
- [ ] `gaps/utilities-and-other.md` and `gaps/stillmissing.md` are fully synchronized.
|
||||
74
docs/plans/2026-02-25-gap-port-websocket-design.md
Normal file
74
docs/plans/2026-02-25-gap-port-websocket-design.md
Normal file
@@ -0,0 +1,74 @@
|
||||
# WebSocket Full Parity Design
|
||||
|
||||
**Date:** 2026-02-25
|
||||
**Category:** `websocket`
|
||||
**Gap Inventory:** `gaps/websocket.md`
|
||||
**Target Outcome:** Full Go-to-.NET behavioral parity for this category.
|
||||
|
||||
## Assumptions
|
||||
- Full parity is the required outcome.
|
||||
- No additional requirements gathering is needed for this pass.
|
||||
- Existing public .NET APIs are preserved unless parity requires targeted, documented adjustments.
|
||||
|
||||
## Current State Snapshot
|
||||
- `MISSING`: 5
|
||||
- `PARTIAL`: 6
|
||||
- `PORTED`: 39
|
||||
- `NOT_APPLICABLE`: 0
|
||||
- `DEFERRED`: 0
|
||||
- **Open parity work items:** 11
|
||||
|
||||
## Approaches Considered
|
||||
1. **Symbol-first closure (Recommended):** execute directly against each `MISSING` and `PARTIAL` row in `gaps/websocket.md`, closing items in deterministic order.
|
||||
Trade-off: strongest traceability and auditability, but can require broad context switching.
|
||||
2. **Test-first closure:** derive all work from Go test scenarios first, then backfill missing symbols.
|
||||
Trade-off: maximizes behavioral confidence, but can miss non-test-covered API and helper parity.
|
||||
3. **Vertical runtime slices:** port connect/auth/pubsub/cluster flows end-to-end before moving to next slice.
|
||||
Trade-off: smoother integration validation, but weaker one-to-one mapping against inventory rows.
|
||||
|
||||
## Recommended Design
|
||||
### Architecture
|
||||
Use the gap inventory as the authoritative backlog. For each row, implement or complete the .NET equivalent, then attach test evidence and update the inventory status. Keep implementation inside existing category boundaries and only refactor when needed to match Go behavior.
|
||||
|
||||
### Components
|
||||
- **Backlog driver:** `gaps/websocket.md` (row-level tracking for all parity items).
|
||||
- **Implementation surface:** category-specific .NET source files.
|
||||
- **Verification surface:** category-specific .NET tests plus cross-module regression tests.
|
||||
- **Parity bookkeeping:** updates to `gaps/websocket.md` and `gaps/stillmissing.md` after each closure batch.
|
||||
|
||||
### Data Flow
|
||||
1. Read one `MISSING` or `PARTIAL` row from `gaps/websocket.md`.
|
||||
2. Inspect referenced Go implementation and tests.
|
||||
3. Add/adjust .NET implementation in listed category files.
|
||||
4. Add failing .NET tests that reproduce the missing/partial behavior, then make them pass.
|
||||
5. Re-run targeted and regression tests.
|
||||
6. Update the row to `PORTED` (or keep `PARTIAL` with explicit residual notes).
|
||||
|
||||
### Error Handling and Risk Controls
|
||||
- Avoid broad rewrites; prefer narrow patches tied to specific inventory rows.
|
||||
- Preserve protocol and timing semantics when replacing Go concurrency constructs with .NET async patterns.
|
||||
- Treat edge cases in Go tests as mandatory parity requirements unless explicitly marked `NOT_APPLICABLE`.
|
||||
- Require evidence (tests + inventory status updates) before declaring row completion.
|
||||
|
||||
### Testing Strategy
|
||||
- Add or expand tests for each row moved from `MISSING`/`PARTIAL` toward `PORTED`.
|
||||
- Prioritize wire/protocol compatibility, lifecycle transitions, auth boundaries, and backpressure/timeout behavior.
|
||||
- Keep category-targeted tests fast; run full `NATS.Server.Tests` regression before closure.
|
||||
|
||||
### Definition of Done
|
||||
- All category rows are either `PORTED` or explicitly justified `NOT_APPLICABLE`/`DEFERRED`.
|
||||
- No unresolved `MISSING` or unqualified `PARTIAL` rows remain for this category.
|
||||
- Relevant .NET tests pass locally and parity evidence is written into inventory notes.
|
||||
|
||||
## Implementation Scope Inputs
|
||||
### Go Source Files
|
||||
- `golang/nats-server/server/websocket.go`
|
||||
|
||||
### Go Test Files
|
||||
- `golang/nats-server/server/websocket_test.go`
|
||||
|
||||
### .NET Source Files
|
||||
- `src/NATS.Server/WebSocket/ (all files)`
|
||||
|
||||
### .NET Test Files
|
||||
- `tests/NATS.Server.Tests/WebSocket/`
|
||||
103
docs/plans/2026-02-25-gap-port-websocket-plan.md
Normal file
103
docs/plans/2026-02-25-gap-port-websocket-plan.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# WebSocket Gap Port Implementation Plan
|
||||
|
||||
> **For Codex:** REQUIRED SUB-SKILL: Use `executeplan` to implement this plan task-by-task.
|
||||
|
||||
**Goal:** Port all remaining `websocket` gap inventory items to achieve full behavior parity with Go.
|
||||
|
||||
**Architecture:** Use the category gap inventory as the execution backlog. Drive work row-by-row from `MISSING` and `PARTIAL` toward `PORTED`, with test-first validation and explicit parity evidence in notes.
|
||||
|
||||
**Tech Stack:** .NET 10, C#, xUnit, existing `NATS.Server` runtime modules, Go NATS server reference source.
|
||||
|
||||
---
|
||||
|
||||
## Category Inputs
|
||||
- Gap Inventory: `gaps/websocket.md`
|
||||
- Primary .NET Source Anchor: `src/NATS.Server/WebSocket/ (all files)`
|
||||
- Primary .NET Test Anchor: `tests/NATS.Server.Tests/WebSocket/`
|
||||
- Full .NET test project: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
## Task 1: Freeze Row-Level Backlog
|
||||
|
||||
**Files:**
|
||||
- Modify: `gaps/websocket.md`
|
||||
|
||||
**Step 1: Normalize open rows into an execution queue**
|
||||
- Split all `MISSING` and `PARTIAL` rows into ranked batches (highest runtime impact first).
|
||||
|
||||
**Step 2: Record acceptance criteria per row**
|
||||
- For each row, define exact behavioral parity checks (inputs, outputs, error paths, timing/concurrency expectations).
|
||||
|
||||
**Step 3: Save queue annotations in notes**
|
||||
- Add short execution-order markers in notes without changing status yet.
|
||||
|
||||
## Task 2: Write Failing Tests for Batch 1
|
||||
|
||||
**Files:**
|
||||
- Modify: `tests/NATS.Server.Tests/WebSocket/`
|
||||
- Test: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
**Step 1: Add failing tests for first open row batch**
|
||||
- Create tests that reproduce the exact missing/partial Go behavior.
|
||||
|
||||
**Step 2: Run tests to confirm failure**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: FAIL in newly added tests only.
|
||||
|
||||
## Task 3: Implement Minimal Parity for Batch 1
|
||||
|
||||
**Files:**
|
||||
- Modify: `src/NATS.Server/WebSocket/ (all files)`
|
||||
- Modify: additional category files listed in `gaps/websocket.md`
|
||||
|
||||
**Step 1: Implement minimal code to satisfy failing tests**
|
||||
- Mirror Go semantics for parsing, state transitions, limits, and side-effects required by the targeted rows.
|
||||
|
||||
**Step 2: Re-run tests for validation**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: PASS for batch-1 tests; no new regressions.
|
||||
|
||||
## Task 4: Close Remaining Batches Iteratively
|
||||
|
||||
**Files:**
|
||||
- Modify: category .NET source and test files referenced in `gaps/websocket.md`
|
||||
- Modify: `gaps/websocket.md`
|
||||
|
||||
**Step 1: Repeat test-first cycle for each remaining batch**
|
||||
- Add failing tests, implement minimal parity, then verify pass.
|
||||
|
||||
**Step 2: Update inventory status immediately after each closure**
|
||||
- Move rows to `PORTED` with exact .NET file:line references.
|
||||
- Keep `PARTIAL` only if explicit residual behavior remains.
|
||||
|
||||
## Task 5: Cross-Module Regression and Hardening
|
||||
|
||||
**Files:**
|
||||
- Test: `tests/NATS.Server.Tests/NATS.Server.Tests.csproj`
|
||||
|
||||
**Step 1: Run full regression suite**
|
||||
- Run: `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release`
|
||||
- Expected: PASS.
|
||||
|
||||
**Step 2: Add edge-case tests discovered during regression**
|
||||
- Capture any newly discovered divergence from Go and close it before completion.
|
||||
|
||||
## Task 6: Finalize Parity Bookkeeping
|
||||
|
||||
**Files:**
|
||||
- Modify: `gaps/websocket.md`
|
||||
- Modify: `gaps/stillmissing.md`
|
||||
|
||||
**Step 1: Ensure final status correctness**
|
||||
- Verify no unresolved `MISSING` rows remain for `websocket`.
|
||||
|
||||
**Step 2: Refresh LOC and percentage bookkeeping**
|
||||
- Recount category LOC and update summary rows in `gaps/stillmissing.md`.
|
||||
|
||||
**Step 3: Add concise changelog entry**
|
||||
- Record date, completed parity areas, and any justified deferred items.
|
||||
|
||||
## Completion Checklist
|
||||
- [ ] All prioritized `websocket` rows are `PORTED` or explicitly justified as `NOT_APPLICABLE`/`DEFERRED`.
|
||||
- [ ] New/updated tests demonstrate parity for all previously open rows.
|
||||
- [ ] `dotnet test tests/NATS.Server.Tests/NATS.Server.Tests.csproj -c Release` passes.
|
||||
- [ ] `gaps/websocket.md` and `gaps/stillmissing.md` are fully synchronized.
|
||||
149
docs/plans/2026-03-12-e2e-extended-design.md
Normal file
149
docs/plans/2026-03-12-e2e-extended-design.md
Normal file
@@ -0,0 +1,149 @@
|
||||
# NATS.E2E.Tests Extended Coverage — Design
|
||||
|
||||
**Date:** 2026-03-12
|
||||
**Status:** Approved
|
||||
|
||||
## Overview
|
||||
|
||||
Extend the existing `NATS.E2E.Tests` project with phased test coverage that progressively exercises more complex NATS server functionality. All tests are black-box: the server runs as a child process, tests connect via `NATS.Client.Core` (and `NATS.Client.JetStream` for Phase 5).
|
||||
|
||||
## Infrastructure Extensions
|
||||
|
||||
### NatsServerProcess Changes
|
||||
|
||||
- Add optional `string[]? extraArgs` to constructor, appended after `-p <port>`
|
||||
- Add `WithConfigFile(string content)` static factory — writes content to a temp file, passes `-c <path>`, cleans up on dispose
|
||||
- Add `MonitorPort` property — allocates a second free port when monitoring is needed, passes `-m <port>`
|
||||
|
||||
### New Fixtures (Infrastructure/)
|
||||
|
||||
Each fixture gets its own `[CollectionDefinition]`:
|
||||
|
||||
| Fixture | Collection | Config |
|
||||
|---------|-----------|--------|
|
||||
| `NatsServerFixture` (existing) | `E2E` | Default, no auth/TLS/JS |
|
||||
| `AuthServerFixture` | `E2E-Auth` | Config file with users, tokens, NKeys, permissions |
|
||||
| `MonitorServerFixture` | `E2E-Monitor` | `-m <port>` for HTTP monitoring |
|
||||
| `TlsServerFixture` | `E2E-TLS` | Self-signed certs generated at startup, `--tlscert/--tlskey/--tlscacert` |
|
||||
| `AccountServerFixture` | `E2E-Accounts` | Config with two isolated accounts |
|
||||
| `JetStreamServerFixture` | `E2E-JetStream` | Config with `jetstream { store_dir: <tmpdir> }` |
|
||||
|
||||
### Shared Helper
|
||||
|
||||
`E2ETestHelper` static class:
|
||||
- `CreateClient(int port)` — returns `NatsConnection`
|
||||
- `Timeout(int seconds = 10)` — returns `CancellationToken`
|
||||
|
||||
### NuGet Additions
|
||||
|
||||
- `NATS.NKeys` — already in `Directory.Packages.props`, add to E2E csproj
|
||||
- `NATS.Client.JetStream` — add to `Directory.Packages.props` and E2E csproj
|
||||
|
||||
## Phase 1: Core Messaging (11 tests)
|
||||
|
||||
**File:** `CoreMessagingTests.cs` — `[Collection("E2E")]`
|
||||
|
||||
| Test | Verifies |
|
||||
|------|----------|
|
||||
| `WildcardStar_MatchesSingleToken` | Sub `foo.*`, pub `foo.bar` → received |
|
||||
| `WildcardGreaterThan_MatchesMultipleTokens` | Sub `foo.>`, pub `foo.bar.baz` → received |
|
||||
| `WildcardStar_DoesNotMatchMultipleTokens` | Sub `foo.*`, pub `foo.bar.baz` → no message |
|
||||
| `QueueGroup_LoadBalances` | 3 queue subs, 30 msgs → distributed across all 3 |
|
||||
| `QueueGroup_MixedWithPlainSub` | 1 plain + 2 queue subs → plain gets all, 1 queue gets each |
|
||||
| `Unsub_StopsDelivery` | Sub, unsub, pub → no message |
|
||||
| `Unsub_WithMaxMessages` | Auto-unsub after 3, pub 5 → only 3 received |
|
||||
| `FanOut_MultipleSubscribers` | 3 subs, 1 pub → all 3 receive |
|
||||
| `EchoOff_PublisherDoesNotReceiveSelf` | `echo: false`, self-pub → no echo |
|
||||
| `VerboseMode_OkResponses` | Raw socket, `verbose: true` → `+OK` after SUB |
|
||||
| `NoResponders_Returns503` | `no_responders: true`, request with no subs → 503 |
|
||||
|
||||
## Phase 2: Auth & Permissions (12 tests)
|
||||
|
||||
**File:** `AuthTests.cs` — `[Collection("E2E-Auth")]`
|
||||
|
||||
Config includes: user/pass pair, token, NKey public key, permission-restricted users, `max_subs: 5` user.
|
||||
|
||||
| Test | Verifies |
|
||||
|------|----------|
|
||||
| `UsernamePassword_ValidCredentials_Connects` | Correct user/pass → connected |
|
||||
| `UsernamePassword_InvalidPassword_Rejected` | Wrong pass → rejected |
|
||||
| `UsernamePassword_NoCredentials_Rejected` | No creds to auth server → rejected |
|
||||
| `TokenAuth_ValidToken_Connects` | Correct token → connected |
|
||||
| `TokenAuth_InvalidToken_Rejected` | Wrong token → rejected |
|
||||
| `NKeyAuth_ValidSignature_Connects` | Valid NKey sig → connected |
|
||||
| `NKeyAuth_InvalidSignature_Rejected` | Wrong NKey sig → rejected |
|
||||
| `Permission_PublishAllowed_Succeeds` | Pub to allowed subject → delivered |
|
||||
| `Permission_PublishDenied_NoDelivery` | Pub to denied subject → not delivered |
|
||||
| `Permission_SubscribeDenied_Rejected` | Sub to denied subject → rejected |
|
||||
| `MaxSubscriptions_ExceedsLimit_Rejected` | 6th sub on `max_subs: 5` user → rejected |
|
||||
| `MaxPayload_ExceedsLimit_Disconnected` | Oversized message → disconnected |
|
||||
|
||||
## Phase 3: Monitoring & Config (7 tests)
|
||||
|
||||
**File:** `MonitoringTests.cs` — `[Collection("E2E-Monitor")]`
|
||||
|
||||
Fixture exposes `MonitorPort` and `HttpClient MonitorClient`.
|
||||
|
||||
| Test | Verifies |
|
||||
|------|----------|
|
||||
| `Healthz_ReturnsOk` | `GET /healthz` → 200, `{"status":"ok"}` |
|
||||
| `Varz_ReturnsServerInfo` | `GET /varz` → JSON with `server_id`, `version`, `port` |
|
||||
| `Varz_ReflectsMessageCounts` | Publish msgs, `GET /varz` → `in_msgs > 0` |
|
||||
| `Connz_ListsActiveConnections` | 2 clients, `GET /connz` → `num_connections: 2` |
|
||||
| `Connz_SortByParameter` | `GET /connz?sort=bytes_to` → sorted |
|
||||
| `Connz_LimitAndOffset` | 5 clients, `GET /connz?limit=2&offset=1` → 2 entries |
|
||||
| `Subz_ReturnsSubscriptionStats` | Subs active, `GET /subz` → count > 0 |
|
||||
|
||||
## Phase 4: TLS & Account Isolation (6 tests)
|
||||
|
||||
**File:** `TlsTests.cs` — `[Collection("E2E-TLS")]`
|
||||
|
||||
Fixture generates self-signed CA + server cert + client cert using `System.Security.Cryptography` at startup.
|
||||
|
||||
| Test | Verifies |
|
||||
|------|----------|
|
||||
| `Tls_ClientConnectsSecurely` | TLS connect + ping succeeds |
|
||||
| `Tls_PlainTextConnection_Rejected` | Non-TLS connect → fails |
|
||||
| `Tls_PubSub_WorksOverEncryptedConnection` | Full pub/sub over TLS |
|
||||
|
||||
**File:** `AccountIsolationTests.cs` — `[Collection("E2E-Accounts")]`
|
||||
|
||||
Config with `ACCT_A` and `ACCT_B`, each with its own user.
|
||||
|
||||
| Test | Verifies |
|
||||
|------|----------|
|
||||
| `Accounts_SameAccount_MessageDelivered` | Two `ACCT_A` clients → pub/sub works |
|
||||
| `Accounts_CrossAccount_MessageNotDelivered` | `ACCT_A` pub, `ACCT_B` sub → no message |
|
||||
| `Accounts_EachAccountHasOwnNamespace` | Both accounts sub `foo.bar` independently |
|
||||
|
||||
## Phase 5: JetStream (10 tests)
|
||||
|
||||
**File:** `JetStreamTests.cs` — `[Collection("E2E-JetStream")]`
|
||||
|
||||
Fixture enables JetStream with temp `store_dir`.
|
||||
|
||||
| Test | Verifies |
|
||||
|------|----------|
|
||||
| `Stream_CreateAndInfo` | Create stream, verify info matches config |
|
||||
| `Stream_ListAndNames` | Create 3 streams, list/names returns all |
|
||||
| `Stream_Delete` | Create, delete, verify gone |
|
||||
| `Stream_PublishAndGet` | Publish msgs, get by sequence |
|
||||
| `Stream_Purge` | Publish, purge, verify count = 0 |
|
||||
| `Consumer_CreatePullAndConsume` | Pull consumer, publish 5, pull → receive 5 |
|
||||
| `Consumer_AckExplicit` | Explicit ack, verify no redelivery |
|
||||
| `Consumer_ListAndDelete` | Create consumers, list, delete, verify |
|
||||
| `Retention_LimitsMaxMessages` | `max_msgs: 10`, publish 15 → stream has 10 |
|
||||
| `Retention_MaxAge` | Short `max_age`, verify msgs expire |
|
||||
|
||||
## Test Count Summary
|
||||
|
||||
| Phase | Tests | New Files |
|
||||
|-------|-------|-----------|
|
||||
| 1 — Core Messaging | 11 | `CoreMessagingTests.cs` |
|
||||
| 2 — Auth & Permissions | 12 | `AuthTests.cs`, `AuthServerFixture.cs` |
|
||||
| 3 — Monitoring | 7 | `MonitoringTests.cs`, `MonitorServerFixture.cs` |
|
||||
| 4 — TLS & Accounts | 6 | `TlsTests.cs`, `TlsServerFixture.cs`, `AccountIsolationTests.cs`, `AccountServerFixture.cs` |
|
||||
| 5 — JetStream | 10 | `JetStreamTests.cs`, `JetStreamServerFixture.cs` |
|
||||
| **Total** | **46** | |
|
||||
|
||||
Plus infrastructure changes: `NatsServerProcess.cs` (edit), `E2ETestHelper.cs` (new).
|
||||
573
docs/plans/2026-03-12-e2e-extended-plan.md
Normal file
573
docs/plans/2026-03-12-e2e-extended-plan.md
Normal file
@@ -0,0 +1,573 @@
|
||||
# NATS.E2E.Tests Extended Coverage — Implementation Plan
|
||||
|
||||
**Date:** 2026-03-12
|
||||
**Design:** [2026-03-12-e2e-extended-design.md](2026-03-12-e2e-extended-design.md)
|
||||
|
||||
## Batch Structure
|
||||
|
||||
7 batches. Each batch is independently verifiable. Phases 1-5 from the design map to batches 2-6. Batch 1 is infrastructure. Batch 7 is final verification.
|
||||
|
||||
| Batch | Steps | Can Parallelize |
|
||||
|-------|-------|-----------------|
|
||||
| 1 — Infrastructure | Steps 1-4 | Steps 2-4 in parallel after Step 1 |
|
||||
| 2 — Phase 1: Core Messaging | Step 5 | No |
|
||||
| 3 — Phase 2: Auth & Permissions | Steps 6-7 | No (fixture then tests) |
|
||||
| 4 — Phase 3: Monitoring | Steps 8-9 | No |
|
||||
| 5 — Phase 4: TLS & Accounts | Steps 10-13 | Steps 10-11 parallel, Steps 12-13 parallel |
|
||||
| 6 — Phase 5: JetStream | Steps 14-15 | No |
|
||||
| 7 — Final Verification | Step 16 | No |
|
||||
|
||||
---
|
||||
|
||||
## Batch 1: Infrastructure
|
||||
|
||||
### Step 1: Update NuGet packages and csproj
|
||||
|
||||
**Files:**
|
||||
- `Directory.Packages.props` (edit)
|
||||
- `tests/NATS.E2E.Tests/NATS.E2E.Tests.csproj` (edit)
|
||||
|
||||
**Details:**
|
||||
|
||||
Add to `Directory.Packages.props`:
|
||||
```xml
|
||||
<PackageVersion Include="NATS.Client.JetStream" Version="2.7.2" />
|
||||
```
|
||||
|
||||
Add to `NATS.E2E.Tests.csproj` `<ItemGroup>`:
|
||||
```xml
|
||||
<PackageReference Include="NATS.NKeys" />
|
||||
<PackageReference Include="NATS.Client.JetStream" />
|
||||
```
|
||||
|
||||
**Verify:** `dotnet build tests/NATS.E2E.Tests` succeeds.
|
||||
|
||||
---
|
||||
|
||||
### Step 2: Extend NatsServerProcess
|
||||
|
||||
**Files:**
|
||||
- `tests/NATS.E2E.Tests/Infrastructure/NatsServerProcess.cs` (edit)
|
||||
|
||||
**Details:**
|
||||
|
||||
Add to the class:
|
||||
|
||||
1. **New constructor overload**: `NatsServerProcess(string[]? extraArgs = null, string? configContent = null, bool enableMonitoring = false)`
|
||||
- Stores `_extraArgs`, `_configContent`, `_enableMonitoring`
|
||||
- If `enableMonitoring`, allocate a second free port → `MonitorPort`
|
||||
- Keep existing no-arg constructor as-is (calls new one with defaults)
|
||||
|
||||
2. **New property**: `int? MonitorPort { get; }`
|
||||
|
||||
3. **Config file support in `StartAsync()`**:
|
||||
- If `_configContent` is not null, write to a temp file (`Path.GetTempFileName()` with `.conf` extension), store path in `_configFilePath`
|
||||
- Build args: `exec "{dll}" -p {Port}` + (if config: `-c {_configFilePath}`) + (if monitoring: `-m {MonitorPort}`) + (extra args)
|
||||
|
||||
4. **Cleanup in `DisposeAsync()`**: Delete `_configFilePath` if it exists.
|
||||
|
||||
5. **Static factory**: `static NatsServerProcess WithConfig(string configContent, bool enableMonitoring = false)` — convenience for creating with config.
|
||||
|
||||
**Verify:** `dotnet build tests/NATS.E2E.Tests` succeeds. Existing tests still pass (`dotnet test tests/NATS.E2E.Tests`).
|
||||
|
||||
---
|
||||
|
||||
### Step 3: Create E2ETestHelper
|
||||
|
||||
**Files:**
|
||||
- `tests/NATS.E2E.Tests/Infrastructure/E2ETestHelper.cs` (new)
|
||||
|
||||
**Details:**
|
||||
|
||||
```csharp
|
||||
namespace NATS.E2E.Tests.Infrastructure;
|
||||
|
||||
public static class E2ETestHelper
|
||||
{
|
||||
public static NatsConnection CreateClient(int port)
|
||||
=> new(new NatsOpts { Url = $"nats://127.0.0.1:{port}" });
|
||||
|
||||
public static NatsConnection CreateClient(int port, NatsOpts opts)
|
||||
=> new(opts with { Url = $"nats://127.0.0.1:{port}" });
|
||||
|
||||
public static CancellationToken Timeout(int seconds = 10)
|
||||
=> new CancellationTokenSource(TimeSpan.FromSeconds(seconds)).Token;
|
||||
}
|
||||
```
|
||||
|
||||
**Verify:** Builds.
|
||||
|
||||
---
|
||||
|
||||
### Step 4: Create collection definitions file
|
||||
|
||||
**Files:**
|
||||
- `tests/NATS.E2E.Tests/Infrastructure/Collections.cs` (new)
|
||||
|
||||
**Details:**
|
||||
|
||||
Move existing `E2ECollection` from `NatsServerFixture.cs` into this file. Add all collection definitions:
|
||||
|
||||
```csharp
|
||||
[CollectionDefinition("E2E")]
|
||||
public class E2ECollection : ICollectionFixture<NatsServerFixture>;
|
||||
|
||||
[CollectionDefinition("E2E-Auth")]
|
||||
public class AuthCollection : ICollectionFixture<AuthServerFixture>;
|
||||
|
||||
[CollectionDefinition("E2E-Monitor")]
|
||||
public class MonitorCollection : ICollectionFixture<MonitorServerFixture>;
|
||||
|
||||
[CollectionDefinition("E2E-TLS")]
|
||||
public class TlsCollection : ICollectionFixture<TlsServerFixture>;
|
||||
|
||||
[CollectionDefinition("E2E-Accounts")]
|
||||
public class AccountsCollection : ICollectionFixture<AccountServerFixture>;
|
||||
|
||||
[CollectionDefinition("E2E-JetStream")]
|
||||
public class JetStreamCollection : ICollectionFixture<JetStreamServerFixture>;
|
||||
```
|
||||
|
||||
Remove `E2ECollection` from `NatsServerFixture.cs`.
|
||||
|
||||
Note: The fixture classes referenced here (AuthServerFixture, etc.) don't exist yet — they'll be created in later steps. This file will have build errors until then; that's fine as long as we build after each batch completes.
|
||||
|
||||
Actually — to keep each batch independently verifiable, only add the `E2E` collection definition here in Step 4. The other collection definitions will be added in their respective fixture files in later batches.
|
||||
|
||||
**Verify:** `dotnet test tests/NATS.E2E.Tests` — existing 3 tests still pass.
|
||||
|
||||
---
|
||||
|
||||
## Batch 2: Phase 1 — Core Messaging
|
||||
|
||||
### Step 5: Implement CoreMessagingTests
|
||||
|
||||
**Files:**
|
||||
- `tests/NATS.E2E.Tests/CoreMessagingTests.cs` (new)
|
||||
|
||||
**Details:**
|
||||
|
||||
`[Collection("E2E")]` — uses existing `NatsServerFixture`. Primary constructor takes `NatsServerFixture fixture`.
|
||||
|
||||
**11 tests:**
|
||||
|
||||
1. **`WildcardStar_MatchesSingleToken`**: Sub `foo.*`, pub `foo.bar` → assert received with correct data.
|
||||
|
||||
2. **`WildcardGreaterThan_MatchesMultipleTokens`**: Sub `foo.>`, pub `foo.bar.baz` → assert received.
|
||||
|
||||
3. **`WildcardStar_DoesNotMatchMultipleTokens`**: Sub `foo.*`, pub `foo.bar.baz` → assert NO message within 1s timeout (use `Task.WhenAny` with short delay to prove no delivery).
|
||||
|
||||
4. **`QueueGroup_LoadBalances`**: 3 clients sub to `qtest` with queue group `workers`. Pub client sends 30 messages. Each sub collects received messages. Assert: total across all 3 = 30, each sub got at least 1 (no single sub got all).
|
||||
|
||||
5. **`QueueGroup_MixedWithPlainSub`**: 1 plain sub + 2 queue subs on `qmix`. Pub 10 messages. Plain sub should get all 10. Queue subs combined should get 10 (each message to exactly 1 queue sub).
|
||||
|
||||
6. **`Unsub_StopsDelivery`**: Sub to `unsub.test`, ping to flush, then unsubscribe, pub → assert no message within 1s.
|
||||
|
||||
7. **`Unsub_WithMaxMessages`**: Sub to `maxmsg.test`. Use raw socket or low-level NATS protocol to send `UNSUB sid 3`. Pub 5 messages → assert exactly 3 received. Note: NATS.Client.Core may not expose auto-unsub-after-N directly. If not, use raw socket for this test.
|
||||
|
||||
8. **`FanOut_MultipleSubscribers`**: 3 clients sub to `fanout.test`. Pub 1 message. All 3 receive it.
|
||||
|
||||
9. **`EchoOff_PublisherDoesNotReceiveSelf`**: Connect with `NatsOpts { Echo = false }`. Sub to `echo.test`, pub to `echo.test`. Assert no message within 1s. Then connect a second client (default echo=true), sub and pub → that client DOES receive its own message (as control).
|
||||
|
||||
10. **`VerboseMode_OkResponses`**: Use raw `TcpClient`/`NetworkStream`. Send `CONNECT {"verbose":true}\r\n` → read `+OK`. Send `SUB test 1\r\n` → read `+OK`. Send `PING\r\n` → read `PONG`.
|
||||
|
||||
11. **`NoResponders_Returns503`**: Connect with `NatsOpts { Headers = true, NoResponders = true }` (check if NATS.Client.Core exposes this). Send request to subject with no subscribers → expect exception or 503 status in reply headers.
|
||||
|
||||
For negative tests (no message expected), use a short 500ms-1s timeout with `Task.WhenAny(readTask, Task.Delay(1000))` pattern — assert the delay wins.
|
||||
|
||||
**Verify:** `dotnet test tests/NATS.E2E.Tests` — all 14 tests pass (3 original + 11 new).
|
||||
|
||||
---
|
||||
|
||||
## Batch 3: Phase 2 — Auth & Permissions
|
||||
|
||||
### Step 6: Implement AuthServerFixture
|
||||
|
||||
**Files:**
|
||||
- `tests/NATS.E2E.Tests/Infrastructure/AuthServerFixture.cs` (new)
|
||||
|
||||
**Details:**
|
||||
|
||||
Class `AuthServerFixture : IAsyncLifetime`.
|
||||
|
||||
At construction time, generate an NKey pair using `NATS.NKeys`:
|
||||
```csharp
|
||||
var kp = KeyPair.CreateUser();
|
||||
NKeyPublicKey = kp.EncodedPublicKey; // starts with 'U'
|
||||
NKeySeed = kp.EncodedSeed; // starts with 'SU'
|
||||
```
|
||||
|
||||
Store these as public properties so tests can use them.
|
||||
|
||||
Config content (NATS conf format):
|
||||
```
|
||||
max_payload: 512
|
||||
authorization {
|
||||
users = [
|
||||
{ user: "testuser", password: "testpass" }
|
||||
{ user: "tokenuser", password: "s3cret_token" }
|
||||
{ user: "pubonly", password: "pubpass", permissions: { publish: { allow: ["allowed.>"] }, subscribe: { allow: ["_INBOX.>"] } } }
|
||||
{ user: "subonly", password: "subpass", permissions: { subscribe: { allow: ["allowed.>", "_INBOX.>"] }, publish: { allow: ["_INBOX.>"] } } }
|
||||
{ user: "limited", password: "limpass", permissions: { publish: ">", subscribe: ">" } }
|
||||
{ nkey: "<NKEY_PUBLIC_KEY>" }
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Wait — token auth uses `authorization { token: "..." }` which is separate from users. We can't mix both in one config. Instead, use separate users for each auth mechanism and test user/pass. For token auth, we need a separate fixture or a workaround.
|
||||
|
||||
Simpler approach: use a config with `users` only (user/pass, nkeys, permissions). For token auth, we can test it with a dedicated `NatsServerProcess` instance inside the test itself (create server, run test, dispose). This keeps the fixture simple.
|
||||
|
||||
Actually, let's keep it simpler: make AuthServerFixture handle user/pass + nkeys + permissions. Add the token tests and max_payload test as standalone tests that spin up their own mini-server via `NatsServerProcess`.
|
||||
|
||||
Properties exposed:
|
||||
- `int Port`
|
||||
- `string NKeyPublicKey`
|
||||
- `string NKeySeed`
|
||||
- `NatsConnection CreateClient(string user, string password)` — connects with credentials
|
||||
- `NatsConnection CreateClient()` — connects without credentials (should fail on auth-required server)
|
||||
|
||||
Collection definition: `[CollectionDefinition("E2E-Auth")]` in this file.
|
||||
|
||||
**Verify:** Builds.
|
||||
|
||||
---
|
||||
|
||||
### Step 7: Implement AuthTests
|
||||
|
||||
**Files:**
|
||||
- `tests/NATS.E2E.Tests/AuthTests.cs` (new)
|
||||
|
||||
**Details:**
|
||||
|
||||
`[Collection("E2E-Auth")]` with `AuthServerFixture fixture`.
|
||||
|
||||
**12 tests:**
|
||||
|
||||
1. **`UsernamePassword_ValidCredentials_Connects`**: `fixture.CreateClient("testuser", "testpass")` → connect, ping → succeeds.
|
||||
|
||||
2. **`UsernamePassword_InvalidPassword_Rejected`**: Connect with wrong password → expect `NatsException` on connect.
|
||||
|
||||
3. **`UsernamePassword_NoCredentials_Rejected`**: `fixture.CreateClient()` (no creds) → expect connection error.
|
||||
|
||||
4. **`TokenAuth_ValidToken_Connects`**: Spin up a temp `NatsServerProcess` with config `authorization { token: "s3cret" }`. Connect with `NatsOpts { AuthToken = "s3cret" }` → succeeds.
|
||||
|
||||
5. **`TokenAuth_InvalidToken_Rejected`**: Same temp server, wrong token → rejected.
|
||||
|
||||
6. **`NKeyAuth_ValidSignature_Connects`**: Connect with `NatsOpts` configured for NKey auth using `fixture.NKeySeed` → succeeds.
|
||||
|
||||
7. **`NKeyAuth_InvalidSignature_Rejected`**: Connect with a different NKey seed → rejected.
|
||||
|
||||
8. **`Permission_PublishAllowed_Succeeds`**: `pubonly` user pubs to `allowed.foo`, `testuser` sub on same → message delivered.
|
||||
|
||||
9. **`Permission_PublishDenied_NoDelivery`**: `pubonly` user pubs to `denied.foo` → permission violation, message not delivered.
|
||||
|
||||
10. **`Permission_SubscribeDenied_Rejected`**: `pubonly` user tries to sub to `denied.foo` → error or no messages.
|
||||
|
||||
11. **`MaxSubscriptions_ExceedsLimit_Rejected`**: Use `limited` user config with `max_subs: 5` added to fixture config. Create 6 subs → last one triggers error.
|
||||
|
||||
12. **`MaxPayload_ExceedsLimit_Disconnected`**: Fixture config has `max_payload: 512`. Send message > 512 bytes → connection closed.
|
||||
|
||||
For tests 4-5 (token auth): create/dispose their own `NatsServerProcess` within the test. Use `await using` for cleanup.
|
||||
|
||||
**Verify:** `dotnet test tests/NATS.E2E.Tests` — all 25 tests pass (14 + 11 new; token tests may take slightly longer due to extra server startup).
|
||||
|
||||
Note: Token tests spin up independent servers, so they'll be slightly slower. That's acceptable for E2E.
|
||||
|
||||
---
|
||||
|
||||
## Batch 4: Phase 3 — Monitoring
|
||||
|
||||
### Step 8: Implement MonitorServerFixture
|
||||
|
||||
**Files:**
|
||||
- `tests/NATS.E2E.Tests/Infrastructure/MonitorServerFixture.cs` (new)
|
||||
|
||||
**Details:**
|
||||
|
||||
Class `MonitorServerFixture : IAsyncLifetime`.
|
||||
|
||||
Creates `NatsServerProcess` with `enableMonitoring: true`. This passes `-m <port>` to the server.
|
||||
|
||||
Properties:
|
||||
- `int Port` — NATS client port
|
||||
- `int MonitorPort` — HTTP monitoring port
|
||||
- `HttpClient MonitorClient` — pre-configured with `BaseAddress = new Uri($"http://127.0.0.1:{MonitorPort}")`
|
||||
- `NatsConnection CreateClient()`
|
||||
|
||||
Dispose: dispose `HttpClient` and server process.
|
||||
|
||||
Collection definition: `[CollectionDefinition("E2E-Monitor")]` in this file.
|
||||
|
||||
**Verify:** Builds.
|
||||
|
||||
---
|
||||
|
||||
### Step 9: Implement MonitoringTests
|
||||
|
||||
**Files:**
|
||||
- `tests/NATS.E2E.Tests/MonitoringTests.cs` (new)
|
||||
|
||||
**Details:**
|
||||
|
||||
`[Collection("E2E-Monitor")]` with `MonitorServerFixture fixture`.
|
||||
|
||||
All tests use `fixture.MonitorClient` for HTTP calls and `System.Text.Json.JsonDocument` for JSON parsing.
|
||||
|
||||
**7 tests:**
|
||||
|
||||
1. **`Healthz_ReturnsOk`**: `GET /healthz` → 200, body contains `"status"` key with value `"ok"`.
|
||||
|
||||
2. **`Varz_ReturnsServerInfo`**: `GET /varz` → 200, JSON has `server_id` (non-empty string), `version`, `port` (matches fixture port).
|
||||
|
||||
3. **`Varz_ReflectsMessageCounts`**: Connect client, pub 5 messages to a subject (with a sub to ensure delivery). `GET /varz` → `in_msgs` >= 5.
|
||||
|
||||
4. **`Connz_ListsActiveConnections`**: Connect 2 clients, ping both. `GET /connz` → `num_connections` >= 2, `connections` array has entries.
|
||||
|
||||
5. **`Connz_SortByParameter`**: Connect 3 clients, send different amounts of data. `GET /connz?sort=bytes_to` → `connections` array returned (verify it doesn't error; exact sort validation optional).
|
||||
|
||||
6. **`Connz_LimitAndOffset`**: Connect 5 clients. `GET /connz?limit=2&offset=1` → `connections` array has exactly 2 entries.
|
||||
|
||||
7. **`Subz_ReturnsSubscriptionStats`**: Connect client, sub to 3 subjects. `GET /subz` → response has subscription data, `num_subscriptions` > 0.
|
||||
|
||||
**Verify:** `dotnet test tests/NATS.E2E.Tests` — all 32 tests pass (25 + 7).
|
||||
|
||||
---
|
||||
|
||||
## Batch 5: Phase 4 — TLS & Accounts
|
||||
|
||||
### Step 10: Implement TlsServerFixture
|
||||
|
||||
**Files:**
|
||||
- `tests/NATS.E2E.Tests/Infrastructure/TlsServerFixture.cs` (new)
|
||||
|
||||
**Details:**
|
||||
|
||||
Class `TlsServerFixture : IAsyncLifetime`.
|
||||
|
||||
In `InitializeAsync()`:
|
||||
1. Create a temp directory for certs.
|
||||
2. Generate self-signed CA, server cert, client cert using `System.Security.Cryptography`:
|
||||
- CA: RSA 2048, self-signed, `CN=E2E Test CA`
|
||||
- Server cert: RSA 2048, signed by CA, `CN=localhost`, SAN=`127.0.0.1`
|
||||
- Client cert: RSA 2048, signed by CA, `CN=testclient`
|
||||
3. Export to PEM files in temp dir: `ca.pem`, `server-cert.pem`, `server-key.pem`, `client-cert.pem`, `client-key.pem`
|
||||
4. Create `NatsServerProcess` with config:
|
||||
```
|
||||
listen: "0.0.0.0:{port}"
|
||||
tls {
|
||||
cert_file: "{server-cert.pem}"
|
||||
key_file: "{server-key.pem}"
|
||||
ca_file: "{ca.pem}"
|
||||
}
|
||||
```
|
||||
5. Start server.
|
||||
|
||||
Properties:
|
||||
- `int Port`
|
||||
- `string CaCertPath`, `string ClientCertPath`, `string ClientKeyPath`
|
||||
- `NatsConnection CreateTlsClient()` — creates client with TLS configured, trusting the test CA
|
||||
- `NatsConnection CreatePlainClient()` — creates client WITHOUT TLS (for rejection test)
|
||||
|
||||
Dispose: stop server, delete temp cert directory.
|
||||
|
||||
Collection definition: `[CollectionDefinition("E2E-TLS")]` in this file.
|
||||
|
||||
**Verify:** Builds.
|
||||
|
||||
---
|
||||
|
||||
### Step 11: Implement AccountServerFixture
|
||||
|
||||
**Files:**
|
||||
- `tests/NATS.E2E.Tests/Infrastructure/AccountServerFixture.cs` (new)
|
||||
|
||||
**Details:**
|
||||
|
||||
Class `AccountServerFixture : IAsyncLifetime`.
|
||||
|
||||
Config:
|
||||
```
|
||||
accounts {
|
||||
ACCT_A {
|
||||
users = [
|
||||
{ user: "user_a", password: "pass_a" }
|
||||
]
|
||||
}
|
||||
ACCT_B {
|
||||
users = [
|
||||
{ user: "user_b", password: "pass_b" }
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Properties:
|
||||
- `int Port`
|
||||
- `NatsConnection CreateClientA()` — connects as `user_a`
|
||||
- `NatsConnection CreateClientB()` — connects as `user_b`
|
||||
|
||||
Collection definition: `[CollectionDefinition("E2E-Accounts")]` in this file.
|
||||
|
||||
**Verify:** Builds.
|
||||
|
||||
---
|
||||
|
||||
### Step 12: Implement TlsTests
|
||||
|
||||
**Files:**
|
||||
- `tests/NATS.E2E.Tests/TlsTests.cs` (new)
|
||||
|
||||
**Details:**
|
||||
|
||||
`[Collection("E2E-TLS")]` with `TlsServerFixture fixture`.
|
||||
|
||||
**3 tests:**
|
||||
|
||||
1. **`Tls_ClientConnectsSecurely`**: `fixture.CreateTlsClient()` → connect, ping → succeeds.
|
||||
|
||||
2. **`Tls_PlainTextConnection_Rejected`**: `fixture.CreatePlainClient()` → connect → expect exception (timeout or auth error since TLS handshake fails).
|
||||
|
||||
3. **`Tls_PubSub_WorksOverEncryptedConnection`**: Two TLS clients, pub/sub round-trip → message received.
|
||||
|
||||
**Verify:** Builds, TLS tests pass.
|
||||
|
||||
---
|
||||
|
||||
### Step 13: Implement AccountIsolationTests
|
||||
|
||||
**Files:**
|
||||
- `tests/NATS.E2E.Tests/AccountIsolationTests.cs` (new)
|
||||
|
||||
**Details:**
|
||||
|
||||
`[Collection("E2E-Accounts")]` with `AccountServerFixture fixture`.
|
||||
|
||||
**3 tests:**
|
||||
|
||||
1. **`Accounts_SameAccount_MessageDelivered`**: Two `ACCT_A` clients. Sub + pub on `acct.test` → message received.
|
||||
|
||||
2. **`Accounts_CrossAccount_MessageNotDelivered`**: `ACCT_A` client pubs to `cross.test`, `ACCT_B` client subs to `cross.test` → no message within 1s.
|
||||
|
||||
3. **`Accounts_EachAccountHasOwnNamespace`**: `ACCT_A` sub on `shared.topic`, `ACCT_B` sub on `shared.topic`. Pub from `ACCT_A` → only `ACCT_A` sub receives. Pub from `ACCT_B` → only `ACCT_B` sub receives.
|
||||
|
||||
**Verify:** `dotnet test tests/NATS.E2E.Tests` — all 38 tests pass (32 + 6).
|
||||
|
||||
---
|
||||
|
||||
## Batch 6: Phase 5 — JetStream
|
||||
|
||||
### Step 14: Implement JetStreamServerFixture
|
||||
|
||||
**Files:**
|
||||
- `tests/NATS.E2E.Tests/Infrastructure/JetStreamServerFixture.cs` (new)
|
||||
|
||||
**Details:**
|
||||
|
||||
Class `JetStreamServerFixture : IAsyncLifetime`.
|
||||
|
||||
Config:
|
||||
```
|
||||
listen: "0.0.0.0:{port}"
|
||||
jetstream {
|
||||
store_dir: "{tmpdir}"
|
||||
max_mem_store: 64mb
|
||||
max_file_store: 256mb
|
||||
}
|
||||
```
|
||||
|
||||
Where `{tmpdir}` is created via `Path.Combine(Path.GetTempPath(), "nats-e2e-js-" + Guid.NewGuid().ToString("N")[..8])`.
|
||||
|
||||
Properties:
|
||||
- `int Port`
|
||||
- `NatsConnection CreateClient()`
|
||||
|
||||
Dispose: stop server, delete `store_dir`.
|
||||
|
||||
Collection definition: `[CollectionDefinition("E2E-JetStream")]` in this file.
|
||||
|
||||
**Verify:** Builds.
|
||||
|
||||
---
|
||||
|
||||
### Step 15: Implement JetStreamTests
|
||||
|
||||
**Files:**
|
||||
- `tests/NATS.E2E.Tests/JetStreamTests.cs` (new)
|
||||
|
||||
**Details:**
|
||||
|
||||
`[Collection("E2E-JetStream")]` with `JetStreamServerFixture fixture`.
|
||||
|
||||
Uses `NATS.Client.JetStream` NuGet — create `NatsJSContext` from the connection.
|
||||
|
||||
**10 tests:**
|
||||
|
||||
1. **`Stream_CreateAndInfo`**: Create stream `TEST1` on subjects `["js.test.>"]` with limits retention. Get stream info → verify name, subjects, retention policy match.
|
||||
|
||||
2. **`Stream_ListAndNames`**: Create 3 streams (`LIST_A`, `LIST_B`, `LIST_C`). List streams → all 3 present. Get names → all 3 names returned.
|
||||
|
||||
3. **`Stream_Delete`**: Create stream `DEL_TEST`, delete it, attempt info → expect not-found error.
|
||||
|
||||
4. **`Stream_PublishAndGet`**: Create stream on `js.pub.>`. Publish 3 messages. Get message by sequence 1, 2, 3 → verify data matches.
|
||||
|
||||
5. **`Stream_Purge`**: Create stream, publish 5 messages. Purge. Get stream info → `state.messages == 0`.
|
||||
|
||||
6. **`Consumer_CreatePullAndConsume`**: Create stream + pull consumer. Publish 5 messages. Pull next batch (5) → receive all 5 with correct data.
|
||||
|
||||
7. **`Consumer_AckExplicit`**: Create stream + consumer with explicit ack. Publish message. Pull, ack it. Pull again → no more messages (not redelivered).
|
||||
|
||||
8. **`Consumer_ListAndDelete`**: Create stream + 2 consumers. List consumers → 2 present. Delete one. List → 1 remaining.
|
||||
|
||||
9. **`Retention_LimitsMaxMessages`**: Create stream with `MaxMsgs: 10`. Publish 15 messages. Stream info → `state.messages == 10`, first seq is 6.
|
||||
|
||||
10. **`Retention_MaxAge`**: Create stream with `MaxAge: TimeSpan.FromSeconds(2)`. Publish messages. Wait 3s. Stream info → `state.messages == 0`.
|
||||
|
||||
Each test uses unique stream/subject names to avoid interference (tests share one JetStream server).
|
||||
|
||||
**Verify:** `dotnet test tests/NATS.E2E.Tests` — all 48 tests pass (38 + 10).
|
||||
|
||||
---
|
||||
|
||||
## Batch 7: Final Verification
|
||||
|
||||
### Step 16: Full build and test run
|
||||
|
||||
**Commands:**
|
||||
```bash
|
||||
dotnet build
|
||||
dotnet test tests/NATS.E2E.Tests -v normal
|
||||
```
|
||||
|
||||
**Success criteria:** Solution builds clean, all 49 tests pass (3 original + 46 new).
|
||||
|
||||
---
|
||||
|
||||
## File Summary
|
||||
|
||||
| File | Action | Batch |
|
||||
|------|--------|-------|
|
||||
| `Directory.Packages.props` | edit | 1 |
|
||||
| `NATS.E2E.Tests.csproj` | edit | 1 |
|
||||
| `Infrastructure/NatsServerProcess.cs` | edit | 1 |
|
||||
| `Infrastructure/E2ETestHelper.cs` | new | 1 |
|
||||
| `Infrastructure/NatsServerFixture.cs` | edit (remove collection def) | 1 |
|
||||
| `Infrastructure/Collections.cs` | new | 1 |
|
||||
| `CoreMessagingTests.cs` | new | 2 |
|
||||
| `Infrastructure/AuthServerFixture.cs` | new | 3 |
|
||||
| `AuthTests.cs` | new | 3 |
|
||||
| `Infrastructure/MonitorServerFixture.cs` | new | 4 |
|
||||
| `MonitoringTests.cs` | new | 4 |
|
||||
| `Infrastructure/TlsServerFixture.cs` | new | 5 |
|
||||
| `Infrastructure/AccountServerFixture.cs` | new | 5 |
|
||||
| `TlsTests.cs` | new | 5 |
|
||||
| `AccountIsolationTests.cs` | new | 5 |
|
||||
| `Infrastructure/JetStreamServerFixture.cs` | new | 6 |
|
||||
| `JetStreamTests.cs` | new | 6 |
|
||||
|
||||
## Agent Model Guidance
|
||||
|
||||
- **Batch 1 (infrastructure)**: Opus — involves modifying existing code carefully
|
||||
- **Batches 2-6 (test phases)**: Sonnet — straightforward test implementation from spec
|
||||
- **Batch 7 (verify)**: Either — just running commands
|
||||
- **Parallel agents within Batch 5**: Steps 10-11 (fixtures) can run in parallel, Steps 12-13 (tests) can run in parallel
|
||||
57
docs/plans/2026-03-12-e2e-tests-design.md
Normal file
57
docs/plans/2026-03-12-e2e-tests-design.md
Normal file
@@ -0,0 +1,57 @@
|
||||
# NATS.E2E.Tests — Design
|
||||
|
||||
**Date:** 2026-03-12
|
||||
**Status:** Approved
|
||||
|
||||
## Overview
|
||||
|
||||
A true black-box E2E test project that launches `NATS.Server.Host` as a child process and connects using only `NATS.Client.Core` from NuGet. No project references to any server code.
|
||||
|
||||
## Components
|
||||
|
||||
### 1. `NatsServerProcess` — Server Lifecycle Helper
|
||||
|
||||
- Builds the host binary once (or locates pre-built output)
|
||||
- Launches `dotnet exec <path>/NATS.Server.Host.dll -p <port>` as a child process
|
||||
- Allocates a free port per instance
|
||||
- Waits for the server to be ready by polling TCP connect (with timeout)
|
||||
- On dispose: sends SIGINT / kills process, waits for exit
|
||||
- Captures stdout/stderr for diagnostics on failure
|
||||
|
||||
### 2. `NatsServerFixture` — xUnit Collection Fixture
|
||||
|
||||
- Implements `IAsyncLifetime`
|
||||
- Creates one `NatsServerProcess` per test class (or shared via collection)
|
||||
- Exposes `Port` and a `CreateClient()` helper that returns a connected `NatsConnection`
|
||||
|
||||
### 3. Initial Tests
|
||||
|
||||
- `ConnectAndPingTest` — Client connects, PING/PONG succeeds
|
||||
- `PubSubTest` — Two clients, publish on a subject, subscriber receives the message
|
||||
- `RequestReplyTest` — One client subscribes and replies, another sends a request and gets the response
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
tests/NATS.E2E.Tests/
|
||||
NATS.E2E.Tests.csproj # xUnit + NATS.Client.Core only, no server refs
|
||||
Infrastructure/
|
||||
NatsServerProcess.cs # Process lifecycle management
|
||||
NatsServerFixture.cs # xUnit fixture
|
||||
BasicTests.cs # Connect, PubSub, Request/Reply
|
||||
```
|
||||
|
||||
## Key Decisions
|
||||
|
||||
- **Binary discovery**: The fixture runs `dotnet build` on the host project and locates the output DLL via the known relative path from the solution root.
|
||||
- **Ready detection**: TCP connect poll to the allocated port with 10s timeout, 100ms interval.
|
||||
- **Process cleanup**: `Process.Kill()` with a graceful SIGINT attempt first.
|
||||
- **No shared state**: Each test class gets its own server process and port — full isolation.
|
||||
- **Timeout**: All async test operations use 10s CancellationTokenSource to avoid hangs.
|
||||
|
||||
## Out of Scope (YAGNI)
|
||||
|
||||
- No TLS/auth E2E tests in the initial project
|
||||
- No cluster/route/gateway/leaf-node multi-server tests
|
||||
- No JetStream E2E
|
||||
- No custom config file testing
|
||||
166
docs/plans/2026-03-12-e2e-tests-plan.md
Normal file
166
docs/plans/2026-03-12-e2e-tests-plan.md
Normal file
@@ -0,0 +1,166 @@
|
||||
# NATS.E2E.Tests — Implementation Plan
|
||||
|
||||
**Date:** 2026-03-12
|
||||
**Design:** [2026-03-12-e2e-tests-design.md](2026-03-12-e2e-tests-design.md)
|
||||
|
||||
## Steps
|
||||
|
||||
### Step 1: Create the project and add to solution
|
||||
|
||||
**Files:**
|
||||
- `tests/NATS.E2E.Tests/NATS.E2E.Tests.csproj` (new)
|
||||
- `NatsDotNet.slnx` (edit)
|
||||
|
||||
**Details:**
|
||||
|
||||
Create `tests/NATS.E2E.Tests/NATS.E2E.Tests.csproj`:
|
||||
```xml
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="coverlet.collector" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" />
|
||||
<PackageReference Include="NATS.Client.Core" />
|
||||
<PackageReference Include="Shouldly" />
|
||||
<PackageReference Include="xunit" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Using Include="Xunit" />
|
||||
<Using Include="Shouldly" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
```
|
||||
|
||||
No project references — black-box only. All package versions come from `Directory.Packages.props` (CPM). TFM inherited from `Directory.Build.props` (`net10.0`).
|
||||
|
||||
Add to `NatsDotNet.slnx` under the `/tests/` folder:
|
||||
```xml
|
||||
<Project Path="tests/NATS.E2E.Tests/NATS.E2E.Tests.csproj" />
|
||||
```
|
||||
|
||||
**Verify:** `dotnet build tests/NATS.E2E.Tests` succeeds.
|
||||
|
||||
---
|
||||
|
||||
### Step 2: Implement `NatsServerProcess`
|
||||
|
||||
**Files:**
|
||||
- `tests/NATS.E2E.Tests/Infrastructure/NatsServerProcess.cs` (new)
|
||||
|
||||
**Details:**
|
||||
|
||||
Class `NatsServerProcess : IAsyncDisposable`:
|
||||
|
||||
- **Constructor**: Takes no args. Allocates a free TCP port via ephemeral socket bind.
|
||||
- **`StartAsync()`**:
|
||||
1. Resolves the host DLL path: walk up from `AppContext.BaseDirectory` to find the solution root (contains `NatsDotNet.slnx`), then build path `src/NATS.Server.Host/bin/Debug/net10.0/NATS.Server.Host.dll`. If not found, run `dotnet build src/NATS.Server.Host/NATS.Server.Host.csproj -c Debug` from solution root first.
|
||||
2. Launch `dotnet exec <dll> -p <port>` via `System.Diagnostics.Process`. Redirect stdout/stderr, capture into `StringBuilder` for diagnostics.
|
||||
3. Poll TCP connect to `127.0.0.1:<port>` every 100ms, timeout after 10s. Throw `TimeoutException` with captured output if server doesn't become ready.
|
||||
- **`DisposeAsync()`**:
|
||||
1. If process is running: try `Process.Kill(entireProcessTree: true)` (cross-platform in .NET 10).
|
||||
2. Wait for exit with 5s timeout, then force kill if still alive.
|
||||
3. Dispose the process.
|
||||
- **Properties**: `int Port`, `string Output` (captured stdout+stderr for diagnostics).
|
||||
|
||||
**Verify:** Builds without errors.
|
||||
|
||||
---
|
||||
|
||||
### Step 3: Implement `NatsServerFixture`
|
||||
|
||||
**Files:**
|
||||
- `tests/NATS.E2E.Tests/Infrastructure/NatsServerFixture.cs` (new)
|
||||
|
||||
**Details:**
|
||||
|
||||
Class `NatsServerFixture : IAsyncLifetime`:
|
||||
|
||||
- **Field**: `NatsServerProcess _server`
|
||||
- **`InitializeAsync()`**: Create `NatsServerProcess`, call `StartAsync()`.
|
||||
- **`DisposeAsync()`**: Dispose the server process.
|
||||
- **`int Port`**: Delegates to `_server.Port`.
|
||||
- **`NatsConnection CreateClient()`**: Returns `new NatsConnection(new NatsOpts { Url = $"nats://127.0.0.1:{Port}" })`.
|
||||
|
||||
Define a collection attribute:
|
||||
```csharp
|
||||
[CollectionDefinition("E2E")]
|
||||
public class E2ECollection : ICollectionFixture<NatsServerFixture>;
|
||||
```
|
||||
|
||||
This lets multiple test classes share one server process via `[Collection("E2E")]`.
|
||||
|
||||
**Verify:** Builds without errors.
|
||||
|
||||
---
|
||||
|
||||
### Step 4: Implement `BasicTests`
|
||||
|
||||
**Files:**
|
||||
- `tests/NATS.E2E.Tests/BasicTests.cs` (new)
|
||||
|
||||
**Details:**
|
||||
|
||||
```csharp
|
||||
[Collection("E2E")]
|
||||
public class BasicTests(NatsServerFixture fixture)
|
||||
{
|
||||
private static CancellationToken Timeout => new CancellationTokenSource(TimeSpan.FromSeconds(10)).Token;
|
||||
```
|
||||
|
||||
**Test 1 — `ConnectAndPing`:**
|
||||
- Create client via `fixture.CreateClient()`
|
||||
- `await client.ConnectAsync()`
|
||||
- `await client.PingAsync()` — if no exception, PING/PONG succeeded
|
||||
- Assert `client.ConnectionState` is `Open` (via Shouldly)
|
||||
|
||||
**Test 2 — `PubSub`:**
|
||||
- Create two clients (pub, sub)
|
||||
- Connect both
|
||||
- Subscribe sub to `"e2e.test.pubsub"`
|
||||
- Flush sub via `PingAsync()`
|
||||
- Publish `"hello e2e"` on the subject
|
||||
- Read one message from subscription with 10s timeout
|
||||
- Assert `msg.Data.ShouldBe("hello e2e")`
|
||||
|
||||
**Test 3 — `RequestReply`:**
|
||||
- Create two clients (requester, responder)
|
||||
- Connect both
|
||||
- Subscribe responder to `"e2e.test.rpc"`, in a background task read messages and reply with `"reply: " + msg.Data`
|
||||
- Flush responder via `PingAsync()`
|
||||
- Send request from requester: `await requester.RequestAsync<string, string>("e2e.test.rpc", "ping")`
|
||||
- Assert reply data is `"reply: ping"`
|
||||
|
||||
All tests use `await using` for client cleanup.
|
||||
|
||||
**Verify:** `dotnet test tests/NATS.E2E.Tests` — all 3 tests pass.
|
||||
|
||||
---
|
||||
|
||||
### Step 5: Verify full solution builds and tests pass
|
||||
|
||||
**Commands:**
|
||||
```bash
|
||||
dotnet build
|
||||
dotnet test tests/NATS.E2E.Tests -v normal
|
||||
```
|
||||
|
||||
**Success criteria:** Solution builds clean, all 3 E2E tests pass.
|
||||
|
||||
## Batch Structure
|
||||
|
||||
All 5 steps are in a single batch — the project is small and sequential (each step builds on the prior). No parallelization needed.
|
||||
|
||||
| Step | Files | Depends On |
|
||||
|------|-------|------------|
|
||||
| 1 | csproj + slnx | — |
|
||||
| 2 | NatsServerProcess.cs | Step 1 |
|
||||
| 3 | NatsServerFixture.cs | Step 2 |
|
||||
| 4 | BasicTests.cs | Step 3 |
|
||||
| 5 | (verify only) | Step 4 |
|
||||
Reference in New Issue
Block a user