Perf test target — local server
This folder contains a simple static HTML page and a tiny Node server that exposes endpoints useful for load and performance testing.
Files added:
server.js— lightweight Node server (no dependencies) that servesperformance_test.htmland provides endpoints:/delay?ms=500— responds after the requested delay (ms) to simulate network latency./cpu?ms=100— busy-loop on the server for the requested ms to simulate CPU-bound responses./error— returns an HTTP 500 to test error handling./stream?chunks=5&delay=200— chunked transfer response to simulate slow streaming.
How to run (macOS / zsh):
# from this folder
# prefer npm start which checks for JMeter first
npm run check:jmeter # check whether JMeter is installed
npm start # will check for JMeter then start server if present
# if you want to skip the JMeter check (not recommended):
npm run start:force
# open http://localhost:3000/ in your browserQuick test examples:
# simple delay
curl -s "http://localhost:3000/delay?ms=1000" | jq
# simulate CPU work
curl -s "http://localhost:3000/cpu?ms=200" | jq
# streaming response
curl -N "http://localhost:3000/stream?chunks=5&delay=300"
# returns 500
curl -i "http://localhost:3000/error"Notes and suggestions:
- Use this server as a local target for tools like k6, autocannon, or ApacheBench to practice load testing.
- Keep tests small on your laptop; the
/cpuendpoint will block the Node event loop for the requested duration. - For distributed or larger tests, run workers on separate machines or inside containers.
Control API:
- The server starts a control API on the next port (PORT+1 by default). Example endpoints:
-
POST /run-test— start a test (JSON body: { url, vus, durationSeconds, engine })- Supported engines:
jmeter(requires JMeter on PATH) and an opt-indemoengine (ALLOW_DEMO=true).
- Supported engines:
-
GET /test/:id— query test status and results -
GET /history?limit=50— fetch recent test history (readstests_history.ndjson) -
POST /admin/cleanup-history— trim history tomaxEntries(JSON body: { maxEntries }). This endpoint is gated byALLOW_ADMIN=truefor safety. -
GET /history/download— download the rawtests_history.ndjsonfile. -
POST /admin/seed-history— append a few fake sample entries for UI testing (gated byALLOW_ADMIN=true). -
GET /history/tail— Server-Sent Events (SSE) live tail of history entries. Useful for UI live updates. -
POST /admin/clear-history— remove the history file (gated byALLOW_ADMIN=true).
-
Additional notes:
- Concurrency: The server limits concurrent running tests (env
MAX_CONCURRENT_TESTS, default 3). Extra tests are queued and started when capacity frees. - Demo mode: enable with
ALLOW_DEMO=true; demo caps are configurable withMAX_DEMO_VUS(default 50) andMAX_DEMO_DURATION(default 120 seconds). - History: test runs (queued/started/completed) are appended to
tests_history.ndjsonin the project folder. - Admin cleanup: If you don't want to enable
ALLOW_ADMIN, use the helpernode scripts/cleanup_history.js 1000to keep the last 1000 entries. - Installer: On macOS, you can try
npm run install:jmeterto install JMeter via Homebrew (this script attempts to callbrew).
Port conflicts and "Upgrade Required":
- If you receive an HTTP 426 "Upgrade Required" when calling the control API, another local tool (for example VS Code Live Preview) may be listening on that port. Check with
lsof -iTCP:<port> -sTCP:LISTENto find the process, or start the server with a differentPORTenvironment variable.
- Start the safe local target (serves sample endpoints):
cd perf_test
node server.js
# open http://localhost:4000/- Start the main runner (content UI + control API). Enable demo mode for an in-process runner:
cd .. # repo root
ALLOW_DEMO=true npm run start:force
# content UI -> http://localhost:3000/ control API -> http://localhost:3001/- Run a quick demo test (via UI or curl):
curl -s -X POST "http://localhost:3001/run-test" -H "Content-Type: application/json" \
-d '{"url":"http://localhost:4000/api/delay?ms=50","vus":5,"durationSeconds":10,"engine":"demo"}' | jq- View history and visualization:
- History JSON: http://localhost:3001/history
- Visualization: http://localhost:3000/visualize.html
This repo includes a JMeter test template jmeter_template.jmx and helper scripts in scripts/:
scripts/check_jmeter.js— checks whetherjmeteris on PATH.scripts/install_jmeter.sh— macOS Homebrew helper to install JMeter.scripts/run_jmeter.sh— wrapper to run the included JMX against a specified target.
Quick example (macOS):
# install jmeter (Homebrew)
npm run install:jmeter
# start the local perf target (content server)
npm run start:force &
# run the included JMeter template against the local perf_test target
TARGET=http://localhost:4000/api/delay?ms=50 VUS=10 DURATION=15 npm run jmeter:runNotes:
- The JMX template expects the host/path to be supplied via
-Jhost,-Jpath, etc.scripts/run_jmeter.shsets those based on theTARGETenv var. - Running JMeter may create result artifacts in
/tmp— check the printed results path after a run.