@@ -70,28 +70,47 @@ def setUp(self):
70
70
71
71
self .adm ("box.space['test']:truncate()" )
72
72
73
- conn_cases = {
74
- 'encoding_utf8' : {
73
+
74
+ # msgpack data for different encodings are actually the same,
75
+ # but sometimes python msgpack module use different string
76
+ # types (str8 and str16) for the same strings depending on use_bin_type:
77
+ #
78
+ # >>> msgpack.Packer(use_bin_type=True).pack('[string " local err = box.error.ne..."]')
79
+ # b'\xd9;[string " local err = box.error.ne..."]'
80
+ # >>> msgpack.Packer(use_bin_type=False).pack('[string " local err = box.error.ne..."]')
81
+ # b'\xda\x00;[string " local err = box.error.ne..."]'
82
+
83
+ cases = {
84
+ 'simple_error_for_encoding_utf8' : {
75
85
'conn' : 'conn_encoding_utf8' ,
76
86
'str_type' : str ,
87
+ 'python' : tarantool .BoxError (
88
+ type = 'ClientError' ,
89
+ file = '[string " local err = box.error.ne..."]' ,
90
+ line = 1 ,
91
+ message = 'Unknown error' ,
92
+ errno = 0 ,
93
+ errcode = 0 ,
94
+ ),
95
+ 'msgpack' : (b'\x81 \x00 \x91 \x86 \x00 \xab \x43 \x6c \x69 \x65 \x6e \x74 ' +
96
+ b'\x45 \x72 \x72 \x6f \x72 \x01 \xd9 \x3b \x5b \x73 \x74 \x72 ' +
97
+ b'\x69 \x6e \x67 \x20 \x22 \x20 \x20 \x20 \x20 \x20 \x20 \x20 ' +
98
+ b'\x20 \x20 \x20 \x20 \x20 \x20 \x20 \x20 \x20 \x20 \x20 \x20 ' +
99
+ b'\x20 \x20 \x6c \x6f \x63 \x61 \x6c \x20 \x65 \x72 \x72 \x20 ' +
100
+ b'\x3d \x20 \x62 \x6f \x78 \x2e \x65 \x72 \x72 \x6f \x72 \x2e ' +
101
+ b'\x6e \x65 \x2e \x2e \x2e \x22 \x5d \x02 \x01 \x03 \xad \x55 ' +
102
+ b'\x6e \x6b \x6e \x6f \x77 \x6e \x20 \x65 \x72 \x72 \x6f \x72 ' +
103
+ b'\x04 \x00 \x05 \x00 ' ),
104
+ 'tarantool' : "box.error.new(box.error.UNKNOWN)" ,
77
105
},
78
- 'encoding_none ' : {
106
+ 'simple_error_for_encoding_none ' : {
79
107
'conn' : 'conn_encoding_none' ,
80
108
'str_type' : lambda obj : bytes (obj , encoding = 'utf8' ),
81
- },
82
- }
83
-
84
- cases = {}
85
-
86
- for key , value in conn_cases .items ():
87
- cases [f'simple_error_for_{ key } ' ] = {
88
- 'conn' : value ['conn' ],
89
- 'str_type' : value ['str_type' ],
90
109
'python' : tarantool .BoxError (
91
- type = value [ 'str_type' ]( ' ClientError') ,
92
- file = value [ 'str_type' ]( ' [string " local err = box.error.ne..."]') ,
110
+ type = b' ClientError' ,
111
+ file = b' [string " local err = box.error.ne..."]' ,
93
112
line = 1 ,
94
- message = value [ 'str_type' ]( ' Unknown error') ,
113
+ message = b' Unknown error' ,
95
114
errno = 0 ,
96
115
errcode = 0 ,
97
116
),
@@ -105,23 +124,60 @@ def setUp(self):
105
124
b'\x55 \x6e \x6b \x6e \x6f \x77 \x6e \x20 \x65 \x72 \x72 \x6f ' +
106
125
b'\x72 \x04 \x00 \x05 \x00 ' ),
107
126
'tarantool' : "box.error.new(box.error.UNKNOWN)" ,
108
- 'ignore_file_info' : False ,
109
- }
110
-
111
- cases [f'error_with_fields_for_{ key } ' ] = {
112
- 'conn' : value ['conn' ],
113
- 'str_type' : value ['str_type' ],
127
+ },
128
+ 'error_with_fields_for_encoding_utf8' : {
129
+ 'conn' : 'conn_encoding_utf8' ,
130
+ 'str_type' : str ,
131
+ 'python' : tarantool .BoxError (
132
+ type = 'AccessDeniedError' ,
133
+ file = '/__w/sdk/sdk/tarantool-2.10/tarantool/src/box/func.c' ,
134
+ line = 535 ,
135
+ message = "Execute access to function 'forbidden_function' is denied for user 'guest'" ,
136
+ errno = 0 ,
137
+ errcode = 42 ,
138
+ fields = {
139
+ 'object_type' : 'function' ,
140
+ 'object_name' : 'forbidden_function' ,
141
+ 'access_type' : 'Execute' ,
142
+ },
143
+ ),
144
+ 'msgpack' : (b'\x81 \x00 \x91 \x87 \x00 \xb1 \x41 \x63 \x63 \x65 \x73 \x73 ' +
145
+ b'\x44 \x65 \x6e \x69 \x65 \x64 \x45 \x72 \x72 \x6f \x72 \x01 ' +
146
+ b'\xd9 \x34 \x2f \x5f \x5f \x77 \x2f \x73 \x64 \x6b \x2f \x73 ' +
147
+ b'\x64 \x6b \x2f \x74 \x61 \x72 \x61 \x6e \x74 \x6f \x6f \x6c ' +
148
+ b'\x2d \x32 \x2e \x31 \x30 \x2f \x74 \x61 \x72 \x61 \x6e \x74 ' +
149
+ b'\x6f \x6f \x6c \x2f \x73 \x72 \x63 \x2f \x62 \x6f \x78 \x2f ' +
150
+ b'\x66 \x75 \x6e \x63 \x2e \x63 \x02 \xcd \x02 \x17 \x03 \xd9 ' +
151
+ b'\x4a \x45 \x78 \x65 \x63 \x75 \x74 \x65 \x20 \x61 \x63 \x63 ' +
152
+ b'\x65 \x73 \x73 \x20 \x74 \x6f \x20 \x66 \x75 \x6e \x63 \x74 ' +
153
+ b'\x69 \x6f \x6e \x20 \x27 \x66 \x6f \x72 \x62 \x69 \x64 \x64 ' +
154
+ b'\x65 \x6e \x5f \x66 \x75 \x6e \x63 \x74 \x69 \x6f \x6e \x27 ' +
155
+ b'\x20 \x69 \x73 \x20 \x64 \x65 \x6e \x69 \x65 \x64 \x20 \x66 ' +
156
+ b'\x6f \x72 \x20 \x75 \x73 \x65 \x72 \x20 \x27 \x67 \x75 \x65 ' +
157
+ b'\x73 \x74 \x27 \x04 \x00 \x05 \x2a \x06 \x83 \xab \x6f \x62 ' +
158
+ b'\x6a \x65 \x63 \x74 \x5f \x74 \x79 \x70 \x65 \xa8 \x66 \x75 ' +
159
+ b'\x6e \x63 \x74 \x69 \x6f \x6e \xab \x6f \x62 \x6a \x65 \x63 ' +
160
+ b'\x74 \x5f \x6e \x61 \x6d \x65 \xb2 \x66 \x6f \x72 \x62 \x69 ' +
161
+ b'\x64 \x64 \x65 \x6e \x5f \x66 \x75 \x6e \x63 \x74 \x69 \x6f ' +
162
+ b'\x6e \xab \x61 \x63 \x63 \x65 \x73 \x73 \x5f \x74 \x79 \x70 ' +
163
+ b'\x65 \xa7 \x45 \x78 \x65 \x63 \x75 \x74 \x65 ' ),
164
+ 'tarantool' : "access_denied_error" ,
165
+ 'ignore_file_info' : True ,
166
+ },
167
+ 'error_with_fields_for_encoding_none' : {
168
+ 'conn' : 'conn_encoding_none' ,
169
+ 'str_type' : lambda obj : bytes (obj , encoding = 'utf8' ),
114
170
'python' : tarantool .BoxError (
115
- type = value [ 'str_type' ]( ' AccessDeniedError') ,
116
- file = value [ 'str_type' ]( ' /__w/sdk/sdk/tarantool-2.10/tarantool/src/box/func.c') ,
171
+ type = b' AccessDeniedError' ,
172
+ file = b' /__w/sdk/sdk/tarantool-2.10/tarantool/src/box/func.c' ,
117
173
line = 535 ,
118
- message = value [ 'str_type' ]( "Execute access to function 'forbidden_function' is denied for user 'guest'" ) ,
174
+ message = b "Execute access to function 'forbidden_function' is denied for user 'guest'" ,
119
175
errno = 0 ,
120
176
errcode = 42 ,
121
177
fields = {
122
- value [ 'str_type' ]( ' object_type'): value [ 'str_type' ]( ' function') ,
123
- value [ 'str_type' ]( ' object_name'): value [ 'str_type' ]( ' forbidden_function') ,
124
- value [ 'str_type' ]( ' access_type'): value [ 'str_type' ]( ' Execute') ,
178
+ b' object_type': b' function' ,
179
+ b' object_name': b' forbidden_function' ,
180
+ b' access_type': b' Execute' ,
125
181
},
126
182
),
127
183
'msgpack' : (b'\x81 \x00 \x91 \x87 \x00 \xb1 \x41 \x63 \x63 \x65 \x73 \x73 ' +
@@ -146,23 +202,51 @@ def setUp(self):
146
202
b'\x79 \x70 \x65 \xa7 \x45 \x78 \x65 \x63 \x75 \x74 \x65 ' ),
147
203
'tarantool' : "access_denied_error" ,
148
204
'ignore_file_info' : True ,
149
- }
150
-
151
- cases [f'error_chain_for_{ key } ' ] = {
152
- 'conn' : value ['conn' ],
153
- 'str_type' : value ['str_type' ],
205
+ },
206
+ 'error_chain_for_encoding_utf8' : {
207
+ 'conn' : 'conn_encoding_utf8' ,
208
+ 'str_type' : str ,
154
209
'python' : tarantool .BoxError (
155
- type = value [ 'str_type' ]( ' ClientError') ,
156
- file = value [ 'str_type' ]( ' eval') ,
210
+ type = ' ClientError' ,
211
+ file = ' eval' ,
157
212
line = 3 ,
158
- message = value [ 'str_type' ]( ' Unknown error') ,
213
+ message = ' Unknown error' ,
159
214
errno = 0 ,
160
215
errcode = 0 ,
161
216
prev = tarantool .BoxError (
162
- type = value [ 'str_type' ]( ' ClientError') ,
163
- file = value [ 'str_type' ]( ' eval') ,
217
+ type = ' ClientError' ,
218
+ file = ' eval' ,
164
219
line = 2 ,
165
- message = value ['str_type' ]('Unknown error' ),
220
+ message = 'Unknown error' ,
221
+ errno = 0 ,
222
+ errcode = 0 ,
223
+ ),
224
+ ),
225
+ 'msgpack' : (b'\x81 \x00 \x92 \x86 \x00 \xab \x43 \x6c \x69 \x65 \x6e \x74 ' +
226
+ b'\x45 \x72 \x72 \x6f \x72 \x01 \xa4 \x65 \x76 \x61 \x6c \x02 ' +
227
+ b'\x03 \x03 \xad \x55 \x6e \x6b \x6e \x6f \x77 \x6e \x20 \x65 ' +
228
+ b'\x72 \x72 \x6f \x72 \x04 \x00 \x05 \x00 \x86 \x00 \xab \x43 ' +
229
+ b'\x6c \x69 \x65 \x6e \x74 \x45 \x72 \x72 \x6f \x72 \x01 \xa4 ' +
230
+ b'\x65 \x76 \x61 \x6c \x02 \x02 \x03 \xad \x55 \x6e \x6b \x6e ' +
231
+ b'\x6f \x77 \x6e \x20 \x65 \x72 \x72 \x6f \x72 \x04 \x00 \x05 \x00 ' ),
232
+ 'tarantool' : "chained_error" ,
233
+ 'ignore_file_info' : False ,
234
+ },
235
+ 'error_chain_for_encoding_none' : {
236
+ 'conn' : 'conn_encoding_none' ,
237
+ 'str_type' : lambda obj : bytes (obj , encoding = 'utf8' ),
238
+ 'python' : tarantool .BoxError (
239
+ type = b'ClientError' ,
240
+ file = b'eval' ,
241
+ line = 3 ,
242
+ message = b'Unknown error' ,
243
+ errno = 0 ,
244
+ errcode = 0 ,
245
+ prev = tarantool .BoxError (
246
+ type = b'ClientError' ,
247
+ file = b'eval' ,
248
+ line = 2 ,
249
+ message = b'Unknown error' ,
166
250
errno = 0 ,
167
251
errcode = 0 ,
168
252
),
@@ -177,6 +261,8 @@ def setUp(self):
177
261
'tarantool' : "chained_error" ,
178
262
'ignore_file_info' : False ,
179
263
}
264
+ }
265
+
180
266
181
267
def test_msgpack_decode (self ):
182
268
for name in self .cases .keys ():
@@ -207,31 +293,26 @@ def test_tarantool_decode(self):
207
293
res = conn .select ('test' , case ['str_type' ](name ))
208
294
self .assertEqual (len (res ), 1 )
209
295
210
- if not case ['ignore_file_info' ]:
211
- self .assertSequenceEqual (
212
- res ,
213
- [[case ['str_type' ](name ), case ['python' ], case ['str_type' ]('payload' )]])
214
- else :
215
- # Errors raised from Tarantool internals contain source code lines
216
- # and file paths. They could be different for each version.
217
- self .assertEqual (res [0 ][0 ], case ['str_type' ](name ))
218
- self .assertEqual (res [0 ][2 ], case ['str_type' ]('payload' ))
296
+ # Tarantool error file and line could differ even between
297
+ # different patches.
298
+ self .assertEqual (res [0 ][0 ], case ['str_type' ](name ))
299
+ self .assertEqual (res [0 ][2 ], case ['str_type' ]('payload' ))
219
300
220
- self .assertTrue (isinstance (res [0 ][1 ], tarantool .BoxError ))
301
+ self .assertTrue (isinstance (res [0 ][1 ], tarantool .BoxError ))
221
302
222
- err = res [0 ][1 ]
223
- expected_err = case ['python' ]
224
- while err is not None :
225
- self .assertEqual (err .type , expected_err .type )
226
- self .assertEqual (err .message , expected_err .message )
227
- self .assertEqual (err .errno , expected_err .errno )
228
- self .assertEqual (err .errcode , expected_err .errcode )
229
- self .assertEqual (err .fields , expected_err .fields )
303
+ err = res [0 ][1 ]
304
+ expected_err = case ['python' ]
305
+ while err is not None :
306
+ self .assertEqual (err .type , expected_err .type )
307
+ self .assertEqual (err .message , expected_err .message )
308
+ self .assertEqual (err .errno , expected_err .errno )
309
+ self .assertEqual (err .errcode , expected_err .errcode )
310
+ self .assertEqual (err .fields , expected_err .fields )
230
311
231
- err = err .prev
232
- expected_err = expected_err .prev
312
+ err = err .prev
313
+ expected_err = expected_err .prev
233
314
234
- self .assertEqual (err , expected_err )
315
+ self .assertEqual (err , expected_err )
235
316
236
317
237
318
def test_msgpack_encode (self ):
@@ -254,8 +335,6 @@ def test_tarantool_encode(self):
254
335
'test' ,
255
336
[case ['str_type' ](name ), case ['python' ], case ['str_type' ]('payload' )])
256
337
257
- ignore_file_info = str (case ['ignore_file_info' ]).lower ()
258
-
259
338
lua_eval = f"""
260
339
local err = { case ['tarantool' ]}
261
340
@@ -271,19 +350,7 @@ def test_tarantool_encode(self):
271
350
272
351
local tuple_err = tuple[2]
273
352
274
- local fields = {{}}
275
-
276
- if { ignore_file_info } then
277
- fields = {{
278
- 'type', 'message', 'errno',
279
- 'errcode', 'fields',
280
- }}
281
- else
282
- fields = {{
283
- 'type', 'message', 'line', 'file',
284
- 'errno', 'errcode', 'fields',
285
- }}
286
- end
353
+ local fields = {{'type', 'message', 'errno', 'errcode', 'fields'}}
287
354
288
355
local json = require('json')
289
356
@@ -295,7 +362,9 @@ def test_tarantool_encode(self):
295
362
end
296
363
297
364
if (err1 ~= nil) and (err2 == nil) then
298
- return nil, err1
365
+ return nil, ('Expected error stack is empty, but test error ' ..
366
+ 'has previous %s (%s) error'):format(
367
+ err1.type, err1.message)
299
368
end
300
369
301
370
for _, field in ipairs(fields) do
@@ -307,15 +376,14 @@ def test_tarantool_encode(self):
307
376
end
308
377
end
309
378
310
- if err1.prev ~= nil then
379
+ if ( err1.prev ~= nil) or (err2.prev ~= nil) then
311
380
return compare_errors(err1.prev, err2.prev)
312
381
end
313
382
314
383
return true
315
384
end
316
385
317
- -- return compare_errors(tuple_err, err)
318
- return tuple_err, err
386
+ return compare_errors(tuple_err, err)
319
387
"""
320
388
321
389
self .assertSequenceEqual (conn .eval (lua_eval ), [True ])
0 commit comments