MEMO-038: Proxy Integration Testing Strategy
Context
PR #29 introduced transparent proxying for KeyValue operations (prism-proxy → keyvalue-runner → memstore). Initial unit tests failed because they expected the proxy to work without a backend connection. We needed both proper unit tests and true integration tests.
Problem
- Unit tests were testing the wrong thing - expecting success when backend unavailable
- No integration tests to verify end-to-end transparent proxying works
- E2E tests require manual setup (
prismctl local start) - not suitable for CI
Solution
1. Fixed Unit Tests
Updated tests in prism-proxy/src/server/keyvalue.rs to verify correct error handling:
// Unit tests now expect Unavailable status when backend not connected
let response = service.set(request).await;
assert!(response.is_err(), "Set request should fail without backend");
let err = response.unwrap_err();
assert_eq!(err.code(), tonic::Code::Unavailable);
assert!(err.message().contains("not connected"));
Result: All 17 unit tests pass ✅
2. Created Integration Test Runner
New binary: proxy-integration-runner (prism-proxy/src/bin/proxy_integration_runner.rs)
What it does:
- Builds prism-proxy and keyvalue-runner binaries
- Spawns keyvalue-runner with memstore on port 9095
- Spawns prism-proxy on port 9090 (connects to keyvalue-runner)
- Runs 6 gRPC client tests against prism-proxy
- Auto-cleanup on completion/failure
Test coverage:
- Set → Get → Verify value matches
- Exists check
- Delete → Verify deleted
- Non-existent key handling
Architecture:
Test Client → prism-proxy:9090 → keyvalue-runner:9095 → memstore
3. Usage
# From project root
./prism-proxy/target/debug/proxy-integration-runner
# Or build first
cd prism-proxy && cargo build --bin proxy-integration-runner
Output:
✅ All integration tests passed!
Test 1: Set key - ✅ Set operation succeeded
Test 2: Get key - ✅ Get operation succeeded, value matches
Test 3: Check key exists - ✅ Exists operation succeeded
Test 4: Delete key - ✅ Delete operation succeeded
Test 5: Verify key deleted - ✅ Key no longer exists
Test 6: Get non-existent key - ✅ Non-existent key returns not found
Testing Pyramid
E2E Tests (manual) → tests/e2e/transparent_proxy_test.go
│ (requires `prismctl local start`)
│
Integration Tests → proxy-integration-runner
│ (spawns real processes, automated)
│
Unit Tests → cargo test --lib
(mocked/no backend, fast)
CI Integration
Add to GitHub Actions:
- name: Run Proxy Integration Tests
run: |
cd prism-proxy
cargo build --bin prism-proxy --bin proxy-integration-runner
cd ..
./prism-proxy/target/debug/proxy-integration-runner
Key Insights
- Unit tests test component behavior (error handling, logic)
- Integration tests test component interaction (proxy → runner → backend)
- E2E tests test full system (launcher, admin, proxy, runners)
- Use real processes for integration tests, not mocks (catches protocol/connection issues)
- Auto-cleanup via Drop trait ensures ports don't stay occupied
Files Changed
prism-proxy/src/server/keyvalue.rs- Fixed unit testsprism-proxy/src/bin/proxy_integration_runner.rs- New integration runner (320 lines)prism-proxy/Cargo.toml- Added binary target
Results
- ✅ All unit tests pass (17/17)
- ✅ All integration tests pass (6/6)
- ✅ PR #29 CI passes
- ✅ Verifies transparent proxying works end-to-end
Related
- PR #29: Transparent proxy of KeyValueTTL and launcher callback integration
- RFC-035: Pattern Process Launcher
- MEMO-037: Launcher Callback Protocol