snapshot of https://github.com/jitsi/jitsi-meet.git @ fd1749dd28f4138aa80234fc7f311b19aaffa0e7 (2026-09-15)
Some checks failed
Prosody Plugin Tests / test (push) Failing after 10m11s
Close stale issues and PRs / stale (push) Failing after 1s

This commit is contained in:
upstream-mirror
2026-09-15 15:56:32 +05:00
commit 1d2bfcac0c
3159 changed files with 464524 additions and 0 deletions

View File

@@ -0,0 +1,251 @@
-- Unit tests for mod_debug_traceback.lua
-- Run with busted from resources/prosody-plugins/:
-- busted spec/lua/
--
-- No Prosody installation required — all dependencies are stubbed.
-- The module exposes a global `dump_traceback` function that is called directly.
-- ---------------------------------------------------------------------------
-- Package preloads (must be registered before any dofile() call)
-- ---------------------------------------------------------------------------
package.preload['util.debug'] = function()
return { traceback = function() return "fake traceback\nframe 1\nframe 2" end }
end
package.preload['util.pposix'] = function()
return { getpid = function() return 99 end }
end
-- Minimal interpolation stub: substitutes {key} and {key.subkey} tokens.
-- Filters (yyyymmdd, hhmmss) are invoked when the key matches.
package.preload['util.interpolation'] = function()
return {
new = function(_, _, filters)
return function(template, vars)
return (template:gsub('{([^}]+)}', function(key)
-- Try filters first (yyyymmdd, hhmmss, ...)
if filters and filters[key] and vars.time then
return tostring(filters[key](vars.time))
end
-- Nested key lookup (e.g. paths.data)
local val = vars
for part in key:gmatch('[^%.]+') do
if type(val) == 'table' then val = val[part]
else val = nil; break end
end
return val ~= nil and tostring(val) or ('{' .. key .. '}')
end))
end
end,
}
end
-- util.signal is required when mod_posix lacks signal_events support
package.preload['util.signal'] = function()
return { signal = function() end }
end
-- ---------------------------------------------------------------------------
-- Prosody global required by get_filename (prosody.paths.data)
-- ---------------------------------------------------------------------------
_G.prosody = { paths = { data = "/tmp/prosody-test" } }
-- ---------------------------------------------------------------------------
-- Helper: load module with given option overrides
--
-- Returns: dump_traceback fn, log_calls list, fired_events list
-- ---------------------------------------------------------------------------
local function load_module(options)
options = options or {}
local log_calls = {}
local fired_events = {}
local mod = {
set_global = function() end,
get_option_string = function(_, key, default)
local v = options[key]
return v ~= nil and v or default
end,
log = function(_, level, fmt, ...)
local ok, msg = pcall(string.format, fmt, ...)
table.insert(log_calls, { level = level, msg = ok and msg or fmt })
end,
fire_event = function(_, name, data)
table.insert(fired_events, { name = name, data = data })
end,
depends = function() return {} end, -- no features.signal_events → util.signal path
hook = function() end,
wrap_event = function() end,
}
_G.module = mod
_G.dump_traceback = nil
local ok, err = pcall(dofile, "mod_debug_traceback.lua")
assert(ok, "module load failed: " .. tostring(err))
return _G.dump_traceback, log_calls, fired_events
end
-- ---------------------------------------------------------------------------
-- io.open helpers
-- ---------------------------------------------------------------------------
-- Replace io.open for the duration of fn(); collect written content per path.
local function with_mock_io(files_written, fn)
local orig = io.open
io.open = function(path, _mode)
local buf = {}
files_written[path] = buf
return {
write = function(_, s) buf[#buf + 1] = s end,
close = function() end,
}
end
fn()
io.open = orig
end
-- Replace io.open with one that always fails.
local function with_failing_io(fn)
local orig = io.open
io.open = function() return nil, "permission denied" end
fn()
io.open = orig
end
-- ---------------------------------------------------------------------------
-- Tests
-- ---------------------------------------------------------------------------
describe("mod_debug_traceback", function()
-- -----------------------------------------------------------------------
describe("dump_traceback()", function()
it("writes traceback content to file", function()
local dump = load_module()
local files = {}
with_mock_io(files, function() dump() end)
local path = next(files)
local content = table.concat(files[path])
assert.is_truthy(content:find("fake traceback", 1, true))
end)
it("surrounds traceback with header and footer lines", function()
local dump = load_module()
local files = {}
with_mock_io(files, function() dump() end)
local content = table.concat(files[next(files)])
assert.is_truthy(content:find("-- Traceback generated at", 1, true))
assert.is_truthy(content:find("-- End of traceback --", 1, true))
end)
it("fires debug_traceback/triggered event with a traceback string", function()
local dump, _, events = load_module()
local files = {}
with_mock_io(files, function() dump() end)
assert.equal(1, #events)
assert.equal("debug_traceback/triggered", events[1].name)
assert.is_string(events[1].data.traceback)
end)
it("fires event before attempting file write (even on io failure)", function()
local dump, _, events = load_module()
with_failing_io(function() dump() end)
assert.equal(1, #events)
assert.equal("debug_traceback/triggered", events[1].name)
end)
it("logs an error when the file cannot be opened", function()
local dump, log_calls = load_module()
with_failing_io(function() dump() end)
local found = false
for _, e in ipairs(log_calls) do
if e.level == "error" and e.msg:find("permission denied", 1, true) then
found = true
end
end
assert.is_true(found, "expected error log mentioning 'permission denied'")
end)
it("does not write a file when io.open fails", function()
local dump = load_module()
local files = {}
with_failing_io(function() dump() end)
-- files table should remain empty (no successful open)
assert.is_nil(next(files))
end)
it("default filename contains pid and starts with data path", function()
local dump = load_module()
local files = {}
with_mock_io(files, function() dump() end)
local path = next(files)
assert.is_truthy(path:find("/tmp/prosody-test", 1, true))
assert.is_truthy(path:find("99", 1, true)) -- pid = 99
end)
it("default filename embeds count (starting at 0)", function()
local dump = load_module()
local files = {}
with_mock_io(files, function() dump() end)
local path = next(files)
-- default template: traceback-{pid}-{count}.log → count=0 on first call
assert.is_truthy(path:find("%-0%.log$"))
end)
it("increments count between calls producing distinct filenames", function()
local dump = load_module()
local paths = {}
local orig = io.open
io.open = function(path, _)
paths[#paths + 1] = path
return { write = function() end, close = function() end }
end
dump()
dump()
io.open = orig
assert.equal(2, #paths)
assert.not_equal(paths[1], paths[2])
end)
it("uses custom signal name in info log message", function()
local dump, log_calls = load_module({ debug_traceback_signal = "SIGUSR2" })
local files = {}
with_mock_io(files, function() dump() end)
local found = false
for _, e in ipairs(log_calls) do
if e.level == "info" and e.msg:find("SIGUSR2", 1, true) then
found = true
end
end
assert.is_true(found, "expected info log mentioning 'SIGUSR2'")
end)
it("uses custom filename template from config", function()
local dump = load_module({
debug_traceback_filename = "/custom/tb-{pid}.log",
})
local files = {}
with_mock_io(files, function() dump() end)
local path = next(files)
assert.equal("/custom/tb-99.log", path)
end)
end) -- dump_traceback()
end)