Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions scalability/2_curiosity.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { sleep } from "k6";
import { submitter } from "./workflows/submitter.js";
import { queryUsersList, queryUserById } from "./workflows/querier.js";

const BASE_URL = __ENV.TEST_HOST;

export let options = {
scenarios: {
submitters: {
executor: "constant-vus",
vus: 10,
duration: "2m",
exec: "submitRequests",
},
auditors: {
executor: "ramping-arrival-rate",
startTime: "2m",
startRate: 100,
timeUnit: "1s",
preAllocatedVUs: 200,
maxVUs: 500,
stages: [
// generate ~60k requests in the 2-minute sustained burst (500 req/s × 120s)
{ duration: "30s", target: 500 }, // ramp to 500 req/s
{ duration: "2m", target: 500 }, // sustain ~60k requests
{ duration: "30s", target: 10 }, // cool down
],
exec: "auditorRead",
},
},
};

export function setup() {
let customers = [];
let userIds = [];
for (let i = 0; i < 5; i++) customers.push(crypto.randomUUID());
for (let i = 0; i < 50; i++) userIds.push(crypto.randomUUID());
return {
customers: customers,
userIds: userIds,
tag: "curiosity",
generator: "normal",
urgentRatio: 0.05,
};
}

export function submitRequests(data) {
submitter(data);
sleep(5);
}

export function auditorRead(data) {
let host = BASE_URL.endsWith("/") ? BASE_URL.slice(0, -1) : BASE_URL;
let customer = data.customers[0];

// Query list of users for the customer
let res = queryUsersList(host, customer);
sleep(1);

// Query a random user discovered from the list endpoint
if (res.users && res.users.length > 0) {
let user = res.users[Math.floor(Math.random() * res.users.length)];
queryUserById(host, customer, user.id);
}
sleep(1);
}
1 change: 0 additions & 1 deletion scalability/3_compliance_early.js
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ export function setup() {
tag: "compliance_early",
generator: "normal",
urgentRatio: 0.05,
photoComplexity: 4,
};
}

Expand Down
81 changes: 81 additions & 0 deletions scalability/4_compliance_mid.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { sleep } from "k6";
import { submitter } from "./workflows/submitter.js";
import {
queryRequestsList,
queryStats,
queryBatchUserResults,
} from "./workflows/querier.js";

const BASE_URL = __ENV.TEST_HOST;

export let options = {
scenarios: {
submitters: {
executor: "ramping-vus",
startVUs: 0,
stages: [
{ duration: "2m", target: 5 }, // ramp up to 5 VUs, at ~10s/iteration -> 6 iterations per minute per VU, so 6 * 5 * 2 = 60 iterations (POST + poll GET) in the first 2 minute
{ duration: "3m", target: 50 }, // ramp up to 50 VUs, so 6 * 50 * 3 = 900 iterations in the next 3 minutes
{ duration: "2m", target: 10 }, // ramp down to 10 VUs, so 6 * 10 * 2 = 120 iterations in the next 2 minutes
{ duration: "3m", target: 2 }, // ramp down to 2 VUs, so 6 * 2 * 3 = 36 iterations in the last 3 minutes
],
exec: "submitRequests",
},
readers: {
executor: "ramping-vus",
startVUs: 0,
startTime: "1m",
stages: [
{ duration: "2m", target: 3 },
{ duration: "3m", target: 15 },
{ duration: "2m", target: 15 },
{ duration: "3m", target: 3 },
],
exec: "readResults",
},
auditors: {
executor: "constant-vus",
startTime: "1m",
vus: 5,
duration: "10m",
exec: "auditBatch",
},
},
};

export function setup() {
let customers = [];
let userIds = [];
for (let i = 0; i < 15; i++) customers.push(crypto.randomUUID());
for (let i = 0; i < 60; i++) userIds.push(crypto.randomUUID());
return {
customers: customers,
userIds: userIds,
tag: "compliance_mid",
generator: "normal",
urgentRatio: 0.15,
};
}

export function submitRequests(data) {
submitter(data);
sleep(5);
}

export function readResults(data) {
let host = BASE_URL.endsWith("/") ? BASE_URL.slice(0, -1) : BASE_URL;
let customer =
data.customers[Math.floor(Math.random() * data.customers.length)];

queryRequestsList(host, customer);
sleep(1);
queryStats(host, customer);
sleep(5);
}

export function auditBatch(data) {
let host = BASE_URL.endsWith("/") ? BASE_URL.slice(0, -1) : BASE_URL;
let batch = data.customers.slice(0, 5);
queryBatchUserResults(host, batch);
sleep(5);
}
97 changes: 97 additions & 0 deletions scalability/5_compliance_peak.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
import { sleep } from "k6";
import { submitter } from "./workflows/submitter.js";
import {
pollPendingRequests,
queryBatchUserResults,
queryUserResults,
queryRequestsList,
} from "./workflows/querier.js";

const BASE_URL = __ENV.TEST_HOST;

export let options = {
scenarios: {
submitters: {
executor: "ramping-vus",
startVUs: 0,
stages: [
{ duration: "1m", target: 5 }, // ramp up to 5 VUs, at ~10s/iteration -> 6 iterations per minute per VU, so 6 * 5 * 1 = 30 iterations (POST + poll GET) in the first minute
{ duration: "2m", target: 40 }, // ramp up to 40 VUs, so 6 * 40 * 2 = 480 iterations in the next 2 minutes
{ duration: "2m", target: 40 }, // stay at 40 VUs, so 6 * 40 * 2 = 480 iterations in the next 2 minutes
{ duration: "1m", target: 2 }, // ramp down to 2 VUs, so 6 * 2 * 1 = 12 iterations in the last minute
],
exec: "submitRequests",
},
readers: {
executor: "ramping-vus",
startVUs: 0,
startTime: "1m",
stages: [
{ duration: "1m", target: 5 },
{ duration: "4m", target: 60 },
{ duration: "4m", target: 60 },
{ duration: "1m", target: 10 },
],
exec: "readResults",
},
auditors: {
executor: "ramping-vus",
startVUs: 0,
startTime: "1m",
stages: [
{ duration: "2m", target: 5 },
{ duration: "4m", target: 15 },
{ duration: "3m", target: 15 },
{ duration: "1m", target: 1 },
],
exec: "auditBatch",
},
},
};

export function setup() {
let customers = [];
let userIds = [];
for (let i = 0; i < 20; i++) customers.push(crypto.randomUUID());
for (let i = 0; i < 90; i++) userIds.push(crypto.randomUUID());
return {
customers: customers,
userIds: userIds,
tag: "compliance_peak",
generator: "heavy",
urgentRatio: 0.3,
};
}

export function submitRequests(data) {
submitter(data);
sleep(10);
}

export function readResults(data) {
let host = BASE_URL.endsWith("/") ? BASE_URL.slice(0, -1) : BASE_URL;
let customer =
data.customers[Math.floor(Math.random() * data.customers.length)];

// List requests, then re-query any that are still pending
queryRequestsList(host, customer);
sleep(1);
pollPendingRequests(host, customer);
sleep(5);
}

export function auditBatch(data) {
let host = BASE_URL.endsWith("/") ? BASE_URL.slice(0, -1) : BASE_URL;

// Batch queries across all clients
queryBatchUserResults(host, data.customers);
sleep(1);

// Per-user queries across all customers
for (let i = 0; i < data.customers.length; i++) {
const customer = data.customers[i];
queryUserResults(host, customer);
Comment on lines +85 to +93
sleep(1);
}
sleep(1);
}
Comment on lines +83 to +97
88 changes: 88 additions & 0 deletions scalability/6_compliance_tail.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import { sleep } from "k6";
import { submitter } from "./workflows/submitter.js";
import {
pollPendingRequests,
queryBatchUserResults,
queryUserResults,
} from "./workflows/querier.js";
import { randomIntBetween } from "https://jslib.k6.io/k6-utils/1.2.0/index.js";

const BASE_URL = __ENV.TEST_HOST;

export let options = {
scenarios: {
submitters: {
executor: "ramping-vus",
startVUs: 0,
stages: [
{ duration: "2m", target: 10 },
{ duration: "2m", target: 40 },
{ duration: "2m", target: 20 },
{ duration: "2m", target: 35 },
{ duration: "2m", target: 5 },
],
exec: "submitRequests",
},
readers: {
executor: "constant-vus",
vus: 20,
startTime: "1m",
duration: "10m",
exec: "readResults",
},
auditors: {
executor: "constant-vus",
vus: 8,
startTime: "1m",
duration: "10m",
exec: "auditBatch",
},
},
};

export function setup() {
let customers = [];
let userIds = [];
for (let i = 0; i < 20; i++) customers.push(crypto.randomUUID());
for (let i = 0; i < 80; i++) userIds.push(crypto.randomUUID());
return {
customers: customers,
userIds: userIds,
tag: "compliance_tail",
generator: "heavy",
urgentRatio: 0.1,
};
}

export function submitRequests(data) {
submitter(data);
sleep(5);
}

export function readResults(data) {
let host = BASE_URL.endsWith("/") ? BASE_URL.slice(0, -1) : BASE_URL;
let customer =
data.customers[Math.floor(Math.random() * data.customers.length)];

pollPendingRequests(host, customer);
sleep(5);
}

export function auditBatch(data) {
let host = BASE_URL.endsWith("/") ? BASE_URL.slice(0, -1) : BASE_URL;

// Moderate batch queries
let batchSize = randomIntBetween(4, data.customers.length);
let startIdx = Math.floor(
Math.random() * Math.max(1, data.customers.length - batchSize),
);
let batch = data.customers.slice(startIdx, startIdx + batchSize);
queryBatchUserResults(host, batch);
sleep(1);

// Per-user queries max 50 users
let customer =
data.customers[Math.floor(Math.random() * data.customers.length)];
queryUserResults(host, customer, 50);
sleep(5);
}
Loading