|
| 1 | +--- |
| 2 | +name: wiremock-test |
| 3 | +description: Manage WireMock proxy for RPC testing. Starts the proxy, arms scenarios to simulate transient errors (timeouts, 500s, connection resets, and network-specific errors like Stellar TRY_AGAIN_LATER), and checks metrics. Use to verify relayer behavior under failure conditions. |
| 4 | +allowed-tools: Bash, Read, Grep, Glob, Agent |
| 5 | +argument-hint: "<scenario> | setup <network> [rpc-url] | teardown | status | check-metrics" |
| 6 | +--- |
| 7 | + |
| 8 | +# WireMock RPC Test Proxy |
| 9 | + |
| 10 | +You manage a WireMock proxy that sits between the relayer and an RPC endpoint. It forwards traffic normally, but can inject mock error responses on demand. |
| 11 | + |
| 12 | +## Project paths |
| 13 | + |
| 14 | +- Docker compose: `testing/wiremock/docker-compose.yaml` |
| 15 | +- Generic mappings: `testing/wiremock/mappings/generic/` (work with any JSON-RPC network) |
| 16 | +- Stellar mappings: `testing/wiremock/mappings/stellar/` |
| 17 | +- Future EVM mappings: `testing/wiremock/mappings/evm/` (not yet created) |
| 18 | +- Helper scripts: `testing/wiremock/scripts/` |
| 19 | + |
| 20 | +## Available scenarios |
| 21 | + |
| 22 | +### Generic (any network) |
| 23 | + |
| 24 | +| Scenario name | Shorthand | What it does | |
| 25 | +|---|---|---| |
| 26 | +| `rpc-timeout` | `timeout` | 30s delay on next RPC call (any method) | |
| 27 | +| `rpc-500` | `500` | HTTP 500 on next RPC call | |
| 28 | +| `rpc-connection-reset` | `reset` | TCP connection reset on next RPC call | |
| 29 | + |
| 30 | +### Stellar-specific |
| 31 | + |
| 32 | +| Scenario name | Shorthand | What it does | |
| 33 | +|---|---|---| |
| 34 | +| `stellar-try-again-later` | `tal`, `try-again-later` | Returns `TRY_AGAIN_LATER` on next `sendTransaction` | |
| 35 | +| `stellar-insufficient-fee` | `fee`, `insufficient-fee` | Returns `ERROR` with `TxInsufficientFee` on next `sendTransaction` | |
| 36 | +| `stellar-get-transaction-not-found` | `not-found`, `get-tx-not-found` | Returns `NOT_FOUND` for next `getTransaction` | |
| 37 | + |
| 38 | +All scenarios fire **exactly once** then revert to proxying real traffic. |
| 39 | + |
| 40 | +## How to handle user arguments ($ARGUMENTS) |
| 41 | + |
| 42 | +Based on the argument, execute the matching flow: |
| 43 | + |
| 44 | +### `setup` — requires a network argument |
| 45 | +**Syntax:** `setup <network> [rpc-url]` |
| 46 | + |
| 47 | +A bare `setup` with no network is **not allowed** — ask the user which network they want (stellar or evm). |
| 48 | + |
| 49 | +1. Determine target RPC: |
| 50 | + - `setup stellar` → default: `https://soroban-testnet.stellar.org` |
| 51 | + - `setup evm` or `setup anvil` → default: `http://host.docker.internal:8545` |
| 52 | + - `setup stellar <url>` or `setup evm <url>` → use the provided URL as `WIREMOCK_PROXY_TARGET` |
| 53 | +2. Start WireMock: |
| 54 | + ```bash |
| 55 | + WIREMOCK_PROXY_TARGET=<target> docker compose -f testing/wiremock/docker-compose.yaml up -d |
| 56 | + ``` |
| 57 | + For stellar with default target, just: `docker compose -f testing/wiremock/docker-compose.yaml up -d` |
| 58 | +3. Wait for health: poll `curl -sf http://localhost:9090/__admin/health` (retry up to 10 times with 2s sleep) |
| 59 | +4. Verify scenarios loaded: `curl -s http://localhost:9090/__admin/scenarios` |
| 60 | +5. Remind the user: |
| 61 | + - WireMock proxy is running on `http://localhost:9090` proxying to `<target>` |
| 62 | + - To use it, update the relevant network config `rpc_urls` to `["http://localhost:9090"]` |
| 63 | + - If the relayer runs in Docker, use `http://host.docker.internal:9090` instead |
| 64 | + - Show only the **relevant** scenarios: generic + the chosen network's specific scenarios |
| 65 | + - For Stellar: mention updating `config/networks/stellar.json` testnet entry |
| 66 | + - For EVM: mention updating the relevant EVM network config |
| 67 | + |
| 68 | +### `teardown` or `stop` |
| 69 | +1. Run: `docker compose -f testing/wiremock/docker-compose.yaml down` |
| 70 | +2. Confirm stopped |
| 71 | + |
| 72 | +### `status` |
| 73 | +1. Check if WireMock is running: `docker compose -f testing/wiremock/docker-compose.yaml ps` |
| 74 | +2. If running, show scenario states: `curl -s http://localhost:9090/__admin/scenarios` |
| 75 | +3. Show recent requests: `curl -s 'http://localhost:9090/__admin/requests?limit=10'` |
| 76 | +4. Parse and display in a readable format |
| 77 | + |
| 78 | +### `check-metrics` or `metrics` |
| 79 | +1. Fetch relayer metrics: `curl -s http://localhost:8081/debug/metrics/scrape` |
| 80 | +2. Filter and display lines matching: `insufficient_fee|try_again_later|transactions_success|transactions_failed|stellar_submission_failures|stellar_try_again_later|rpc_call_latency|api_rpc_failures` |
| 81 | +3. Summarize what the metrics show |
| 82 | + |
| 83 | +### A scenario name or shorthand |
| 84 | +1. First ensure WireMock is running (check health endpoint, start if needed) |
| 85 | +2. Resolve the scenario name — the user may use shorthand: |
| 86 | + - Generic: `timeout` → `rpc-timeout`, `500` → `rpc-500`, `reset` → `rpc-connection-reset` |
| 87 | + - Stellar: `try-again-later` or `tal` → `stellar-try-again-later`, `insufficient-fee` or `fee` → `stellar-insufficient-fee`, `not-found` or `get-tx-not-found` → `stellar-get-transaction-not-found` |
| 88 | +3. Arm the scenario: |
| 89 | + ```bash |
| 90 | + curl -s -X PUT "http://localhost:9090/__admin/scenarios/{scenario-name}/state" \ |
| 91 | + -H 'Content-Type: application/json' -d '{"state": "armed"}' |
| 92 | + ``` |
| 93 | +4. Verify it's armed by checking the scenario state |
| 94 | +5. Tell the user what will happen on the next matching RPC call |
| 95 | + |
| 96 | +### `chaos` or `all-chaos` |
| 97 | +1. Ensure WireMock is running |
| 98 | +2. Arm ALL scenarios simultaneously |
| 99 | +3. Explain what will happen: scenarios are priority-based, so the most specific one fires first |
| 100 | + |
| 101 | +### `reset` |
| 102 | +1. Reset all scenarios: `curl -s -X POST http://localhost:9090/__admin/scenarios/reset` |
| 103 | +2. Clear request log: `curl -s -X DELETE http://localhost:9090/__admin/requests` |
| 104 | +3. Confirm all scenarios are back to initial (inactive) state |
| 105 | + |
| 106 | +## Important reminders |
| 107 | + |
| 108 | +Always remind the user about these when relevant: |
| 109 | +- The relayer's network `rpc_urls` must point to `http://localhost:9090` (or `http://host.docker.internal:9090` from Docker) for WireMock to intercept traffic |
| 110 | +- After testing, they should revert `rpc_urls` back to the real RPC endpoint |
| 111 | +- Scenarios are one-shot: they fire once and revert. Re-arm to test again. |
| 112 | +- The relayer's metrics endpoint is at `http://localhost:8081/debug/metrics/scrape` (configurable via METRICS_PORT) |
| 113 | +- Generic scenarios (timeout, 500, connection-reset) work with any network — no need to change them when switching between Stellar and EVM testing |
| 114 | + |
| 115 | +## Adding new network support |
| 116 | + |
| 117 | +When adding EVM or other network-specific scenarios: |
| 118 | +1. Create `testing/wiremock/mappings/<network>/` directory |
| 119 | +2. Add scenario JSON files following the existing pattern (use `"requiredScenarioState": "armed"`) |
| 120 | +3. Mount the directory in `docker-compose.yaml` (uncomment or add the volume line) |
| 121 | +4. Update this skill's scenario tables above |
| 122 | +5. Restart WireMock to load new mappings |
0 commit comments