# Phase 7: Porting Verification Verify all ported code through targeted testing per module. This phase does NOT run the full test suite as a single pass -- it systematically verifies each module, marks items as verified, and confirms behavioral equivalence with the Go server. ## Objective Every ported module passes its targeted tests. Every item in the database reaches `verified` or `n_a` status. Cross-module integration tests pass. Key behavioral scenarios produce equivalent results between the Go and .NET servers. ## Prerequisites - Phase 6 complete: all non-N/A items at `complete` or better - All tests ported and compilable - Verify readiness: `dotnet run --project tools/NatsNet.PortTracker -- phase check 6 --db porting.db` ## Source and Target Locations - **Go source code** is located in the `golang/` folder (specifically `golang/nats-server/`) - **.NET ported version** is located in the `dotnet/` folder ## Verification Workflow Work through modules one at a time. Do not move to the next module until the current one is fully verified. ### Step 1: List modules to verify ```bash # Show all modules — look for status 'complete' (not yet verified) dotnet run --project tools/NatsNet.PortTracker -- module list --db porting.db ``` Start with leaf modules (those with the fewest dependencies) and work upward, same order as the porting phase. ### Step 2: List tests for the module For each module, identify all mapped tests: ```bash dotnet run --project tools/NatsNet.PortTracker -- test list --module --db porting.db ``` This shows every test associated with the module, its status, and its .NET method name. ### Step 3: Run targeted tests Run only the tests for this module using `dotnet test --filter`: ```bash # Filter by namespace (matches all tests in the module's namespace) dotnet test --filter "FullyQualifiedName~ZB.MOM.NatsNet.Server.Tests.Protocol" \ dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ # Filter by test class dotnet test --filter "FullyQualifiedName~ZB.MOM.NatsNet.Server.Tests.Protocol.NatsParserTests" \ dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ # Filter by specific test method dotnet test --filter "FullyQualifiedName~ZB.MOM.NatsNet.Server.Tests.Protocol.NatsParserTests.TryParse_ValidInput_ReturnsTrue" \ dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ ``` The `--filter` flag uses partial matching on the fully qualified test name. Use the namespace pattern for module-wide runs, and the class or method pattern for debugging specific failures. ### Step 4: Handle failures When tests fail: 1. **Read the failure output.** The test runner prints the assertion that failed, the expected vs actual values, and the stack trace. 2. **Locate the Go reference.** Look up the test in the database to find the original Go test and source: ```bash dotnet run --project tools/NatsNet.PortTracker -- test show --db porting.db ``` 3. **Compare Go and .NET logic.** Open the Go source at the stored line number. Check for translation errors: off-by-one, missing edge cases, different default values. 4. **Fix and re-run.** After fixing, re-run only the failing test: ```bash dotnet test --filter "FullyQualifiedName~ZB.MOM.NatsNet.Server.Tests.Protocol.NatsParserTests.TryParse_EmptyInput_ReturnsFalse" \ dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ ``` 5. **Then re-run the full module.** Confirm no regressions: ```bash dotnet test --filter "FullyQualifiedName~ZB.MOM.NatsNet.Server.Tests.Protocol" \ dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ ``` Common failure causes: | Symptom | Likely cause | |---------|-------------| | Off-by-one in buffer parsing | Go slices are half-open `[start:end)`, C# spans match but array indexing might differ | | Timeout in async test | Missing `CancellationToken`, or `Task` not awaited | | Wrong byte sequence | Go uses `[]byte("string")` which is UTF-8; ensure C# uses `Encoding.UTF8` | | Nil vs null behavior | Go nil checks behave differently from C# null; check for `default` values | | Map iteration order | Go maps iterate in random order; if the test depends on order, sort first | ### Step 5: Mark module as verified Once all tests pass for a module: ```bash # Mark the module itself as verified dotnet run --project tools/NatsNet.PortTracker -- module update --status verified --db porting.db # Mark all features in the module as verified dotnet run --project tools/NatsNet.PortTracker -- feature update 0 --status verified \ --all-in-module --db porting.db # Mark individual tests as verified dotnet run --project tools/NatsNet.PortTracker -- test update --status verified --db porting.db ``` ### Step 6: Move to next module Repeat Steps 2-5 for each module. Track progress: ```bash dotnet run --project tools/NatsNet.PortTracker -- report summary --db porting.db ``` ## Integration Testing After all modules are individually verified, run integration tests that exercise cross-module behavior. ### Step 7: Run integration tests ```bash dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/ ``` Integration tests cover scenarios like: - Client connects, subscribes, receives published messages - Multiple clients with wildcard subscriptions - Connection lifecycle (connect, disconnect, reconnect) - Protocol error handling (malformed commands, oversized payloads) - Configuration loading and server startup Fix any failures by tracing through the modules involved and checking the interaction boundaries. ### Step 8: Behavioral comparison Run both the Go server and the .NET server with the same workload and compare behavior. This catches semantic differences that unit tests might miss. **Setup:** 1. Start the Go server: ```bash cd golang/nats-server && go run . -p 4222 ``` 2. Start the .NET server: ```bash dotnet run --project dotnet/src/ZB.MOM.NatsNet.Server.Host -- --port 4223 ``` **Comparison scenarios:** | Scenario | What to compare | |----------|----------------| | Basic pub/sub | Publish a message, verify subscriber receives identical payload | | Wildcard matching | Subscribe with `foo.*` and `foo.>`, publish to `foo.bar`, verify same match results | | Queue groups | Multiple subscribers in a queue group, verify round-robin distribution | | Protocol errors | Send malformed commands, verify same error responses | | Connection info | Connect and check `INFO` response fields | | Graceful shutdown | Send SIGTERM, verify clean disconnection | Use the `nats` CLI tool to drive traffic: ```bash # Subscribe on Go server nats sub -s nats://localhost:4222 "test.>" # Subscribe on .NET server nats sub -s nats://localhost:4223 "test.>" # Publish to both and compare nats pub -s nats://localhost:4222 test.hello "payload" nats pub -s nats://localhost:4223 test.hello "payload" ``` Document any behavioral differences. Some differences are expected (e.g., server name, version string) while others indicate bugs. ### Step 9: Final verification Run the complete check: ```bash # Phase 7 check — all tests verified dotnet run --project tools/NatsNet.PortTracker -- phase check 7 --db porting.db # Final summary — all items should be verified or n_a dotnet run --project tools/NatsNet.PortTracker -- report summary --db porting.db # Export final report dotnet run --project tools/NatsNet.PortTracker -- report export \ --format md \ --output porting-final-report.md \ --db porting.db ``` ## Troubleshooting ### Test passes individually but fails in module run Likely a test ordering dependency or shared state. Check for: - Static mutable state not reset between tests - Port conflicts if tests start servers - File system artifacts from previous test runs Fix by adding proper test cleanup (`IDisposable`, `IAsyncLifetime`) and using unique ports/paths per test. ### Module passes but integration test fails The issue is at a module boundary. Check: - Interface implementations match expectations - Serialization/deserialization is consistent across modules - Thread safety at module interaction points - Async patterns are correct (no fire-and-forget `Task` without error handling) ### Behavioral difference with Go server 1. Identify the specific protocol message or state that differs 2. Trace through both implementations step by step 3. Check the NATS protocol specification for the correct behavior 4. Fix the .NET implementation to match (the Go server is the reference) ## Completion Criteria - All non-N/A modules have status `verified` - All non-N/A features have status `verified` - All non-N/A tests have status `verified` - All targeted tests pass: `dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/` - All integration tests pass: `dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/` - Key behavioral scenarios produce equivalent results on Go and .NET servers - `phase check 7` passes with no errors - Final report exported and reviewed ## Related Documentation - [Phase 6: Porting](phase-6-porting.md) -- the implementation phase this verifies - [Phase 4: .NET Solution Design](phase-4-dotnet-design.md) -- the original design mappings