Files
upstream-jitsi-meet/tests/prosody/busted_allure.lua
upstream-mirror 1d2bfcac0c
Some checks failed
Prosody Plugin Tests / test (push) Failing after 10m11s
Close stale issues and PRs / stale (push) Failing after 1s
snapshot of https://github.com/jitsi/jitsi-meet.git @ fd1749dd28f4138aa80234fc7f311b19aaffa0e7 (2026-09-15)
2026-09-15 15:56:32 +05:00

183 lines
5.9 KiB
Lua

-- Custom busted output handler that writes Allure-native JSON result files.
-- Produces {uuid}-result.json files in spec/allure-results/ with proper
-- parentSuite/suite/subSuite labels derived from the describe() nesting.
--
-- Usage (run from tests/prosody/):
-- busted --output busted_allure lua/
local io = io
local os = os
local math = math
local string = string
local table = table
return function(options)
local busted = require 'busted'
local handler = require 'busted.outputHandlers.base'()
-- Output directory. When run via npm (from tests/prosody/) the ALLURE_RESULTS_DIR
-- env var is set to an absolute path so results land in tests/prosody/allure-results/
-- regardless of busted's CWD (resources/prosody-plugins/).
local results_dir = os.getenv('ALLURE_RESULTS_DIR') or 'allure-results'
local test_start_ms = 0
local current_status = 'passed'
local current_message = nil
local current_trace = nil
local counter = 0
local passed = 0
local failed = 0
local skipped = 0
math.randomseed(os.time())
local function now_ms()
return math.floor(os.time() * 1000)
end
local function uuid()
counter = counter + 1
return string.format('%08x-%04x-4%03x-%04x-%08x%04x',
os.time() % 0xffffffff,
math.random(0, 0xffff),
math.random(0, 0xfff),
math.random(0x8000, 0xbfff),
counter,
math.random(0, 0xffff)
)
end
local function escape_json(s)
s = tostring(s or '')
s = s:gsub('\\', '\\\\')
s = s:gsub('"', '\\"')
s = s:gsub('\n', '\\n')
s = s:gsub('\r', '\\r')
s = s:gsub('\t', '\\t')
return s
end
-- Traverse element's parent chain to collect describe() names.
-- Returns an array like {'luajwtjitsi', 'verify', 'HS256'}.
local function get_describe_stack(element)
local stack = {}
local parent = busted.parent(element)
while parent and parent.descriptor ~= 'file' do
table.insert(stack, 1, parent.name)
parent = busted.parent(parent)
end
return stack
end
local function write_result(element, allure_status, start_ms, stop_ms, message, trace)
local stack = get_describe_stack(element)
local labels = {}
if stack[1] then
table.insert(labels, string.format(
'{"name":"parentSuite","value":"%s"}', escape_json(stack[1])))
end
if stack[2] then
table.insert(labels, string.format(
'{"name":"suite","value":"%s"}', escape_json(stack[2])))
end
if #stack >= 3 then
local parts = {}
for i = 3, #stack do parts[#parts + 1] = stack[i] end
table.insert(labels, string.format(
'{"name":"subSuite","value":"%s"}', escape_json(table.concat(parts, ' \xe2\x80\xba '))))
end
table.insert(labels, '{"name":"framework","value":"busted"}')
table.insert(labels, '{"name":"language","value":"lua"}')
local status_block = ''
if message or trace then
status_block = string.format(
',"statusDetails":{"message":"%s","trace":"%s"}',
escape_json(message), escape_json(trace))
end
local id = uuid()
local json = string.format(
'{"uuid":"%s","name":"%s","status":"%s","start":%d,"stop":%d,"labels":[%s]%s}',
id,
escape_json(element.name),
allure_status,
start_ms,
stop_ms,
table.concat(labels, ','),
status_block
)
local f = io.open(results_dir .. '/' .. id .. '-result.json', 'w')
if f then
f:write(json)
f:write('\n')
f:close()
end
end
handler.testStart = function(element, parent)
test_start_ms = now_ms()
current_status = 'passed'
current_message = nil
current_trace = nil
return nil, true
end
handler.testEnd = function(element, parent, status)
local stop_ms = now_ms()
local allure_status
if status == 'success' then
allure_status = 'passed'
passed = passed + 1
io.write('.')
elseif status == 'pending' then
allure_status = 'skipped'
skipped = skipped + 1
local p = handler.pendings[#handler.pendings]
if p then current_message = p.message end
io.write('S')
else
-- failure or error — current_status set by failureTest/errorTest
allure_status = current_status
failed = failed + 1
io.write('F')
end
io.flush()
write_result(element, allure_status, test_start_ms, stop_ms,
current_message, current_trace)
return nil, true
end
handler.failureTest = function(element, parent, message, trace)
current_status = 'failed'
current_message = message
current_trace = trace and trace.traceback
return nil, true
end
handler.errorTest = function(element, parent, message, trace)
current_status = 'broken'
current_message = message
current_trace = trace and trace.traceback
return nil, true
end
handler.exit = function()
io.write(string.format('\nLua tests: %d passed, %d failed, %d skipped\n',
passed, failed, skipped))
io.flush()
return nil, true
end
busted.subscribe({'test', 'start'}, handler.testStart, {predicate = handler.cancelOnPending})
busted.subscribe({'test', 'end'}, handler.testEnd, {predicate = handler.cancelOnPending})
busted.subscribe({'error', 'it'}, handler.errorTest)
busted.subscribe({'failure', 'it'}, handler.failureTest)
busted.subscribe({'exit'}, handler.exit)
return handler
end