You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
3. tops up paymaster deposits (1000 ETH per EntryPoint)
53
+
per test:
54
+
4. clears alto mempool + resets base fee
55
+
5. awaits the test body with { rpc: { anvilRpc, altoRpc, paymasterRpc } }
56
+
worker exit:
57
+
6. stops all 3 instances (Promise.all)
54
58
```
55
59
56
60
Fixture mechanics are detailed in [02-lifecycle.md](./02-lifecycle.md); process details in [03-infrastructure.md](./03-infrastructure.md).
@@ -99,31 +103,32 @@ Field-by-field:
99
103
|`coverage.reporter`|`CI ? ["lcov"] : ["text","json","html"]`| Local dev gets HTML + text output; CI produces only lcov (Codecov-friendly). |
100
104
|`coverage.include`|`["**/permissionless/**"]`| Measures coverage of the published package only. |
101
105
|`coverage.exclude`| test files, generated `_cjs`/`_esm`/`_types`, test infra | Keeps coverage numbers honest. |
102
-
|`sequence.concurrent`|`false`| Tests inside one file run **sequentially**. Multiple parallel Anvil stacks from one file would risk port exhaustion and noisy logs. |
103
-
|`fileParallelism`|`true`| Separate `.test.ts` files DO run in parallel (in separate workers). |
106
+
|`sequence.concurrent`|`false`| Tests inside one file run **sequentially**. This is essential for the shared-rig model: tests in a worker share the same anvil/alto/paymaster trio and clear state between runs. |
107
+
|`fileParallelism`|`true`| Separate `.test.ts` files DO run in parallel (in separate workers). Each worker gets its own shared rig.|
104
108
|`environment`|`"node"`| No jsdom; tests run in raw Node. |
105
109
|`testTimeout`|`60_000` (60s) | User operations + bundling + receipts are slow; 60s is the per-test cap. |
106
-
|`hookTimeout`|`45_000` (45s) | The `testWithRpc` fixture setup (anvil + contracts + alto + paymaster) can take tens of seconds cold.|
110
+
|`hookTimeout`|`45_000` (45s) | The `testWithRpc` fixture setup (on first test: anvil + contracts + alto + paymaster) can take tens of seconds cold. |
107
111
|`include`|`join(__dirname, "./**/*.test.ts")`| Discovery is rooted at `packages/permissionless/` — not the repo root. Tests elsewhere (e.g. `packages/mock-paymaster/`) are **not** picked up. |
108
112
|`env`|`loadEnv("test", process.cwd())`| Reads `.env.test`, `.env.test.local`, `.env`, `.env.local` from the CWD and exposes `VITE_*` vars to tests. |
109
113
110
114
### Parallelism model
111
115
112
-
-**File-level:** parallel. Each `.test.ts` file runs in its own worker, which means each has its own module-level state (including the `ports: number[]` tracker in `testWithRpc.ts:80`). Workers do not share a port list, but `get-port` asks the OS for a free port, so real collisions are rare.
113
-
-**Test-level (inside a file):** serial. Each `testWithRpc(...)` inside a file waits for the previous one to tear down before the next starts. That means **within one file, there is never more than one Anvil/Alto/paymaster trio alive at once**.
116
+
-**File-level:** parallel. Each `.test.ts` file runs in its own worker, which means each has its own shared rig (anvil + alto + paymaster trio). Workers do not share processes or ports.
117
+
-**Test-level (inside a file):** serial. Each `testWithRpc(...)` inside a file waits for the previous one to complete before the next starts. This is critical because tests share the same anvil/alto/paymaster trio within a worker.
114
118
115
119
Combined: at any instant, concurrency ≈ number of `.test.ts` files currently in flight. With Vitest's default worker count (≈ CPU cores), you typically have 4–8 parallel stacks.
116
120
117
121
### Why `hookTimeout` is 45s
118
122
119
-
`testWithRpc`setup does, in order:
123
+
The first `testWithRpc`call in a worker triggers `getSharedRig()`, which does:
120
124
1. Allocate 3 free ports (ms).
121
125
2. Start Anvil (~1–3s cold).
122
126
3. Call `setupContracts(anvilRpc)` which issues **~80+ transactions** to the deterministic deployer and a few impersonation + `setCode` calls. With all txns batched via `Promise.all`, this typically lands in 2–8s but can spike.
4. Start Alto with debug endpoints enabled (subprocess, waits for `"Server listening at"` message; ~2–5s).
124
128
5. Start the paymaster (Fastify boot; ~1s).
129
+
6. Top up paymaster deposits (~1s).
125
130
126
-
On a slow machine or noisy CI runner, cumulative setup > 30s is possible; 45s is the margin.
131
+
On a slow machine or noisy CI runner, cumulative setup > 30s is possible; 45s is the margin. Subsequent tests in the same worker skip this setup entirely (the rig is already running), so only the first test pays the cold-start cost.
127
132
128
133
## File layout
129
134
@@ -152,7 +157,7 @@ Non-exhaustive — see `packages/permissionless/**/*.test.ts` for the full set.
| Change how tests are discovered / timed out |`packages/permissionless/vitest.config.ts`|
174
-
| Change the per-test setup/teardown |`packages/permissionless-test/src/testWithRpc.ts`|
179
+
| Change the per-worker setup or per-test reset|`packages/permissionless-test/src/testWithRpc.ts`|
175
180
| Add a new viem client helper |`packages/permissionless-test/src/utils.ts`|
176
181
| Add a new smart account type |`packages/permissionless-test/src/utils.ts` + `mock-aa-infra/alto/constants/accounts/` + `mock-aa-infra/alto/index.ts`|
177
182
| Change how the bundler is started |`packages/permissionless-test/mock-aa-infra/alto/instance.ts`|
0 commit comments