File: extended_error.test.lua

package info (click to toggle)
tarantool 2.6.0-1.4
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 85,412 kB
  • sloc: ansic: 513,775; cpp: 69,493; sh: 25,650; python: 19,190; perl: 14,973; makefile: 4,178; yacc: 1,329; sql: 1,074; pascal: 620; ruby: 190; awk: 18; lisp: 7
file content (150 lines) | stat: -rwxr-xr-x 4,078 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#! /usr/bin/env tarantool

local netbox = require('net.box')
local os = require('os')
local tap = require('tap')

box.cfg{
    listen = os.getenv('LISTEN')
}

--
-- gh-4398: error objects after transmission through network
-- should not loose their fields and type.
--

-- Create AccessDeniedError. It is going to be used in the tests
-- below.
function forbidden_function()
    return nil
end
local user = box.session.user()
box.session.su('admin')
box.schema.func.create('forbidden_function')
box.session.su('guest')
local tmp = box.func.forbidden_function
local access_denied_error
tmp, access_denied_error = pcall(tmp.call, tmp)
box.session.su('admin')
box.schema.func.drop('forbidden_function')
box.session.su(user)

local test = tap.test('Error marshaling')
test:plan(12)

function error_new(...)
    return box.error.new(...)
end

function error_throw(...)
    box.error(error_new(...))
end

function error_new_stacked(args1, args2)
    local e1 = box.error.new(args1)
    local e2 = box.error.new(args2)
    e1:set_prev(e2)
    return e1
end

function error_throw_stacked(...)
    box.error(error_new_stacked(...))
end

function error_access_denied()
    return access_denied_error
end

function error_throw_access_denied()
    box.error(access_denied_error)
end

local function check_error(err, check_list)
    assert(type(check_list) == 'table')
    if type(err.trace) ~= 'table' or err.trace[1] == nil or
       err.trace[1].file == nil or err.trace[1].line == nil then
        return false
    end
    for k, v in pairs(check_list) do
        if err[k] ~= v then
            return false
        end
    end
    return true
end

box.schema.user.grant('guest', 'super')
local c = netbox.connect(box.cfg.listen)
c:eval('box.session.settings.error_marshaling_enabled = true')
local args = {{code = 1000, reason = 'Reason'}}
local err = c:call('error_new', args)
local checks = {
    code = 1000,
    message = 'Reason',
    base_type = 'ClientError',
    type = 'ClientError',
}
test:ok(check_error(err, checks), "ClientError marshaling")
tmp, err = pcall(c.call, c, 'error_throw', args)
test:ok(check_error(err, checks), "ClientError marshaling in iproto fields")

args = {{code = 1001, reason = 'Reason2', type = 'MyError'}}
err = c:call('error_new', args)
checks = {
    code = 1001,
    message = 'Reason2',
    base_type = 'CustomError',
    type = 'MyError',
}
test:ok(check_error(err, checks), "CustomError marshaling")
tmp, err = pcall(c.call, c, 'error_throw', args)
test:ok(check_error(err, checks), "CustomError marshaling in iproto fields")

err = c:call('error_access_denied')
checks = {
    code = 42,
    type = 'AccessDeniedError',
    base_type = 'AccessDeniedError',
    message = "Execute access to function 'forbidden_function' is denied for user 'guest'",
    object_type = 'function',
    object_name = 'forbidden_function',
    access_type = 'Execute',
}
test:ok(check_error(err, checks), "AccessDeniedError marshaling")
tmp, err = pcall(c.call, c, 'error_throw_access_denied')
test:ok(check_error(err, checks), "AccessDeniedError marshaling in iproto fields")

args = {
    {code = 1003, reason = 'Reason3', type = 'MyError2'},
    {code = 1004, reason = 'Reason4'}
}
err = c:call('error_new_stacked', args)
local err1 = err
local err2 = err.prev
test:isnt(err2, nil, 'Stack is received')
local checks1 = {
    code = 1003,
    message = 'Reason3',
    base_type = 'CustomError',
    type = 'MyError2'
}
test:ok(check_error(err1, checks1), "First error in the stack")
local checks2 = {
    code = 1004,
    message = 'Reason4',
    base_type = 'ClientError',
    type = 'ClientError'
}
test:ok(check_error(err2, checks2), "Second error in the stack")

tmp, err = pcall(c.call, c, 'error_throw_stacked', args)
err1 = err
err2 = err.prev
test:isnt(err2, nil, 'Stack is received via iproto fields')
test:ok(check_error(err1, checks1), "First error in the stack in iproto fields")
test:ok(check_error(err2, checks2), "Second error in the stack in iproto fields")

c:close()
box.schema.user.revoke('guest', 'super')

os.exit(test:check() and 0 or 1)