- 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.
55 lines
2.2 KiB
Bash
55 lines
2.2 KiB
Bash
#!/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
|