Skip to content

Commit c8b5323

Browse files
WIP on gh-105-unpack-binary: 0f95f28 Skip SQL tests if tarantool version < 2.0.0
1 WIP
1 parent 0f95f28 commit c8b5323

File tree

3 files changed

+88
-5
lines changed

3 files changed

+88
-5
lines changed

tarantool/request.py

+10-4
Original file line numberDiff line numberDiff line change
@@ -84,9 +84,6 @@ def __init__(self, conn):
8484
# The option controls whether to pack binary (non-unicode)
8585
# string values as mp_bin or as mp_str.
8686
#
87-
# The default behaviour of the connector is to pack both
88-
# bytes and Unicode strings as mp_str.
89-
#
9087
# msgpack-0.5.0 (and only this version) warns when the
9188
# option is unset:
9289
#
@@ -98,7 +95,16 @@ def __init__(self, conn):
9895
# just always set it for all msgpack versions to get rid
9996
# of the warning on msgpack-0.5.0 and to keep our
10097
# behaviour on msgpack-1.0.0.
101-
packer_kwargs['use_bin_type'] = False
98+
#
99+
# Currect default connector behavior is to pack str as mp_str
100+
# and to pack bytes as mp_bin and vice versa on unpack if
101+
# connection encoding is not None. If encoding is None,
102+
# pack bytes as mp_str and unpack mp_str to bytes. mp_bin is
103+
# unsupported in this mode.
104+
if conn.encoding is None:
105+
packer_kwargs['use_bin_type'] = False
106+
else:
107+
packer_kwargs['use_bin_type'] = True
102108

103109
self.packer = msgpack.Packer(**packer_kwargs)
104110

tarantool/utils.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def check_key(*args, **kwargs):
4343
elif args[0] is None and kwargs['select']:
4444
return []
4545
for key in args:
46-
assert isinstance(key, integer_types + string_types + (float,))
46+
assert isinstance(key, integer_types + string_types + binary_types + (float,))
4747
return list(args)
4848

4949

test/suites/test_dml.py

+77
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44

55
import sys
66
import unittest
7+
78
import tarantool
89

910
from .lib.tarantool_server import TarantoolServer
1011

12+
1113
class TestSuite_Request(unittest.TestCase):
1214
@classmethod
1315
def setUpClass(self):
@@ -17,6 +19,7 @@ def setUpClass(self):
1719
self.srv.script = 'test/suites/box.lua'
1820
self.srv.start()
1921
self.con = tarantool.Connection(self.srv.host, self.srv.args['primary'])
22+
self.con_encoding_none = tarantool.Connection(self.srv.host, self.srv.args['primary'], encoding=None)
2023
self.adm = self.srv.admin
2124
self.space_created = self.adm("box.schema.create_space('space_1')")
2225
self.adm("""
@@ -31,17 +34,64 @@ def setUpClass(self):
3134
parts = {2, 'num', 3, 'str'},
3235
unique = false})
3336
""".replace('\n', ' '))
37+
3438
self.space_created = self.adm("box.schema.create_space('space_2')")
3539
self.adm("""
3640
box.space['space_2']:create_index('primary', {
3741
type = 'hash',
3842
parts = {1, 'num'},
3943
unique = true})
4044
""".replace('\n', ' '))
45+
46+
self.adm("box.schema.create_space('space_str')")
47+
self.adm("""
48+
box.space['space_str']:create_index('primary', {
49+
type = 'tree',
50+
parts = {1, 'str'},
51+
unique = true})
52+
""".replace('\n', ' '))
53+
54+
self.adm("box.schema.create_space('space_varbin')")
55+
self.adm("""
56+
box.space['space_varbin']:create_index('primary', {
57+
type = 'tree',
58+
parts = {1, 'varbinary'},
59+
unique = true})
60+
""".replace('\n', ' '))
61+
self.adm("""
62+
buffer = require('buffer')
63+
ffi = require('ffi')
64+
65+
function encode_bin(bytes)
66+
local tmpbuf = buffer.ibuf()
67+
local p = tmpbuf:alloc(3 + #bytes)
68+
p[0] = 0x91
69+
p[1] = 0xC4
70+
p[2] = #bytes
71+
for i, c in pairs(bytes) do
72+
p[i + 3 - 1] = c
73+
end
74+
return tmpbuf
75+
end
76+
77+
function bintuple_insert(space, bytes)
78+
local tmpbuf = encode_bin(bytes)
79+
ffi.cdef[[
80+
int box_insert(uint32_t space_id, const char *tuple, const char *tuple_end, box_tuple_t **result);
81+
]]
82+
ffi.C.box_insert(space.id, tmpbuf.rpos, tmpbuf.wpos, nil)
83+
end
84+
""")
4185
self.adm("json = require('json')")
4286
self.adm("fiber = require('fiber')")
4387
self.adm("uuid = require('uuid')")
4488

89+
def assertNotRaises(self, func, *args, **kwargs):
90+
try:
91+
func(*args, **kwargs)
92+
except Exception as e:
93+
self.fail('Function raised Exception: %s' % repr(e))
94+
4595
def setUp(self):
4696
# prevent a remote tarantool from clean our session
4797
if self.srv.is_started():
@@ -55,6 +105,7 @@ def test_00_00_authenticate(self):
55105
box.schema.user.grant('test', 'execute,read,write', 'universe')
56106
"""))
57107
self.assertEqual(self.con.authenticate('test', 'test')._data, None)
108+
self.assertEqual(self.con_encoding_none.authenticate('test', 'test')._data, None)
58109

59110
def test_00_01_space_created(self):
60111
# Check that space is created in setUpClass
@@ -299,6 +350,32 @@ def test_12_update_fields(self):
299350
[[2, 'help', 7]]
300351
)
301352

353+
def test_13_00_string_insert_default_behavior(self):
354+
self.assertNotRaises(self.con.insert, 'space_str', [ 'test_13_string_insert_default_behavior' ])
355+
356+
def test_13_01_string_select_default_behavior(self):
357+
self.adm(r"box.space['space_str']:insert{'test_14_string_select_default_behavior'}")
358+
resp = self.con.select('space_str', ['test_14_string_select_default_behavior'])
359+
self.assertIsInstance(resp[0][0], tarantool.utils.string_types)
360+
361+
def test_13_02_varbinary_insert_default_behavior(self):
362+
self.assertNotRaises(self.con.insert, 'space_varbin', [ b'test_15_varbinary_insert_default_behavior' ])
363+
364+
def test_13_03_varbinary_select_default_behavior(self):
365+
self.adm(r"""
366+
bintuple_insert(box.space['space_varbin'], {0xDE, 0xAD, 0xBE, 0xAF, 0x16})
367+
""")
368+
resp = self.con.select('space_varbin', [bytes.fromhex('DEADBEAF16')])
369+
self.assertIsInstance(resp[0][0], tarantool.utils.binary_types)
370+
371+
def test_14_00_string_insert_encoding_none_behavior(self):
372+
self.assertNotRaises(self.con_encoding_none.insert, 'space_str', [ bytes.fromhex('DEADBEAF17') ])
373+
374+
def test_14_01_string_select_encoding_none_behavior(self):
375+
self.adm(r"box.space['space_str']:insert{'\xDE\xAD\xBE\xAF\x18'}")
376+
resp = self.con_encoding_none.select('space_str', [bytes.fromhex('DEADBEAF18')])
377+
self.assertIsInstance(resp[0][0], tarantool.utils.binary_types)
378+
302379
@classmethod
303380
def tearDownClass(self):
304381
self.con.close()

0 commit comments

Comments
 (0)