/** * Artillery processor functions. * * Artillery loads this file and calls exported functions * as hooks during virtual user lifecycle. * * Note: this must be plain JS/MJS (not TypeScript) — Artillery loads it directly. */ import { readFileSync } from "fs"; import { join, dirname } from "path"; import { fileURLToPath } from "url"; const __dirname = dirname(fileURLToPath(import.meta.url)); // ── Load customer -> stripeId mapping (generated by setup.ts) ─── let customerMap = {}; try { customerMap = JSON.parse( readFileSync(join(__dirname, ".customers.json"), "utf-8") ); } catch { console.warn( "[processor] No .customers.json found — attach scenarios will fail.\n" + " Run: cd server && bun loadtest:setup" ); } const CUSTOMER_IDS = Object.keys(customerMap); const CUSTOMER_COUNT = CUSTOMER_IDS.length || 500; const CUSTOMER_PREFIX = "load-cus-"; /** Products in the load-test group (for upgrade/downgrade cycling). */ const PLAN_PRODUCTS = ["load-pro", "load-premium", "load-free"]; /** The main metered feature all products include. */ const FEATURE_ID = "messages"; function padNumber(n) { return String(n).padStart(3, "0"); } function pickRandom(arr) { return arr[Math.floor(Math.random() * arr.length)]; } function getRandomCustomerId() { if (CUSTOMER_IDS.length > 0) { return pickRandom(CUSTOMER_IDS); } // Fallback if .customers.json not loaded const num = Math.floor(Math.random() * 500) + 1; return `${CUSTOMER_PREFIX}${padNumber(num)}`; } /** * Called before each "Core API loop" virtual user. * Sets customer + feature for check/track/get requests. */ export function setCustomerContext(ctx, _events, done) { ctx.vars.customerId = getRandomCustomerId(); ctx.vars.featureId = FEATURE_ID; done(); } /** * Called before each "Attach flow" virtual user. * Sets customer + a random product for upgrade/downgrade. */ export function setAttachContext(ctx, _events, done) { const customerId = getRandomCustomerId(); ctx.vars.customerId = customerId; ctx.vars.stripeId = customerMap[customerId] || ""; ctx.vars.productId = pickRandom(PLAN_PRODUCTS); ctx.vars.featureId = FEATURE_ID; done(); }