Skip to content

Commit 7036837

Browse files
committed
feat: add web socket server load tests
1 parent ebe594f commit 7036837

File tree

2 files changed

+114
-0
lines changed

2 files changed

+114
-0
lines changed

.github/workflows/k6-web-socket.yaml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,54 @@ name: K6 WebSocket server load tests
22

33
on:
44
workflow_dispatch:
5+
branches: ['master', 'feat/web-socket-network-info-provider']
6+
inputs:
7+
environment:
8+
description: 'Target environment'
9+
type: choice
10+
required: true
11+
options:
12+
- 'dev'
13+
- 'ops'
14+
- 'staging'
15+
- 'prod'
16+
network:
17+
description: 'Target network'
18+
type: choice
19+
required: true
20+
options:
21+
- 'preview'
22+
- 'preprod'
23+
- 'sanchonet'
24+
- 'mainnet'
25+
wallets:
26+
description: 'Number of wallets to simulate'
27+
type: number
28+
required: true
29+
default: 1000
530

631
jobs:
732
web-socket:
833
runs-on: ubuntu-latest
934
steps:
1035
- name: Checkout
1136
uses: actions/checkout@v3
37+
- name: Run k6 cloud test
38+
uses: grafana/[email protected]
39+
env:
40+
K6_CLOUD_PROJECT_ID: ${{ secrets.K6_CLOUD_PROJECT_ID }}
41+
with:
42+
filename: ./packages/e2e/test/k6/scenarios/web-socket.test.js
43+
cloud: false
44+
token: ${{ secrets.K6_CLOUD_API_TOKEN }}
45+
flags: >
46+
-e TARGET_ENV=${{ inputs.environment }}
47+
-e TARGET_NET=${{ inputs.network }}
48+
-e WALLETS=${{ inputs.wallets }}
49+
--out json=web-socket-results.json
50+
--quiet
51+
- name: Upload performance test results
52+
uses: actions/upload-artifact@v3
53+
with:
54+
name: k6-report
55+
path: web-socket-results.json
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// cSpell:ignore loadimpact
2+
3+
import { Counter, Trend } from 'k6/metrics';
4+
import { check } from 'k6';
5+
import ws from 'k6/ws';
6+
7+
// eslint-disable-next-line no-undef
8+
const { TARGET_ENV, TARGET_NET, URL, WALLETS } = Object.assign({ WALLETS: '10000' }, __ENV);
9+
const url = TARGET_ENV ? `wss://${TARGET_ENV}-${TARGET_NET}${TARGET_ENV === 'ops' ? '-1' : ''}.lw.iog.io/ws` : URL;
10+
11+
if (TARGET_ENV && !['dev', 'ops', 'staging', 'prod'].includes(TARGET_ENV))
12+
throw new Error(`Not valid TARGET_ENV: ${TARGET_ENV}`);
13+
if (TARGET_NET && !['preview', 'preprod', 'sanchonet', 'mainnet'].includes(TARGET_NET))
14+
throw new Error(`Not valid TARGET_NET: ${TARGET_NET}`);
15+
if (!(TARGET_ENV && TARGET_NET) && !URL) throw new Error('Please specify both TARGET_ENV and TARGET_NET or URL');
16+
17+
export const options = {
18+
ext: {
19+
loadimpact: {
20+
apm: [],
21+
distribution: { 'amazon:us:portland': { loadZone: 'amazon:us:portland', percent: 100 } }
22+
}
23+
},
24+
scenarios: {
25+
connections: {
26+
executor: 'ramping-vus',
27+
gracefulRampDown: '0s',
28+
gracefulStop: '120s',
29+
stages: [{ duration: '3s', target: Number.parseInt(WALLETS, 10) }],
30+
startVUs: 10
31+
}
32+
}
33+
};
34+
35+
const operationalTrend = new Trend('_operational', true);
36+
const unexpectedCloseCounter = new Counter('_unexpected_close');
37+
38+
export const run = () => {
39+
const begin = Date.now();
40+
41+
const res = ws.connect(url, null, (socket) => {
42+
let closed = false;
43+
let firstMessage = true;
44+
45+
socket.on('message', () => {
46+
if (firstMessage) {
47+
operationalTrend.add(Date.now() - begin);
48+
firstMessage = false;
49+
}
50+
});
51+
52+
// Count unexpected close
53+
socket.on('close', () => {
54+
if (!closed) unexpectedCloseCounter.add(1);
55+
});
56+
57+
// Heartbeat
58+
socket.setTimeout(() => socket.send('{}'), 30 * 1000);
59+
60+
// End the test after 80"
61+
socket.setTimeout(() => {
62+
closed = true;
63+
socket.close();
64+
}, 80 * 1000);
65+
});
66+
67+
check(res, { 'status is 101': (r) => r && r.status === 101 });
68+
};
69+
70+
export default run;

0 commit comments

Comments
 (0)