-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
eb7b13d
commit 02f5c47
Showing
5 changed files
with
384 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
# Loadtesting the boards | ||
|
||
The socket.io documentation suggests to use the tool artillery in order to load test a socket-io tool like our board-collaboration service. | ||
|
||
For defining scenarios you need to use/create Yaml-files that define which operations with which parameters need to be executed in which order. | ||
|
||
Some sceneraios were already prepared and are stored in the subfolder scenarios. | ||
|
||
## install artillery | ||
|
||
To run artillery from your local environment you need to install it first including an adapter that supports socketio-v3-websocket communication: | ||
|
||
```sh | ||
npm install -g artillery artillery-engine-socketio-v3 | ||
``` | ||
|
||
## manual execution | ||
|
||
To execute a scenario you can run artillery from the shell / commandline...: | ||
|
||
Using the `--variables` parameter it is possible to define several variables and there values that can be used in the scenerio-yaml-file: | ||
|
||
- **target**: defines the base url for all requests (REST and WebSocket) | ||
e.g. https://main.dbc.dbildungscloud.dev | ||
- **token**: a valid JWT for the targeted system | ||
- **board_id**: id of an existing board the tests should be executed on | ||
|
||
```powershell | ||
npx artillery run --variables "{'target': 'https://main.dbc.dbildungscloud.dev', 'token': 'eJ....', 'board_id': '668d0e03bf3689d12e1e86fb' }" './scenarios/3users.yml' --output artilleryreport.json | ||
``` | ||
|
||
## visualizing the recorded results | ||
|
||
It is possible to generate a HTML-report based on the recorded data. | ||
|
||
```powershell | ||
npx artillery report --output=$board_title.html artilleryreport.json | ||
``` | ||
|
||
## automatic execution | ||
|
||
You can run one of the existing scenarios by executing: | ||
|
||
```bash | ||
bash runScenario.sh | ||
``` | ||
|
||
This will: | ||
|
||
1. let you choose from scenario-files | ||
2. create a fresh JWT-webtoken | ||
3. create a fresh board (in one of the courses) the user has access to | ||
4. name the board by a combination of datetime and the scenario name. | ||
5. start the execution of the scenario against this newly created board | ||
6. generate a html report in the end | ||
|
||
## Open Todos: | ||
|
||
- [x] split code into functions | ||
- [x] suppress curl output | ||
- [ ] add proper error handling of failed requests | ||
- [x] cleanup scenarios | ||
- x ] write documentation for linux => runScenario.sh | ||
- [x] write documentation for windows => direct command | ||
- [ ] properly handle credentials - env-vars? | ||
- [ ] replace selects with parameters from script call |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
#!/bin/bash | ||
function select_target() { | ||
declare -a targets=("https://main.nbc.dbildungscloud.dev" "https://bc-6854-basic-load-tests.nbc.dbildungscloud.dev") | ||
echo "Please select the target for the test:" >&2 | ||
select target in "${targets[@]}"; do | ||
if [[ -n $target ]]; then | ||
break | ||
else | ||
echo "Invalid selection. Please try again." >&2 | ||
fi | ||
done | ||
} | ||
|
||
function select_scenario() { | ||
# list files in the scenarios directory | ||
scenarios_dir="./scenarios" | ||
declare -a scenario_files=($(ls $scenarios_dir)) | ||
|
||
echo "Please select a scenario file for the test:" >&2 | ||
select scenario_file in "${scenario_files[@]}"; do | ||
if [[ -n $scenario_file ]]; then | ||
echo "You have selected: $scenario_file" >&2 | ||
break | ||
else | ||
echo "Invalid selection. Please try again." >&2 | ||
fi | ||
done | ||
|
||
scenario_name="${scenario_file%.*}" | ||
} | ||
|
||
function get_token() { | ||
response=$(curl -s -f -X 'POST' \ | ||
"$target/api/v3/authentication/local" \ | ||
-H 'accept: application/json' \ | ||
-H 'Content-Type: application/json' \ | ||
-d '{ | ||
"username": "[email protected]", | ||
"password": "Schulcloud1!" | ||
}') | ||
|
||
if [ $? -ne 0 ]; then | ||
echo "ERROR: Failed to get token. Please check your credentials and target URL." >&2 | ||
exit 1 | ||
fi | ||
|
||
token=$(echo $response | sed -n 's/.*"accessToken":"\([^"]*\)".*/\1/p') | ||
} | ||
|
||
function get_course_id() { | ||
response=$(curl -s -f -X 'GET' \ | ||
"$target/api/v3/courses" \ | ||
-H "Accept: application/json" \ | ||
-H "Authorization: Bearer $token") | ||
|
||
if [ $? -ne 0 ]; then | ||
echo "ERROR: Failed to get course list. Please check your credentials and target URL." >&2 | ||
exit 1 | ||
fi | ||
|
||
course_id=$(echo $response | sed -n 's/.*"id":"\([^"]*\)".*/\1/p') | ||
} | ||
|
||
function create_board_title() { | ||
current_date=$(date +%Y-%m-%d_%H:%M) | ||
board_title="${current_date}_$1" | ||
} | ||
|
||
function create_board() { | ||
response=$(curl -s -f -X 'POST' \ | ||
"$target/api/v3/boards" \ | ||
-H 'accept: application/json' \ | ||
-H 'Content-Type: application/json' \ | ||
-H "Authorization: Bearer $token" \ | ||
-d "{ | ||
\"title\": \"$board_title\", | ||
\"parentId\": \"$course_id\", | ||
\"parentType\": \"course\", | ||
\"layout\": \"columns\" | ||
}") | ||
|
||
if [ $? -ne 0 ]; then | ||
echo "ERROR: Failed to create a board." >&2 | ||
exit 1 | ||
fi | ||
|
||
board_id=$(echo $response | sed -n 's/.*"id":"\([^"]*\)".*/\1/p' ) | ||
} | ||
|
||
#select_target | ||
target=https://bc-6854-basic-load-tests.nbc.dbildungscloud.dev | ||
echo "target: $target" | ||
|
||
|
||
echo $1 | ||
select_scenario | ||
echo "scenario_name: $scenario_name" | ||
|
||
get_token | ||
echo "token: ${token:0:50}..." | ||
|
||
get_course_id | ||
echo "course_id: $course_id" | ||
|
||
create_board_title $scenario_name | ||
echo "board_title: $board_title" | ||
|
||
create_board | ||
echo "board_id $board_id" | ||
|
||
echo "board: $target/rooms/$board_id/board" | ||
echo "Running artillery test..." | ||
|
||
npx artillery run --variables "{\"target\": \"$target\", \"token\": \"$token\", \"board_id\": \"$board_id\" }" "./scenarios/$scenario_name.yml" --output artilleryreport.json | ||
|
||
npx artillery report --output=$board_title.html artilleryreport.json |
75 changes: 75 additions & 0 deletions
75
apps/server/src/modules/board/loadtest/scenarios/30users_5minutes.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
config: | ||
target: '{{ target }}' | ||
engines: | ||
socketio: | ||
transport: ['websocket', 'polling'] | ||
path: '/board-collaboration' | ||
socketio-v3: | ||
path: '/board-collaboration' | ||
timeout: 1000000 | ||
extraHeaders: | ||
Cookie: 'jwt={{ token }}' | ||
|
||
phases: | ||
- duration: 300 | ||
arrivalRate: 10 | ||
maxVusers: 30 | ||
|
||
scenarios: | ||
- name: create card | ||
engine: socketio-v3 | ||
socketio-v3: | ||
extraHeaders: | ||
Cookie: 'jwt={{ token }}' | ||
flow: | ||
- think: 1 | ||
|
||
- emit: | ||
channel: 'fetch-board-request' | ||
data: | ||
boardId: '{{ board_id }}' | ||
|
||
- think: 1 | ||
|
||
- emit: | ||
channel: 'create-column-request' | ||
data: | ||
boardId: '{{ board_id }}' | ||
response: | ||
on: 'create-column-success' | ||
capture: | ||
- json: $.newColumn.id | ||
as: columnId | ||
|
||
- think: 1 | ||
|
||
- loop: | ||
- emit: | ||
channel: 'create-card-request' | ||
data: | ||
columnId: '{{ columnId}}' | ||
response: | ||
on: 'create-card-success' | ||
capture: | ||
- json: $.newCard.id | ||
as: cardId | ||
|
||
- think: 1 | ||
|
||
- emit: | ||
channel: 'fetch-card-request' | ||
data: | ||
cardIds: | ||
- '{{ cardId }}' | ||
|
||
- think: 2 | ||
|
||
- emit: | ||
channel: 'update-card-title-request' | ||
data: | ||
cardId: '{{ cardId }}' | ||
newTitle: 'Card {{ cardId}}' | ||
|
||
- think: 1 | ||
|
||
count: 20 |
57 changes: 57 additions & 0 deletions
57
apps/server/src/modules/board/loadtest/scenarios/3users.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
config: | ||
target: '{{ target }}' | ||
engines: | ||
socketio: | ||
transport: ['websocket', 'polling'] | ||
path: '/board-collaboration' | ||
socketio-v3: | ||
path: '/board-collaboration' | ||
timeout: 1000000 | ||
extraHeaders: | ||
Cookie: 'jwt={{ token }}' | ||
|
||
phases: | ||
- duration: 1 | ||
arrivalRate: 3 | ||
|
||
scenarios: | ||
- name: create card | ||
engine: socketio-v3 | ||
socketio-v3: | ||
extraHeaders: | ||
Cookie: 'jwt={{ token }}' | ||
flow: | ||
- log: '{{ target }}' | ||
- think: 1 | ||
|
||
- emit: | ||
channel: 'create-column-request' | ||
data: | ||
boardId: '{{ board_id }}' | ||
response: | ||
on: 'create-column-success' | ||
capture: | ||
- json: $.newColumn.id | ||
as: columnId | ||
|
||
- think: 1 | ||
|
||
- emit: | ||
channel: 'create-card-request' | ||
data: | ||
columnId: '{{ columnId}}' | ||
response: | ||
on: 'create-card-success' | ||
capture: | ||
- json: $.newCard.id | ||
as: cardId | ||
|
||
- think: 1 | ||
|
||
- emit: | ||
channel: 'update-card-title-request' | ||
data: | ||
cardId: '{{ cardId }}' | ||
newTitle: 'One {{ cardId}}' | ||
|
||
- think: 2 |
70 changes: 70 additions & 0 deletions
70
apps/server/src/modules/board/loadtest/scenarios/6createCard_6UpdateTitle.yml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
config: | ||
target: '{{ target }}' | ||
engines: | ||
socketio: | ||
transport: ['websocket', 'polling'] | ||
path: '/board-collaboration' | ||
socketio-v3: | ||
path: '/board-collaboration' | ||
timeout: 1000000 | ||
extraHeaders: | ||
Cookie: 'jwt={{ token }}' | ||
|
||
phases: | ||
- duration: 2 | ||
arrivalRate: 50 | ||
|
||
scenarios: | ||
- name: create card | ||
engine: socketio-v3 | ||
socketio: | ||
extraHeaders: | ||
Cookie: 'jwt={{ token }}' | ||
socketio-v3: | ||
extraHeaders: | ||
Cookie: 'jwt={{ token }}' | ||
flow: | ||
- think: 1 | ||
|
||
- emit: | ||
channel: 'create-column-request' | ||
data: | ||
boardId: '{{ board_id }}' | ||
response: | ||
on: 'create-column-success' | ||
capture: | ||
- json: $.newColumn.id | ||
as: columnId | ||
|
||
- think: 2 | ||
|
||
- loop: | ||
- emit: | ||
channel: 'create-card-request' | ||
data: | ||
columnId: '{{ columnId}}' | ||
response: | ||
on: 'create-card-success' | ||
capture: | ||
- json: $.newCard.id | ||
as: cardId | ||
|
||
- think: 1 | ||
|
||
- emit: | ||
channel: 'fetch-card-request' | ||
data: | ||
cardIds: | ||
- '{{ cardId }}' | ||
|
||
- think: 2 | ||
|
||
- emit: | ||
channel: 'update-card-title-request' | ||
data: | ||
cardId: '{{ cardId }}' | ||
newTitle: 'Card {{ cardId}}' | ||
|
||
- think: 1 | ||
|
||
count: 6 |