Skip to content

Latest commit

 

History

History
226 lines (177 loc) · 5.74 KB

conformance.md

File metadata and controls

226 lines (177 loc) · 5.74 KB

PM2 conformance

tests/conformance/run.js runs the same ecosystem file under PM2 and under Vexor, each in an isolated home, and compares what a probe app experienced (runs, argv, cwd, environment, instance numbers, stop signal) with what each tool reported (status, restart count). Run it in a throwaway container with pm2 and vexor on PATH:

docker run --rm -v "$PWD/dist":/bin2 -v "$PWD/tests/conformance":/c:ro node:22-alpine \
  sh -c 'npm i -g pm2@7.1.0 && cp /bin2/vexor /usr/local/bin/ && node /c/run.js --out /bin2/report.md'

Summary

Latest run: PM2 7.1.0 vs Vexor 0.1.1, 11 scenarios, 10 identical, 1 intentional difference.

The harness found two real incompatibilities in 0.1.0, both fixed for 0.1.1:

  • max_restarts: N allowed N + 1 runs before errored; PM2 allows N. max_restarts: 0 now means PM2's default, 16.
  • Graceful stop sent SIGTERM; PM2 sends SIGINT. Vexor now sends SIGINT by default, and the new kill_signal setting chooses another signal.

Intentional difference: wait_ready without a ready signal

When listen_timeout expires and the app never called process.send('ready'), PM2 marks the app online anyway. Vexor treats it as a failed start (stopped, counted against max_restarts, restarted with backoff; errored when the budget runs out), so a broken app is never reported healthy and a reload never retires a working process in favour of one that never became ready.

Not compared

Vexor limits automatic restarts to one per second per instance, while PM2 restarts immediately with restart_delay: 0. The final counts match (see crash-budget-0), but Vexor reaches them more slowly; the harness waits long enough for both.


Results

Generated by tests/conformance/run.js: PM2 7.1.0 vs vexor 0.1.1, Node v22.23.4, linux/arm64, 2026-10-23.

Each scenario runs the same ecosystem file under both tools. Rows show what the probe app saw and what each tool reported; bold rows differ.

crash-budget

How many runs before errored with max_restarts 3?

PM2 Vexor
runs 3 3
statuses ["errored"] ["errored"]
restarts [2] [2]
argv [] []
cwd "." "."
mode – –
a – –
insts ["0"] ["0"]
signal – –

crash-budget-0

How many runs before errored with max_restarts 0?

PM2 Vexor
runs 16 16
statuses ["errored"] ["errored"]
restarts [15] [15]
argv [] []
cwd "." "."
mode – –
a – –
insts ["0"] ["0"]
signal – –

crash-budget-1

How many runs before errored with max_restarts 1?

PM2 Vexor
runs 1 1
statuses ["errored"] ["errored"]
restarts [0] [0]
argv [] []
cwd "." "."
mode – –
a – –
insts ["0"] ["0"]
signal – –

vexor said: crash-budget-1 0 errored - - 0

paths

Relative cwd and script resolution

PM2 Vexor
runs 1 1
statuses ["online"] ["online"]
restarts [0] [0]
argv [] []
cwd "sub" "sub"
mode – –
a – –
insts ["0"] ["0"]
signal "SIGINT" "SIGINT"

env-args

env + env_production with --env production; args string splitting; instance var

PM2 Vexor
runs 2 2
statuses ["online","online"] ["online","online"]
restarts [0,0] [0,0]
argv ["x","y z","w"] ["x","y z","w"]
cwd "." "."
mode "prod" "prod"
a "1" "1"
insts ["0","1"] ["0","1"]
signal "SIGINT" "SIGINT"

stop-exit-codes

Exit 0 with stop_exit_codes [0]

PM2 Vexor
runs 1 1
statuses ["stopped"] ["stopped"]
restarts [0] [0]
argv [] []
cwd "." "."
mode – –
a – –
insts ["0"] ["0"]
signal – –

autorestart-false

Crash with autorestart false

PM2 Vexor
runs 1 1
statuses ["stopped"] ["stopped"]
restarts [0] [0]
argv [] []
cwd "." "."
mode – –
a – –
insts ["0"] ["0"]
signal – –

stop-signal

Which signal does stop send?

PM2 Vexor
runs 1 1
statuses ["stopped"] ["stopped"]
restarts [0] [0]
argv [] []
cwd "." "."
mode – –
a – –
insts ["0"] ["0"]
signal "SIGINT" "SIGINT"

wait-ready-missing

wait_ready with no ready signal (listen_timeout 1500)

PM2 Vexor
runs 1 1
statuses ["online"] ["errored"]
restarts [0] [0]
argv [] []
cwd "." "."
mode – –
a – –
insts ["0"] ["0"]
signal "SIGINT" "SIGINT"

wait-ready-ok

wait_ready with a ready signal

PM2 Vexor
runs 1 1
statuses ["online"] ["online"]
restarts [0] [0]
argv [] []
cwd "." "."
mode – –
a – –
insts ["0"] ["0"]
signal "SIGINT" "SIGINT"

cluster-instances

Cluster mode with 2 instances: instance numbers

PM2 Vexor
runs 2 2
statuses ["online","online"] ["online","online"]
restarts [0,0] [0,0]
argv [] []
cwd "." "."
mode – –
a – –
insts ["0","1"] ["0","1"]
signal "SIGINT" "SIGINT"