1321 lines
48 KiB
Markdown
1321 lines
48 KiB
Markdown
# Remaining Go Parity Implementation Plan
|
|
|
|
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers-extended-cc:executing-plans to implement this plan task-by-task.
|
|
|
|
**Goal:** Port ~1,418 unmapped Go tests to .NET, building/enhancing features as needed. Mark ~224 Go-specific tests as not_applicable. Target: 90%+ Go test mapping.
|
|
|
|
**Architecture:** Feature-first by gap severity across 8 parallel tracks. Each task: enhance .NET feature → port Go tests → update test_parity.db → commit. Targeted test runs only (`dotnet test --filter`); full suite at end.
|
|
|
|
**Tech Stack:** .NET 10 / C# 14, xUnit 3, Shouldly, NSubstitute, SQLite (test_parity.db)
|
|
|
|
---
|
|
|
|
## Conventions
|
|
|
|
- **Assertions**: Shouldly only (`value.ShouldBe(expected)`, `action.ShouldThrow<T>()`)
|
|
- **Go reference**: Each ported test gets a comment: `// Go: TestName (file.go:line)`
|
|
- **Test run**: `dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~ClassName" -v minimal`
|
|
- **DB update**: `sqlite3 docs/test_parity.db "UPDATE go_tests SET status='mapped', dotnet_test='DotNetName', dotnet_file='TestFile.cs' WHERE go_test='GoTestName' AND go_file='go_file.go'"`
|
|
- **Commit**: After each task, commit with `test(parity): <description> + DB update`
|
|
|
|
---
|
|
|
|
## Task 0: Mark Not-Applicable Tests in DB
|
|
|
|
**Files:**
|
|
- Modify: `docs/test_parity.db`
|
|
|
|
**Step 1: Mark norace tests (126)**
|
|
|
|
```bash
|
|
sqlite3 docs/test_parity.db "UPDATE go_tests SET status='not_applicable', notes='Stress test requiring real multi-server infrastructure' WHERE go_file IN ('norace_1_test.go','norace_2_test.go') AND status='unmapped'"
|
|
```
|
|
|
|
**Step 2: Mark platform-specific tests (23)**
|
|
|
|
```bash
|
|
sqlite3 docs/test_parity.db "UPDATE go_tests SET status='not_applicable', notes='Platform-specific: not applicable to .NET' WHERE go_file IN ('signal_test.go','certstore_windows_test.go','service_windows_test.go','service_test.go') AND status='unmapped'"
|
|
```
|
|
|
|
**Step 3: Mark Go-specific data structure tests (38)**
|
|
|
|
```bash
|
|
sqlite3 docs/test_parity.db "UPDATE go_tests SET status='not_applicable', notes='Go-specific data structure/mechanism' WHERE go_file IN ('dirstore_test.go','ipqueue_test.go','split_test.go','ring_test.go') AND status='unmapped'"
|
|
```
|
|
|
|
**Step 4: Mark performance/benchmark tests (35)**
|
|
|
|
```bash
|
|
sqlite3 docs/test_parity.db "UPDATE go_tests SET status='not_applicable', notes='Go performance benchmark, not functional test' WHERE status='unmapped' AND (go_test LIKE '%Perf%' OR go_test LIKE '%Bench%')"
|
|
```
|
|
|
|
**Step 5: Verify counts**
|
|
|
|
```bash
|
|
sqlite3 docs/test_parity.db "SELECT status, COUNT(*) FROM go_tests GROUP BY status"
|
|
```
|
|
|
|
Expected: not_applicable count increases by ~222.
|
|
|
|
**Step 6: Commit**
|
|
|
|
```bash
|
|
git add docs/test_parity.db
|
|
git commit -m "chore: mark ~222 Go tests as not_applicable in parity DB"
|
|
```
|
|
|
|
---
|
|
|
|
## Track 1: Storage Engine (167 tests)
|
|
|
|
### Task 1: FileStore Block Recovery & Compaction (~50 tests)
|
|
|
|
**Gaps addressed:** Gap 1 — CRITICAL
|
|
|
|
**Files:**
|
|
- Modify: `src/NATS.Server/JetStream/Storage/FileStore.cs`
|
|
- Modify: `src/NATS.Server/JetStream/Storage/MsgBlock.cs`
|
|
- Create: `tests/NATS.Server.Tests/JetStream/Storage/FileStoreRecoveryTests.cs`
|
|
- Modify: `docs/test_parity.db`
|
|
|
|
**Feature work:**
|
|
1. Add `RecoverFullState()` to FileStore — deserialize binary state file, validate checksums, reconstruct block metadata. Go ref: `filestore.go:1754`
|
|
2. Add `RebuildStateLocked()` — iterate blocks, sum messages/bytes, set FirstSeq/LastSeq. Go ref: `filestore.go:1284`
|
|
3. Enhance `Compact(seq)` — delete entire blocks below compact point, partial-block deletion with dmap update. Go ref: `filestore.go:9346`
|
|
4. Add `FlushAllPending()` — force write pending data to disk
|
|
5. Add block index rebuild on corrupt/missing index files
|
|
|
|
**Go tests to port (~50):**
|
|
```
|
|
TestFileStoreInvalidIndexesRebuilt
|
|
TestFileStoreRecoverFullState
|
|
TestFileStoreLargeFullState
|
|
TestFileStoreLargeFullStatePSIM
|
|
TestFileStoreMsgBlockHolesAndIndexing
|
|
TestFileStoreMsgBlockCompactionAndHoles
|
|
TestFileStoreReloadAndLoseLastSequence
|
|
TestFileStoreRestoreIndexWithMatchButLeftOverBlocks
|
|
TestFileStoreCompactAndPSIMWhenDeletingBlocks
|
|
TestFileStoreCheckSkipFirstBlockBug
|
|
TestFileStoreSelectMsgBlockBinarySearch
|
|
TestFileStoreSyncCompressOnlyIfDirty
|
|
TestFileStorePartialIndexes
|
|
TestFileStoreErrPartialLoad
|
|
TestFileStoreStreamFailToRollBug
|
|
TestFileStoreBadFirstAndFailedExpireAfterRestart
|
|
TestFileStoreSyncIntervals
|
|
TestFileStoreAsyncFlushOnSkipMsgs
|
|
TestFileStoreLeftoverSkipMsgInDmap
|
|
TestFileStoreCacheLookupOnEmptyBlock
|
|
TestFileStoreWriteFullStateHighSubjectCardinality
|
|
TestFileStoreWriteFullStateDetectCorruptState
|
|
TestFileStoreRecoverFullStateDetectCorruptState
|
|
TestFileStoreFullStateTestUserRemoveWAL
|
|
TestFileStoreFullStateTestSysRemovals
|
|
TestFileStoreTrackSubjLenForPSIM
|
|
TestFileStoreMsgBlockFirstAndLastSeqCorrupt
|
|
TestFileStoreCorruptPSIMOnDisk
|
|
TestFileStoreCorruptionSetsHbitWithoutHeaders
|
|
TestFileStoreWriteFullStateThrowsPermissionErrorIfFSModeReadOnly
|
|
TestFileStoreStoreRawMessageThrowsPermissionErrorIfFSModeReadOnly
|
|
TestFileStoreWriteFailures
|
|
TestFileStoreStreamDeleteDirNotEmpty
|
|
TestFileStoreFSSCloseAndKeepOnExpireOnRecoverBug
|
|
TestFileStoreExpireOnRecoverSubjectAccounting
|
|
TestFileStoreFSSExpireNumPendingBug
|
|
```
|
|
|
|
**Test command:**
|
|
```bash
|
|
dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~FileStoreRecoveryTests" -v minimal
|
|
```
|
|
|
|
**DB update:** Update each ported test in test_parity.db.
|
|
|
|
**Commit:** `test(parity): port FileStore recovery & compaction tests (T1, ~50 tests) + DB update`
|
|
|
|
---
|
|
|
|
### Task 2: FileStore Tombstones, Deletion & TTL (~40 tests)
|
|
|
|
**Files:**
|
|
- Modify: `src/NATS.Server/JetStream/Storage/FileStore.cs`
|
|
- Modify: `src/NATS.Server/JetStream/Storage/MsgBlock.cs`
|
|
- Create: `tests/NATS.Server.Tests/JetStream/Storage/FileStoreTombstoneTests.cs`
|
|
- Modify: `docs/test_parity.db`
|
|
|
|
**Feature work:**
|
|
1. Integrate `SequenceSet` (AVL) for sparse deletion tracking (dmap). Go ref: `filestore.go` dmap usage
|
|
2. Add tombstone tracking with byte accounting (`rbytes`)
|
|
3. Implement subject delete markers — mark deleted subjects for mirror/source propagation
|
|
4. Add message TTL recovery from disk state. Go ref: `filestore.go` TTL wheel persistence
|
|
5. Add message schedule encode/decode. Go ref: `filestore.go:MessageSchedule`
|
|
6. Integrate AEAD encryption into block write/read path
|
|
|
|
**Go tests to port (~40):**
|
|
```
|
|
TestFileStoreTombstoneRbytes
|
|
TestFileStoreTombstonesNoFirstSeqRollback
|
|
TestFileStoreTombstonesSelectNextFirstCleanup
|
|
TestFileStoreEraseMsgDoesNotLoseTombstones
|
|
TestFileStoreDetectDeleteGapWithLastSkipMsg
|
|
TestFileStoreMissingDeletesAfterCompact
|
|
TestFileStoreSubjectDeleteMarkers
|
|
TestFileStoreMessageTTLRecoveredSingleMessageWithoutStreamState
|
|
TestFileStoreMessageTTLWriteTombstone
|
|
TestFileStoreMessageTTLRecoveredOffByOne
|
|
TestFileStoreMessageScheduleEncode
|
|
TestFileStoreMessageScheduleDecode
|
|
TestFileStoreRecoverTTLAndScheduleStateAndCounters
|
|
TestFileStoreNoPanicOnRecoverTTLWithCorruptBlocks
|
|
TestFileStoreConsumerEncodeDecodeRedelivered
|
|
TestFileStoreConsumerEncodeDecodePendingBelowStreamAckFloor
|
|
TestFileStoreConsumerRedeliveredLost
|
|
TestFileStoreConsumerFlusher
|
|
TestFileStoreConsumerDeliveredUpdates
|
|
TestFileStoreConsumerDeliveredAndAckUpdates
|
|
TestFileStoreBadConsumerState
|
|
```
|
|
|
|
**Test command:**
|
|
```bash
|
|
dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~FileStoreTombstoneTests" -v minimal
|
|
```
|
|
|
|
**Commit:** `test(parity): port FileStore tombstone, TTL & consumer state tests (T2, ~40 tests) + DB update`
|
|
|
|
---
|
|
|
|
### Task 3: MemStore Go-Parity Methods (~28 tests)
|
|
|
|
**Files:**
|
|
- Modify: `src/NATS.Server/JetStream/Storage/MemStore.cs`
|
|
- Create: `tests/NATS.Server.Tests/JetStream/Storage/MemStoreGoParityTests.cs`
|
|
- Modify: `docs/test_parity.db`
|
|
|
|
**Feature work:**
|
|
1. Add all sync Go-parity methods to MemStore: `StoreMsg`, `LoadMsg`, `LoadLastMsg`, `LoadNextMsg`, `NumPending`, `Compact`, `Truncate`, `GetSeqFromTime`, `State()`, `FastState()`, `SubjectsState()`, `SubjectsTotals()`, `FilteredState()`, `AllLastSeqs()`, `MultiLastSeqs()`, `SubjectForSeq()`, `PurgeEx()`, `SkipMsg()`, `SkipMsgs()`
|
|
2. Add per-subject tracking for subject-filtered operations
|
|
3. Add TTL/schedule support for in-memory messages
|
|
4. Add UpdateConfig for dynamic limit changes
|
|
|
|
**Go tests to port (~28):**
|
|
```
|
|
TestMemStoreCompact
|
|
TestMemStoreStreamStateDeleted
|
|
TestMemStoreStreamTruncate
|
|
TestMemStoreUpdateMaxMsgsPerSubject
|
|
TestMemStoreStreamCompactMultiBlockSubjectInfo
|
|
TestMemStoreSubjectsTotals
|
|
TestMemStoreNumPending
|
|
TestMemStoreMultiLastSeqs
|
|
TestMemStoreSubjectForSeq
|
|
TestMemStoreSubjectDeleteMarkers
|
|
TestMemStoreAllLastSeqs
|
|
TestMemStoreGetSeqFromTimeWithLastDeleted
|
|
TestMemStoreSkipMsgs
|
|
TestMemStoreDeleteBlocks
|
|
TestMemStoreMessageTTL
|
|
TestMemStoreMessageSchedule
|
|
TestMemStoreUpdateConfigTTLState
|
|
TestMemStoreNextWildcardMatch
|
|
TestMemStoreNextLiteralMatch
|
|
```
|
|
|
|
Plus remaining 9 MemStore tests from the unmapped list.
|
|
|
|
**Test command:**
|
|
```bash
|
|
dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~MemStoreGoParityTests" -v minimal
|
|
```
|
|
|
|
**Commit:** `test(parity): port MemStore Go-parity methods + 28 tests (T3) + DB update`
|
|
|
|
---
|
|
|
|
### Task 4: Store Interface Tests (~16 tests)
|
|
|
|
**Files:**
|
|
- Create: `tests/NATS.Server.Tests/JetStream/Storage/StoreInterfaceTests.cs`
|
|
- Modify: `docs/test_parity.db`
|
|
|
|
**Feature work:** Minimal — these test the IStreamStore interface contract. Both FileStore and MemStore should already implement the methods after Tasks 1-3.
|
|
|
|
**Go tests to port (~16):**
|
|
```
|
|
TestStoreMsgLoadNextMsgMulti
|
|
TestStoreMsgLoadPrevMsgMulti
|
|
TestStoreLoadNextMsgWildcardStartBeforeFirstMatch
|
|
TestStoreDeleteSlice
|
|
TestStoreDeleteRange
|
|
TestStoreCompactCleansUpDmap
|
|
TestStoreTruncateCleansUpDmap
|
|
TestStoreSubjectStateConsistency
|
|
TestStoreStreamInteriorDeleteAccounting
|
|
TestStoreGetSeqFromTime
|
|
TestStoreUpdateConfigTTLState
|
|
TestStorePurgeExZero
|
|
```
|
|
|
|
Plus remaining 4 store_test.go tests.
|
|
|
|
**Test command:**
|
|
```bash
|
|
dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~StoreInterfaceTests" -v minimal
|
|
```
|
|
|
|
**Commit:** `test(parity): port store interface contract tests (T4, 16 tests) + DB update`
|
|
|
|
---
|
|
|
|
## Track 2: JetStream Core API (220 tests)
|
|
|
|
### Task 5: JetStream Mirrors, Sources & Transforms (~42 tests)
|
|
|
|
**Gaps addressed:** Gap 3 — HIGH, Gap 7 — HIGH
|
|
|
|
**Files:**
|
|
- Modify: `src/NATS.Server/JetStream/MirrorSource/MirrorCoordinator.cs`
|
|
- Modify: `src/NATS.Server/JetStream/MirrorSource/SourceCoordinator.cs`
|
|
- Modify: `src/NATS.Server/JetStream/StreamManager.cs`
|
|
- Create: `tests/NATS.Server.Tests/JetStream/MirrorSourceGoParityTests.cs`
|
|
- Modify: `docs/test_parity.db`
|
|
|
|
**Feature work:**
|
|
1. Implement `MirrorCoordinator.StartSyncLoop()` — pull-based batch fetch from origin, apply to local store. Go ref: `stream.go:processMirrorMsgs`
|
|
2. Implement `SourceCoordinator.StartSyncLoop()` — consume from source with filter/transform. Go ref: `stream.go:processSourceMsgs`
|
|
3. Add subject transform integration on source consumption
|
|
4. Add dedup window maintenance (prune expired entries)
|
|
5. Add mirror/source health tracking and error state
|
|
6. Add stream republish support — re-publish on subject match. Go ref: `stream.go:republish`
|
|
|
|
**Go tests to port (~42):**
|
|
```
|
|
TestJetStreamMirrorStripExpectedHeaders
|
|
TestJetStreamMirroredConsumerFailAfterRestart
|
|
TestJetStreamMirrorUpdatesNotSupported
|
|
TestJetStreamMirrorFirstSeqNotSupported
|
|
TestJetStreamMirroringClipStartSeq
|
|
TestJetStreamMessageTTLWhenMirroring
|
|
TestJetStreamSubjectDeleteMarkersWithMirror
|
|
TestJetStreamPromoteMirrorDeletingOrigin
|
|
TestJetStreamPromoteMirrorUpdatingOrigin
|
|
TestJetStreamScheduledMirrorOrSource
|
|
TestJetStreamRecoverBadMirrorConfigWithSubjects
|
|
TestJetStreamSourceWorkingQueueWithLimit
|
|
TestJetStreamStreamSourceFromKV
|
|
TestJetStreamRemoveExternalSource
|
|
TestJetStreamWorkQueueSourceRestart
|
|
TestJetStreamWorkQueueSourceNamingRestart
|
|
TestJetStreamStreamUpdateWithExternalSource
|
|
TestJetStreamSourceRemovalAndReAdd
|
|
TestJetStreamAllowMsgCounterSourceAggregates
|
|
TestJetStreamAllowMsgCounterSourceVerbatim
|
|
TestJetStreamAllowMsgCounterSourceStartingAboveZero
|
|
TestJetStreamSourcingClipStartSeq
|
|
TestJetStreamInputTransform
|
|
TestJetStreamImplicitRePublishAfterSubjectTransform
|
|
TestJetStreamStreamRepublishCycle
|
|
TestJetStreamStreamRepublishOneTokenMatch
|
|
TestJetStreamStreamRepublishMultiTokenMatch
|
|
TestJetStreamStreamRepublishAnySubjectMatch
|
|
TestJetStreamStreamRepublishMultiTokenNoMatch
|
|
TestJetStreamStreamRepublishOneTokenNoMatch
|
|
TestJetStreamStreamRepublishHeadersOnly
|
|
```
|
|
|
|
**Test command:**
|
|
```bash
|
|
dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~MirrorSourceGoParityTests" -v minimal
|
|
```
|
|
|
|
**Commit:** `test(parity): port mirror, source & transform tests (T5, ~42 tests) + DB update`
|
|
|
|
---
|
|
|
|
### Task 6: JetStream Storage, Recovery & Encryption (~26 tests)
|
|
|
|
**Files:**
|
|
- Modify: `src/NATS.Server/JetStream/StreamManager.cs`
|
|
- Modify: `src/NATS.Server/JetStream/Storage/FileStore.cs`
|
|
- Create: `tests/NATS.Server.Tests/JetStream/JsStorageRecoveryTests.cs`
|
|
- Modify: `docs/test_parity.db`
|
|
|
|
**Feature work:**
|
|
1. Add stream recovery after server restart — reload stream state from store. Go ref: `jetstream.go:recovery`
|
|
2. Add server encryption key management — per-stream key, rotation. Go ref: `jetstream.go:encryption`
|
|
3. Add direct get with time-based queries. Go ref: `jetstream_api.go:directGet`
|
|
4. Add subject delete marker generation and handling
|
|
|
|
**Go tests to port (~26):**
|
|
```
|
|
TestJetStreamSimpleFileRecovery
|
|
TestJetStreamStoredMsgsDontDisappearAfterCacheExpiration
|
|
TestJetStreamDeliveryAfterServerRestart
|
|
TestJetStreamStoreDirectoryFix
|
|
TestJetStreamServerEncryption
|
|
TestJetStreamServerEncryptionServerRestarts
|
|
TestJetStreamServerReencryption
|
|
TestJetStreamMessageTTLBasics
|
|
TestJetStreamMessageTTLExpiration
|
|
TestJetStreamMessageTTLInvalidConfig
|
|
TestJetStreamSubjectDeleteMarkers
|
|
TestJetStreamSubjectDeleteMarkersRestart
|
|
TestJetStreamDirectGetUpToTime
|
|
TestJetStreamDirectGetStartTimeSingleMsg
|
|
TestJetStreamFileStoreFirstSeqAfterRestart
|
|
TestJetStreamLargeExpiresAndServerRestart
|
|
TestJetStreamExpireCausesDeadlock
|
|
TestJetStreamExpireAllWhileServerDown
|
|
TestJetStreamStreamInfoSubjectsDetailsAfterRestart
|
|
TestJetStreamDanglingMessageAutoCleanup
|
|
```
|
|
|
|
**Test command:**
|
|
```bash
|
|
dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~JsStorageRecoveryTests" -v minimal
|
|
```
|
|
|
|
**Commit:** `test(parity): port JetStream storage, recovery & encryption tests (T6, ~26 tests) + DB update`
|
|
|
|
---
|
|
|
|
### Task 7: JetStream Config, Limits & Validation (~36 tests)
|
|
|
|
**Files:**
|
|
- Modify: `src/NATS.Server/JetStream/JetStreamService.cs`
|
|
- Modify: `src/NATS.Server/JetStream/StreamManager.cs`
|
|
- Modify: `src/NATS.Server/JetStream/Validation/JetStreamConfigValidator.cs`
|
|
- Create: `tests/NATS.Server.Tests/JetStream/JsConfigLimitsTests.cs`
|
|
- Modify: `docs/test_parity.db`
|
|
|
|
**Feature work:**
|
|
1. Add tiered JetStream limits — per-account storage by replica factor (R1, R3). Go ref: `jetstream.go:tieredLimits`
|
|
2. Add reserved storage allocation tracking
|
|
3. Add pedantic/strict mode validation for stream creation
|
|
4. Add subject overlap detection between streams
|
|
5. Add auto-tune filesystem config based on system resources. Go ref: `jetstream.go:autoTuneFS`
|
|
|
|
**Go tests to port (~36):**
|
|
```
|
|
TestJetStreamAutoTuneFSConfig
|
|
TestJetStreamServerDomainConfig
|
|
TestJetStreamServerResourcesConfig
|
|
TestJetStreamSystemLimitsPlacement
|
|
TestJetStreamTieredLimits
|
|
TestJetStreamDisabledLimitsEnforcement
|
|
TestJetStreamWouldExceedLimits
|
|
TestJetStreamStorageReservedBytes
|
|
TestJetStreamUsageNoReservation
|
|
TestJetStreamUsageReservationNegativeMaxBytes
|
|
TestJetStreamGetLastMsgBySubjectAfterUpdate
|
|
TestJetStreamProperErrorDueToOverlapSubjects
|
|
TestJetStreamStreamCreatePedanticMode
|
|
TestJetStreamStrictMode
|
|
TestJetStreamBadSubjectMappingStream
|
|
TestJetStreamCreateStreamWithSubjectDeleteMarkersOptions
|
|
TestJetStreamLimitLockBug
|
|
TestJetStreamStoreFilterIsAll
|
|
TestJetStreamCleanupNoInterestAboveThreshold
|
|
TestJetStreamServerReload
|
|
TestJetStreamConfigReloadWithGlobalAccount
|
|
TestJetStreamImportReload
|
|
TestJetStreamOperatorAccounts
|
|
TestJetStreamNoPanicOnRaceBetweenShutdownAndConsumerDelete
|
|
TestJetStreamReloadMetaCompact
|
|
```
|
|
|
|
**Test command:**
|
|
```bash
|
|
dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~JsConfigLimitsTests" -v minimal
|
|
```
|
|
|
|
**Commit:** `test(parity): port JetStream config, limits & validation tests (T7, ~36 tests) + DB update`
|
|
|
|
---
|
|
|
|
### Task 8: JetStream Delivery, Ack & Multi-Account (~39 tests)
|
|
|
|
**Files:**
|
|
- Modify: `src/NATS.Server/JetStream/Consumers/PushConsumerEngine.cs`
|
|
- Modify: `src/NATS.Server/JetStream/Consumers/AckProcessor.cs`
|
|
- Modify: `src/NATS.Server/JetStream/StreamManager.cs`
|
|
- Create: `tests/NATS.Server.Tests/JetStream/JsDeliveryAckTests.cs`
|
|
- Modify: `docs/test_parity.db`
|
|
|
|
**Feature work:**
|
|
1. Enhance NAK handling — NAK with delay, NAK of already-acked messages rejection
|
|
2. Add idle heartbeat generation for push consumers with no interest
|
|
3. Enhance interest retention with wildcards and filtered consumers
|
|
4. Add dedup window (Nats-Msg-Id header tracking). Go ref: `stream.go:checkMsgId`
|
|
5. Add cross-account JetStream access via imports/exports
|
|
|
|
**Go tests to port (~39):**
|
|
```
|
|
TestJetStreamRedeliverAndLateAck
|
|
TestJetStreamCanNotNakAckd
|
|
TestJetStreamNakRedeliveryWithNoWait
|
|
TestJetStreamPushConsumerIdleHeartbeatsWithNoInterest
|
|
TestJetStreamPendingNextTimer
|
|
TestJetStreamInterestRetentionWithWildcardsAndFilteredConsumers
|
|
TestJetStreamInterestRetentionStreamWithDurableRestart
|
|
TestJetStreamInterestStreamConsumerFilterEdit
|
|
TestJetStreamInterestStreamWithFilterSubjectsConsumer
|
|
TestJetStreamAckAllWithLargeFirstSequenceAndNoAckFloor
|
|
TestJetStreamDeliverLastPerSubjectNumPending
|
|
TestJetStreamDeliverLastPerSubjectWithKV
|
|
TestJetStreamWorkQueueWorkingIndicator
|
|
TestJetStreamInvalidDeliverSubject
|
|
TestJetStreamFlowControlStall
|
|
TestJetStreamFlowControlCrossAccountFanOut
|
|
TestJetStreamMsgIDHeaderCollision
|
|
TestJetStreamMultipleAccountsBasics
|
|
TestJetStreamAccountImportJSAdvisoriesAsService
|
|
TestJetStreamAccountImportJSAdvisoriesAsStream
|
|
TestJetStreamCrossAccountsDeliverSubjectInterest
|
|
TestJetStreamCrossAccountsFanOut
|
|
TestJetStreamCrossAccounts
|
|
TestJetStreamImportConsumerStreamSubjectRemapSingle
|
|
TestJetStreamSingleInstanceRemoteAccess
|
|
TestJetStreamMemoryCorruption
|
|
TestJetStreamMessagePerSubjectKeepBug
|
|
TestJetStreamRedeliveryAfterServerRestart
|
|
TestJetStreamKVDelete
|
|
TestJetStreamKVHistoryRegression
|
|
TestJetStreamKVReductionInHistory
|
|
TestJetStreamGetNoHeaders
|
|
TestJetStreamKVNoSubjectDeleteMarkerOnPurgeMarker
|
|
TestJetStreamAllowMsgCounter
|
|
```
|
|
|
|
**Test command:**
|
|
```bash
|
|
dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~JsDeliveryAckTests" -v minimal
|
|
```
|
|
|
|
**Commit:** `test(parity): port JetStream delivery, ack & multi-account tests (T8, ~39 tests) + DB update`
|
|
|
|
---
|
|
|
|
### Task 9: JetStream Batching API (~29 tests)
|
|
|
|
**Files:**
|
|
- Create: `src/NATS.Server/JetStream/Publish/BatchPublisher.cs`
|
|
- Modify: `src/NATS.Server/JetStream/Api/Handlers/StreamApiHandlers.cs`
|
|
- Modify: `src/NATS.Server/JetStream/StreamManager.cs`
|
|
- Create: `tests/NATS.Server.Tests/JetStream/JsBatchingTests.cs`
|
|
- Modify: `docs/test_parity.db`
|
|
|
|
**Feature work:**
|
|
1. Create `BatchPublisher` — atomic multi-message publish with stage/commit/rollback semantics. Go ref: `jetstream.go:processAtomicBatch`
|
|
2. Add batch markers to storage layer (begin-of-batch, end-of-batch)
|
|
3. Add batch recovery on server restart — detect partial batches, rollback incomplete ones
|
|
4. Add batch advisory events
|
|
5. Add per-subject expected sequence validation in batches
|
|
|
|
**Go tests to port (~29):**
|
|
```
|
|
TestJetStreamAtomicBatchPublish
|
|
TestJetStreamAtomicBatchPublishEmptyAck
|
|
TestJetStreamAtomicBatchPublishCommitEob
|
|
TestJetStreamAtomicBatchPublishLimits
|
|
TestJetStreamAtomicBatchPublishDedupeNotAllowed
|
|
TestJetStreamAtomicBatchPublishSourceAndMirror
|
|
TestJetStreamAtomicBatchPublishCleanup
|
|
TestJetStreamAtomicBatchPublishConfigOpts
|
|
TestJetStreamAtomicBatchPublishDenyHeaders
|
|
TestJetStreamAtomicBatchPublishStageAndCommit
|
|
TestJetStreamAtomicBatchPublishHighLevelRollback
|
|
TestJetStreamAtomicBatchPublishExpectedPerSubject
|
|
TestJetStreamAtomicBatchPublishSingleServerRecovery
|
|
TestJetStreamAtomicBatchPublishSingleServerRecoveryCommitEob
|
|
TestJetStreamAtomicBatchPublishEncode
|
|
TestJetStreamAtomicBatchPublishProposeOne
|
|
TestJetStreamAtomicBatchPublishProposeMultiple
|
|
TestJetStreamAtomicBatchPublishProposeOnePartialBatch
|
|
TestJetStreamAtomicBatchPublishProposeMultiplePartialBatches
|
|
TestJetStreamAtomicBatchPublishContinuousBatchesStillMoveAppliedUp
|
|
TestJetStreamAtomicBatchPublishPartiallyAppliedBatchOnRecovery
|
|
TestJetStreamRollupIsolatedRead
|
|
TestJetStreamAtomicBatchPublishAdvisories
|
|
TestJetStreamAtomicBatchPublishExpectedSeq
|
|
TestJetStreamAtomicBatchPublishPartialBatchInSharedAppendEntry
|
|
TestJetStreamAtomicBatchPublishRejectPartialBatchOnLeaderChange
|
|
TestJetStreamAtomicBatchPublishPersistModeAsync
|
|
TestJetStreamAtomicBatchPublishExpectedLastSubjectSequence
|
|
TestJetStreamAtomicBatchPublishCommitUnsupported
|
|
```
|
|
|
|
**Test command:**
|
|
```bash
|
|
dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~JsBatchingTests" -v minimal
|
|
```
|
|
|
|
**Commit:** `test(parity): port JetStream atomic batch publish API (T9, 29 tests) + DB update`
|
|
|
|
---
|
|
|
|
### Task 10: JetStream Versioning & Direct Get (~48 tests)
|
|
|
|
**Files:**
|
|
- Modify: `src/NATS.Server/JetStream/Models/StreamConfig.cs` (or equivalent)
|
|
- Modify: `src/NATS.Server/JetStream/Api/Handlers/DirectApiHandlers.cs`
|
|
- Create: `tests/NATS.Server.Tests/JetStream/JsVersioningTests.cs`
|
|
- Modify: `docs/test_parity.db`
|
|
|
|
**Feature work:**
|
|
1. Add `RequiredApiLevel` field to StreamConfig and ConsumerConfig
|
|
2. Add static/dynamic metadata fields — static immutable after creation
|
|
3. Add API version negotiation on responses
|
|
4. Add batched direct get — multi-message response with MaxBytes paging. Go ref: `jetstream_api.go:directGet`
|
|
5. Add snapshot/restore API stubs with healthz integration
|
|
|
|
**Go tests to port (~48):**
|
|
All 18 from jetstream_versioning_test.go plus remaining jetstream_test.go tests:
|
|
```
|
|
TestGetAndSupportsRequiredApiLevel
|
|
TestJetStreamSetStaticStreamMetadata
|
|
TestJetStreamSetStaticStreamMetadataRemoveDynamicFields
|
|
TestJetStreamSetDynamicStreamMetadata
|
|
TestJetStreamCopyStreamMetadata
|
|
TestJetStreamCopyStreamMetadataRemoveDynamicFields
|
|
TestJetStreamSetStaticConsumerMetadata
|
|
TestJetStreamSetStaticConsumerMetadataRemoveDynamicFields
|
|
TestJetStreamSetDynamicConsumerMetadata
|
|
TestJetStreamSetDynamicConsumerInfoMetadata
|
|
TestJetStreamCopyConsumerMetadata
|
|
TestJetStreamCopyConsumerMetadataRemoveDynamicFields
|
|
TestJetStreamMetadataMutations
|
|
TestJetStreamMetadataStreamRestoreAndRestart
|
|
TestJetStreamMetadataStreamRestoreAndRestartCluster
|
|
TestJetStreamApiErrorOnRequiredApiLevel
|
|
TestJetStreamApiErrorOnRequiredApiLevelDirectGet
|
|
TestJetStreamApiErrorOnRequiredApiLevelPullConsumerNextMsg
|
|
TestJetStreamDirectGetBatchMaxBytes
|
|
TestJetStreamDirectGetMultiUpToTime
|
|
TestJetStreamDirectGetMultiMaxAllowed
|
|
TestJetStreamDirectGetMultiPaging
|
|
TestJetStreamDirectGetSubjectDeleteMarker
|
|
TestJetStreamDirectGetBatchParallelWriteDeadlock
|
|
TestJetStreamSnapshotRestoreStallAndHealthz
|
|
TestJetStreamUpgradeStreamVersioning
|
|
TestJetStreamUpgradeConsumerVersioning
|
|
TestJetStreamOfflineStreamAndConsumerAfterDowngrade
|
|
```
|
|
|
|
**Test command:**
|
|
```bash
|
|
dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~JsVersioningTests" -v minimal
|
|
```
|
|
|
|
**Commit:** `test(parity): port JetStream versioning, metadata & direct get tests (T10, ~48 tests) + DB update`
|
|
|
|
---
|
|
|
|
## Track 3: JetStream Cluster (296 tests)
|
|
|
|
> **Dependency:** Track 1 (Tasks 1-4) should complete first for storage reliability.
|
|
|
|
### Task 11: JetStream Cluster Batch 1 — Meta Recovery & Consumer State (~73 tests)
|
|
|
|
**Files:**
|
|
- Modify: `src/NATS.Server/JetStream/Cluster/JetStreamMetaGroup.cs`
|
|
- Modify: `tests/NATS.Server.Tests/JetStream/Cluster/JetStreamClusterFixture.cs`
|
|
- Create: `tests/NATS.Server.Tests/JetStream/Cluster/JsCluster1GoParityTests.cs`
|
|
- Modify: `docs/test_parity.db`
|
|
|
|
**Feature work:**
|
|
1. Enhance `JetStreamClusterFixture` — add multi-node simulation (3-node), add partition simulation
|
|
2. Add inflight request dedup in MetaGroup
|
|
3. Add meta recovery for consumer creates/deletes. Go ref: `jetstream_cluster.go:processStreamAssignment`
|
|
4. Add health check simulation — stream and consumer health status reporting
|
|
|
|
**Go tests to port:** All 73 unmapped from `jetstream_cluster_1_test.go` (see exploration output above).
|
|
|
|
**Test command:**
|
|
```bash
|
|
dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~JsCluster1GoParityTests" -v minimal
|
|
```
|
|
|
|
**Commit:** `test(parity): port JetStream cluster-1 tests (T11, 73 tests) + DB update`
|
|
|
|
---
|
|
|
|
### Task 12: JetStream Cluster Batch 2 — Cross-Domain & Rollups (~92 tests)
|
|
|
|
**Files:**
|
|
- Modify: `tests/NATS.Server.Tests/JetStream/Cluster/JetStreamClusterFixture.cs`
|
|
- Create: `tests/NATS.Server.Tests/JetStream/Cluster/JsCluster2GoParityTests.cs`
|
|
- Modify: `docs/test_parity.db`
|
|
|
|
**Feature work:**
|
|
1. Add domain simulation in cluster fixture — cross-domain source/mirror
|
|
2. Add mixed-mode cluster simulation (some nodes with JS, some without)
|
|
3. Add rollup support (KV-style subject rollup semantics)
|
|
4. Add consumer NAK/backoff in cluster context
|
|
|
|
**Go tests to port:** All 92 unmapped from `jetstream_cluster_2_test.go` (see exploration output above).
|
|
|
|
**Test command:**
|
|
```bash
|
|
dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~JsCluster2GoParityTests" -v minimal
|
|
```
|
|
|
|
**Commit:** `test(parity): port JetStream cluster-2 tests (T12, 92 tests) + DB update`
|
|
|
|
---
|
|
|
|
### Task 13: JetStream Cluster Batch 3 — Scale, Move & Pause (~131 tests)
|
|
|
|
**Files:**
|
|
- Modify: `src/NATS.Server/JetStream/Cluster/JetStreamMetaGroup.cs`
|
|
- Modify: `src/NATS.Server/JetStream/Cluster/StreamReplicaGroup.cs`
|
|
- Create: `tests/NATS.Server.Tests/JetStream/Cluster/JsCluster34GoParityTests.cs`
|
|
- Modify: `docs/test_parity.db`
|
|
|
|
**Feature work:**
|
|
1. Add stream/consumer scale up/down simulation — change replica count dynamically
|
|
2. Add stream move simulation — relocate stream to different nodes
|
|
3. Add consumer pause in cluster context with leader handoff
|
|
4. Add lame duck mode simulation
|
|
5. Add orphan NRG detection and cleanup
|
|
|
|
**Go tests to port:** All 64 from `jetstream_cluster_3_test.go` + all 61 from `jetstream_cluster_4_test.go` + 6 from `jetstream_cluster_long_test.go` (see exploration output).
|
|
|
|
**Test command:**
|
|
```bash
|
|
dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~JsCluster34GoParityTests" -v minimal
|
|
```
|
|
|
|
**Commit:** `test(parity): port JetStream cluster-3/4/long tests (T13, ~131 tests) + DB update`
|
|
|
|
---
|
|
|
|
## Track 4: Consumer Engines (96 tests)
|
|
|
|
### Task 14: Consumer Pull Queue, State & Filters (~48 tests)
|
|
|
|
**Gaps addressed:** Gap 4 — HIGH
|
|
|
|
**Files:**
|
|
- Modify: `src/NATS.Server/JetStream/Consumers/PullConsumerEngine.cs`
|
|
- Modify: `src/NATS.Server/JetStream/Consumers/AckProcessor.cs`
|
|
- Modify: `src/NATS.Server/JetStream/ConsumerManager.cs`
|
|
- Create: `tests/NATS.Server.Tests/JetStream/Consumers/ConsumerPullQueueTests.cs`
|
|
- Modify: `docs/test_parity.db`
|
|
|
|
**Feature work:**
|
|
1. Add pull request queue with priority ordering. Go ref: `consumer.go:waitingPending`
|
|
2. Add MaxWaiting enforcement — limit concurrent pull requests per consumer
|
|
3. Add pull request cleanup/expiry — remove stale requests
|
|
4. Add multi-filter race condition handling — safe concurrent filter evaluation
|
|
5. Add batch completion detection — track when all requested messages delivered
|
|
6. Add MaxBytes enforcement on pull responses
|
|
7. Add NoWait behavior for empty pending
|
|
|
|
**Go tests to port (~48):**
|
|
```
|
|
TestJetStreamConsumerPullMaxAckPending
|
|
TestJetStreamConsumerPullConsumerFIFO
|
|
TestJetStreamConsumerPullConsumerOneShotOnMaxAckLimit
|
|
TestJetStreamConsumerPullMaxWaitingOfOne
|
|
TestJetStreamConsumerPullMaxWaiting
|
|
TestJetStreamConsumerPullRequestCleanup
|
|
TestJetStreamConsumerPullRequestMaximums
|
|
TestJetStreamConsumerPullCrossAccountExpires
|
|
TestJetStreamConsumerPullCrossAccountExpiresNoDataRace
|
|
TestJetStreamConsumerPullCrossAccountsAndLeafNodes
|
|
TestJetStreamConsumerPullOneShotBehavior
|
|
TestJetStreamConsumerPullMultipleRequestsExpireOutOfOrder
|
|
TestJetStreamConsumerPullLastPerSubjectRedeliveries
|
|
TestJetStreamConsumerPullTimeoutHeaders
|
|
TestJetStreamConsumerPullBatchCompleted
|
|
TestJetStreamConsumerPullLargeBatchExpired
|
|
TestJetStreamConsumerPullTimeout
|
|
TestJetStreamConsumerPullMaxBytes
|
|
TestJetStreamConsumerPullNoWaitBatchLargerThanPending
|
|
TestJetStreamConsumerPullRemoveInterest
|
|
TestJetStreamConsumerPullDelayedFirstPullWithReplayOriginal
|
|
TestJetStreamConsumerMultipleFiltersRace
|
|
TestJetStreamConsumerMultipleFitersWithStartDate
|
|
TestJetStreamConsumerMultipleSubjectsLast
|
|
TestJetStreamConsumerMultipleSubjectsLastPerSubject
|
|
TestJetStreamConsumerMultipleSubjectsWithEmpty
|
|
TestJetStreamConsumerMultipleSubjectsAck
|
|
TestJetStreamConsumerMultipleSubjectAndNewAPI
|
|
TestJetStreamConsumerMultipleSubjectsWithAddedMessages
|
|
TestJetStreamConsumerThreeFilters
|
|
TestJetStreamConsumerUpdateFilterSubjects
|
|
TestJetStreamConsumerFilterUpdate
|
|
TestJetStreamConsumerIsFiltered
|
|
TestJetStreamConsumerSingleFilterSubjectInFilterSubjects
|
|
TestSortingConsumerPullRequests
|
|
TestWaitQueuePopAndRequeue
|
|
TestJetStreamConsumerStateAlwaysFromStore
|
|
TestJetStreamConsumerCheckNumPending
|
|
TestJetStreamConsumerOnlyRecalculatePendingIfFilterSubjectUpdated
|
|
TestJetStreamConsumerAllowOverlappingSubjectsIfNotSubset
|
|
TestJetStreamConsumerBadNumPending
|
|
TestJetStreamConsumerPendingCountWithRedeliveries
|
|
TestJetStreamConsumerPendingCountAfterMsgAckAboveFloor
|
|
TestJetStreamConsumerDontDecrementPendingCountOnSkippedMsg
|
|
TestJetStreamConsumerNumPendingWithMaxPerSubjectGreaterThanOne
|
|
TestJetStreamConsumerPendingLowerThanStreamFirstSeq
|
|
TestJetStreamConsumerInfoNumPending
|
|
TestJetStreamConsumerEfficientInterestStateCheck
|
|
```
|
|
|
|
**Test command:**
|
|
```bash
|
|
dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~ConsumerPullQueueTests" -v minimal
|
|
```
|
|
|
|
**Commit:** `test(parity): port consumer pull queue, state & filter tests (T14, ~48 tests) + DB update`
|
|
|
|
---
|
|
|
|
### Task 15: Consumer Pause, Replay, Priority & Lifecycle (~48 tests)
|
|
|
|
**Files:**
|
|
- Modify: `src/NATS.Server/JetStream/Consumers/PushConsumerEngine.cs`
|
|
- Modify: `src/NATS.Server/JetStream/Consumers/PriorityGroupManager.cs`
|
|
- Modify: `src/NATS.Server/JetStream/Consumers/RedeliveryTracker.cs`
|
|
- Modify: `src/NATS.Server/JetStream/ConsumerManager.cs`
|
|
- Create: `tests/NATS.Server.Tests/JetStream/Consumers/ConsumerLifecycleTests.cs`
|
|
- Modify: `docs/test_parity.db`
|
|
|
|
**Feature work:**
|
|
1. Add consumer pause/resume — state machine with Pause(until), Resume(), advisory publication
|
|
2. Add replay rate matching — deliver at original publish timestamps. Go ref: `consumer.go:replayRate`
|
|
3. Add priority pull requests — priority-based consumer ordering. Go ref: `consumer.go:prioritized`
|
|
4. Add consumer state persistence — survive server restart. Go ref: `consumer.go:writeState`
|
|
5. Add max delivery underflow handling
|
|
6. Add inactive threshold for ephemeral consumer cleanup
|
|
|
|
**Go tests to port (~48):**
|
|
```
|
|
TestJetStreamConsumerPauseViaConfig
|
|
TestJetStreamConsumerPauseViaEndpoint
|
|
TestJetStreamConsumerPauseResumeViaEndpoint
|
|
TestJetStreamConsumerPauseAdvisories
|
|
TestJetStreamConsumerReplayRate
|
|
TestJetStreamConsumerReplayQuit
|
|
TestJetStreamConsumerPrioritized
|
|
TestJetStreamConsumerPriorityPullRequests
|
|
TestJetStreamConsumerMaxDeliverUnderflow
|
|
TestJetStreamConsumerNoWaitNoMessagesOnEos
|
|
TestJetStreamConsumerNoWaitNoMessagesOnEosWithDeliveredMsgs
|
|
TestJetStreamConsumerActionsViaAPI
|
|
TestJetStreamConsumerActionsUnmarshal
|
|
TestJetStreamConsumerWorkQueuePolicyOverlap
|
|
TestJetStreamConsumerLongSubjectHang
|
|
TestJetStreamConsumerStuckAckPending
|
|
TestJetStreamConsumerSwitchLeaderDuringInflightAck
|
|
TestJetStreamConsumerEphemeralRecoveryAfterServerRestart
|
|
TestJetStreamConsumerMaxDeliveryAndServerRestart
|
|
TestJetStreamConsumerDeleteAndServerRestart
|
|
TestJetStreamConsumerDurableReconnectWithOnlyPending
|
|
TestJetStreamConsumerDurableFilteredSubjectReconnect
|
|
TestJetStreamConsumerInactiveNoDeadlock
|
|
TestJetStreamConsumerReconnect
|
|
TestJetStreamConsumerDeliverNewMaxRedeliveriesAndServerRestart
|
|
TestJetStreamConsumerEOFBugNewFileStore
|
|
TestJetStreamConsumerCleanupWithRetentionPolicy
|
|
TestJetStreamConsumerPendingBugWithKV
|
|
TestJetStreamConsumerBadCreateErr
|
|
TestJetStreamConsumerInternalClientLeak
|
|
TestJetStreamConsumerEventingRaceOnShutdown
|
|
TestJetStreamConsumerNoMsgPayload
|
|
TestJetStreamConsumerUpdateSurvival
|
|
TestJetStreamConsumerAckSamplingSpecifiedUsingUpdateConsumer
|
|
TestJetStreamConsumerStreamUpdate
|
|
TestJetStreamConsumerAndStreamNamesWithPathSeparators
|
|
TestJetStreamConsumerUpdateFilterSubject
|
|
TestJetStreamConsumerAndStreamMetadata
|
|
TestJetStreamConsumerDefaultsFromStream
|
|
TestJetStreamConsumerWithFormattingSymbol
|
|
TestJetStreamConsumerWithCorruptStateIsDeleted
|
|
TestJetStreamConsumerNoDeleteAfterConcurrentShutdownAndLeaderChange
|
|
TestJetStreamConsumerResetToSequenceConstraintOnStartSeq
|
|
TestJetStreamConsumerResetToSequenceConstraintOnStartTime
|
|
TestJetStreamConsumerLegacyDurableCreateSetsConsumerName
|
|
TestJetStreamConsumerNotInactiveDuringAckWait
|
|
```
|
|
|
|
**Test command:**
|
|
```bash
|
|
dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~ConsumerLifecycleTests" -v minimal
|
|
```
|
|
|
|
**Commit:** `test(parity): port consumer pause, replay, priority & lifecycle tests (T15, ~48 tests) + DB update`
|
|
|
|
---
|
|
|
|
## Track 5: Auth/JWT/Accounts (105 tests)
|
|
|
|
### Task 16: JWT Claims & Account Resolver (~61 tests)
|
|
|
|
**Gaps addressed:** Gap 9 — MEDIUM
|
|
|
|
**Files:**
|
|
- Modify: `src/NATS.Server/Auth/JwtAuthenticator.cs`
|
|
- Modify: `src/NATS.Server/Auth/AccountClaims.cs`
|
|
- Modify: `src/NATS.Server/Auth/AccountResolver.cs`
|
|
- Create: `tests/NATS.Server.Tests/Auth/JwtGoParityTests.cs`
|
|
- Modify: `docs/test_parity.db`
|
|
|
|
**Feature work:**
|
|
1. Add full operator→account→user trust chain validation. Go ref: `jwt.go:validateTrustedOperators`
|
|
2. Add signing key hierarchy — operator signing keys, account signing keys
|
|
3. Add account URL resolver with fetch, timeout, retry. Go ref: `accounts.go:URLAccResolver`
|
|
4. Add NATS resolver — resolve accounts via NATS request/reply. Go ref: `accounts.go:NATSAccResolver`
|
|
5. Add JWT expiration handling — disconnect expired users/accounts
|
|
6. Add import activation — activation tokens with expiration
|
|
7. Add account limits from JWT claims — max connections, payload, subs
|
|
|
|
**Go tests to port:** All 61 from jwt_test.go (see exploration output above).
|
|
|
|
**Test command:**
|
|
```bash
|
|
dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~JwtGoParityTests" -v minimal
|
|
```
|
|
|
|
**Commit:** `test(parity): port JWT claims & account resolver tests (T16, 61 tests) + DB update`
|
|
|
|
---
|
|
|
|
### Task 17: Auth Callout (~30 tests)
|
|
|
|
**Files:**
|
|
- Create: `src/NATS.Server/Auth/AuthCalloutHandler.cs`
|
|
- Modify: `src/NATS.Server/Auth/AuthService.cs`
|
|
- Create: `tests/NATS.Server.Tests/Auth/AuthCalloutGoParityTests.cs`
|
|
- Modify: `docs/test_parity.db`
|
|
|
|
**Feature work:**
|
|
1. Create `AuthCalloutHandler` — external auth delegation via NATS request/reply. Go ref: `auth_callout.go`
|
|
2. Add callout with TLS client certificate forwarding
|
|
3. Add callout with operator mode and encryption
|
|
4. Add callout error response handling
|
|
5. Add callout with leaf node integration
|
|
|
|
**Go tests to port:** All 30 from auth_callout_test.go (see exploration output above).
|
|
|
|
**Test command:**
|
|
```bash
|
|
dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~AuthCalloutGoParityTests" -v minimal
|
|
```
|
|
|
|
**Commit:** `test(parity): port auth callout tests (T17, 30 tests) + DB update`
|
|
|
|
---
|
|
|
|
### Task 18: Account Imports/Exports & Routing (~14 tests)
|
|
|
|
**Files:**
|
|
- Modify: `src/NATS.Server/Auth/Account.cs`
|
|
- Modify: `src/NATS.Server/Auth/AuthService.cs`
|
|
- Create: `tests/NATS.Server.Tests/Auth/AccountRoutingTests.cs`
|
|
- Modify: `docs/test_parity.db`
|
|
|
|
**Feature work:**
|
|
1. Add weighted subject route mappings. Go ref: `accounts.go:addMapping`
|
|
2. Add origin cluster filtering on route mappings
|
|
3. Add service/stream export with authorization checks
|
|
4. Add system account permissions with global access
|
|
5. Add per-account system event permissions
|
|
|
|
**Go tests to port:** All 14 from accounts_test.go (see exploration output above).
|
|
|
|
**Test command:**
|
|
```bash
|
|
dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~AccountRoutingTests" -v minimal
|
|
```
|
|
|
|
**Commit:** `test(parity): port account routing & import/export tests (T18, 14 tests) + DB update`
|
|
|
|
---
|
|
|
|
## Track 6: Networking (187 tests)
|
|
|
|
### Task 19: Gateway Tests (~48 tests)
|
|
|
|
**Gaps addressed:** Gap 11 — MEDIUM
|
|
|
|
**Files:**
|
|
- Modify: `src/NATS.Server/Gateway/GatewayManager.cs`
|
|
- Modify: `src/NATS.Server/Gateway/GatewayConnection.cs`
|
|
- Create: `tests/NATS.Server.Tests/Gateway/GatewayGoParityTests.cs`
|
|
- Modify: `docs/test_parity.db`
|
|
|
|
**Feature work:**
|
|
1. Add gateway auto-discovery — learn gateways from cluster gossip. Go ref: `gateway.go:solicitGateway`
|
|
2. Add gateway TLS with mutual auth and cert reload
|
|
3. Add gateway queue sub propagation. Go ref: `gateway.go:sendQSubs`
|
|
4. Add gateway interest-only mode optimization. Go ref: `gateway.go:switchToInterestOnly`
|
|
5. Add gateway service import/export with queue groups
|
|
6. Add gateway connection events (advisory publication)
|
|
|
|
**Go tests to port:** All 48 from gateway_test.go (see exploration output above).
|
|
|
|
**Test command:**
|
|
```bash
|
|
dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~GatewayGoParityTests" -v minimal
|
|
```
|
|
|
|
**Commit:** `test(parity): port gateway tests (T19, 48 tests) + DB update`
|
|
|
|
---
|
|
|
|
### Task 20: Leaf Node Tests (~75 tests)
|
|
|
|
**Gaps addressed:** Gap 12 — MEDIUM
|
|
|
|
**Files:**
|
|
- Modify: `src/NATS.Server/LeafNode/LeafNodeManager.cs`
|
|
- Modify: `src/NATS.Server/LeafNode/LeafConnection.cs`
|
|
- Create: `tests/NATS.Server.Tests/LeafNode/LeafNodeGoParityTests.cs`
|
|
- Modify: `docs/test_parity.db`
|
|
|
|
**Feature work:**
|
|
1. Add solicited leaf connections with TLS, retry, backoff. Go ref: `leafnode.go:solicitLeafNode`
|
|
2. Add leaf node compression negotiation (S2). Go ref: `leafnode.go:compressionNegotiation`
|
|
3. Add leaf node WebSocket support. Go ref: `leafnode.go:wsLeaf`
|
|
4. Add leaf node queue group distribution across hubs. Go ref: `leafnode.go:processLeafSub`
|
|
5. Add leaf node TLS handshake-first mode
|
|
6. Add leaf JetStream domain forwarding
|
|
|
|
**Go tests to port:** All 55 from leafnode_test.go + 8 from leafnode_proxy_test.go + 12 from jetstream_leafnode_test.go.
|
|
|
|
**Test command:**
|
|
```bash
|
|
dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~LeafNodeGoParityTests" -v minimal
|
|
```
|
|
|
|
**Commit:** `test(parity): port leaf node tests (T20, ~75 tests) + DB update`
|
|
|
|
---
|
|
|
|
### Task 21: Routes & Super-Cluster (~84 tests)
|
|
|
|
**Gaps addressed:** Gap 13 — MEDIUM
|
|
|
|
**Files:**
|
|
- Modify: `src/NATS.Server/Route/RouteManager.cs`
|
|
- Modify: `src/NATS.Server/Route/RouteConnection.cs`
|
|
- Create: `tests/NATS.Server.Tests/Route/RouteGoParityTests.cs`
|
|
- Create: `tests/NATS.Server.Tests/JetStream/Cluster/JsSuperClusterTests.cs`
|
|
- Modify: `docs/test_parity.db`
|
|
|
|
**Feature work:**
|
|
1. Add route pooling — multiple connections per peer. Go ref: `route.go:routePool`
|
|
2. Add route compression with S2. Go ref: `route.go:compressionNegotiation`
|
|
3. Add per-account dedicated routes. Go ref: `route.go:perAccountRoutes`
|
|
4. Add route slow consumer detection and recovery
|
|
5. Add super-cluster simulation fixture — multi-cluster topology via gateway
|
|
6. Add route TLS with implicit cert allow/reject
|
|
|
|
**Go tests to port:** All 37 from routes_test.go + all 47 from jetstream_super_cluster_test.go.
|
|
|
|
**Test command:**
|
|
```bash
|
|
dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~RouteGoParityTests OR FullyQualifiedName~JsSuperClusterTests" -v minimal
|
|
```
|
|
|
|
**Commit:** `test(parity): port route + super-cluster tests (T21, ~84 tests) + DB update`
|
|
|
|
---
|
|
|
|
## Track 7: Config/Reload/Monitoring (132 tests)
|
|
|
|
### Task 22: Configuration & Options (~49 tests)
|
|
|
|
**Gaps addressed:** Gap 14 — MEDIUM
|
|
|
|
**Files:**
|
|
- Modify: `src/NATS.Server/Configuration/ConfigProcessor.cs`
|
|
- Modify: `src/NATS.Server/Configuration/NatsConfParser.cs`
|
|
- Create: `tests/NATS.Server.Tests/Configuration/OptsGoParityTests.cs`
|
|
- Modify: `docs/test_parity.db`
|
|
|
|
**Feature work:**
|
|
1. Add gateway config parsing. Go ref: `opts.go:parseGateways`
|
|
2. Add leaf node remote config parsing. Go ref: `opts.go:parseLeafNodes`
|
|
3. Add operator JWT config reading. Go ref: `opts.go:readOperatorJWT`
|
|
4. Add NKey user config parsing with permissions. Go ref: `opts.go:parseNKeys`
|
|
5. Add environment variable include/reference support. Go ref: `opts.go:envInclude`
|
|
6. Add service latency config parsing
|
|
7. Add authorization timeout config for leaf nodes
|
|
|
|
**Go tests to port:** All 49 from opts_test.go (see exploration output above).
|
|
|
|
**Test command:**
|
|
```bash
|
|
dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~OptsGoParityTests" -v minimal
|
|
```
|
|
|
|
**Commit:** `test(parity): port config & options tests (T22, 49 tests) + DB update`
|
|
|
|
---
|
|
|
|
### Task 23: Config Reload (~38 tests)
|
|
|
|
**Files:**
|
|
- Modify: `src/NATS.Server/Configuration/ConfigReloader.cs`
|
|
- Create: `tests/NATS.Server.Tests/Configuration/ReloadGoParityTests.cs`
|
|
- Modify: `docs/test_parity.db`
|
|
|
|
**Feature work:**
|
|
1. Add TLS cert rotation on reload. Go ref: `reload.go:reloadTLS`
|
|
2. Add cluster authorization reload. Go ref: `reload.go:reloadClusterAuthorization`
|
|
3. Add cluster routes reload — add/remove solicited routes. Go ref: `reload.go:reloadClusterRoutes`
|
|
4. Add account NKey user reload
|
|
5. Add account stream/service import/export reload
|
|
6. Add route pool and per-account reload
|
|
7. Add route/leaf compression reload
|
|
|
|
**Go tests to port:** All 38 from reload_test.go (see exploration output above).
|
|
|
|
**Test command:**
|
|
```bash
|
|
dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~ReloadGoParityTests" -v minimal
|
|
```
|
|
|
|
**Commit:** `test(parity): port config reload tests (T23, 38 tests) + DB update`
|
|
|
|
---
|
|
|
|
### Task 24: Monitoring Endpoints (~45 tests)
|
|
|
|
**Gaps addressed:** Gap 10 — MEDIUM
|
|
|
|
**Files:**
|
|
- Modify: `src/NATS.Server/Monitoring/ConnzHandler.cs`
|
|
- Modify: `src/NATS.Server/Monitoring/Varz.cs`
|
|
- Create: `tests/NATS.Server.Tests/Monitoring/MonitorGoParityTests.cs`
|
|
- Modify: `docs/test_parity.db`
|
|
|
|
**Feature work:**
|
|
1. Add connz sort by uptime, stop time for closed connections. Go ref: `monitor.go:connzSort`
|
|
2. Add connz closed connections ring buffer. Go ref: `monitor.go:closedClients`
|
|
3. Add connz TLS info reporting (handshake state, cipher suite)
|
|
4. Add operator mode account reporting in connz/accountz
|
|
5. Add gateway URL reporting in gatewayz. Go ref: `monitor.go:gatewayz`
|
|
6. Add leafz endpoint with full leaf connection details
|
|
7. Add healthz with JetStream availability check
|
|
8. Add varz metadata, sync interval, TLS cert expiry
|
|
9. Add profilez endpoint
|
|
|
|
**Go tests to port:** All 45 from monitor_test.go (see exploration output above).
|
|
|
|
**Test command:**
|
|
```bash
|
|
dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~MonitorGoParityTests" -v minimal
|
|
```
|
|
|
|
**Commit:** `test(parity): port monitoring endpoint tests (T24, 45 tests) + DB update`
|
|
|
|
---
|
|
|
|
## Track 8: Client/Protocol/Misc (112 tests)
|
|
|
|
### Task 25: Client Protocol & Server Lifecycle (~50 tests)
|
|
|
|
**Gaps addressed:** Gap 5 — HIGH
|
|
|
|
**Files:**
|
|
- Modify: `src/NATS.Server/NatsClient.cs`
|
|
- Modify: `src/NATS.Server/NatsServer.cs`
|
|
- Create: `tests/NATS.Server.Tests/ClientServerGoParityTests.cs`
|
|
- Modify: `docs/test_parity.db`
|
|
|
|
**Feature work:**
|
|
1. Add TLS handshake-first mode — TLS before INFO. Go ref: `client.go:tlsHandshakeFirst`
|
|
2. Add write timeout policy configuration. Go ref: `client.go:writeTimeout`
|
|
3. Add slow consumer write loop stall detection
|
|
4. Add server rate limit logging
|
|
5. Add in-process connection type support
|
|
6. Add semantic version parsing. Go ref: `server.go:versionComponents`
|
|
7. Add profiler and monitoring port startup
|
|
|
|
**Go tests to port:** All 22 from client_test.go + all 28 from server_test.go.
|
|
|
|
**Test command:**
|
|
```bash
|
|
dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~ClientServerGoParityTests" -v minimal
|
|
```
|
|
|
|
**Commit:** `test(parity): port client protocol & server lifecycle tests (T25, ~50 tests) + DB update`
|
|
|
|
---
|
|
|
|
### Task 26: PROXY Protocol & SubList (~48 tests)
|
|
|
|
**Files:**
|
|
- Create: `src/NATS.Server/Protocol/ProxyProtocol.cs`
|
|
- Modify: `src/NATS.Server/Subscriptions/SubList.cs`
|
|
- Create: `tests/NATS.Server.Tests/Protocol/ProxyProtocolTests.cs`
|
|
- Create: `tests/NATS.Server.Tests/Subscriptions/SubListGoParityTests.cs`
|
|
- Modify: `docs/test_parity.db`
|
|
|
|
**Feature work:**
|
|
1. Create PROXY protocol v1/v2 parser — extract source IP/port from load balancer header. Go ref: `client.go:parseProxyProto`
|
|
2. Add v1 (text-based TCP4/TCP6/UNKNOWN) and v2 (binary IPv4/IPv6/LOCAL) support
|
|
3. Add SubList interest notification registration. Go ref: `sublist.go:RegisterNotification`
|
|
4. Add SubList subject collision detection
|
|
5. Add SubList cache hit rate tracking
|
|
|
|
**Go tests to port:** All 23 from client_proxyproto_test.go + all 25 from sublist_test.go.
|
|
|
|
**Test command:**
|
|
```bash
|
|
dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~ProxyProtocolTests OR FullyQualifiedName~SubListGoParityTests" -v minimal
|
|
```
|
|
|
|
**Commit:** `test(parity): port PROXY protocol + SubList tests (T26, ~48 tests) + DB update`
|
|
|
|
---
|
|
|
|
### Task 27: Message Trace, Closed Conns & Infrastructure (~70 tests)
|
|
|
|
**Files:**
|
|
- Modify: `src/NATS.Server/Internal/MessageTraceContext.cs`
|
|
- Create: `tests/NATS.Server.Tests/MsgTraceGoParityTests.cs`
|
|
- Create: `tests/NATS.Server.Tests/InfrastructureGoParityTests.cs`
|
|
- Modify: `docs/test_parity.db`
|
|
|
|
**Feature work:**
|
|
1. Add message trace propagation through routes, leaf nodes, gateways. Go ref: `msgtrace.go`
|
|
2. Add trace with compression support
|
|
3. Add trace triggered by external header
|
|
4. Add trace with JetStream and super-cluster
|
|
5. Add closed connection tracking with reason codes. Go ref: `client.go:closedConns`
|
|
6. Port remaining infrastructure tests: parser, log, errors, config_check, auth, jetstream_errors, jetstream_jwt, jetstream_tpm, trust, subject_transform, nkey, ping, rate_counter, util, mqtt_ex
|
|
|
|
**Go tests to port:** All 22 from msgtrace_test.go + 6 from closed_conns_test.go + remaining infrastructure tests (~42):
|
|
```
|
|
# parser_test.go (5)
|
|
TestServerInfoNonceAlwaysEnabled, TestParseRoutedHeaderMsg, TestParseRouteMsg, TestParseMsgSpace, TestProtoSnippet
|
|
|
|
# log_test.go (4)
|
|
TestSetLogger, TestReOpenLogFile, TestRemovePassFromTrace, TestRemoveAuthTokenFromTrace
|
|
|
|
# errors_test.go (2)
|
|
TestErrCtx, TestErrCtxWrapped
|
|
|
|
# config_check_test.go (2)
|
|
TestConfigCheck, TestConfigCheckMultipleErrors
|
|
|
|
# auth_test.go (2)
|
|
TestDNSAltNameMatching, TestNoAuthUserNoConnectProto
|
|
|
|
# jetstream_errors_test.go (4)
|
|
TestIsNatsErr, TestApiError_Error, TestApiError_NewWithTags, TestApiError_NewWithUnless
|
|
|
|
# jetstream_jwt_test.go (18)
|
|
TestJetStreamJWTLimits, TestJetStreamJWTDisallowBearer, TestJetStreamJWTMove, TestJetStreamJWTClusteredTiers, ...
|
|
|
|
# jetstream_tpm_test.go (5)
|
|
TestJetStreamTPMBasic, TestJetStreamTPMKeyBadPassword, TestJetStreamTPMKeyWithPCR, TestJetStreamTPMAll, ...
|
|
|
|
# trust_test.go (3)
|
|
TestStampedTrustedKeys, TestTrustedKeysOptions, TestTrustConfigOption
|
|
|
|
# subject_transform_test.go (3)
|
|
TestSubjectTransforms, TestSubjectTransformDoesntPanicTransformingMissingToken, ...
|
|
|
|
# nkey_test.go (1), ping_test.go (1), rate_counter_test.go (1)
|
|
# util_test.go (6), mqtt_ex_test_test.go (2)
|
|
```
|
|
|
|
**Test command:**
|
|
```bash
|
|
dotnet test tests/NATS.Server.Tests --filter "FullyQualifiedName~MsgTraceGoParityTests OR FullyQualifiedName~InfrastructureGoParityTests" -v minimal
|
|
```
|
|
|
|
**Commit:** `test(parity): port message trace + infrastructure tests (T27, ~70 tests) + DB update`
|
|
|
|
---
|
|
|
|
## Task 28: Full Test Suite Verification & DB Reconciliation
|
|
|
|
**Step 1: Run full test suite**
|
|
|
|
```bash
|
|
dotnet test tests/NATS.Server.Tests -v minimal
|
|
```
|
|
|
|
Expected: 6,000+ tests passing, 0 failures.
|
|
|
|
**Step 2: Verify DB status**
|
|
|
|
```bash
|
|
sqlite3 docs/test_parity.db "SELECT status, COUNT(*) FROM go_tests GROUP BY status"
|
|
```
|
|
|
|
Expected:
|
|
- mapped: ~2,666 (90.8%)
|
|
- not_applicable: ~268
|
|
- skipped: 3
|
|
- unmapped: ~0
|
|
|
|
**Step 3: Generate summary report**
|
|
|
|
```bash
|
|
sqlite3 docs/test_parity.db "SELECT go_file, COUNT(*) as total, SUM(status='mapped') as mapped, SUM(status='unmapped') as unmapped, SUM(status='not_applicable') as na FROM go_tests GROUP BY go_file ORDER BY unmapped DESC"
|
|
```
|
|
|
|
**Step 4: Commit final state**
|
|
|
|
```bash
|
|
git add docs/test_parity.db
|
|
git commit -m "chore: final parity DB reconciliation — target 90%+ mapped"
|
|
```
|
|
|
|
---
|
|
|
|
## Execution Summary
|
|
|
|
| Task | Track | Tests | Dependencies |
|
|
|------|-------|------:|-------------|
|
|
| T0 | — | ~222 (mark n/a) | None |
|
|
| T1 | 1: Storage | ~50 | None |
|
|
| T2 | 1: Storage | ~40 | None |
|
|
| T3 | 1: Storage | ~28 | None |
|
|
| T4 | 1: Storage | ~16 | T1-T3 |
|
|
| T5 | 2: JS Core | ~42 | None |
|
|
| T6 | 2: JS Core | ~26 | None |
|
|
| T7 | 2: JS Core | ~36 | None |
|
|
| T8 | 2: JS Core | ~39 | None |
|
|
| T9 | 2: JS Core | ~29 | None |
|
|
| T10 | 2: JS Core | ~48 | None |
|
|
| T11 | 3: JS Cluster | ~73 | T1-T4 |
|
|
| T12 | 3: JS Cluster | ~92 | T1-T4 |
|
|
| T13 | 3: JS Cluster | ~131 | T1-T4 |
|
|
| T14 | 4: Consumer | ~48 | None |
|
|
| T15 | 4: Consumer | ~48 | None |
|
|
| T16 | 5: Auth/JWT | ~61 | None |
|
|
| T17 | 5: Auth/JWT | ~30 | None |
|
|
| T18 | 5: Auth/JWT | ~14 | None |
|
|
| T19 | 6: Network | ~48 | None |
|
|
| T20 | 6: Network | ~75 | None |
|
|
| T21 | 6: Network | ~84 | None |
|
|
| T22 | 7: Config | ~49 | None |
|
|
| T23 | 7: Config | ~38 | None |
|
|
| T24 | 7: Monitor | ~45 | None |
|
|
| T25 | 8: Client | ~50 | None |
|
|
| T26 | 8: Protocol | ~48 | None |
|
|
| T27 | 8: Misc | ~70 | None |
|
|
| T28 | — | Verify | All |
|
|
| **Total** | | **~1,418** | |
|
|
|
|
### Parallelism
|
|
|
|
**Independent (can run in parallel):** T0, T1-T3, T5-T10, T14-T15, T16-T18, T19-T21, T22-T24, T25-T27
|
|
|
|
**Sequential within track:**
|
|
- Track 1: T1→T2→T3→T4
|
|
- Track 3: Waits for Track 1 completion, then T11→T12→T13
|
|
|
|
**Final:** T28 runs after all others complete.
|