tests/_runner.lua: Allow non-step based tests

The current _runner.lua expects a table containing steps to be passed
in. However, not all tests look like this. This commits adds an API to
the runner that allows tests to run however they like. They just have to
call run_direct() initially and call done() when they are finished.

Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Uli Schlachter 2019-02-28 09:22:36 +01:00
parent 2d2dba0d80
commit f304c608e8
1 changed files with 58 additions and 40 deletions

View File

@ -43,7 +43,54 @@ runner.step_kill_clients = function(step)
end end
end end
runner.run_steps = function(steps, options) --- Print a message if verbose mode is enabled.
-- @tparam string message The message to print.
function runner.verbose(message)
if verbose then
io.stderr:write(message .. "\n")
end
end
--- When using run_direct(), this function indicates that the test is now done.
-- @tparam[opt=nil] string message An error message explaining the test failure, if it failed.
function runner.done(message)
if message then
io.stderr:write("Error: " .. message .. "\n")
if not runner.quit_awesome_on_error then
io.stderr:write("Keeping awesome open...\n")
return
end
end
local client_count = #client.get()
if client_count > 0 then
io.stderr:write(string.format(
"NOTE: there were %d clients left after the test.\n", client_count))
-- Remove any clients.
for _,c in ipairs(client.get()) do
c:kill()
end
end
if not message then
io.stderr:write("Test finished successfully.\n")
end
awesome.quit()
end
--- This function is called to indicate that a test does not use the run_steps()
-- facility, but instead runs something else directly.
function runner.run_direct()
assert(not running, "API abuse: Test was started twice")
running = true
end
--- Start some step-wise tests. The given steps are called in order until all
-- succeeded. Each step is a function that can return true/false to indicate
-- success/failure, but can also return nothing if it needs to be called again
-- later.
function runner.run_steps(steps, options)
-- Setup timer/timeout to limit waiting for signal and quitting awesome. -- Setup timer/timeout to limit waiting for signal and quitting awesome.
local t = timer({timeout=0}) local t = timer({timeout=0})
local wait=20 local wait=20
@ -52,8 +99,7 @@ runner.run_steps = function(steps, options)
options = options or { options = options or {
kill_clients=true, kill_clients=true,
} }
assert(not running, "run_steps() was called twice") runner.run_direct()
running = true
if options.kill_clients then if options.kill_clients then
-- Add a final step to kill all clients and wait for them to finish. -- Add a final step to kill all clients and wait for them to finish.
@ -65,9 +111,7 @@ runner.run_steps = function(steps, options)
io.flush() -- for "tail -f". io.flush() -- for "tail -f".
step_count = step_count + 1 step_count = step_count + 1
local step_as_string = step..'/'..#steps..' (@'..step_count..')' local step_as_string = step..'/'..#steps..' (@'..step_count..')'
if verbose then runner.verbose(string.format('Running step %s..\n', step_as_string))
io.stderr:write(string.format('Running step %s..\n', step_as_string))
end
-- Call the current step's function. -- Call the current step's function.
local success, result = xpcall(function() local success, result = xpcall(function()
@ -75,14 +119,9 @@ runner.run_steps = function(steps, options)
end, debug.traceback) end, debug.traceback)
if not success then if not success then
io.stderr:write('Error: running function for step ' runner.done('running function for step '
..step_as_string..': '..tostring(result)..'!\n') ..step_as_string..': '..tostring(result)..'!')
t:stop() t:stop()
if not runner.quit_awesome_on_error then
io.stderr:write("Keeping awesome open...\n")
return -- keep awesome open on error.
end
elseif result then elseif result then
-- true: test succeeded. -- true: test succeeded.
if step < #steps then if step < #steps then
@ -92,16 +131,12 @@ runner.run_steps = function(steps, options)
wait = 20 wait = 20
t.timeout = 0 t.timeout = 0
t:again() t:again()
return else
-- All steps finished, we are done.
runner.done()
end end
elseif result == false then elseif result == false then
io.stderr:write("Step "..step_as_string.." failed (returned false).\n") runner.done("Step "..step_as_string.." failed (returned false).")
if not runner.quit_awesome_on_error then
io.stderr:write("Keeping awesome open...\n")
return
end
else else
-- No result yet, run this step again. -- No result yet, run this step again.
wait = wait-1 wait = wait-1
@ -109,28 +144,11 @@ runner.run_steps = function(steps, options)
t.timeout = 0.1 t.timeout = 0.1
t:again() t:again()
else else
io.stderr:write("Error: timeout waiting for signal in step " runner.done("timeout waiting for signal in step "
..step_as_string..".\n") ..step_as_string..".")
t:stop() t:stop()
end end
return
end end
local client_count = #client.get()
if client_count > 0 then
io.stderr:write(string.format(
"NOTE: there were %d clients left after the test.\n", client_count))
-- Remove any clients.
for _,c in ipairs(client.get()) do
c:kill()
end
end
if success and result then
io.stderr:write("Test finished successfully.\n")
end
awesome.quit()
end) end) end) end)
t:start() t:start()
end end