@aztec/end-to-end 0.0.1-commit.1142ef1 → 0.0.1-commit.18ccd8f0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (159) hide show
  1. package/dest/bench/client_flows/benchmark.d.ts +3 -2
  2. package/dest/bench/client_flows/benchmark.d.ts.map +1 -1
  3. package/dest/bench/client_flows/benchmark.js +21 -1
  4. package/dest/bench/client_flows/client_flows_benchmark.d.ts +12 -13
  5. package/dest/bench/client_flows/client_flows_benchmark.d.ts.map +1 -1
  6. package/dest/bench/client_flows/client_flows_benchmark.js +117 -132
  7. package/dest/bench/utils.d.ts +6 -5
  8. package/dest/bench/utils.d.ts.map +1 -1
  9. package/dest/bench/utils.js +9 -7
  10. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts +6 -7
  11. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.d.ts.map +1 -1
  12. package/dest/e2e_blacklist_token_contract/blacklist_token_contract_test.js +96 -112
  13. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts +6 -7
  14. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.d.ts.map +1 -1
  15. package/dest/e2e_cross_chain_messaging/cross_chain_messaging_test.js +65 -62
  16. package/dest/e2e_deploy_contract/deploy_test.d.ts +4 -3
  17. package/dest/e2e_deploy_contract/deploy_test.d.ts.map +1 -1
  18. package/dest/e2e_deploy_contract/deploy_test.js +18 -13
  19. package/dest/e2e_epochs/epochs_test.d.ts +7 -1
  20. package/dest/e2e_epochs/epochs_test.d.ts.map +1 -1
  21. package/dest/e2e_epochs/epochs_test.js +30 -8
  22. package/dest/e2e_fees/bridging_race.notest.js +3 -5
  23. package/dest/e2e_fees/fees_test.d.ts +13 -13
  24. package/dest/e2e_fees/fees_test.d.ts.map +1 -1
  25. package/dest/e2e_fees/fees_test.js +122 -140
  26. package/dest/e2e_l1_publisher/write_json.d.ts +4 -3
  27. package/dest/e2e_l1_publisher/write_json.d.ts.map +1 -1
  28. package/dest/e2e_l1_publisher/write_json.js +14 -13
  29. package/dest/e2e_nested_contract/nested_contract_test.d.ts +6 -9
  30. package/dest/e2e_nested_contract/nested_contract_test.d.ts.map +1 -1
  31. package/dest/e2e_nested_contract/nested_contract_test.js +31 -39
  32. package/dest/e2e_p2p/inactivity_slash_test.d.ts +3 -3
  33. package/dest/e2e_p2p/inactivity_slash_test.d.ts.map +1 -1
  34. package/dest/e2e_p2p/inactivity_slash_test.js +3 -3
  35. package/dest/e2e_p2p/p2p_network.d.ts +7 -6
  36. package/dest/e2e_p2p/p2p_network.d.ts.map +1 -1
  37. package/dest/e2e_p2p/p2p_network.js +110 -103
  38. package/dest/e2e_p2p/shared.d.ts +6 -6
  39. package/dest/e2e_p2p/shared.d.ts.map +1 -1
  40. package/dest/e2e_p2p/shared.js +9 -16
  41. package/dest/e2e_token_contract/token_contract_test.d.ts +16 -9
  42. package/dest/e2e_token_contract/token_contract_test.d.ts.map +1 -1
  43. package/dest/e2e_token_contract/token_contract_test.js +89 -91
  44. package/dest/fixtures/e2e_prover_test.d.ts +8 -14
  45. package/dest/fixtures/e2e_prover_test.d.ts.map +1 -1
  46. package/dest/fixtures/e2e_prover_test.js +85 -93
  47. package/dest/fixtures/setup.d.ts +218 -0
  48. package/dest/fixtures/setup.d.ts.map +1 -0
  49. package/dest/fixtures/setup.js +695 -0
  50. package/dest/fixtures/setup_p2p_test.d.ts +4 -5
  51. package/dest/fixtures/setup_p2p_test.d.ts.map +1 -1
  52. package/dest/fixtures/setup_p2p_test.js +24 -19
  53. package/dest/fixtures/token_utils.d.ts +1 -1
  54. package/dest/fixtures/token_utils.d.ts.map +1 -1
  55. package/dest/fixtures/token_utils.js +7 -4
  56. package/dest/fixtures/utils.d.ts +5 -191
  57. package/dest/fixtures/utils.d.ts.map +1 -1
  58. package/dest/fixtures/utils.js +4 -615
  59. package/dest/quality_of_service/prometheus_client.d.ts +38 -0
  60. package/dest/quality_of_service/prometheus_client.d.ts.map +1 -0
  61. package/dest/quality_of_service/prometheus_client.js +67 -0
  62. package/dest/shared/cross_chain_test_harness.d.ts +14 -4
  63. package/dest/shared/cross_chain_test_harness.d.ts.map +1 -1
  64. package/dest/shared/cross_chain_test_harness.js +11 -11
  65. package/dest/shared/gas_portal_test_harness.d.ts +11 -1
  66. package/dest/shared/gas_portal_test_harness.d.ts.map +1 -1
  67. package/dest/shared/gas_portal_test_harness.js +1 -1
  68. package/dest/shared/submit-transactions.d.ts +3 -3
  69. package/dest/shared/submit-transactions.d.ts.map +1 -1
  70. package/dest/shared/submit-transactions.js +9 -11
  71. package/dest/shared/uniswap_l1_l2.d.ts +1 -1
  72. package/dest/shared/uniswap_l1_l2.d.ts.map +1 -1
  73. package/dest/shared/uniswap_l1_l2.js +12 -12
  74. package/dest/simulators/lending_simulator.d.ts +5 -1
  75. package/dest/simulators/lending_simulator.d.ts.map +1 -1
  76. package/dest/simulators/lending_simulator.js +2 -2
  77. package/dest/spartan/setup_test_wallets.d.ts +1 -1
  78. package/dest/spartan/setup_test_wallets.d.ts.map +1 -1
  79. package/dest/spartan/setup_test_wallets.js +61 -34
  80. package/dest/spartan/tx_metrics.d.ts +51 -2
  81. package/dest/spartan/tx_metrics.d.ts.map +1 -1
  82. package/dest/spartan/tx_metrics.js +333 -6
  83. package/dest/spartan/utils/bot.d.ts +27 -0
  84. package/dest/spartan/utils/bot.d.ts.map +1 -0
  85. package/dest/spartan/utils/bot.js +141 -0
  86. package/dest/spartan/utils/chaos.d.ts +79 -0
  87. package/dest/spartan/utils/chaos.d.ts.map +1 -0
  88. package/dest/spartan/utils/chaos.js +142 -0
  89. package/dest/spartan/utils/clients.d.ts +39 -0
  90. package/dest/spartan/utils/clients.d.ts.map +1 -0
  91. package/dest/spartan/utils/clients.js +90 -0
  92. package/dest/spartan/utils/config.d.ts +36 -0
  93. package/dest/spartan/utils/config.d.ts.map +1 -0
  94. package/dest/spartan/utils/config.js +20 -0
  95. package/dest/spartan/utils/health.d.ts +63 -0
  96. package/dest/spartan/utils/health.d.ts.map +1 -0
  97. package/dest/spartan/utils/health.js +202 -0
  98. package/dest/spartan/utils/helm.d.ts +15 -0
  99. package/dest/spartan/utils/helm.d.ts.map +1 -0
  100. package/dest/spartan/utils/helm.js +47 -0
  101. package/dest/spartan/utils/index.d.ts +9 -0
  102. package/dest/spartan/utils/index.d.ts.map +1 -0
  103. package/dest/spartan/utils/index.js +18 -0
  104. package/dest/spartan/utils/k8s.d.ts +98 -0
  105. package/dest/spartan/utils/k8s.d.ts.map +1 -0
  106. package/dest/spartan/utils/k8s.js +257 -0
  107. package/dest/spartan/utils/nodes.d.ts +31 -0
  108. package/dest/spartan/utils/nodes.d.ts.map +1 -0
  109. package/dest/spartan/utils/nodes.js +290 -0
  110. package/dest/spartan/utils/scripts.d.ts +16 -0
  111. package/dest/spartan/utils/scripts.d.ts.map +1 -0
  112. package/dest/spartan/utils/scripts.js +66 -0
  113. package/dest/spartan/utils.d.ts +2 -253
  114. package/dest/spartan/utils.d.ts.map +1 -1
  115. package/dest/spartan/utils.js +1 -892
  116. package/package.json +40 -39
  117. package/src/bench/client_flows/benchmark.ts +24 -2
  118. package/src/bench/client_flows/client_flows_benchmark.ts +137 -203
  119. package/src/bench/utils.ts +9 -7
  120. package/src/e2e_blacklist_token_contract/blacklist_token_contract_test.ts +104 -142
  121. package/src/e2e_cross_chain_messaging/cross_chain_messaging_test.ts +99 -106
  122. package/src/e2e_deploy_contract/deploy_test.ts +21 -14
  123. package/src/e2e_epochs/epochs_test.ts +59 -33
  124. package/src/e2e_fees/bridging_race.notest.ts +3 -9
  125. package/src/e2e_fees/fees_test.ts +171 -217
  126. package/src/e2e_l1_publisher/write_json.ts +16 -13
  127. package/src/e2e_nested_contract/nested_contract_test.ts +33 -56
  128. package/src/e2e_p2p/inactivity_slash_test.ts +5 -5
  129. package/src/e2e_p2p/p2p_network.ts +171 -167
  130. package/src/e2e_p2p/shared.ts +20 -22
  131. package/src/e2e_token_contract/token_contract_test.ts +103 -118
  132. package/src/fixtures/e2e_prover_test.ts +99 -133
  133. package/src/fixtures/setup.ts +1017 -0
  134. package/src/fixtures/setup_p2p_test.ts +15 -20
  135. package/src/fixtures/token_utils.ts +6 -5
  136. package/src/fixtures/utils.ts +27 -901
  137. package/src/quality_of_service/prometheus_client.ts +113 -0
  138. package/src/shared/cross_chain_test_harness.ts +13 -27
  139. package/src/shared/gas_portal_test_harness.ts +1 -1
  140. package/src/shared/submit-transactions.ts +9 -15
  141. package/src/shared/uniswap_l1_l2.ts +12 -19
  142. package/src/simulators/lending_simulator.ts +2 -2
  143. package/src/spartan/setup_test_wallets.ts +72 -24
  144. package/src/spartan/tx_metrics.ts +255 -9
  145. package/src/spartan/utils/bot.ts +185 -0
  146. package/src/spartan/utils/chaos.ts +253 -0
  147. package/src/spartan/utils/clients.ts +100 -0
  148. package/src/spartan/utils/config.ts +26 -0
  149. package/src/spartan/utils/health.ts +255 -0
  150. package/src/spartan/utils/helm.ts +84 -0
  151. package/src/spartan/utils/index.ts +62 -0
  152. package/src/spartan/utils/k8s.ts +375 -0
  153. package/src/spartan/utils/nodes.ts +323 -0
  154. package/src/spartan/utils/scripts.ts +63 -0
  155. package/src/spartan/utils.ts +1 -1158
  156. package/dest/fixtures/snapshot_manager.d.ts +0 -93
  157. package/dest/fixtures/snapshot_manager.d.ts.map +0 -1
  158. package/dest/fixtures/snapshot_manager.js +0 -488
  159. package/src/fixtures/snapshot_manager.ts +0 -646
@@ -0,0 +1,323 @@
1
+ import { createLogger } from '@aztec/aztec.js/log';
2
+ import type { RollupCheatCodes } from '@aztec/aztec/testing';
3
+ import type { CheckpointNumber } from '@aztec/foundation/branded-types';
4
+ import type { Logger } from '@aztec/foundation/log';
5
+ import { makeBackoff, retry } from '@aztec/foundation/retry';
6
+ import { sleep } from '@aztec/foundation/sleep';
7
+ import {
8
+ type AztecNodeAdmin,
9
+ type AztecNodeAdminConfig,
10
+ createAztecNodeAdminClient,
11
+ } from '@aztec/stdlib/interfaces/client';
12
+
13
+ import { exec } from 'child_process';
14
+ import { promisify } from 'util';
15
+
16
+ import type { TestConfig } from './config.js';
17
+ import { execHelmCommand } from './helm.js';
18
+ import { deleteResourceByLabel, getChartDir, startPortForward, waitForResourceByLabel } from './k8s.js';
19
+
20
+ const execAsync = promisify(exec);
21
+
22
+ const logger = createLogger('e2e:k8s-utils');
23
+
24
+ export async function awaitCheckpointNumber(
25
+ rollupCheatCodes: RollupCheatCodes,
26
+ checkpointNumber: CheckpointNumber,
27
+ timeoutSeconds: number,
28
+ log: Logger,
29
+ ) {
30
+ log.info(`Waiting for checkpoint ${checkpointNumber}`);
31
+ let tips = await rollupCheatCodes.getTips();
32
+ const endTime = Date.now() + timeoutSeconds * 1000;
33
+ while (tips.pending < checkpointNumber && Date.now() < endTime) {
34
+ log.info(`At checkpoint ${tips.pending}`);
35
+ await sleep(1000);
36
+ tips = await rollupCheatCodes.getTips();
37
+ }
38
+ if (tips.pending < checkpointNumber) {
39
+ throw new Error(`Timeout waiting for checkpoint ${checkpointNumber}, only reached ${tips.pending}`);
40
+ } else {
41
+ log.info(`Reached checkpoint ${tips.pending}`);
42
+ }
43
+ }
44
+
45
+ export async function getSequencers(namespace: string) {
46
+ const selectors = [
47
+ 'app.kubernetes.io/name=validator',
48
+ 'app.kubernetes.io/component=validator',
49
+ 'app.kubernetes.io/component=sequencer-node',
50
+ 'app=validator',
51
+ ];
52
+ for (const selector of selectors) {
53
+ try {
54
+ const command = `kubectl get pods -l ${selector} -n ${namespace} -o jsonpath='{.items[*].metadata.name}'`;
55
+ const { stdout } = await execAsync(command);
56
+ const sequencers = stdout
57
+ .split(' ')
58
+ .map(s => s.trim())
59
+ .filter(Boolean);
60
+ if (sequencers.length > 0) {
61
+ logger.verbose(`Found sequencer pods ${sequencers.join(', ')} (selector=${selector})`);
62
+ return sequencers;
63
+ }
64
+ } catch {
65
+ // try next selector
66
+ }
67
+ }
68
+
69
+ // Fail fast instead of returning [''] which leads to attempts to port-forward `pod/`.
70
+ throw new Error(
71
+ `No sequencer/validator pods found in namespace ${namespace}. Tried selectors: ${selectors.join(', ')}`,
72
+ );
73
+ }
74
+
75
+ export function updateSequencersConfig(env: TestConfig, config: Partial<AztecNodeAdminConfig>) {
76
+ return withSequencersAdmin(env, async client => {
77
+ await client.setConfig(config);
78
+ return client.getConfig();
79
+ });
80
+ }
81
+
82
+ export function getSequencersConfig(env: TestConfig) {
83
+ return withSequencersAdmin(env, client => client.getConfig());
84
+ }
85
+
86
+ export async function withSequencersAdmin<T>(env: TestConfig, fn: (node: AztecNodeAdmin) => Promise<T>): Promise<T[]> {
87
+ const adminContainerPort = 8880;
88
+ const namespace = env.NAMESPACE;
89
+ const sequencers = await getSequencers(namespace);
90
+ const results = [];
91
+
92
+ for (const sequencer of sequencers) {
93
+ // Wrap port-forward + fetch in a retry to handle flaky port-forwards
94
+ const result = await retry(
95
+ async () => {
96
+ const { process, port } = await startPortForward({
97
+ resource: `pod/${sequencer}`,
98
+ namespace,
99
+ containerPort: adminContainerPort,
100
+ });
101
+
102
+ try {
103
+ const url = `http://localhost:${port}`;
104
+ // Quick health check before using the connection
105
+ const statusRes = await fetch(`${url}/status`);
106
+ if (statusRes.status !== 200) {
107
+ throw new Error(`Admin endpoint returned status ${statusRes.status}`);
108
+ }
109
+ const client = createAztecNodeAdminClient(url);
110
+ return { result: await fn(client), process };
111
+ } catch (err) {
112
+ // Kill the port-forward before retrying
113
+ process.kill();
114
+ throw err;
115
+ }
116
+ },
117
+ 'connect to node admin',
118
+ makeBackoff([1, 2, 4, 8]),
119
+ logger,
120
+ true,
121
+ );
122
+
123
+ results.push(result.result);
124
+ result.process.kill();
125
+ }
126
+
127
+ return results;
128
+ }
129
+
130
+ /**
131
+ * Enables or disables probabilistic transaction dropping on validators and waits for rollout.
132
+ * Wired to env vars P2P_DROP_TX and P2P_DROP_TX_CHANCE via Helm values.
133
+ */
134
+ export async function setValidatorTxDrop({
135
+ namespace,
136
+ enabled,
137
+ probability,
138
+ logger: log,
139
+ }: {
140
+ namespace: string;
141
+ enabled: boolean;
142
+ probability: number;
143
+ logger: Logger;
144
+ }) {
145
+ const drop = enabled ? 'true' : 'false';
146
+ const prob = String(probability);
147
+
148
+ const selectors = ['app.kubernetes.io/name=validator', 'app.kubernetes.io/component=validator', 'app=validator'];
149
+ let updated = false;
150
+ for (const selector of selectors) {
151
+ try {
152
+ const list = await execAsync(`kubectl get statefulset -l ${selector} -n ${namespace} --no-headers -o name | cat`);
153
+ const names = list.stdout
154
+ .split('\n')
155
+ .map(s => s.trim())
156
+ .filter(Boolean);
157
+ if (names.length === 0) {
158
+ continue;
159
+ }
160
+ const cmd = `kubectl set env statefulset -l ${selector} -n ${namespace} P2P_DROP_TX=${drop} P2P_DROP_TX_CHANCE=${prob}`;
161
+ log.info(`command: ${cmd}`);
162
+ await execAsync(cmd);
163
+ updated = true;
164
+ } catch (e) {
165
+ log.warn(`Failed to update validators with selector ${selector}: ${String(e)}`);
166
+ }
167
+ }
168
+
169
+ if (!updated) {
170
+ log.warn(`No validator StatefulSets found in ${namespace}. Skipping tx drop toggle.`);
171
+ return;
172
+ }
173
+
174
+ // Restart validator pods to ensure env vars take effect and wait for readiness
175
+ await restartValidators(namespace, log);
176
+ }
177
+
178
+ export async function restartValidators(namespace: string, log: Logger) {
179
+ const selectors = ['app.kubernetes.io/name=validator', 'app.kubernetes.io/component=validator', 'app=validator'];
180
+ let any = false;
181
+ for (const selector of selectors) {
182
+ try {
183
+ const { stdout } = await execAsync(`kubectl get pods -l ${selector} -n ${namespace} --no-headers -o name | cat`);
184
+ if (!stdout || stdout.trim().length === 0) {
185
+ continue;
186
+ }
187
+ any = true;
188
+ await deleteResourceByLabel({ resource: 'pods', namespace, label: selector });
189
+ } catch (e) {
190
+ log.warn(`Error restarting validator pods with selector ${selector}: ${String(e)}`);
191
+ }
192
+ }
193
+
194
+ if (!any) {
195
+ log.warn(`No validator pods found to restart in ${namespace}.`);
196
+ return;
197
+ }
198
+
199
+ // Wait for either label to be Ready
200
+ for (const selector of selectors) {
201
+ try {
202
+ await waitForResourceByLabel({ resource: 'pods', namespace, label: selector });
203
+ return;
204
+ } catch {
205
+ // try next
206
+ }
207
+ }
208
+ log.warn(`Validator pods did not report Ready; continuing.`);
209
+ }
210
+
211
+ export async function enableValidatorDynamicBootNode(
212
+ instanceName: string,
213
+ namespace: string,
214
+ spartanDir: string,
215
+ log: Logger,
216
+ ) {
217
+ log.info(`Enabling validator dynamic boot node`);
218
+ await execHelmCommand({
219
+ instanceName,
220
+ namespace,
221
+ helmChartDir: getChartDir(spartanDir, 'aztec-network'),
222
+ values: {
223
+ 'validator.dynamicBootNode': 'true',
224
+ },
225
+ valuesFile: undefined,
226
+ timeout: '15m',
227
+ reuseValues: true,
228
+ });
229
+
230
+ log.info(`Validator dynamic boot node enabled`);
231
+ }
232
+
233
+ /**
234
+ * Rolls the Aztec pods in the given namespace.
235
+ * @param namespace - The namespace to roll the Aztec pods in.
236
+ * @param clearState - If true, also deletes the underlying PVCs to clear persistent storage.
237
+ * This is required for rollup upgrades where the old state is incompatible with the new rollup.
238
+ * Defaults to false, which preserves the existing storage.
239
+ */
240
+ export async function rollAztecPods(namespace: string, clearState: boolean = false) {
241
+ // Pod components use 'validator', but StatefulSets and PVCs use 'sequencer-node' for validators
242
+ const podComponents = ['p2p-bootstrap', 'prover-node', 'prover-broker', 'prover-agent', 'sequencer-node', 'rpc'];
243
+ const pvcComponents = ['p2p-bootstrap', 'prover-node', 'prover-broker', 'sequencer-node', 'rpc'];
244
+ // StatefulSet components that need to be scaled down before PVC deletion
245
+ // Note: validators use 'sequencer-node' as component label, not 'validator'
246
+ const statefulSetComponents = ['p2p-bootstrap', 'prover-node', 'prover-broker', 'sequencer-node', 'rpc'];
247
+
248
+ if (clearState) {
249
+ // To delete PVCs, we must first scale down StatefulSets so pods release the volumes
250
+ // Otherwise PVC deletion will hang waiting for pods to terminate
251
+
252
+ // First, save original replica counts
253
+ const originalReplicas: Map<string, number> = new Map();
254
+ for (const component of statefulSetComponents) {
255
+ try {
256
+ const getCmd = `kubectl get statefulset -l app.kubernetes.io/component=${component} -n ${namespace} -o jsonpath='{.items[0].spec.replicas}'`;
257
+ const { stdout } = await execAsync(getCmd);
258
+ const replicas = parseInt(stdout.replace(/'/g, '').trim(), 10);
259
+ if (!isNaN(replicas) && replicas > 0) {
260
+ originalReplicas.set(component, replicas);
261
+ }
262
+ } catch {
263
+ // Component might not exist, continue
264
+ }
265
+ }
266
+
267
+ // Scale down to 0
268
+ for (const component of statefulSetComponents) {
269
+ try {
270
+ const scaleCmd = `kubectl scale statefulset -l app.kubernetes.io/component=${component} -n ${namespace} --replicas=0 --timeout=2m`;
271
+ logger.info(`command: ${scaleCmd}`);
272
+ await execAsync(scaleCmd);
273
+ } catch (e) {
274
+ // Component might not exist or might be a Deployment, continue
275
+ logger.verbose(`Scale down ${component} skipped: ${e}`);
276
+ }
277
+ }
278
+
279
+ // Wait for pods to terminate
280
+ await sleep(15 * 1000);
281
+
282
+ // Now delete PVCs (they should no longer be in use)
283
+ for (const component of pvcComponents) {
284
+ await deleteResourceByLabel({
285
+ resource: 'persistentvolumeclaims',
286
+ namespace: namespace,
287
+ label: `app.kubernetes.io/component=${component}`,
288
+ });
289
+ }
290
+
291
+ // Scale StatefulSets back up to original replica counts
292
+ for (const component of statefulSetComponents) {
293
+ const replicas = originalReplicas.get(component) ?? 1;
294
+ try {
295
+ const scaleCmd = `kubectl scale statefulset -l app.kubernetes.io/component=${component} -n ${namespace} --replicas=${replicas} --timeout=2m`;
296
+ logger.info(`command: ${scaleCmd}`);
297
+ await execAsync(scaleCmd);
298
+ } catch (e) {
299
+ logger.verbose(`Scale up ${component} skipped: ${e}`);
300
+ }
301
+ }
302
+ } else {
303
+ // Just delete pods (no state clearing)
304
+ for (const component of podComponents) {
305
+ await deleteResourceByLabel({
306
+ resource: 'pods',
307
+ namespace: namespace,
308
+ label: `app.kubernetes.io/component=${component}`,
309
+ });
310
+ }
311
+ }
312
+
313
+ await sleep(10 * 1000);
314
+
315
+ // Wait for pods to come back
316
+ for (const component of podComponents) {
317
+ await waitForResourceByLabel({
318
+ resource: 'pods',
319
+ namespace: namespace,
320
+ label: `app.kubernetes.io/component=${component}`,
321
+ });
322
+ }
323
+ }
@@ -0,0 +1,63 @@
1
+ import type { Logger } from '@aztec/foundation/log';
2
+
3
+ import { execSync, spawn } from 'child_process';
4
+ import path from 'path';
5
+
6
+ /**
7
+ * @param scriptPath - The path to the script, relative to the project root
8
+ * @param args - The arguments to pass to the script
9
+ * @param logger - The logger to use
10
+ * @returns The exit code of the script
11
+ */
12
+ function runScript(scriptPath: string, args: string[], logger: Logger, env?: Record<string, string>) {
13
+ const childProcess = spawn(scriptPath, args, {
14
+ stdio: ['ignore', 'pipe', 'pipe'],
15
+ env: env ? { ...process.env, ...env } : process.env,
16
+ });
17
+ return new Promise<number>((resolve, reject) => {
18
+ childProcess.on('close', (code: number | null) => resolve(code ?? 0));
19
+ childProcess.on('error', reject);
20
+ childProcess.stdout?.on('data', (data: Buffer) => {
21
+ logger.info(data.toString());
22
+ });
23
+ childProcess.stderr?.on('data', (data: Buffer) => {
24
+ logger.error(data.toString());
25
+ });
26
+ });
27
+ }
28
+
29
+ /**
30
+ * Returns the absolute path to the git repository root
31
+ */
32
+ export function getGitProjectRoot(): string {
33
+ try {
34
+ const rootDir = execSync('git rev-parse --show-toplevel', {
35
+ encoding: 'utf-8',
36
+ stdio: ['ignore', 'pipe', 'ignore'],
37
+ }).trim();
38
+
39
+ return rootDir;
40
+ } catch (error) {
41
+ throw new Error(`Failed to determine git project root: ${error}`);
42
+ }
43
+ }
44
+
45
+ export function getAztecBin() {
46
+ return path.join(getGitProjectRoot(), 'yarn-project/aztec/dest/bin/index.js');
47
+ }
48
+
49
+ /**
50
+ * Runs the Aztec binary
51
+ * @param args - The arguments to pass to the Aztec binary
52
+ * @param logger - The logger to use
53
+ * @param env - Optional environment variables to set for the process
54
+ * @returns The exit code of the Aztec binary
55
+ */
56
+ export function runAztecBin(args: string[], logger: Logger, env?: Record<string, string>) {
57
+ return runScript('node', [getAztecBin(), ...args], logger, env);
58
+ }
59
+
60
+ export function runProjectScript(script: string, args: string[], logger: Logger, env?: Record<string, string>) {
61
+ const scriptPath = script.startsWith('/') ? script : path.join(getGitProjectRoot(), script);
62
+ return runScript(scriptPath, args, logger, env);
63
+ }