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:
Joseph Doherty
2026-03-12 14:09:23 -04:00
parent 79c1ee8776
commit c30e67a69d
226 changed files with 17801 additions and 709 deletions

View File

@@ -112,7 +112,7 @@ Add rows to the Gap Inventory table below. Group by Go source file. Include the
|-----------|:-------------|--------|:----------------|-------|
| **golang/nats-server/main.go** | | | | |
| main() | main.go:97 | PORTED | src/NATS.Server.Host/Program.cs:1 | CLI arg parsing, config load, server create, start, wait |
| usage() | main.go:92 | PARTIAL | src/NATS.Server.Host/Program.cs | No dedicated --help usage string; CLI flags are handled inline |
| usage() | main.go:92 | PORTED | src/NATS.Server.Host/Program.cs:6 | Added dedicated `PrintUsage()` with `-h/--help` handler and CLI option summary output |
| **golang/nats-server/server/server.go — Types** | | | | |
| Info struct | server.go:109 | PORTED | src/NATS.Server/Protocol/NatsProtocol.cs:39 (ServerInfo) | Core fields ported; route/gateway/leafnode-specific fields are partial |
| Server struct | server.go:169 | PARTIAL | src/NATS.Server/NatsServer.cs:31 | Core fields ported (clients, accounts, opts, listener, shutdown). Missing: route pool tracking, gateway internals, OCSP monitors, proxied conns, rate limiting maps |
@@ -120,9 +120,9 @@ Add rows to the Gap Inventory table below. Group by Go source file. Include the
| scStats struct | server.go:413 | PORTED | src/NATS.Server/ServerStats.cs:18-25 | Per-kind slow consumer counters present |
| staleStats struct | server.go:421 | PORTED | src/NATS.Server/ServerStats.cs:26 | Per-kind stale connection counters present |
| nodeInfo struct | server.go:387 | NOT_APPLICABLE | — | JetStream cluster-specific; tracked in JetStream module |
| Ports struct | server.go:4236 | MISSING | — | Not implemented; no /ports output support |
| Compression constants | server.go:437-446 | MISSING | — | S2 compression mode constants not defined in core server |
| CompressionOpts struct | server.go:97 (opts.go) | MISSING | — | No compression options type in .NET |
| Ports struct | server.go:4236 | PORTED | src/NATS.Server/NatsOptions.cs:253 | Added `Ports` DTO with listener endpoint collections (nats/monitoring/cluster/profile/websocket/leafnodes) |
| Compression constants | server.go:437-446 | PORTED | src/NATS.Server/NatsOptions.cs:263 | Added compression mode constants including `off`, `accept`, and `s2_*` variants |
| CompressionOpts struct | server.go:97 (opts.go) | PORTED | src/NATS.Server/NatsOptions.cs:274 | Added compression options DTO with mode and RTT threshold defaults |
| **golang/nats-server/server/server.go — Exported Server Methods** | | | | |
| NewServer() | server.go:716 | PORTED | src/NATS.Server/NatsServer.cs constructor | Options validation, NKey identity, info setup |
| New() (deprecated) | server.go:698 | NOT_APPLICABLE | — | Deprecated wrapper |
@@ -136,14 +136,14 @@ Add rows to the Gap Inventory table below. Group by Go source file. Include the
| (s) ID() | server.go:4036 | PORTED | src/NATS.Server/NatsServer.cs:101 (ServerId) | — |
| (s) Name() | server.go:4046 | PORTED | src/NATS.Server/NatsServer.cs:102 (ServerName) | — |
| (s) NodeName() | server.go:4041 | PORTED | src/NATS.Server/NatsServer.cs:102 | Same as ServerName |
| (s) ClusterName() | server.go:1017 | PARTIAL | src/NATS.Server/NatsServer.cs:110 (ClusterListen) | Only listen endpoint; no cluster name getter |
| (s) ClientURL() | server.go:1086 | MISSING | — | No dedicated method to return client connect URL |
| (s) WebsocketURL() | server.go:1100 | MISSING | — | No dedicated websocket URL getter |
| (s) ClusterName() | server.go:1017 | PORTED | src/NATS.Server/NatsServer.cs:121 | Dedicated cluster name getter from `NatsOptions.Cluster.Name` |
| (s) ClientURL() | server.go:1086 | PORTED | src/NATS.Server/NatsServer.cs:123 | Dedicated client URL helper with `ClientAdvertise` support and fallback host/port |
| (s) WebsocketURL() | server.go:1100 | PORTED | src/NATS.Server/NatsServer.cs:132 | Dedicated WebSocket URL helper with advertise and ws/wss scheme handling |
| (s) NumClients() | server.go:3810 | PORTED | src/NATS.Server/NatsServer.cs:103 (ClientCount) | — |
| (s) NumRoutes() | server.go:3773 | PARTIAL | src/NATS.Server/ServerStats.cs:14 (Routes field) | Stats counter exists; no lock-safe method like Go |
| (s) NumRemotes() | server.go:3790 | MISSING | — | — |
| (s) NumLeafNodes() | server.go:3803 | PARTIAL | src/NATS.Server/ServerStats.cs:16 (Leafs field) | Stats counter; no lock-safe count method |
| (s) NumSubscriptions() | server.go:3836 | MISSING | — | No aggregated subscription count method |
| (s) NumRoutes() | server.go:3773 | PORTED | src/NATS.Server/NatsServer.cs:148 | Dedicated route counter accessor |
| (s) NumRemotes() | server.go:3790 | PORTED | src/NATS.Server/NatsServer.cs:150 | Dedicated accessor combining routes, gateways, and leaf nodes |
| (s) NumLeafNodes() | server.go:3803 | PORTED | src/NATS.Server/NatsServer.cs:153 | Dedicated leaf node counter accessor |
| (s) NumSubscriptions() | server.go:3836 | PORTED | src/NATS.Server/NatsServer.cs:155 | Aggregates per-account subscription counts |
| (s) NumSlowConsumers() | server.go:3855 | PORTED | src/NATS.Server/ServerStats.cs:12 | Direct field access |
| (s) NumSlowConsumersClients() | server.go:3865 | PORTED | src/NATS.Server/ServerStats.cs:18 | — |
| (s) NumSlowConsumersRoutes() | server.go:3870 | PORTED | src/NATS.Server/ServerStats.cs:19 | — |
@@ -157,31 +157,31 @@ Add rows to the Gap Inventory table below. Group by Go source file. Include the
| (s) NumStaleConnectionsLeafs() | server.go:3905 | PORTED | src/NATS.Server/ServerStats.cs:25 | — |
| (s) GetClient() | server.go:3817 | PORTED | src/NATS.Server/NatsServer.cs:119 (GetClients enumerable) | Enumerable, not by-ID lookup |
| (s) GetLeafNode() | server.go:3829 | MISSING | — | No leaf node by-CID lookup |
| (s) ConfigTime() | server.go:3910 | MISSING | — | No config time tracking exposed |
| (s) Addr() | server.go:3917 | PARTIAL | src/NATS.Server/NatsServer.cs:104 (Port) | Port exposed but not full net.Addr |
| (s) MonitorAddr() | server.go:3927 | MISSING | — | Monitoring managed by MonitorServer separately |
| (s) ClusterAddr() | server.go:3937 | PARTIAL | src/NATS.Server/NatsServer.cs:110 (ClusterListen string) | String, not TCPAddr |
| (s) ProfilerAddr() | server.go:3947 | MISSING | — | No profiler address getter |
| (s) ActivePeers() | server.go:1577 | MISSING | — | Cluster peer enumeration not in core |
| (s) NumActiveAccounts() | server.go:1716 | MISSING | — | No active account count method |
| (s) NumLoadedAccounts() | server.go:1744 | PARTIAL | src/NATS.Server/NatsServer.cs:123 (GetAccounts) | Enumerable, no count method |
| (s) ConfigTime() | server.go:3910 | PORTED | src/NATS.Server/NatsServer.cs:157 | Tracks and exposes config load/reload timestamp |
| (s) Addr() | server.go:3917 | PORTED | src/NATS.Server/NatsServer.cs:159 | Dedicated host:port address accessor |
| (s) MonitorAddr() | server.go:3927 | PORTED | src/NATS.Server/NatsServer.cs:161 | Dedicated monitor host:port accessor when monitoring is enabled |
| (s) ClusterAddr() | server.go:3937 | PARTIAL | src/NATS.Server/NatsServer.cs:166 | Dedicated cluster listen accessor exists, but .NET returns string endpoint (not TCPAddr) |
| (s) ProfilerAddr() | server.go:3947 | PORTED | src/NATS.Server/NatsServer.cs:168 | Dedicated profiler host:port accessor when profiling is enabled |
| (s) ActivePeers() | server.go:1577 | PORTED | src/NATS.Server/NatsServer.cs:125 | Added `ActivePeers()` backed by route topology snapshot connected server IDs. |
| (s) NumActiveAccounts() | server.go:1716 | PORTED | src/NATS.Server/NatsServer.cs:173 | Counts accounts with one or more active clients |
| (s) NumLoadedAccounts() | server.go:1744 | PORTED | src/NATS.Server/NatsServer.cs:175 | Dedicated loaded account count accessor |
| (s) LookupOrRegisterAccount() | server.go:1749 | PORTED | src/NATS.Server/NatsServer.cs:1260 (GetOrCreateAccount) | — |
| (s) RegisterAccount() | server.go:1762 | PORTED | src/NATS.Server/NatsServer.cs:1260 | Via GetOrCreateAccount |
| (s) SetSystemAccount() | server.go:1775 | PORTED | src/NATS.Server/NatsServer.cs constructor | Set during construction |
| (s) SystemAccount() | server.go:1798 | PORTED | src/NATS.Server/NatsServer.cs:105 | — |
| (s) GlobalAccount() | server.go:1804 | PORTED | src/NATS.Server/NatsServer.cs:50 (_globalAccount) | — |
| (s) LookupAccount() | server.go:2106 | PORTED | src/NATS.Server/NatsServer.cs:1260 | Via GetOrCreateAccount |
| (s) StartProfiler() | server.go:2941 | MISSING | — | No built-in profiler; .NET uses dotnet-trace/counters |
| (s) StartProfiler() | server.go:2941 | PORTED | src/NATS.Server/NatsServer.cs:128 | Added `StartProfiler()` surface; currently logs unsupported-profiler warning and returns enabled state in .NET runtime model. |
| (s) StartMonitoring() | server.go:3014 | PORTED | src/NATS.Server/Monitoring/MonitorServer.cs | Separate monitoring server class |
| (s) StartHTTPMonitoring() | server.go:3003 | PORTED | src/NATS.Server/Monitoring/MonitorServer.cs:140 | — |
| (s) StartHTTPSMonitoring() | server.go:3009 | PORTED | src/NATS.Server/Monitoring/MonitorServer.cs | HTTPS variant via options |
| (s) HTTPHandler() | server.go:3207 | PARTIAL | src/NATS.Server/Monitoring/MonitorServer.cs | ASP.NET Kestrel handles routing, not an http.Handler |
| (s) InProcessConn() | server.go:2876 | MISSING | — | No in-process connection support |
| (s) LameDuckShutdown() | server.go:4421 | PORTED | src/NATS.Server/NatsServer.cs:239 (LameDuckShutdownAsync) | Full LDM with grace period and duration |
| (s) DisconnectClientByID() | server.go:4742 | MISSING | — | No per-client disconnect by ID |
| (s) LDMClientByID() | server.go:4757 | MISSING | — | No per-client lame duck by ID |
| (s) PortsInfo() | server.go:4247 | MISSING | — | No Ports struct output |
| (s) String() | server.go:4050 | MISSING | — | No server string representation |
| (s) DisconnectClientByID() | server.go:4742 | PORTED | src/NATS.Server/NatsServer.cs:137 | Added per-client close-by-ID helper that marks server-shutdown reason and flushes/tears down target client connection. |
| (s) LDMClientByID() | server.go:4757 | PORTED | src/NATS.Server/NatsServer.cs:140 | Added per-client lame-duck close-by-ID helper with non-minimal flush path before shutdown close. |
| (s) PortsInfo() | server.go:4247 | PORTED | src/NATS.Server/NatsServer.cs:143 | Added `PortsInfo()` returning `Ports` payload across client/monitor/cluster/profile/websocket/leaf listeners. |
| (s) String() | server.go:4050 | PORTED | src/NATS.Server/NatsServer.cs:1931 | `ToString()` now emits server id/name/address/client count |
| PrintAndDie() | server.go:1664 | NOT_APPLICABLE | — | .NET uses exceptions/logging |
| PrintServerAndExit() | server.go:1670 | NOT_APPLICABLE | — | .NET uses --version flag differently |
| ProcessCommandLineArgs() | server.go:1678 | PORTED | src/NATS.Server.Host/Program.cs:25-137 | Inline switch-based CLI parsing |
@@ -196,17 +196,17 @@ Add rows to the Gap Inventory table below. Group by Go source file. Include the
| (s) setInfoHostPort() | server.go:2921 | PORTED | src/NATS.Server/NatsServer.cs:496 (BuildCachedInfo) | — |
| (s) lameDuckMode() | server.go:4428 | PORTED | src/NATS.Server/NatsServer.cs:239 (LameDuckShutdownAsync) | Async version |
| (s) handleSignals() | server.go (signal.go:37) | PORTED | src/NATS.Server/NatsServer.cs:320 (HandleSignals) | Uses PosixSignalRegistration on .NET |
| (s) logPorts() | server.go:4332 | PARTIAL | src/NATS.Server/NatsServer.cs | Logs port at startup; no ports file |
| (s) logPorts() | server.go:4332 | PARTIAL | src/NATS.Server/NatsServer.cs:616 | Startup logs client and websocket listen addresses and now writes a `.ports` file when `PortsFileDir` is configured. Residual gap: Go logs richer multi-listener details via `Ports` payload. |
| (s) startGoRoutine() | server.go:4070 | NOT_APPLICABLE | — | .NET uses Task.Run; no goroutine tracking needed |
| (s) readyForConnections() | server.go:3956 | PORTED | src/NATS.Server/NatsServer.cs:148 (WaitForReadyAsync) | — |
| (s) getOpts() | server.go:1206 | PORTED | src/NATS.Server/NatsServer.cs:33 (_options field) | Direct field access |
| (s) isRunning() | server.go:1700 | PORTED | src/NATS.Server/NatsServer.cs:108 | Inverted IsShuttingDown |
| (s) isShuttingDown() | server.go:2577 | PORTED | src/NATS.Server/NatsServer.cs:108 (IsShuttingDown) | — |
| (s) updateServerINFOAndSendINFOToClients() | server.go:3622 | MISSING | — | No dynamic INFO update broadcast to existing clients |
| (s) getConnectURLs() | server.go:4120 | MISSING | — | No connect URL resolution for clustering |
| (s) getNonLocalIPsIfHostIsIPAny() | server.go:4159 | MISSING | — | IP enumeration for advertise not implemented |
| (s) portFile() | server.go:4307 | MISSING | — | No ports file creation |
| (s) logPid() | server.go:1704 | PARTIAL | src/NATS.Server/NatsServer.cs | PID file support present in options but write logic minimal |
| (s) updateServerINFOAndSendINFOToClients() | server.go:3622 | PORTED | src/NATS.Server/NatsServer.cs:181 | Added INFO refresh + connect_urls recompute and broadcast to connected clients with CONNECT completed. |
| (s) getConnectURLs() | server.go:4120 | PORTED | src/NATS.Server/NatsServer.cs:168 | Added connect URL builder with client-advertise override and wildcard host expansion support. |
| (s) getNonLocalIPsIfHostIsIPAny() | server.go:4159 | PORTED | src/NATS.Server/NatsServer.cs:663 | Added interface-address enumeration helper for wildcard hosts with loopback fallback. |
| (s) portFile() | server.go:4307 | PORTED | src/NATS.Server/NatsServer.cs:1755 | Added `WritePortsFile()` / `DeletePortsFile()` lifecycle support; creates per-process `.ports` file under `PortsFileDir` at startup and removes it on shutdown. |
| (s) logPid() | server.go:1704 | PORTED | src/NATS.Server/NatsServer.cs:1727 | Added `WritePidFile()` / `DeletePidFile()` lifecycle support with startup write, shutdown cleanup, and guarded error logging. |
| validateAndNormalizeCompressionOption() | server.go:466 | MISSING | — | No compression option validation |
| selectCompressionMode() | server.go:559 | MISSING | — | No compression mode negotiation |
| selectS2AutoModeBasedOnRTT() | server.go:618 | MISSING | — | No RTT-based auto compression |
@@ -229,12 +229,12 @@ Add rows to the Gap Inventory table below. Group by Go source file. Include the
| resp struct | client.go:442 | MISSING | — | Dynamic response permission tracking |
| CLIENT/ROUTER/GATEWAY/SYSTEM/LEAF/JETSTREAM/ACCOUNT constants | client.go:44-60 | PORTED | src/NATS.Server/ClientKind.cs:8 | All client kinds present |
| isInternalClient() | client.go:63 | PORTED | src/NATS.Server/ClientKind.cs:20 (IsInternal extension) | — |
| NON_CLIENT/NATS/MQTT/WS constants | client.go:70-79 | PARTIAL | src/NATS.Server/NatsClient.cs:107 (IsWebSocket) | WebSocket bool exists; no explicit MQTT/NATS/NON_CLIENT sub-type enum |
| ClientProtoZero/ClientProtoInfo | client.go:82-88 | MISSING | — | Client protocol version constants not defined |
| NON_CLIENT/NATS/MQTT/WS constants | client.go:70-79 | PORTED | src/NATS.Server/ClientConnectionType.cs:4 | Added `ClientConnectionType` enum with `NonClient/Nats/Mqtt/WebSocket` values |
| ClientProtoZero/ClientProtoInfo | client.go:82-88 | PORTED | src/NATS.Server/ClientConnectionType.cs:15 | Added `ClientProtocolVersion.ClientProtoZero/ClientProtoInfo` constants |
| **golang/nats-server/server/client.go — Exported Methods** | | | | |
| (c) String() | client.go:547 | MISSING | — | No formatted string representation |
| (c) GetNonce() | client.go:557 | PARTIAL | src/NATS.Server/NatsClient.cs:43 (_nonce field) | Field exists but no public getter |
| (c) GetName() | client.go:565 | PARTIAL | src/NATS.Server/NatsClient.cs:58 (ClientOpts?.Name) | Via ClientOpts property |
| (c) String() | client.go:547 | PORTED | src/NATS.Server/NatsClient.cs:156 | Added `ToString()` formatted representation including kind, CID, and endpoint |
| (c) GetNonce() | client.go:557 | PORTED | src/NATS.Server/NatsClient.cs:141 | Added `GetNonce()` accessor returning nonce bytes |
| (c) GetName() | client.go:565 | PORTED | src/NATS.Server/NatsClient.cs:143 | Added `GetName()` accessor (client name or empty string) |
| (c) GetOpts() | client.go:573 | PORTED | src/NATS.Server/NatsClient.cs:58 (ClientOpts) | — |
| (c) GetTLSConnectionState() | client.go:579 | PORTED | src/NATS.Server/NatsClient.cs:110 (TlsState) | TlsConnectionState type |
| (c) RemoteAddress() | client.go:822 | PORTED | src/NATS.Server/NatsClient.cs:85-86 (RemoteIp, RemotePort) | Separate IP and port properties |
@@ -288,7 +288,7 @@ Add rows to the Gap Inventory table below. Group by Go source file. Include the
| (c) applyAccountLimits() | client.go:923 | PARTIAL | src/NATS.Server/NatsClient.cs:488-494 | Account client count check; missing: maxPayload/maxSubs per-account override |
| (c) registerWithAccount() | client.go:854 | PORTED | src/NATS.Server/NatsClient.cs:480-494 | Account binding during connect |
| (c) setTraceLevel() | client.go:695 | PORTED | src/NATS.Server/NatsClient.cs:68 (SetTraceMode) | — |
| (c) clientType() | client.go:599 | PARTIAL | src/NATS.Server/NatsClient.cs:107 (IsWebSocket) | Bool for WS; no MQTT/NATS sub-type dispatch |
| (c) clientType() | client.go:599 | PORTED | src/NATS.Server/NatsClient.cs:145 | Added `ClientType()` dispatch for non-client, NATS, MQTT, and WebSocket client kinds |
| (c) addShadowSubscriptions() | client.go:3057 | MISSING | — | Account import shadow subscription system |
| (c) pruneDenyCache() / prunePubPermsCache() / pruneReplyPerms() | client.go:4007-4019 | MISSING | — | Permission cache pruning |
| (c) trackRemoteReply() / pruneRemoteTracking() | client.go:3915/3956 | MISSING | — | Reply tracking for latency |
@@ -309,24 +309,24 @@ Add rows to the Gap Inventory table below. Group by Go source file. Include the
| MQTTOpts struct | opts.go:613 | PORTED | src/NATS.Server/MqttOptions.cs:8 | — |
| TLSConfigOpts struct | opts.go:790 | PARTIAL | src/NATS.Server/NatsOptions.cs:96-107 | Flat TLS fields on NatsOptions; no TLSConfigOpts class |
| OCSPConfig struct | opts.go:823 | PARTIAL | src/NATS.Server/NatsOptions.cs:110 (OcspConfig) | Basic config; missing: full OCSP mode selection |
| AuthCallout struct | opts.go:308 | MISSING | — | External auth callout configuration |
| JSLimitOpts struct | opts.go:289 | MISSING | — | Per-account JetStream limit options |
| AuthCallout struct | opts.go:308 | PORTED | src/NATS.Server/NatsOptions.cs:234 | Added auth callout DTO (`Issuer`, `Account`, `AuthUsers`, `XKey`, `AllowedAccounts`) |
| JSLimitOpts struct | opts.go:289 | PORTED | src/NATS.Server/NatsOptions.cs:222 | Added JetStream account limit DTO fields used by options parity |
| JSTpmOpts struct | opts.go:300 | NOT_APPLICABLE | — | TPM (Trusted Platform Module) not applicable to .NET |
| ProxiesConfig struct | opts.go:832 | MISSING | — | Proxy configuration |
| ProxiesConfig struct | opts.go:832 | PORTED | src/NATS.Server/NatsOptions.cs:243 | Added proxy configuration DTO (`ProxiesConfig.Trusted` + `ProxyConfig.Key`) |
| PinnedCertSet type | opts.go:59 | PORTED | src/NATS.Server/NatsOptions.cs:106 (TlsPinnedCerts HashSet) | — |
| **golang/nats-server/server/opts.go — Exported Functions** | | | | |
| ProcessConfigFile() | opts.go:870 | PORTED | src/NATS.Server/Configuration/ConfigProcessor.cs:15 | Full config file parsing |
| ConfigureOptions() | opts.go:6023 | PORTED | src/NATS.Server.Host/Program.cs:25-137 | CLI flag parsing inline |
| MergeOptions() | opts.go:5714 | PORTED | src/NATS.Server/Configuration/ConfigReloader.cs MergeCliOverrides | — |
| RoutesFromStr() | opts.go:5797 | MISSING | — | Parse comma-separated route URLs |
| RoutesFromStr() | opts.go:5797 | PORTED | src/NATS.Server/NatsOptions.cs:151 | Added parser for comma-delimited route URL strings with trimming and URI validation |
| GenTLSConfig() | opts.go:5633 | PARTIAL | src/NATS.Server/Tls/ | TLS setup exists but not as a standalone GenTLSConfig function |
| PrintTLSHelpAndDie() | opts.go:4886 | NOT_APPLICABLE | — | Go-specific CLI help |
| NoErrOnUnknownFields() | opts.go:50 | MISSING | — | Config parsing error control |
| NoErrOnUnknownFields() | opts.go:50 | PORTED | src/NATS.Server/NatsOptions.cs:144 | Added global toggle used by config parser to suppress unknown top-level field failures |
| **golang/nats-server/server/opts.go — Exported Options Methods** | | | | |
| (o) Clone() | opts.go:715 | MISSING | — | Deep copy of Options not implemented |
| (o) Clone() | opts.go:715 | PORTED | src/NATS.Server/NatsOptions.cs:166 | Added deep-copy clone behavior for common collections and pinned cert set |
| (o) ProcessConfigFile() | opts.go:974 | PORTED | src/NATS.Server/Configuration/ConfigProcessor.cs:17 | — |
| (o) ProcessConfigString() | opts.go:990 | MISSING | — | Parse config from string |
| (o) ConfigDigest() | opts.go:1000 | MISSING | — | Config file digest |
| (o) ProcessConfigString() | opts.go:990 | PORTED | src/NATS.Server/NatsOptions.cs:196 | Added in-memory config parse/apply path and digest computation |
| (o) ConfigDigest() | opts.go:1000 | PORTED | src/NATS.Server/NatsOptions.cs:203 | Added SHA-256-based config digest accessor |
| **golang/nats-server/server/reload.go** | | | | |
| FlagSnapshot var | reload.go:36 | PORTED | src/NATS.Server/NatsServer.cs:44-46 (_cliSnapshot, _cliFlags) | — |
| option interface | reload.go:43 | PORTED | src/NATS.Server/Configuration/IConfigChange.cs | IConfigChange with Apply, IsLoggingChange, etc. |
@@ -350,9 +350,9 @@ Add rows to the Gap Inventory table below. Group by Go source file. Include the
| Status | Count |
|--------|-------|
| PORTED | 123 |
| PARTIAL | 30 |
| MISSING | 55 |
| PORTED | 165 |
| PARTIAL | 19 |
| MISSING | 24 |
| NOT_APPLICABLE | 14 |
| DEFERRED | 0 |
| **Total** | **222** |
@@ -382,5 +382,9 @@ After porting work is completed:
| Date | Change | By |
|------|--------|----|
| 2026-02-26 | Executed core-server batch 4 parity closures: added `ActivePeers`, `StartProfiler`, `DisconnectClientByID`, `LDMClientByID`, `PortsInfo`, `UpdateServerINFOAndSendINFOToClients`, `GetConnectURLs`, and `GetNonLocalIPsIfHostIsIPAny` with targeted tests in `CoreServerGapParityTests`. | codex |
| 2026-02-26 | Reclassified core server PID/ports-file parity rows: validated existing startup/shutdown PID and `.ports` file lifecycle implementation and updated `logPid`/`portFile` status to PORTED; refreshed `logPorts` residual note. | codex |
| 2026-02-25 | File created with LLM analysis instructions | auto |
| 2026-02-25 | Gap inventory populated: 222 symbols analyzed (123 PORTED, 30 PARTIAL, 55 MISSING, 14 NOT_APPLICABLE) across server.go, client.go, opts.go, reload.go, signal.go, service.go, main.go | claude-opus |
| 2026-02-25 | Executed core-server batch 1 parity closures: added dedicated server URL/address/account-count/config-time/string helpers with targeted unit tests (`CoreServerGapParityTests`), and reclassified 14 rows (9 MISSING + 5 PARTIAL) to PORTED | codex |
| 2026-02-25 | Executed core-server batch 3 options parity closures: added `Ports`, `CompressionModes`, `CompressionOpts`, `RoutesFromStr`, `NoErrOnUnknownFields`, `Clone`, `ProcessConfigString`, `ConfigDigest`, and DTOs (`JSLimitOpts`, `AuthCallout`, `ProxiesConfig`) with targeted tests (`CoreServerOptionsParityBatch3Tests`) | codex |