diff --git a/tests/soak/scripts/seed-accounts.ts b/tests/soak/scripts/seed-accounts.ts new file mode 100644 index 0000000..ff67686 --- /dev/null +++ b/tests/soak/scripts/seed-accounts.ts @@ -0,0 +1,60 @@ +#!/usr/bin/env tsx +/** + * Seed N soak-harness accounts via the register endpoint. + * + * Usage: + * TEST_URL=http://localhost:8000 \ + * SOAK_INVITE_CODE=SOAKTEST \ + * bun run seed -- --count=16 + * + * The invite code must already exist and be flagged marks_as_test=TRUE + * in the target environment. See docs/soak-harness-bringup.md. + */ + +import * as path from 'path'; +import { SessionPool } from '../core/session-pool'; +import { createLogger } from '../core/logger'; + +function parseArgs(argv: string[]): { count: number } { + const result = { count: 16 }; + for (const arg of argv.slice(2)) { + const m = arg.match(/^--count=(\d+)$/); + if (m) result.count = parseInt(m[1], 10); + } + return result; +} + +async function main(): Promise { + const { count } = parseArgs(process.argv); + const targetUrl = process.env.TEST_URL ?? 'http://localhost:8000'; + const inviteCode = process.env.SOAK_INVITE_CODE; + if (!inviteCode) { + console.error('SOAK_INVITE_CODE env var is required'); + console.error(' Local dev: SOAK_INVITE_CODE=SOAKTEST'); + console.error(' Staging: SOAK_INVITE_CODE=5VC2MCCN'); + process.exit(2); + } + + const credFile = path.resolve(__dirname, '..', '.env.stresstest'); + const logger = createLogger({ runId: `seed-${Date.now()}` }); + + logger.info('seed_start', { count, targetUrl, credFile }); + try { + const accounts = await SessionPool.seed({ + targetUrl, + inviteCode, + count, + credFile, + logger, + }); + logger.info('seed_complete', { created: accounts.length }); + console.error(`Seeded ${accounts.length} accounts → ${credFile}`); + } catch (err) { + logger.error('seed_failed', { + error: err instanceof Error ? err.message : String(err), + }); + process.exit(1); + } +} + +main();