init benchmarks
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
This commit is contained in:
6
.gitignore
vendored
6
.gitignore
vendored
@ -209,3 +209,9 @@ source_docs/
|
|||||||
|
|
||||||
### Golang ###
|
### Golang ###
|
||||||
/vendor/
|
/vendor/
|
||||||
|
|
||||||
|
### Benchmark ###
|
||||||
|
tests/benchmark/k6
|
||||||
|
tests/benchmark/**/*.json
|
||||||
|
tests/benchmark/**/*.ndjson
|
||||||
|
tests/benchmark/**/*.html
|
||||||
|
|||||||
9
Makefile
9
Makefile
@ -278,3 +278,12 @@ ci-bandit: ci--meta-debug
|
|||||||
|
|
||||||
ci-pending-migrations: ci--meta-debug
|
ci-pending-migrations: ci--meta-debug
|
||||||
ak makemigrations --check
|
ak makemigrations --check
|
||||||
|
|
||||||
|
#########################
|
||||||
|
## Benchmark
|
||||||
|
#########################
|
||||||
|
|
||||||
|
benchmark-install:
|
||||||
|
cd tests/benchmark
|
||||||
|
go install go.k6.io/xk6/cmd/xk6@latest
|
||||||
|
$$(go env GOPATH)/bin/xk6 build latest --with github.com/grafana/xk6-exec@latest
|
||||||
|
|||||||
@ -4,6 +4,7 @@ services:
|
|||||||
postgresql:
|
postgresql:
|
||||||
container_name: postgres
|
container_name: postgres
|
||||||
image: docker.io/library/postgres:16
|
image: docker.io/library/postgres:16
|
||||||
|
command: "-c max_connections=500"
|
||||||
volumes:
|
volumes:
|
||||||
- db-data:/var/lib/postgresql/data
|
- db-data:/var/lib/postgresql/data
|
||||||
environment:
|
environment:
|
||||||
|
|||||||
0
tests/benchmark/__init__.py
Normal file
0
tests/benchmark/__init__.py
Normal file
9
tests/benchmark/create_users.py
Executable file
9
tests/benchmark/create_users.py
Executable file
@ -0,0 +1,9 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from uuid import uuid4
|
||||||
|
|
||||||
|
from tests.benchmark.init import *
|
||||||
|
|
||||||
|
while User.objects.count() < int(sys.argv[1]):
|
||||||
|
User.objects.create(username=uuid4(), name=uuid4())
|
||||||
7
tests/benchmark/delete_users.py
Executable file
7
tests/benchmark/delete_users.py
Executable file
@ -0,0 +1,7 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from uuid import uuid4
|
||||||
|
|
||||||
|
from tests.benchmark.init import *
|
||||||
|
|
||||||
|
User.objects.exclude_anonymous().exclude(username="akadmin").delete()
|
||||||
8
tests/benchmark/init.py
Normal file
8
tests/benchmark/init.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
from os import environ
|
||||||
|
|
||||||
|
import django
|
||||||
|
|
||||||
|
environ.setdefault("DJANGO_SETTINGS_MODULE", "authentik.root.settings")
|
||||||
|
django.setup()
|
||||||
|
|
||||||
|
from authentik.core.models import User
|
||||||
30
tests/benchmark/run.sh
Executable file
30
tests/benchmark/run.sh
Executable file
@ -0,0 +1,30 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
BASE_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd)"
|
||||||
|
|
||||||
|
function _k6 {
|
||||||
|
local filename="${1}"
|
||||||
|
|
||||||
|
"${BASE_DIR}/k6" \
|
||||||
|
run \
|
||||||
|
--out "web-dashboard=port=-1&report=${filename%.*}.html&period=1s&tag=name&tag=group&tag=user_count&tag=page_size" \
|
||||||
|
--out "json=${filename%.*}.json" \
|
||||||
|
"${@}"
|
||||||
|
}
|
||||||
|
|
||||||
|
filename=""
|
||||||
|
if [ "${#}" -ge 1 ]; then
|
||||||
|
filename="${1:-}"
|
||||||
|
shift
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
if [ -f "${filename}" ]; then
|
||||||
|
_k6 "${filename}" "${@}"
|
||||||
|
else
|
||||||
|
find "${BASE_DIR}" -name '*.js' | while read -r f; do
|
||||||
|
_k6 "${f}" "${@}"
|
||||||
|
done
|
||||||
|
fi
|
||||||
74
tests/benchmark/user_list.js
Executable file
74
tests/benchmark/user_list.js
Executable file
@ -0,0 +1,74 @@
|
|||||||
|
import exec from "k6/execution";
|
||||||
|
import { command } from "k6/x/exec";
|
||||||
|
import http from "k6/http";
|
||||||
|
import { check, group } from "k6";
|
||||||
|
|
||||||
|
export const options = {
|
||||||
|
discardResponseBodies: true,
|
||||||
|
scenarios: Object.fromEntries(
|
||||||
|
[
|
||||||
|
[10, 20],
|
||||||
|
[100, 20],
|
||||||
|
[1000, 20],
|
||||||
|
[10000, 20],
|
||||||
|
[10, 100],
|
||||||
|
[100, 100],
|
||||||
|
[1000, 100],
|
||||||
|
[10000, 100],
|
||||||
|
].map((obj, i) => [
|
||||||
|
`${obj[0]}_${obj[1]}`,
|
||||||
|
{
|
||||||
|
executor: "constant-vus",
|
||||||
|
vus: 10,
|
||||||
|
duration: "10s",
|
||||||
|
startTime: `${10 * i}s`,
|
||||||
|
env: {
|
||||||
|
USER_COUNT: `${obj[0]}`,
|
||||||
|
PAGE_SIZE: `${obj[1]}`,
|
||||||
|
},
|
||||||
|
tags: {
|
||||||
|
user_count: `${obj[0]}`,
|
||||||
|
page_size: `${obj[1]}`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]),
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
export function setup() {
|
||||||
|
command("./create_users.py", ["11000"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function teardown() {
|
||||||
|
command("./delete_users.py");
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function () {
|
||||||
|
const user_count = Number(__ENV.USER_COUNT);
|
||||||
|
const page_size = Number(__ENV.PAGE_SIZE);
|
||||||
|
const pages = Math.round(user_count / 20);
|
||||||
|
let requests = [];
|
||||||
|
for (let page = 1; page <= pages; page++) {
|
||||||
|
requests.push([
|
||||||
|
"GET",
|
||||||
|
`http://localhost:9000/api/v3/core/users/?page=${page}&page_size=${page_size}`,
|
||||||
|
null,
|
||||||
|
{
|
||||||
|
headers: {
|
||||||
|
Authorization: "Bearer akadmin",
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
Accept: "*/*",
|
||||||
|
},
|
||||||
|
tags: {
|
||||||
|
name: "/core/users/",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
const responses = http.batch(requests);
|
||||||
|
for (let page = 1; page <= pages; page++) {
|
||||||
|
check(responses[page - 1], {
|
||||||
|
"status is 200": (res) => res.status === 200,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user