# 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 per [.NET Coding Standards](../../standards/dotnet-standards.md) (xUnit 3 / Shouldly / NSubstitute)
- 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

## Milestone Tracking

This phase corresponds to **Milestone 7** in [Gitea](https://gitea.dohertylan.com/dohertj2/natsnet/milestone/7). When starting this phase, verify the milestone is open. Assign relevant issues to this milestone as work progresses.

### Issue Updates

Each completion criterion has a corresponding Gitea issue. Update issues as you work:

- **Starting a criterion**: Add a comment noting work has begun
- **Blocked**: Add a comment describing the blocker
- **Complete**: Close the issue with a comment summarizing the result (e.g., counts, verification output)

Close issues via CLI:
```bash
curl -s -X PATCH "https://gitea.dohertylan.com/api/v1/repos/dohertj2/natsnet/issues/{N}" \
  -H "Content-Type: application/json" \
  -H "Authorization: token $GITEA_TOKEN" \
  -d '{"state":"closed"}'
```
Or close via the Gitea web UI.

## 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

- [ ] [#45](https://gitea.dohertylan.com/dohertj2/natsnet/issues/45) All non-N/A modules have status `verified`
- [ ] [#46](https://gitea.dohertylan.com/dohertj2/natsnet/issues/46) All non-N/A features have status `verified`
- [ ] [#47](https://gitea.dohertylan.com/dohertj2/natsnet/issues/47) All non-N/A tests have status `verified`
- [ ] [#48](https://gitea.dohertylan.com/dohertj2/natsnet/issues/48) All targeted tests pass: `dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.Tests/`
- [ ] [#49](https://gitea.dohertylan.com/dohertj2/natsnet/issues/49) All integration tests pass: `dotnet test dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/`
- [ ] [#50](https://gitea.dohertylan.com/dohertj2/natsnet/issues/50) Key behavioral scenarios produce equivalent results on Go and .NET servers
- [ ] [#51](https://gitea.dohertylan.com/dohertj2/natsnet/issues/51) `phase check 7` passes with no errors
- [ ] [#52](https://gitea.dohertylan.com/dohertj2/natsnet/issues/52) Final report exported and reviewed
- [ ] Close the Phase 7 milestone in Gitea:
  ```bash
  curl -s -X PATCH "https://gitea.dohertylan.com/api/v1/repos/dohertj2/natsnet/milestones/7" \
    -H "Content-Type: application/json" \
    -H "Authorization: token $GITEA_TOKEN" \
    -d '{"state":"closed"}'
  ```
  Or close it via the Gitea web UI at https://gitea.dohertylan.com/dohertj2/natsnet/milestone/7
- [ ] Close the **Final: Porting Complete** milestone in Gitea:
  ```bash
  curl -s -X PATCH "https://gitea.dohertylan.com/api/v1/repos/dohertj2/natsnet/milestones/8" \
    -H "Content-Type: application/json" \
    -H "Authorization: token $GITEA_TOKEN" \
    -d '{"state":"closed"}'
  ```
  Or close it via the Gitea web UI at https://gitea.dohertylan.com/dohertj2/natsnet/milestone/8

## 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
