aded k6 and script and updated code with better logic and indexing on schema
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
import http from 'k6/http';
|
||||
import { check } from 'k6';
|
||||
import { Counter } from 'k6/metrics';
|
||||
|
||||
const seed = JSON.parse(open('./seed-data.json'));
|
||||
const BASE_URL = __ENV.BASE_URL || 'http://app:3000';
|
||||
|
||||
const successfulBookings = new Counter('successful_bookings');
|
||||
|
||||
export const options = {
|
||||
scenarios: {
|
||||
concurrent_booking: {
|
||||
executor: 'per-vu-iterations',
|
||||
vus: 10,
|
||||
iterations: 1,
|
||||
maxDuration: '30s',
|
||||
},
|
||||
},
|
||||
thresholds: {
|
||||
successful_bookings: ['count==1'],
|
||||
},
|
||||
};
|
||||
|
||||
export default function () {
|
||||
const session = seed.sessions[0];
|
||||
const user = seed.users[__VU - 1];
|
||||
|
||||
const response = http.post(
|
||||
`${BASE_URL}/sessions/${session.id}/book`,
|
||||
JSON.stringify({ userId: user.id }),
|
||||
{
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
responseCallback: http.expectedStatuses(200, 400),
|
||||
}
|
||||
);
|
||||
|
||||
if (response.status === 200) {
|
||||
successfulBookings.add(1);
|
||||
}
|
||||
|
||||
check(response, {
|
||||
'booking returned expected status': (r) =>
|
||||
r.status === 200 || r.status === 400,
|
||||
});
|
||||
|
||||
console.log(
|
||||
`VU ${__VU}: status=${response.status}, session=${session.id}`
|
||||
);
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
import http from 'k6/http';
|
||||
import { check, sleep } from 'k6';
|
||||
|
||||
const BASE_URL = __ENV.BASE_URL || 'http://app:3000';
|
||||
const seed = JSON.parse(open('./seed-data.json'));
|
||||
|
||||
export const options = {
|
||||
stages: [
|
||||
{ duration: '15s', target: 1 },
|
||||
{ duration: '20s', target: 3 },
|
||||
{ duration: '20s', target: 5 },
|
||||
{ duration: '10s', target: 0 },
|
||||
],
|
||||
thresholds: {
|
||||
http_req_failed: ['rate<0.01'],
|
||||
http_req_duration: ['p(95)<500'],
|
||||
checks: ['rate>0.99'],
|
||||
},
|
||||
};
|
||||
|
||||
export default function () {
|
||||
const user = seed.users[(__VU + __ITER) % seed.users.length];
|
||||
const session =
|
||||
seed.sessions[(__VU + __ITER) % seed.sessions.length];
|
||||
|
||||
const requests = [
|
||||
['users', `${BASE_URL}/users/`],
|
||||
['teachers', `${BASE_URL}/teachers/`],
|
||||
[
|
||||
'available sessions',
|
||||
`${BASE_URL}/sessions/available?dateTimestamp=${encodeURIComponent(session.dateTimestamp)}`,
|
||||
],
|
||||
[
|
||||
'user session history',
|
||||
`${BASE_URL}/sessions/${user.id}/sessions`,
|
||||
],
|
||||
];
|
||||
|
||||
for (const [name, url] of requests) {
|
||||
const response = http.get(url);
|
||||
|
||||
check(response, {
|
||||
[`${name}: HTTP 200`]: (r) => r.status === 200,
|
||||
[`${name}: JSON response`]: (r) =>
|
||||
r.headers['Content-Type']?.includes('application/json'),
|
||||
});
|
||||
}
|
||||
|
||||
sleep(1);
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
import http from 'k6/http';
|
||||
import { check, sleep } from 'k6';
|
||||
import { Counter } from 'k6/metrics';
|
||||
|
||||
const BASE_URL = __ENV.BASE_URL || 'http://app:3000';
|
||||
const seed = JSON.parse(open('./seed-data.json'));
|
||||
|
||||
const writeFailures = new Counter('write_failures');
|
||||
|
||||
export const options = {
|
||||
stages: [
|
||||
{ duration: '20s', target: 50 },
|
||||
{ duration: '20s', target: 100 },
|
||||
{ duration: '30s', target: 150 },
|
||||
{ duration: '30s', target: 200 },
|
||||
{ duration: '30s', target: 250 },
|
||||
{ duration: '30s', target: 300 },
|
||||
{ duration: '30s', target: 350 },
|
||||
{ duration: '30s', target: 400 },
|
||||
{ duration: '20s', target: 0 },
|
||||
],
|
||||
thresholds: {
|
||||
http_req_failed: ['rate<0.02'],
|
||||
http_req_duration: ['p(95)<500'],
|
||||
write_failures: ['count==0'],
|
||||
},
|
||||
};
|
||||
|
||||
export default function () {
|
||||
const unique = `${__VU}-${__ITER}-${Date.now()}`;
|
||||
const startTime = new Date(Date.now() + 60 * 60 * 1000);
|
||||
const endTime = new Date(startTime.getTime() + 30 * 60 * 1000);
|
||||
|
||||
// 1. Insert a new user
|
||||
const userResponse = http.post(
|
||||
`${BASE_URL}/users/`,
|
||||
JSON.stringify({
|
||||
fullName: `Load Test ${unique}`,
|
||||
email: `load-${unique}@example.invalid`,
|
||||
phone: `9${String(__VU).padStart(1, '0')}${String(__ITER).padStart(8, '0')}`.slice(0, 10),
|
||||
}),
|
||||
{ headers: { 'Content-Type': 'application/json' }, tags: { name: 'POST /users' } }
|
||||
);
|
||||
|
||||
const userOk = check(userResponse, {
|
||||
'user inserted (201)': (r) => r.status === 201,
|
||||
});
|
||||
|
||||
if (!userOk) {
|
||||
writeFailures.add(1);
|
||||
return;
|
||||
}
|
||||
|
||||
const userId = userResponse.json('result._id');
|
||||
|
||||
// 2. Insert a session for the existing seeded teacher
|
||||
const sessionResponse = http.post(
|
||||
`${BASE_URL}/sessions/`,
|
||||
JSON.stringify({
|
||||
teacherId: seed.teacher.id,
|
||||
startTime: startTime.toISOString(),
|
||||
endTime: endTime.toISOString(),
|
||||
}),
|
||||
{ headers: { 'Content-Type': 'application/json' }, tags: { name: 'POST /sessions' } }
|
||||
);
|
||||
|
||||
const sessionOk = check(sessionResponse, {
|
||||
'session inserted (201)': (r) => r.status === 201,
|
||||
});
|
||||
|
||||
if (!sessionOk) {
|
||||
writeFailures.add(1);
|
||||
return;
|
||||
}
|
||||
|
||||
const sessionId = sessionResponse.json('result._id');
|
||||
|
||||
// 3. Book the newly created session
|
||||
const bookingResponse = http.post(
|
||||
`${BASE_URL}/sessions/${sessionId}/book`,
|
||||
JSON.stringify({ userId }),
|
||||
{ headers: { 'Content-Type': 'application/json' }, tags: { name: 'POST /sessions/:id/book' } }
|
||||
);
|
||||
|
||||
const bookingOk = check(bookingResponse, {
|
||||
'session booked (200)': (r) => r.status === 200,
|
||||
});
|
||||
|
||||
if (!bookingOk) {
|
||||
writeFailures.add(1);
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. Complete the booked session
|
||||
const completeResponse = http.patch(
|
||||
`${BASE_URL}/sessions/${sessionId}/complete`,
|
||||
null,
|
||||
{ tags: { name: 'PATCH /sessions/:id/complete' } }
|
||||
);
|
||||
|
||||
const completeOk = check(completeResponse, {
|
||||
'session completed (200)': (r) => r.status === 200,
|
||||
});
|
||||
|
||||
if (!completeOk) {
|
||||
writeFailures.add(1);
|
||||
return;
|
||||
}
|
||||
|
||||
// 5. Read user session history
|
||||
const historyResponse = http.get(
|
||||
`${BASE_URL}/sessions/${userId}/sessions`,
|
||||
{ tags: { name: 'GET /sessions/:userId/sessions' } }
|
||||
);
|
||||
|
||||
check(historyResponse, {
|
||||
'user history returned (200)': (r) => r.status === 200,
|
||||
});
|
||||
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
export function handleSummary(data) {
|
||||
return {
|
||||
'/results/endpoint-summary.json': JSON.stringify(data, null, 2),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
|
||||
import http from 'k6/http';
|
||||
import { check, sleep } from 'k6';
|
||||
import { Counter } from 'k6/metrics';
|
||||
|
||||
const BASE_URL = __ENV.BASE_URL || 'http://app:3000';
|
||||
const seed = JSON.parse(open('./seed-data.json'));
|
||||
|
||||
const writeFailures = new Counter('write_failures');
|
||||
|
||||
export const options = {
|
||||
stages: [
|
||||
{ duration: '20s', target: 50 },
|
||||
{ duration: '20s', target: 100 },
|
||||
{ duration: '30s', target: 150 },
|
||||
{ duration: '30s', target: 200 },
|
||||
{ duration: '30s', target: 250 },
|
||||
{ duration: '30s', target: 300 },
|
||||
{ duration: '30s', target: 350 },
|
||||
{ duration: '30s', target: 400 },
|
||||
{ duration: '20s', target: 0 },
|
||||
],
|
||||
thresholds: {
|
||||
http_req_failed: ['rate<0.02'],
|
||||
http_req_duration: ['p(95)<500'],
|
||||
write_failures: ['count==0'],
|
||||
},
|
||||
};
|
||||
|
||||
export default function () {
|
||||
const unique = `${__VU}-${__ITER}-${Date.now()}`;
|
||||
const startTime = new Date(Date.now() + 60 * 60 * 1000);
|
||||
const endTime = new Date(startTime.getTime() + 30 * 60 * 1000);
|
||||
|
||||
// 1. Insert a new user
|
||||
const userResponse = http.post(
|
||||
`${BASE_URL}/users/`,
|
||||
JSON.stringify({
|
||||
fullName: `Load Test ${unique}`,
|
||||
email: `load-${unique}@example.invalid`,
|
||||
phone: `9${String(__VU).padStart(1, '0')}${String(__ITER).padStart(8, '0')}`.slice(0, 10),
|
||||
}),
|
||||
{ headers: { 'Content-Type': 'application/json' }, tags: { name: 'POST /users' } }
|
||||
);
|
||||
|
||||
const userOk = check(userResponse, {
|
||||
'user inserted (201)': (r) => r.status === 201,
|
||||
});
|
||||
|
||||
if (!userOk) {
|
||||
writeFailures.add(1);
|
||||
return;
|
||||
}
|
||||
|
||||
const userId = userResponse.json('result._id');
|
||||
|
||||
// 2. Insert a session for the existing seeded teacher
|
||||
const sessionResponse = http.post(
|
||||
`${BASE_URL}/sessions/`,
|
||||
JSON.stringify({
|
||||
teacherId: seed.teacher.id,
|
||||
startTime: startTime.toISOString(),
|
||||
endTime: endTime.toISOString(),
|
||||
}),
|
||||
{ headers: { 'Content-Type': 'application/json' }, tags: { name: 'POST /sessions' } }
|
||||
);
|
||||
|
||||
const sessionOk = check(sessionResponse, {
|
||||
'session inserted (201)': (r) => r.status === 201,
|
||||
});
|
||||
|
||||
if (!sessionOk) {
|
||||
writeFailures.add(1);
|
||||
return;
|
||||
}
|
||||
|
||||
const sessionId = sessionResponse.json('result._id');
|
||||
|
||||
// 3. Book the newly created session
|
||||
const bookingResponse = http.post(
|
||||
`${BASE_URL}/sessions/${sessionId}/book`,
|
||||
JSON.stringify({ userId }),
|
||||
{ headers: { 'Content-Type': 'application/json' }, tags: { name: 'POST /sessions/:id/book' } }
|
||||
);
|
||||
|
||||
const bookingOk = check(bookingResponse, {
|
||||
'session booked (200)': (r) => r.status === 200,
|
||||
});
|
||||
|
||||
if (!bookingOk) {
|
||||
writeFailures.add(1);
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. Complete the booked session
|
||||
const completeResponse = http.patch(
|
||||
`${BASE_URL}/sessions/${sessionId}/complete`,
|
||||
null,
|
||||
{ tags: { name: 'PATCH /sessions/:id/complete' } }
|
||||
);
|
||||
|
||||
const completeOk = check(completeResponse, {
|
||||
'session completed (200)': (r) => r.status === 200,
|
||||
});
|
||||
|
||||
if (!completeOk) {
|
||||
writeFailures.add(1);
|
||||
return;
|
||||
}
|
||||
|
||||
// 5. Read user session history
|
||||
const historyResponse = http.get(
|
||||
`${BASE_URL}/sessions/${userId}/sessions`,
|
||||
{ tags: { name: 'GET /sessions/:userId/sessions' } }
|
||||
);
|
||||
|
||||
check(historyResponse, {
|
||||
'user history returned (200)': (r) => r.status === 200,
|
||||
});
|
||||
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
export function handleSummary(data) {
|
||||
return {
|
||||
'/results/endpoint-summary.json': JSON.stringify(data, null, 2),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,130 @@
|
||||
|
||||
import http from 'k6/http';
|
||||
import { check, sleep } from 'k6';
|
||||
import { Counter } from 'k6/metrics';
|
||||
import { textSummary } from 'https://jslib.k6.io/k6-summary/0.0.1/index.js';
|
||||
|
||||
const BASE_URL = __ENV.BASE_URL || 'http://app:3000';
|
||||
const seed = JSON.parse(open('./seed-data.json'));
|
||||
|
||||
const writeFailures = new Counter('write_failures');
|
||||
|
||||
export const options = {
|
||||
stages: [
|
||||
{ duration: '20s', target: 100 },
|
||||
{ duration: '20s', target: 200 },
|
||||
{ duration: '30s', target: 300 },
|
||||
{ duration: '30s', target: 400 },
|
||||
{ duration: '30s', target: 450 },
|
||||
{ duration: '30s', target: 500 },
|
||||
{ duration: '30s', target: 550 },
|
||||
{ duration: '30s', target: 600 },
|
||||
{ duration: '20s', target: 0 },
|
||||
],
|
||||
thresholds: {
|
||||
http_req_failed: ['rate<0.02'],
|
||||
http_req_duration: ['p(95)<500'],
|
||||
write_failures: ['count==0'],
|
||||
},
|
||||
};
|
||||
|
||||
export default function () {
|
||||
const unique = `${__VU}-${__ITER}-${Date.now()}`;
|
||||
const startTime = new Date(Date.now() + 60 * 60 * 1000);
|
||||
const endTime = new Date(startTime.getTime() + 30 * 60 * 1000);
|
||||
|
||||
// 1. Insert a new user
|
||||
const userResponse = http.post(
|
||||
`${BASE_URL}/users/`,
|
||||
JSON.stringify({
|
||||
fullName: `Load Test ${unique}`,
|
||||
email: `load-${unique}@example.invalid`,
|
||||
phone: `9${String(__VU).padStart(1, '0')}${String(__ITER).padStart(8, '0')}`.slice(0, 10),
|
||||
}),
|
||||
{ headers: { 'Content-Type': 'application/json' }, tags: { name: 'POST /users' } }
|
||||
);
|
||||
|
||||
const userOk = check(userResponse, {
|
||||
'user inserted (201)': (r) => r.status === 201,
|
||||
});
|
||||
|
||||
if (!userOk) {
|
||||
writeFailures.add(1);
|
||||
return;
|
||||
}
|
||||
|
||||
const userId = userResponse.json('result._id');
|
||||
|
||||
// 2. Insert a session for the existing seeded teacher
|
||||
const sessionResponse = http.post(
|
||||
`${BASE_URL}/sessions/`,
|
||||
JSON.stringify({
|
||||
teacherId: seed.teacher.id,
|
||||
startTime: startTime.toISOString(),
|
||||
endTime: endTime.toISOString(),
|
||||
}),
|
||||
{ headers: { 'Content-Type': 'application/json' }, tags: { name: 'POST /sessions' } }
|
||||
);
|
||||
|
||||
const sessionOk = check(sessionResponse, {
|
||||
'session inserted (201)': (r) => r.status === 201,
|
||||
});
|
||||
|
||||
if (!sessionOk) {
|
||||
writeFailures.add(1);
|
||||
return;
|
||||
}
|
||||
|
||||
const sessionId = sessionResponse.json('result._id');
|
||||
|
||||
// 3. Book the newly created session
|
||||
const bookingResponse = http.post(
|
||||
`${BASE_URL}/sessions/${sessionId}/book`,
|
||||
JSON.stringify({ userId }),
|
||||
{ headers: { 'Content-Type': 'application/json' }, tags: { name: 'POST /sessions/:id/book' } }
|
||||
);
|
||||
|
||||
const bookingOk = check(bookingResponse, {
|
||||
'session booked (200)': (r) => r.status === 200,
|
||||
});
|
||||
|
||||
if (!bookingOk) {
|
||||
writeFailures.add(1);
|
||||
return;
|
||||
}
|
||||
|
||||
// 4. Complete the booked session
|
||||
const completeResponse = http.patch(
|
||||
`${BASE_URL}/sessions/${sessionId}/complete`,
|
||||
null,
|
||||
{ tags: { name: 'PATCH /sessions/:id/complete' } }
|
||||
);
|
||||
|
||||
const completeOk = check(completeResponse, {
|
||||
'session completed (200)': (r) => r.status === 200,
|
||||
});
|
||||
|
||||
if (!completeOk) {
|
||||
writeFailures.add(1);
|
||||
return;
|
||||
}
|
||||
|
||||
// 5. Read user session history
|
||||
const historyResponse = http.get(
|
||||
`${BASE_URL}/sessions/${userId}/sessions`,
|
||||
{ tags: { name: 'GET /sessions/:userId/sessions' } }
|
||||
);
|
||||
|
||||
check(historyResponse, {
|
||||
'user history returned (200)': (r) => r.status === 200,
|
||||
});
|
||||
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
export function handleSummary(data) {
|
||||
return {
|
||||
stdout: textSummary(data, { indent: ' ', enableColors: true }),
|
||||
'/results/endpoint-summary.json': JSON.stringify(data, null, 2),
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,392 @@
|
||||
{
|
||||
"generatedAt": "2026-10-21T18:53:24.974Z",
|
||||
"runId": "1792608804974",
|
||||
"teacher": {
|
||||
"id": "6ad90a253d51b696cdc51357",
|
||||
"email": "teacher-1792608804974@example.invalid"
|
||||
},
|
||||
"users": [
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51358",
|
||||
"email": "user-1792608804974-1@example.invalid"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51359",
|
||||
"email": "user-1792608804974-2@example.invalid"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc5135a",
|
||||
"email": "user-1792608804974-3@example.invalid"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc5135b",
|
||||
"email": "user-1792608804974-4@example.invalid"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc5135c",
|
||||
"email": "user-1792608804974-5@example.invalid"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc5135d",
|
||||
"email": "user-1792608804974-6@example.invalid"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc5135e",
|
||||
"email": "user-1792608804974-7@example.invalid"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc5135f",
|
||||
"email": "user-1792608804974-8@example.invalid"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51360",
|
||||
"email": "user-1792608804974-9@example.invalid"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51361",
|
||||
"email": "user-1792608804974-10@example.invalid"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51362",
|
||||
"email": "user-1792608804974-11@example.invalid"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51363",
|
||||
"email": "user-1792608804974-12@example.invalid"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51364",
|
||||
"email": "user-1792608804974-13@example.invalid"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51365",
|
||||
"email": "user-1792608804974-14@example.invalid"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51366",
|
||||
"email": "user-1792608804974-15@example.invalid"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51367",
|
||||
"email": "user-1792608804974-16@example.invalid"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51368",
|
||||
"email": "user-1792608804974-17@example.invalid"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51369",
|
||||
"email": "user-1792608804974-18@example.invalid"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc5136a",
|
||||
"email": "user-1792608804974-19@example.invalid"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc5136b",
|
||||
"email": "user-1792608804974-20@example.invalid"
|
||||
}
|
||||
],
|
||||
"sessions": [
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc5136c",
|
||||
"startTime": "2026-10-22T18:53:25.235Z",
|
||||
"endTime": "2026-10-22T19:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-22T18:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc5136d",
|
||||
"startTime": "2026-10-22T19:53:25.235Z",
|
||||
"endTime": "2026-10-22T20:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-22T19:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc5136e",
|
||||
"startTime": "2026-10-22T20:53:25.235Z",
|
||||
"endTime": "2026-10-22T21:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-22T20:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc5136f",
|
||||
"startTime": "2026-10-22T21:53:25.235Z",
|
||||
"endTime": "2026-10-22T22:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-22T21:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51370",
|
||||
"startTime": "2026-10-22T22:53:25.235Z",
|
||||
"endTime": "2026-10-22T23:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-22T22:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51371",
|
||||
"startTime": "2026-10-22T23:53:25.235Z",
|
||||
"endTime": "2026-10-23T00:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-22T23:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51372",
|
||||
"startTime": "2026-10-23T00:53:25.235Z",
|
||||
"endTime": "2026-10-23T01:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-23T00:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51373",
|
||||
"startTime": "2026-10-23T01:53:25.235Z",
|
||||
"endTime": "2026-10-23T02:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-23T01:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51374",
|
||||
"startTime": "2026-10-23T02:53:25.235Z",
|
||||
"endTime": "2026-10-23T03:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-23T02:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51375",
|
||||
"startTime": "2026-10-23T03:53:25.235Z",
|
||||
"endTime": "2026-10-23T04:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-23T03:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51376",
|
||||
"startTime": "2026-10-23T04:53:25.235Z",
|
||||
"endTime": "2026-10-23T05:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-23T04:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51377",
|
||||
"startTime": "2026-10-23T05:53:25.235Z",
|
||||
"endTime": "2026-10-23T06:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-23T05:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51378",
|
||||
"startTime": "2026-10-23T06:53:25.235Z",
|
||||
"endTime": "2026-10-23T07:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-23T06:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51379",
|
||||
"startTime": "2026-10-23T07:53:25.235Z",
|
||||
"endTime": "2026-10-23T08:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-23T07:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc5137a",
|
||||
"startTime": "2026-10-23T08:53:25.235Z",
|
||||
"endTime": "2026-10-23T09:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-23T08:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc5137b",
|
||||
"startTime": "2026-10-23T09:53:25.235Z",
|
||||
"endTime": "2026-10-23T10:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-23T09:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc5137c",
|
||||
"startTime": "2026-10-23T10:53:25.235Z",
|
||||
"endTime": "2026-10-23T11:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-23T10:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc5137d",
|
||||
"startTime": "2026-10-23T11:53:25.235Z",
|
||||
"endTime": "2026-10-23T12:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-23T11:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc5137e",
|
||||
"startTime": "2026-10-23T12:53:25.235Z",
|
||||
"endTime": "2026-10-23T13:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-23T12:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc5137f",
|
||||
"startTime": "2026-10-23T13:53:25.235Z",
|
||||
"endTime": "2026-10-23T14:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-23T13:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51380",
|
||||
"startTime": "2026-10-23T14:53:25.235Z",
|
||||
"endTime": "2026-10-23T15:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-23T14:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51381",
|
||||
"startTime": "2026-10-23T15:53:25.235Z",
|
||||
"endTime": "2026-10-23T16:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-23T15:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51382",
|
||||
"startTime": "2026-10-23T16:53:25.235Z",
|
||||
"endTime": "2026-10-23T17:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-23T16:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51383",
|
||||
"startTime": "2026-10-23T17:53:25.235Z",
|
||||
"endTime": "2026-10-23T18:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-23T17:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51384",
|
||||
"startTime": "2026-10-23T18:53:25.235Z",
|
||||
"endTime": "2026-10-23T19:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-23T18:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51385",
|
||||
"startTime": "2026-10-23T19:53:25.235Z",
|
||||
"endTime": "2026-10-23T20:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-23T19:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51386",
|
||||
"startTime": "2026-10-23T20:53:25.235Z",
|
||||
"endTime": "2026-10-23T21:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-23T20:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51387",
|
||||
"startTime": "2026-10-23T21:53:25.235Z",
|
||||
"endTime": "2026-10-23T22:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-23T21:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51388",
|
||||
"startTime": "2026-10-23T22:53:25.235Z",
|
||||
"endTime": "2026-10-23T23:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-23T22:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51389",
|
||||
"startTime": "2026-10-23T23:53:25.235Z",
|
||||
"endTime": "2026-10-24T00:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-23T23:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc5138a",
|
||||
"startTime": "2026-10-24T00:53:25.235Z",
|
||||
"endTime": "2026-10-24T01:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-24T00:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc5138b",
|
||||
"startTime": "2026-10-24T01:53:25.235Z",
|
||||
"endTime": "2026-10-24T02:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-24T01:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc5138c",
|
||||
"startTime": "2026-10-24T02:53:25.235Z",
|
||||
"endTime": "2026-10-24T03:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-24T02:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc5138d",
|
||||
"startTime": "2026-10-24T03:53:25.235Z",
|
||||
"endTime": "2026-10-24T04:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-24T03:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc5138e",
|
||||
"startTime": "2026-10-24T04:53:25.235Z",
|
||||
"endTime": "2026-10-24T05:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-24T04:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc5138f",
|
||||
"startTime": "2026-10-24T05:53:25.235Z",
|
||||
"endTime": "2026-10-24T06:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-24T05:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51390",
|
||||
"startTime": "2026-10-24T06:53:25.235Z",
|
||||
"endTime": "2026-10-24T07:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-24T06:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51391",
|
||||
"startTime": "2026-10-24T07:53:25.235Z",
|
||||
"endTime": "2026-10-24T08:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-24T07:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51392",
|
||||
"startTime": "2026-10-24T08:53:25.235Z",
|
||||
"endTime": "2026-10-24T09:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-24T08:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51393",
|
||||
"startTime": "2026-10-24T09:53:25.235Z",
|
||||
"endTime": "2026-10-24T10:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-24T09:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51394",
|
||||
"startTime": "2026-10-24T10:53:25.235Z",
|
||||
"endTime": "2026-10-24T11:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-24T10:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51395",
|
||||
"startTime": "2026-10-24T11:53:25.235Z",
|
||||
"endTime": "2026-10-24T12:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-24T11:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51396",
|
||||
"startTime": "2026-10-24T12:53:25.235Z",
|
||||
"endTime": "2026-10-24T13:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-24T12:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51397",
|
||||
"startTime": "2026-10-24T13:53:25.235Z",
|
||||
"endTime": "2026-10-24T14:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-24T13:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51398",
|
||||
"startTime": "2026-10-24T14:53:25.235Z",
|
||||
"endTime": "2026-10-24T15:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-24T14:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc51399",
|
||||
"startTime": "2026-10-24T15:53:25.235Z",
|
||||
"endTime": "2026-10-24T16:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-24T15:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc5139a",
|
||||
"startTime": "2026-10-24T16:53:25.235Z",
|
||||
"endTime": "2026-10-24T17:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-24T16:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc5139b",
|
||||
"startTime": "2026-10-24T17:53:25.235Z",
|
||||
"endTime": "2026-10-24T18:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-24T17:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc5139c",
|
||||
"startTime": "2026-10-24T18:53:25.235Z",
|
||||
"endTime": "2026-10-24T19:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-24T18:53:25.235Z"
|
||||
},
|
||||
{
|
||||
"id": "6ad90a253d51b696cdc5139d",
|
||||
"startTime": "2026-10-24T19:53:25.235Z",
|
||||
"endTime": "2026-10-24T20:23:25.235Z",
|
||||
"dateTimestamp": "2026-10-24T19:53:25.235Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
import http from 'k6/http';
|
||||
import { check, sleep } from 'k6';
|
||||
|
||||
export const options = {
|
||||
vus: 1,
|
||||
iterations: 10,
|
||||
thresholds: {
|
||||
http_req_failed: ['rate<0.01'],
|
||||
http_req_duration: ['p(95)<500'],
|
||||
},
|
||||
};
|
||||
|
||||
export default function () {
|
||||
const response = http.get('http://app:3000/users/');
|
||||
|
||||
check(response, {
|
||||
'status is 200': (r) => r.status === 200,
|
||||
'response is JSON': (r) =>
|
||||
r.headers['Content-Type']?.includes('application/json'),
|
||||
});
|
||||
|
||||
sleep(1);
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import http from 'k6/http';
|
||||
import { check } from 'k6';
|
||||
|
||||
const BASE_URL = __ENV.BASE_URL || 'http://app:3000';
|
||||
|
||||
export const options = {
|
||||
stages: [
|
||||
{ duration: '20s', target: 5 },
|
||||
{ duration: '20s', target: 10 },
|
||||
{ duration: '20s', target: 20 },
|
||||
{ duration: '20s', target: 30 },
|
||||
{ duration: '20s', target: 40 },
|
||||
{ duration: '20s', target: 50 },
|
||||
{ duration: '15s', target: 0 },
|
||||
],
|
||||
thresholds: {
|
||||
http_req_failed: ['rate<0.01'],
|
||||
http_req_duration: ['p(95)<500'],
|
||||
checks: ['rate>0.99'],
|
||||
},
|
||||
};
|
||||
|
||||
export default function () {
|
||||
const endpoints = [
|
||||
'/users/',
|
||||
'/teachers/',
|
||||
'/sessions/available?dateTimestamp=2026-10-25T10%3A00%3A00.000Z',
|
||||
];
|
||||
|
||||
for (const endpoint of endpoints) {
|
||||
const response = http.get(`${BASE_URL}${endpoint}`);
|
||||
|
||||
check(response, {
|
||||
[`${endpoint}: status 200`]: (r) => r.status === 200,
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user