Skip to content

Commit

Permalink
Migrate msgpack to luatest
Browse files Browse the repository at this point in the history
Use luatest assertions for checking tarantool msgpack decode/encode
functions.

Part of: tarantool/test-run#304
  • Loading branch information
VitaliyaIoffe committed Jun 9, 2021
1 parent 9222190 commit 7d1136a
Showing 1 changed file with 257 additions and 0 deletions.
257 changes: 257 additions & 0 deletions test/msgpack_test.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,257 @@
buffer = require 'buffer'
msgpack = require 'msgpack'
ffi = require 'ffi'
local t = require('luatest')
local g = t.group()

local log = require('log')
local helper = require('test.helper')
local HTTPResponse = require('luatest.http_response')
local fio = require('fio')
local json = require('json')


local Process = t.Process
local Server = t.Server

local root = fio.dirname(fio.dirname(fio.abspath(package.search('test.helper'))))
local datadir = fio.pathjoin(root, 'tmp', 'db_test')
local command = fio.pathjoin(root, 'test', 'server_instance.lua')

local server = Server:new({
command = command,
workdir = fio.pathjoin(datadir, 'common'),
env = {custom_env = 'test_value'},
http_port = 8182,
net_box_port = 3133,
})

local s

g.before_all = function()
pcall(log.cfg, {level = 6})
fio.rmtree(datadir)
fio.mktree(server.workdir)
server:start()
-- wait until booted
t.helpers.retrying(
{timeout = 2}, function() server:http_request('get', '/ping') end)

local workdir = fio.pathjoin(datadir, 'start_stop')
fio.mktree(workdir)
s = Server:new({command = command, workdir = workdir, net_box_port = 3301})
local orig_args = table.copy(s.args)
s:start()

local pid = s.process.pid
t.helpers.retrying({timeout = 0.5}, function()
t.assert(Process.is_pid_alive(pid))
s:connect_net_box()
end)

buf = buffer.ibuf()
t.assert_equals(s.net_box.state, 'active')
s.net_box:eval("buffer = require 'buffer'")
s.net_box:eval("msgpack = require 'msgpack'")
s.net_box:eval("ffi = require 'ffi'")
end

g.after_all = function()
if server.process then
server:stop()
end
fio.rmtree(datadir)
end

msgpack.encode = function(params)
s.net_box:eval("return msgpack.encode(" .. params .. ")")
end

table_to_string = function(table)
local s = "{"
for i=1,#table do
s = s .. table[i]
if i < #table then
s = s .. ", "
end
end
s = s .. "}"
return s
end

g.test_errors = function()
-- Arguments check.
s.net_box:eval("buf = buffer.ibuf()")
t.assert_error_msg_content_equals("msgpack.encode: a Lua object expected",
function() msgpack.encode("") end)
t.assert_error_msg_content_equals(
"msgpack.encode: argument 2 must be of type 'struct ibuf'",
function() msgpack.encode("'test', 'str'") end)
t.assert_error_msg_content_equals(
"msgpack.encode: argument 2 must be of type 'struct ibuf'",
function()
s.net_box:eval("return msgpack.encode('test', buf.buf)")
end)

t.assert_error_msg_content_equals("msgpack.decode: a Lua string or 'char *' expected",
function() s.net_box:eval("return msgpack.decode()") end)
t.assert_error_msg_content_equals("msgpack.decode: a Lua string or 'char *' expected",
function() s.net_box:eval("return msgpack.decode(123)") end)
t.assert_error_msg_content_equals("msgpack.decode: a Lua string or 'char *' expected",
function() s.net_box:eval("return msgpack.decode(buf)") end)

t.assert_error_msg_content_equals("bad argument #2 to '?' (number expected, got string)",
function() s.net_box:eval("return msgpack.decode(buf.buf, 'size')") end)
t.assert_error_msg_content_equals("msgpack.decode: offset is out of bounds",
function() s.net_box:eval("return msgpack.decode('test', 0)") end)
t.assert_error_msg_content_equals("msgpack.decode: offset is out of bounds",
function() s.net_box:eval("return msgpack.decode('test', 5)") end)

t.assert_error_msg_content_equals("bad argument #2 to '?' (number expected, got string)",
function() s.net_box:eval("return msgpack.decode('test', 'offset')") end)
t.assert_error_msg_content_equals("msgpack.decode: a Lua string or 'char *' expected",
function() s.net_box:eval("return msgpack.decode_unchecked()") end)
t.assert_error_msg_content_equals("msgpack.decode: a Lua string or 'char *' expected",
function() s.net_box:eval("return msgpack.decode_unchecked(123)") end)
t.assert_error_msg_content_equals("msgpack.decode: a Lua string or 'char *' expected",
function() s.net_box:eval("return msgpack.decode_unchecked(buf)") end)

t.assert_error_msg_content_equals("msgpack.decode: offset is out of bounds",
function() s.net_box:eval("return msgpack.decode_unchecked('test', 0)") end)
t.assert_error_msg_content_equals("msgpack.decode: offset is out of bounds",
function() s.net_box:eval("return msgpack.decode_unchecked('test', 5)") end)
t.assert_error_msg_content_equals("bad argument #2 to '?' (number expected, got string)",
function() s.net_box:eval("return msgpack.decode_unchecked('test', 'offset')") end)
end

g.test_encode_decode_strings = function()
-- Encode/decode a string.
first_table = {1, 2, 3}
second_table = {4, 5, 6}
s.net_box:eval("s = msgpack.encode(" .. table_to_string(first_table) ..
") .. msgpack.encode(" .. table_to_string(second_table) .. ")")
s.net_box:eval("return obj")
s.net_box:eval("obj, offset = msgpack.decode(s)")
t.assert_items_equals(s.net_box:eval("return obj"), first_table) -- brackets??
s.net_box:eval("obj, offset = msgpack.decode(s, offset)")
t.assert_items_equals(s.net_box:eval("return obj"), second_table) -- brackets??
t.assert(s.net_box:eval("return offset == #s + 1")) -- why is here #s+1 == 9?

obj, offset = s.net_box:eval("return msgpack.decode_unchecked(s)")
t.assert_items_equals(obj, first_table) -- brackets??
obj, offset = s.net_box:eval("return msgpack.decode_unchecked(s, ".. offset .. ")")
t.assert_items_equals(obj, second_table) -- brackets??
t.assert_equals(offset, s.net_box:eval("return #s + 1"))
end

g.test_encode_decode_buffer = function()
-- Encode/decode a buffer.
first_buffer = {1, 2, 3}
second_buffer = {4, 5, 6}
s.net_box:eval("buf = buffer.ibuf()")
len = s.net_box:eval("return msgpack.encode(" .. table_to_string(first_buffer) .. ", buf)")
len = s.net_box:eval("return msgpack.encode(" .. table_to_string(second_buffer) .. ", buf)") + len
t.assert_equals(s.net_box:eval("return buf:size()"), len)

orig_rpos = s.net_box:eval("orig_rpos = buf.rpos")
s.net_box:eval("obj, rpos = msgpack.decode(buf.rpos, buf:size())")
t.assert_items_equals(s.net_box:eval("return obj"), first_buffer) -- brackets??

s.net_box:eval("buf.rpos = rpos")
s.net_box:eval("obj, rpos = msgpack.decode(buf.rpos, buf:size())")
t.assert_items_equals(s.net_box:eval("return obj"), second_buffer) -- brackets??

s.net_box:eval("buf.rpos = rpos")
t.assert_equals(s.net_box:eval("return buf:size()"), 0)

s.net_box:eval("buf.rpos = orig_rpos")
s.net_box:eval("obj, rpos = msgpack.decode_unchecked(buf.rpos, buf:size())")
t.assert_items_equals(s.net_box:eval("return obj"), first_buffer) -- brackets??

s.net_box:eval("buf.rpos = rpos")
s.net_box:eval("obj, rpos = msgpack.decode_unchecked(buf.rpos, buf:size())")
t.assert_items_equals(s.net_box:eval("return obj"), second_buffer) -- brackets??

s.net_box:eval("buf.rpos = rpos")
t.assert_equals(s.net_box:eval("return buf:size()"), 0)
end

g.test_invalid_msg_pack = function()
-- Invalid msgpack.
first_buffer = {1, 2, 3}
s.net_box:eval("s = msgpack.encode(" .. table_to_string(first_buffer) .. ")")
s.net_box:eval("s = s:sub(1, -2)")
t.assert_error_msg_content_equals("msgpack.decode: invalid MsgPack",
function() s.net_box:eval("return msgpack.decode(s)") end)

s.net_box:eval("buf = buffer.ibuf()")
t.assert_equals(s.net_box:eval("return msgpack.encode(" .. table_to_string(first_buffer) .. ", buf)"), 4)
t.assert_error_msg_content_equals("msgpack.decode: invalid MsgPack",
function() s.net_box:eval("return msgpack.decode(buf.rpos, buf:size() - 1)") end)
end

g.test_encode_decode_struct_buffer = function()
-- Provide a buffer. Try both 'struct ibuf' and 'struct ibuf *'.
s.net_box:eval("buf_storage = buffer.ibuf()")
s.net_box:eval("buf = ffi.cast('struct ibuf *', buf_storage)")
s.net_box:eval("size = msgpack.encode({a = 1, b = 2}, buf)")
t.assert_equals(s.net_box:eval("return (msgpack.decode(buf.rpos, size))"), {a = 1, b = 2})

s.net_box:eval("buf_storage = nil")
s.net_box:eval("buf = buffer.ibuf()")
s.net_box:eval("size = msgpack.encode({c = 3, d = 4}, buf)")
t.assert_equals(s.net_box:eval("return (msgpack.decode(buf.rpos, size))"), {c = 3, d = 4})
end

g.test_encode_decode_char_buffer = function()
-- Decode should accept both 'char *' and 'const char *'.
s.net_box:eval("buf:reset()")
elem = 100
size = s.net_box:eval("size = msgpack.encode(".. elem .. ", buf)")
t.assert_equals(s.net_box:eval("return (msgpack.decode(ffi.cast('char *', buf.rpos), size))"), elem)
t.assert_equals(s.net_box:eval("return (msgpack.decode(ffi.cast('const char *', buf.rpos), size))"), elem)
end

g.test_size_not_negative = function()
-- gh-4224: msgpack.decode(cdata, size) should check, that size
-- is not negative.
t.assert_error_msg_content_equals("msgpack.decode: size can't be negative",
function() s.net_box:eval("msgpack.decode(ffi.cast('char *', '\x04\x05\x06'), -1)") end)
end

g.test_encode_decode_decimals = function()
-- gh-4333: msgpack encode/decode decimals.
s.net_box:eval("decimal = require('decimal')")
s.net_box:eval("a = decimal.new('1e37')")
s.net_box:eval("b = decimal.new('1e-38')")
s.net_box:eval("c = decimal.new('1')")
s.net_box:eval("d = decimal.new('0.1234567')")
s.net_box:eval("e = decimal.new('123.4567')")
t.assert_equals(s.net_box:eval("return msgpack.decode(msgpack.encode(decimal.new('1e37')))"),
s.net_box:eval("return decimal.new('1e37')"))
t.assert_equals(s.net_box:eval("return msgpack.decode(msgpack.encode(b))"),
s.net_box:eval("return b"))
t.assert_equals(s.net_box:eval("return msgpack.decode(msgpack.encode(c))"),
s.net_box:eval("return c"))
t.assert_equals(s.net_box:eval("return msgpack.decode(msgpack.encode(d))"),
s.net_box:eval("return d"))
t.assert_equals(s.net_box:eval("return msgpack.decode(msgpack.encode(e))"),
s.net_box:eval("return e"))
end

g.test_encode_decode_uuid = function()
-- -- gh-4268: msgpack encode/decode UUID
s.net_box:eval("uuid = require('uuid')")
s.net_box:eval("fail = nil")
s.net_box:eval([[
for i = 1,10 do
local a = uuid.new()
if msgpack.decode(msgpack.encode(a)) ~= a then
fail = a
end
end
]])
-- todo: how to check?
-- t.assert_equals(s.net_box:eval("return fail"), "null")
end

0 comments on commit 7d1136a

Please sign in to comment.