test(session): load tests for session api (#9212)

# Which Problems Are Solved

We currently are not able to benchmark the performance of the session
api

# How the Problems Are Solved

Load tests were added to
- use sessions in oidc tokens analog
https://zitadel.com/docs/guides/integrate/login-ui/oidc-standard

# Additional Context

- Closes https://github.com/zitadel/zitadel/issues/7847
This commit is contained in:
Silvan
2025-01-29 12:08:20 +00:00
committed by GitHub
parent 679ab58fa1
commit b10428fb56
18 changed files with 409 additions and 112 deletions
@@ -0,0 +1,45 @@
import { loginByUsernamePassword } from '../../login_ui';
import { createOrg, removeOrg } from '../../org';
import { User, createHuman } from '../../user';
import { Trend } from 'k6/metrics';
import { Config, MaxVUs } from '../../config';
import { createSession } from '../../session';
import { check } from 'k6';
export async function setup() {
const tokens = loginByUsernamePassword(Config.admin as User);
console.log('setup: admin signed in');
const org = await createOrg(tokens.accessToken!);
console.log(`setup: org (${org.organizationId}) created`);
const humanPromises = Array.from({ length: MaxVUs() }, (_, i) => {
return createHuman(`zitizen-${i}`, org, tokens.accessToken!);
});
const humans = (await Promise.all(humanPromises)).map((user) => {
return { userId: user.userId, loginName: user.loginNames[0], password: 'Password1!' };
});
console.log(`setup: ${humans.length} users created`);
return { tokens, users: humans, org };
}
const addSessionTrend = new Trend('add_session_duration', true);
export default async function (data: any) {
const start = new Date();
const session = await createSession(data.org, data.tokens.accessToken, {
user: {
userId: data.users[__VU - 1].userId,
},
});
check(session, {
'add session is status ok': (s) => s.id !== '',
});
addSessionTrend.add(new Date().getTime() - start.getTime());
}
export function teardown(data: any) {
removeOrg(data.org, data.tokens.accessToken);
}
@@ -0,0 +1,53 @@
import { loginByUsernamePassword, initLogin } from '../../login_ui';
import { createOrg, removeOrg } from '../../org';
import { User, addMachineKey, createMachine } from '../../user';
import { Trend } from 'k6/metrics';
import { Config } from '../../config';
import { check } from 'k6';
import { finalizeAuthRequest, JWTProfileRequest, token } from '../../oidc';
import { createSession } from '../../session';
import encoding from 'k6/encoding';
import { addIAMMember } from '../../membership';
const publicKey = encoding.b64encode(open('../.keys/key.pem.pub'));
export async function setup() {
const adminTokens = loginByUsernamePassword(Config.admin as User);
console.log('setup: admin signed in');
const org = await createOrg(adminTokens.accessToken!);
console.log(`setup: org (${org.organizationId}) created`);
const loginUser = await createMachine('load-test', org, adminTokens.accessToken!);
const loginUserKey = await addMachineKey(loginUser.userId, org, adminTokens.accessToken!, publicKey);
await addIAMMember(loginUser.userId, ['IAM_LOGIN_CLIENT'], adminTokens.accessToken!);
const tokens = await token(new JWTProfileRequest(loginUser.userId, loginUserKey.keyId));
return { tokens, user: loginUser, key: loginUserKey, org, adminTokens };
}
// implements the flow described in
// https://zitadel.com/docs/guides/integrate/login-ui/oidc-standard
const addSessionTrend = new Trend('oidc_session_duration', true);
export default async function (data: any) {
const start = new Date();
const authorizeResponse = initLogin(data.tokens.info.client_id);
const authRequestId = new URLSearchParams(authorizeResponse.headers['Location']).values().next().value;
check(authRequestId, {
'auth request id returned': (s) => s !== '',
});
const session = await createSession(data.org, data.tokens.accessToken, {
user: {
userId: data.user.userId,
},
});
await finalizeAuthRequest(authRequestId!, session, data.tokens!);
addSessionTrend.add(new Date().getTime() - start.getTime());
}
export function teardown(data: any) {
removeOrg(data.org, data.adminTokens.accessToken);
}
@@ -0,0 +1,57 @@
import { loginByUsernamePassword } from '../../login_ui';
import { createOrg, removeOrg } from '../../org';
import { createHuman, setEmailOTPOnHuman, User } from '../../user';
import { Trend } from 'k6/metrics';
import { Config, MaxVUs } from '../../config';
import { createSession, setSession } from '../../session';
export async function setup() {
const tokens = loginByUsernamePassword(Config.admin as User);
console.log('setup: admin signed in');
const org = await createOrg(tokens.accessToken!);
console.log(`setup: org (${org.organizationId}) created`);
const humanPromises = Array.from({ length: MaxVUs() }, (_, i) => {
return createHuman(`zitizen-${i}`, org, tokens.accessToken!);
});
const humans = (await Promise.all(humanPromises)).map((user) => {
setEmailOTPOnHuman(user, org, tokens.accessToken!);
return { userId: user.userId, loginName: user.loginNames[0], password: 'Password1!' };
});
console.log(`setup: ${humans.length} users created`);
return { tokens, org, users: humans };
}
// implements the flow described in
// https://zitadel.com/docs/guides/integrate/login-ui/oidc-standard
const otpSessionTrend = new Trend('otp_session_duration', true);
export default async function (data: any) {
const start = new Date();
let session = await createSession(data.org, data.tokens.accessToken, {
user: {
loginName: data.users[__VU - 1].loginName,
},
});
const sessionId = (session as any).sessionId;
session = await setSession(sessionId, session, data.tokens.accessToken, {
otpEmail: {
return_code: {},
},
});
session = await setSession(sessionId, session, data.tokens.accessToken, null, {
otpEmail: {
code: session.challenges.otpEmail,
},
});
otpSessionTrend.add(new Date().getTime() - start.getTime());
}
export function teardown(data: any) {
removeOrg(data.org, data.tokens.accessToken);
}
@@ -0,0 +1,49 @@
import { loginByUsernamePassword } from '../../login_ui';
import { createOrg, removeOrg } from '../../org';
import { createHuman, setEmailOTPOnHuman, User } from '../../user';
import { Trend } from 'k6/metrics';
import { Config, MaxVUs } from '../../config';
import { createSession, setSession } from '../../session';
export async function setup() {
const tokens = loginByUsernamePassword(Config.admin as User);
console.log('setup: admin signed in');
const org = await createOrg(tokens.accessToken!);
console.log(`setup: org (${org.organizationId}) created`);
const humanPromises = Array.from({ length: MaxVUs() }, (_, i) => {
return createHuman(`zitizen-${i}`, org, tokens.accessToken!);
});
const humans = (await Promise.all(humanPromises)).map((user) => {
setEmailOTPOnHuman(user, org, tokens.accessToken!);
return { userId: user.userId, loginName: user.loginNames[0], password: 'Password1!' };
});
console.log(`setup: ${humans.length} users created`);
return { tokens, org, users: humans };
}
const passwordSessionTrend = new Trend('password_session_duration', true);
export default async function (data: any) {
const start = new Date();
let session = await createSession(data.org, data.tokens.accessToken, {
user: {
loginName: data.users[__VU - 1].loginName,
},
});
const sessionId = (session as any).sessionId;
session = await setSession(sessionId, session, data.tokens.accessToken, null, {
password: {
password: data.users[__VU - 1].password,
},
});
passwordSessionTrend.add(new Date().getTime() - start.getTime());
}
export function teardown(data: any) {
removeOrg(data.org, data.tokens.accessToken);
}