Refactor load testing scripts to support Bash and PowerShell
- Updated README.md to reflect changes in load testing commands and added usage examples for Bash scripts. - Converted PowerShell load testing scripts to Bash equivalents for better cross-platform compatibility. - Added new Bash scripts: run-loadtests.sh, summarize-artillery.sh, and summarize-k6.sh to mirror existing PowerShell functionality. - Updated admin-api.js and ws-chat.yml for consistency and improved performance metrics reporting. - Enhanced error handling and output formatting in summary scripts for better readability.
This commit is contained in:
1 parent
9f60087a4c
commit
33b6296c5e
82 files changed
+19682
-21133
No files matched your search
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env bash
|
||||
# summarize-artillery.sh — Extract counters, rates and percentile stats from an
|
||||
# Artillery JSON report. Mirrors scripts/loadtest/summarize-artillery.ps1.
|
||||
# Usage: ./scripts/loadtest/summarize-artillery.sh <artillery-report.json>
|
||||
set -euo pipefail
|
||||
|
||||
if [[ $# -lt 1 ]]; then
|
||||
echo "Usage: $0 <artillery-report.json>" >&2
|
||||
exit 2
|
||||
fi
|
||||
report_file="$1"
|
||||
[[ -f "$report_file" ]] || { echo "Report file not found: $report_file" >&2; exit 1; }
|
||||
|
||||
REPORT_FILE="$report_file" node <<'EOF'
|
||||
const fs = require('fs');
|
||||
const report = JSON.parse(fs.readFileSync(process.env.REPORT_FILE, 'utf8'));
|
||||
const aggregate = report.aggregate;
|
||||
if (!aggregate) throw new Error('Artillery report is missing aggregate data.');
|
||||
|
||||
const get = (obj, name) => (obj && obj[name] !== undefined) ? obj[name] : undefined;
|
||||
const counters = aggregate.counters || {};
|
||||
const rates = aggregate.rates || {};
|
||||
const summaries = aggregate.summaries || {};
|
||||
|
||||
const created = Number(get(counters, 'vusers.created') || 0);
|
||||
const failed = Number(get(counters, 'vusers.failed') || 0);
|
||||
const completed = Number(get(counters, 'vusers.completed') || 0);
|
||||
const errorRate = created > 0 ? +((failed / created) * 100).toFixed(2) : 0;
|
||||
|
||||
console.log('=== Artillery WebSocket Summary ===');
|
||||
console.log(`source: ${process.env.REPORT_FILE}`);
|
||||
if (report.timestamp) console.log(`timestamp: ${report.timestamp}`);
|
||||
console.log(`vusers.created: ${created}`);
|
||||
console.log(`vusers.completed: ${completed}`);
|
||||
console.log(`vusers.failed: ${failed}`);
|
||||
console.log(`vusers.failure_rate_percent: ${errorRate}`);
|
||||
|
||||
for (const metric of ['ws.messages_sent', 'ws.messages_received', 'ws.ping', 'plugins.metrics-by-endpoint.response_time']) {
|
||||
const v = get(counters, metric);
|
||||
if (v !== undefined) console.log(`${metric}: ${v}`);
|
||||
}
|
||||
for (const [k, v] of Object.entries(rates || {})) console.log(`rate.${k}: ${v}`);
|
||||
|
||||
const fmt = (prefix, stats) => {
|
||||
if (!stats) return;
|
||||
const parts = [];
|
||||
for (const name of ['count', 'min', 'max', 'mean', 'median', 'p95', 'p99']) {
|
||||
const v = get(stats, name);
|
||||
if (v !== undefined) parts.push(`${name}=${v}`);
|
||||
}
|
||||
if (parts.length) console.log(`${prefix}: ${parts.join(', ')}`);
|
||||
};
|
||||
for (const [k, v] of Object.entries(summaries)) fmt(`summary.${k}`, v);
|
||||
EOF
|
||||
Reference in new issue
Block a user