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
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.
local t = timer({timeout=0})
local wait=20
@ -52,8 +99,7 @@ runner.run_steps = function(steps, options)
options = options or {
kill_clients=true,
}
assert(not running, "run_steps() was called twice")
running = true
runner.run_direct()
if options.kill_clients then
-- 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".
step_count = step_count + 1
local step_as_string = step..'/'..#steps..' (@'..step_count..')'
if verbose then
io.stderr:write(string.format('Running step %s..\n', step_as_string))
end
runner.verbose(string.format('Running step %s..\n', step_as_string))
-- Call the current step's function.
local success, result = xpcall(function()
@ -75,14 +119,9 @@ runner.run_steps = function(steps, options)
end, debug.traceback)
if not success then
io.stderr:write('Error: running function for step '
..step_as_string..': '..tostring(result)..'!\n')
runner.done('running function for step '
..step_as_string..': '..tostring(result)..'!')
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
-- true: test succeeded.
if step < #steps then
@ -92,16 +131,12 @@ runner.run_steps = function(steps, options)
wait = 20
t.timeout = 0
t:again()
return
else
-- All steps finished, we are done.
runner.done()
end
elseif result == false then
io.stderr:write("Step "..step_as_string.." failed (returned false).\n")
if not runner.quit_awesome_on_error then
io.stderr:write("Keeping awesome open...\n")
return
end
runner.done("Step "..step_as_string.." failed (returned false).")
else
-- No result yet, run this step again.
wait = wait-1
@ -109,28 +144,11 @@ runner.run_steps = function(steps, options)
t.timeout = 0.1
t:again()
else
io.stderr:write("Error: timeout waiting for signal in step "
..step_as_string..".\n")
runner.done("timeout waiting for signal in step "
..step_as_string..".")
t:stop()
end
return
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)
t:start()
end