Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

822 Load Testing #833

Merged
merged 15 commits into from
Feb 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading