Sync all scripts from website downloads — 352 scripts total
Includes updated JS challenge scripts with Claude-User whitelist, same-site referer bypass, Blackbox-Exporter allowed bot, and all new exporters, cheat sheets, and automation scripts.
This commit is contained in:
@@ -0,0 +1,559 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
#########################################################################################
|
||||
#### k6-test-runner.sh — Run k6 load tests with Prometheus push and formatted ####
|
||||
#### reports. Execute test scripts, push metrics, compare runs, threshold checks ####
|
||||
#### Requires: bash 4+, k6 ####
|
||||
#### ####
|
||||
#### Author: Phil Connor ####
|
||||
#### Contact: contact@mylinux.work ####
|
||||
#### License: MIT ####
|
||||
#### Version 1.01 ####
|
||||
#### ####
|
||||
#### Usage: ####
|
||||
#### ./k6-test-runner.sh --run ./tests/load.js ####
|
||||
#### ####
|
||||
#### See --help for all options. ####
|
||||
#########################################################################################
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# ── Colors (pre-initialized) ─────────────────────────────────────────
|
||||
RED="" GREEN="" YELLOW="" BLUE="" CYAN="" BOLD="" DIM="" RESET=""
|
||||
|
||||
setup_colors() {
|
||||
if [[ "${COLOR:-auto}" == "never" ]]; then
|
||||
return
|
||||
fi
|
||||
if [[ "${COLOR:-auto}" == "always" ]] || [[ -t 1 ]]; then
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[0;33m'
|
||||
BLUE='\033[0;34m'
|
||||
CYAN='\033[0;36m'
|
||||
BOLD='\033[1m'
|
||||
DIM='\033[2m'
|
||||
RESET='\033[0m'
|
||||
fi
|
||||
}
|
||||
|
||||
# ── Logging ───────────────────────────────────────────────────────────
|
||||
log() { echo -e "${BLUE}[INFO]${RESET} $*"; }
|
||||
warn() { echo -e "${YELLOW}[WARN]${RESET} $*" >&2; }
|
||||
err() { echo -e "${RED}[ERROR]${RESET} $*" >&2; }
|
||||
verbose() { if [[ "$VERBOSE" == "true" ]]; then echo -e "${DIM}[DEBUG]${RESET} $*"; fi; }
|
||||
die() { err "$*"; exit 1; }
|
||||
|
||||
section_header() {
|
||||
echo ""
|
||||
echo -e " ${BOLD}${CYAN}── $1 ──${RESET}"
|
||||
echo ""
|
||||
}
|
||||
|
||||
field() {
|
||||
printf " ${BOLD}%-22s${RESET} %s\n" "$1" "$2"
|
||||
}
|
||||
|
||||
field_color() {
|
||||
printf " ${BOLD}%-22s${RESET} %b\n" "$1" "$2"
|
||||
}
|
||||
|
||||
elapsed() {
|
||||
local end_time
|
||||
end_time=$(date +%s)
|
||||
echo "$(( end_time - START_TIME ))s"
|
||||
}
|
||||
|
||||
# ── Defaults ──────────────────────────────────────────────────────────
|
||||
RUN_MODE=""
|
||||
TEST_SCRIPT=""
|
||||
K6_PATH="${K6_PATH:-k6}"
|
||||
VUS="${K6_VUS:-10}"
|
||||
DURATION="${K6_DURATION:-30s}"
|
||||
PUSH_GW="${K6_PUSH_GATEWAY:-}"
|
||||
RESULTS_DIR="${K6_RESULTS_DIR:-./k6-results}"
|
||||
OUTPUT_FORMAT="${K6_FORMAT:-text}"
|
||||
THRESHOLDS_FILE=""
|
||||
COMPARE_RUN=""
|
||||
LIST_DIR=""
|
||||
INSPECT_SCRIPT=""
|
||||
VERBOSE="${VERBOSE:-false}"
|
||||
COLOR="${COLOR:-auto}"
|
||||
declare -a ENV_VARS=()
|
||||
TAGS="${K6_TAGS:-}"
|
||||
|
||||
# ── State ─────────────────────────────────────────────────────────────
|
||||
SCRIPT_NAME="$(basename "$0")"
|
||||
readonly SCRIPT_NAME
|
||||
START_TIME=""
|
||||
RUN_ID=""
|
||||
|
||||
# ── Dependency checks ────────────────────────────────────────────────
|
||||
require_k6() {
|
||||
if ! command -v "$K6_PATH" &>/dev/null; then
|
||||
die "k6 not found: ${K6_PATH}. Install from https://k6.io/docs/get-started/installation/"
|
||||
fi
|
||||
verbose "k6 found: $(command -v "$K6_PATH") ($("$K6_PATH" version 2>/dev/null | head -1))"
|
||||
}
|
||||
|
||||
require_jq() {
|
||||
if ! command -v jq &>/dev/null; then
|
||||
die "jq is required for result parsing"
|
||||
fi
|
||||
}
|
||||
|
||||
# ── Format helpers ───────────────────────────────────────────────────
|
||||
format_duration_ms() {
|
||||
local ms="$1"
|
||||
if command -v awk &>/dev/null; then
|
||||
if awk "BEGIN{exit ($ms >= 1000) ? 0 : 1}" 2>/dev/null; then
|
||||
awk "BEGIN{printf \"%.2fs\", $ms / 1000}"
|
||||
else
|
||||
awk "BEGIN{printf \"%.1fms\", $ms}"
|
||||
fi
|
||||
else
|
||||
echo "${ms}ms"
|
||||
fi
|
||||
}
|
||||
|
||||
format_rate() {
|
||||
local rate="$1"
|
||||
if command -v awk &>/dev/null; then
|
||||
awk "BEGIN{printf \"%.1f/s\", $rate}"
|
||||
else
|
||||
echo "${rate}/s"
|
||||
fi
|
||||
}
|
||||
|
||||
# ══════════════════════════════════════════════════════════════════════
|
||||
# RUN MODE
|
||||
# ══════════════════════════════════════════════════════════════════════
|
||||
do_run() {
|
||||
[[ -z "$TEST_SCRIPT" ]] && die "No test script specified"
|
||||
[[ ! -f "$TEST_SCRIPT" ]] && die "Test script not found: ${TEST_SCRIPT}"
|
||||
require_k6
|
||||
|
||||
RUN_ID="$(date +%Y%m%d-%H%M%S)"
|
||||
local run_dir="${RESULTS_DIR}/${RUN_ID}"
|
||||
mkdir -p "$run_dir"
|
||||
|
||||
section_header "k6 Load Test"
|
||||
field "Test script:" "$TEST_SCRIPT"
|
||||
field "Virtual users:" "$VUS"
|
||||
field "Duration:" "$DURATION"
|
||||
field "Run ID:" "$RUN_ID"
|
||||
[[ -n "$PUSH_GW" ]] && field "Push gateway:" "$PUSH_GW"
|
||||
echo ""
|
||||
|
||||
# Build k6 command
|
||||
local -a k6_args=("run")
|
||||
k6_args+=("--vus" "$VUS")
|
||||
k6_args+=("--duration" "$DURATION")
|
||||
k6_args+=("--summary-export" "${run_dir}/summary.json")
|
||||
k6_args+=("--out" "json=${run_dir}/results.json")
|
||||
|
||||
if [[ -n "$PUSH_GW" ]]; then
|
||||
k6_args+=("--out" "experimental-prometheus-rw=${PUSH_GW}")
|
||||
fi
|
||||
|
||||
if [[ -n "$THRESHOLDS_FILE" && -f "$THRESHOLDS_FILE" ]]; then
|
||||
k6_args+=("--config" "$THRESHOLDS_FILE")
|
||||
fi
|
||||
|
||||
for ev in "${ENV_VARS[@]+"${ENV_VARS[@]}"}"; do
|
||||
k6_args+=("-e" "$ev")
|
||||
done
|
||||
|
||||
if [[ -n "$TAGS" ]]; then
|
||||
k6_args+=("--tag" "$TAGS")
|
||||
fi
|
||||
|
||||
k6_args+=("$TEST_SCRIPT")
|
||||
|
||||
verbose "Command: ${K6_PATH} ${k6_args[*]}"
|
||||
|
||||
# Save run metadata
|
||||
cat > "${run_dir}/metadata.json" <<EOF
|
||||
{"run_id":"${RUN_ID}","script":"${TEST_SCRIPT}","vus":${VUS},"duration":"${DURATION}","timestamp":"$(date -u '+%Y-%m-%dT%H:%M:%SZ')"}
|
||||
EOF
|
||||
|
||||
log "Starting k6 test..."
|
||||
echo ""
|
||||
|
||||
local exit_code=0
|
||||
"$K6_PATH" "${k6_args[@]}" 2>&1 | tee "${run_dir}/output.log" || exit_code=$?
|
||||
|
||||
echo ""
|
||||
|
||||
# Parse and display results
|
||||
if [[ -f "${run_dir}/summary.json" ]]; then
|
||||
display_results "${run_dir}/summary.json"
|
||||
else
|
||||
warn "No summary file generated"
|
||||
fi
|
||||
|
||||
section_header "Run Summary"
|
||||
field "Run ID:" "$RUN_ID"
|
||||
field "Results:" "$run_dir"
|
||||
field "Duration:" "$(elapsed)"
|
||||
|
||||
if [[ $exit_code -ne 0 ]]; then
|
||||
field_color "Status:" "${RED}FAILED (exit ${exit_code})${RESET}"
|
||||
else
|
||||
field_color "Status:" "${GREEN}PASSED${RESET}"
|
||||
fi
|
||||
|
||||
return "$exit_code"
|
||||
}
|
||||
|
||||
display_results() {
|
||||
local summary_file="$1"
|
||||
|
||||
if ! command -v jq &>/dev/null; then
|
||||
warn "jq not available — skipping detailed results"
|
||||
return
|
||||
fi
|
||||
|
||||
section_header "Test Results"
|
||||
|
||||
local http_reqs http_req_dur_avg http_req_dur_p95 http_req_dur_p99
|
||||
local http_req_failed iterations data_received data_sent
|
||||
|
||||
http_reqs=$(jq -r '.metrics.http_reqs.values.count // 0' "$summary_file" 2>/dev/null || echo 0)
|
||||
http_req_dur_avg=$(jq -r '.metrics.http_req_duration.values.avg // 0' "$summary_file" 2>/dev/null || echo 0)
|
||||
http_req_dur_p95=$(jq -r '.metrics.http_req_duration.values["p(95)"] // 0' "$summary_file" 2>/dev/null || echo 0)
|
||||
http_req_dur_p99=$(jq -r '.metrics.http_req_duration.values["p(99)"] // 0' "$summary_file" 2>/dev/null || echo 0)
|
||||
http_req_failed=$(jq -r '.metrics.http_req_failed.values.rate // 0' "$summary_file" 2>/dev/null || echo 0)
|
||||
iterations=$(jq -r '.metrics.iterations.values.count // 0' "$summary_file" 2>/dev/null || echo 0)
|
||||
data_received=$(jq -r '.metrics.data_received.values.count // 0' "$summary_file" 2>/dev/null || echo 0)
|
||||
data_sent=$(jq -r '.metrics.data_sent.values.count // 0' "$summary_file" 2>/dev/null || echo 0)
|
||||
|
||||
local iter_rate
|
||||
iter_rate=$(jq -r '.metrics.iterations.values.rate // 0' "$summary_file" 2>/dev/null || echo 0)
|
||||
|
||||
printf " ${BOLD}%-28s %s${RESET}\n" "METRIC" "VALUE"
|
||||
printf " %s\n" "$(printf '%.0s─' {1..50})"
|
||||
printf " %-28s %s\n" "HTTP Requests" "$http_reqs"
|
||||
printf " %-28s %s\n" "Request Duration (avg)" "$(format_duration_ms "$http_req_dur_avg")"
|
||||
printf " %-28s %s\n" "Request Duration (p95)" "$(format_duration_ms "$http_req_dur_p95")"
|
||||
printf " %-28s %s\n" "Request Duration (p99)" "$(format_duration_ms "$http_req_dur_p99")"
|
||||
|
||||
local fail_pct
|
||||
fail_pct=$(awk "BEGIN{printf \"%.2f\", $http_req_failed * 100}" 2>/dev/null || echo "0")
|
||||
if awk "BEGIN{exit ($http_req_failed > 0) ? 0 : 1}" 2>/dev/null; then
|
||||
printf " %-28s ${RED}%s%%${RESET}\n" "Failed Requests" "$fail_pct"
|
||||
else
|
||||
printf " %-28s ${GREEN}%s%%${RESET}\n" "Failed Requests" "$fail_pct"
|
||||
fi
|
||||
|
||||
printf " %-28s %s\n" "Iterations" "$iterations"
|
||||
printf " %-28s %s\n" "Iteration Rate" "$(format_rate "$iter_rate")"
|
||||
printf " %-28s %s\n" "Data Received" "$(numfmt --to=iec "$data_received" 2>/dev/null || echo "${data_received} B")"
|
||||
printf " %-28s %s\n" "Data Sent" "$(numfmt --to=iec "$data_sent" 2>/dev/null || echo "${data_sent} B")"
|
||||
}
|
||||
|
||||
# ══════════════════════════════════════════════════════════════════════
|
||||
# LIST MODE
|
||||
# ══════════════════════════════════════════════════════════════════════
|
||||
do_list() {
|
||||
local dir="${LIST_DIR:-.}"
|
||||
[[ ! -d "$dir" ]] && die "Directory not found: ${dir}"
|
||||
|
||||
section_header "Available Test Scripts"
|
||||
|
||||
local count=0
|
||||
printf " ${BOLD}%-40s %10s %s${RESET}\n" "SCRIPT" "SIZE" "MODIFIED"
|
||||
printf " %s\n" "$(printf '%.0s─' {1..65})"
|
||||
|
||||
while IFS= read -r -d '' f; do
|
||||
local name size modified
|
||||
name=$(basename "$f")
|
||||
size=$(stat --printf="%s" "$f" 2>/dev/null || stat -f%z "$f" 2>/dev/null || echo 0)
|
||||
modified=$(stat --printf="%y" "$f" 2>/dev/null | cut -d' ' -f1 || stat -f"%Sm" -t "%Y-%m-%d" "$f" 2>/dev/null || echo "unknown")
|
||||
local human_size
|
||||
human_size=$(numfmt --to=iec "$size" 2>/dev/null || echo "${size}B")
|
||||
printf " %-40s %10s %s\n" "${name:0:38}" "$human_size" "$modified"
|
||||
((count++)) || true
|
||||
done < <(find "$dir" -maxdepth 2 -name '*.js' -type f -print0 2>/dev/null | sort -z)
|
||||
|
||||
echo ""
|
||||
field "Total scripts:" "$count"
|
||||
|
||||
if [[ "$count" -eq 0 ]]; then
|
||||
warn "No .js test scripts found in ${dir}"
|
||||
fi
|
||||
}
|
||||
|
||||
# ══════════════════════════════════════════════════════════════════════
|
||||
# COMPARE MODE
|
||||
# ══════════════════════════════════════════════════════════════════════
|
||||
do_compare() {
|
||||
[[ -z "$COMPARE_RUN" ]] && die "No run ID specified for comparison"
|
||||
require_jq
|
||||
|
||||
local prev_summary="${RESULTS_DIR}/${COMPARE_RUN}/summary.json"
|
||||
[[ ! -f "$prev_summary" ]] && die "Previous run not found: ${prev_summary}"
|
||||
|
||||
# Find most recent run (excluding the comparison target)
|
||||
local latest_dir=""
|
||||
while IFS= read -r d; do
|
||||
local base
|
||||
base=$(basename "$d")
|
||||
if [[ "$base" != "$COMPARE_RUN" && -f "${d}/summary.json" ]]; then
|
||||
latest_dir="$d"
|
||||
break
|
||||
fi
|
||||
done < <(find "$RESULTS_DIR" -mindepth 1 -maxdepth 1 -type d 2>/dev/null | sort -r)
|
||||
|
||||
if [[ -z "$latest_dir" ]]; then
|
||||
die "No other runs found to compare against"
|
||||
fi
|
||||
|
||||
local curr_summary="${latest_dir}/summary.json"
|
||||
local curr_id
|
||||
curr_id=$(basename "$latest_dir")
|
||||
|
||||
section_header "Run Comparison"
|
||||
field "Current run:" "$curr_id"
|
||||
field "Previous run:" "$COMPARE_RUN"
|
||||
echo ""
|
||||
|
||||
printf " ${BOLD}%-24s %14s %14s %10s${RESET}\n" "METRIC" "CURRENT" "PREVIOUS" "DELTA"
|
||||
printf " %s\n" "$(printf '%.0s─' {1..66})"
|
||||
|
||||
local metrics=("http_reqs.values.count" "http_req_duration.values.avg" "http_req_duration.values[\"p(95)\"]" "iterations.values.count")
|
||||
local labels=("HTTP Requests" "Duration (avg ms)" "Duration (p95 ms)" "Iterations")
|
||||
|
||||
for i in "${!metrics[@]}"; do
|
||||
local metric="${metrics[$i]}"
|
||||
local label="${labels[$i]}"
|
||||
local curr_val prev_val
|
||||
curr_val=$(jq -r ".metrics.${metric} // 0" "$curr_summary" 2>/dev/null || echo 0)
|
||||
prev_val=$(jq -r ".metrics.${metric} // 0" "$prev_summary" 2>/dev/null || echo 0)
|
||||
|
||||
local delta delta_pct color
|
||||
delta=$(awk "BEGIN{printf \"%.1f\", $curr_val - $prev_val}" 2>/dev/null || echo "0")
|
||||
if awk "BEGIN{exit ($prev_val > 0) ? 0 : 1}" 2>/dev/null; then
|
||||
delta_pct=$(awk "BEGIN{printf \"%.1f%%\", (($curr_val - $prev_val) / $prev_val) * 100}" 2>/dev/null || echo "0%")
|
||||
else
|
||||
delta_pct="N/A"
|
||||
fi
|
||||
|
||||
color="$RESET"
|
||||
if awk "BEGIN{exit ($delta > 0) ? 0 : 1}" 2>/dev/null; then
|
||||
color="$RED"
|
||||
elif awk "BEGIN{exit ($delta < 0) ? 0 : 1}" 2>/dev/null; then
|
||||
color="$GREEN"
|
||||
fi
|
||||
|
||||
printf " %-24s %14s %14s ${color}%10s${RESET}\n" "$label" \
|
||||
"$(awk "BEGIN{printf \"%.1f\", $curr_val}")" \
|
||||
"$(awk "BEGIN{printf \"%.1f\", $prev_val}")" \
|
||||
"$delta_pct"
|
||||
done
|
||||
}
|
||||
|
||||
# ══════════════════════════════════════════════════════════════════════
|
||||
# REPORT MODE
|
||||
# ══════════════════════════════════════════════════════════════════════
|
||||
do_report() {
|
||||
[[ ! -d "$RESULTS_DIR" ]] && die "Results directory not found: ${RESULTS_DIR}"
|
||||
|
||||
section_header "Test Run History"
|
||||
|
||||
printf " ${BOLD}%-20s %-30s %8s %12s %s${RESET}\n" "RUN ID" "SCRIPT" "VUS" "DURATION" "STATUS"
|
||||
printf " %s\n" "$(printf '%.0s─' {1..80})"
|
||||
|
||||
local count=0
|
||||
while IFS= read -r d; do
|
||||
local meta="${d}/metadata.json"
|
||||
[[ ! -f "$meta" ]] && continue
|
||||
|
||||
local run_id script vus duration
|
||||
run_id=$(basename "$d")
|
||||
if command -v jq &>/dev/null; then
|
||||
script=$(jq -r '.script // "unknown"' "$meta" 2>/dev/null || echo "unknown")
|
||||
vus=$(jq -r '.vus // "?"' "$meta" 2>/dev/null || echo "?")
|
||||
duration=$(jq -r '.duration // "?"' "$meta" 2>/dev/null || echo "?")
|
||||
else
|
||||
script="(jq required)"
|
||||
vus="?"
|
||||
duration="?"
|
||||
fi
|
||||
|
||||
local status_icon="${GREEN}✓${RESET}"
|
||||
if [[ -f "${d}/summary.json" ]]; then
|
||||
local fail_rate
|
||||
fail_rate=$(jq -r '.metrics.http_req_failed.values.rate // 0' "${d}/summary.json" 2>/dev/null || echo 0)
|
||||
if awk "BEGIN{exit ($fail_rate > 0) ? 0 : 1}" 2>/dev/null; then
|
||||
status_icon="${RED}✗${RESET}"
|
||||
fi
|
||||
else
|
||||
status_icon="${YELLOW}?${RESET}"
|
||||
fi
|
||||
|
||||
printf " %-20s %-30s %8s %12s %b\n" "$run_id" "${script:0:28}" "$vus" "$duration" "$status_icon"
|
||||
((count++)) || true
|
||||
done < <(find "$RESULTS_DIR" -mindepth 1 -maxdepth 1 -type d 2>/dev/null | sort -r)
|
||||
|
||||
echo ""
|
||||
field "Total runs:" "$count"
|
||||
|
||||
if [[ "$count" -eq 0 ]]; then
|
||||
warn "No test runs found in ${RESULTS_DIR}"
|
||||
fi
|
||||
}
|
||||
|
||||
# ══════════════════════════════════════════════════════════════════════
|
||||
# INSPECT MODE
|
||||
# ══════════════════════════════════════════════════════════════════════
|
||||
do_inspect() {
|
||||
[[ -z "$INSPECT_SCRIPT" ]] && die "No test script specified"
|
||||
[[ ! -f "$INSPECT_SCRIPT" ]] && die "Test script not found: ${INSPECT_SCRIPT}"
|
||||
|
||||
section_header "Test Inspection"
|
||||
field "Script:" "$INSPECT_SCRIPT"
|
||||
field "Size:" "$(stat --printf="%s" "$INSPECT_SCRIPT" 2>/dev/null || stat -f%z "$INSPECT_SCRIPT" 2>/dev/null || echo unknown) bytes"
|
||||
echo ""
|
||||
|
||||
log "k6 command that would execute:"
|
||||
echo ""
|
||||
echo -e " ${DIM}${K6_PATH} run \\"
|
||||
echo -e " --vus ${VUS} \\"
|
||||
echo -e " --duration ${DURATION} \\"
|
||||
[[ -n "$PUSH_GW" ]] && echo -e " --out experimental-prometheus-rw=${PUSH_GW} \\"
|
||||
[[ -n "$THRESHOLDS_FILE" ]] && echo -e " --config ${THRESHOLDS_FILE} \\"
|
||||
for ev in "${ENV_VARS[@]+"${ENV_VARS[@]}"}"; do
|
||||
echo -e " -e ${ev} \\"
|
||||
done
|
||||
echo -e " ${INSPECT_SCRIPT}${RESET}"
|
||||
|
||||
echo ""
|
||||
if command -v "$K6_PATH" &>/dev/null; then
|
||||
field_color "k6 version:" "${GREEN}$("$K6_PATH" version 2>/dev/null | head -1)${RESET}"
|
||||
else
|
||||
field_color "k6 status:" "${RED}not installed${RESET}"
|
||||
fi
|
||||
}
|
||||
|
||||
# ══════════════════════════════════════════════════════════════════════
|
||||
# HELP
|
||||
# ══════════════════════════════════════════════════════════════════════
|
||||
show_help() {
|
||||
cat <<EOF
|
||||
${BOLD}${SCRIPT_NAME}${RESET} — k6 Load Test Runner
|
||||
|
||||
Run k6 load tests with Prometheus metrics push, result comparison,
|
||||
and formatted reporting.
|
||||
|
||||
${BOLD}MODES${RESET}
|
||||
--run SCRIPT Execute a k6 test script
|
||||
--list [DIR] List available test scripts (default: current dir)
|
||||
--compare RUN_ID Compare latest run against a previous run
|
||||
--report Show test run history
|
||||
--inspect SCRIPT Show what would execute without running
|
||||
|
||||
${BOLD}OPTIONS${RESET}
|
||||
--vus N Number of virtual users (default: 10)
|
||||
--duration TIME Test duration (default: 30s)
|
||||
--push-gw URL Prometheus push gateway URL
|
||||
--results-dir DIR Results directory (default: ./k6-results)
|
||||
--thresholds FILE k6 config file with threshold definitions
|
||||
--env KEY=VALUE Pass environment variable to k6 (repeatable)
|
||||
--tag KEY=VALUE Add tag to k6 metrics
|
||||
--format FORMAT Output format: text, json, csv (default: text)
|
||||
--verbose Debug output
|
||||
--no-color Disable colored output
|
||||
--help Show this help message
|
||||
|
||||
${BOLD}ENVIRONMENT VARIABLES${RESET}
|
||||
K6_PATH Path to k6 binary (default: k6)
|
||||
K6_VUS Default virtual users (default: 10)
|
||||
K6_DURATION Default test duration (default: 30s)
|
||||
K6_PUSH_GATEWAY Prometheus push gateway URL
|
||||
K6_RESULTS_DIR Results directory (default: ./k6-results)
|
||||
K6_FORMAT Output format (default: text)
|
||||
K6_TAGS Default tags for k6 metrics
|
||||
VERBOSE Enable verbose output (true/false)
|
||||
COLOR Color mode: auto, always, never
|
||||
|
||||
${BOLD}EXAMPLES${RESET}
|
||||
# Run a load test
|
||||
${SCRIPT_NAME} --run ./tests/load.js
|
||||
|
||||
# Run with custom VUs and duration
|
||||
${SCRIPT_NAME} --run ./tests/api.js --vus 50 --duration 2m
|
||||
|
||||
# Run with Prometheus push
|
||||
${SCRIPT_NAME} --run ./tests/load.js --push-gw http://pushgw:9091
|
||||
|
||||
# Compare runs
|
||||
${SCRIPT_NAME} --compare 20260410-143000
|
||||
|
||||
# List available tests
|
||||
${SCRIPT_NAME} --list ./tests/
|
||||
|
||||
# Inspect without running
|
||||
${SCRIPT_NAME} --inspect ./tests/load.js --vus 100 --duration 5m
|
||||
|
||||
${BOLD}EXIT CODES${RESET}
|
||||
0 Test passed
|
||||
1 Runtime error
|
||||
2 Test thresholds exceeded
|
||||
EOF
|
||||
}
|
||||
|
||||
# ══════════════════════════════════════════════════════════════════════
|
||||
# PARSE ARGS
|
||||
# ══════════════════════════════════════════════════════════════════════
|
||||
parse_args() {
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--run) RUN_MODE="run"; TEST_SCRIPT="${2:?--run requires a script path}"; shift 2 ;;
|
||||
--list) RUN_MODE="list"; LIST_DIR="${2:-.}"; shift; if [[ "${1:-}" != -* ]]; then shift; fi ;;
|
||||
--compare) RUN_MODE="compare"; COMPARE_RUN="${2:?--compare requires a run ID}"; shift 2 ;;
|
||||
--report) RUN_MODE="report"; shift ;;
|
||||
--inspect) RUN_MODE="inspect"; INSPECT_SCRIPT="${2:?--inspect requires a script path}"; shift 2 ;;
|
||||
--vus) VUS="${2:?--vus requires a number}"; shift 2 ;;
|
||||
--duration) DURATION="${2:?--duration requires a value}"; shift 2 ;;
|
||||
--push-gw) PUSH_GW="${2:?--push-gw requires a URL}"; shift 2 ;;
|
||||
--results-dir) RESULTS_DIR="${2:?--results-dir requires a path}"; shift 2 ;;
|
||||
--thresholds) THRESHOLDS_FILE="${2:?--thresholds requires a file}"; shift 2 ;;
|
||||
--env) ENV_VARS+=("${2:?--env requires KEY=VALUE}"); shift 2 ;;
|
||||
--tag) TAGS="${2:?--tag requires KEY=VALUE}"; shift 2 ;;
|
||||
--format) OUTPUT_FORMAT="${2:?--format requires a value}"; export OUTPUT_FORMAT; shift 2 ;;
|
||||
--verbose) VERBOSE="true"; shift ;;
|
||||
--no-color) COLOR="never"; shift ;;
|
||||
--help|-h) setup_colors; show_help; exit 0 ;;
|
||||
*) die "Unknown option: $1 (see --help)" ;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
# ══════════════════════════════════════════════════════════════════════
|
||||
# MAIN
|
||||
# ══════════════════════════════════════════════════════════════════════
|
||||
main() {
|
||||
parse_args "$@"
|
||||
setup_colors
|
||||
|
||||
if [[ -z "$RUN_MODE" ]]; then
|
||||
err "No mode specified"
|
||||
echo ""
|
||||
show_help
|
||||
exit 1
|
||||
fi
|
||||
|
||||
START_TIME=$(date +%s)
|
||||
|
||||
case "$RUN_MODE" in
|
||||
run) do_run ;;
|
||||
list) do_list ;;
|
||||
compare) do_compare ;;
|
||||
report) do_report ;;
|
||||
inspect) do_inspect ;;
|
||||
*) die "Unknown mode: ${RUN_MODE}" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user