add group and event list

Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
This commit is contained in:
Marc 'risson' Schmitt
2024-04-18 17:05:40 +02:00
parent 71fe8b4fb3
commit 77fe4e9fe2
4 changed files with 284 additions and 18 deletions

View File

@ -0,0 +1,79 @@
import exec from "k6/execution";
import http from "k6/http";
import { check } from "k6";
const host = __ENV.BENCH_HOST ? __ENV.BENCH_HOST : "localhost";
const VUs = __ENV.VUS ? __ENV.VUS : 8;
export const options = {
discardResponseBodies: true,
scenarios: Object.fromEntries(
[
// Number of events, page size
[1000, 100],
[10000, 20],
[10000, 100],
[100000, 100],
[1000000, 100],
].map((obj, i) => [
`${obj[0]}_${obj[1]}`,
{
executor: "constant-vus",
vus: VUs,
duration: "300s",
startTime: `${315 * i}s`,
env: {
EVENT_COUNT: `${obj[0]}`,
PAGE_SIZE: `${obj[1]}`,
},
tags: {
testid: `event_list_${obj[0]}_${obj[1]}`,
event_count: `${obj[0]}`,
page_size: `${obj[1]}`,
},
},
]),
),
};
export default function () {
const event_count = Number(__ENV.EVENT_COUNT);
const domain = `event-list-${event_count}.${host}:9000`;
const page_size = Number(__ENV.PAGE_SIZE);
const pages = Math.round(event_count / page_size);
const params = {
headers: {
Authorization: "Bearer akadmin",
"Content-Type": "application/json",
Accept: "*/*",
},
};
if (pages <= 10) {
for (let page = 1; page <= pages; page++) {
let res = http.get(
http.url`http://${domain}/api/v3/events/events/?page=${page}&page_size=${page_size}`,
params,
);
check(res, {
"status is 200": (res) => res.status === 200,
});
}
} else {
let requests = [];
for (let page = 1; page <= pages; page++) {
requests.push([
"GET",
http.url`http://${domain}/api/v3/events/events/?page=${page}&page_size=${page_size}`,
null,
params,
]);
}
const responses = http.batch(requests);
for (let page = 1; page <= pages; page++) {
check(responses[page - 1], {
"status is 200": (res) => res.status === 200,
});
}
}
}

View File

@ -16,6 +16,7 @@ from django.conf import settings
from authentik.core.models import Application, Group, User
from authentik.crypto.models import CertificateKeyPair
from authentik.events.models import Event, EventAction
from authentik.flows.models import Flow
from authentik.policies.expression.models import ExpressionPolicy
from authentik.policies.models import PolicyBinding
@ -31,17 +32,12 @@ host = environ.get("BENCH_HOST", "localhost")
def user_list():
# Number of users, groups per user, parents per groups
tenants = [
(10, 0, 0),
(100, 0, 0),
(1000, 0, 0),
(10000, 0, 0),
(100, 3, 0),
(1000, 3, 0),
(10000, 3, 0),
(100, 20, 0),
(1000, 20, 0),
(10000, 20, 0),
(100, 20, 3),
(1000, 20, 3),
(10000, 20, 3),
]
@ -88,6 +84,62 @@ def user_list():
)
def group_list():
# Number of groups, users per group, with_parent
tenants = [
(1000, 0, False),
(10000, 0, False),
(1000, 1000, False),
(1000, 10000, False),
(1000, 0, True),
(10000, 0, True),
]
for tenant in tenants:
group_count = tenant[0]
users_per_group = tenant[1]
with_parent = tenant[2]
tenant_name = f"group-list-{group_count}-{users_per_group}-{str(with_parent).lower()}"
schema_name = f"t_{tenant_name.replace('-', '_')}"
created = False
t = Tenant.objects.filter(schema_name=schema_name).first()
if not t:
created = True
t = Tenant.objects.create(schema_name=schema_name, name=uuid4())
Domain.objects.get_or_create(tenant=t, domain=f"{tenant_name}.{host}")
if not created:
continue
with t:
User.objects.bulk_create(
[
User(
username=uuid4(),
name=uuid4(),
)
for _ in range(users_per_group * 5)
]
)
if with_parent:
parents = Group.objects.bulk_create(
[Group(name=uuid4()) for _ in range(group_count)]
)
groups = Group.objects.bulk_create(
[
Group(name=uuid4(), parent=(parents[i] if with_parent else None))
for i in range(group_count)
]
)
if users_per_group:
for group in groups:
group.users.set(
User.objects.exclude_anonymous()
.exclude(username="akadmin")
.order_by("?")[:users_per_group]
)
def login():
schema_name = f"t_login_no_mfa"
created = False
@ -226,6 +278,55 @@ def provider_oauth2():
)
def event_list():
tenants = [
# Number of events
1_000,
10_000,
100_000,
1_000_000,
]
for tenant in tenants:
event_count = tenant
tenant_name = f"event-list-{event_count}"
schema_name = f"t_{tenant_name.replace('-', '_')}"
created = False
t = Tenant.objects.filter(schema_name=schema_name).first()
if not t:
created = True
t = Tenant.objects.create(schema_name=schema_name, name=uuid4())
Domain.objects.get_or_create(tenant=t, domain=f"{tenant_name}.{host}")
if not created:
continue
with t:
Event.objects.bulk_create(
[
Event(
user={
"pk": str(uuid4()),
"name": str(uuid4()),
"username": str(uuid4()),
"email": f"{uuid4()}@example.org",
},
action="custom_benchmark",
app="tests_benchmarks",
context={
str(uuid4()): str(uuid4()),
str(uuid4()): str(uuid4()),
str(uuid4()): str(uuid4()),
str(uuid4()): str(uuid4()),
str(uuid4()): str(uuid4()),
},
client_ip="192.0.2.42",
)
for _ in range(event_count)
]
)
def delete():
Tenant.objects.exclude(schema_name="public").delete()
@ -233,9 +334,11 @@ def delete():
def main(action: str):
match action:
case "create":
user_list()
login()
provider_oauth2()
# login()
# provider_oauth2()
# user_list()
group_list()
event_list()
case "delete":
delete()
case _:

View File

@ -0,0 +1,93 @@
import exec from "k6/execution";
import http from "k6/http";
import { check } from "k6";
const host = __ENV.BENCH_HOST ? __ENV.BENCH_HOST : "localhost";
const VUs = __ENV.VUS ? __ENV.VUS : 8;
export const options = {
discardResponseBodies: true,
scenarios: Object.fromEntries(
[
// Number of groups, number of users per group, with parent, page size, include users
[1000, 0, false, 20, false],
[10000, 0, false, 20, false],
[1000, 0, false, 100, false],
[10000, 0, false, 100, false],
[1000, 1000, false, 100, false],
[10000, 10000, false, 100, false],
[1000, 1000, false, 100, true],
[10000, 10000, false, 100, true],
[1000, 0, true, 100, false],
[10000, 0, true, 100, false],
].map((obj, i) => [
`${obj[0]}_${obj[1]}_${obj[2] ? "with_parents" : "without_parents"}_${obj[3]}_${obj[4] ? "with_users" : "without_users"}`,
{
executor: "constant-vus",
vus: VUs,
duration: "300s",
startTime: `${315 * i}s`,
env: {
GROUP_COUNT: `${obj[0]}`,
USERS_PER_GROUP: `${obj[1]}`,
WITH_PARENTS: `${obj[2]}`,
PAGE_SIZE: `${obj[3]}`,
WITH_USERS: `${obj[4]}`,
},
tags: {
testid: `group_list_${obj[0]}_${obj[1]}_${obj[2] ? "with_parents" : "without_parents"}_${obj[3]}_${obj[4] ? "with_users" : "without_users"}`,
group_count: `${obj[0]}`,
users_per_group: `${obj[1]}`,
with_parents: `${obj[2]}`,
page_size: `${obj[3]}`,
with_users: `${obj[4]}`,
},
},
]),
),
};
export default function () {
const group_count = Number(__ENV.GROUP_COUNT);
const users_per_group = Number(__ENV.USERS_PER_GROUP);
const with_parents = __ENV.WITH_PARENTS;
const with_users = Number(__ENV.WITH_USERS);
const domain = `group-list-${group_count}-${users_per_group}-${with_parents}.${host}:9000`;
const page_size = Number(__ENV.PAGE_SIZE);
const pages = Math.round(group_count / page_size);
const params = {
headers: {
Authorization: "Bearer akadmin",
"Content-Type": "application/json",
Accept: "*/*",
},
};
if (pages <= 10) {
for (let page = 1; page <= pages; page++) {
let res = http.get(
http.url`http://${domain}/api/v3/core/groups/?page=${page}&page_size=${page_size}&include_users=${with_users}`,
params,
);
check(res, {
"status is 200": (res) => res.status === 200,
});
}
} else {
let requests = [];
for (let page = 1; page <= pages; page++) {
requests.push([
"GET",
http.url`http://${domain}/api/v3/core/groups/?page=${page}&page_size=${page_size}&include_users=${with_users}`,
null,
params,
]);
}
const responses = http.batch(requests);
for (let page = 1; page <= pages; page++) {
check(responses[page - 1], {
"status is 200": (res) => res.status === 200,
});
}
}
}

View File

@ -10,29 +10,20 @@ export const options = {
scenarios: Object.fromEntries(
[
// Number of users, number of groups per user, number of parents per group, page size, with groups
[10, 0, 0, 20, true],
[100, 0, 0, 20, true],
[1000, 0, 0, 20, true],
[10000, 0, 0, 20, true],
[1000, 0, 0, 20, false],
[10000, 0, 0, 20, false],
[10, 0, 0, 100, true],
[100, 0, 0, 100, true],
[1000, 0, 0, 100, true],
[10000, 0, 0, 100, true],
[100, 3, 0, 20, true],
[1000, 3, 0, 20, true],
[10000, 3, 0, 20, true],
[100, 20, 0, 20, true],
[1000, 20, 0, 20, true],
[10000, 20, 0, 20, true],
[100, 20, 3, 20, true],
[1000, 20, 3, 20, true],
[10000, 20, 3, 20, true],
[100, 20, 0, 20, false],
[1000, 20, 0, 20, false],
[10000, 20, 0, 20, false],
[100, 20, 3, 20, false],
[1000, 20, 3, 20, false],
[10000, 20, 3, 20, false],
].map((obj, i) => [
@ -80,7 +71,7 @@ export default function () {
if (pages <= 10) {
for (let page = 1; page <= pages; page++) {
let res = requests.get(
let res = http.get(
http.url`http://${domain}/api/v3/core/users/?page=${page}&page_size=${page_size}&include_groups=${with_groups}`,
params,
);