Moved benchmark to its own directory and added multicore testing + a README
This commit is contained in:
parent
d4fe59d154
commit
b37a8f63be
11 changed files with 160 additions and 1337 deletions
69
benchmark/README.md
Normal file
69
benchmark/README.md
Normal file
|
@ -0,0 +1,69 @@
|
|||
# Load testing
|
||||
|
||||
Load testing is performed with Artillery.
|
||||
|
||||
Install:
|
||||
|
||||
```bash
|
||||
cd benchmark
|
||||
npm install
|
||||
```
|
||||
|
||||
Running the tests (on one core):
|
||||
|
||||
```bash
|
||||
cd benchmark
|
||||
npm run start
|
||||
```
|
||||
|
||||
You can adapt the `socketio-load-test.yaml` file to increase/decrease load.
|
||||
|
||||
Default settings are:
|
||||
|
||||
```yaml
|
||||
phases:
|
||||
- duration: 20
|
||||
arrivalRate: 2
|
||||
```
|
||||
|
||||
which means: during 20 seconds, 2 users will be added every second (peaking at 40 simultaneous users).
|
||||
|
||||
Important: don't go above 40 simultaneous users for Artillery, otherwise, it is Artillery that will fail to run the tests properly.
|
||||
To know, simply run "top". The "node" process for Artillery should never reach 100%.
|
||||
|
||||
Reports are generated in `artillery_output.html`.
|
||||
|
||||
# Multicore tests
|
||||
|
||||
You will want to test with Artillery running on multiple cores.
|
||||
|
||||
You can use
|
||||
|
||||
```bash
|
||||
./artillery_multi_core.sh
|
||||
```
|
||||
|
||||
This will trigger 4 Artillery instances in parallel.
|
||||
|
||||
Beware, the report generated is generated for only one instance.
|
||||
|
||||
# How to test, what to track?
|
||||
|
||||
While testing, you can check:
|
||||
|
||||
- CPU load of WorkAdventure API node process (it should not reach 100%)
|
||||
- Get metrics at the end of the run: `http://api.workadventure.localhost/metrics`
|
||||
In particular, look for:
|
||||
```
|
||||
# HELP nodejs_eventloop_lag_max_seconds The maximum recorded event loop delay.
|
||||
# TYPE nodejs_eventloop_lag_max_seconds gauge
|
||||
nodejs_eventloop_lag_max_seconds 23.991418879
|
||||
```
|
||||
This is the maximum time it took Node to process an event (you need to restart node after each test to reset this counter)
|
||||
- Generate a profiling using "node --prof" by switching the command in docker-compose.yaml:
|
||||
```
|
||||
#command: yarn dev
|
||||
command: yarn run profile
|
||||
```
|
||||
Read https://nodejs.org/en/docs/guides/simple-profiling/ on how to generate a profile.
|
||||
|
17
benchmark/artillery_multi_core.sh
Executable file
17
benchmark/artillery_multi_core.sh
Executable file
|
@ -0,0 +1,17 @@
|
|||
#!/bin/bash
|
||||
|
||||
npm run start &
|
||||
pid1=$!
|
||||
npm run start:nooutput &
|
||||
pid2=$!
|
||||
npm run start:nooutput &
|
||||
pid3=$!
|
||||
npm run start:nooutput &
|
||||
pid4=$!
|
||||
|
||||
wait $pid1
|
||||
wait $pid2
|
||||
wait $pid3
|
||||
wait $pid4
|
||||
|
||||
|
27
benchmark/package.json
Normal file
27
benchmark/package.json
Normal file
|
@ -0,0 +1,27 @@
|
|||
{
|
||||
"name": "workadventure-artillery",
|
||||
"version": "1.0.0",
|
||||
"description": "Load testing for WorkAdventure",
|
||||
"scripts": {
|
||||
"start": "artillery run socketio-load-test.yaml -o artillery_output.json && artillery report --output artillery_output.html artillery_output.json",
|
||||
"start:nooutput": "artillery run socketio-load-test.yaml"
|
||||
},
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Grégoire Parant",
|
||||
"email": "g.parant@thecodingmachine.com"
|
||||
},
|
||||
{
|
||||
"name": "David Négrier",
|
||||
"email": "d.negrier@thecodingmachine.com"
|
||||
},
|
||||
{
|
||||
"name": "Arthmaël Poly",
|
||||
"email": "a.poly@thecodingmachine.com"
|
||||
}
|
||||
],
|
||||
"license": "SEE LICENSE IN LICENSE.txt",
|
||||
"dependencies": {
|
||||
"artillery": "^1.6.1"
|
||||
}
|
||||
}
|
43
benchmark/socketio-load-test.yaml
Normal file
43
benchmark/socketio-load-test.yaml
Normal file
|
@ -0,0 +1,43 @@
|
|||
config:
|
||||
target: "http://api.workadventure.localhost/"
|
||||
socketio:
|
||||
transports: ["websocket"]
|
||||
query:
|
||||
token: "test"
|
||||
phases:
|
||||
- duration: 20
|
||||
arrivalRate: 2
|
||||
processor: "./socketioLoadTest.js"
|
||||
scenarios:
|
||||
- name: "Connects and moves player for 20 seconds"
|
||||
weight: 90
|
||||
engine: "socketio"
|
||||
flow:
|
||||
- emit:
|
||||
channel: "set-player-details"
|
||||
data:
|
||||
name: 'TEST'
|
||||
characterLayers: ['male3']
|
||||
- think: 1
|
||||
- emit:
|
||||
channel: "join-room"
|
||||
data:
|
||||
roomId: 'global__api.workadventure.localhost/map/files/Floor0/floor0'
|
||||
position:
|
||||
x: 783
|
||||
y: 170
|
||||
direction: 'down'
|
||||
moving: false
|
||||
- think: 1
|
||||
- loop:
|
||||
- function: "setYRandom"
|
||||
- emit:
|
||||
channel: "user-position"
|
||||
data:
|
||||
x: "{{ x }}"
|
||||
y: "{{ y }}"
|
||||
direction: 'down'
|
||||
moving: false
|
||||
- think: 0.2
|
||||
count: 100
|
||||
- think: 10
|
11
benchmark/socketioLoadTest.js
Normal file
11
benchmark/socketioLoadTest.js
Normal file
|
@ -0,0 +1,11 @@
|
|||
'use strict';
|
||||
|
||||
module.exports = {
|
||||
setYRandom
|
||||
};
|
||||
|
||||
function setYRandom(context, events, done) {
|
||||
context.vars.x = (883 + Math.round(Math.random() * 300));
|
||||
context.vars.y = (270 + Math.round(Math.random() * 300));
|
||||
return done();
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue