diff --git a/tests/_runner.lua b/tests/_runner.lua index fc65b67d5..532d8fed8 100644 --- a/tests/_runner.lua +++ b/tests/_runner.lua @@ -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