Skip to content

Commit

Permalink
feat: add web socket server load tests
Browse files Browse the repository at this point in the history
  • Loading branch information
iccicci committed Jul 22, 2024
1 parent ebe594f commit 7036837
Show file tree
Hide file tree
Showing 2 changed files with 114 additions and 0 deletions.
44 changes: 44 additions & 0 deletions .github/workflows/k6-web-socket.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,54 @@ name: K6 WebSocket server load tests

on:
workflow_dispatch:
branches: ['master', 'feat/web-socket-network-info-provider']
inputs:
environment:
description: 'Target environment'
type: choice
required: true
options:
- 'dev'
- 'ops'
- 'staging'
- 'prod'
network:
description: 'Target network'
type: choice
required: true
options:
- 'preview'
- 'preprod'
- 'sanchonet'
- 'mainnet'
wallets:
description: 'Number of wallets to simulate'
type: number
required: true
default: 1000

jobs:
web-socket:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Run k6 cloud test
uses: grafana/[email protected]
env:
K6_CLOUD_PROJECT_ID: ${{ secrets.K6_CLOUD_PROJECT_ID }}
with:
filename: ./packages/e2e/test/k6/scenarios/web-socket.test.js
cloud: false
token: ${{ secrets.K6_CLOUD_API_TOKEN }}
flags: >
-e TARGET_ENV=${{ inputs.environment }}
-e TARGET_NET=${{ inputs.network }}
-e WALLETS=${{ inputs.wallets }}
--out json=web-socket-results.json
--quiet
- name: Upload performance test results
uses: actions/upload-artifact@v3
with:
name: k6-report
path: web-socket-results.json
70 changes: 70 additions & 0 deletions packages/e2e/test/k6/scenarios/web-socket.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// cSpell:ignore loadimpact

import { Counter, Trend } from 'k6/metrics';
import { check } from 'k6';
import ws from 'k6/ws';

// eslint-disable-next-line no-undef
const { TARGET_ENV, TARGET_NET, URL, WALLETS } = Object.assign({ WALLETS: '10000' }, __ENV);
const url = TARGET_ENV ? `wss://${TARGET_ENV}-${TARGET_NET}${TARGET_ENV === 'ops' ? '-1' : ''}.lw.iog.io/ws` : URL;

if (TARGET_ENV && !['dev', 'ops', 'staging', 'prod'].includes(TARGET_ENV))
throw new Error(`Not valid TARGET_ENV: ${TARGET_ENV}`);
if (TARGET_NET && !['preview', 'preprod', 'sanchonet', 'mainnet'].includes(TARGET_NET))
throw new Error(`Not valid TARGET_NET: ${TARGET_NET}`);
if (!(TARGET_ENV && TARGET_NET) && !URL) throw new Error('Please specify both TARGET_ENV and TARGET_NET or URL');

export const options = {
ext: {
loadimpact: {
apm: [],
distribution: { 'amazon:us:portland': { loadZone: 'amazon:us:portland', percent: 100 } }
}
},
scenarios: {
connections: {
executor: 'ramping-vus',
gracefulRampDown: '0s',
gracefulStop: '120s',
stages: [{ duration: '3s', target: Number.parseInt(WALLETS, 10) }],
startVUs: 10
}
}
};

const operationalTrend = new Trend('_operational', true);
const unexpectedCloseCounter = new Counter('_unexpected_close');

export const run = () => {
const begin = Date.now();

const res = ws.connect(url, null, (socket) => {
let closed = false;
let firstMessage = true;

socket.on('message', () => {
if (firstMessage) {
operationalTrend.add(Date.now() - begin);
firstMessage = false;
}
});

// Count unexpected close
socket.on('close', () => {
if (!closed) unexpectedCloseCounter.add(1);
});

// Heartbeat
socket.setTimeout(() => socket.send('{}'), 30 * 1000);

// End the test after 80"
socket.setTimeout(() => {
closed = true;
socket.close();
}, 80 * 1000);
});

check(res, { 'status is 101': (r) => r && r.status === 101 });
};

export default run;

0 comments on commit 7036837

Please sign in to comment.