Bound every test with a wall-clock timeout
A runaway test spins at full CPU instead of failing, stalling the whole run. A debug hook enforces a per-test deadline; the JIT stays off so the hook is reachable from compiled code.
This commit is contained in:
+26
-1
@@ -1,14 +1,39 @@
|
||||
local M = { passed = 0, failed = 0, failures = {} }
|
||||
|
||||
local uv = vim.uv or vim.loop
|
||||
local current = '?'
|
||||
|
||||
M.timeout_ms = tonumber(vim.env.ARTI_PACK_TEST_TIMEOUT_MS) or 5000
|
||||
|
||||
-- LuaJIT never reaches a debug hook from inside a compiled trace, so the
|
||||
-- interpreter has to stay in charge for the budget below to be enforceable.
|
||||
if _G.jit then
|
||||
_G.jit.off()
|
||||
_G.jit.flush()
|
||||
end
|
||||
|
||||
local HOOK_INTERVAL = 20000
|
||||
|
||||
local function bounded(fn)
|
||||
local deadline = uv.hrtime() + M.timeout_ms * 1e6
|
||||
debug.sethook(function()
|
||||
if uv.hrtime() > deadline then
|
||||
debug.sethook()
|
||||
error(string.format('timed out after %dms', M.timeout_ms), 0)
|
||||
end
|
||||
end, '', HOOK_INTERVAL)
|
||||
local ok, err = pcall(fn)
|
||||
debug.sethook()
|
||||
return ok, err
|
||||
end
|
||||
|
||||
function M.describe(name, fn)
|
||||
current = name
|
||||
fn()
|
||||
end
|
||||
|
||||
function M.it(name, fn)
|
||||
local ok, err = pcall(fn)
|
||||
local ok, err = bounded(fn)
|
||||
if ok then
|
||||
M.passed = M.passed + 1
|
||||
else
|
||||
|
||||
Reference in New Issue
Block a user