# p4bridge-unit-test/ — C++ bridge test harness

Scoped instructions for the native bridge test suite. Loads when you read/edit files under `p4api.net/p4bridge-unit-test/`.

Bridge architecture: `../p4bridge/CLAUDE.md`. Project overview: root `CLAUDE.md`. .NET test harness: `../p4api.net-unit-test/CLAUDE.md`.

## What this is

A custom C++ test harness (`BridgeUnit` binary) that links against the same `libp4bridge` produced by the bridge build, then drives it through the C ABI directly — **bypassing the managed layer**. Catches issues the .NET tests can't:
- Export ABI breakage (a removed/renamed export silently breaks `[DllImport]`)
- Native-side memory leaks
- p4api C++ version skew at the native layer
- Threading and connection-lifecycle bugs in the bridge itself

## Layout

| File | Role |
|---|---|
| `UnitTestFrameWork.{cpp,h}` | Assertion macros, test registration, runner |
| `UnitTestConfig.h` | Compile-time config (paths, server port) |
| `TestSuiteTest.{cpp,h}` | Top-level suite orchestration |
| `TestP4Base.{cpp,h}` | Base class for tests that need a p4d connection |
| `TestP4BridgeServer.{cpp,h}` | Server-side bridge tests (connections, sessions) |
| `TestP4BridgeServerLogging.{cpp,h}` | Logging-callback tests |
| `TestP4BridgeServerUtf8.{cpp,h}` | UTF-8 path / encoding tests |
| `TestP4BridgeClient.{cpp,h}` | Client-side (callback) tests |
| `TestUtils.{cpp,h}`, `TextEncoder.{cpp,h}` | Helpers, encoding |
| `a.tar`, `u.tar` | p4d checkpoint archives — test fixtures |
| `CMakeLists.txt`, `CMakePresets.json` | Build config (eight presets, mirrors `../p4bridge/`) |

## Fixture data

`a.tar` and `u.tar` are p4d **checkpoint archives** that get untarred at runtime. Tests like `TestGetConfig`, `TestConnectSetClient`, and other p4d-dependent cases use them to seed a local server. They must sit **next to the built binary**:

```
cp a.tar u.tar out/linux-Release/
```

Don't relocate these files without updating the test setup logic.

## Build & run

```
cd p4bridge-unit-test
cmake --preset=linux-Release            # or osx-Release / x64-Release / x86-Release
cmake --build out/linux-Release
cp a.tar u.tar out/linux-Release/
cd out/linux-Release
./BridgeUnit -s ../..                   # -s = unit-test source root
```

The harness reports per-test timings and exits non-zero on failure. Output is plain stdout; redirect to a file if you want to capture (`./BridgeUnit -s ../.. | tee BridgeUnit.log`).

## Patterns

- **`TestP4Base` for p4d-dependent tests** — derive from this when your test needs a live local server (uses the checkpoint archives).
- **`UnitTestFrameWork` for ABI-only tests** — use this for tests that exercise the bridge's C ABI without needing p4d.
- **Smoke tests cheap, p4d-dependent tests expensive** — the harness reports timings. Flag any new test that adds substantial wall-time without justification.
- **One test, one purpose** — the harness reports each `TEST(...)` invocation separately. Don't pack multiple assertions for unrelated behaviors into a single test.

## When to add a test here vs. in `../p4api.net-unit-test/`

| Change touches… | Add a test in… |
|---|---|
| Only managed code (no PInvoke surface change) | `p4api.net-unit-test/<Type>Test.cs` |
| `p4bridge-api.cpp` (new or modified export) | **Both** — managed proves callability, native proves correctness without the managed wrapper |
| `P4BridgeServer.cpp`, `P4BridgeClient.cpp`, `P4Connection.cpp` | `p4bridge-unit-test/` (the bridge internals; managed tests can't reach these directly) |
| `CMakeLists.txt` / `CMakePresets.json` for the bridge | Re-run the harness on the affected presets to confirm the binary still links & runs |

## CMake preset must match the bridge

Build the harness with the **same** preset you used for `../p4bridge/` — they share the build output layout. Mixing presets produces a linker error or, worse, ABI skew (Release-built bridge + Debug-built harness can crash on STL container layout differences).
