Skip to content

Commit

Permalink
822 Load Testing (#833)
Browse files Browse the repository at this point in the history
* Creation of load script
  • Loading branch information
kclark-scottlogic authored and chriswilty committed Apr 8, 2024
1 parent c01f92a commit f060b01
Show file tree
Hide file tree
Showing 9 changed files with 2,900 additions and 23 deletions.
23 changes: 23 additions & 0 deletions .github/workflows/node.js.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,26 @@ jobs:
- run: npx prettier . --check
- run: npm run build
- run: npm test

build-test-k6:
runs-on: ubuntu-latest

strategy:
matrix:
node-version: [18.x]
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/

defaults:
run:
working-directory: ./k6
steps:
- uses: actions/checkout@v3
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node-version }}
cache: "npm"
cache-dependency-path: "./frontend/package-lock.json"
- run: npm ci
- run: npx eslint .
- run: npx prettier . --check
10 changes: 5 additions & 5 deletions backend/src/controller/testController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ import { handleAddInfoToChatHistory } from '@src/controller/chatController';
import { OpenAiAddInfoToChatHistoryRequest } from '@src/models/api/OpenAiAddInfoToChatHistoryRequest';

function handleTest(req: OpenAiAddInfoToChatHistoryRequest, res: Response) {
let num = 0;
for (let x = 0; x <= 1000000; x++) {
num = num++;
}
handleAddInfoToChatHistory(req, res);
const ranNum = Math.round((Math.random() + 1) * 1000);

setTimeout(() => {
handleAddInfoToChatHistory(req, res);
}, ranNum);
}
export { handleTest };
6 changes: 3 additions & 3 deletions backend/src/sessionRoutes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,9 @@ router.post('/openai/model/configure', handleConfigureModel);
// reset progress for all levels
router.post('/reset', handleResetProgress);

// Testing endpoints
router.post('/test/load', handleTest);

// Debugging: log headers in prod for primary routes
if (isProd) {
router.use('/openai', (req, res, next) => {
Expand All @@ -133,7 +136,4 @@ if (isProd) {
});
}

// Testing dummy endpoint
router.post('/test/load', handleTest);

export default router;
47 changes: 47 additions & 0 deletions k6/.eslintrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/* eslint-env node */
module.exports = {
root: true,
extends: ['eslint:recommended', 'plugin:import/recommended'],
parser: '@typescript-eslint/parser',
plugins: ['@typescript-eslint'],
ignorePatterns: ['node_modules'],
rules: {
eqeqeq: 'error',
'func-style': ['error', 'declaration'],
'object-shorthand': 'error',
'no-restricted-imports': [
'error',
{
patterns: ['../*'],
},
],
'prefer-template': 'error',
'import/no-unresolved': [
'error',
{
ignore: ['k6/*'],
},
],
'import/order': [
'error',
{
alphabetize: { order: 'asc' },
'newlines-between': 'always',
warnOnUnassignedImports: true,
pathGroups: [
{
pattern: '@src/**',
group: 'internal',
position: 'before',
},
],
groups: [
['builtin', 'external'],
['internal', 'parent', 'index', 'sibling'],
['object', 'type'],
],
},
],
'no-mixed-spaces-and-tabs': 0, // disable rule
},
};
3 changes: 2 additions & 1 deletion k6/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ Grafana k6 is an open-source load testing tool that makes performance testing ea
## Running locally

1. Make sure local backend is running, [refer to the backend README](../backend/README.md)
1. in a separate terminal cd into the K6 folder and run `k6 run script.js` (Where 'script' is the name of the script you want to run)
1. in a separate terminal cd into the K6 folder and run `npm test script.js` (Where 'script' is the name of the script you want to run)
1. If you want a dashboard to view track trends in real time run `K6_WEB_DASHBOARD=true K6_WEB_DASHBOARD_OPEN=true k6 run script.js` (Where 'script' is the name of the script you want to run). Note: When running this refresh the dashboard at the end of the run for the test to finish in the terminal
52 changes: 52 additions & 0 deletions k6/load.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { check, sleep } from 'k6';
import exec from 'k6/execution';
import http from 'k6/http';

export const options = {
//vus and duration can be changed depending on what simulation needed running
scenarios: {
contacts: {
executor: 'constant-vus',
vus: 100,
duration: '30m',
},
},
};

const baseUrl = 'http://localhost:3001';
const cookieName = 'prompt-injection.sid';
const vuCookieJar = (() => {
const cookieJars = {};
return {
get: (id) => cookieJars[id],
set: (id, jar) => (cookieJars[id] = jar),
};
})();

export default () => {
// Use same jar for every iteration of same VU! k6 doesn't do this for us :(
const vuID = exec.vu.idInTest;
let jar = vuCookieJar.get(vuID);
if (!jar) {
jar = http.cookieJar();
vuCookieJar.set(vuID, jar);
}
let originalCookie = (jar.cookiesForURL(baseUrl)[cookieName] || [])[0];

const data = { infoMessage: 'Hi', chatMessageType: 'LEVEL_INFO', level: 3 };
const response = http.post(`${baseUrl}/test/load`, JSON.stringify(data), {
headers: { 'Content-Type': 'application/json' },
jar,
});
// Expecting cookie to match original, OR first-time be added to the jar
const expectedCookie =
originalCookie || jar.cookiesForURL(baseUrl)[cookieName][0];
check(response, {
'response code was 200': (response) => response.status === 200,
'cookie was preserved': (response) =>
response.cookies[cookieName].length === 1 &&
response.cookies[cookieName][0].value === expectedCookie,
});

sleep(1);
};
Loading

0 comments on commit f060b01

Please sign in to comment.