Skip to content

Commit 6b3f49c

Browse files
committed
Add execute-js load test
1 parent 17bcc87 commit 6b3f49c

File tree

3 files changed

+114
-0
lines changed

3 files changed

+114
-0
lines changed

e2e/artillery/configs/execute.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
config:
2+
target: "dummy"
3+
phases:
4+
# Over 60s, ramp up to creating 50 vusers per second
5+
- duration: 60
6+
arrivalRate: 5
7+
rampTo: 50
8+
name: "Ramp Up"
9+
# Over 300s, create 50 vusers per second
10+
- duration: 300
11+
arrivalRate: 50
12+
name: "Sustained Encrypt & Decrypt"
13+
# Over 60s, ramp down to creating 5 vusers per second
14+
- duration: 60
15+
arrivalRate: 10
16+
name: "Ramp Down"
17+
processor: "../src/processors/multi-endpoints.ts"
18+
19+
scenarios:
20+
- name: "Execute JS Stress Test"
21+
weight: 100
22+
flow:
23+
- function: "runExecuteJSTest"
24+
- think: 0.1

e2e/artillery/src/processors/multi-endpoints.ts

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,28 @@ const PkpSignResultSchema = z.object({
1818
sigType: z.string().min(1, 'Signature type cannot be empty'),
1919
});
2020

21+
// Execute JS Result Schema
22+
const ExecuteJsResultSchema = z.object({
23+
success: z.boolean(),
24+
signatures: z.record(
25+
z.string(),
26+
z.object({
27+
signature: z.string().regex(/^0x[a-fA-F0-9]+$/, 'Invalid hex signature'),
28+
verifyingKey: z
29+
.string()
30+
.regex(/^0x[a-fA-F0-9]+$/, 'Invalid hex verifying key'),
31+
signedData: z
32+
.string()
33+
.regex(/^0x[a-fA-F0-9]+$/, 'Invalid hex signed data'),
34+
recoveryId: z.number().int().min(0).max(3, 'Recovery ID must be 0-3'),
35+
publicKey: z.string().regex(/^0x[a-fA-F0-9]+$/, 'Invalid hex public key'),
36+
sigType: z.string().min(1, 'Signature type cannot be empty'),
37+
})
38+
),
39+
response: z.string(),
40+
logs: z.string(),
41+
});
42+
2143
// Global variables to cache expensive operations
2244
let litClient: LitClientType;
2345
let authManager: any = null;
@@ -212,6 +234,73 @@ export async function runEncryptDecryptTest() {
212234
}
213235
}
214236

237+
// test '/web/execute/v2' endpoint
238+
export async function runExecuteJSTest() {
239+
const startTime = Date.now();
240+
241+
try {
242+
// 1. Initialise shared resources (only happens once)
243+
await initialiseSharedResources();
244+
245+
// 2. Read state
246+
const state = await StateManager.readFile();
247+
248+
// Create auth context
249+
const authContext = await createAuthContextFromState();
250+
251+
// Perform executeJs operation
252+
const litActionCode = `
253+
(async () => {
254+
const { sigName, toSign, publicKey } = jsParams;
255+
const { keccak256, arrayify } = ethers.utils;
256+
257+
const toSignBytes = new TextEncoder().encode(toSign);
258+
const toSignBytes32 = keccak256(toSignBytes);
259+
const toSignBytes32Array = arrayify(toSignBytes32);
260+
261+
const sigShare = await Lit.Actions.signEcdsa({
262+
toSign: toSignBytes32Array,
263+
publicKey,
264+
sigName,
265+
});
266+
})();`;
267+
268+
const result = await litClient.executeJs({
269+
code: litActionCode,
270+
authContext,
271+
jsParams: {
272+
message: 'Test message from e2e executeJs',
273+
sigName: 'e2e-test-sig',
274+
toSign: 'Test message from e2e executeJs',
275+
publicKey: state.masterAccount.pkp.publicKey,
276+
},
277+
});
278+
279+
// Validate the result using Zod schema
280+
const validatedResult = ExecuteJsResultSchema.parse(result);
281+
282+
const endTime = Date.now();
283+
const duration = endTime - startTime;
284+
285+
console.log(`✅ executeJs successful in ${duration}ms`);
286+
console.log('✅ executeJs result:', validatedResult);
287+
288+
// For Artillery, just return - no need to call next()
289+
return;
290+
} catch (error) {
291+
const endTime = Date.now();
292+
const duration = endTime - startTime;
293+
294+
console.error(
295+
`❌ executeJs failed in ${duration}ms:`,
296+
error instanceof Error ? error.message : String(error)
297+
);
298+
299+
// Throw the error to let Artillery handle it
300+
throw error;
301+
}
302+
}
303+
215304
// test '/web/sign_session_key' endpoint
216305
export async function runSignSessionKeyTest() {
217306
// ❗️ IT'S IMPORTANT TO SET THIS TO FALSE FOR TESTING

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
"artillery:balance-status": "LOG_LEVEL=silent bun run ./e2e/artillery/src/balance-status.ts",
3030
"artillery:pkp-sign": "DEBUG_HTTP=true LOG_LEVEL=silent dotenvx run --env-file=.env -- sh -c 'artillery run ./e2e/artillery/configs/pkp-sign.yml ${ARTILLERY_KEY:+--record --key $ARTILLERY_KEY}'",
3131
"artillery:encrypt-decrypt": "DEBUG_HTTP=true LOG_LEVEL=silent dotenvx run --env-file=.env -- sh -c 'artillery run ./e2e/artillery/configs/encrypt-decrypt.yml ${ARTILLERY_KEY:+--record --key $ARTILLERY_KEY}'",
32+
"artillery:execute-js": "DEBUG_HTTP=true LOG_LEVEL=silent dotenvx run --env-file=.env -- sh -c 'artillery run ./e2e/artillery/configs/execute.yml ${ARTILLERY_KEY:+--record --key $ARTILLERY_KEY}'",
3233
"artillery:sign-session-key": "DEBUG_HTTP=true LOG_LEVEL=silent dotenvx run --env-file=.env -- sh -c 'artillery run ./e2e/artillery/configs/sign-session-key.yml ${ARTILLERY_KEY:+--record --key $ARTILLERY_KEY}'"
3334
},
3435
"private": true,

0 commit comments

Comments
 (0)