- Update all 7 phase docs with source/target location references (golang/ for Go source, dotnet/ for .NET version) - Rename NATS.Server to ZB.MOM.NatsNet.Server in phase 4-7 docs - Update solution layout to dotnet/src/ and dotnet/tests/ structure - Create CLAUDE.md with project summary and phase links - Update .gitignore: track porting.db, add standard .NET patterns - Add golang/nats-server as git submodule - Add reports/generate-report.sh and pre-commit hook - Add documentation_rules.md to version control
239 lines
8.9 KiB
Markdown
239 lines
8.9 KiB
Markdown
# 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 <module_id> --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 <test_id> --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 <module_id> --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 <module_id> --db porting.db
|
|
|
|
# Mark individual tests as verified
|
|
dotnet run --project tools/NatsNet.PortTracker -- test update <test_id> --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
|