final TESTING
Some checks failed
Test / test (push) Has been cancelled

This commit is contained in:
2026-06-13 14:11:42 +07:00
parent c05b1d5f5c
commit 9776e29d7d
24 changed files with 434 additions and 392 deletions

71
scripts/lib/bench.sh Executable file
View File

@@ -0,0 +1,71 @@
# shellcheck shell=bash
bench_http_endpoint() {
local label="$1" method="$2" path="$3" base="$4"
local body="${5:-}" requests="${6:-${BENCH_REQUESTS:-100}}" warmup="${7:-${BENCH_WARMUP:-10}}"
python3 - "$label" "$method" "$base$path" "$requests" "$warmup" "$body" <<'PY'
import statistics
import sys
import urllib.request
label, method, url, n_req, n_warm, body = sys.argv[1:7]
n_req = int(n_req)
n_warm = int(n_warm)
data = body.encode() if body else None
headers = {"Content-Type": "application/json"} if data else {}
def once():
req = urllib.request.Request(url, data=data, headers=headers, method=method)
t0 = __import__("time").perf_counter()
with urllib.request.urlopen(req, timeout=10) as resp:
resp.read()
return (__import__("time").perf_counter() - t0) * 1000.0
for _ in range(n_warm):
try:
once()
except Exception:
pass
samples = []
errors = 0
for _ in range(n_req):
try:
samples.append(once())
except Exception:
errors += 1
if not samples:
print(f"{label}: FAIL errors={errors}")
else:
samples.sort()
def pct(p):
i = max(0, min(len(samples) - 1, int(len(samples) * p / 100.0) - 1))
return samples[i]
print(
f"{label}: ok={len(samples)} err={errors} "
f"p50={pct(50):.2f}ms p95={pct(95):.2f}ms avg={statistics.mean(samples):.2f}ms max={samples[-1]:.2f}ms"
)
PY
}
bench_http_suite() {
local base="${1:-$LM_URL}"
if ! curl -sf "${base}/api/health" >/dev/null; then
echo "Server không phản hồi tại $base" >&2
return 1
fi
bench_http_endpoint "GET /api/health" GET "/api/health" "$base"
bench_http_endpoint "GET /api/state" GET "/api/state" "$base"
bench_http_endpoint "GET /api/missions" GET "/api/missions" "$base"
bench_http_endpoint "GET /api/mission_queue" GET "/api/mission_queue" "$base"
bench_http_endpoint "GET /api/v2.0.0/mission_queue" GET "/api/v2.0.0/mission_queue" "$base"
bench_http_endpoint "GET /" GET "/" "$base"
bench_http_endpoint "GET /missions.js" GET "/missions.js" "$base"
local mid
mid="$(curl -sf "${base}/api/missions" | python3 -c "import json,sys; m=json.load(sys.stdin).get('missions',[]); print(m[0]['id'] if m else '')" 2>/dev/null || true)"
if [[ -n "$mid" ]]; then
bench_http_endpoint "POST /api/v2.0.0/mission_queue" POST "/api/v2.0.0/mission_queue" "$base" \
"{\"mission_id\":\"${mid}\",\"priority\":0}"
fi
}

33
scripts/lib/common.sh Executable file
View File

@@ -0,0 +1,33 @@
# Shared paths and helpers for Test3 scripts.
# shellcheck shell=bash
_lm_lib_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
LM_ROOT="$(cd "$_lm_lib_dir/../.." && pwd)"
LM_SCRIPTS="$(cd "$_lm_lib_dir/.." && pwd)"
LM_CONTAINER="${LM_CONTAINER:-lidar-manager-limited}"
LM_URL="${LM_URL:-http://127.0.0.1:8080}"
LM_TEST_PORT="${LM_TEST_PORT:-18080}"
wait_for_health() {
local base="${1:-$LM_URL}"
local tries="${2:-40}"
local i
for ((i = 1; i <= tries; i++)); do
if curl -sf "${base}/api/health" >/dev/null 2>&1; then
return 0
fi
sleep 0.5
done
return 1
}
free_port() {
local port="$1"
if command -v fuser >/dev/null 2>&1; then
fuser -k "${port}/tcp" 2>/dev/null || true
elif command -v lsof >/dev/null 2>&1; then
local pids
pids="$(lsof -ti "tcp:${port}" 2>/dev/null || true)"
[[ -n "$pids" ]] && kill $pids 2>/dev/null || true
fi
}

32
scripts/lib/docker.sh Executable file
View File

@@ -0,0 +1,32 @@
# shellcheck shell=bash
# shellcheck source=common.sh
source "$(dirname "${BASH_SOURCE[0]}")/common.sh"
docker_cmd() {
if docker info >/dev/null 2>&1; then
DOCKER=(docker)
elif sudo -n docker info >/dev/null 2>&1; then
DOCKER=(sudo docker)
else
DOCKER=(sudo docker)
fi
}
require_container() {
local name="${1:-$LM_CONTAINER}"
docker_cmd
if ! "${DOCKER[@]}" ps --format '{{.Names}}' | grep -qx "$name"; then
echo "Container '$name' không chạy. Thử: ./scripts/lm.sh docker up" >&2
exit 1
fi
}
print_container_limits() {
local name="${1:-$LM_CONTAINER}"
local nano mem cpus ram_mb
nano="$("${DOCKER[@]}" inspect -f '{{.HostConfig.NanoCpus}}' "$name")"
mem="$("${DOCKER[@]}" inspect -f '{{.HostConfig.Memory}}' "$name")"
cpus="$(awk "BEGIN { if ($nano > 0) printf \"%.2f\", $nano / 1000000000; else print \"unlimited\" }")"
ram_mb=$((mem / 1048576))
echo " CPUs quota = ${cpus} core(s), RAM max = ${ram_mb} MB"
}