Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## Unreleased

- Implemented verbose serialization of uncaught box errors thrown in tests
(gh-445).
- Fixed a bug when errors reported by the address sanitizer during process
termination were ignored (gh-460).

Expand Down
22 changes: 2 additions & 20 deletions luatest/assertions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ local log = require('luatest.log')
local utils = require('luatest.utils')
local tarantool = require('tarantool')
local fio = require('fio')
local ffi = require('ffi')

local prettystr = pp.tostring
local prettystr_pairs = pp.tostring_pair
Expand All @@ -22,8 +21,6 @@ local M = {}

local xfail = false

local box_error_type = ffi.typeof(box.error.new(box.error.UNKNOWN))

-- private exported functions (for testing)
M.private = {}

Expand Down Expand Up @@ -159,7 +156,7 @@ local function pcall_check_trace(level, fn, ...)
if ok then
return ok, err
end
if type(err) ~= 'cdata' or ffi.typeof(err) ~= box_error_type then
if not utils.is_box_error(err) then
fail_fmt(level + 1, nil, 'Error raised is not a box.error: %s',
prettystr(err))
end
Expand Down Expand Up @@ -704,21 +701,6 @@ function M.assert_error_msg_matches(pattern, fn, ...)
end
end

-- If it is box.error that unpack it recursively. If it is not then
-- return argument unchanged.
local function error_unpack(err)
if type(err) ~= 'cdata' or ffi.typeof(err) ~= box_error_type then
return err
end
local unpacked = err:unpack()
local tmp = unpacked
while tmp.prev ~= nil do
tmp.prev = tmp.prev:unpack()
tmp = tmp.prev
end
return unpacked
end

--- Checks that error raised by function is table that includes expected one.
--- box.error is unpacked to convert to table. Stacked errors are supported.
--- That is if there is prev field in expected then it should cover prev field
Expand All @@ -734,7 +716,7 @@ function M.assert_error_covers(expected, fn, ...)
'Function successfully returned: %s\nExpected error: %s',
prettystr(actual), prettystr(expected))
end
local unpacked = error_unpack(actual)
local unpacked = utils.error_unpack(actual)
if not comparator.equals(table_slice(unpacked, expected), expected) then
actual, expected = prettystr_pairs(unpacked, expected)
fail_fmt(2, nil, 'Error expected: %s\nError received: %s',
Expand Down
3 changes: 3 additions & 0 deletions luatest/pp.lua
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
local Class = require('luatest.class')
local sorted_pairs = require('luatest.sorted_pairs')
local utils = require('luatest.utils')

-- Pretty printer.
local pp = {
Expand Down Expand Up @@ -160,6 +161,8 @@ function Formatter.mt:format(v, indentLevel)
return tostring(i)
end
end
elseif utils.is_box_error(v) then
return self:format_table(utils.error_unpack(v), indentLevel)
end

return tostring(v)
Expand Down
22 changes: 22 additions & 0 deletions luatest/utils.lua
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
local digest = require('digest')
local ffi = require('ffi')
local fio = require('fio')
local fun = require('fun')
local yaml = require('yaml')

local utils = {}

local box_error_type = ffi.typeof(box.error.new(box.error.UNKNOWN))

-- Helper to override methods.
--
-- utils.patch(target, 'method_name', function(super) return function(...)
Expand Down Expand Up @@ -251,4 +254,23 @@ function utils.table_is_array(t)
return true
end

function utils.is_box_error(err)
return type(err) == 'cdata' and ffi.typeof(err) == box_error_type
end

-- If it is box.error that unpack it recursively. If it is not then
-- return argument unchanged.
function utils.error_unpack(err)
if not utils.is_box_error(err) then
return err
end
local unpacked = err:unpack()
local tmp = unpacked
while tmp.prev ~= nil do
tmp.prev = tmp.prev:unpack()
tmp = tmp.prev
end
return unpacked
end

return utils
8 changes: 8 additions & 0 deletions test/pp_test.lua
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,11 @@ g.test_tostring_huge_table = function()
t.assert_equals(result, 0)
t.assert_almost_equals(clock.time() - start, 0, 0.5)
end

g.test_tostring_box_error = function()
local s = pp.tostring(box.error.new({
type = 'MyError', reason = 'FOOBAR',
}))
t.assert_str_contains(s, 'type = "MyError"')
t.assert_str_contains(s, 'message = "FOOBAR"')
end
13 changes: 13 additions & 0 deletions test/utils_test.lua
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,16 @@ g.test_table_pack = function()
t.assert_equals(utils.table_pack(1, 2, nil), {n = 3, 1, 2})
t.assert_equals(utils.table_pack(1, 2, nil, 3), {n = 4, 1, 2, nil, 3})
end

g.test_box_error = function()
local err = 'FOOBAR'
t.assert_not(utils.is_box_error(err))
t.assert_equals(utils.error_unpack(err), err)
err = box.error.new({type = 'MyError', reason = 'FOOBAR'})
err:set_prev(box.error.new({type = 'MyError2', reason = 'FUZZ'}))
t.assert(utils.is_box_error(err))
t.assert_covers(utils.error_unpack(err), {
type = 'MyError', message = 'FOOBAR',
prev = {type = 'MyError2', message = 'FUZZ'}
})
end
Loading