* [Tarantool-patches] [PATCH v1] Divide test box/net.box @ 2020-04-02 6:38 Alexander V. Tikhonov 2020-04-02 15:44 ` Sergey Bronnikov 0 siblings, 1 reply; 8+ messages in thread From: Alexander V. Tikhonov @ 2020-04-02 6:38 UTC (permalink / raw) To: Oleg Piskunov, Sergey Bronnikov; +Cc: tarantool-patches box/net.box_bad_argument_gh-594.test.lua box/net.box_call_blocks_gh-946.test.lua box/net.box_collectgarbage_gh-3107.test.lua box/net.box_connect_triggers.test.lua box/net.box_console_connections_gh-2677.test.lua box/net.box_count_inconsistent_gh-3262.test.lua box/net.box_discard_gh-3107.test.lua box/net.box_disconnect_gh-3859.test.lua box/net.box_fiber-async_gh-3107.test.lua box/net.box_field_names_gh-2978.test.lua box/net.box_get_connection_object.test.lua box/net.box_gibberish_gh-3900.test.lua box/net.box_huge_data_gh-983.test.lua box/net.box_incompatible_index-gh-1729.test.lua box/net.box_incorrect_iterator_gh-841.test.lua box/net.box_index_unique_flag_gh-4091.test.lua box/net.box_iproto_hangs_gh-3464.test.lua box/net.box_is_nullable_gh-3256.test.lua box/net.box_leaks_gh-3629.test.lua box/net.box_log_corrupted_rows_gh-4040.test.lua box/net.box_long-poll_input_gh-3400.test.lua box/net.box_methods_gh-3107.test.lua box/net.box_msgpack_gh-2195.test.lua box/net.box_on_schema_reload-gh-1904.test.lua box/net.box_password_gh-1545.test.lua box/net.box_permissions.test.lua box/net.box_pseudo_objects_gh-2401.test.lua box/net.box_raw_response_gh-3107.test.lua box/net.box_readahead_gh-3958.test.lua box/net.box_reconnect_after_gh-3164.test.lua box/net.box_reconnect_after.test.lua box/net.box_reload_schema_gh-636.test.lua box/net.box_remote_method_gh-544.test.lua box/net.box_roll_back_gh-822.test.lua box/net.box_schema_change_gh-2666.test.lua box/net.box_schema_change_gh-3107.test.lua box/net.box_session_type_gh-2642.test.lua box/net.box_space_format_gh-2402.test.lua box/net.box_timeout_gh-1533.test.lua box/net.box_timeout-gh-3107.test.lua box/net.box_upsert_gh-970.test.lua box/net.box_wait_connected_gh-3856.test.lua --- Github: https://github.com/tarantool/tarantool/tree/avtikhon/divide_tests test/box/gh-3107_rest1_net.box.result | 119 + test/box/net.box.result | 3932 ----------------- test/box/net.box.test.lua | 1585 ------- test/box/net.box_bad_argument_gh-594.result | 38 + test/box/net.box_bad_argument_gh-594.test.lua | 17 + test/box/net.box_call_blocks_gh-946.result | 124 + test/box/net.box_call_blocks_gh-946.test.lua | 67 + .../box/net.box_collectgarbage_gh-3107.result | 120 + .../net.box_collectgarbage_gh-3107.test.lua | 44 + test/box/net.box_connect_triggers.result | 82 + test/box/net.box_connect_triggers.test.lua | 27 + ...net.box_console_connections_gh-2677.result | 95 + ...t.box_console_connections_gh-2677.test.lua | 39 + .../net.box_count_inconsistent_gh-3262.result | 488 ++ ...et.box_count_inconsistent_gh-3262.test.lua | 182 + test/box/net.box_discard_gh-3107.result | 119 + test/box/net.box_discard_gh-3107.test.lua | 44 + test/box/net.box_disconnect_gh-3859.result | 113 + test/box/net.box_disconnect_gh-3859.test.lua | 50 + test/box/net.box_fiber-async_gh-3107.result | 115 + test/box/net.box_fiber-async_gh-3107.test.lua | 42 + test/box/net.box_field_names_gh-2978.result | 101 + test/box/net.box_field_names_gh-2978.test.lua | 29 + test/box/net.box_get_connection_object.result | 40 + .../net.box_get_connection_object.test.lua | 19 + test/box/net.box_gibberish_gh-3900.result | 31 + test/box/net.box_gibberish_gh-3900.test.lua | 13 + test/box/net.box_huge_data_gh-983.result | 30 + test/box/net.box_huge_data_gh-983.test.lua | 16 + .../net.box_incompatible_index-gh-1729.result | 99 + ...et.box_incompatible_index-gh-1729.test.lua | 33 + .../net.box_incorrect_iterator_gh-841.result | 497 +++ ...net.box_incorrect_iterator_gh-841.test.lua | 182 + .../net.box_index_unique_flag_gh-4091.result | 28 + ...net.box_index_unique_flag_gh-4091.test.lua | 15 + test/box/net.box_iproto_hangs_gh-3464.result | 31 + .../box/net.box_iproto_hangs_gh-3464.test.lua | 13 + test/box/net.box_is_nullable_gh-3256.result | 97 + test/box/net.box_is_nullable_gh-3256.test.lua | 36 + test/box/net.box_leaks_gh-3629.result | 51 + test/box/net.box_leaks_gh-3629.test.lua | 20 + .../net.box_log_corrupted_rows_gh-4040.result | 72 + ...et.box_log_corrupted_rows_gh-4040.test.lua | 31 + .../net.box_long-poll_input_gh-3400.result | 35 + .../net.box_long-poll_input_gh-3400.test.lua | 19 + test/box/net.box_methods_gh-3107.result | 277 ++ test/box/net.box_methods_gh-3107.test.lua | 96 + test/box/net.box_msgpack_gh-2195.result | 527 +++ test/box/net.box_msgpack_gh-2195.test.lua | 192 + .../net.box_on_schema_reload-gh-1904.result | 102 + .../net.box_on_schema_reload-gh-1904.test.lua | 65 + test/box/net.box_password_gh-1545.result | 28 + test/box/net.box_password_gh-1545.test.lua | 10 + test/box/net.box_permissions.result | 186 + test/box/net.box_permissions.test.lua | 66 + .../box/net.box_pseudo_objects_gh-2401.result | 55 + .../net.box_pseudo_objects_gh-2401.test.lua | 23 + test/box/net.box_raw_response_gh-3107.result | 123 + .../box/net.box_raw_response_gh-3107.test.lua | 46 + test/box/net.box_readahead_gh-3958.result | 55 + test/box/net.box_readahead_gh-3958.test.lua | 29 + test/box/net.box_reconnect_after.result | 32 + test/box/net.box_reconnect_after.test.lua | 16 + .../net.box_reconnect_after_gh-3164.result | 119 + .../net.box_reconnect_after_gh-3164.test.lua | 52 + test/box/net.box_reload_schema_gh-636.result | 108 + .../box/net.box_reload_schema_gh-636.test.lua | 46 + test/box/net.box_remote_method_gh-544.result | 95 + .../box/net.box_remote_method_gh-544.test.lua | 40 + test/box/net.box_roll_back_gh-822.result | 68 + test/box/net.box_roll_back_gh-822.test.lua | 42 + test/box/net.box_schema_change_gh-2666.result | 79 + .../net.box_schema_change_gh-2666.test.lua | 28 + test/box/net.box_schema_change_gh-3107.result | 151 + .../net.box_schema_change_gh-3107.test.lua | 55 + test/box/net.box_session_type_gh-2642.result | 22 + .../box/net.box_session_type_gh-2642.test.lua | 11 + test/box/net.box_space_format_gh-2402.result | 49 + .../box/net.box_space_format_gh-2402.test.lua | 23 + test/box/net.box_timeout-gh-3107.result | 125 + test/box/net.box_timeout-gh-3107.test.lua | 47 + test/box/net.box_timeout_gh-1533.result | 89 + test/box/net.box_timeout_gh-1533.test.lua | 45 + test/box/net.box_upsert_gh-970.result | 49 + test/box/net.box_upsert_gh-970.test.lua | 16 + .../box/net.box_wait_connected_gh-3856.result | 20 + .../net.box_wait_connected_gh-3856.test.lua | 8 + 87 files changed, 6778 insertions(+), 5517 deletions(-) create mode 100644 test/box/gh-3107_rest1_net.box.result delete mode 100644 test/box/net.box.result delete mode 100644 test/box/net.box.test.lua create mode 100644 test/box/net.box_bad_argument_gh-594.result create mode 100644 test/box/net.box_bad_argument_gh-594.test.lua create mode 100644 test/box/net.box_call_blocks_gh-946.result create mode 100644 test/box/net.box_call_blocks_gh-946.test.lua create mode 100644 test/box/net.box_collectgarbage_gh-3107.result create mode 100644 test/box/net.box_collectgarbage_gh-3107.test.lua create mode 100644 test/box/net.box_connect_triggers.result create mode 100644 test/box/net.box_connect_triggers.test.lua create mode 100644 test/box/net.box_console_connections_gh-2677.result create mode 100644 test/box/net.box_console_connections_gh-2677.test.lua create mode 100644 test/box/net.box_count_inconsistent_gh-3262.result create mode 100644 test/box/net.box_count_inconsistent_gh-3262.test.lua create mode 100644 test/box/net.box_discard_gh-3107.result create mode 100644 test/box/net.box_discard_gh-3107.test.lua create mode 100644 test/box/net.box_disconnect_gh-3859.result create mode 100644 test/box/net.box_disconnect_gh-3859.test.lua create mode 100644 test/box/net.box_fiber-async_gh-3107.result create mode 100644 test/box/net.box_fiber-async_gh-3107.test.lua create mode 100644 test/box/net.box_field_names_gh-2978.result create mode 100644 test/box/net.box_field_names_gh-2978.test.lua create mode 100644 test/box/net.box_get_connection_object.result create mode 100644 test/box/net.box_get_connection_object.test.lua create mode 100644 test/box/net.box_gibberish_gh-3900.result create mode 100644 test/box/net.box_gibberish_gh-3900.test.lua create mode 100644 test/box/net.box_huge_data_gh-983.result create mode 100644 test/box/net.box_huge_data_gh-983.test.lua create mode 100644 test/box/net.box_incompatible_index-gh-1729.result create mode 100644 test/box/net.box_incompatible_index-gh-1729.test.lua create mode 100644 test/box/net.box_incorrect_iterator_gh-841.result create mode 100644 test/box/net.box_incorrect_iterator_gh-841.test.lua create mode 100644 test/box/net.box_index_unique_flag_gh-4091.result create mode 100644 test/box/net.box_index_unique_flag_gh-4091.test.lua create mode 100644 test/box/net.box_iproto_hangs_gh-3464.result create mode 100644 test/box/net.box_iproto_hangs_gh-3464.test.lua create mode 100644 test/box/net.box_is_nullable_gh-3256.result create mode 100644 test/box/net.box_is_nullable_gh-3256.test.lua create mode 100644 test/box/net.box_leaks_gh-3629.result create mode 100644 test/box/net.box_leaks_gh-3629.test.lua create mode 100644 test/box/net.box_log_corrupted_rows_gh-4040.result create mode 100644 test/box/net.box_log_corrupted_rows_gh-4040.test.lua create mode 100644 test/box/net.box_long-poll_input_gh-3400.result create mode 100644 test/box/net.box_long-poll_input_gh-3400.test.lua create mode 100644 test/box/net.box_methods_gh-3107.result create mode 100644 test/box/net.box_methods_gh-3107.test.lua create mode 100644 test/box/net.box_msgpack_gh-2195.result create mode 100644 test/box/net.box_msgpack_gh-2195.test.lua create mode 100644 test/box/net.box_on_schema_reload-gh-1904.result create mode 100644 test/box/net.box_on_schema_reload-gh-1904.test.lua create mode 100644 test/box/net.box_password_gh-1545.result create mode 100644 test/box/net.box_password_gh-1545.test.lua create mode 100644 test/box/net.box_permissions.result create mode 100644 test/box/net.box_permissions.test.lua create mode 100644 test/box/net.box_pseudo_objects_gh-2401.result create mode 100644 test/box/net.box_pseudo_objects_gh-2401.test.lua create mode 100644 test/box/net.box_raw_response_gh-3107.result create mode 100644 test/box/net.box_raw_response_gh-3107.test.lua create mode 100644 test/box/net.box_readahead_gh-3958.result create mode 100644 test/box/net.box_readahead_gh-3958.test.lua create mode 100644 test/box/net.box_reconnect_after.result create mode 100644 test/box/net.box_reconnect_after.test.lua create mode 100644 test/box/net.box_reconnect_after_gh-3164.result create mode 100644 test/box/net.box_reconnect_after_gh-3164.test.lua create mode 100644 test/box/net.box_reload_schema_gh-636.result create mode 100644 test/box/net.box_reload_schema_gh-636.test.lua create mode 100644 test/box/net.box_remote_method_gh-544.result create mode 100644 test/box/net.box_remote_method_gh-544.test.lua create mode 100644 test/box/net.box_roll_back_gh-822.result create mode 100644 test/box/net.box_roll_back_gh-822.test.lua create mode 100644 test/box/net.box_schema_change_gh-2666.result create mode 100644 test/box/net.box_schema_change_gh-2666.test.lua create mode 100644 test/box/net.box_schema_change_gh-3107.result create mode 100644 test/box/net.box_schema_change_gh-3107.test.lua create mode 100644 test/box/net.box_session_type_gh-2642.result create mode 100644 test/box/net.box_session_type_gh-2642.test.lua create mode 100644 test/box/net.box_space_format_gh-2402.result create mode 100644 test/box/net.box_space_format_gh-2402.test.lua create mode 100644 test/box/net.box_timeout-gh-3107.result create mode 100644 test/box/net.box_timeout-gh-3107.test.lua create mode 100644 test/box/net.box_timeout_gh-1533.result create mode 100644 test/box/net.box_timeout_gh-1533.test.lua create mode 100644 test/box/net.box_upsert_gh-970.result create mode 100644 test/box/net.box_upsert_gh-970.test.lua create mode 100644 test/box/net.box_wait_connected_gh-3856.result create mode 100644 test/box/net.box_wait_connected_gh-3856.test.lua diff --git a/test/box/gh-3107_rest1_net.box.result b/test/box/gh-3107_rest1_net.box.result new file mode 100644 index 000000000..d9c59d1cf --- /dev/null +++ b/test/box/gh-3107_rest1_net.box.result @@ -0,0 +1,119 @@ +fiber = require 'fiber' +--- +... +net = require('net.box') +--- +... +-- +-- gh-3107: fiber-async netbox. +-- +cond = nil +--- +... +box.schema.func.create('long_function') +--- +... +box.schema.user.grant('guest', 'execute', 'function', 'long_function') +--- +... +function long_function(...) cond = fiber.cond() cond:wait() return ... end +--- +... +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end +--- +... +s = box.schema.create_space('test') +--- +... +pk = s:create_index('pk') +--- +... +s:replace{1} +--- +- [1] +... +s:replace{2} +--- +- [2] +... +s:replace{3} +--- +- [3] +... +s:replace{4} +--- +- [4] +... +c = net:connect(box.cfg.listen) +--- +... +-- +-- Check infinity timeout. +-- +ret = nil +--- +... +_ = fiber.create(function() ret = c:call('long_function', {1, 2, 3}, {is_async = true}):wait_result() end) +--- +... +finalize_long() +--- +... +while not ret do fiber.sleep(0.01) end +--- +... +ret +--- +- [1, 2, 3] +... +c:close() +--- +... +box.schema.user.grant('guest', 'execute', 'universe') +--- +... +c = net:connect(box.cfg.listen) +--- +... +future = c:eval('return long_function(...)', {1, 2, 3}, {is_async = true}) +--- +... +future:result() +--- +- null +- Response is not ready +... +future:wait_result(0.01) -- Must fail on timeout. +--- +- null +- Timeout exceeded +... +finalize_long() +--- +... +future:wait_result(100) +--- +- [1, 2, 3] +... +c:close() +--- +... +-- +-- Check that is_async does not work on a closed connection. +-- +c:call('any_func', {}, {is_async = true}) +--- +- error: Connection closed +... +box.schema.user.revoke('guest', 'execute', 'universe') +--- +... +c = net:connect(box.cfg.listen) +--- +... +c:close() +--- +... +s:drop() +--- +... diff --git a/test/box/net.box.result b/test/box/net.box.result deleted file mode 100644 index e3dabf7d9..000000000 --- a/test/box/net.box.result +++ /dev/null @@ -1,3932 +0,0 @@ -remote = require 'net.box' ---- -... -fiber = require 'fiber' ---- -... -log = require 'log' ---- -... -msgpack = require 'msgpack' ---- -... -env = require('test_run') ---- -... -test_run = env.new() ---- -... -test_run:cmd("push filter ".."'\\.lua.*:[0-9]+: ' to '.lua...\"]:<line>: '") ---- -- true -... -test_run:cmd("setopt delimiter ';'") ---- -- true -... -function x_select(cn, space_id, index_id, iterator, offset, limit, key, opts) - local ret = cn:_request('select', opts, nil, space_id, index_id, iterator, - offset, limit, key) - return ret -end -function x_fatal(cn) cn._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') end -test_run:cmd("setopt delimiter ''"); ---- -... -LISTEN = require('uri').parse(box.cfg.listen) ---- -... -space = box.schema.space.create('net_box_test_space') ---- -... -index = space:create_index('primary', { type = 'tree' }) ---- -... --- low level connection -log.info("create connection") ---- -... -cn = remote.connect(LISTEN.host, LISTEN.service) ---- -... -log.info("state is %s", cn.state) ---- -... -cn:ping() ---- -- true -... -log.info("ping is done") ---- -... -cn:ping() ---- -- true -... -log.info("ping is done") ---- -... -cn:ping() ---- -- true -... --- check permissions -cn:call('unexists_procedure') ---- -- error: Execute access to function 'unexists_procedure' is denied for user 'guest' -... -function test_foo(a,b,c) return { {{ [a] = 1 }}, {{ [b] = 2 }}, c } end ---- -... -cn:call('test_foo', {'a', 'b', 'c'}) ---- -- error: Execute access to function 'test_foo' is denied for user 'guest' -... -cn:eval('return 2+2') ---- -- error: Execute access to universe '' is denied for user 'guest' -... -cn:close() ---- -... --- connect and call without usage access -box.schema.user.grant('guest','execute','universe') ---- -... -box.schema.user.revoke('guest','usage','universe') ---- -... -box.session.su("guest") ---- -... -cn = remote.connect(LISTEN.host, LISTEN.service) ---- -... -cn:call('test_foo', {'a', 'b', 'c'}) ---- -- error: Usage access to universe '' is denied for user 'guest' -... -box.session.su("admin") ---- -... -box.schema.user.grant('guest','usage','universe') ---- -... -cn:close() ---- -... -cn = remote.connect(box.cfg.listen) ---- -... -cn:call('unexists_procedure') ---- -- error: Procedure 'unexists_procedure' is not defined -... -cn:call('test_foo', {'a', 'b', 'c'}) ---- -- [[{'a': 1}], [{'b': 2}], 'c'] -... -cn:call(nil, {'a', 'b', 'c'}) ---- -- error: Procedure 'nil' is not defined -... -cn:eval('return 2+2') ---- -- 4 -... -cn:eval('return 1, 2, 3') ---- -- 1 -- 2 -- 3 -... -cn:eval('return ...', {1, 2, 3}) ---- -- 1 -- 2 -- 3 -... -cn:eval('return { k = "v1" }, true, { xx = 10, yy = 15 }, nil') ---- -- {'k': 'v1'} -- true -- {'yy': 15, 'xx': 10} -- null -... -cn:eval('return nil') ---- -- null -... -cn:eval('return') ---- -... -cn:eval('error("exception")') ---- -- error: 'eval:1: exception' -... -cn:eval('box.error(0)') ---- -- error: Unknown error -... -cn:eval('!invalid expression') ---- -- error: 'eval:1: unexpected symbol near ''!''' -... --- box.commit() missing at return of CALL/EVAL -function no_commit() box.begin() fiber.sleep(0.001) end ---- -... -cn:call('no_commit') ---- -- error: Transaction is active at return from function -... -cn:eval('no_commit()') ---- -- error: Transaction is active at return from function -... -remote.self:eval('return 1+1, 2+2') ---- -- 2 -- 4 -... -remote.self:eval('return') ---- -... -remote.self:eval('error("exception")') ---- -- error: '[string "error("exception")"]:1: exception' -... -remote.self:eval('box.error(0)') ---- -- error: Unknown error -... -remote.self:eval('!invalid expression') ---- -- error: '[string "return !invalid expression"]:1: unexpected symbol near ''!''' -... -box.schema.user.revoke('guest', 'execute', 'universe') ---- -... --- --- gh-822: net.box.call should roll back local transaction on error --- -_ = box.schema.space.create('gh822') ---- -... -_ = box.space.gh822:create_index('primary') ---- -... -test_run:cmd("setopt delimiter ';'") ---- -- true -... --- rollback on invalid function -function rollback_on_invalid_function() - box.begin() - box.space.gh822:insert{1, "netbox_test"} - pcall(remote.self.call, remote.self, 'invalid_function') - return box.space.gh822:get(1) == nil -end; ---- -... -rollback_on_invalid_function(); ---- -- true -... --- rollback on call error -function test_error() error('Some error') end; ---- -... -function rollback_on_call_error() - box.begin() - box.space.gh822:insert{1, "netbox_test"} - pcall(remote.self.call, remote.self, 'test_error') - return box.space.gh822:get(1) == nil -end; ---- -... -rollback_on_call_error(); ---- -- true -... --- rollback on eval -function rollback_on_eval_error() - box.begin() - box.space.gh822:insert{1, "netbox_test"} - pcall(remote.self.eval, remote.self, "error('Some error')") - return box.space.gh822:get(1) == nil -end; ---- -... -rollback_on_eval_error(); ---- -- true -... -test_run:cmd("setopt delimiter ''"); ---- -- true -... -box.space.gh822:drop() ---- -... -box.schema.user.grant('guest', 'read,write', 'space', 'net_box_test_space') ---- -... -box.schema.user.grant('guest', 'execute', 'universe') ---- -... -cn:close() ---- -... -cn = remote.connect(box.cfg.listen) ---- -... -x_select(cn, space.id, space.index.primary.id, box.index.EQ, 0, 0xFFFFFFFF, 123) ---- -- [] -... -space:insert{123, 345} ---- -- [123, 345] -... -x_select(cn, space.id, space.index.primary.id, box.index.EQ, 0, 0, 123) ---- -- [] -... -x_select(cn, space.id, space.index.primary.id, box.index.EQ, 0, 1, 123) ---- -- - [123, 345] -... -x_select(cn, space.id, space.index.primary.id, box.index.EQ, 1, 1, 123) ---- -- [] -... -cn.space[space.id] ~= nil ---- -- true -... -cn.space.net_box_test_space ~= nil ---- -- true -... -cn.space.net_box_test_space ~= nil ---- -- true -... -cn.space.net_box_test_space.index ~= nil ---- -- true -... -cn.space.net_box_test_space.index.primary ~= nil ---- -- true -... -cn.space.net_box_test_space.index[space.index.primary.id] ~= nil ---- -- true -... -cn.space.net_box_test_space.index.primary:select(123) ---- -- - [123, 345] -... -cn.space.net_box_test_space.index.primary:select(123, { limit = 0 }) ---- -- [] -... -cn.space.net_box_test_space.index.primary:select(nil, { limit = 1, }) ---- -- - [123, 345] -... -cn.space.net_box_test_space:insert{234, 1,2,3} ---- -- [234, 1, 2, 3] -... -cn.space.net_box_test_space:insert{234, 1,2,3} ---- -- error: Duplicate key exists in unique index 'primary' in space 'net_box_test_space' -... -cn.space.net_box_test_space.insert{234, 1,2,3} ---- -- error: 'builtin/box/schema.lua..."]:<line>: Use space:insert(...) instead of space.insert(...)' -... -cn.space.net_box_test_space:replace{354, 1,2,3} ---- -- [354, 1, 2, 3] -... -cn.space.net_box_test_space:replace{354, 1,2,4} ---- -- [354, 1, 2, 4] -... -cn.space.net_box_test_space:select{123} ---- -- - [123, 345] -... -space:select({123}, { iterator = 'GE' }) ---- -- - [123, 345] - - [234, 1, 2, 3] - - [354, 1, 2, 4] -... -cn.space.net_box_test_space:select({123}, { iterator = 'GE' }) ---- -- - [123, 345] - - [234, 1, 2, 3] - - [354, 1, 2, 4] -... -cn.space.net_box_test_space:select({123}, { iterator = 'GT' }) ---- -- - [234, 1, 2, 3] - - [354, 1, 2, 4] -... -cn.space.net_box_test_space:select({123}, { iterator = 'GT', limit = 1 }) ---- -- - [234, 1, 2, 3] -... -cn.space.net_box_test_space:select({123}, { iterator = 'GT', limit = 1, offset = 1 }) ---- -- - [354, 1, 2, 4] -... -cn.space.net_box_test_space:select{123} ---- -- - [123, 345] -... -cn.space.net_box_test_space:update({123}, { { '+', 2, 1 } }) ---- -- [123, 346] -... -cn.space.net_box_test_space:update(123, { { '+', 2, 1 } }) ---- -- [123, 347] -... -cn.space.net_box_test_space:select{123} ---- -- - [123, 347] -... -cn.space.net_box_test_space:insert(cn.space.net_box_test_space:get{123}:update{ { '=', 1, 2 } }) ---- -- [2, 347] -... -cn.space.net_box_test_space:delete{123} ---- -- [123, 347] -... -cn.space.net_box_test_space:select{2} ---- -- - [2, 347] -... -cn.space.net_box_test_space:select({234}, { iterator = 'LT' }) ---- -- - [2, 347] -... -cn.space.net_box_test_space:update({1}, { { '+', 2, 2 } }) ---- -... -cn.space.net_box_test_space:delete{1} ---- -... -cn.space.net_box_test_space:delete{2} ---- -- [2, 347] -... -cn.space.net_box_test_space:delete{2} ---- -... --- test one-based indexing in splice operation (see update.test.lua) -cn.space.net_box_test_space:replace({10, 'abcde'}) ---- -- [10, 'abcde'] -... -cn.space.net_box_test_space:update(10, {{':', 2, 0, 0, '!'}}) ---- -- error: 'SPLICE error on field 2: offset is out of bound' -... -cn.space.net_box_test_space:update(10, {{':', 2, 1, 0, '('}}) ---- -- [10, '(abcde'] -... -cn.space.net_box_test_space:update(10, {{':', 2, 2, 0, '({'}}) ---- -- [10, '(({abcde'] -... -cn.space.net_box_test_space:update(10, {{':', 2, -1, 0, ')'}}) ---- -- [10, '(({abcde)'] -... -cn.space.net_box_test_space:update(10, {{':', 2, -2, 0, '})'}}) ---- -- [10, '(({abcde}))'] -... -cn.space.net_box_test_space:delete{10} ---- -- [10, '(({abcde}))'] -... -cn.space.net_box_test_space:select({}, { iterator = 'ALL' }) ---- -- - [234, 1, 2, 3] - - [354, 1, 2, 4] -... --- gh-841: net.box uses incorrect iterator type for select with no arguments -cn.space.net_box_test_space:select() ---- -- - [234, 1, 2, 3] - - [354, 1, 2, 4] -... -cn.space.net_box_test_space.index.primary:min() ---- -- [234, 1, 2, 3] -... -cn.space.net_box_test_space.index.primary:min(354) ---- -- [354, 1, 2, 4] -... -cn.space.net_box_test_space.index.primary:max() ---- -- [354, 1, 2, 4] -... -cn.space.net_box_test_space.index.primary:max(234) ---- -- [234, 1, 2, 3] -... -cn.space.net_box_test_space.index.primary:count() ---- -- 2 -... -cn.space.net_box_test_space.index.primary:count(354) ---- -- 1 -... -cn.space.net_box_test_space:get(354) ---- -- [354, 1, 2, 4] -... --- reconnects after errors -box.schema.user.revoke('guest', 'execute', 'universe') ---- -... -box.schema.func.create('test_foo') ---- -... -box.schema.user.grant('guest', 'execute', 'function', 'test_foo') ---- -... --- -- 1. no reconnect -x_fatal(cn) ---- -... -cn.state ---- -- error -... -cn:ping() ---- -- false -... -cn:call('test_foo') ---- -- error: Peer closed -... -cn:wait_state('active') ---- -- false -... --- -- 2 reconnect -cn = remote.connect(LISTEN.host, LISTEN.service, { reconnect_after = .1 }) ---- -... -cn.space ~= nil ---- -- true -... -cn.space.net_box_test_space:select({}, { iterator = 'ALL' }) ---- -- - [234, 1, 2, 3] - - [354, 1, 2, 4] -... -x_fatal(cn) ---- -... -cn:wait_connected() ---- -- true -... -cn:wait_state('active') ---- -- true -... -cn:wait_state({active=true}) ---- -- true -... -cn:ping() ---- -- true -... -cn.state ---- -- active -... -cn.space.net_box_test_space:select({}, { iterator = 'ALL' }) ---- -- - [234, 1, 2, 3] - - [354, 1, 2, 4] -... -x_fatal(cn) ---- -... -x_select(cn, space.id, 0, box.index.ALL, 0, 0xFFFFFFFF, {}) ---- -- - [234, 1, 2, 3] - - [354, 1, 2, 4] -... -cn.state ---- -- active -... -cn:ping() ---- -- true -... --- -- dot-new-method -cn1 = remote.new(LISTEN.host, LISTEN.service) ---- -... -x_select(cn1, space.id, 0, box.index.ALL, 0, 0xFFFFFFF, {}) ---- -- - [234, 1, 2, 3] - - [354, 1, 2, 4] -... -cn1:close() ---- -... --- -- error while waiting for response -type(fiber.create(function() fiber.sleep(.5) x_fatal(cn) end)) ---- -- userdata -... -function pause() fiber.sleep(10) return true end ---- -... -box.schema.func.create('pause') ---- -... -box.schema.user.grant('guest', 'execute', 'function', 'pause') ---- -... -cn:call('pause') ---- -- error: Peer closed -... -cn:call('test_foo', {'a', 'b', 'c'}) ---- -- [[{'a': 1}], [{'b': 2}], 'c'] -... -box.schema.func.drop('pause') ---- -... --- call -remote.self:call('test_foo', {'a', 'b', 'c'}) ---- -- - - a: 1 - - - b: 2 - - c -... -cn:call('test_foo', {'a', 'b', 'c'}) ---- -- [[{'a': 1}], [{'b': 2}], 'c'] -... -box.schema.func.drop('test_foo') ---- -... -box.schema.func.create('long_rep') ---- -... -box.schema.user.grant('guest', 'execute', 'function', 'long_rep') ---- -... --- long replies -function long_rep() return { 1, string.rep('a', 5000) } end ---- -... -res = cn:call('long_rep') ---- -... -res[1] == 1 ---- -- true -... -res[2] == string.rep('a', 5000) ---- -- true -... -function long_rep() return { 1, string.rep('a', 50000) } end ---- -... -res = cn:call('long_rep') ---- -... -res[1] == 1 ---- -- true -... -res[2] == string.rep('a', 50000) ---- -- true -... -box.schema.func.drop('long_rep') ---- -... --- a.b.c.d -u = '84F7BCFA-079C-46CC-98B4-F0C821BE833E' ---- -... -X = {} ---- -... -X.X = X ---- -... -function X.fn(x,y) return y or x end ---- -... -box.schema.user.grant('guest', 'execute', 'universe') ---- -... -cn:close() ---- -... -cn = remote.connect(LISTEN.host, LISTEN.service) ---- -... -cn:call('X.fn', {u}) ---- -- 84F7BCFA-079C-46CC-98B4-F0C821BE833E -... -cn:call('X.X.X.X.X.X.X.fn', {u}) ---- -- 84F7BCFA-079C-46CC-98B4-F0C821BE833E -... -cn:call('X.X.X.X:fn', {u}) ---- -- 84F7BCFA-079C-46CC-98B4-F0C821BE833E -... -box.schema.user.revoke('guest', 'execute', 'universe') ---- -... -cn:close() ---- -... --- auth -cn = remote.connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123', wait_connected = true }) ---- -... -cn:is_connected() ---- -- false -... -cn.error ---- -- User 'netbox' is not found -... -cn.state ---- -- error -... -box.schema.user.create('netbox', { password = 'test' }) ---- -... -box.schema.user.grant('netbox', 'read,write', 'space', 'net_box_test_space') ---- -... -box.schema.user.grant('netbox', 'execute', 'universe') ---- -... -cn = remote.connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = 'test' }) ---- -... -cn.state ---- -- active -... -cn.error ---- -- null -... -cn:ping() ---- -- true -... -function ret_after(to) fiber.sleep(to) return {{to}} end ---- -... -cn:ping({timeout = 1.00}) ---- -- true -... -cn:ping({timeout = 1e-9}) ---- -- false -... -cn:ping() ---- -- true -... -remote_space = cn.space.net_box_test_space ---- -... -remote_pk = remote_space.index.primary ---- -... -remote_space:insert({0}, { timeout = 1.00 }) ---- -- [0] -... -remote_space:insert({1}, { timeout = 1e-9 }) ---- -- error: Timeout exceeded -... -remote_space:insert({2}) ---- -- [2] -... -remote_space:replace({0}, { timeout = 1e-9 }) ---- -- error: Timeout exceeded -... -remote_space:replace({1}) ---- -- [1] -... -remote_space:replace({2}, { timeout = 1.00 }) ---- -- [2] -... -remote_space:upsert({3}, {}, { timeout = 1e-9 }) ---- -- error: Timeout exceeded -... -remote_space:upsert({4}, {}) ---- -... -remote_space:upsert({5}, {}, { timeout = 1.00 }) ---- -... -remote_space:upsert({3}, {}) ---- -... -remote_space:update({3}, {}, { timeout = 1e-9 }) ---- -- error: Timeout exceeded -... -remote_space:update({4}, {}) ---- -- [4] -... -remote_space:update({5}, {}, { timeout = 1.00 }) ---- -- [5] -... -remote_space:update({3}, {}) ---- -- [3] -... -remote_pk:update({5}, {}, { timeout = 1e-9 }) ---- -- error: Timeout exceeded -... -remote_pk:update({4}, {}) ---- -- [4] -... -remote_pk:update({3}, {}, { timeout = 1.00 }) ---- -- [3] -... -remote_pk:update({5}, {}) ---- -- [5] -... -remote_space:get({0}) ---- -- [0] -... -remote_space:get({1}, { timeout = 1.00 }) ---- -- [1] -... -remote_space:get({2}, { timeout = 1e-9 }) ---- -- error: Timeout exceeded -... -remote_pk:get({3}, { timeout = 1e-9 }) ---- -- error: Timeout exceeded -... -remote_pk:get({4}) ---- -- [4] -... -remote_pk:get({5}, { timeout = 1.00 }) ---- -- [5] -... -remote_space:select({2}, { timeout = 1e-9 }) ---- -- error: Timeout exceeded -... -remote_space:select({2}, { timeout = 1.00 }) ---- -- - [2] -... -remote_space:select({2}) ---- -- - [2] -... -remote_pk:select({2}, { timeout = 1.00 }) ---- -- - [2] -... -remote_pk:select({2}, { timeout = 1e-9 }) ---- -- error: Timeout exceeded -... -remote_pk:select({2}) ---- -- - [2] -... -remote_space:select({5}, { timeout = 1.00, iterator = 'LE', limit = 5 }) ---- -- - [5] - - [4] - - [3] - - [2] - - [1] -... -remote_space:select({5}, { iterator = 'LE', limit = 5}) ---- -- - [5] - - [4] - - [3] - - [2] - - [1] -... -remote_space:select({5}, { timeout = 1e-9, iterator = 'LE', limit = 5 }) ---- -- error: Timeout exceeded -... -remote_pk:select({2}, { timeout = 1.00, iterator = 'LE', limit = 5 }) ---- -- - [2] - - [1] - - [0] -... -remote_pk:select({2}, { iterator = 'LE', limit = 5}) ---- -- - [2] - - [1] - - [0] -... -remote_pk:select({2}, { timeout = 1e-9, iterator = 'LE', limit = 5 }) ---- -- error: Timeout exceeded -... -remote_pk:count({2}, { timeout = 1.00}) ---- -- 1 -... -remote_pk:count({2}, { timeout = 1e-9}) ---- -- error: Timeout exceeded -... -remote_pk:count({2}) ---- -- 1 -... -remote_pk:count({2}, { timeout = 1.00, iterator = 'LE' }) ---- -- 3 -... -remote_pk:count({2}, { iterator = 'LE'}) ---- -- 3 -... -remote_pk:count({2}, { timeout = 1e-9, iterator = 'LE' }) ---- -- error: Timeout exceeded -... -remote_pk:min(nil, { timeout = 1.00 }) ---- -- [0] -... -remote_pk:min(nil, { timeout = 1e-9 }) ---- -- error: Timeout exceeded -... -remote_pk:min(nil) ---- -- [0] -... -remote_pk:min({0}, { timeout = 1e-9 }) ---- -- error: Timeout exceeded -... -remote_pk:min({1}) ---- -- [1] -... -remote_pk:min({2}, { timeout = 1.00 }) ---- -- [2] -... -remote_pk:max(nil) ---- -- [354, 1, 2, 4] -... -remote_pk:max(nil, { timeout = 1e-9 }) ---- -- error: Timeout exceeded -... -remote_pk:max(nil, { timeout = 1.00 }) ---- -- [354, 1, 2, 4] -... -remote_pk:max({0}, { timeout = 1.00 }) ---- -- [0] -... -remote_pk:max({1}, { timeout = 1e-9 }) ---- -- error: Timeout exceeded -... -remote_pk:max({2}) ---- -- [2] -... --- --- gh-3262: index:count() inconsistent results --- -test_run:cmd("setopt delimiter ';'") ---- -- true -... -function do_count_test(min, it) - local r1 = remote_pk:count(min, {iterator = it} ) - local r2 = box.space.net_box_test_space.index.primary:count(min, {iterator = it} ) - local r3 = remote.self.space.net_box_test_space.index.primary:count(min, {iterator = it} ) - return r1 == r2 and r2 == r3 -end; ---- -... -data = remote_pk:select(); ---- -... -for _, v in pairs(data) do - local itrs = {'GE', 'GT', 'LE', 'LT' } - for _, it in pairs(itrs) do - assert(do_count_test(v[0], it) == true) - end -end; ---- -... -test_run:cmd("setopt delimiter ''"); ---- -- true -... -_ = remote_space:delete({0}, { timeout = 1e-9 }) ---- -- error: Timeout exceeded -... -_ = remote_pk:delete({0}, { timeout = 1.00 }) ---- -... -_ = remote_space:delete({1}, { timeout = 1.00 }) ---- -... -_ = remote_pk:delete({1}, { timeout = 1e-9 }) ---- -- error: Timeout exceeded -... -_ = remote_space:delete({2}, { timeout = 1e-9 }) ---- -- error: Timeout exceeded -... -_ = remote_pk:delete({2}) ---- -... -_ = remote_pk:delete({3}) ---- -... -_ = remote_pk:delete({4}) ---- -... -_ = remote_pk:delete({5}) ---- -... -remote_space:get(0) ---- -... -remote_space:get(1) ---- -... -remote_space:get(2) ---- -... -remote_space = nil ---- -... -cn:call('ret_after', {0.01}, { timeout = 1.00 }) ---- -- [[0.01]] -... -cn:call('ret_after', {1.00}, { timeout = 1e-9 }) ---- -- error: Timeout exceeded -... -cn:eval('return ret_after(...)', {0.01}, { timeout = 1.00 }) ---- -- [[0.01]] -... -cn:eval('return ret_after(...)', {1.00}, { timeout = 1e-9 }) ---- -- error: Timeout exceeded -... --- --- :timeout() --- @deprecated since 1.7.4 --- -cn:timeout(1).space.net_box_test_space.index.primary:select{234} ---- -- - [234, 1, 2, 3] -... -cn:call('ret_after', {.01}) ---- -- [[0.01]] -... -cn:timeout(1):call('ret_after', {.01}) ---- -- [[0.01]] -... -cn:timeout(.01):call('ret_after', {1}) ---- -- error: Timeout exceeded -... -cn = remote:timeout(0.0000000001):connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123' }) ---- -... -cn:close() ---- -... -cn = remote:timeout(1):connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123' }) ---- -... -remote.self:ping() ---- -- true -... -remote.self.space.net_box_test_space:select{234} ---- -- - [234, 1, 2, 3] -... -remote.self:timeout(123).space.net_box_test_space:select{234} ---- -- - [234, 1, 2, 3] -... -remote.self:is_connected() ---- -- true -... -remote.self:wait_connected() ---- -- true -... -cn:close() ---- -... --- cleanup database after tests -space:drop() ---- -... --- #1545 empty password -cn = remote.connect(LISTEN.host, LISTEN.service, { user = 'test' }) ---- -... -cn ~= nil ---- -- true -... -cn:close() ---- -... -cn = remote.connect(LISTEN.host, LISTEN.service, { password = 'test' }) ---- -- error: 'net.box: user is not defined' -... -cn ~= nil ---- -- true -... -cn:close() ---- -... --- #544 usage for remote[point]method -cn = remote.connect(LISTEN.host, LISTEN.service) ---- -... -box.schema.user.grant('guest', 'execute', 'universe') ---- -... -cn:close() ---- -... -cn = remote.connect(LISTEN.host, LISTEN.service) ---- -... -cn:eval('return true') ---- -- true -... -cn.eval('return true') ---- -- error: 'Use remote:eval(...) instead of remote.eval(...):' -... -cn.ping() ---- -- error: 'Use remote:ping(...) instead of remote.ping(...):' -... -cn:close() ---- -... -remote.self:eval('return true') ---- -- true -... -remote.self.eval('return true') ---- -- error: 'Use remote:eval(...) instead of remote.eval(...):' -... -box.schema.user.revoke('guest', 'execute', 'universe') ---- -... --- uri as the first argument -uri = string.format('%s:%s@%s:%s', 'netbox', 'test', LISTEN.host, LISTEN.service) ---- -... -cn = remote.new(uri) ---- -... -cn:ping() ---- -- true -... -cn:close() ---- -... -uri = string.format('%s@%s:%s', 'netbox', LISTEN.host, LISTEN.service) ---- -... -cn = remote.new(uri) ---- -... -cn ~= nil, cn.state, cn.error ---- -- true -- error -- Incorrect password supplied for user 'netbox' -... -cn:close() ---- -... --- don't merge creds from uri & opts -remote.new(uri, { password = 'test' }) ---- -- error: 'net.box: user is not defined' -... -cn = remote.new(uri, { user = 'netbox', password = 'test' }) ---- -... -cn:ping() ---- -- true -... -cn:close() ---- -... -box.schema.user.drop('netbox') ---- -... --- #594: bad argument #1 to 'setmetatable' (table expected, got number) -box.schema.func.create('dostring') ---- -... -box.schema.user.grant('guest', 'execute', 'function', 'dostring') ---- -... -test_run:cmd("setopt delimiter ';'") ---- -- true -... -function gh594() - local cn = remote.connect(box.cfg.listen) - local ping = fiber.create(function() cn:ping() end) - cn:call('dostring', {'return 2 + 2'}) - cn:close() -end; ---- -... -test_run:cmd("setopt delimiter ''"); ---- -- true -... -gh594() ---- -... -box.schema.func.drop('dostring') ---- -... --- #636: Reload schema on demand -sp = box.schema.space.create('test_old') ---- -... -_ = sp:create_index('primary') ---- -... -sp:insert{1, 2, 3} ---- -- [1, 2, 3] -... -box.schema.user.grant('guest', 'read', 'space', 'test_old') ---- -... -con = remote.new(box.cfg.listen) ---- -... -con:ping() ---- -- true -... -con.space.test_old:select{} ---- -- - [1, 2, 3] -... -con.space.test == nil ---- -- true -... -sp = box.schema.space.create('test') ---- -... -_ = sp:create_index('primary') ---- -... -sp:insert{2, 3, 4} ---- -- [2, 3, 4] -... -box.schema.user.grant('guest', 'read', 'space', 'test') ---- -... -con.space.test == nil ---- -- true -... -con:reload_schema() ---- -... -con.space.test:select{} ---- -- - [2, 3, 4] -... -box.space.test:drop() ---- -... -box.space.test_old:drop() ---- -... -con:close() ---- -... -name = string.match(arg[0], "([^,]+)%.lua") ---- -... -file_log = require('fio').open(name .. '.log', {'O_RDONLY', 'O_NONBLOCK'}) ---- -... -file_log:seek(0, 'SEEK_END') ~= 0 ---- -- true -... -box.schema.user.grant('guest', 'execute', 'universe') ---- -... -test_run:cmd("setopt delimiter ';'") ---- -- true -... -_ = fiber.create( - function() - local conn = require('net.box').new(box.cfg.listen) - conn:call('no_such_function', {}) - conn:close() - end -); ---- -... -test_run:cmd("setopt delimiter ''"); ---- -- true -... -test_run:wait_log('default', 'ER_NO_SUCH_PROC', nil, 10) ---- -- ER_NO_SUCH_PROC -... -box.schema.user.revoke('guest', 'execute', 'universe') ---- -... --- --- gh-3900: tarantool can be crashed by sending gibberish to a --- binary socket --- -socket = require("socket") ---- -... -sock = socket.tcp_connect(LISTEN.host, LISTEN.service) ---- -... -data = string.fromhex("6783000000000000000000000000000000000000000000800000C8000000000000000000000000000000000000000000FFFF210100373208000000FFFF000055AAEB66486472530D02000000000010A0350001008000001000000000000000000000000000D05700") ---- -... -sock:write(data) ---- -- 104 -... -test_run:wait_log('default', 'ER_INVALID_MSGPACK: Invalid MsgPack %- packet body', nil, 10) ---- -- 'ER_INVALID_MSGPACK: Invalid MsgPack - packet body' -... -sock:close() ---- -- true -... --- gh-983 selecting a lot of data crashes the server or hangs the --- connection --- gh-983 test case: iproto connection selecting a lot of data -_ = box.schema.space.create('test', { temporary = true }) ---- -... -_ = box.space.test:create_index('primary', {type = 'TREE', parts = {1,'unsigned'}}) ---- -... -data1k = "aaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhh" ---- -... -for i = 0,10000 do box.space.test:insert{i, data1k} end ---- -... -box.schema.user.grant('guest', 'read', 'space', 'test') ---- -... -net = require('net.box') ---- -... -c = net:connect(box.cfg.listen) ---- -... -r = c.space.test:select(nil, {limit=5000}) ---- -... -box.space.test:drop() ---- -... --- gh-970 gh-971 UPSERT over network -_ = box.schema.space.create('test') ---- -... -_ = box.space.test:create_index('primary', {type = 'TREE', parts = {1,'unsigned'}}) ---- -... -_ = box.space.test:create_index('covering', {type = 'TREE', parts = {1,'unsigned',3,'string',2,'unsigned'}}) ---- -... -_ = box.space.test:insert{1, 2, "string"} ---- -... -box.schema.user.grant('guest', 'read,write', 'space', 'test') ---- -... -c = net:connect(box.cfg.listen) ---- -... -c.space.test:select{} ---- -- - [1, 2, 'string'] -... -c.space.test:upsert({1, 2, 'nothing'}, {{'+', 2, 1}}) -- common update ---- -... -c.space.test:select{} ---- -- - [1, 3, 'string'] -... -c.space.test:upsert({2, 4, 'something'}, {{'+', 2, 1}}) -- insert ---- -... -c.space.test:select{} ---- -- - [1, 3, 'string'] - - [2, 4, 'something'] -... -c.space.test:upsert({2, 4, 'nothing'}, {{'+', 3, 100500}}) -- wrong operation ---- -... -c.space.test:select{} ---- -- - [1, 3, 'string'] - - [2, 4, 'something'] -... --- gh-1729 net.box index metadata incompatible with local metadata -c.space.test.index.primary.parts ---- -- - type: unsigned - is_nullable: false - fieldno: 1 -... -c.space.test.index.covering.parts ---- -- - type: unsigned - is_nullable: false - fieldno: 1 - - type: string - is_nullable: false - fieldno: 3 - - type: unsigned - is_nullable: false - fieldno: 2 -... -box.space.test:drop() ---- -... --- CALL vs CALL_16 in connect options -function echo(...) return ... end ---- -... -box.schema.user.grant('guest', 'execute', 'universe') ---- -... -c = net.connect(box.cfg.listen) ---- -... -c:call('echo', {42}) ---- -- 42 -... -c:eval('return echo(...)', {42}) ---- -- 42 -... --- invalid arguments -c:call('echo', 42) ---- -- error: 'builtin/box/net_box.lua..."]:<line>: Use remote:call(func_name, {arg1, arg2, ...}, - opts) instead of remote:call(func_name, arg1, arg2, ...)' -... -c:eval('return echo(...)', 42) ---- -- error: 'builtin/box/net_box.lua..."]:<line>: Use remote:eval(expression, {arg1, arg2, ...}, - opts) instead of remote:eval(expression, arg1, arg2, ...)' -... -c:close() ---- -... -c = net.connect(box.cfg.listen, {call_16 = true}) ---- -... -c:call('echo', 42) ---- -- - [42] -... -c:eval('return echo(...)', 42) ---- -- 42 -... -c:close() ---- -... -box.schema.user.revoke('guest', 'execute', 'universe') ---- -... --- --- gh-2195 export pure msgpack from net.box --- -space = box.schema.space.create('test') ---- -... -_ = box.space.test:create_index('primary') ---- -... -box.schema.user.grant('guest', 'read,write', 'space', 'test') ---- -... -box.schema.user.grant('guest', 'execute', 'universe') ---- -... -c = net.connect(box.cfg.listen) ---- -... -ibuf = require('buffer').ibuf() ---- -... -c:ping() ---- -- true -... -c.space.test ~= nil ---- -- true -... -c.space.test:replace({1, 'hello'}) ---- -- [1, 'hello'] -... --- replace -c.space.test:replace({2}, {buffer = ibuf}) ---- -- 9 -... -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) ---- -... -result ---- -- {48: [[2]]} -... --- replace + skip_header -c.space.test:replace({2}, {buffer = ibuf, skip_header = true}) ---- -- 7 -... -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) ---- -... -result ---- -- [[2]] -... --- insert -c.space.test:insert({3}, {buffer = ibuf}) ---- -- 9 -... -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) ---- -... -result ---- -- {48: [[3]]} -... --- insert + skip_header -_ = space:delete({3}) ---- -... -c.space.test:insert({3}, {buffer = ibuf, skip_header = true}) ---- -- 7 -... -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) ---- -... -result ---- -- [[3]] -... --- update -c.space.test:update({3}, {}, {buffer = ibuf}) ---- -- 9 -... -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) ---- -... -result ---- -- {48: [[3]]} -... -c.space.test.index.primary:update({3}, {}, {buffer = ibuf}) ---- -- 9 -... -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) ---- -... -result ---- -- {48: [[3]]} -... --- update + skip_header -c.space.test:update({3}, {}, {buffer = ibuf, skip_header = true}) ---- -- 7 -... -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) ---- -... -result ---- -- [[3]] -... -c.space.test.index.primary:update({3}, {}, {buffer = ibuf, skip_header = true}) ---- -- 7 -... -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) ---- -... -result ---- -- [[3]] -... --- upsert -c.space.test:upsert({4}, {}, {buffer = ibuf}) ---- -- 7 -... -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) ---- -... -result ---- -- {48: []} -... --- upsert + skip_header -c.space.test:upsert({4}, {}, {buffer = ibuf, skip_header = true}) ---- -- 5 -... -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) ---- -... -result ---- -- [] -... --- delete -c.space.test:upsert({4}, {}, {buffer = ibuf}) ---- -- 7 -... -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) ---- -... -result ---- -- {48: []} -... --- delete + skip_header -c.space.test:upsert({4}, {}, {buffer = ibuf, skip_header = true}) ---- -- 5 -... -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) ---- -... -result ---- -- [] -... --- select -c.space.test.index.primary:select({3}, {iterator = 'LE', buffer = ibuf}) ---- -- 19 -... -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) ---- -... -result ---- -- {48: [[3], [2], [1, 'hello']]} -... --- select + skip_header -c.space.test.index.primary:select({3}, {iterator = 'LE', buffer = ibuf, skip_header = true}) ---- -- 17 -... -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) ---- -... -result ---- -- [[3], [2], [1, 'hello']] -... --- select -len = c.space.test:select({}, {buffer = ibuf}) ---- -... -ibuf.rpos + len == ibuf.wpos ---- -- true -... -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) ---- -... -ibuf.rpos == ibuf.wpos ---- -- true -... -len ---- -- 21 -... -result ---- -- {48: [[1, 'hello'], [2], [3], [4]]} -... --- select + skip_header -len = c.space.test:select({}, {buffer = ibuf, skip_header = true}) ---- -... -ibuf.rpos + len == ibuf.wpos ---- -- true -... -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) ---- -... -ibuf.rpos == ibuf.wpos ---- -- true -... -len ---- -- 19 -... -result ---- -- [[1, 'hello'], [2], [3], [4]] -... --- call -c:call("echo", {1, 2, 3}, {buffer = ibuf}) ---- -- 10 -... -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) ---- -... -result ---- -- {48: [1, 2, 3]} -... -c:call("echo", {}, {buffer = ibuf}) ---- -- 7 -... -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) ---- -... -result ---- -- {48: []} -... -c:call("echo", nil, {buffer = ibuf}) ---- -- 7 -... -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) ---- -... -result ---- -- {48: []} -... --- call + skip_header -c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) ---- -- 8 -... -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) ---- -... -result ---- -- [1, 2, 3] -... -c:call("echo", {}, {buffer = ibuf, skip_header = true}) ---- -- 5 -... -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) ---- -... -result ---- -- [] -... -c:call("echo", nil, {buffer = ibuf, skip_header = true}) ---- -- 5 -... -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) ---- -... -result ---- -- [] -... --- eval -c:eval("echo(...)", {1, 2, 3}, {buffer = ibuf}) ---- -- 7 -... -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) ---- -... -result ---- -- {48: []} -... -c:eval("echo(...)", {}, {buffer = ibuf}) ---- -- 7 -... -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) ---- -... -result ---- -- {48: []} -... -c:eval("echo(...)", nil, {buffer = ibuf}) ---- -- 7 -... -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) ---- -... -result ---- -- {48: []} -... --- eval + skip_header -c:eval("echo(...)", {1, 2, 3}, {buffer = ibuf, skip_header = true}) ---- -- 5 -... -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) ---- -... -result ---- -- [] -... -c:eval("echo(...)", {}, {buffer = ibuf, skip_header = true}) ---- -- 5 -... -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) ---- -... -result ---- -- [] -... -c:eval("echo(...)", nil, {buffer = ibuf, skip_header = true}) ---- -- 5 -... -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) ---- -... -result ---- -- [] -... --- make several request into a buffer with skip_header, then read --- results -c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) ---- -- 8 -... -c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) ---- -- 8 -... -c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) ---- -- 8 -... -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) ---- -... -result ---- -- [1, 2, 3] -... -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) ---- -... -result ---- -- [1, 2, 3] -... -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) ---- -... -result ---- -- [1, 2, 3] -... --- unsupported methods -c.space.test:get({1}, { buffer = ibuf}) ---- -- error: 'builtin/box/net_box.lua..."]:<line>: index:get() doesn''t support `buffer` argument' -... -c.space.test.index.primary:min({}, { buffer = ibuf}) ---- -- error: 'builtin/box/net_box.lua..."]:<line>: index:min() doesn''t support `buffer` argument' -... -c.space.test.index.primary:max({}, { buffer = ibuf}) ---- -- error: 'builtin/box/net_box.lua..."]:<line>: index:max() doesn''t support `buffer` argument' -... -c.space.test.index.primary:count({}, { buffer = ibuf}) ---- -- error: 'builtin/box/net_box.lua..."]:<line>: index:count() doesn''t support `buffer` argument' -... -c.space.test.index.primary:get({1}, { buffer = ibuf}) ---- -- error: 'builtin/box/net_box.lua..."]:<line>: index:get() doesn''t support `buffer` argument' -... --- error handling -rpos, wpos = ibuf.rpos, ibuf.wpos ---- -... -c.space.test:insert({1}, {buffer = ibuf}) ---- -- error: Duplicate key exists in unique index 'primary' in space 'test' -... -ibuf.rpos == rpos, ibuf.wpos == wpos ---- -- true -- true -... -ibuf = nil ---- -... -c:close() ---- -... -space:drop() ---- -... -box.schema.user.revoke('guest', 'execute', 'universe') ---- -... --- gh-1904 net.box hangs in :close() if a fiber was cancelled --- while blocked in :_wait_state() in :_request() -options = {user = 'netbox', password = 'badpass', wait_connected = false, reconnect_after = 0.01} ---- -... -c = net:new(box.cfg.listen, options) ---- -... -f = fiber.create(function() c:call("") end) ---- -... -fiber.sleep(0.01) ---- -... -f:cancel(); c:close() ---- -... -box.schema.user.grant('guest', 'read', 'space', '_schema') ---- -... --- check for on_schema_reload callback -test_run:cmd("setopt delimiter ';'") ---- -- true -... -do - local a = 0 - function osr_cb() - a = a + 1 - end - local con = net.new(box.cfg.listen, { - wait_connected = false - }) - con:on_schema_reload(osr_cb) - con:wait_connected() - con.space._schema:select{} - box.schema.space.create('misisipi') - box.space.misisipi:drop() - con.space._schema:select{} - con:close() - con = nil - - return a -end; ---- -- 2 -... -do - local a = 0 - function osr_cb() - a = a + 1 - end - local con = net.new(box.cfg.listen, { - wait_connected = true - }) - con:on_schema_reload(osr_cb) - con.space._schema:select{} - box.schema.space.create('misisipi') - box.space.misisipi:drop() - con.space._schema:select{} - con:close() - con = nil - - return a -end; ---- -- 1 -... -test_run:cmd("setopt delimiter ''"); ---- -- true -... -box.schema.user.revoke('guest', 'read', 'space', '_schema') ---- -... --- Tarantool < 1.7.1 compatibility (gh-1533) -c = net.new(box.cfg.listen) ---- -... -c:ping() ---- -- true -... -c:close() ---- -... --- Test for connect_timeout > 0 in netbox connect -test_run:cmd("setopt delimiter ';'"); ---- -- true -... -need_stop = false; ---- -... -greeting = -"Tarantool 1.7.3 (Lua console)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" .. -"type 'help' for interactive help~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"; ---- -... -socket = require('socket'); ---- -... -srv = socket.tcp_server('localhost', 0, { - handler = function(fd) - local fiber = require('fiber') - while not need_stop do - fiber.sleep(0.01) - end - fd:write(greeting) - end -}); ---- -... --- we must get timeout -port = srv:name().port -nb = net.new('localhost:' .. port, { - wait_connected = true, console = true, - connect_timeout = 0.1 -}); ---- -... -nb.error:find('timed out') ~= nil; ---- -- true -... -need_stop = true -nb:close(); ---- -... --- we must get peer closed -nb = net.new('localhost:' .. port, { - wait_connected = true, console = true, - connect_timeout = 0.2 -}); ---- -... -nb.error ~= "Timeout exceeded"; ---- -- true -... -nb:close(); ---- -... -test_run:cmd("setopt delimiter ''"); ---- -- true -... -srv:close() ---- -- true -... -test_run:cmd("clear filter") ---- -- true -... --- --- gh-2402 net.box doesn't support space:format() --- -space = box.schema.space.create('test', {format={{name="id", type="unsigned"}}}) ---- -... -space ~= nil ---- -- true -... -_ = box.space.test:create_index('primary') ---- -... -box.schema.user.grant('guest', 'read', 'space', 'test') ---- -... -c = net.connect(box.cfg.listen) ---- -... -c:ping() ---- -- true -... -c.space.test ~= nil ---- -- true -... -format = c.space.test:format() ---- -... -format[1] ~= nil ---- -- true -... -format[1].name == "id" ---- -- true -... -format[1].type == "unsigned" ---- -- true -... -c.space.test:format({}) ---- -- error: net.box does not support setting space format -... --- --- gh-4091: index unique flag is always false. --- -c.space.test.index.primary.unique ---- -- true -... -c:close() ---- -... -space:drop() ---- -... --- --- Check that it's possible to get connection object form net.box space --- -space = box.schema.space.create('test', {format={{name="id", type="unsigned"}}}) ---- -... -space ~= nil ---- -- true -... -_ = box.space.test:create_index('primary') ---- -... -box.schema.user.grant('guest','read,write,execute','space', 'test') ---- -... -c = net.connect(box.cfg.listen) ---- -... -c:ping() ---- -- true -... -c.space.test ~= nil ---- -- true -... -c.space.test.connection == c ---- -- true -... -box.schema.user.revoke('guest','read,write,execute','space', 'test') ---- -... -c:close() ---- -... --- --- gh-2642: box.session.type() --- -box.schema.user.grant('guest','execute','universe') ---- -... -c = net.connect(box.cfg.listen) ---- -... -c:call("box.session.type") ---- -- binary -... -c:close() ---- -... -box.schema.user.revoke('guest', 'execute', 'universe') ---- -... --- --- On_connect/disconnect triggers. --- -test_run:cmd('create server connecter with script = "box/proxy.lua"') ---- -- true -... -test_run:cmd('start server connecter') ---- -- true -... -test_run:cmd("set variable connect_to to 'connecter.listen'") ---- -- true -... -conn = net.connect(connect_to, { reconnect_after = 0.1 }) ---- -... -conn.state ---- -- active -... -connected_cnt = 0 ---- -... -disconnected_cnt = 0 ---- -... -function on_connect() connected_cnt = connected_cnt + 1 end ---- -... -function on_disconnect() disconnected_cnt = disconnected_cnt + 1 end ---- -... -conn:on_connect(on_connect) ---- -... -conn:on_disconnect(on_disconnect) ---- -... -test_run:cmd('stop server connecter') ---- -- true -... -test_run:cmd('start server connecter') ---- -- true -... -while conn.state ~= 'active' do fiber.sleep(0.1) end ---- -... -connected_cnt ---- -- 1 -... -old_disconnected_cnt = disconnected_cnt ---- -... -disconnected_cnt >= 1 ---- -- true -... -conn:close() ---- -... -disconnected_cnt == old_disconnected_cnt + 1 ---- -- true -... -test_run:cmd('stop server connecter') ---- -- true -... --- --- gh-2401 update pseudo objects not replace them --- -space:drop() ---- -... -space = box.schema.space.create('test') ---- -... -box.schema.user.grant('guest', 'read', 'space', 'test') ---- -... -c = net.connect(box.cfg.listen) ---- -... -cspace = c.space.test ---- -... -space.index.test_index == nil ---- -- true -... -cspace.index.test_index == nil ---- -- true -... -_ = space:create_index("test_index", {parts={1, 'string'}}) ---- -... -c:reload_schema() ---- -... -space.index.test_index ~= nil ---- -- true -... -cspace.index.test_index ~= nil ---- -- true -... -c.space.test.index.test_index ~= nil ---- -- true -... --- cleanup -space:drop() ---- -... --- --- gh-946: long polling CALL blocks input --- -box.schema.func.create('fast_call') ---- -... -box.schema.func.create('long_call') ---- -... -box.schema.func.create('wait_signal') ---- -... -box.schema.user.grant('guest', 'execute', 'function', 'fast_call') ---- -... -box.schema.user.grant('guest', 'execute', 'function', 'long_call') ---- -... -box.schema.user.grant('guest', 'execute', 'function', 'wait_signal') ---- -... -c = net.connect(box.cfg.listen) ---- -... -N = 100 ---- -... -pad = string.rep('x', 1024) ---- -... -long_call_cond = fiber.cond() ---- -... -long_call_channel = fiber.channel() ---- -... -fast_call_channel = fiber.channel() ---- -... -function fast_call(x) return x end ---- -... -function long_call(x) long_call_cond:wait() return x * 2 end ---- -... -test_run:cmd("setopt delimiter ';'") ---- -- true -... -for i = 1, N do - fiber.create(function() - fast_call_channel:put(c:call('fast_call', {i, pad})) - end) - fiber.create(function() - long_call_channel:put(c:call('long_call', {i, pad})) - end) -end -test_run:cmd("setopt delimiter ''"); ---- -... -x = 0 ---- -... -for i = 1, N do x = x + fast_call_channel:get() end ---- -... -x ---- -- 5050 -... -long_call_cond:broadcast() ---- -... -x = 0 ---- -... -for i = 1, N do x = x + long_call_channel:get() end ---- -... -x ---- -- 10100 -... --- --- Check that a connection does not leak if there is --- a long CALL in progress when it is closed. --- -disconnected = false ---- -... -function on_disconnect() disconnected = true end ---- -... --- Make sure all dangling connections are collected so --- that on_disconnect trigger isn't called spuriously. -collectgarbage('collect') ---- -- 0 -... -fiber.sleep(0) ---- -... -box.session.on_disconnect(on_disconnect) == on_disconnect ---- -- true -... --- --- gh-3859: on_disconnect is called only after all requests are --- processed, but should be called right after disconnect and --- only once. --- -ch1 = fiber.channel(1) ---- -... -ch2 = fiber.channel(1) ---- -... -function wait_signal() ch1:put(true) ch2:get() end ---- -... -_ = fiber.create(function() c:call('wait_signal') end) ---- -... -ch1:get() ---- -- true -... -c:close() ---- -... -fiber.sleep(0) ---- -... -while disconnected == false do fiber.sleep(0.01) end ---- -... -disconnected -- true ---- -- true -... -disconnected = nil ---- -... -ch2:put(true) ---- -- true -... -fiber.sleep(0) ---- -... -disconnected -- nil, on_disconnect is not called second time. ---- -- null -... -box.session.on_disconnect(nil, on_disconnect) ---- -... -box.schema.func.drop('long_call') ---- -... -box.schema.func.drop('fast_call') ---- -... -box.schema.func.drop('wait_signal') ---- -... --- --- gh-2666: check that netbox.call is not repeated on schema --- change. --- -box.schema.user.grant('guest', 'write', 'space', '_space') ---- -... -box.schema.user.grant('guest', 'write', 'space', '_schema') ---- -... -box.schema.user.grant('guest', 'create', 'universe') ---- -... -count = 0 ---- -... -function create_space(name) count = count + 1 box.schema.create_space(name) return true end ---- -... -box.schema.func.create('create_space') ---- -... -box.schema.user.grant('guest', 'execute', 'function', 'create_space') ---- -... -c = net.connect(box.cfg.listen) ---- -... -c:call('create_space', {'test1'}) ---- -- true -... -count ---- -- 1 -... -c:call('create_space', {'test2'}) ---- -- true -... -count ---- -- 2 -... -c:call('create_space', {'test3'}) ---- -- true -... -count ---- -- 3 -... -box.space.test1:drop() ---- -... -box.space.test2:drop() ---- -... -box.space.test3:drop() ---- -... -box.schema.user.revoke('guest', 'write', 'space', '_space') ---- -... -box.schema.user.revoke('guest', 'write', 'space', '_schema') ---- -... -box.schema.user.revoke('guest', 'create', 'universe') ---- -... -c:close() ---- -... -box.schema.func.drop('create_space') ---- -... --- --- gh-3164: netbox connection is not closed and garbage collected --- ever, if reconnect_after is set. --- -test_run:cmd('start server connecter') ---- -- true -... -test_run:cmd("set variable connect_to to 'connecter.listen'") ---- -- true -... -weak = setmetatable({}, {__mode = 'v'}) ---- -... --- Create strong and weak reference. Weak is valid until strong --- is valid too. -strong = net.connect(connect_to, {reconnect_after = 0.1}) ---- -... -weak.c = strong ---- -... -weak.c:ping() ---- -- true -... -test_run:cmd('stop server connecter') ---- -- true -... -test_run:cmd('cleanup server connecter') ---- -- true -... --- Check the connection tries to reconnect at least two times. --- 'Cannot assign requested address' is the crutch for running the --- tests in a docker. This error emits instead of --- 'Connection refused' inside a docker. -old_log_level = box.cfg.log_level ---- -... -box.cfg{log_level = 6} ---- -... -log.info(string.rep('a', 1000)) ---- -... -test_run:cmd("setopt delimiter ';'") ---- -- true -... -while test_run:grep_log('default', 'Network is unreachable', 1000) == nil and - test_run:grep_log('default', 'Connection refused', 1000) == nil and - test_run:grep_log('default', 'Cannot assign requested address', 1000) == nil do - fiber.sleep(0.1) -end; ---- -... -log.info(string.rep('a', 1000)); ---- -... -while test_run:grep_log('default', 'Network is unreachable', 1000) == nil and - test_run:grep_log('default', 'Connection refused', 1000) == nil and - test_run:grep_log('default', 'Cannot assign requested address', 1000) == nil do - fiber.sleep(0.1) -end; ---- -... -test_run:cmd("setopt delimiter ''"); ---- -- true -... -box.cfg{log_level = old_log_level} ---- -... -collectgarbage('collect') ---- -- 0 -... -strong.state ---- -- error_reconnect -... -strong == weak.c ---- -- true -... --- Remove single strong reference. Now connection must be garbage --- collected. -strong = nil ---- -... -collectgarbage('collect') ---- -- 0 -... --- Now weak.c is null, because it was weak reference, and the --- connection is deleted by 'collect'. -weak.c ---- -- null -... --- --- gh-2677: netbox supports console connections, that complicates --- both console and netbox. It was necessary because before a --- connection is established, a console does not known is it --- binary or text protocol, and netbox could not be created from --- existing socket. --- -box.schema.user.grant('guest', 'execute', 'universe') ---- -... -urilib = require('uri') ---- -... -uri = urilib.parse(tostring(box.cfg.listen)) ---- -... -s, greeting = net.establish_connection(uri.host, uri.service) ---- -... -c = net.wrap(s, greeting, uri.host, uri.service, {reconnect_after = 0.01}) ---- -... -c.state ---- -- active -... -a = 100 ---- -... -function kek(args) return {1, 2, 3, args} end ---- -... -c:eval('a = 200') ---- -... -a ---- -- 200 -... -c:call('kek', {300}) ---- -- [1, 2, 3, 300] -... -s = box.schema.create_space('test') ---- -... -box.schema.user.grant('guest', 'read,write', 'space', 'test') ---- -... -pk = s:create_index('pk') ---- -... -c:reload_schema() ---- -... -c.space.test:replace{1} ---- -- [1] -... -c.space.test:get{1} ---- -- [1] -... -c.space.test:delete{1} ---- -- [1] -... --- --- Break a connection to test reconnect_after. --- -_ = c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') ---- -... -while not c:is_connected() do fiber.sleep(0.01) end ---- -... -c:ping() ---- -- true -... -s:drop() ---- -... -c:close() ---- -... --- --- Test a case, when netbox can not connect first time, but --- reconnect_after is set. --- -c = net.connect('localhost:33333', {reconnect_after = 0.1, wait_connected = false}) ---- -... -while c.state ~= 'error_reconnect' do fiber.sleep(0.01) end ---- -... -c:close() ---- -... -box.schema.user.revoke('guest', 'execute', 'universe') ---- -... -c.state ---- -- closed -... -c = nil ---- -... --- --- gh-3256 net.box is_nullable and collation options output --- -space = box.schema.create_space('test') ---- -... -box.schema.user.grant('guest', 'read', 'space', 'test') ---- -... -_ = space:create_index('pk') ---- -... -_ = space:create_index('sk', {parts = {{2, 'unsigned', is_nullable = true}}}) ---- -... -c = net:connect(box.cfg.listen) ---- -... -c.space.test.index.sk.parts ---- -- - type: unsigned - is_nullable: true - fieldno: 2 -... -space:drop() ---- -... -space = box.schema.create_space('test') ---- -... -c:close() ---- -... -box.schema.user.grant('guest', 'read', 'space', 'test') ---- -... -c = net:connect(box.cfg.listen) ---- -... -box.internal.collation.create('test', 'ICU', 'ru-RU') ---- -... -collation_id = box.internal.collation.id_by_name('test') ---- -... -_ = space:create_index('sk', { type = 'tree', parts = {{1, 'str', collation = 'test'}}, unique = true }) ---- -... -c:reload_schema() ---- -... -parts = c.space.test.index.sk.parts ---- -... -#parts == 1 ---- -- true -... -parts[1].fieldno == 1 ---- -- true -... -parts[1].type == 'string' ---- -- true -... -parts[1].is_nullable == false ---- -- true -... -if _TARANTOOL >= '2.2.1' then \ - return parts[1].collation == 'test' \ -else \ - return parts[1].collation_id == collation_id \ -end ---- -- true -... -c:close() ---- -... -box.internal.collation.drop('test') ---- -... -space:drop() ---- -... -c.state ---- -- closed -... -c = nil ---- -... --- --- gh-3107: fiber-async netbox. --- -cond = nil ---- -... -box.schema.func.create('long_function') ---- -... -box.schema.user.grant('guest', 'execute', 'function', 'long_function') ---- -... -function long_function(...) cond = fiber.cond() cond:wait() return ... end ---- -... -function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end ---- -... -s = box.schema.create_space('test') ---- -... -pk = s:create_index('pk') ---- -... -s:replace{1} ---- -- [1] -... -s:replace{2} ---- -- [2] -... -s:replace{3} ---- -- [3] -... -s:replace{4} ---- -- [4] -... -c = net:connect(box.cfg.listen) ---- -... --- --- Check long connections, multiple wait_result(). --- -future = c:call('long_function', {1, 2, 3}, {is_async = true}) ---- -... -future:result() ---- -- null -- Response is not ready -... -future:is_ready() ---- -- false -... -future:wait_result(0.01) -- Must fail on timeout. ---- -- null -- Timeout exceeded -... -finalize_long() ---- -... -ret = future:wait_result(100) ---- -... -future:is_ready() ---- -- true -... --- Any timeout is ok - response is received already. -future:wait_result(0) ---- -- [1, 2, 3] -... -future:wait_result(0.01) ---- -- [1, 2, 3] -... -ret ---- -- [1, 2, 3] -... -_, err = pcall(future.wait_result, future, true) ---- -... -err:find('Usage') ~= nil ---- -- true -... -_, err = pcall(future.wait_result, future, '100') ---- -... -err:find('Usage') ~= nil ---- -- true -... --- --- Check infinity timeout. --- -ret = nil ---- -... -_ = fiber.create(function() ret = c:call('long_function', {1, 2, 3}, {is_async = true}):wait_result() end) ---- -... -finalize_long() ---- -... -while not ret do fiber.sleep(0.01) end ---- -... -ret ---- -- [1, 2, 3] -... -c:close() ---- -... -box.schema.user.grant('guest', 'execute', 'universe') ---- -... -c = net:connect(box.cfg.listen) ---- -... -future = c:eval('return long_function(...)', {1, 2, 3}, {is_async = true}) ---- -... -future:result() ---- -- null -- Response is not ready -... -future:wait_result(0.01) -- Must fail on timeout. ---- -- null -- Timeout exceeded -... -finalize_long() ---- -... -future:wait_result(100) ---- -- [1, 2, 3] -... -c:close() ---- -... --- --- Check that is_async does not work on a closed connection. --- -c:call('any_func', {}, {is_async = true}) ---- -- error: Connection closed -... -box.schema.user.revoke('guest', 'execute', 'universe') ---- -... -c = net:connect(box.cfg.listen) ---- -... --- --- Ensure the request is garbage collected both if is not used and --- if is. --- -gc_test = setmetatable({}, {__mode = 'v'}) ---- -... -gc_test.future = c:call('long_function', {1, 2, 3}, {is_async = true}) ---- -... -gc_test.future ~= nil ---- -- true -... -collectgarbage() ---- -- 0 -... -gc_test ---- -- [] -... -finalize_long() ---- -... -future = c:call('long_function', {1, 2, 3}, {is_async = true}) ---- -... -collectgarbage() ---- -- 0 -... -future ~= nil ---- -- true -... -finalize_long() ---- -... -future:wait_result(1000) ---- -- [1, 2, 3] -... -collectgarbage() ---- -- 0 -... -future ~= nil ---- -- true -... -gc_test.future = future ---- -... -future = nil ---- -... -collectgarbage() ---- -- 0 -... -gc_test ---- -- [] -... --- --- Ensure a request can be finalized from non-caller fibers. --- -future = c:call('long_function', {1, 2, 3}, {is_async = true}) ---- -... -ret = {} ---- -... -count = 0 ---- -... -for i = 1, 10 do fiber.create(function() ret[i] = future:wait_result(1000) count = count + 1 end) end ---- -... -future:wait_result(0.01) -- Must fail on timeout. ---- -- null -- Timeout exceeded -... -finalize_long() ---- -... -while count ~= 10 do fiber.sleep(0.1) end ---- -... -ret ---- -- - &0 [1, 2, 3] - - *0 - - *0 - - *0 - - *0 - - *0 - - *0 - - *0 - - *0 - - *0 -... --- --- Test space methods. --- -c:close() ---- -... -box.schema.user.grant('guest', 'read,write', 'space', 'test') ---- -... -c = net:connect(box.cfg.listen) ---- -... -future = c.space.test:select({1}, {is_async = true}) ---- -... -ret = future:wait_result(100) ---- -... -ret ---- -- - [1] -... -type(ret[1]) ---- -- cdata -... -future = c.space.test:insert({5}, {is_async = true}) ---- -... -future:wait_result(100) ---- -- [5] -... -s:get{5} ---- -- [5] -... -future = c.space.test:replace({6}, {is_async = true}) ---- -... -future:wait_result(100) ---- -- [6] -... -s:get{6} ---- -- [6] -... -future = c.space.test:delete({6}, {is_async = true}) ---- -... -future:wait_result(100) ---- -- [6] -... -s:get{6} ---- -... -future = c.space.test:update({5}, {{'=', 2, 5}}, {is_async = true}) ---- -... -future:wait_result(100) ---- -- [5, 5] -... -s:get{5} ---- -- [5, 5] -... -future = c.space.test:upsert({5}, {{'=', 2, 6}}, {is_async = true}) ---- -... -future:wait_result(100) ---- -- null -... -s:get{5} ---- -- [5, 6] -... -future = c.space.test:get({5}, {is_async = true}) ---- -... -future:wait_result(100) ---- -- [5, 6] -... --- --- Test index methods. --- -future = c.space.test.index.pk:select({1}, {is_async = true}) ---- -... -future:wait_result(100) ---- -- - [1] -... -future = c.space.test.index.pk:get({2}, {is_async = true}) ---- -... -future:wait_result(100) ---- -- [2] -... -future = c.space.test.index.pk:min({}, {is_async = true}) ---- -... -future:wait_result(100) ---- -- [1] -... -future = c.space.test.index.pk:max({}, {is_async = true}) ---- -... -future:wait_result(100) ---- -- [5, 6] -... -c:close() ---- -... -box.schema.user.grant('guest', 'execute', 'universe') ---- -... -c = net:connect(box.cfg.listen) ---- -... -future = c.space.test.index.pk:count({3}, {is_async = true}) ---- -... -future:wait_result(100) ---- -- 1 -... -c:close() ---- -... -box.schema.user.revoke('guest', 'execute', 'universe') ---- -... -c = net:connect(box.cfg.listen) ---- -... -future = c.space.test.index.pk:delete({3}, {is_async = true}) ---- -... -future:wait_result(100) ---- -- [3] -... -s:get{3} ---- -... -future = c.space.test.index.pk:update({4}, {{'=', 2, 6}}, {is_async = true}) ---- -... -future:wait_result(100) ---- -- [4, 6] -... -s:get{4} ---- -- [4, 6] -... --- --- Test async errors. --- -future = c.space.test:insert({1}, {is_async = true}) ---- -... -future:wait_result() ---- -- null -- Duplicate key exists in unique index 'pk' in space 'test' -... -future:result() ---- -- null -- Duplicate key exists in unique index 'pk' in space 'test' -... --- --- Test discard. --- -future = c:call('long_function', {1, 2, 3}, {is_async = true}) ---- -... -future:discard() ---- -... -finalize_long() ---- -... -future:result() ---- -- null -- Response is discarded -... -future:wait_result(100) ---- -- null -- Response is discarded -... --- --- Test closed connection. --- -future = c:call('long_function', {1, 2, 3}, {is_async = true}) ---- -... -finalize_long() ---- -... -future:wait_result(100) ---- -- [1, 2, 3] -... -future2 = c:call('long_function', {1, 2, 3}, {is_async = true}) ---- -... -c:close() ---- -... -future2:wait_result(100) ---- -- null -- Connection closed -... -future2:result() ---- -- null -- Connection closed -... -future2:discard() ---- -... --- Already successful result must be available. -future:wait_result(100) ---- -- [1, 2, 3] -... -future:result() ---- -- [1, 2, 3] -... -future:is_ready() ---- -- true -... -finalize_long() ---- -... --- --- Test reconnect. --- -c = net:connect(box.cfg.listen, {reconnect_after = 0.01}) ---- -... -future = c:call('long_function', {1, 2, 3}, {is_async = true}) ---- -... -_ = c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') ---- -... -while not c:is_connected() do fiber.sleep(0.01) end ---- -... -finalize_long() ---- -... -future:wait_result(100) ---- -- null -- Peer closed -... -future:result() ---- -- null -- Peer closed -... -future = c:call('long_function', {1, 2, 3}, {is_async = true}) ---- -... -finalize_long() ---- -... -future:wait_result(100) ---- -- [1, 2, 3] -... --- --- Test raw response getting. --- -ibuf = require('buffer').ibuf() ---- -... -future = c:call('long_function', {1, 2, 3}, {is_async = true, buffer = ibuf}) ---- -... -finalize_long() ---- -... -future:wait_result(100) ---- -- 10 -... -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) ---- -... -result ---- -- {48: [1, 2, 3]} -... -box.schema.func.drop('long_function') ---- -... --- --- Test async schema version change. --- -function change_schema(i) local tmp = box.schema.create_space('test'..i) return 'ok' end ---- -... -box.schema.func.create('change_schema') ---- -... -box.schema.user.grant('guest', 'execute', 'function', 'change_schema') ---- -... -box.schema.user.grant('guest', 'write', 'space', '_schema') ---- -... -box.schema.user.grant('guest', 'read,write', 'space', '_space') ---- -... -box.schema.user.grant('guest', 'create', 'space') ---- -... -future1 = c:call('change_schema', {'1'}, {is_async = true}) ---- -... -future2 = c:call('change_schema', {'2'}, {is_async = true}) ---- -... -future3 = c:call('change_schema', {'3'}, {is_async = true}) ---- -... -future1:wait_result() ---- -- ['ok'] -... -future2:wait_result() ---- -- ['ok'] -... -future3:wait_result() ---- -- ['ok'] -... -c:close() ---- -... -s:drop() ---- -... -box.space.test1:drop() ---- -... -box.space.test2:drop() ---- -... -box.space.test3:drop() ---- -... -box.schema.func.drop('change_schema') ---- -... --- --- gh-2978: field names for tuples received from netbox. --- -_ = box.schema.create_space("named", {format = {{name = "id"}, {name="abc"}}}) ---- -... -_ = box.space.named:create_index('id', {parts = {{1, 'unsigned'}}}) ---- -... -box.space.named:insert({1, 1}) ---- -- [1, 1] -... -box.schema.user.grant('guest', 'read, write, execute', 'space') ---- -... -cn = net.connect(box.cfg.listen) ---- -... -s = cn.space.named ---- -... -s:get{1}.id ---- -- 1 -... -s:get{1}:tomap() ---- -- 1: 1 - 2: 1 - abc: 1 - id: 1 -... -s:insert{2,3}:tomap() ---- -- 1: 2 - 2: 3 - abc: 3 - id: 2 -... -s:replace{2,14}:tomap() ---- -- 1: 2 - 2: 14 - abc: 14 - id: 2 -... -s:update(1, {{'+', 2, 10}}):tomap() ---- -- 1: 1 - 2: 11 - abc: 11 - id: 1 -... -s:select()[1]:tomap() ---- -- 1: 1 - 2: 11 - abc: 11 - id: 1 -... -s:delete({2}):tomap() ---- -- 1: 2 - 2: 14 - abc: 14 - id: 2 -... --- Check that formats changes after reload. -box.space.named:format({{name = "id2"}, {name="abc2"}}) ---- -... -s:select()[1]:tomap() ---- -- 1: 1 - 2: 11 - abc: 11 - id: 1 -... -cn:reload_schema() ---- -... -s:select()[1]:tomap() ---- -- 1: 1 - 2: 11 - id2: 1 - abc2: 11 -... -cn:close() ---- -... -box.space.named:drop() ---- -... -box.schema.user.revoke('guest', 'read, write, execute', 'space') ---- -... --- --- gh-3400: long-poll input discard must not touch event loop of --- a closed connection. --- -function long() fiber.yield() return 100 end ---- -... -c = net.connect(box.cfg.listen) ---- -... -c:ping() ---- -- true -... --- Create batch of two requests. First request is sent to TX --- thread, second one terminates connection. The preceeding --- request discards input, and this operation must not trigger --- new attempts to read any data - the connection is closed --- already. --- -f = fiber.create(c._transport.perform_request, nil, nil, false, 'call_17', nil, nil, nil, 'long', {}) c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') ---- -... -while f:status() ~= 'dead' do fiber.sleep(0.01) end ---- -... -c:close() ---- -... --- --- gh-3464: iproto hangs in 100% CPU when too big packet size --- is received due to size_t overflow. --- -c = net:connect(box.cfg.listen) ---- -... -data = msgpack.encode(18400000000000000000)..'aaaaaaa' ---- -... -c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, data) ---- -- null -- Peer closed -... -c:close() ---- -... -test_run:grep_log('default', 'too big packet size in the header') ~= nil ---- -- true -... --- --- gh-3629: netbox leaks when a connection is closed deliberately --- and it has non-finished requests. --- -ready = false ---- -... -ok = nil ---- -... -err = nil ---- -... -c = net:connect(box.cfg.listen) ---- -... -function do_long() while not ready do fiber.sleep(0.01) end end ---- -... -box.schema.func.create('do_long') ---- -... -box.schema.user.grant('guest', 'execute', 'function', 'do_long') ---- -... -f = fiber.create(function() ok, err = pcall(c.call, c, 'do_long') end) ---- -... -while f:status() ~= 'suspended' do fiber.sleep(0.01) end ---- -... -c:close() ---- -... -ready = true ---- -... -while not err do fiber.sleep(0.01) end ---- -... -ok, err ---- -- false -- Connection closed -... --- --- gh-3856: wait_connected = false is ignored. --- -c = net.connect('8.8.8.8:123456', {wait_connected = false}) ---- -... -c ---- -- opts: - wait_connected: false - host: 8.8.8.8 - state: initial - port: '123456' -... -c:close() ---- -... -box.schema.func.drop('do_long') ---- -... -box.schema.user.revoke('guest', 'write', 'space', '_schema') ---- -... -box.schema.user.revoke('guest', 'read,write', 'space', '_space') ---- -... -box.schema.user.revoke('guest', 'create', 'space') ---- -... --- --- gh-3958 updating box.cfg.readahead doesn't affect existing connections. --- -readahead = box.cfg.readahead ---- -... -box.cfg{readahead = 128} ---- -... -s = box.schema.space.create("test") ---- -... -_ = s:create_index("pk") ---- -... -box.schema.user.grant("guest", "read,write", "space", "test") ---- -... --- connection is created with small readahead value, --- make sure it is updated if box.cfg.readahead is changed. -c = net.connect(box.cfg.listen) ---- -... -box.cfg{readahead = 100 * 1024} ---- -... -box.error.injection.set("ERRINJ_WAL_DELAY", true) ---- -- ok -... -pad = string.rep('x', 8192) ---- -... -for i = 1, 5 do c.space.test:replace({i, pad}, {is_async = true}) end ---- -... -box.error.injection.set("ERRINJ_WAL_DELAY", false) ---- -- ok -... -test_run:wait_log('default', 'readahead limit is reached', 1024, 0.1) ---- -... -s:drop() ---- -... -box.cfg{readahead = readahead} ---- -... --- --- related to gh-4040: log corrupted rows --- -log_level = box.cfg.log_level ---- -... -box.cfg{log_level=6} ---- -... -sock = socket.tcp_connect(LISTEN.host, LISTEN.service) ---- -... -sock:read(9) ---- -- Tarantool -... --- we need to have a packet with correctly encoded length, --- so that it bypasses iproto length check, but cannot be --- decoded in xrow_header_decode --- 0x3C = 60, sha1 digest is 20 bytes long -data = string.fromhex('3C'..string.rep(require('digest').sha1_hex('bcde'), 3)) ---- -... -sock:write(data) ---- -- 61 -... -sock:close() ---- -- true -... -test_run:wait_log('default', 'Got a corrupted row.*', nil, 10) ---- -- 'Got a corrupted row:' -... -test_run:wait_log('default', '00000000:.*', nil, 10) ---- -- '00000000: A3 02 D6 5A E4 D9 E7 68 A1 53 8D 53 60 5F 20 3F ' -... -test_run:wait_log('default', '00000010:.*', nil, 10) ---- -- '00000010: D8 E2 D6 E2 A3 02 D6 5A E4 D9 E7 68 A1 53 8D 53 ' -... -test_run:wait_log('default', '00000020:.*', nil, 10) ---- -- '00000020: 60 5F 20 3F D8 E2 D6 E2 A3 02 D6 5A E4 D9 E7 68 ' -... -test_run:wait_log('default', '00000030:.*', nil, 10) ---- -- '00000030: A1 53 8D 53 60 5F 20 3F D8 E2 D6 E2 ' -... --- we expect nothing below, so don't wait -test_run:grep_log('default', '00000040:.*') ---- -- null -... -box.cfg{log_level=log_level} ---- -... diff --git a/test/box/net.box.test.lua b/test/box/net.box.test.lua deleted file mode 100644 index 8e65ff470..000000000 --- a/test/box/net.box.test.lua +++ /dev/null @@ -1,1585 +0,0 @@ -remote = require 'net.box' -fiber = require 'fiber' -log = require 'log' -msgpack = require 'msgpack' -env = require('test_run') -test_run = env.new() -test_run:cmd("push filter ".."'\\.lua.*:[0-9]+: ' to '.lua...\"]:<line>: '") - -test_run:cmd("setopt delimiter ';'") -function x_select(cn, space_id, index_id, iterator, offset, limit, key, opts) - local ret = cn:_request('select', opts, nil, space_id, index_id, iterator, - offset, limit, key) - return ret -end -function x_fatal(cn) cn._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') end -test_run:cmd("setopt delimiter ''"); - -LISTEN = require('uri').parse(box.cfg.listen) -space = box.schema.space.create('net_box_test_space') -index = space:create_index('primary', { type = 'tree' }) - --- low level connection -log.info("create connection") -cn = remote.connect(LISTEN.host, LISTEN.service) -log.info("state is %s", cn.state) - -cn:ping() -log.info("ping is done") -cn:ping() -log.info("ping is done") - - -cn:ping() - - --- check permissions -cn:call('unexists_procedure') -function test_foo(a,b,c) return { {{ [a] = 1 }}, {{ [b] = 2 }}, c } end -cn:call('test_foo', {'a', 'b', 'c'}) -cn:eval('return 2+2') -cn:close() --- connect and call without usage access -box.schema.user.grant('guest','execute','universe') -box.schema.user.revoke('guest','usage','universe') -box.session.su("guest") -cn = remote.connect(LISTEN.host, LISTEN.service) -cn:call('test_foo', {'a', 'b', 'c'}) -box.session.su("admin") -box.schema.user.grant('guest','usage','universe') -cn:close() -cn = remote.connect(box.cfg.listen) - -cn:call('unexists_procedure') -cn:call('test_foo', {'a', 'b', 'c'}) -cn:call(nil, {'a', 'b', 'c'}) -cn:eval('return 2+2') -cn:eval('return 1, 2, 3') -cn:eval('return ...', {1, 2, 3}) -cn:eval('return { k = "v1" }, true, { xx = 10, yy = 15 }, nil') -cn:eval('return nil') -cn:eval('return') -cn:eval('error("exception")') -cn:eval('box.error(0)') -cn:eval('!invalid expression') - --- box.commit() missing at return of CALL/EVAL -function no_commit() box.begin() fiber.sleep(0.001) end -cn:call('no_commit') -cn:eval('no_commit()') - -remote.self:eval('return 1+1, 2+2') -remote.self:eval('return') -remote.self:eval('error("exception")') -remote.self:eval('box.error(0)') -remote.self:eval('!invalid expression') - -box.schema.user.revoke('guest', 'execute', 'universe') - --- --- gh-822: net.box.call should roll back local transaction on error --- - -_ = box.schema.space.create('gh822') -_ = box.space.gh822:create_index('primary') - -test_run:cmd("setopt delimiter ';'") - --- rollback on invalid function -function rollback_on_invalid_function() - box.begin() - box.space.gh822:insert{1, "netbox_test"} - pcall(remote.self.call, remote.self, 'invalid_function') - return box.space.gh822:get(1) == nil -end; -rollback_on_invalid_function(); - --- rollback on call error -function test_error() error('Some error') end; -function rollback_on_call_error() - box.begin() - box.space.gh822:insert{1, "netbox_test"} - pcall(remote.self.call, remote.self, 'test_error') - return box.space.gh822:get(1) == nil -end; -rollback_on_call_error(); - --- rollback on eval -function rollback_on_eval_error() - box.begin() - box.space.gh822:insert{1, "netbox_test"} - pcall(remote.self.eval, remote.self, "error('Some error')") - return box.space.gh822:get(1) == nil -end; -rollback_on_eval_error(); - -test_run:cmd("setopt delimiter ''"); -box.space.gh822:drop() - -box.schema.user.grant('guest', 'read,write', 'space', 'net_box_test_space') -box.schema.user.grant('guest', 'execute', 'universe') - -cn:close() -cn = remote.connect(box.cfg.listen) - -x_select(cn, space.id, space.index.primary.id, box.index.EQ, 0, 0xFFFFFFFF, 123) -space:insert{123, 345} -x_select(cn, space.id, space.index.primary.id, box.index.EQ, 0, 0, 123) -x_select(cn, space.id, space.index.primary.id, box.index.EQ, 0, 1, 123) -x_select(cn, space.id, space.index.primary.id, box.index.EQ, 1, 1, 123) - -cn.space[space.id] ~= nil -cn.space.net_box_test_space ~= nil -cn.space.net_box_test_space ~= nil -cn.space.net_box_test_space.index ~= nil -cn.space.net_box_test_space.index.primary ~= nil -cn.space.net_box_test_space.index[space.index.primary.id] ~= nil - - -cn.space.net_box_test_space.index.primary:select(123) -cn.space.net_box_test_space.index.primary:select(123, { limit = 0 }) -cn.space.net_box_test_space.index.primary:select(nil, { limit = 1, }) -cn.space.net_box_test_space:insert{234, 1,2,3} -cn.space.net_box_test_space:insert{234, 1,2,3} -cn.space.net_box_test_space.insert{234, 1,2,3} - -cn.space.net_box_test_space:replace{354, 1,2,3} -cn.space.net_box_test_space:replace{354, 1,2,4} - -cn.space.net_box_test_space:select{123} -space:select({123}, { iterator = 'GE' }) -cn.space.net_box_test_space:select({123}, { iterator = 'GE' }) -cn.space.net_box_test_space:select({123}, { iterator = 'GT' }) -cn.space.net_box_test_space:select({123}, { iterator = 'GT', limit = 1 }) -cn.space.net_box_test_space:select({123}, { iterator = 'GT', limit = 1, offset = 1 }) - -cn.space.net_box_test_space:select{123} -cn.space.net_box_test_space:update({123}, { { '+', 2, 1 } }) -cn.space.net_box_test_space:update(123, { { '+', 2, 1 } }) -cn.space.net_box_test_space:select{123} - -cn.space.net_box_test_space:insert(cn.space.net_box_test_space:get{123}:update{ { '=', 1, 2 } }) -cn.space.net_box_test_space:delete{123} -cn.space.net_box_test_space:select{2} -cn.space.net_box_test_space:select({234}, { iterator = 'LT' }) - -cn.space.net_box_test_space:update({1}, { { '+', 2, 2 } }) - -cn.space.net_box_test_space:delete{1} -cn.space.net_box_test_space:delete{2} -cn.space.net_box_test_space:delete{2} - --- test one-based indexing in splice operation (see update.test.lua) -cn.space.net_box_test_space:replace({10, 'abcde'}) -cn.space.net_box_test_space:update(10, {{':', 2, 0, 0, '!'}}) -cn.space.net_box_test_space:update(10, {{':', 2, 1, 0, '('}}) -cn.space.net_box_test_space:update(10, {{':', 2, 2, 0, '({'}}) -cn.space.net_box_test_space:update(10, {{':', 2, -1, 0, ')'}}) -cn.space.net_box_test_space:update(10, {{':', 2, -2, 0, '})'}}) -cn.space.net_box_test_space:delete{10} - -cn.space.net_box_test_space:select({}, { iterator = 'ALL' }) --- gh-841: net.box uses incorrect iterator type for select with no arguments -cn.space.net_box_test_space:select() - -cn.space.net_box_test_space.index.primary:min() -cn.space.net_box_test_space.index.primary:min(354) -cn.space.net_box_test_space.index.primary:max() -cn.space.net_box_test_space.index.primary:max(234) -cn.space.net_box_test_space.index.primary:count() -cn.space.net_box_test_space.index.primary:count(354) - -cn.space.net_box_test_space:get(354) - --- reconnects after errors - -box.schema.user.revoke('guest', 'execute', 'universe') -box.schema.func.create('test_foo') -box.schema.user.grant('guest', 'execute', 'function', 'test_foo') - --- -- 1. no reconnect -x_fatal(cn) -cn.state -cn:ping() -cn:call('test_foo') -cn:wait_state('active') - --- -- 2 reconnect -cn = remote.connect(LISTEN.host, LISTEN.service, { reconnect_after = .1 }) -cn.space ~= nil - -cn.space.net_box_test_space:select({}, { iterator = 'ALL' }) -x_fatal(cn) -cn:wait_connected() -cn:wait_state('active') -cn:wait_state({active=true}) -cn:ping() -cn.state -cn.space.net_box_test_space:select({}, { iterator = 'ALL' }) - -x_fatal(cn) -x_select(cn, space.id, 0, box.index.ALL, 0, 0xFFFFFFFF, {}) - -cn.state -cn:ping() - --- -- dot-new-method - -cn1 = remote.new(LISTEN.host, LISTEN.service) -x_select(cn1, space.id, 0, box.index.ALL, 0, 0xFFFFFFF, {}) -cn1:close() --- -- error while waiting for response -type(fiber.create(function() fiber.sleep(.5) x_fatal(cn) end)) -function pause() fiber.sleep(10) return true end - -box.schema.func.create('pause') -box.schema.user.grant('guest', 'execute', 'function', 'pause') -cn:call('pause') -cn:call('test_foo', {'a', 'b', 'c'}) -box.schema.func.drop('pause') - --- call -remote.self:call('test_foo', {'a', 'b', 'c'}) -cn:call('test_foo', {'a', 'b', 'c'}) -box.schema.func.drop('test_foo') - -box.schema.func.create('long_rep') -box.schema.user.grant('guest', 'execute', 'function', 'long_rep') - --- long replies -function long_rep() return { 1, string.rep('a', 5000) } end -res = cn:call('long_rep') -res[1] == 1 -res[2] == string.rep('a', 5000) - -function long_rep() return { 1, string.rep('a', 50000) } end -res = cn:call('long_rep') -res[1] == 1 -res[2] == string.rep('a', 50000) - -box.schema.func.drop('long_rep') - --- a.b.c.d -u = '84F7BCFA-079C-46CC-98B4-F0C821BE833E' -X = {} -X.X = X -function X.fn(x,y) return y or x end -box.schema.user.grant('guest', 'execute', 'universe') -cn:close() -cn = remote.connect(LISTEN.host, LISTEN.service) -cn:call('X.fn', {u}) -cn:call('X.X.X.X.X.X.X.fn', {u}) -cn:call('X.X.X.X:fn', {u}) -box.schema.user.revoke('guest', 'execute', 'universe') -cn:close() - --- auth - -cn = remote.connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123', wait_connected = true }) -cn:is_connected() -cn.error -cn.state - - -box.schema.user.create('netbox', { password = 'test' }) -box.schema.user.grant('netbox', 'read,write', 'space', 'net_box_test_space') -box.schema.user.grant('netbox', 'execute', 'universe') -cn = remote.connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = 'test' }) -cn.state -cn.error -cn:ping() - -function ret_after(to) fiber.sleep(to) return {{to}} end - -cn:ping({timeout = 1.00}) -cn:ping({timeout = 1e-9}) -cn:ping() - -remote_space = cn.space.net_box_test_space -remote_pk = remote_space.index.primary - -remote_space:insert({0}, { timeout = 1.00 }) -remote_space:insert({1}, { timeout = 1e-9 }) -remote_space:insert({2}) - -remote_space:replace({0}, { timeout = 1e-9 }) -remote_space:replace({1}) -remote_space:replace({2}, { timeout = 1.00 }) - -remote_space:upsert({3}, {}, { timeout = 1e-9 }) -remote_space:upsert({4}, {}) -remote_space:upsert({5}, {}, { timeout = 1.00 }) -remote_space:upsert({3}, {}) - -remote_space:update({3}, {}, { timeout = 1e-9 }) -remote_space:update({4}, {}) -remote_space:update({5}, {}, { timeout = 1.00 }) -remote_space:update({3}, {}) - -remote_pk:update({5}, {}, { timeout = 1e-9 }) -remote_pk:update({4}, {}) -remote_pk:update({3}, {}, { timeout = 1.00 }) -remote_pk:update({5}, {}) - -remote_space:get({0}) -remote_space:get({1}, { timeout = 1.00 }) -remote_space:get({2}, { timeout = 1e-9 }) - -remote_pk:get({3}, { timeout = 1e-9 }) -remote_pk:get({4}) -remote_pk:get({5}, { timeout = 1.00 }) - -remote_space:select({2}, { timeout = 1e-9 }) -remote_space:select({2}, { timeout = 1.00 }) -remote_space:select({2}) - -remote_pk:select({2}, { timeout = 1.00 }) -remote_pk:select({2}, { timeout = 1e-9 }) -remote_pk:select({2}) - -remote_space:select({5}, { timeout = 1.00, iterator = 'LE', limit = 5 }) -remote_space:select({5}, { iterator = 'LE', limit = 5}) -remote_space:select({5}, { timeout = 1e-9, iterator = 'LE', limit = 5 }) - -remote_pk:select({2}, { timeout = 1.00, iterator = 'LE', limit = 5 }) -remote_pk:select({2}, { iterator = 'LE', limit = 5}) -remote_pk:select({2}, { timeout = 1e-9, iterator = 'LE', limit = 5 }) - -remote_pk:count({2}, { timeout = 1.00}) -remote_pk:count({2}, { timeout = 1e-9}) -remote_pk:count({2}) - -remote_pk:count({2}, { timeout = 1.00, iterator = 'LE' }) -remote_pk:count({2}, { iterator = 'LE'}) -remote_pk:count({2}, { timeout = 1e-9, iterator = 'LE' }) - -remote_pk:min(nil, { timeout = 1.00 }) -remote_pk:min(nil, { timeout = 1e-9 }) -remote_pk:min(nil) - -remote_pk:min({0}, { timeout = 1e-9 }) -remote_pk:min({1}) -remote_pk:min({2}, { timeout = 1.00 }) - -remote_pk:max(nil) -remote_pk:max(nil, { timeout = 1e-9 }) -remote_pk:max(nil, { timeout = 1.00 }) - -remote_pk:max({0}, { timeout = 1.00 }) -remote_pk:max({1}, { timeout = 1e-9 }) -remote_pk:max({2}) - --- --- gh-3262: index:count() inconsistent results --- -test_run:cmd("setopt delimiter ';'") - -function do_count_test(min, it) - local r1 = remote_pk:count(min, {iterator = it} ) - local r2 = box.space.net_box_test_space.index.primary:count(min, {iterator = it} ) - local r3 = remote.self.space.net_box_test_space.index.primary:count(min, {iterator = it} ) - return r1 == r2 and r2 == r3 -end; - -data = remote_pk:select(); - -for _, v in pairs(data) do - local itrs = {'GE', 'GT', 'LE', 'LT' } - for _, it in pairs(itrs) do - assert(do_count_test(v[0], it) == true) - end -end; - -test_run:cmd("setopt delimiter ''"); - -_ = remote_space:delete({0}, { timeout = 1e-9 }) -_ = remote_pk:delete({0}, { timeout = 1.00 }) -_ = remote_space:delete({1}, { timeout = 1.00 }) -_ = remote_pk:delete({1}, { timeout = 1e-9 }) -_ = remote_space:delete({2}, { timeout = 1e-9 }) -_ = remote_pk:delete({2}) -_ = remote_pk:delete({3}) -_ = remote_pk:delete({4}) -_ = remote_pk:delete({5}) - -remote_space:get(0) -remote_space:get(1) -remote_space:get(2) - -remote_space = nil - -cn:call('ret_after', {0.01}, { timeout = 1.00 }) -cn:call('ret_after', {1.00}, { timeout = 1e-9 }) - -cn:eval('return ret_after(...)', {0.01}, { timeout = 1.00 }) -cn:eval('return ret_after(...)', {1.00}, { timeout = 1e-9 }) - --- --- :timeout() --- @deprecated since 1.7.4 --- - -cn:timeout(1).space.net_box_test_space.index.primary:select{234} -cn:call('ret_after', {.01}) -cn:timeout(1):call('ret_after', {.01}) -cn:timeout(.01):call('ret_after', {1}) - -cn = remote:timeout(0.0000000001):connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123' }) -cn:close() -cn = remote:timeout(1):connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123' }) - -remote.self:ping() -remote.self.space.net_box_test_space:select{234} -remote.self:timeout(123).space.net_box_test_space:select{234} -remote.self:is_connected() -remote.self:wait_connected() - -cn:close() --- cleanup database after tests -space:drop() - --- #1545 empty password -cn = remote.connect(LISTEN.host, LISTEN.service, { user = 'test' }) -cn ~= nil -cn:close() -cn = remote.connect(LISTEN.host, LISTEN.service, { password = 'test' }) -cn ~= nil -cn:close() - --- #544 usage for remote[point]method -cn = remote.connect(LISTEN.host, LISTEN.service) - -box.schema.user.grant('guest', 'execute', 'universe') -cn:close() -cn = remote.connect(LISTEN.host, LISTEN.service) -cn:eval('return true') -cn.eval('return true') - -cn.ping() - -cn:close() - -remote.self:eval('return true') -remote.self.eval('return true') -box.schema.user.revoke('guest', 'execute', 'universe') - --- uri as the first argument -uri = string.format('%s:%s@%s:%s', 'netbox', 'test', LISTEN.host, LISTEN.service) - -cn = remote.new(uri) -cn:ping() -cn:close() - -uri = string.format('%s@%s:%s', 'netbox', LISTEN.host, LISTEN.service) -cn = remote.new(uri) -cn ~= nil, cn.state, cn.error -cn:close() --- don't merge creds from uri & opts -remote.new(uri, { password = 'test' }) -cn = remote.new(uri, { user = 'netbox', password = 'test' }) -cn:ping() -cn:close() - -box.schema.user.drop('netbox') - --- #594: bad argument #1 to 'setmetatable' (table expected, got number) -box.schema.func.create('dostring') -box.schema.user.grant('guest', 'execute', 'function', 'dostring') -test_run:cmd("setopt delimiter ';'") -function gh594() - local cn = remote.connect(box.cfg.listen) - local ping = fiber.create(function() cn:ping() end) - cn:call('dostring', {'return 2 + 2'}) - cn:close() -end; -test_run:cmd("setopt delimiter ''"); -gh594() -box.schema.func.drop('dostring') - - --- #636: Reload schema on demand -sp = box.schema.space.create('test_old') -_ = sp:create_index('primary') -sp:insert{1, 2, 3} - -box.schema.user.grant('guest', 'read', 'space', 'test_old') -con = remote.new(box.cfg.listen) -con:ping() -con.space.test_old:select{} -con.space.test == nil - -sp = box.schema.space.create('test') -_ = sp:create_index('primary') -sp:insert{2, 3, 4} - -box.schema.user.grant('guest', 'read', 'space', 'test') - -con.space.test == nil -con:reload_schema() -con.space.test:select{} - -box.space.test:drop() -box.space.test_old:drop() -con:close() - -name = string.match(arg[0], "([^,]+)%.lua") -file_log = require('fio').open(name .. '.log', {'O_RDONLY', 'O_NONBLOCK'}) -file_log:seek(0, 'SEEK_END') ~= 0 - -box.schema.user.grant('guest', 'execute', 'universe') -test_run:cmd("setopt delimiter ';'") - -_ = fiber.create( - function() - local conn = require('net.box').new(box.cfg.listen) - conn:call('no_such_function', {}) - conn:close() - end -); -test_run:cmd("setopt delimiter ''"); -test_run:wait_log('default', 'ER_NO_SUCH_PROC', nil, 10) -box.schema.user.revoke('guest', 'execute', 'universe') - --- --- gh-3900: tarantool can be crashed by sending gibberish to a --- binary socket --- -socket = require("socket") -sock = socket.tcp_connect(LISTEN.host, LISTEN.service) -data = string.fromhex("6783000000000000000000000000000000000000000000800000C8000000000000000000000000000000000000000000FFFF210100373208000000FFFF000055AAEB66486472530D02000000000010A0350001008000001000000000000000000000000000D05700") -sock:write(data) -test_run:wait_log('default', 'ER_INVALID_MSGPACK: Invalid MsgPack %- packet body', nil, 10) -sock:close() - --- gh-983 selecting a lot of data crashes the server or hangs the --- connection - --- gh-983 test case: iproto connection selecting a lot of data -_ = box.schema.space.create('test', { temporary = true }) -_ = box.space.test:create_index('primary', {type = 'TREE', parts = {1,'unsigned'}}) - -data1k = "aaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhh" - -for i = 0,10000 do box.space.test:insert{i, data1k} end - -box.schema.user.grant('guest', 'read', 'space', 'test') -net = require('net.box') -c = net:connect(box.cfg.listen) -r = c.space.test:select(nil, {limit=5000}) -box.space.test:drop() - --- gh-970 gh-971 UPSERT over network -_ = box.schema.space.create('test') -_ = box.space.test:create_index('primary', {type = 'TREE', parts = {1,'unsigned'}}) -_ = box.space.test:create_index('covering', {type = 'TREE', parts = {1,'unsigned',3,'string',2,'unsigned'}}) -_ = box.space.test:insert{1, 2, "string"} -box.schema.user.grant('guest', 'read,write', 'space', 'test') -c = net:connect(box.cfg.listen) -c.space.test:select{} -c.space.test:upsert({1, 2, 'nothing'}, {{'+', 2, 1}}) -- common update -c.space.test:select{} -c.space.test:upsert({2, 4, 'something'}, {{'+', 2, 1}}) -- insert -c.space.test:select{} -c.space.test:upsert({2, 4, 'nothing'}, {{'+', 3, 100500}}) -- wrong operation -c.space.test:select{} - --- gh-1729 net.box index metadata incompatible with local metadata -c.space.test.index.primary.parts -c.space.test.index.covering.parts - -box.space.test:drop() - --- CALL vs CALL_16 in connect options -function echo(...) return ... end -box.schema.user.grant('guest', 'execute', 'universe') -c = net.connect(box.cfg.listen) -c:call('echo', {42}) -c:eval('return echo(...)', {42}) --- invalid arguments -c:call('echo', 42) -c:eval('return echo(...)', 42) -c:close() -c = net.connect(box.cfg.listen, {call_16 = true}) -c:call('echo', 42) -c:eval('return echo(...)', 42) -c:close() -box.schema.user.revoke('guest', 'execute', 'universe') - --- --- gh-2195 export pure msgpack from net.box --- - -space = box.schema.space.create('test') -_ = box.space.test:create_index('primary') -box.schema.user.grant('guest', 'read,write', 'space', 'test') -box.schema.user.grant('guest', 'execute', 'universe') -c = net.connect(box.cfg.listen) -ibuf = require('buffer').ibuf() - -c:ping() -c.space.test ~= nil - -c.space.test:replace({1, 'hello'}) - --- replace -c.space.test:replace({2}, {buffer = ibuf}) -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) -result - --- replace + skip_header -c.space.test:replace({2}, {buffer = ibuf, skip_header = true}) -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) -result - --- insert -c.space.test:insert({3}, {buffer = ibuf}) -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) -result - --- insert + skip_header -_ = space:delete({3}) -c.space.test:insert({3}, {buffer = ibuf, skip_header = true}) -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) -result - --- update -c.space.test:update({3}, {}, {buffer = ibuf}) -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) -result -c.space.test.index.primary:update({3}, {}, {buffer = ibuf}) -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) -result - --- update + skip_header -c.space.test:update({3}, {}, {buffer = ibuf, skip_header = true}) -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) -result -c.space.test.index.primary:update({3}, {}, {buffer = ibuf, skip_header = true}) -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) -result - --- upsert -c.space.test:upsert({4}, {}, {buffer = ibuf}) -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) -result - --- upsert + skip_header -c.space.test:upsert({4}, {}, {buffer = ibuf, skip_header = true}) -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) -result - --- delete -c.space.test:upsert({4}, {}, {buffer = ibuf}) -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) -result - --- delete + skip_header -c.space.test:upsert({4}, {}, {buffer = ibuf, skip_header = true}) -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) -result - --- select -c.space.test.index.primary:select({3}, {iterator = 'LE', buffer = ibuf}) -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) -result - --- select + skip_header -c.space.test.index.primary:select({3}, {iterator = 'LE', buffer = ibuf, skip_header = true}) -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) -result - --- select -len = c.space.test:select({}, {buffer = ibuf}) -ibuf.rpos + len == ibuf.wpos -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) -ibuf.rpos == ibuf.wpos -len -result - --- select + skip_header -len = c.space.test:select({}, {buffer = ibuf, skip_header = true}) -ibuf.rpos + len == ibuf.wpos -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) -ibuf.rpos == ibuf.wpos -len -result - --- call -c:call("echo", {1, 2, 3}, {buffer = ibuf}) -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) -result -c:call("echo", {}, {buffer = ibuf}) -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) -result -c:call("echo", nil, {buffer = ibuf}) -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) -result - --- call + skip_header -c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) -result -c:call("echo", {}, {buffer = ibuf, skip_header = true}) -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) -result -c:call("echo", nil, {buffer = ibuf, skip_header = true}) -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) -result - --- eval -c:eval("echo(...)", {1, 2, 3}, {buffer = ibuf}) -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) -result -c:eval("echo(...)", {}, {buffer = ibuf}) -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) -result -c:eval("echo(...)", nil, {buffer = ibuf}) -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) -result - --- eval + skip_header -c:eval("echo(...)", {1, 2, 3}, {buffer = ibuf, skip_header = true}) -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) -result -c:eval("echo(...)", {}, {buffer = ibuf, skip_header = true}) -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) -result -c:eval("echo(...)", nil, {buffer = ibuf, skip_header = true}) -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) -result - --- make several request into a buffer with skip_header, then read --- results -c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) -c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) -c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) -result -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) -result -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) -result - --- unsupported methods -c.space.test:get({1}, { buffer = ibuf}) -c.space.test.index.primary:min({}, { buffer = ibuf}) -c.space.test.index.primary:max({}, { buffer = ibuf}) -c.space.test.index.primary:count({}, { buffer = ibuf}) -c.space.test.index.primary:get({1}, { buffer = ibuf}) - --- error handling -rpos, wpos = ibuf.rpos, ibuf.wpos -c.space.test:insert({1}, {buffer = ibuf}) -ibuf.rpos == rpos, ibuf.wpos == wpos - -ibuf = nil -c:close() -space:drop() -box.schema.user.revoke('guest', 'execute', 'universe') - --- gh-1904 net.box hangs in :close() if a fiber was cancelled --- while blocked in :_wait_state() in :_request() -options = {user = 'netbox', password = 'badpass', wait_connected = false, reconnect_after = 0.01} -c = net:new(box.cfg.listen, options) -f = fiber.create(function() c:call("") end) -fiber.sleep(0.01) -f:cancel(); c:close() - -box.schema.user.grant('guest', 'read', 'space', '_schema') - --- check for on_schema_reload callback -test_run:cmd("setopt delimiter ';'") -do - local a = 0 - function osr_cb() - a = a + 1 - end - local con = net.new(box.cfg.listen, { - wait_connected = false - }) - con:on_schema_reload(osr_cb) - con:wait_connected() - con.space._schema:select{} - box.schema.space.create('misisipi') - box.space.misisipi:drop() - con.space._schema:select{} - con:close() - con = nil - - return a -end; -do - local a = 0 - function osr_cb() - a = a + 1 - end - local con = net.new(box.cfg.listen, { - wait_connected = true - }) - con:on_schema_reload(osr_cb) - con.space._schema:select{} - box.schema.space.create('misisipi') - box.space.misisipi:drop() - con.space._schema:select{} - con:close() - con = nil - - return a -end; -test_run:cmd("setopt delimiter ''"); - -box.schema.user.revoke('guest', 'read', 'space', '_schema') - --- Tarantool < 1.7.1 compatibility (gh-1533) -c = net.new(box.cfg.listen) -c:ping() -c:close() - --- Test for connect_timeout > 0 in netbox connect -test_run:cmd("setopt delimiter ';'"); -need_stop = false; -greeting = -"Tarantool 1.7.3 (Lua console)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" .. -"type 'help' for interactive help~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"; -socket = require('socket'); -srv = socket.tcp_server('localhost', 0, { - handler = function(fd) - local fiber = require('fiber') - while not need_stop do - fiber.sleep(0.01) - end - fd:write(greeting) - end -}); -port = srv:name().port --- we must get timeout -nb = net.new('localhost:' .. port, { - wait_connected = true, console = true, - connect_timeout = 0.1 -}); -nb.error:find('timed out') ~= nil; -need_stop = true -nb:close(); --- we must get peer closed -nb = net.new('localhost:' .. port, { - wait_connected = true, console = true, - connect_timeout = 0.2 -}); -nb.error ~= "Timeout exceeded"; -nb:close(); -test_run:cmd("setopt delimiter ''"); -srv:close() - -test_run:cmd("clear filter") - --- --- gh-2402 net.box doesn't support space:format() --- - -space = box.schema.space.create('test', {format={{name="id", type="unsigned"}}}) -space ~= nil -_ = box.space.test:create_index('primary') -box.schema.user.grant('guest', 'read', 'space', 'test') - -c = net.connect(box.cfg.listen) - -c:ping() -c.space.test ~= nil - -format = c.space.test:format() - -format[1] ~= nil -format[1].name == "id" -format[1].type == "unsigned" - -c.space.test:format({}) - --- --- gh-4091: index unique flag is always false. --- -c.space.test.index.primary.unique - -c:close() -space:drop() - --- --- Check that it's possible to get connection object form net.box space --- - -space = box.schema.space.create('test', {format={{name="id", type="unsigned"}}}) -space ~= nil -_ = box.space.test:create_index('primary') -box.schema.user.grant('guest','read,write,execute','space', 'test') - -c = net.connect(box.cfg.listen) - -c:ping() -c.space.test ~= nil - -c.space.test.connection == c -box.schema.user.revoke('guest','read,write,execute','space', 'test') -c:close() - --- --- gh-2642: box.session.type() --- - -box.schema.user.grant('guest','execute','universe') -c = net.connect(box.cfg.listen) -c:call("box.session.type") -c:close() -box.schema.user.revoke('guest', 'execute', 'universe') - - --- --- On_connect/disconnect triggers. --- -test_run:cmd('create server connecter with script = "box/proxy.lua"') -test_run:cmd('start server connecter') -test_run:cmd("set variable connect_to to 'connecter.listen'") -conn = net.connect(connect_to, { reconnect_after = 0.1 }) -conn.state -connected_cnt = 0 -disconnected_cnt = 0 -function on_connect() connected_cnt = connected_cnt + 1 end -function on_disconnect() disconnected_cnt = disconnected_cnt + 1 end -conn:on_connect(on_connect) -conn:on_disconnect(on_disconnect) -test_run:cmd('stop server connecter') -test_run:cmd('start server connecter') -while conn.state ~= 'active' do fiber.sleep(0.1) end -connected_cnt -old_disconnected_cnt = disconnected_cnt -disconnected_cnt >= 1 -conn:close() -disconnected_cnt == old_disconnected_cnt + 1 -test_run:cmd('stop server connecter') - --- --- gh-2401 update pseudo objects not replace them --- -space:drop() -space = box.schema.space.create('test') -box.schema.user.grant('guest', 'read', 'space', 'test') -c = net.connect(box.cfg.listen) -cspace = c.space.test -space.index.test_index == nil -cspace.index.test_index == nil -_ = space:create_index("test_index", {parts={1, 'string'}}) -c:reload_schema() -space.index.test_index ~= nil -cspace.index.test_index ~= nil -c.space.test.index.test_index ~= nil - --- cleanup - -space:drop() - --- --- gh-946: long polling CALL blocks input --- -box.schema.func.create('fast_call') -box.schema.func.create('long_call') -box.schema.func.create('wait_signal') -box.schema.user.grant('guest', 'execute', 'function', 'fast_call') -box.schema.user.grant('guest', 'execute', 'function', 'long_call') -box.schema.user.grant('guest', 'execute', 'function', 'wait_signal') -c = net.connect(box.cfg.listen) - -N = 100 - -pad = string.rep('x', 1024) - -long_call_cond = fiber.cond() -long_call_channel = fiber.channel() -fast_call_channel = fiber.channel() - -function fast_call(x) return x end -function long_call(x) long_call_cond:wait() return x * 2 end - -test_run:cmd("setopt delimiter ';'") -for i = 1, N do - fiber.create(function() - fast_call_channel:put(c:call('fast_call', {i, pad})) - end) - fiber.create(function() - long_call_channel:put(c:call('long_call', {i, pad})) - end) -end -test_run:cmd("setopt delimiter ''"); - -x = 0 -for i = 1, N do x = x + fast_call_channel:get() end -x - -long_call_cond:broadcast() - -x = 0 -for i = 1, N do x = x + long_call_channel:get() end -x - --- --- Check that a connection does not leak if there is --- a long CALL in progress when it is closed. --- -disconnected = false -function on_disconnect() disconnected = true end - --- Make sure all dangling connections are collected so --- that on_disconnect trigger isn't called spuriously. -collectgarbage('collect') -fiber.sleep(0) - -box.session.on_disconnect(on_disconnect) == on_disconnect - --- --- gh-3859: on_disconnect is called only after all requests are --- processed, but should be called right after disconnect and --- only once. --- -ch1 = fiber.channel(1) -ch2 = fiber.channel(1) -function wait_signal() ch1:put(true) ch2:get() end -_ = fiber.create(function() c:call('wait_signal') end) -ch1:get() - -c:close() -fiber.sleep(0) -while disconnected == false do fiber.sleep(0.01) end -disconnected -- true -disconnected = nil - -ch2:put(true) -fiber.sleep(0) -disconnected -- nil, on_disconnect is not called second time. - -box.session.on_disconnect(nil, on_disconnect) - -box.schema.func.drop('long_call') -box.schema.func.drop('fast_call') -box.schema.func.drop('wait_signal') --- --- gh-2666: check that netbox.call is not repeated on schema --- change. --- -box.schema.user.grant('guest', 'write', 'space', '_space') -box.schema.user.grant('guest', 'write', 'space', '_schema') -box.schema.user.grant('guest', 'create', 'universe') -count = 0 -function create_space(name) count = count + 1 box.schema.create_space(name) return true end -box.schema.func.create('create_space') -box.schema.user.grant('guest', 'execute', 'function', 'create_space') -c = net.connect(box.cfg.listen) -c:call('create_space', {'test1'}) -count -c:call('create_space', {'test2'}) -count -c:call('create_space', {'test3'}) -count -box.space.test1:drop() -box.space.test2:drop() -box.space.test3:drop() -box.schema.user.revoke('guest', 'write', 'space', '_space') -box.schema.user.revoke('guest', 'write', 'space', '_schema') -box.schema.user.revoke('guest', 'create', 'universe') -c:close() -box.schema.func.drop('create_space') - --- --- gh-3164: netbox connection is not closed and garbage collected --- ever, if reconnect_after is set. --- -test_run:cmd('start server connecter') -test_run:cmd("set variable connect_to to 'connecter.listen'") -weak = setmetatable({}, {__mode = 'v'}) --- Create strong and weak reference. Weak is valid until strong --- is valid too. -strong = net.connect(connect_to, {reconnect_after = 0.1}) -weak.c = strong -weak.c:ping() -test_run:cmd('stop server connecter') -test_run:cmd('cleanup server connecter') --- Check the connection tries to reconnect at least two times. --- 'Cannot assign requested address' is the crutch for running the --- tests in a docker. This error emits instead of --- 'Connection refused' inside a docker. -old_log_level = box.cfg.log_level -box.cfg{log_level = 6} -log.info(string.rep('a', 1000)) -test_run:cmd("setopt delimiter ';'") -while test_run:grep_log('default', 'Network is unreachable', 1000) == nil and - test_run:grep_log('default', 'Connection refused', 1000) == nil and - test_run:grep_log('default', 'Cannot assign requested address', 1000) == nil do - fiber.sleep(0.1) -end; -log.info(string.rep('a', 1000)); -while test_run:grep_log('default', 'Network is unreachable', 1000) == nil and - test_run:grep_log('default', 'Connection refused', 1000) == nil and - test_run:grep_log('default', 'Cannot assign requested address', 1000) == nil do - fiber.sleep(0.1) -end; -test_run:cmd("setopt delimiter ''"); -box.cfg{log_level = old_log_level} -collectgarbage('collect') -strong.state -strong == weak.c --- Remove single strong reference. Now connection must be garbage --- collected. -strong = nil -collectgarbage('collect') --- Now weak.c is null, because it was weak reference, and the --- connection is deleted by 'collect'. -weak.c - --- --- gh-2677: netbox supports console connections, that complicates --- both console and netbox. It was necessary because before a --- connection is established, a console does not known is it --- binary or text protocol, and netbox could not be created from --- existing socket. --- -box.schema.user.grant('guest', 'execute', 'universe') -urilib = require('uri') -uri = urilib.parse(tostring(box.cfg.listen)) -s, greeting = net.establish_connection(uri.host, uri.service) -c = net.wrap(s, greeting, uri.host, uri.service, {reconnect_after = 0.01}) -c.state - -a = 100 -function kek(args) return {1, 2, 3, args} end -c:eval('a = 200') -a -c:call('kek', {300}) -s = box.schema.create_space('test') -box.schema.user.grant('guest', 'read,write', 'space', 'test') -pk = s:create_index('pk') -c:reload_schema() -c.space.test:replace{1} -c.space.test:get{1} -c.space.test:delete{1} --- --- Break a connection to test reconnect_after. --- -_ = c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') -while not c:is_connected() do fiber.sleep(0.01) end -c:ping() - -s:drop() -c:close() - --- --- Test a case, when netbox can not connect first time, but --- reconnect_after is set. --- -c = net.connect('localhost:33333', {reconnect_after = 0.1, wait_connected = false}) -while c.state ~= 'error_reconnect' do fiber.sleep(0.01) end -c:close() - -box.schema.user.revoke('guest', 'execute', 'universe') -c.state -c = nil - --- --- gh-3256 net.box is_nullable and collation options output --- -space = box.schema.create_space('test') -box.schema.user.grant('guest', 'read', 'space', 'test') -_ = space:create_index('pk') -_ = space:create_index('sk', {parts = {{2, 'unsigned', is_nullable = true}}}) -c = net:connect(box.cfg.listen) -c.space.test.index.sk.parts -space:drop() - -space = box.schema.create_space('test') -c:close() -box.schema.user.grant('guest', 'read', 'space', 'test') -c = net:connect(box.cfg.listen) -box.internal.collation.create('test', 'ICU', 'ru-RU') -collation_id = box.internal.collation.id_by_name('test') -_ = space:create_index('sk', { type = 'tree', parts = {{1, 'str', collation = 'test'}}, unique = true }) -c:reload_schema() -parts = c.space.test.index.sk.parts -#parts == 1 -parts[1].fieldno == 1 -parts[1].type == 'string' -parts[1].is_nullable == false -if _TARANTOOL >= '2.2.1' then \ - return parts[1].collation == 'test' \ -else \ - return parts[1].collation_id == collation_id \ -end -c:close() -box.internal.collation.drop('test') -space:drop() -c.state -c = nil - --- --- gh-3107: fiber-async netbox. --- -cond = nil -box.schema.func.create('long_function') -box.schema.user.grant('guest', 'execute', 'function', 'long_function') -function long_function(...) cond = fiber.cond() cond:wait() return ... end -function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end -s = box.schema.create_space('test') -pk = s:create_index('pk') -s:replace{1} -s:replace{2} -s:replace{3} -s:replace{4} -c = net:connect(box.cfg.listen) --- --- Check long connections, multiple wait_result(). --- -future = c:call('long_function', {1, 2, 3}, {is_async = true}) -future:result() -future:is_ready() -future:wait_result(0.01) -- Must fail on timeout. -finalize_long() -ret = future:wait_result(100) -future:is_ready() --- Any timeout is ok - response is received already. -future:wait_result(0) -future:wait_result(0.01) -ret - -_, err = pcall(future.wait_result, future, true) -err:find('Usage') ~= nil -_, err = pcall(future.wait_result, future, '100') -err:find('Usage') ~= nil - --- --- Check infinity timeout. --- -ret = nil -_ = fiber.create(function() ret = c:call('long_function', {1, 2, 3}, {is_async = true}):wait_result() end) -finalize_long() -while not ret do fiber.sleep(0.01) end -ret -c:close() -box.schema.user.grant('guest', 'execute', 'universe') -c = net:connect(box.cfg.listen) -future = c:eval('return long_function(...)', {1, 2, 3}, {is_async = true}) -future:result() -future:wait_result(0.01) -- Must fail on timeout. -finalize_long() -future:wait_result(100) - -c:close() --- --- Check that is_async does not work on a closed connection. --- -c:call('any_func', {}, {is_async = true}) - -box.schema.user.revoke('guest', 'execute', 'universe') -c = net:connect(box.cfg.listen) - --- --- Ensure the request is garbage collected both if is not used and --- if is. --- -gc_test = setmetatable({}, {__mode = 'v'}) -gc_test.future = c:call('long_function', {1, 2, 3}, {is_async = true}) -gc_test.future ~= nil -collectgarbage() -gc_test -finalize_long() - -future = c:call('long_function', {1, 2, 3}, {is_async = true}) -collectgarbage() -future ~= nil -finalize_long() -future:wait_result(1000) -collectgarbage() -future ~= nil -gc_test.future = future -future = nil -collectgarbage() -gc_test - --- --- Ensure a request can be finalized from non-caller fibers. --- -future = c:call('long_function', {1, 2, 3}, {is_async = true}) -ret = {} -count = 0 -for i = 1, 10 do fiber.create(function() ret[i] = future:wait_result(1000) count = count + 1 end) end -future:wait_result(0.01) -- Must fail on timeout. -finalize_long() -while count ~= 10 do fiber.sleep(0.1) end -ret - --- --- Test space methods. --- -c:close() -box.schema.user.grant('guest', 'read,write', 'space', 'test') -c = net:connect(box.cfg.listen) -future = c.space.test:select({1}, {is_async = true}) -ret = future:wait_result(100) -ret -type(ret[1]) -future = c.space.test:insert({5}, {is_async = true}) -future:wait_result(100) -s:get{5} -future = c.space.test:replace({6}, {is_async = true}) -future:wait_result(100) -s:get{6} -future = c.space.test:delete({6}, {is_async = true}) -future:wait_result(100) -s:get{6} -future = c.space.test:update({5}, {{'=', 2, 5}}, {is_async = true}) -future:wait_result(100) -s:get{5} -future = c.space.test:upsert({5}, {{'=', 2, 6}}, {is_async = true}) -future:wait_result(100) -s:get{5} -future = c.space.test:get({5}, {is_async = true}) -future:wait_result(100) - --- --- Test index methods. --- -future = c.space.test.index.pk:select({1}, {is_async = true}) -future:wait_result(100) -future = c.space.test.index.pk:get({2}, {is_async = true}) -future:wait_result(100) -future = c.space.test.index.pk:min({}, {is_async = true}) -future:wait_result(100) -future = c.space.test.index.pk:max({}, {is_async = true}) -future:wait_result(100) -c:close() -box.schema.user.grant('guest', 'execute', 'universe') -c = net:connect(box.cfg.listen) -future = c.space.test.index.pk:count({3}, {is_async = true}) -future:wait_result(100) -c:close() -box.schema.user.revoke('guest', 'execute', 'universe') -c = net:connect(box.cfg.listen) -future = c.space.test.index.pk:delete({3}, {is_async = true}) -future:wait_result(100) -s:get{3} -future = c.space.test.index.pk:update({4}, {{'=', 2, 6}}, {is_async = true}) -future:wait_result(100) -s:get{4} - --- --- Test async errors. --- -future = c.space.test:insert({1}, {is_async = true}) -future:wait_result() -future:result() - --- --- Test discard. --- -future = c:call('long_function', {1, 2, 3}, {is_async = true}) -future:discard() -finalize_long() -future:result() -future:wait_result(100) - --- --- Test closed connection. --- -future = c:call('long_function', {1, 2, 3}, {is_async = true}) -finalize_long() -future:wait_result(100) -future2 = c:call('long_function', {1, 2, 3}, {is_async = true}) -c:close() -future2:wait_result(100) -future2:result() -future2:discard() --- Already successful result must be available. -future:wait_result(100) -future:result() -future:is_ready() -finalize_long() - --- --- Test reconnect. --- -c = net:connect(box.cfg.listen, {reconnect_after = 0.01}) -future = c:call('long_function', {1, 2, 3}, {is_async = true}) -_ = c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') -while not c:is_connected() do fiber.sleep(0.01) end -finalize_long() -future:wait_result(100) -future:result() -future = c:call('long_function', {1, 2, 3}, {is_async = true}) -finalize_long() -future:wait_result(100) - --- --- Test raw response getting. --- -ibuf = require('buffer').ibuf() -future = c:call('long_function', {1, 2, 3}, {is_async = true, buffer = ibuf}) -finalize_long() -future:wait_result(100) -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) -result - -box.schema.func.drop('long_function') - --- --- Test async schema version change. --- -function change_schema(i) local tmp = box.schema.create_space('test'..i) return 'ok' end -box.schema.func.create('change_schema') -box.schema.user.grant('guest', 'execute', 'function', 'change_schema') -box.schema.user.grant('guest', 'write', 'space', '_schema') -box.schema.user.grant('guest', 'read,write', 'space', '_space') -box.schema.user.grant('guest', 'create', 'space') -future1 = c:call('change_schema', {'1'}, {is_async = true}) -future2 = c:call('change_schema', {'2'}, {is_async = true}) -future3 = c:call('change_schema', {'3'}, {is_async = true}) -future1:wait_result() -future2:wait_result() -future3:wait_result() - -c:close() -s:drop() -box.space.test1:drop() -box.space.test2:drop() -box.space.test3:drop() -box.schema.func.drop('change_schema') - --- --- gh-2978: field names for tuples received from netbox. --- -_ = box.schema.create_space("named", {format = {{name = "id"}, {name="abc"}}}) -_ = box.space.named:create_index('id', {parts = {{1, 'unsigned'}}}) -box.space.named:insert({1, 1}) -box.schema.user.grant('guest', 'read, write, execute', 'space') -cn = net.connect(box.cfg.listen) - -s = cn.space.named -s:get{1}.id -s:get{1}:tomap() -s:insert{2,3}:tomap() -s:replace{2,14}:tomap() -s:update(1, {{'+', 2, 10}}):tomap() -s:select()[1]:tomap() -s:delete({2}):tomap() - --- Check that formats changes after reload. -box.space.named:format({{name = "id2"}, {name="abc2"}}) -s:select()[1]:tomap() -cn:reload_schema() -s:select()[1]:tomap() - -cn:close() -box.space.named:drop() -box.schema.user.revoke('guest', 'read, write, execute', 'space') - --- --- gh-3400: long-poll input discard must not touch event loop of --- a closed connection. --- -function long() fiber.yield() return 100 end -c = net.connect(box.cfg.listen) -c:ping() --- Create batch of two requests. First request is sent to TX --- thread, second one terminates connection. The preceeding --- request discards input, and this operation must not trigger --- new attempts to read any data - the connection is closed --- already. --- -f = fiber.create(c._transport.perform_request, nil, nil, false, 'call_17', nil, nil, nil, 'long', {}) c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') -while f:status() ~= 'dead' do fiber.sleep(0.01) end -c:close() - --- --- gh-3464: iproto hangs in 100% CPU when too big packet size --- is received due to size_t overflow. --- -c = net:connect(box.cfg.listen) -data = msgpack.encode(18400000000000000000)..'aaaaaaa' -c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, data) -c:close() -test_run:grep_log('default', 'too big packet size in the header') ~= nil - - --- --- gh-3629: netbox leaks when a connection is closed deliberately --- and it has non-finished requests. --- -ready = false -ok = nil -err = nil -c = net:connect(box.cfg.listen) -function do_long() while not ready do fiber.sleep(0.01) end end -box.schema.func.create('do_long') -box.schema.user.grant('guest', 'execute', 'function', 'do_long') -f = fiber.create(function() ok, err = pcall(c.call, c, 'do_long') end) -while f:status() ~= 'suspended' do fiber.sleep(0.01) end -c:close() -ready = true -while not err do fiber.sleep(0.01) end -ok, err - --- --- gh-3856: wait_connected = false is ignored. --- -c = net.connect('8.8.8.8:123456', {wait_connected = false}) -c -c:close() - -box.schema.func.drop('do_long') -box.schema.user.revoke('guest', 'write', 'space', '_schema') -box.schema.user.revoke('guest', 'read,write', 'space', '_space') -box.schema.user.revoke('guest', 'create', 'space') - --- --- gh-3958 updating box.cfg.readahead doesn't affect existing connections. --- -readahead = box.cfg.readahead - -box.cfg{readahead = 128} - -s = box.schema.space.create("test") -_ = s:create_index("pk") -box.schema.user.grant("guest", "read,write", "space", "test") - --- connection is created with small readahead value, --- make sure it is updated if box.cfg.readahead is changed. -c = net.connect(box.cfg.listen) - -box.cfg{readahead = 100 * 1024} - -box.error.injection.set("ERRINJ_WAL_DELAY", true) -pad = string.rep('x', 8192) -for i = 1, 5 do c.space.test:replace({i, pad}, {is_async = true}) end -box.error.injection.set("ERRINJ_WAL_DELAY", false) - -test_run:wait_log('default', 'readahead limit is reached', 1024, 0.1) - -s:drop() -box.cfg{readahead = readahead} - --- --- related to gh-4040: log corrupted rows --- -log_level = box.cfg.log_level -box.cfg{log_level=6} -sock = socket.tcp_connect(LISTEN.host, LISTEN.service) -sock:read(9) --- we need to have a packet with correctly encoded length, --- so that it bypasses iproto length check, but cannot be --- decoded in xrow_header_decode --- 0x3C = 60, sha1 digest is 20 bytes long -data = string.fromhex('3C'..string.rep(require('digest').sha1_hex('bcde'), 3)) -sock:write(data) -sock:close() - -test_run:wait_log('default', 'Got a corrupted row.*', nil, 10) -test_run:wait_log('default', '00000000:.*', nil, 10) -test_run:wait_log('default', '00000010:.*', nil, 10) -test_run:wait_log('default', '00000020:.*', nil, 10) -test_run:wait_log('default', '00000030:.*', nil, 10) --- we expect nothing below, so don't wait -test_run:grep_log('default', '00000040:.*') - -box.cfg{log_level=log_level} diff --git a/test/box/net.box_bad_argument_gh-594.result b/test/box/net.box_bad_argument_gh-594.result new file mode 100644 index 000000000..339886eaa --- /dev/null +++ b/test/box/net.box_bad_argument_gh-594.result @@ -0,0 +1,38 @@ +remote = require 'net.box' +--- +... +fiber = require 'fiber' +--- +... +test_run = require('test_run').new() +--- +... +-- #594: bad argument #1 to 'setmetatable' (table expected, got number) +box.schema.func.create('dostring') +--- +... +box.schema.user.grant('guest', 'execute', 'function', 'dostring') +--- +... +test_run:cmd("setopt delimiter ';'") +--- +- true +... +function gh594() + local cn = remote.connect(box.cfg.listen) + local ping = fiber.create(function() cn:ping() end) + cn:call('dostring', {'return 2 + 2'}) + cn:close() +end; +--- +... +test_run:cmd("setopt delimiter ''"); +--- +- true +... +gh594() +--- +... +box.schema.func.drop('dostring') +--- +... diff --git a/test/box/net.box_bad_argument_gh-594.test.lua b/test/box/net.box_bad_argument_gh-594.test.lua new file mode 100644 index 000000000..65265cbb5 --- /dev/null +++ b/test/box/net.box_bad_argument_gh-594.test.lua @@ -0,0 +1,17 @@ +remote = require 'net.box' +fiber = require 'fiber' +test_run = require('test_run').new() + +-- #594: bad argument #1 to 'setmetatable' (table expected, got number) +box.schema.func.create('dostring') +box.schema.user.grant('guest', 'execute', 'function', 'dostring') +test_run:cmd("setopt delimiter ';'") +function gh594() + local cn = remote.connect(box.cfg.listen) + local ping = fiber.create(function() cn:ping() end) + cn:call('dostring', {'return 2 + 2'}) + cn:close() +end; +test_run:cmd("setopt delimiter ''"); +gh594() +box.schema.func.drop('dostring') diff --git a/test/box/net.box_call_blocks_gh-946.result b/test/box/net.box_call_blocks_gh-946.result new file mode 100644 index 000000000..40afec416 --- /dev/null +++ b/test/box/net.box_call_blocks_gh-946.result @@ -0,0 +1,124 @@ +fiber = require 'fiber' +--- +... +test_run = require('test_run').new() +--- +... +--space = box.schema.space.create('net_box_test_space') +--index = space:create_index('primary', { type = 'tree' }) +net = require('net.box') +--- +... +socket = require('socket'); +--- +... +test_run:cmd('create server connecter with script = "box/proxy.lua"') +--- +- true +... +-- +-- gh-946: long polling CALL blocks input +-- +box.schema.func.create('fast_call') +--- +... +box.schema.func.create('long_call') +--- +... +box.schema.func.create('wait_signal') +--- +... +box.schema.user.grant('guest', 'execute', 'function', 'fast_call') +--- +... +box.schema.user.grant('guest', 'execute', 'function', 'long_call') +--- +... +box.schema.user.grant('guest', 'execute', 'function', 'wait_signal') +--- +... +c = net.connect(box.cfg.listen) +--- +... +N = 100 +--- +... +pad = string.rep('x', 1024) +--- +... +long_call_cond = fiber.cond() +--- +... +long_call_channel = fiber.channel() +--- +... +fast_call_channel = fiber.channel() +--- +... +function fast_call(x) return x end +--- +... +function long_call(x) long_call_cond:wait() return x * 2 end +--- +... +test_run:cmd("setopt delimiter ';'") +--- +- true +... +for i = 1, N do + fiber.create(function() + fast_call_channel:put(c:call('fast_call', {i, pad})) + end) + fiber.create(function() + long_call_channel:put(c:call('long_call', {i, pad})) + end) +end +test_run:cmd("setopt delimiter ''"); +--- +... +x = 0 +--- +... +for i = 1, N do x = x + fast_call_channel:get() end +--- +... +x +--- +- 5050 +... +long_call_cond:broadcast() +--- +... +x = 0 +--- +... +for i = 1, N do x = x + long_call_channel:get() end +--- +... +x +--- +- 10100 +... +-- +-- Check that a connection does not leak if there is +-- a long CALL in progress when it is closed. +-- +disconnected = false +--- +... +function on_disconnect() disconnected = true end +--- +... +-- Make sure all dangling connections are collected so +-- that on_disconnect trigger isn't called spuriously. +collectgarbage('collect') +--- +- 0 +... +fiber.sleep(0) +--- +... +box.session.on_disconnect(on_disconnect) == on_disconnect +--- +- true +... diff --git a/test/box/net.box_call_blocks_gh-946.test.lua b/test/box/net.box_call_blocks_gh-946.test.lua new file mode 100644 index 000000000..f3cd3f305 --- /dev/null +++ b/test/box/net.box_call_blocks_gh-946.test.lua @@ -0,0 +1,67 @@ +fiber = require 'fiber' +test_run = require('test_run').new() + +--space = box.schema.space.create('net_box_test_space') +--index = space:create_index('primary', { type = 'tree' }) + +net = require('net.box') +socket = require('socket'); + +test_run:cmd('create server connecter with script = "box/proxy.lua"') + +-- +-- gh-946: long polling CALL blocks input +-- +box.schema.func.create('fast_call') +box.schema.func.create('long_call') +box.schema.func.create('wait_signal') +box.schema.user.grant('guest', 'execute', 'function', 'fast_call') +box.schema.user.grant('guest', 'execute', 'function', 'long_call') +box.schema.user.grant('guest', 'execute', 'function', 'wait_signal') +c = net.connect(box.cfg.listen) + +N = 100 + +pad = string.rep('x', 1024) + +long_call_cond = fiber.cond() +long_call_channel = fiber.channel() +fast_call_channel = fiber.channel() + +function fast_call(x) return x end +function long_call(x) long_call_cond:wait() return x * 2 end + +test_run:cmd("setopt delimiter ';'") +for i = 1, N do + fiber.create(function() + fast_call_channel:put(c:call('fast_call', {i, pad})) + end) + fiber.create(function() + long_call_channel:put(c:call('long_call', {i, pad})) + end) +end +test_run:cmd("setopt delimiter ''"); + +x = 0 +for i = 1, N do x = x + fast_call_channel:get() end +x + +long_call_cond:broadcast() + +x = 0 +for i = 1, N do x = x + long_call_channel:get() end +x + +-- +-- Check that a connection does not leak if there is +-- a long CALL in progress when it is closed. +-- +disconnected = false +function on_disconnect() disconnected = true end + +-- Make sure all dangling connections are collected so +-- that on_disconnect trigger isn't called spuriously. +collectgarbage('collect') +fiber.sleep(0) + +box.session.on_disconnect(on_disconnect) == on_disconnect diff --git a/test/box/net.box_collectgarbage_gh-3107.result b/test/box/net.box_collectgarbage_gh-3107.result new file mode 100644 index 000000000..240a472de --- /dev/null +++ b/test/box/net.box_collectgarbage_gh-3107.result @@ -0,0 +1,120 @@ +fiber = require 'fiber' +--- +... +net = require('net.box') +--- +... +-- +-- gh-3107: fiber-async netbox. +-- +cond = nil +--- +... +box.schema.func.create('long_function') +--- +... +box.schema.user.grant('guest', 'execute', 'function', 'long_function') +--- +... +function long_function(...) cond = fiber.cond() cond:wait() return ... end +--- +... +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end +--- +... +s = box.schema.create_space('test') +--- +... +pk = s:create_index('pk') +--- +... +s:replace{1} +--- +- [1] +... +s:replace{2} +--- +- [2] +... +s:replace{3} +--- +- [3] +... +s:replace{4} +--- +- [4] +... +c = net:connect(box.cfg.listen) +--- +... +-- +-- Ensure the request is garbage collected both if is not used and +-- if is. +-- +gc_test = setmetatable({}, {__mode = 'v'}) +--- +... +gc_test.future = c:call('long_function', {1, 2, 3}, {is_async = true}) +--- +... +gc_test.future ~= nil +--- +- true +... +collectgarbage() +--- +- 0 +... +gc_test +--- +- [] +... +finalize_long() +--- +... +future = c:call('long_function', {1, 2, 3}, {is_async = true}) +--- +... +collectgarbage() +--- +- 0 +... +future ~= nil +--- +- true +... +finalize_long() +--- +... +future:wait_result(1000) +--- +- [1, 2, 3] +... +collectgarbage() +--- +- 0 +... +future ~= nil +--- +- true +... +gc_test.future = future +--- +... +future = nil +--- +... +collectgarbage() +--- +- 0 +... +gc_test +--- +- [] +... +c:close() +--- +... +s:drop() +--- +... diff --git a/test/box/net.box_collectgarbage_gh-3107.test.lua b/test/box/net.box_collectgarbage_gh-3107.test.lua new file mode 100644 index 000000000..cfe333757 --- /dev/null +++ b/test/box/net.box_collectgarbage_gh-3107.test.lua @@ -0,0 +1,44 @@ +fiber = require 'fiber' +net = require('net.box') + +-- +-- gh-3107: fiber-async netbox. +-- +cond = nil +box.schema.func.create('long_function') +box.schema.user.grant('guest', 'execute', 'function', 'long_function') +function long_function(...) cond = fiber.cond() cond:wait() return ... end +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end +s = box.schema.create_space('test') +pk = s:create_index('pk') +s:replace{1} +s:replace{2} +s:replace{3} +s:replace{4} +c = net:connect(box.cfg.listen) + +-- +-- Ensure the request is garbage collected both if is not used and +-- if is. +-- +gc_test = setmetatable({}, {__mode = 'v'}) +gc_test.future = c:call('long_function', {1, 2, 3}, {is_async = true}) +gc_test.future ~= nil +collectgarbage() +gc_test +finalize_long() + +future = c:call('long_function', {1, 2, 3}, {is_async = true}) +collectgarbage() +future ~= nil +finalize_long() +future:wait_result(1000) +collectgarbage() +future ~= nil +gc_test.future = future +future = nil +collectgarbage() +gc_test + +c:close() +s:drop() diff --git a/test/box/net.box_connect_triggers.result b/test/box/net.box_connect_triggers.result new file mode 100644 index 000000000..c5b1ef6db --- /dev/null +++ b/test/box/net.box_connect_triggers.result @@ -0,0 +1,82 @@ +fiber = require 'fiber' +--- +... +test_run = require('test_run').new() +--- +... +net = require('net.box') +--- +... +-- +-- On_connect/disconnect triggers. +-- +test_run:cmd('create server connecter with script = "box/proxy.lua"') +--- +- true +... +test_run:cmd('start server connecter') +--- +- true +... +test_run:cmd("set variable connect_to to 'connecter.listen'") +--- +- true +... +conn = net.connect(connect_to, { reconnect_after = 0.1 }) +--- +... +conn.state +--- +- active +... +connected_cnt = 0 +--- +... +disconnected_cnt = 0 +--- +... +function on_connect() connected_cnt = connected_cnt + 1 end +--- +... +function on_disconnect() disconnected_cnt = disconnected_cnt + 1 end +--- +... +conn:on_connect(on_connect) +--- +... +conn:on_disconnect(on_disconnect) +--- +... +test_run:cmd('stop server connecter') +--- +- true +... +test_run:cmd('start server connecter') +--- +- true +... +while conn.state ~= 'active' do fiber.sleep(0.1) end +--- +... +connected_cnt +--- +- 1 +... +old_disconnected_cnt = disconnected_cnt +--- +... +disconnected_cnt >= 1 +--- +- true +... +conn:close() +--- +... +disconnected_cnt == old_disconnected_cnt + 1 +--- +- true +... +test_run:cmd('stop server connecter') +--- +- true +... diff --git a/test/box/net.box_connect_triggers.test.lua b/test/box/net.box_connect_triggers.test.lua new file mode 100644 index 000000000..86794035e --- /dev/null +++ b/test/box/net.box_connect_triggers.test.lua @@ -0,0 +1,27 @@ +fiber = require 'fiber' +test_run = require('test_run').new() +net = require('net.box') + +-- +-- On_connect/disconnect triggers. +-- +test_run:cmd('create server connecter with script = "box/proxy.lua"') +test_run:cmd('start server connecter') +test_run:cmd("set variable connect_to to 'connecter.listen'") +conn = net.connect(connect_to, { reconnect_after = 0.1 }) +conn.state +connected_cnt = 0 +disconnected_cnt = 0 +function on_connect() connected_cnt = connected_cnt + 1 end +function on_disconnect() disconnected_cnt = disconnected_cnt + 1 end +conn:on_connect(on_connect) +conn:on_disconnect(on_disconnect) +test_run:cmd('stop server connecter') +test_run:cmd('start server connecter') +while conn.state ~= 'active' do fiber.sleep(0.1) end +connected_cnt +old_disconnected_cnt = disconnected_cnt +disconnected_cnt >= 1 +conn:close() +disconnected_cnt == old_disconnected_cnt + 1 +test_run:cmd('stop server connecter') diff --git a/test/box/net.box_console_connections_gh-2677.result b/test/box/net.box_console_connections_gh-2677.result new file mode 100644 index 000000000..c9116e5d4 --- /dev/null +++ b/test/box/net.box_console_connections_gh-2677.result @@ -0,0 +1,95 @@ +fiber = require 'fiber' +--- +... +net = require('net.box') +--- +... +-- +-- gh-2677: netbox supports console connections, that complicates +-- both console and netbox. It was necessary because before a +-- connection is established, a console does not known is it +-- binary or text protocol, and netbox could not be created from +-- existing socket. +-- +box.schema.user.grant('guest', 'execute', 'universe') +--- +... +urilib = require('uri') +--- +... +uri = urilib.parse(tostring(box.cfg.listen)) +--- +... +s, greeting = net.establish_connection(uri.host, uri.service) +--- +... +c = net.wrap(s, greeting, uri.host, uri.service, {reconnect_after = 0.01}) +--- +... +c.state +--- +- active +... +a = 100 +--- +... +function kek(args) return {1, 2, 3, args} end +--- +... +c:eval('a = 200') +--- +... +a +--- +- 200 +... +c:call('kek', {300}) +--- +- [1, 2, 3, 300] +... +s = box.schema.create_space('test') +--- +... +box.schema.user.grant('guest', 'read,write', 'space', 'test') +--- +... +pk = s:create_index('pk') +--- +... +c:reload_schema() +--- +... +c.space.test:replace{1} +--- +- [1] +... +c.space.test:get{1} +--- +- [1] +... +c.space.test:delete{1} +--- +- [1] +... +-- +-- Break a connection to test reconnect_after. +-- +_ = c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') +--- +... +while not c:is_connected() do fiber.sleep(0.01) end +--- +... +c:ping() +--- +- true +... +s:drop() +--- +... +c:close() +--- +... +box.schema.user.revoke('guest', 'execute', 'universe') +--- +... diff --git a/test/box/net.box_console_connections_gh-2677.test.lua b/test/box/net.box_console_connections_gh-2677.test.lua new file mode 100644 index 000000000..c6c9ea846 --- /dev/null +++ b/test/box/net.box_console_connections_gh-2677.test.lua @@ -0,0 +1,39 @@ +fiber = require 'fiber' +net = require('net.box') + +-- +-- gh-2677: netbox supports console connections, that complicates +-- both console and netbox. It was necessary because before a +-- connection is established, a console does not known is it +-- binary or text protocol, and netbox could not be created from +-- existing socket. +-- +box.schema.user.grant('guest', 'execute', 'universe') +urilib = require('uri') +uri = urilib.parse(tostring(box.cfg.listen)) +s, greeting = net.establish_connection(uri.host, uri.service) +c = net.wrap(s, greeting, uri.host, uri.service, {reconnect_after = 0.01}) +c.state + +a = 100 +function kek(args) return {1, 2, 3, args} end +c:eval('a = 200') +a +c:call('kek', {300}) +s = box.schema.create_space('test') +box.schema.user.grant('guest', 'read,write', 'space', 'test') +pk = s:create_index('pk') +c:reload_schema() +c.space.test:replace{1} +c.space.test:get{1} +c.space.test:delete{1} +-- +-- Break a connection to test reconnect_after. +-- +_ = c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') +while not c:is_connected() do fiber.sleep(0.01) end +c:ping() + +s:drop() +c:close() +box.schema.user.revoke('guest', 'execute', 'universe') diff --git a/test/box/net.box_count_inconsistent_gh-3262.result b/test/box/net.box_count_inconsistent_gh-3262.result new file mode 100644 index 000000000..c77677625 --- /dev/null +++ b/test/box/net.box_count_inconsistent_gh-3262.result @@ -0,0 +1,488 @@ +remote = require 'net.box' +--- +... +fiber = require 'fiber' +--- +... +test_run = require('test_run').new() +--- +... +LISTEN = require('uri').parse(box.cfg.listen) +--- +... +space = box.schema.space.create('net_box_test_space') +--- +... +index = space:create_index('primary', { type = 'tree' }) +--- +... +box.schema.user.grant('guest', 'read,write', 'space', 'net_box_test_space') +--- +... +box.schema.user.grant('guest', 'execute', 'universe') +--- +... +cn = remote.connect(box.cfg.listen) +--- +... +cn.space[space.id] ~= nil +--- +- true +... +cn.space.net_box_test_space ~= nil +--- +- true +... +cn.space.net_box_test_space ~= nil +--- +- true +... +cn.space.net_box_test_space.index ~= nil +--- +- true +... +cn.space.net_box_test_space.index.primary ~= nil +--- +- true +... +cn.space.net_box_test_space.index[space.index.primary.id] ~= nil +--- +- true +... +cn.space.net_box_test_space:insert{234, 1,2,3} +--- +- [234, 1, 2, 3] +... +cn.space.net_box_test_space:replace{354, 1,2,4} +--- +- [354, 1, 2, 4] +... +cn.space.net_box_test_space.index.primary:min(354) +--- +- [354, 1, 2, 4] +... +cn.space.net_box_test_space.index.primary:max(234) +--- +- [234, 1, 2, 3] +... +cn.space.net_box_test_space.index.primary:count(354) +--- +- 1 +... +box.schema.user.create('netbox', { password = 'test' }) +--- +... +box.schema.user.grant('netbox', 'read,write', 'space', 'net_box_test_space') +--- +... +box.schema.user.grant('netbox', 'execute', 'universe') +--- +... +cn = remote.connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = 'test' }) +--- +... +cn.state +--- +- active +... +cn.error +--- +- null +... +cn:ping() +--- +- true +... +function ret_after(to) fiber.sleep(to) return {{to}} end +--- +... +cn:ping({timeout = 1.00}) +--- +- true +... +cn:ping({timeout = 1e-9}) +--- +- false +... +cn:ping() +--- +- true +... +remote_space = cn.space.net_box_test_space +--- +... +remote_pk = remote_space.index.primary +--- +... +remote_space:insert({0}, { timeout = 1.00 }) +--- +- [0] +... +remote_space:insert({1}, { timeout = 1e-9 }) +--- +- error: Timeout exceeded +... +remote_space:insert({2}) +--- +- [2] +... +remote_space:replace({0}, { timeout = 1e-9 }) +--- +- error: Timeout exceeded +... +remote_space:replace({1}) +--- +- [1] +... +remote_space:replace({2}, { timeout = 1.00 }) +--- +- [2] +... +remote_space:upsert({3}, {}, { timeout = 1e-9 }) +--- +- error: Timeout exceeded +... +remote_space:upsert({4}, {}) +--- +... +remote_space:upsert({5}, {}, { timeout = 1.00 }) +--- +... +remote_space:upsert({3}, {}) +--- +... +remote_space:update({3}, {}, { timeout = 1e-9 }) +--- +- error: Timeout exceeded +... +remote_space:update({4}, {}) +--- +- [4] +... +remote_space:update({5}, {}, { timeout = 1.00 }) +--- +- [5] +... +remote_space:update({3}, {}) +--- +- [3] +... +remote_pk:update({5}, {}, { timeout = 1e-9 }) +--- +- error: Timeout exceeded +... +remote_pk:update({4}, {}) +--- +- [4] +... +remote_pk:update({3}, {}, { timeout = 1.00 }) +--- +- [3] +... +remote_pk:update({5}, {}) +--- +- [5] +... +remote_space:get({0}) +--- +- [0] +... +remote_space:get({1}, { timeout = 1.00 }) +--- +- [1] +... +remote_space:get({2}, { timeout = 1e-9 }) +--- +- error: Timeout exceeded +... +remote_pk:get({3}, { timeout = 1e-9 }) +--- +- error: Timeout exceeded +... +remote_pk:get({4}) +--- +- [4] +... +remote_pk:get({5}, { timeout = 1.00 }) +--- +- [5] +... +remote_space:select({2}, { timeout = 1e-9 }) +--- +- error: Timeout exceeded +... +remote_space:select({2}, { timeout = 1.00 }) +--- +- - [2] +... +remote_space:select({2}) +--- +- - [2] +... +remote_pk:select({2}, { timeout = 1.00 }) +--- +- - [2] +... +remote_pk:select({2}, { timeout = 1e-9 }) +--- +- error: Timeout exceeded +... +remote_pk:select({2}) +--- +- - [2] +... +remote_space:select({5}, { timeout = 1.00, iterator = 'LE', limit = 5 }) +--- +- - [5] + - [4] + - [3] + - [2] + - [1] +... +remote_space:select({5}, { iterator = 'LE', limit = 5}) +--- +- - [5] + - [4] + - [3] + - [2] + - [1] +... +remote_space:select({5}, { timeout = 1e-9, iterator = 'LE', limit = 5 }) +--- +- error: Timeout exceeded +... +remote_pk:select({2}, { timeout = 1.00, iterator = 'LE', limit = 5 }) +--- +- - [2] + - [1] + - [0] +... +remote_pk:select({2}, { iterator = 'LE', limit = 5}) +--- +- - [2] + - [1] + - [0] +... +remote_pk:select({2}, { timeout = 1e-9, iterator = 'LE', limit = 5 }) +--- +- error: Timeout exceeded +... +remote_pk:count({2}, { timeout = 1.00}) +--- +- 1 +... +remote_pk:count({2}, { timeout = 1e-9}) +--- +- error: Timeout exceeded +... +remote_pk:count({2}) +--- +- 1 +... +remote_pk:count({2}, { timeout = 1.00, iterator = 'LE' }) +--- +- 3 +... +remote_pk:count({2}, { iterator = 'LE'}) +--- +- 3 +... +remote_pk:count({2}, { timeout = 1e-9, iterator = 'LE' }) +--- +- error: Timeout exceeded +... +remote_pk:min(nil, { timeout = 1.00 }) +--- +- [0] +... +remote_pk:min(nil, { timeout = 1e-9 }) +--- +- error: Timeout exceeded +... +remote_pk:min(nil) +--- +- [0] +... +remote_pk:min({0}, { timeout = 1e-9 }) +--- +- error: Timeout exceeded +... +remote_pk:min({1}) +--- +- [1] +... +remote_pk:min({2}, { timeout = 1.00 }) +--- +- [2] +... +remote_pk:max(nil) +--- +- [354, 1, 2, 4] +... +remote_pk:max(nil, { timeout = 1e-9 }) +--- +- error: Timeout exceeded +... +remote_pk:max(nil, { timeout = 1.00 }) +--- +- [354, 1, 2, 4] +... +remote_pk:max({0}, { timeout = 1.00 }) +--- +- [0] +... +remote_pk:max({1}, { timeout = 1e-9 }) +--- +- error: Timeout exceeded +... +remote_pk:max({2}) +--- +- [2] +... +-- +-- gh-3262: index:count() inconsistent results +-- +test_run:cmd("setopt delimiter ';'") +--- +- true +... +function do_count_test(min, it) + local r1 = remote_pk:count(min, {iterator = it} ) + local r2 = box.space.net_box_test_space.index.primary:count(min, {iterator = it} ) + local r3 = remote.self.space.net_box_test_space.index.primary:count(min, {iterator = it} ) + return r1 == r2 and r2 == r3 +end; +--- +... +data = remote_pk:select(); +--- +... +for _, v in pairs(data) do + local itrs = {'GE', 'GT', 'LE', 'LT' } + for _, it in pairs(itrs) do + assert(do_count_test(v[0], it) == true) + end +end; +--- +... +test_run:cmd("setopt delimiter ''"); +--- +- true +... +_ = remote_space:delete({0}, { timeout = 1e-9 }) +--- +- error: Timeout exceeded +... +_ = remote_pk:delete({0}, { timeout = 1.00 }) +--- +... +_ = remote_space:delete({1}, { timeout = 1.00 }) +--- +... +_ = remote_pk:delete({1}, { timeout = 1e-9 }) +--- +- error: Timeout exceeded +... +_ = remote_space:delete({2}, { timeout = 1e-9 }) +--- +- error: Timeout exceeded +... +_ = remote_pk:delete({2}) +--- +... +_ = remote_pk:delete({3}) +--- +... +_ = remote_pk:delete({4}) +--- +... +_ = remote_pk:delete({5}) +--- +... +remote_space:get(0) +--- +... +remote_space:get(1) +--- +... +remote_space:get(2) +--- +... +remote_space = nil +--- +... +cn:call('ret_after', {0.01}, { timeout = 1.00 }) +--- +- [[0.01]] +... +cn:call('ret_after', {1.00}, { timeout = 1e-9 }) +--- +- error: Timeout exceeded +... +cn:eval('return ret_after(...)', {0.01}, { timeout = 1.00 }) +--- +- [[0.01]] +... +cn:eval('return ret_after(...)', {1.00}, { timeout = 1e-9 }) +--- +- error: Timeout exceeded +... +-- +-- :timeout() +-- @deprecated since 1.7.4 +-- +cn:timeout(1).space.net_box_test_space.index.primary:select{234} +--- +- - [234, 1, 2, 3] +... +cn:call('ret_after', {.01}) +--- +- [[0.01]] +... +cn:timeout(1):call('ret_after', {.01}) +--- +- [[0.01]] +... +cn:timeout(.01):call('ret_after', {1}) +--- +- error: Timeout exceeded +... +cn = remote:timeout(0.0000000001):connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123' }) +--- +... +cn:close() +--- +... +cn = remote:timeout(1):connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123' }) +--- +... +remote.self:ping() +--- +- true +... +remote.self.space.net_box_test_space:select{234} +--- +- - [234, 1, 2, 3] +... +remote.self:timeout(123).space.net_box_test_space:select{234} +--- +- - [234, 1, 2, 3] +... +remote.self:is_connected() +--- +- true +... +remote.self:wait_connected() +--- +- true +... +cn:close() +--- +... +-- cleanup database after tests +space:drop() +--- +... +box.schema.user.revoke('guest', 'execute', 'universe') +--- +... diff --git a/test/box/net.box_count_inconsistent_gh-3262.test.lua b/test/box/net.box_count_inconsistent_gh-3262.test.lua new file mode 100644 index 000000000..e84e85cf3 --- /dev/null +++ b/test/box/net.box_count_inconsistent_gh-3262.test.lua @@ -0,0 +1,182 @@ +remote = require 'net.box' +fiber = require 'fiber' +test_run = require('test_run').new() + +LISTEN = require('uri').parse(box.cfg.listen) +space = box.schema.space.create('net_box_test_space') +index = space:create_index('primary', { type = 'tree' }) + +box.schema.user.grant('guest', 'read,write', 'space', 'net_box_test_space') +box.schema.user.grant('guest', 'execute', 'universe') + +cn = remote.connect(box.cfg.listen) +cn.space[space.id] ~= nil +cn.space.net_box_test_space ~= nil +cn.space.net_box_test_space ~= nil +cn.space.net_box_test_space.index ~= nil +cn.space.net_box_test_space.index.primary ~= nil +cn.space.net_box_test_space.index[space.index.primary.id] ~= nil +cn.space.net_box_test_space:insert{234, 1,2,3} +cn.space.net_box_test_space:replace{354, 1,2,4} +cn.space.net_box_test_space.index.primary:min(354) +cn.space.net_box_test_space.index.primary:max(234) +cn.space.net_box_test_space.index.primary:count(354) + +box.schema.user.create('netbox', { password = 'test' }) +box.schema.user.grant('netbox', 'read,write', 'space', 'net_box_test_space') +box.schema.user.grant('netbox', 'execute', 'universe') +cn = remote.connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = 'test' }) +cn.state +cn.error +cn:ping() + +function ret_after(to) fiber.sleep(to) return {{to}} end + +cn:ping({timeout = 1.00}) +cn:ping({timeout = 1e-9}) +cn:ping() + +remote_space = cn.space.net_box_test_space +remote_pk = remote_space.index.primary + +remote_space:insert({0}, { timeout = 1.00 }) +remote_space:insert({1}, { timeout = 1e-9 }) +remote_space:insert({2}) + +remote_space:replace({0}, { timeout = 1e-9 }) +remote_space:replace({1}) +remote_space:replace({2}, { timeout = 1.00 }) + +remote_space:upsert({3}, {}, { timeout = 1e-9 }) +remote_space:upsert({4}, {}) +remote_space:upsert({5}, {}, { timeout = 1.00 }) +remote_space:upsert({3}, {}) + +remote_space:update({3}, {}, { timeout = 1e-9 }) +remote_space:update({4}, {}) +remote_space:update({5}, {}, { timeout = 1.00 }) +remote_space:update({3}, {}) + +remote_pk:update({5}, {}, { timeout = 1e-9 }) +remote_pk:update({4}, {}) +remote_pk:update({3}, {}, { timeout = 1.00 }) +remote_pk:update({5}, {}) + +remote_space:get({0}) +remote_space:get({1}, { timeout = 1.00 }) +remote_space:get({2}, { timeout = 1e-9 }) + +remote_pk:get({3}, { timeout = 1e-9 }) +remote_pk:get({4}) +remote_pk:get({5}, { timeout = 1.00 }) + +remote_space:select({2}, { timeout = 1e-9 }) +remote_space:select({2}, { timeout = 1.00 }) +remote_space:select({2}) + +remote_pk:select({2}, { timeout = 1.00 }) +remote_pk:select({2}, { timeout = 1e-9 }) +remote_pk:select({2}) + +remote_space:select({5}, { timeout = 1.00, iterator = 'LE', limit = 5 }) +remote_space:select({5}, { iterator = 'LE', limit = 5}) +remote_space:select({5}, { timeout = 1e-9, iterator = 'LE', limit = 5 }) + +remote_pk:select({2}, { timeout = 1.00, iterator = 'LE', limit = 5 }) +remote_pk:select({2}, { iterator = 'LE', limit = 5}) +remote_pk:select({2}, { timeout = 1e-9, iterator = 'LE', limit = 5 }) + +remote_pk:count({2}, { timeout = 1.00}) +remote_pk:count({2}, { timeout = 1e-9}) +remote_pk:count({2}) + +remote_pk:count({2}, { timeout = 1.00, iterator = 'LE' }) +remote_pk:count({2}, { iterator = 'LE'}) +remote_pk:count({2}, { timeout = 1e-9, iterator = 'LE' }) + +remote_pk:min(nil, { timeout = 1.00 }) +remote_pk:min(nil, { timeout = 1e-9 }) +remote_pk:min(nil) + +remote_pk:min({0}, { timeout = 1e-9 }) +remote_pk:min({1}) +remote_pk:min({2}, { timeout = 1.00 }) + +remote_pk:max(nil) +remote_pk:max(nil, { timeout = 1e-9 }) +remote_pk:max(nil, { timeout = 1.00 }) + +remote_pk:max({0}, { timeout = 1.00 }) +remote_pk:max({1}, { timeout = 1e-9 }) +remote_pk:max({2}) + +-- +-- gh-3262: index:count() inconsistent results +-- +test_run:cmd("setopt delimiter ';'") + +function do_count_test(min, it) + local r1 = remote_pk:count(min, {iterator = it} ) + local r2 = box.space.net_box_test_space.index.primary:count(min, {iterator = it} ) + local r3 = remote.self.space.net_box_test_space.index.primary:count(min, {iterator = it} ) + return r1 == r2 and r2 == r3 +end; + +data = remote_pk:select(); + +for _, v in pairs(data) do + local itrs = {'GE', 'GT', 'LE', 'LT' } + for _, it in pairs(itrs) do + assert(do_count_test(v[0], it) == true) + end +end; + +test_run:cmd("setopt delimiter ''"); + +_ = remote_space:delete({0}, { timeout = 1e-9 }) +_ = remote_pk:delete({0}, { timeout = 1.00 }) +_ = remote_space:delete({1}, { timeout = 1.00 }) +_ = remote_pk:delete({1}, { timeout = 1e-9 }) +_ = remote_space:delete({2}, { timeout = 1e-9 }) +_ = remote_pk:delete({2}) +_ = remote_pk:delete({3}) +_ = remote_pk:delete({4}) +_ = remote_pk:delete({5}) + +remote_space:get(0) +remote_space:get(1) +remote_space:get(2) + +remote_space = nil + +cn:call('ret_after', {0.01}, { timeout = 1.00 }) +cn:call('ret_after', {1.00}, { timeout = 1e-9 }) + +cn:eval('return ret_after(...)', {0.01}, { timeout = 1.00 }) +cn:eval('return ret_after(...)', {1.00}, { timeout = 1e-9 }) + +-- +-- :timeout() +-- @deprecated since 1.7.4 +-- + +cn:timeout(1).space.net_box_test_space.index.primary:select{234} +cn:call('ret_after', {.01}) +cn:timeout(1):call('ret_after', {.01}) +cn:timeout(.01):call('ret_after', {1}) + +cn = remote:timeout(0.0000000001):connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123' }) +cn:close() +cn = remote:timeout(1):connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123' }) + +remote.self:ping() +remote.self.space.net_box_test_space:select{234} +remote.self:timeout(123).space.net_box_test_space:select{234} +remote.self:is_connected() +remote.self:wait_connected() + +cn:close() +-- cleanup database after tests +space:drop() + +box.schema.user.revoke('guest', 'execute', 'universe') diff --git a/test/box/net.box_discard_gh-3107.result b/test/box/net.box_discard_gh-3107.result new file mode 100644 index 000000000..3498c9d5a --- /dev/null +++ b/test/box/net.box_discard_gh-3107.result @@ -0,0 +1,119 @@ +fiber = require 'fiber' +--- +... +net = require('net.box') +--- +... +-- +-- gh-3107: fiber-async netbox. +-- +cond = nil +--- +... +box.schema.func.create('long_function') +--- +... +box.schema.user.grant('guest', 'execute', 'function', 'long_function') +--- +... +function long_function(...) cond = fiber.cond() cond:wait() return ... end +--- +... +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end +--- +... +s = box.schema.create_space('test') +--- +... +pk = s:create_index('pk') +--- +... +s:replace{1} +--- +- [1] +... +s:replace{2} +--- +- [2] +... +s:replace{3} +--- +- [3] +... +s:replace{4} +--- +- [4] +... +c = net:connect(box.cfg.listen) +--- +... +-- +-- Ensure a request can be finalized from non-caller fibers. +-- +future = c:call('long_function', {1, 2, 3}, {is_async = true}) +--- +... +ret = {} +--- +... +count = 0 +--- +... +for i = 1, 10 do fiber.create(function() ret[i] = future:wait_result(1000) count = count + 1 end) end +--- +... +future:wait_result(0.01) -- Must fail on timeout. +--- +- null +- Timeout exceeded +... +finalize_long() +--- +... +while count ~= 10 do fiber.sleep(0.1) end +--- +... +ret +--- +- - &0 [1, 2, 3] + - *0 + - *0 + - *0 + - *0 + - *0 + - *0 + - *0 + - *0 + - *0 +... +-- +-- Test discard. +-- +future = c:call('long_function', {1, 2, 3}, {is_async = true}) +--- +... +future:discard() +--- +... +finalize_long() +--- +... +future:result() +--- +- null +- Response is discarded +... +future:wait_result(100) +--- +- null +- Response is discarded +... +box.schema.func.drop('long_function') +--- +... +c:close() +--- +... +s:drop() +--- +... diff --git a/test/box/net.box_discard_gh-3107.test.lua b/test/box/net.box_discard_gh-3107.test.lua new file mode 100644 index 000000000..71f08a411 --- /dev/null +++ b/test/box/net.box_discard_gh-3107.test.lua @@ -0,0 +1,44 @@ +fiber = require 'fiber' +net = require('net.box') + +-- +-- gh-3107: fiber-async netbox. +-- +cond = nil +box.schema.func.create('long_function') +box.schema.user.grant('guest', 'execute', 'function', 'long_function') +function long_function(...) cond = fiber.cond() cond:wait() return ... end +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end +s = box.schema.create_space('test') +pk = s:create_index('pk') +s:replace{1} +s:replace{2} +s:replace{3} +s:replace{4} +c = net:connect(box.cfg.listen) + +-- +-- Ensure a request can be finalized from non-caller fibers. +-- +future = c:call('long_function', {1, 2, 3}, {is_async = true}) +ret = {} +count = 0 +for i = 1, 10 do fiber.create(function() ret[i] = future:wait_result(1000) count = count + 1 end) end +future:wait_result(0.01) -- Must fail on timeout. +finalize_long() +while count ~= 10 do fiber.sleep(0.1) end +ret + +-- +-- Test discard. +-- +future = c:call('long_function', {1, 2, 3}, {is_async = true}) +future:discard() +finalize_long() +future:result() +future:wait_result(100) + +box.schema.func.drop('long_function') + +c:close() +s:drop() diff --git a/test/box/net.box_disconnect_gh-3859.result b/test/box/net.box_disconnect_gh-3859.result new file mode 100644 index 000000000..eae259740 --- /dev/null +++ b/test/box/net.box_disconnect_gh-3859.result @@ -0,0 +1,113 @@ +fiber = require 'fiber' +--- +... +test_run = require('test_run').new() +--- +... +net = require('net.box') +--- +... +test_run:cmd('create server connecter with script = "box/proxy.lua"') +--- +- true +... +box.schema.func.create('fast_call') +--- +... +box.schema.func.create('long_call') +--- +... +box.schema.func.create('wait_signal') +--- +... +box.schema.user.grant('guest', 'execute', 'function', 'fast_call') +--- +... +box.schema.user.grant('guest', 'execute', 'function', 'long_call') +--- +... +box.schema.user.grant('guest', 'execute', 'function', 'wait_signal') +--- +... +c = net.connect(box.cfg.listen) +--- +... +disconnected = false +--- +... +function on_disconnect() disconnected = true end +--- +... +-- Make sure all dangling connections are collected so +-- that on_disconnect trigger isn't called spuriously. +collectgarbage('collect') +--- +- 0 +... +fiber.sleep(0) +--- +... +box.session.on_disconnect(on_disconnect) == on_disconnect +--- +- true +... +-- +-- gh-3859: on_disconnect is called only after all requests are +-- processed, but should be called right after disconnect and +-- only once. +-- +ch1 = fiber.channel(1) +--- +... +ch2 = fiber.channel(1) +--- +... +function wait_signal() ch1:put(true) ch2:get() end +--- +... +_ = fiber.create(function() c:call('wait_signal') end) +--- +... +ch1:get() +--- +- true +... +c:close() +--- +... +fiber.sleep(0) +--- +... +while disconnected == false do fiber.sleep(0.01) end +--- +... +disconnected -- true +--- +- true +... +disconnected = nil +--- +... +ch2:put(true) +--- +- true +... +fiber.sleep(0) +--- +... +disconnected -- nil, on_disconnect is not called second time. +--- +- null +... +box.session.on_disconnect(nil, on_disconnect) +--- +... +box.schema.func.drop('long_call') +--- +... +box.schema.func.drop('fast_call') +--- +... +box.schema.func.drop('wait_signal') +--- +... diff --git a/test/box/net.box_disconnect_gh-3859.test.lua b/test/box/net.box_disconnect_gh-3859.test.lua new file mode 100644 index 000000000..e0ec1a8ea --- /dev/null +++ b/test/box/net.box_disconnect_gh-3859.test.lua @@ -0,0 +1,50 @@ +fiber = require 'fiber' +test_run = require('test_run').new() +net = require('net.box') + +test_run:cmd('create server connecter with script = "box/proxy.lua"') + +box.schema.func.create('fast_call') +box.schema.func.create('long_call') +box.schema.func.create('wait_signal') +box.schema.user.grant('guest', 'execute', 'function', 'fast_call') +box.schema.user.grant('guest', 'execute', 'function', 'long_call') +box.schema.user.grant('guest', 'execute', 'function', 'wait_signal') +c = net.connect(box.cfg.listen) + +disconnected = false +function on_disconnect() disconnected = true end + +-- Make sure all dangling connections are collected so +-- that on_disconnect trigger isn't called spuriously. +collectgarbage('collect') +fiber.sleep(0) + +box.session.on_disconnect(on_disconnect) == on_disconnect + +-- +-- gh-3859: on_disconnect is called only after all requests are +-- processed, but should be called right after disconnect and +-- only once. +-- +ch1 = fiber.channel(1) +ch2 = fiber.channel(1) +function wait_signal() ch1:put(true) ch2:get() end +_ = fiber.create(function() c:call('wait_signal') end) +ch1:get() + +c:close() +fiber.sleep(0) +while disconnected == false do fiber.sleep(0.01) end +disconnected -- true +disconnected = nil + +ch2:put(true) +fiber.sleep(0) +disconnected -- nil, on_disconnect is not called second time. + +box.session.on_disconnect(nil, on_disconnect) + +box.schema.func.drop('long_call') +box.schema.func.drop('fast_call') +box.schema.func.drop('wait_signal') diff --git a/test/box/net.box_fiber-async_gh-3107.result b/test/box/net.box_fiber-async_gh-3107.result new file mode 100644 index 000000000..aaaca351a --- /dev/null +++ b/test/box/net.box_fiber-async_gh-3107.result @@ -0,0 +1,115 @@ +fiber = require 'fiber' +--- +... +net = require('net.box') +--- +... +-- +-- gh-3107: fiber-async netbox. +-- +cond = nil +--- +... +box.schema.func.create('long_function') +--- +... +box.schema.user.grant('guest', 'execute', 'function', 'long_function') +--- +... +function long_function(...) cond = fiber.cond() cond:wait() return ... end +--- +... +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end +--- +... +s = box.schema.create_space('test') +--- +... +pk = s:create_index('pk') +--- +... +s:replace{1} +--- +- [1] +... +s:replace{2} +--- +- [2] +... +s:replace{3} +--- +- [3] +... +s:replace{4} +--- +- [4] +... +c = net:connect(box.cfg.listen) +--- +... +-- +-- Check long connections, multiple wait_result(). +-- +future = c:call('long_function', {1, 2, 3}, {is_async = true}) +--- +... +future:result() +--- +- null +- Response is not ready +... +future:is_ready() +--- +- false +... +future:wait_result(0.01) -- Must fail on timeout. +--- +- null +- Timeout exceeded +... +finalize_long() +--- +... +ret = future:wait_result(100) +--- +... +future:is_ready() +--- +- true +... +-- Any timeout is ok - response is received already. +future:wait_result(0) +--- +- [1, 2, 3] +... +future:wait_result(0.01) +--- +- [1, 2, 3] +... +ret +--- +- [1, 2, 3] +... +_, err = pcall(future.wait_result, future, true) +--- +... +err:find('Usage') ~= nil +--- +- true +... +_, err = pcall(future.wait_result, future, '100') +--- +... +err:find('Usage') ~= nil +--- +- true +... +box.schema.func.drop('long_function') +--- +... +c:close() +--- +... +s:drop() +--- +... diff --git a/test/box/net.box_fiber-async_gh-3107.test.lua b/test/box/net.box_fiber-async_gh-3107.test.lua new file mode 100644 index 000000000..d23f368cb --- /dev/null +++ b/test/box/net.box_fiber-async_gh-3107.test.lua @@ -0,0 +1,42 @@ +fiber = require 'fiber' +net = require('net.box') + +-- +-- gh-3107: fiber-async netbox. +-- +cond = nil +box.schema.func.create('long_function') +box.schema.user.grant('guest', 'execute', 'function', 'long_function') +function long_function(...) cond = fiber.cond() cond:wait() return ... end +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end +s = box.schema.create_space('test') +pk = s:create_index('pk') +s:replace{1} +s:replace{2} +s:replace{3} +s:replace{4} +c = net:connect(box.cfg.listen) +-- +-- Check long connections, multiple wait_result(). +-- +future = c:call('long_function', {1, 2, 3}, {is_async = true}) +future:result() +future:is_ready() +future:wait_result(0.01) -- Must fail on timeout. +finalize_long() +ret = future:wait_result(100) +future:is_ready() +-- Any timeout is ok - response is received already. +future:wait_result(0) +future:wait_result(0.01) +ret + +_, err = pcall(future.wait_result, future, true) +err:find('Usage') ~= nil +_, err = pcall(future.wait_result, future, '100') +err:find('Usage') ~= nil + +box.schema.func.drop('long_function') + +c:close() +s:drop() diff --git a/test/box/net.box_field_names_gh-2978.result b/test/box/net.box_field_names_gh-2978.result new file mode 100644 index 000000000..2b6ea9c44 --- /dev/null +++ b/test/box/net.box_field_names_gh-2978.result @@ -0,0 +1,101 @@ +net = require('net.box') +--- +... +-- +-- gh-2978: field names for tuples received from netbox. +-- +_ = box.schema.create_space("named", {format = {{name = "id"}, {name="abc"}}}) +--- +... +_ = box.space.named:create_index('id', {parts = {{1, 'unsigned'}}}) +--- +... +box.space.named:insert({1, 1}) +--- +- [1, 1] +... +box.schema.user.grant('guest', 'read, write, execute', 'space') +--- +... +cn = net.connect(box.cfg.listen) +--- +... +s = cn.space.named +--- +... +s:get{1}.id +--- +- 1 +... +s:get{1}:tomap() +--- +- 1: 1 + 2: 1 + abc: 1 + id: 1 +... +s:insert{2,3}:tomap() +--- +- 1: 2 + 2: 3 + abc: 3 + id: 2 +... +s:replace{2,14}:tomap() +--- +- 1: 2 + 2: 14 + abc: 14 + id: 2 +... +s:update(1, {{'+', 2, 10}}):tomap() +--- +- 1: 1 + 2: 11 + abc: 11 + id: 1 +... +s:select()[1]:tomap() +--- +- 1: 1 + 2: 11 + abc: 11 + id: 1 +... +s:delete({2}):tomap() +--- +- 1: 2 + 2: 14 + abc: 14 + id: 2 +... +-- Check that formats changes after reload. +box.space.named:format({{name = "id2"}, {name="abc2"}}) +--- +... +s:select()[1]:tomap() +--- +- 1: 1 + 2: 11 + abc: 11 + id: 1 +... +cn:reload_schema() +--- +... +s:select()[1]:tomap() +--- +- 1: 1 + 2: 11 + id2: 1 + abc2: 11 +... +cn:close() +--- +... +box.space.named:drop() +--- +... +box.schema.user.revoke('guest', 'read, write, execute', 'space') +--- +... diff --git a/test/box/net.box_field_names_gh-2978.test.lua b/test/box/net.box_field_names_gh-2978.test.lua new file mode 100644 index 000000000..a5dccf16a --- /dev/null +++ b/test/box/net.box_field_names_gh-2978.test.lua @@ -0,0 +1,29 @@ +net = require('net.box') + +-- +-- gh-2978: field names for tuples received from netbox. +-- +_ = box.schema.create_space("named", {format = {{name = "id"}, {name="abc"}}}) +_ = box.space.named:create_index('id', {parts = {{1, 'unsigned'}}}) +box.space.named:insert({1, 1}) +box.schema.user.grant('guest', 'read, write, execute', 'space') +cn = net.connect(box.cfg.listen) + +s = cn.space.named +s:get{1}.id +s:get{1}:tomap() +s:insert{2,3}:tomap() +s:replace{2,14}:tomap() +s:update(1, {{'+', 2, 10}}):tomap() +s:select()[1]:tomap() +s:delete({2}):tomap() + +-- Check that formats changes after reload. +box.space.named:format({{name = "id2"}, {name="abc2"}}) +s:select()[1]:tomap() +cn:reload_schema() +s:select()[1]:tomap() + +cn:close() +box.space.named:drop() +box.schema.user.revoke('guest', 'read, write, execute', 'space') diff --git a/test/box/net.box_get_connection_object.result b/test/box/net.box_get_connection_object.result new file mode 100644 index 000000000..f461477ed --- /dev/null +++ b/test/box/net.box_get_connection_object.result @@ -0,0 +1,40 @@ +net = require('net.box') +--- +... +-- +-- Check that it's possible to get connection object form net.box space +-- +space = box.schema.space.create('test', {format={{name="id", type="unsigned"}}}) +--- +... +space ~= nil +--- +- true +... +_ = box.space.test:create_index('primary') +--- +... +box.schema.user.grant('guest','read,write,execute','space', 'test') +--- +... +c = net.connect(box.cfg.listen) +--- +... +c:ping() +--- +- true +... +c.space.test ~= nil +--- +- true +... +c.space.test.connection == c +--- +- true +... +box.schema.user.revoke('guest','read,write,execute','space', 'test') +--- +... +c:close() +--- +... diff --git a/test/box/net.box_get_connection_object.test.lua b/test/box/net.box_get_connection_object.test.lua new file mode 100644 index 000000000..71ed110b9 --- /dev/null +++ b/test/box/net.box_get_connection_object.test.lua @@ -0,0 +1,19 @@ +net = require('net.box') + +-- +-- Check that it's possible to get connection object form net.box space +-- + +space = box.schema.space.create('test', {format={{name="id", type="unsigned"}}}) +space ~= nil +_ = box.space.test:create_index('primary') +box.schema.user.grant('guest','read,write,execute','space', 'test') + +c = net.connect(box.cfg.listen) + +c:ping() +c.space.test ~= nil + +c.space.test.connection == c +box.schema.user.revoke('guest','read,write,execute','space', 'test') +c:close() diff --git a/test/box/net.box_gibberish_gh-3900.result b/test/box/net.box_gibberish_gh-3900.result new file mode 100644 index 000000000..302c74c9f --- /dev/null +++ b/test/box/net.box_gibberish_gh-3900.result @@ -0,0 +1,31 @@ +test_run = require('test_run').new() +--- +... +LISTEN = require('uri').parse(box.cfg.listen) +--- +... +-- +-- gh-3900: tarantool can be crashed by sending gibberish to a +-- binary socket +-- +socket = require("socket") +--- +... +sock = socket.tcp_connect(LISTEN.host, LISTEN.service) +--- +... +data = string.fromhex("6783000000000000000000000000000000000000000000800000C8000000000000000000000000000000000000000000FFFF210100373208000000FFFF000055AAEB66486472530D02000000000010A0350001008000001000000000000000000000000000D05700") +--- +... +sock:write(data) +--- +- 104 +... +test_run:wait_log('default', 'ER_INVALID_MSGPACK: Invalid MsgPack %- packet body', nil, 10) +--- +- 'ER_INVALID_MSGPACK: Invalid MsgPack - packet body' +... +sock:close() +--- +- true +... diff --git a/test/box/net.box_gibberish_gh-3900.test.lua b/test/box/net.box_gibberish_gh-3900.test.lua new file mode 100644 index 000000000..7debfd4b3 --- /dev/null +++ b/test/box/net.box_gibberish_gh-3900.test.lua @@ -0,0 +1,13 @@ +test_run = require('test_run').new() +LISTEN = require('uri').parse(box.cfg.listen) + +-- +-- gh-3900: tarantool can be crashed by sending gibberish to a +-- binary socket +-- +socket = require("socket") +sock = socket.tcp_connect(LISTEN.host, LISTEN.service) +data = string.fromhex("6783000000000000000000000000000000000000000000800000C8000000000000000000000000000000000000000000FFFF210100373208000000FFFF000055AAEB66486472530D02000000000010A0350001008000001000000000000000000000000000D05700") +sock:write(data) +test_run:wait_log('default', 'ER_INVALID_MSGPACK: Invalid MsgPack %- packet body', nil, 10) +sock:close() diff --git a/test/box/net.box_huge_data_gh-983.result b/test/box/net.box_huge_data_gh-983.result new file mode 100644 index 000000000..e9b470e28 --- /dev/null +++ b/test/box/net.box_huge_data_gh-983.result @@ -0,0 +1,30 @@ +-- gh-983 selecting a lot of data crashes the server or hangs the +-- connection +-- gh-983 test case: iproto connection selecting a lot of data +_ = box.schema.space.create('test', { temporary = true }) +--- +... +_ = box.space.test:create_index('primary', {type = 'TREE', parts = {1,'unsigned'}}) +--- +... +data1k = "aaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhh" +--- +... +for i = 0,10000 do box.space.test:insert{i, data1k} end +--- +... +box.schema.user.grant('guest', 'read', 'space', 'test') +--- +... +net = require('net.box') +--- +... +c = net:connect(box.cfg.listen) +--- +... +r = c.space.test:select(nil, {limit=5000}) +--- +... +box.space.test:drop() +--- +... diff --git a/test/box/net.box_huge_data_gh-983.test.lua b/test/box/net.box_huge_data_gh-983.test.lua new file mode 100644 index 000000000..93df08834 --- /dev/null +++ b/test/box/net.box_huge_data_gh-983.test.lua @@ -0,0 +1,16 @@ +-- gh-983 selecting a lot of data crashes the server or hangs the +-- connection + +-- gh-983 test case: iproto connection selecting a lot of data +_ = box.schema.space.create('test', { temporary = true }) +_ = box.space.test:create_index('primary', {type = 'TREE', parts = {1,'unsigned'}}) + +data1k = "aaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhh" + +for i = 0,10000 do box.space.test:insert{i, data1k} end + +box.schema.user.grant('guest', 'read', 'space', 'test') +net = require('net.box') +c = net:connect(box.cfg.listen) +r = c.space.test:select(nil, {limit=5000}) +box.space.test:drop() diff --git a/test/box/net.box_incompatible_index-gh-1729.result b/test/box/net.box_incompatible_index-gh-1729.result new file mode 100644 index 000000000..1d9fa542e --- /dev/null +++ b/test/box/net.box_incompatible_index-gh-1729.result @@ -0,0 +1,99 @@ +test_run = require('test_run').new() +--- +... +net = require('net.box') +--- +... +test_run:cmd("push filter ".."'\\.lua.*:[0-9]+: ' to '.lua...\"]:<line>: '") +--- +- true +... +_ = box.schema.space.create('test') +--- +... +_ = box.space.test:create_index('primary', {type = 'TREE', parts = {1,'unsigned'}}) +--- +... +_ = box.space.test:create_index('covering', {type = 'TREE', parts = {1,'unsigned',3,'string',2,'unsigned'}}) +--- +... +_ = box.space.test:insert{1, 2, "string"} +--- +... +box.schema.user.grant('guest', 'read,write', 'space', 'test') +--- +... +c = net:connect(box.cfg.listen) +--- +... +-- gh-1729 net.box index metadata incompatible with local metadata +c.space.test.index.primary.parts +--- +- - type: unsigned + is_nullable: false + fieldno: 1 +... +c.space.test.index.covering.parts +--- +- - type: unsigned + is_nullable: false + fieldno: 1 + - type: string + is_nullable: false + fieldno: 3 + - type: unsigned + is_nullable: false + fieldno: 2 +... +box.space.test:drop() +--- +... +-- CALL vs CALL_16 in connect options +function echo(...) return ... end +--- +... +box.schema.user.grant('guest', 'execute', 'universe') +--- +... +c = net.connect(box.cfg.listen) +--- +... +c:call('echo', {42}) +--- +- 42 +... +c:eval('return echo(...)', {42}) +--- +- 42 +... +-- invalid arguments +c:call('echo', 42) +--- +- error: 'builtin/box/net_box.lua..."]:<line>: Use remote:call(func_name, {arg1, arg2, ...}, + opts) instead of remote:call(func_name, arg1, arg2, ...)' +... +c:eval('return echo(...)', 42) +--- +- error: 'builtin/box/net_box.lua..."]:<line>: Use remote:eval(expression, {arg1, arg2, ...}, + opts) instead of remote:eval(expression, arg1, arg2, ...)' +... +c:close() +--- +... +c = net.connect(box.cfg.listen, {call_16 = true}) +--- +... +c:call('echo', 42) +--- +- - [42] +... +c:eval('return echo(...)', 42) +--- +- 42 +... +c:close() +--- +... +box.schema.user.revoke('guest', 'execute', 'universe') +--- +... diff --git a/test/box/net.box_incompatible_index-gh-1729.test.lua b/test/box/net.box_incompatible_index-gh-1729.test.lua new file mode 100644 index 000000000..2d25b9017 --- /dev/null +++ b/test/box/net.box_incompatible_index-gh-1729.test.lua @@ -0,0 +1,33 @@ +test_run = require('test_run').new() +net = require('net.box') + +test_run:cmd("push filter ".."'\\.lua.*:[0-9]+: ' to '.lua...\"]:<line>: '") + +_ = box.schema.space.create('test') +_ = box.space.test:create_index('primary', {type = 'TREE', parts = {1,'unsigned'}}) +_ = box.space.test:create_index('covering', {type = 'TREE', parts = {1,'unsigned',3,'string',2,'unsigned'}}) +_ = box.space.test:insert{1, 2, "string"} +box.schema.user.grant('guest', 'read,write', 'space', 'test') +c = net:connect(box.cfg.listen) + +-- gh-1729 net.box index metadata incompatible with local metadata +c.space.test.index.primary.parts +c.space.test.index.covering.parts + +box.space.test:drop() + +-- CALL vs CALL_16 in connect options +function echo(...) return ... end +box.schema.user.grant('guest', 'execute', 'universe') +c = net.connect(box.cfg.listen) +c:call('echo', {42}) +c:eval('return echo(...)', {42}) +-- invalid arguments +c:call('echo', 42) +c:eval('return echo(...)', 42) +c:close() +c = net.connect(box.cfg.listen, {call_16 = true}) +c:call('echo', 42) +c:eval('return echo(...)', 42) +c:close() +box.schema.user.revoke('guest', 'execute', 'universe') diff --git a/test/box/net.box_incorrect_iterator_gh-841.result b/test/box/net.box_incorrect_iterator_gh-841.result new file mode 100644 index 000000000..4bdd1afa3 --- /dev/null +++ b/test/box/net.box_incorrect_iterator_gh-841.result @@ -0,0 +1,497 @@ +remote = require 'net.box' +--- +... +fiber = require 'fiber' +--- +... +test_run = require('test_run').new() +--- +... +test_run:cmd("push filter ".."'\\.lua.*:[0-9]+: ' to '.lua...\"]:<line>: '") +--- +- true +... +test_run:cmd("setopt delimiter ';'") +--- +- true +... +function x_select(cn, space_id, index_id, iterator, offset, limit, key, opts) + local ret = cn:_request('select', opts, nil, space_id, index_id, iterator, + offset, limit, key) + return ret +end +function x_fatal(cn) cn._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') end +test_run:cmd("setopt delimiter ''"); +--- +... +LISTEN = require('uri').parse(box.cfg.listen) +--- +... +space = box.schema.space.create('net_box_test_space') +--- +... +index = space:create_index('primary', { type = 'tree' }) +--- +... +function test_foo(a,b,c) return { {{ [a] = 1 }}, {{ [b] = 2 }}, c } end +--- +... +box.schema.user.grant('guest', 'read,write', 'space', 'net_box_test_space') +--- +... +box.schema.user.grant('guest', 'execute', 'universe') +--- +... +cn = remote.connect(box.cfg.listen) +--- +... +x_select(cn, space.id, space.index.primary.id, box.index.EQ, 0, 0xFFFFFFFF, 123) +--- +- [] +... +space:insert{123, 345} +--- +- [123, 345] +... +x_select(cn, space.id, space.index.primary.id, box.index.EQ, 0, 0, 123) +--- +- [] +... +x_select(cn, space.id, space.index.primary.id, box.index.EQ, 0, 1, 123) +--- +- - [123, 345] +... +x_select(cn, space.id, space.index.primary.id, box.index.EQ, 1, 1, 123) +--- +- [] +... +cn.space[space.id] ~= nil +--- +- true +... +cn.space.net_box_test_space ~= nil +--- +- true +... +cn.space.net_box_test_space ~= nil +--- +- true +... +cn.space.net_box_test_space.index ~= nil +--- +- true +... +cn.space.net_box_test_space.index.primary ~= nil +--- +- true +... +cn.space.net_box_test_space.index[space.index.primary.id] ~= nil +--- +- true +... +cn.space.net_box_test_space.index.primary:select(123) +--- +- - [123, 345] +... +cn.space.net_box_test_space.index.primary:select(123, { limit = 0 }) +--- +- [] +... +cn.space.net_box_test_space.index.primary:select(nil, { limit = 1, }) +--- +- - [123, 345] +... +cn.space.net_box_test_space:insert{234, 1,2,3} +--- +- [234, 1, 2, 3] +... +cn.space.net_box_test_space:insert{234, 1,2,3} +--- +- error: Duplicate key exists in unique index 'primary' in space 'net_box_test_space' +... +cn.space.net_box_test_space.insert{234, 1,2,3} +--- +- error: 'builtin/box/schema.lua..."]:<line>: Use space:insert(...) instead of space.insert(...)' +... +cn.space.net_box_test_space:replace{354, 1,2,3} +--- +- [354, 1, 2, 3] +... +cn.space.net_box_test_space:replace{354, 1,2,4} +--- +- [354, 1, 2, 4] +... +cn.space.net_box_test_space:select{123} +--- +- - [123, 345] +... +space:select({123}, { iterator = 'GE' }) +--- +- - [123, 345] + - [234, 1, 2, 3] + - [354, 1, 2, 4] +... +cn.space.net_box_test_space:select({123}, { iterator = 'GE' }) +--- +- - [123, 345] + - [234, 1, 2, 3] + - [354, 1, 2, 4] +... +cn.space.net_box_test_space:select({123}, { iterator = 'GT' }) +--- +- - [234, 1, 2, 3] + - [354, 1, 2, 4] +... +cn.space.net_box_test_space:select({123}, { iterator = 'GT', limit = 1 }) +--- +- - [234, 1, 2, 3] +... +cn.space.net_box_test_space:select({123}, { iterator = 'GT', limit = 1, offset = 1 }) +--- +- - [354, 1, 2, 4] +... +cn.space.net_box_test_space:select{123} +--- +- - [123, 345] +... +cn.space.net_box_test_space:update({123}, { { '+', 2, 1 } }) +--- +- [123, 346] +... +cn.space.net_box_test_space:update(123, { { '+', 2, 1 } }) +--- +- [123, 347] +... +cn.space.net_box_test_space:select{123} +--- +- - [123, 347] +... +cn.space.net_box_test_space:insert(cn.space.net_box_test_space:get{123}:update{ { '=', 1, 2 } }) +--- +- [2, 347] +... +cn.space.net_box_test_space:delete{123} +--- +- [123, 347] +... +cn.space.net_box_test_space:select{2} +--- +- - [2, 347] +... +cn.space.net_box_test_space:select({234}, { iterator = 'LT' }) +--- +- - [2, 347] +... +cn.space.net_box_test_space:update({1}, { { '+', 2, 2 } }) +--- +... +cn.space.net_box_test_space:delete{1} +--- +... +cn.space.net_box_test_space:delete{2} +--- +- [2, 347] +... +cn.space.net_box_test_space:delete{2} +--- +... +-- test one-based indexing in splice operation (see update.test.lua) +cn.space.net_box_test_space:replace({10, 'abcde'}) +--- +- [10, 'abcde'] +... +cn.space.net_box_test_space:update(10, {{':', 2, 0, 0, '!'}}) +--- +- error: 'SPLICE error on field 2: offset is out of bound' +... +cn.space.net_box_test_space:update(10, {{':', 2, 1, 0, '('}}) +--- +- [10, '(abcde'] +... +cn.space.net_box_test_space:update(10, {{':', 2, 2, 0, '({'}}) +--- +- [10, '(({abcde'] +... +cn.space.net_box_test_space:update(10, {{':', 2, -1, 0, ')'}}) +--- +- [10, '(({abcde)'] +... +cn.space.net_box_test_space:update(10, {{':', 2, -2, 0, '})'}}) +--- +- [10, '(({abcde}))'] +... +cn.space.net_box_test_space:delete{10} +--- +- [10, '(({abcde}))'] +... +cn.space.net_box_test_space:select({}, { iterator = 'ALL' }) +--- +- - [234, 1, 2, 3] + - [354, 1, 2, 4] +... +-- gh-841: net.box uses incorrect iterator type for select with no arguments +cn.space.net_box_test_space:select() +--- +- - [234, 1, 2, 3] + - [354, 1, 2, 4] +... +cn.space.net_box_test_space.index.primary:min() +--- +- [234, 1, 2, 3] +... +cn.space.net_box_test_space.index.primary:min(354) +--- +- [354, 1, 2, 4] +... +cn.space.net_box_test_space.index.primary:max() +--- +- [354, 1, 2, 4] +... +cn.space.net_box_test_space.index.primary:max(234) +--- +- [234, 1, 2, 3] +... +cn.space.net_box_test_space.index.primary:count() +--- +- 2 +... +cn.space.net_box_test_space.index.primary:count(354) +--- +- 1 +... +cn.space.net_box_test_space:get(354) +--- +- [354, 1, 2, 4] +... +-- reconnects after errors +box.schema.user.revoke('guest', 'execute', 'universe') +--- +... +box.schema.func.create('test_foo') +--- +... +box.schema.user.grant('guest', 'execute', 'function', 'test_foo') +--- +... +-- -- 1. no reconnect +x_fatal(cn) +--- +... +cn.state +--- +- error +... +cn:ping() +--- +- false +... +cn:call('test_foo') +--- +- error: Peer closed +... +cn:wait_state('active') +--- +- false +... +-- -- 2 reconnect +cn = remote.connect(LISTEN.host, LISTEN.service, { reconnect_after = .1 }) +--- +... +cn.space ~= nil +--- +- true +... +cn.space.net_box_test_space:select({}, { iterator = 'ALL' }) +--- +- - [234, 1, 2, 3] + - [354, 1, 2, 4] +... +x_fatal(cn) +--- +... +cn:wait_connected() +--- +- true +... +cn:wait_state('active') +--- +- true +... +cn:wait_state({active=true}) +--- +- true +... +cn:ping() +--- +- true +... +cn.state +--- +- active +... +cn.space.net_box_test_space:select({}, { iterator = 'ALL' }) +--- +- - [234, 1, 2, 3] + - [354, 1, 2, 4] +... +x_fatal(cn) +--- +... +x_select(cn, space.id, 0, box.index.ALL, 0, 0xFFFFFFFF, {}) +--- +- - [234, 1, 2, 3] + - [354, 1, 2, 4] +... +cn.state +--- +- active +... +cn:ping() +--- +- true +... +-- -- dot-new-method +cn1 = remote.new(LISTEN.host, LISTEN.service) +--- +... +x_select(cn1, space.id, 0, box.index.ALL, 0, 0xFFFFFFF, {}) +--- +- - [234, 1, 2, 3] + - [354, 1, 2, 4] +... +cn1:close() +--- +... +-- -- error while waiting for response +type(fiber.create(function() fiber.sleep(.5) x_fatal(cn) end)) +--- +- userdata +... +function pause() fiber.sleep(10) return true end +--- +... +box.schema.func.create('pause') +--- +... +box.schema.user.grant('guest', 'execute', 'function', 'pause') +--- +... +cn:call('pause') +--- +- error: Peer closed +... +cn:call('test_foo', {'a', 'b', 'c'}) +--- +- [[{'a': 1}], [{'b': 2}], 'c'] +... +box.schema.func.drop('pause') +--- +... +-- call +remote.self:call('test_foo', {'a', 'b', 'c'}) +--- +- - - a: 1 + - - b: 2 + - c +... +cn:call('test_foo', {'a', 'b', 'c'}) +--- +- [[{'a': 1}], [{'b': 2}], 'c'] +... +box.schema.func.drop('test_foo') +--- +... +box.schema.func.create('long_rep') +--- +... +box.schema.user.grant('guest', 'execute', 'function', 'long_rep') +--- +... +-- long replies +function long_rep() return { 1, string.rep('a', 5000) } end +--- +... +res = cn:call('long_rep') +--- +... +res[1] == 1 +--- +- true +... +res[2] == string.rep('a', 5000) +--- +- true +... +function long_rep() return { 1, string.rep('a', 50000) } end +--- +... +res = cn:call('long_rep') +--- +... +res[1] == 1 +--- +- true +... +res[2] == string.rep('a', 50000) +--- +- true +... +box.schema.func.drop('long_rep') +--- +... +-- a.b.c.d +u = '84F7BCFA-079C-46CC-98B4-F0C821BE833E' +--- +... +X = {} +--- +... +X.X = X +--- +... +function X.fn(x,y) return y or x end +--- +... +box.schema.user.grant('guest', 'execute', 'universe') +--- +... +cn:close() +--- +... +cn = remote.connect(LISTEN.host, LISTEN.service) +--- +... +cn:call('X.fn', {u}) +--- +- 84F7BCFA-079C-46CC-98B4-F0C821BE833E +... +cn:call('X.X.X.X.X.X.X.fn', {u}) +--- +- 84F7BCFA-079C-46CC-98B4-F0C821BE833E +... +cn:call('X.X.X.X:fn', {u}) +--- +- 84F7BCFA-079C-46CC-98B4-F0C821BE833E +... +box.schema.user.revoke('guest', 'execute', 'universe') +--- +... +cn:close() +--- +... +-- auth +cn = remote.connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123', wait_connected = true }) +--- +... +cn:is_connected() +--- +- false +... +cn.error +--- +- User 'netbox' is not found +... +cn.state +--- +- error +... diff --git a/test/box/net.box_incorrect_iterator_gh-841.test.lua b/test/box/net.box_incorrect_iterator_gh-841.test.lua new file mode 100644 index 000000000..cd431a57a --- /dev/null +++ b/test/box/net.box_incorrect_iterator_gh-841.test.lua @@ -0,0 +1,182 @@ +remote = require 'net.box' +fiber = require 'fiber' +test_run = require('test_run').new() +test_run:cmd("push filter ".."'\\.lua.*:[0-9]+: ' to '.lua...\"]:<line>: '") + +test_run:cmd("setopt delimiter ';'") +function x_select(cn, space_id, index_id, iterator, offset, limit, key, opts) + local ret = cn:_request('select', opts, nil, space_id, index_id, iterator, + offset, limit, key) + return ret +end +function x_fatal(cn) cn._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') end +test_run:cmd("setopt delimiter ''"); + +LISTEN = require('uri').parse(box.cfg.listen) +space = box.schema.space.create('net_box_test_space') +index = space:create_index('primary', { type = 'tree' }) + +function test_foo(a,b,c) return { {{ [a] = 1 }}, {{ [b] = 2 }}, c } end + +box.schema.user.grant('guest', 'read,write', 'space', 'net_box_test_space') +box.schema.user.grant('guest', 'execute', 'universe') + +cn = remote.connect(box.cfg.listen) + +x_select(cn, space.id, space.index.primary.id, box.index.EQ, 0, 0xFFFFFFFF, 123) +space:insert{123, 345} +x_select(cn, space.id, space.index.primary.id, box.index.EQ, 0, 0, 123) +x_select(cn, space.id, space.index.primary.id, box.index.EQ, 0, 1, 123) +x_select(cn, space.id, space.index.primary.id, box.index.EQ, 1, 1, 123) + +cn.space[space.id] ~= nil +cn.space.net_box_test_space ~= nil +cn.space.net_box_test_space ~= nil +cn.space.net_box_test_space.index ~= nil +cn.space.net_box_test_space.index.primary ~= nil +cn.space.net_box_test_space.index[space.index.primary.id] ~= nil + + +cn.space.net_box_test_space.index.primary:select(123) +cn.space.net_box_test_space.index.primary:select(123, { limit = 0 }) +cn.space.net_box_test_space.index.primary:select(nil, { limit = 1, }) +cn.space.net_box_test_space:insert{234, 1,2,3} +cn.space.net_box_test_space:insert{234, 1,2,3} +cn.space.net_box_test_space.insert{234, 1,2,3} + +cn.space.net_box_test_space:replace{354, 1,2,3} +cn.space.net_box_test_space:replace{354, 1,2,4} + +cn.space.net_box_test_space:select{123} +space:select({123}, { iterator = 'GE' }) +cn.space.net_box_test_space:select({123}, { iterator = 'GE' }) +cn.space.net_box_test_space:select({123}, { iterator = 'GT' }) +cn.space.net_box_test_space:select({123}, { iterator = 'GT', limit = 1 }) +cn.space.net_box_test_space:select({123}, { iterator = 'GT', limit = 1, offset = 1 }) + +cn.space.net_box_test_space:select{123} +cn.space.net_box_test_space:update({123}, { { '+', 2, 1 } }) +cn.space.net_box_test_space:update(123, { { '+', 2, 1 } }) +cn.space.net_box_test_space:select{123} + +cn.space.net_box_test_space:insert(cn.space.net_box_test_space:get{123}:update{ { '=', 1, 2 } }) +cn.space.net_box_test_space:delete{123} +cn.space.net_box_test_space:select{2} +cn.space.net_box_test_space:select({234}, { iterator = 'LT' }) + +cn.space.net_box_test_space:update({1}, { { '+', 2, 2 } }) + +cn.space.net_box_test_space:delete{1} +cn.space.net_box_test_space:delete{2} +cn.space.net_box_test_space:delete{2} + +-- test one-based indexing in splice operation (see update.test.lua) +cn.space.net_box_test_space:replace({10, 'abcde'}) +cn.space.net_box_test_space:update(10, {{':', 2, 0, 0, '!'}}) +cn.space.net_box_test_space:update(10, {{':', 2, 1, 0, '('}}) +cn.space.net_box_test_space:update(10, {{':', 2, 2, 0, '({'}}) +cn.space.net_box_test_space:update(10, {{':', 2, -1, 0, ')'}}) +cn.space.net_box_test_space:update(10, {{':', 2, -2, 0, '})'}}) +cn.space.net_box_test_space:delete{10} + +cn.space.net_box_test_space:select({}, { iterator = 'ALL' }) +-- gh-841: net.box uses incorrect iterator type for select with no arguments +cn.space.net_box_test_space:select() + +cn.space.net_box_test_space.index.primary:min() +cn.space.net_box_test_space.index.primary:min(354) +cn.space.net_box_test_space.index.primary:max() +cn.space.net_box_test_space.index.primary:max(234) +cn.space.net_box_test_space.index.primary:count() +cn.space.net_box_test_space.index.primary:count(354) + +cn.space.net_box_test_space:get(354) + +-- reconnects after errors + +box.schema.user.revoke('guest', 'execute', 'universe') +box.schema.func.create('test_foo') +box.schema.user.grant('guest', 'execute', 'function', 'test_foo') + +-- -- 1. no reconnect +x_fatal(cn) +cn.state +cn:ping() +cn:call('test_foo') +cn:wait_state('active') + +-- -- 2 reconnect +cn = remote.connect(LISTEN.host, LISTEN.service, { reconnect_after = .1 }) +cn.space ~= nil + +cn.space.net_box_test_space:select({}, { iterator = 'ALL' }) +x_fatal(cn) +cn:wait_connected() +cn:wait_state('active') +cn:wait_state({active=true}) +cn:ping() +cn.state +cn.space.net_box_test_space:select({}, { iterator = 'ALL' }) + +x_fatal(cn) +x_select(cn, space.id, 0, box.index.ALL, 0, 0xFFFFFFFF, {}) + +cn.state +cn:ping() + +-- -- dot-new-method + +cn1 = remote.new(LISTEN.host, LISTEN.service) +x_select(cn1, space.id, 0, box.index.ALL, 0, 0xFFFFFFF, {}) +cn1:close() +-- -- error while waiting for response +type(fiber.create(function() fiber.sleep(.5) x_fatal(cn) end)) +function pause() fiber.sleep(10) return true end + +box.schema.func.create('pause') +box.schema.user.grant('guest', 'execute', 'function', 'pause') +cn:call('pause') +cn:call('test_foo', {'a', 'b', 'c'}) +box.schema.func.drop('pause') + +-- call +remote.self:call('test_foo', {'a', 'b', 'c'}) +cn:call('test_foo', {'a', 'b', 'c'}) +box.schema.func.drop('test_foo') + +box.schema.func.create('long_rep') +box.schema.user.grant('guest', 'execute', 'function', 'long_rep') + +-- long replies +function long_rep() return { 1, string.rep('a', 5000) } end +res = cn:call('long_rep') +res[1] == 1 +res[2] == string.rep('a', 5000) + +function long_rep() return { 1, string.rep('a', 50000) } end +res = cn:call('long_rep') +res[1] == 1 +res[2] == string.rep('a', 50000) + +box.schema.func.drop('long_rep') + +-- a.b.c.d +u = '84F7BCFA-079C-46CC-98B4-F0C821BE833E' +X = {} +X.X = X +function X.fn(x,y) return y or x end +box.schema.user.grant('guest', 'execute', 'universe') +cn:close() +cn = remote.connect(LISTEN.host, LISTEN.service) +cn:call('X.fn', {u}) +cn:call('X.X.X.X.X.X.X.fn', {u}) +cn:call('X.X.X.X:fn', {u}) +box.schema.user.revoke('guest', 'execute', 'universe') +cn:close() + +-- auth + +cn = remote.connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123', wait_connected = true }) +cn:is_connected() +cn.error +cn.state diff --git a/test/box/net.box_index_unique_flag_gh-4091.result b/test/box/net.box_index_unique_flag_gh-4091.result new file mode 100644 index 000000000..a72c32c74 --- /dev/null +++ b/test/box/net.box_index_unique_flag_gh-4091.result @@ -0,0 +1,28 @@ +net = require('net.box') +--- +... +space = box.schema.space.create('test', {format={{name="id", type="unsigned"}}}) +--- +... +_ = box.space.test:create_index('primary') +--- +... +box.schema.user.grant('guest', 'read', 'space', 'test') +--- +... +c = net.connect(box.cfg.listen) +--- +... +-- +-- gh-4091: index unique flag is always false. +-- +c.space.test.index.primary.unique +--- +- true +... +c:close() +--- +... +space:drop() +--- +... diff --git a/test/box/net.box_index_unique_flag_gh-4091.test.lua b/test/box/net.box_index_unique_flag_gh-4091.test.lua new file mode 100644 index 000000000..7027b1e33 --- /dev/null +++ b/test/box/net.box_index_unique_flag_gh-4091.test.lua @@ -0,0 +1,15 @@ +net = require('net.box') + +space = box.schema.space.create('test', {format={{name="id", type="unsigned"}}}) +_ = box.space.test:create_index('primary') +box.schema.user.grant('guest', 'read', 'space', 'test') + +c = net.connect(box.cfg.listen) + +-- +-- gh-4091: index unique flag is always false. +-- +c.space.test.index.primary.unique + +c:close() +space:drop() diff --git a/test/box/net.box_iproto_hangs_gh-3464.result b/test/box/net.box_iproto_hangs_gh-3464.result new file mode 100644 index 000000000..d425bf78c --- /dev/null +++ b/test/box/net.box_iproto_hangs_gh-3464.result @@ -0,0 +1,31 @@ +msgpack = require 'msgpack' +--- +... +test_run = require('test_run').new() +--- +... +net = require('net.box') +--- +... +-- +-- gh-3464: iproto hangs in 100% CPU when too big packet size +-- is received due to size_t overflow. +-- +c = net:connect(box.cfg.listen) +--- +... +data = msgpack.encode(18400000000000000000)..'aaaaaaa' +--- +... +c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, data) +--- +- null +- Peer closed +... +c:close() +--- +... +test_run:grep_log('default', 'too big packet size in the header') ~= nil +--- +- true +... diff --git a/test/box/net.box_iproto_hangs_gh-3464.test.lua b/test/box/net.box_iproto_hangs_gh-3464.test.lua new file mode 100644 index 000000000..77551e415 --- /dev/null +++ b/test/box/net.box_iproto_hangs_gh-3464.test.lua @@ -0,0 +1,13 @@ +msgpack = require 'msgpack' +test_run = require('test_run').new() +net = require('net.box') + +-- +-- gh-3464: iproto hangs in 100% CPU when too big packet size +-- is received due to size_t overflow. +-- +c = net:connect(box.cfg.listen) +data = msgpack.encode(18400000000000000000)..'aaaaaaa' +c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, data) +c:close() +test_run:grep_log('default', 'too big packet size in the header') ~= nil diff --git a/test/box/net.box_is_nullable_gh-3256.result b/test/box/net.box_is_nullable_gh-3256.result new file mode 100644 index 000000000..5d6dc4b94 --- /dev/null +++ b/test/box/net.box_is_nullable_gh-3256.result @@ -0,0 +1,97 @@ +net = require('net.box') +--- +... +-- +-- gh-3256 net.box is_nullable and collation options output +-- +space = box.schema.create_space('test') +--- +... +box.schema.user.grant('guest', 'read', 'space', 'test') +--- +... +_ = space:create_index('pk') +--- +... +_ = space:create_index('sk', {parts = {{2, 'unsigned', is_nullable = true}}}) +--- +... +c = net:connect(box.cfg.listen) +--- +... +c.space.test.index.sk.parts +--- +- - type: unsigned + is_nullable: true + fieldno: 2 +... +space:drop() +--- +... +space = box.schema.create_space('test') +--- +... +c:close() +--- +... +box.schema.user.grant('guest', 'read', 'space', 'test') +--- +... +c = net:connect(box.cfg.listen) +--- +... +box.internal.collation.create('test', 'ICU', 'ru-RU') +--- +... +collation_id = box.internal.collation.id_by_name('test') +--- +... +_ = space:create_index('sk', { type = 'tree', parts = {{1, 'str', collation = 'test'}}, unique = true }) +--- +... +c:reload_schema() +--- +... +parts = c.space.test.index.sk.parts +--- +... +#parts == 1 +--- +- true +... +parts[1].fieldno == 1 +--- +- true +... +parts[1].type == 'string' +--- +- true +... +parts[1].is_nullable == false +--- +- true +... +if _TARANTOOL >= '2.2.1' then \ + return parts[1].collation == 'test' \ +else \ + return parts[1].collation_id == collation_id \ +end +--- +- true +... +c:close() +--- +... +box.internal.collation.drop('test') +--- +... +space:drop() +--- +... +c.state +--- +- closed +... +c = nil +--- +... diff --git a/test/box/net.box_is_nullable_gh-3256.test.lua b/test/box/net.box_is_nullable_gh-3256.test.lua new file mode 100644 index 000000000..3c5ee3971 --- /dev/null +++ b/test/box/net.box_is_nullable_gh-3256.test.lua @@ -0,0 +1,36 @@ +net = require('net.box') + +-- +-- gh-3256 net.box is_nullable and collation options output +-- +space = box.schema.create_space('test') +box.schema.user.grant('guest', 'read', 'space', 'test') +_ = space:create_index('pk') +_ = space:create_index('sk', {parts = {{2, 'unsigned', is_nullable = true}}}) +c = net:connect(box.cfg.listen) +c.space.test.index.sk.parts +space:drop() + +space = box.schema.create_space('test') +c:close() +box.schema.user.grant('guest', 'read', 'space', 'test') +c = net:connect(box.cfg.listen) +box.internal.collation.create('test', 'ICU', 'ru-RU') +collation_id = box.internal.collation.id_by_name('test') +_ = space:create_index('sk', { type = 'tree', parts = {{1, 'str', collation = 'test'}}, unique = true }) +c:reload_schema() +parts = c.space.test.index.sk.parts +#parts == 1 +parts[1].fieldno == 1 +parts[1].type == 'string' +parts[1].is_nullable == false +if _TARANTOOL >= '2.2.1' then \ + return parts[1].collation == 'test' \ +else \ + return parts[1].collation_id == collation_id \ +end +c:close() +box.internal.collation.drop('test') +space:drop() +c.state +c = nil diff --git a/test/box/net.box_leaks_gh-3629.result b/test/box/net.box_leaks_gh-3629.result new file mode 100644 index 000000000..4c6688bf2 --- /dev/null +++ b/test/box/net.box_leaks_gh-3629.result @@ -0,0 +1,51 @@ +fiber = require 'fiber' +--- +... +net = require('net.box') +--- +... +-- +-- gh-3629: netbox leaks when a connection is closed deliberately +-- and it has non-finished requests. +-- +ready = false +--- +... +ok = nil +--- +... +err = nil +--- +... +c = net:connect(box.cfg.listen) +--- +... +function do_long() while not ready do fiber.sleep(0.01) end end +--- +... +box.schema.func.create('do_long') +--- +... +box.schema.user.grant('guest', 'execute', 'function', 'do_long') +--- +... +f = fiber.create(function() ok, err = pcall(c.call, c, 'do_long') end) +--- +... +while f:status() ~= 'suspended' do fiber.sleep(0.01) end +--- +... +c:close() +--- +... +ready = true +--- +... +while not err do fiber.sleep(0.01) end +--- +... +ok, err +--- +- false +- Connection closed +... diff --git a/test/box/net.box_leaks_gh-3629.test.lua b/test/box/net.box_leaks_gh-3629.test.lua new file mode 100644 index 000000000..03b5a2327 --- /dev/null +++ b/test/box/net.box_leaks_gh-3629.test.lua @@ -0,0 +1,20 @@ +fiber = require 'fiber' +net = require('net.box') + +-- +-- gh-3629: netbox leaks when a connection is closed deliberately +-- and it has non-finished requests. +-- +ready = false +ok = nil +err = nil +c = net:connect(box.cfg.listen) +function do_long() while not ready do fiber.sleep(0.01) end end +box.schema.func.create('do_long') +box.schema.user.grant('guest', 'execute', 'function', 'do_long') +f = fiber.create(function() ok, err = pcall(c.call, c, 'do_long') end) +while f:status() ~= 'suspended' do fiber.sleep(0.01) end +c:close() +ready = true +while not err do fiber.sleep(0.01) end +ok, err diff --git a/test/box/net.box_log_corrupted_rows_gh-4040.result b/test/box/net.box_log_corrupted_rows_gh-4040.result new file mode 100644 index 000000000..603de0f13 --- /dev/null +++ b/test/box/net.box_log_corrupted_rows_gh-4040.result @@ -0,0 +1,72 @@ +test_run = require('test_run').new() +--- +... +socket = require('socket'); +--- +... +LISTEN = require('uri').parse(box.cfg.listen) +--- +... +test_run:cmd('create server connecter with script = "box/proxy.lua"') +--- +- true +... +-- +-- related to gh-4040: log corrupted rows +-- +log_level = box.cfg.log_level +--- +... +box.cfg{log_level=6} +--- +... +sock = socket.tcp_connect(LISTEN.host, LISTEN.service) +--- +... +sock:read(9) +--- +- Tarantool +... +-- we need to have a packet with correctly encoded length, +-- so that it bypasses iproto length check, but cannot be +-- decoded in xrow_header_decode +-- 0x3C = 60, sha1 digest is 20 bytes long +data = string.fromhex('3C'..string.rep(require('digest').sha1_hex('bcde'), 3)) +--- +... +sock:write(data) +--- +- 61 +... +sock:close() +--- +- true +... +test_run:wait_log('default', 'Got a corrupted row.*', nil, 10) +--- +- 'Got a corrupted row:' +... +test_run:wait_log('default', '00000000:.*', nil, 10) +--- +- '00000000: A3 02 D6 5A E4 D9 E7 68 A1 53 8D 53 60 5F 20 3F ' +... +test_run:wait_log('default', '00000010:.*', nil, 10) +--- +- '00000010: D8 E2 D6 E2 A3 02 D6 5A E4 D9 E7 68 A1 53 8D 53 ' +... +test_run:wait_log('default', '00000020:.*', nil, 10) +--- +- '00000020: 60 5F 20 3F D8 E2 D6 E2 A3 02 D6 5A E4 D9 E7 68 ' +... +test_run:wait_log('default', '00000030:.*', nil, 10) +--- +- '00000030: A1 53 8D 53 60 5F 20 3F D8 E2 D6 E2 ' +... +-- we expect nothing below, so don't wait +test_run:grep_log('default', '00000040:.*') +--- +- null +... +box.cfg{log_level=log_level} +--- +... diff --git a/test/box/net.box_log_corrupted_rows_gh-4040.test.lua b/test/box/net.box_log_corrupted_rows_gh-4040.test.lua new file mode 100644 index 000000000..a30b4a254 --- /dev/null +++ b/test/box/net.box_log_corrupted_rows_gh-4040.test.lua @@ -0,0 +1,31 @@ +test_run = require('test_run').new() +socket = require('socket'); + +LISTEN = require('uri').parse(box.cfg.listen) + +test_run:cmd('create server connecter with script = "box/proxy.lua"') + +-- +-- related to gh-4040: log corrupted rows +-- +log_level = box.cfg.log_level +box.cfg{log_level=6} +sock = socket.tcp_connect(LISTEN.host, LISTEN.service) +sock:read(9) +-- we need to have a packet with correctly encoded length, +-- so that it bypasses iproto length check, but cannot be +-- decoded in xrow_header_decode +-- 0x3C = 60, sha1 digest is 20 bytes long +data = string.fromhex('3C'..string.rep(require('digest').sha1_hex('bcde'), 3)) +sock:write(data) +sock:close() + +test_run:wait_log('default', 'Got a corrupted row.*', nil, 10) +test_run:wait_log('default', '00000000:.*', nil, 10) +test_run:wait_log('default', '00000010:.*', nil, 10) +test_run:wait_log('default', '00000020:.*', nil, 10) +test_run:wait_log('default', '00000030:.*', nil, 10) +-- we expect nothing below, so don't wait +test_run:grep_log('default', '00000040:.*') + +box.cfg{log_level=log_level} diff --git a/test/box/net.box_long-poll_input_gh-3400.result b/test/box/net.box_long-poll_input_gh-3400.result new file mode 100644 index 000000000..062bd563a --- /dev/null +++ b/test/box/net.box_long-poll_input_gh-3400.result @@ -0,0 +1,35 @@ +fiber = require 'fiber' +--- +... +net = require('net.box') +--- +... +-- +-- gh-3400: long-poll input discard must not touch event loop of +-- a closed connection. +-- +function long() fiber.yield() return 100 end +--- +... +c = net.connect(box.cfg.listen) +--- +... +c:ping() +--- +- true +... +-- Create batch of two requests. First request is sent to TX +-- thread, second one terminates connection. The preceeding +-- request discards input, and this operation must not trigger +-- new attempts to read any data - the connection is closed +-- already. +-- +f = fiber.create(c._transport.perform_request, nil, nil, false, 'call_17', nil, nil, nil, 'long', {}) c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') +--- +... +while f:status() ~= 'dead' do fiber.sleep(0.01) end +--- +... +c:close() +--- +... diff --git a/test/box/net.box_long-poll_input_gh-3400.test.lua b/test/box/net.box_long-poll_input_gh-3400.test.lua new file mode 100644 index 000000000..bc9db1e69 --- /dev/null +++ b/test/box/net.box_long-poll_input_gh-3400.test.lua @@ -0,0 +1,19 @@ +fiber = require 'fiber' +net = require('net.box') + +-- +-- gh-3400: long-poll input discard must not touch event loop of +-- a closed connection. +-- +function long() fiber.yield() return 100 end +c = net.connect(box.cfg.listen) +c:ping() +-- Create batch of two requests. First request is sent to TX +-- thread, second one terminates connection. The preceeding +-- request discards input, and this operation must not trigger +-- new attempts to read any data - the connection is closed +-- already. +-- +f = fiber.create(c._transport.perform_request, nil, nil, false, 'call_17', nil, nil, nil, 'long', {}) c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') +while f:status() ~= 'dead' do fiber.sleep(0.01) end +c:close() diff --git a/test/box/net.box_methods_gh-3107.result b/test/box/net.box_methods_gh-3107.result new file mode 100644 index 000000000..8ff69ebd6 --- /dev/null +++ b/test/box/net.box_methods_gh-3107.result @@ -0,0 +1,277 @@ +fiber = require 'fiber' +--- +... +net = require('net.box') +--- +... +-- +-- gh-3107: fiber-async netbox. +-- +cond = nil +--- +... +box.schema.func.create('long_function') +--- +... +box.schema.user.grant('guest', 'execute', 'function', 'long_function') +--- +... +function long_function(...) cond = fiber.cond() cond:wait() return ... end +--- +... +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end +--- +... +s = box.schema.create_space('test') +--- +... +pk = s:create_index('pk') +--- +... +s:replace{1} +--- +- [1] +... +s:replace{2} +--- +- [2] +... +s:replace{3} +--- +- [3] +... +s:replace{4} +--- +- [4] +... +c = net:connect(box.cfg.listen) +--- +... +-- +-- Ensure a request can be finalized from non-caller fibers. +-- +future = c:call('long_function', {1, 2, 3}, {is_async = true}) +--- +... +ret = {} +--- +... +count = 0 +--- +... +for i = 1, 10 do fiber.create(function() ret[i] = future:wait_result(1000) count = count + 1 end) end +--- +... +future:wait_result(0.01) -- Must fail on timeout. +--- +- null +- Timeout exceeded +... +finalize_long() +--- +... +while count ~= 10 do fiber.sleep(0.1) end +--- +... +ret +--- +- - &0 [1, 2, 3] + - *0 + - *0 + - *0 + - *0 + - *0 + - *0 + - *0 + - *0 + - *0 +... +-- +-- Test space methods. +-- +c:close() +--- +... +box.schema.user.grant('guest', 'read,write', 'space', 'test') +--- +... +c = net:connect(box.cfg.listen) +--- +... +future = c.space.test:select({1}, {is_async = true}) +--- +... +ret = future:wait_result(100) +--- +... +ret +--- +- - [1] +... +type(ret[1]) +--- +- cdata +... +future = c.space.test:insert({5}, {is_async = true}) +--- +... +future:wait_result(100) +--- +- [5] +... +s:get{5} +--- +- [5] +... +future = c.space.test:replace({6}, {is_async = true}) +--- +... +future:wait_result(100) +--- +- [6] +... +s:get{6} +--- +- [6] +... +future = c.space.test:delete({6}, {is_async = true}) +--- +... +future:wait_result(100) +--- +- [6] +... +s:get{6} +--- +... +future = c.space.test:update({5}, {{'=', 2, 5}}, {is_async = true}) +--- +... +future:wait_result(100) +--- +- [5, 5] +... +s:get{5} +--- +- [5, 5] +... +future = c.space.test:upsert({5}, {{'=', 2, 6}}, {is_async = true}) +--- +... +future:wait_result(100) +--- +- null +... +s:get{5} +--- +- [5, 6] +... +future = c.space.test:get({5}, {is_async = true}) +--- +... +future:wait_result(100) +--- +- [5, 6] +... +-- +-- Test index methods. +-- +future = c.space.test.index.pk:select({1}, {is_async = true}) +--- +... +future:wait_result(100) +--- +- - [1] +... +future = c.space.test.index.pk:get({2}, {is_async = true}) +--- +... +future:wait_result(100) +--- +- [2] +... +future = c.space.test.index.pk:min({}, {is_async = true}) +--- +... +future:wait_result(100) +--- +- [1] +... +future = c.space.test.index.pk:max({}, {is_async = true}) +--- +... +future:wait_result(100) +--- +- [5, 6] +... +c:close() +--- +... +box.schema.user.grant('guest', 'execute', 'universe') +--- +... +c = net:connect(box.cfg.listen) +--- +... +future = c.space.test.index.pk:count({3}, {is_async = true}) +--- +... +future:wait_result(100) +--- +- 1 +... +c:close() +--- +... +box.schema.user.revoke('guest', 'execute', 'universe') +--- +... +c = net:connect(box.cfg.listen) +--- +... +future = c.space.test.index.pk:delete({3}, {is_async = true}) +--- +... +future:wait_result(100) +--- +- [3] +... +s:get{3} +--- +... +future = c.space.test.index.pk:update({4}, {{'=', 2, 6}}, {is_async = true}) +--- +... +future:wait_result(100) +--- +- [4, 6] +... +s:get{4} +--- +- [4, 6] +... +-- +-- Test async errors. +-- +future = c.space.test:insert({1}, {is_async = true}) +--- +... +future:wait_result() +--- +- null +- Duplicate key exists in unique index 'pk' in space 'test' +... +future:result() +--- +- null +- Duplicate key exists in unique index 'pk' in space 'test' +... +box.schema.func.drop('long_function') +--- +... +c:close() +--- +... +s:drop() +--- +... diff --git a/test/box/net.box_methods_gh-3107.test.lua b/test/box/net.box_methods_gh-3107.test.lua new file mode 100644 index 000000000..364a72ed3 --- /dev/null +++ b/test/box/net.box_methods_gh-3107.test.lua @@ -0,0 +1,96 @@ +fiber = require 'fiber' +net = require('net.box') + +-- +-- gh-3107: fiber-async netbox. +-- +cond = nil +box.schema.func.create('long_function') +box.schema.user.grant('guest', 'execute', 'function', 'long_function') +function long_function(...) cond = fiber.cond() cond:wait() return ... end +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end +s = box.schema.create_space('test') +pk = s:create_index('pk') +s:replace{1} +s:replace{2} +s:replace{3} +s:replace{4} +c = net:connect(box.cfg.listen) + +-- +-- Ensure a request can be finalized from non-caller fibers. +-- +future = c:call('long_function', {1, 2, 3}, {is_async = true}) +ret = {} +count = 0 +for i = 1, 10 do fiber.create(function() ret[i] = future:wait_result(1000) count = count + 1 end) end +future:wait_result(0.01) -- Must fail on timeout. +finalize_long() +while count ~= 10 do fiber.sleep(0.1) end +ret + +-- +-- Test space methods. +-- +c:close() +box.schema.user.grant('guest', 'read,write', 'space', 'test') +c = net:connect(box.cfg.listen) +future = c.space.test:select({1}, {is_async = true}) +ret = future:wait_result(100) +ret +type(ret[1]) +future = c.space.test:insert({5}, {is_async = true}) +future:wait_result(100) +s:get{5} +future = c.space.test:replace({6}, {is_async = true}) +future:wait_result(100) +s:get{6} +future = c.space.test:delete({6}, {is_async = true}) +future:wait_result(100) +s:get{6} +future = c.space.test:update({5}, {{'=', 2, 5}}, {is_async = true}) +future:wait_result(100) +s:get{5} +future = c.space.test:upsert({5}, {{'=', 2, 6}}, {is_async = true}) +future:wait_result(100) +s:get{5} +future = c.space.test:get({5}, {is_async = true}) +future:wait_result(100) + +-- +-- Test index methods. +-- +future = c.space.test.index.pk:select({1}, {is_async = true}) +future:wait_result(100) +future = c.space.test.index.pk:get({2}, {is_async = true}) +future:wait_result(100) +future = c.space.test.index.pk:min({}, {is_async = true}) +future:wait_result(100) +future = c.space.test.index.pk:max({}, {is_async = true}) +future:wait_result(100) +c:close() +box.schema.user.grant('guest', 'execute', 'universe') +c = net:connect(box.cfg.listen) +future = c.space.test.index.pk:count({3}, {is_async = true}) +future:wait_result(100) +c:close() +box.schema.user.revoke('guest', 'execute', 'universe') +c = net:connect(box.cfg.listen) +future = c.space.test.index.pk:delete({3}, {is_async = true}) +future:wait_result(100) +s:get{3} +future = c.space.test.index.pk:update({4}, {{'=', 2, 6}}, {is_async = true}) +future:wait_result(100) +s:get{4} + +-- +-- Test async errors. +-- +future = c.space.test:insert({1}, {is_async = true}) +future:wait_result() +future:result() + +box.schema.func.drop('long_function') + +c:close() +s:drop() diff --git a/test/box/net.box_msgpack_gh-2195.result b/test/box/net.box_msgpack_gh-2195.result new file mode 100644 index 000000000..a4c851334 --- /dev/null +++ b/test/box/net.box_msgpack_gh-2195.result @@ -0,0 +1,527 @@ +msgpack = require 'msgpack' +--- +... +test_run = require('test_run').new() +--- +... +test_run:cmd("push filter ".."'\\.lua.*:[0-9]+: ' to '.lua...\"]:<line>: '") +--- +- true +... +net = require('net.box') +--- +... +-- CALL vs CALL_16 in connect options +function echo(...) return ... end +--- +... +box.schema.user.grant('guest', 'execute', 'universe') +--- +... +c = net.connect(box.cfg.listen) +--- +... +c:call('echo', {42}) +--- +- 42 +... +c:eval('return echo(...)', {42}) +--- +- 42 +... +-- invalid arguments +c:call('echo', 42) +--- +- error: 'builtin/box/net_box.lua..."]:<line>: Use remote:call(func_name, {arg1, arg2, ...}, + opts) instead of remote:call(func_name, arg1, arg2, ...)' +... +c:eval('return echo(...)', 42) +--- +- error: 'builtin/box/net_box.lua..."]:<line>: Use remote:eval(expression, {arg1, arg2, ...}, + opts) instead of remote:eval(expression, arg1, arg2, ...)' +... +c:close() +--- +... +c = net.connect(box.cfg.listen, {call_16 = true}) +--- +... +c:call('echo', 42) +--- +- - [42] +... +c:eval('return echo(...)', 42) +--- +- 42 +... +c:close() +--- +... +box.schema.user.revoke('guest', 'execute', 'universe') +--- +... +-- +-- gh-2195 export pure msgpack from net.box +-- +space = box.schema.space.create('test') +--- +... +_ = box.space.test:create_index('primary') +--- +... +box.schema.user.grant('guest', 'read,write', 'space', 'test') +--- +... +box.schema.user.grant('guest', 'execute', 'universe') +--- +... +c = net.connect(box.cfg.listen) +--- +... +ibuf = require('buffer').ibuf() +--- +... +c:ping() +--- +- true +... +c.space.test ~= nil +--- +- true +... +c.space.test:replace({1, 'hello'}) +--- +- [1, 'hello'] +... +-- replace +c.space.test:replace({2}, {buffer = ibuf}) +--- +- 9 +... +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +--- +... +result +--- +- {48: [[2]]} +... +-- replace + skip_header +c.space.test:replace({2}, {buffer = ibuf, skip_header = true}) +--- +- 7 +... +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +--- +... +result +--- +- [[2]] +... +-- insert +c.space.test:insert({3}, {buffer = ibuf}) +--- +- 9 +... +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +--- +... +result +--- +- {48: [[3]]} +... +-- insert + skip_header +_ = space:delete({3}) +--- +... +c.space.test:insert({3}, {buffer = ibuf, skip_header = true}) +--- +- 7 +... +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +--- +... +result +--- +- [[3]] +... +-- update +c.space.test:update({3}, {}, {buffer = ibuf}) +--- +- 9 +... +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +--- +... +result +--- +- {48: [[3]]} +... +c.space.test.index.primary:update({3}, {}, {buffer = ibuf}) +--- +- 9 +... +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +--- +... +result +--- +- {48: [[3]]} +... +-- update + skip_header +c.space.test:update({3}, {}, {buffer = ibuf, skip_header = true}) +--- +- 7 +... +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +--- +... +result +--- +- [[3]] +... +c.space.test.index.primary:update({3}, {}, {buffer = ibuf, skip_header = true}) +--- +- 7 +... +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +--- +... +result +--- +- [[3]] +... +-- upsert +c.space.test:upsert({4}, {}, {buffer = ibuf}) +--- +- 7 +... +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +--- +... +result +--- +- {48: []} +... +-- upsert + skip_header +c.space.test:upsert({4}, {}, {buffer = ibuf, skip_header = true}) +--- +- 5 +... +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +--- +... +result +--- +- [] +... +-- delete +c.space.test:upsert({4}, {}, {buffer = ibuf}) +--- +- 7 +... +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +--- +... +result +--- +- {48: []} +... +-- delete + skip_header +c.space.test:upsert({4}, {}, {buffer = ibuf, skip_header = true}) +--- +- 5 +... +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +--- +... +result +--- +- [] +... +-- select +c.space.test.index.primary:select({3}, {iterator = 'LE', buffer = ibuf}) +--- +- 19 +... +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +--- +... +result +--- +- {48: [[3], [2], [1, 'hello']]} +... +-- select + skip_header +c.space.test.index.primary:select({3}, {iterator = 'LE', buffer = ibuf, skip_header = true}) +--- +- 17 +... +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +--- +... +result +--- +- [[3], [2], [1, 'hello']] +... +-- select +len = c.space.test:select({}, {buffer = ibuf}) +--- +... +ibuf.rpos + len == ibuf.wpos +--- +- true +... +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +--- +... +ibuf.rpos == ibuf.wpos +--- +- true +... +len +--- +- 21 +... +result +--- +- {48: [[1, 'hello'], [2], [3], [4]]} +... +-- select + skip_header +len = c.space.test:select({}, {buffer = ibuf, skip_header = true}) +--- +... +ibuf.rpos + len == ibuf.wpos +--- +- true +... +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +--- +... +ibuf.rpos == ibuf.wpos +--- +- true +... +len +--- +- 19 +... +result +--- +- [[1, 'hello'], [2], [3], [4]] +... +-- call +c:call("echo", {1, 2, 3}, {buffer = ibuf}) +--- +- 10 +... +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +--- +... +result +--- +- {48: [1, 2, 3]} +... +c:call("echo", {}, {buffer = ibuf}) +--- +- 7 +... +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +--- +... +result +--- +- {48: []} +... +c:call("echo", nil, {buffer = ibuf}) +--- +- 7 +... +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +--- +... +result +--- +- {48: []} +... +-- call + skip_header +c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) +--- +- 8 +... +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +--- +... +result +--- +- [1, 2, 3] +... +c:call("echo", {}, {buffer = ibuf, skip_header = true}) +--- +- 5 +... +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +--- +... +result +--- +- [] +... +c:call("echo", nil, {buffer = ibuf, skip_header = true}) +--- +- 5 +... +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +--- +... +result +--- +- [] +... +-- eval +c:eval("echo(...)", {1, 2, 3}, {buffer = ibuf}) +--- +- 7 +... +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +--- +... +result +--- +- {48: []} +... +c:eval("echo(...)", {}, {buffer = ibuf}) +--- +- 7 +... +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +--- +... +result +--- +- {48: []} +... +c:eval("echo(...)", nil, {buffer = ibuf}) +--- +- 7 +... +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +--- +... +result +--- +- {48: []} +... +-- eval + skip_header +c:eval("echo(...)", {1, 2, 3}, {buffer = ibuf, skip_header = true}) +--- +- 5 +... +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +--- +... +result +--- +- [] +... +c:eval("echo(...)", {}, {buffer = ibuf, skip_header = true}) +--- +- 5 +... +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +--- +... +result +--- +- [] +... +c:eval("echo(...)", nil, {buffer = ibuf, skip_header = true}) +--- +- 5 +... +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +--- +... +result +--- +- [] +... +-- make several request into a buffer with skip_header, then read +-- results +c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) +--- +- 8 +... +c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) +--- +- 8 +... +c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) +--- +- 8 +... +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +--- +... +result +--- +- [1, 2, 3] +... +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +--- +... +result +--- +- [1, 2, 3] +... +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +--- +... +result +--- +- [1, 2, 3] +... +-- unsupported methods +c.space.test:get({1}, { buffer = ibuf}) +--- +- error: 'builtin/box/net_box.lua..."]:<line>: index:get() doesn''t support `buffer` argument' +... +c.space.test.index.primary:min({}, { buffer = ibuf}) +--- +- error: 'builtin/box/net_box.lua..."]:<line>: index:min() doesn''t support `buffer` argument' +... +c.space.test.index.primary:max({}, { buffer = ibuf}) +--- +- error: 'builtin/box/net_box.lua..."]:<line>: index:max() doesn''t support `buffer` argument' +... +c.space.test.index.primary:count({}, { buffer = ibuf}) +--- +- error: 'builtin/box/net_box.lua..."]:<line>: index:count() doesn''t support `buffer` argument' +... +c.space.test.index.primary:get({1}, { buffer = ibuf}) +--- +- error: 'builtin/box/net_box.lua..."]:<line>: index:get() doesn''t support `buffer` argument' +... +-- error handling +rpos, wpos = ibuf.rpos, ibuf.wpos +--- +... +c.space.test:insert({1}, {buffer = ibuf}) +--- +- error: Duplicate key exists in unique index 'primary' in space 'test' +... +ibuf.rpos == rpos, ibuf.wpos == wpos +--- +- true +- true +... +ibuf = nil +--- +... +c:close() +--- +... +space:drop() +--- +... +box.schema.user.revoke('guest', 'execute', 'universe') +--- +... diff --git a/test/box/net.box_msgpack_gh-2195.test.lua b/test/box/net.box_msgpack_gh-2195.test.lua new file mode 100644 index 000000000..8c14b4b43 --- /dev/null +++ b/test/box/net.box_msgpack_gh-2195.test.lua @@ -0,0 +1,192 @@ +msgpack = require 'msgpack' +test_run = require('test_run').new() +test_run:cmd("push filter ".."'\\.lua.*:[0-9]+: ' to '.lua...\"]:<line>: '") +net = require('net.box') + +-- CALL vs CALL_16 in connect options +function echo(...) return ... end +box.schema.user.grant('guest', 'execute', 'universe') +c = net.connect(box.cfg.listen) +c:call('echo', {42}) +c:eval('return echo(...)', {42}) +-- invalid arguments +c:call('echo', 42) +c:eval('return echo(...)', 42) +c:close() +c = net.connect(box.cfg.listen, {call_16 = true}) +c:call('echo', 42) +c:eval('return echo(...)', 42) +c:close() +box.schema.user.revoke('guest', 'execute', 'universe') + +-- +-- gh-2195 export pure msgpack from net.box +-- + +space = box.schema.space.create('test') +_ = box.space.test:create_index('primary') +box.schema.user.grant('guest', 'read,write', 'space', 'test') +box.schema.user.grant('guest', 'execute', 'universe') +c = net.connect(box.cfg.listen) +ibuf = require('buffer').ibuf() + +c:ping() +c.space.test ~= nil + +c.space.test:replace({1, 'hello'}) + +-- replace +c.space.test:replace({2}, {buffer = ibuf}) +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +result + +-- replace + skip_header +c.space.test:replace({2}, {buffer = ibuf, skip_header = true}) +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +result + +-- insert +c.space.test:insert({3}, {buffer = ibuf}) +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +result + +-- insert + skip_header +_ = space:delete({3}) +c.space.test:insert({3}, {buffer = ibuf, skip_header = true}) +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +result + +-- update +c.space.test:update({3}, {}, {buffer = ibuf}) +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +result +c.space.test.index.primary:update({3}, {}, {buffer = ibuf}) +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +result + +-- update + skip_header +c.space.test:update({3}, {}, {buffer = ibuf, skip_header = true}) +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +result +c.space.test.index.primary:update({3}, {}, {buffer = ibuf, skip_header = true}) +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +result + +-- upsert +c.space.test:upsert({4}, {}, {buffer = ibuf}) +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +result + +-- upsert + skip_header +c.space.test:upsert({4}, {}, {buffer = ibuf, skip_header = true}) +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +result + +-- delete +c.space.test:upsert({4}, {}, {buffer = ibuf}) +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +result + +-- delete + skip_header +c.space.test:upsert({4}, {}, {buffer = ibuf, skip_header = true}) +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +result + +-- select +c.space.test.index.primary:select({3}, {iterator = 'LE', buffer = ibuf}) +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +result + +-- select + skip_header +c.space.test.index.primary:select({3}, {iterator = 'LE', buffer = ibuf, skip_header = true}) +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +result + +-- select +len = c.space.test:select({}, {buffer = ibuf}) +ibuf.rpos + len == ibuf.wpos +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +ibuf.rpos == ibuf.wpos +len +result + +-- select + skip_header +len = c.space.test:select({}, {buffer = ibuf, skip_header = true}) +ibuf.rpos + len == ibuf.wpos +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +ibuf.rpos == ibuf.wpos +len +result + +-- call +c:call("echo", {1, 2, 3}, {buffer = ibuf}) +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +result +c:call("echo", {}, {buffer = ibuf}) +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +result +c:call("echo", nil, {buffer = ibuf}) +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +result + +-- call + skip_header +c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +result +c:call("echo", {}, {buffer = ibuf, skip_header = true}) +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +result +c:call("echo", nil, {buffer = ibuf, skip_header = true}) +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +result + +-- eval +c:eval("echo(...)", {1, 2, 3}, {buffer = ibuf}) +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +result +c:eval("echo(...)", {}, {buffer = ibuf}) +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +result +c:eval("echo(...)", nil, {buffer = ibuf}) +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +result + +-- eval + skip_header +c:eval("echo(...)", {1, 2, 3}, {buffer = ibuf, skip_header = true}) +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +result +c:eval("echo(...)", {}, {buffer = ibuf, skip_header = true}) +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +result +c:eval("echo(...)", nil, {buffer = ibuf, skip_header = true}) +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +result + +-- make several request into a buffer with skip_header, then read +-- results +c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) +c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) +c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +result +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +result +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +result + +-- unsupported methods +c.space.test:get({1}, { buffer = ibuf}) +c.space.test.index.primary:min({}, { buffer = ibuf}) +c.space.test.index.primary:max({}, { buffer = ibuf}) +c.space.test.index.primary:count({}, { buffer = ibuf}) +c.space.test.index.primary:get({1}, { buffer = ibuf}) + +-- error handling +rpos, wpos = ibuf.rpos, ibuf.wpos +c.space.test:insert({1}, {buffer = ibuf}) +ibuf.rpos == rpos, ibuf.wpos == wpos + +ibuf = nil +c:close() +space:drop() +box.schema.user.revoke('guest', 'execute', 'universe') diff --git a/test/box/net.box_on_schema_reload-gh-1904.result b/test/box/net.box_on_schema_reload-gh-1904.result new file mode 100644 index 000000000..5029684bf --- /dev/null +++ b/test/box/net.box_on_schema_reload-gh-1904.result @@ -0,0 +1,102 @@ +fiber = require 'fiber' +--- +... +test_run = require('test_run').new() +--- +... +LISTEN = require('uri').parse(box.cfg.listen) +--- +... +space = box.schema.space.create('net_box_test_space') +--- +... +index = space:create_index('primary', { type = 'tree' }) +--- +... +box.schema.user.create('netbox', { password = 'test' }) +--- +... +box.schema.user.grant('netbox', 'read,write', 'space', 'net_box_test_space') +--- +... +box.schema.user.grant('netbox', 'execute', 'universe') +--- +... +net = require('net.box') +--- +... +-- gh-1904 net.box hangs in :close() if a fiber was cancelled +-- while blocked in :_wait_state() in :_request() +options = {user = 'netbox', password = 'badpass', wait_connected = false, reconnect_after = 0.01} +--- +... +c = net:new(box.cfg.listen, options) +--- +... +f = fiber.create(function() c:call("") end) +--- +... +fiber.sleep(0.01) +--- +... +f:cancel(); c:close() +--- +... +box.schema.user.grant('guest', 'read', 'space', '_schema') +--- +... +-- check for on_schema_reload callback +test_run:cmd("setopt delimiter ';'") +--- +- true +... +do + local a = 0 + function osr_cb() + a = a + 1 + end + local con = net.new(box.cfg.listen, { + wait_connected = false + }) + con:on_schema_reload(osr_cb) + con:wait_connected() + con.space._schema:select{} + box.schema.space.create('misisipi') + box.space.misisipi:drop() + con.space._schema:select{} + con:close() + con = nil + + return a +end; +--- +- 2 +... +do + local a = 0 + function osr_cb() + a = a + 1 + end + local con = net.new(box.cfg.listen, { + wait_connected = true + }) + con:on_schema_reload(osr_cb) + con.space._schema:select{} + box.schema.space.create('misisipi') + box.space.misisipi:drop() + con.space._schema:select{} + con:close() + con = nil + + return a +end; +--- +- 1 +... +test_run:cmd("setopt delimiter ''"); +--- +- true +... +box.schema.user.revoke('guest', 'read', 'space', '_schema') +--- +... diff --git a/test/box/net.box_on_schema_reload-gh-1904.test.lua b/test/box/net.box_on_schema_reload-gh-1904.test.lua new file mode 100644 index 000000000..eeb9def65 --- /dev/null +++ b/test/box/net.box_on_schema_reload-gh-1904.test.lua @@ -0,0 +1,65 @@ +fiber = require 'fiber' +test_run = require('test_run').new() + +LISTEN = require('uri').parse(box.cfg.listen) +space = box.schema.space.create('net_box_test_space') +index = space:create_index('primary', { type = 'tree' }) + +box.schema.user.create('netbox', { password = 'test' }) +box.schema.user.grant('netbox', 'read,write', 'space', 'net_box_test_space') +box.schema.user.grant('netbox', 'execute', 'universe') + +net = require('net.box') + +-- gh-1904 net.box hangs in :close() if a fiber was cancelled +-- while blocked in :_wait_state() in :_request() +options = {user = 'netbox', password = 'badpass', wait_connected = false, reconnect_after = 0.01} +c = net:new(box.cfg.listen, options) +f = fiber.create(function() c:call("") end) +fiber.sleep(0.01) +f:cancel(); c:close() + +box.schema.user.grant('guest', 'read', 'space', '_schema') + +-- check for on_schema_reload callback +test_run:cmd("setopt delimiter ';'") +do + local a = 0 + function osr_cb() + a = a + 1 + end + local con = net.new(box.cfg.listen, { + wait_connected = false + }) + con:on_schema_reload(osr_cb) + con:wait_connected() + con.space._schema:select{} + box.schema.space.create('misisipi') + box.space.misisipi:drop() + con.space._schema:select{} + con:close() + con = nil + + return a +end; +do + local a = 0 + function osr_cb() + a = a + 1 + end + local con = net.new(box.cfg.listen, { + wait_connected = true + }) + con:on_schema_reload(osr_cb) + con.space._schema:select{} + box.schema.space.create('misisipi') + box.space.misisipi:drop() + con.space._schema:select{} + con:close() + con = nil + + return a +end; +test_run:cmd("setopt delimiter ''"); + +box.schema.user.revoke('guest', 'read', 'space', '_schema') diff --git a/test/box/net.box_password_gh-1545.result b/test/box/net.box_password_gh-1545.result new file mode 100644 index 000000000..984084cae --- /dev/null +++ b/test/box/net.box_password_gh-1545.result @@ -0,0 +1,28 @@ +remote = require 'net.box' +--- +... +LISTEN = require('uri').parse(box.cfg.listen) +--- +... +-- #1545 empty password +cn = remote.connect(LISTEN.host, LISTEN.service, { user = 'test' }) +--- +... +cn ~= nil +--- +- true +... +cn:close() +--- +... +cn = remote.connect(LISTEN.host, LISTEN.service, { password = 'test' }) +--- +- error: 'net.box: user is not defined' +... +cn ~= nil +--- +- true +... +cn:close() +--- +... diff --git a/test/box/net.box_password_gh-1545.test.lua b/test/box/net.box_password_gh-1545.test.lua new file mode 100644 index 000000000..86d496432 --- /dev/null +++ b/test/box/net.box_password_gh-1545.test.lua @@ -0,0 +1,10 @@ +remote = require 'net.box' +LISTEN = require('uri').parse(box.cfg.listen) + +-- #1545 empty password +cn = remote.connect(LISTEN.host, LISTEN.service, { user = 'test' }) +cn ~= nil +cn:close() +cn = remote.connect(LISTEN.host, LISTEN.service, { password = 'test' }) +cn ~= nil +cn:close() diff --git a/test/box/net.box_permissions.result b/test/box/net.box_permissions.result new file mode 100644 index 000000000..04729dccb --- /dev/null +++ b/test/box/net.box_permissions.result @@ -0,0 +1,186 @@ +remote = require 'net.box' +--- +... +fiber = require 'fiber' +--- +... +log = require 'log' +--- +... +LISTEN = require('uri').parse(box.cfg.listen) +--- +... +space = box.schema.space.create('net_box_test_space') +--- +... +index = space:create_index('primary', { type = 'tree' }) +--- +... +-- low level connection +log.info("create connection") +--- +... +cn = remote.connect(LISTEN.host, LISTEN.service) +--- +... +log.info("state is %s", cn.state) +--- +... +cn:ping() +--- +- true +... +log.info("ping is done") +--- +... +cn:ping() +--- +- true +... +log.info("ping is done") +--- +... +cn:ping() +--- +- true +... +-- check permissions +cn:call('unexists_procedure') +--- +- error: Execute access to function 'unexists_procedure' is denied for user 'guest' +... +function test_foo(a,b,c) return { {{ [a] = 1 }}, {{ [b] = 2 }}, c } end +--- +... +cn:call('test_foo', {'a', 'b', 'c'}) +--- +- error: Execute access to function 'test_foo' is denied for user 'guest' +... +cn:eval('return 2+2') +--- +- error: Execute access to universe '' is denied for user 'guest' +... +cn:close() +--- +... +-- connect and call without usage access +box.schema.user.grant('guest','execute','universe') +--- +... +box.schema.user.revoke('guest','usage','universe') +--- +... +box.session.su("guest") +--- +... +cn = remote.connect(LISTEN.host, LISTEN.service) +--- +... +cn:call('test_foo', {'a', 'b', 'c'}) +--- +- error: Usage access to universe '' is denied for user 'guest' +... +box.session.su("admin") +--- +... +box.schema.user.grant('guest','usage','universe') +--- +... +cn:close() +--- +... +cn = remote.connect(box.cfg.listen) +--- +... +cn:call('unexists_procedure') +--- +- error: Procedure 'unexists_procedure' is not defined +... +cn:call('test_foo', {'a', 'b', 'c'}) +--- +- [[{'a': 1}], [{'b': 2}], 'c'] +... +cn:call(nil, {'a', 'b', 'c'}) +--- +- error: Procedure 'nil' is not defined +... +cn:eval('return 2+2') +--- +- 4 +... +cn:eval('return 1, 2, 3') +--- +- 1 +- 2 +- 3 +... +cn:eval('return ...', {1, 2, 3}) +--- +- 1 +- 2 +- 3 +... +cn:eval('return { k = "v1" }, true, { xx = 10, yy = 15 }, nil') +--- +- {'k': 'v1'} +- true +- {'yy': 15, 'xx': 10} +- null +... +cn:eval('return nil') +--- +- null +... +cn:eval('return') +--- +... +cn:eval('error("exception")') +--- +- error: 'eval:1: exception' +... +cn:eval('box.error(0)') +--- +- error: Unknown error +... +cn:eval('!invalid expression') +--- +- error: 'eval:1: unexpected symbol near ''!''' +... +-- box.commit() missing at return of CALL/EVAL +function no_commit() box.begin() fiber.sleep(0.001) end +--- +... +cn:call('no_commit') +--- +- error: Transaction is active at return from function +... +cn:eval('no_commit()') +--- +- error: Transaction is active at return from function +... +remote.self:eval('return 1+1, 2+2') +--- +- 2 +- 4 +... +remote.self:eval('return') +--- +... +remote.self:eval('error("exception")') +--- +- error: '[string "error("exception")"]:1: exception' +... +remote.self:eval('box.error(0)') +--- +- error: Unknown error +... +remote.self:eval('!invalid expression') +--- +- error: '[string "return !invalid expression"]:1: unexpected symbol near ''!''' +... +box.schema.user.revoke('guest', 'execute', 'universe') +--- +... +cn:close() +--- +... diff --git a/test/box/net.box_permissions.test.lua b/test/box/net.box_permissions.test.lua new file mode 100644 index 000000000..249604f64 --- /dev/null +++ b/test/box/net.box_permissions.test.lua @@ -0,0 +1,66 @@ +remote = require 'net.box' +fiber = require 'fiber' +log = require 'log' + +LISTEN = require('uri').parse(box.cfg.listen) +space = box.schema.space.create('net_box_test_space') +index = space:create_index('primary', { type = 'tree' }) + +-- low level connection +log.info("create connection") +cn = remote.connect(LISTEN.host, LISTEN.service) +log.info("state is %s", cn.state) + +cn:ping() +log.info("ping is done") +cn:ping() +log.info("ping is done") + + +cn:ping() + + +-- check permissions +cn:call('unexists_procedure') +function test_foo(a,b,c) return { {{ [a] = 1 }}, {{ [b] = 2 }}, c } end +cn:call('test_foo', {'a', 'b', 'c'}) +cn:eval('return 2+2') +cn:close() +-- connect and call without usage access +box.schema.user.grant('guest','execute','universe') +box.schema.user.revoke('guest','usage','universe') +box.session.su("guest") +cn = remote.connect(LISTEN.host, LISTEN.service) +cn:call('test_foo', {'a', 'b', 'c'}) +box.session.su("admin") +box.schema.user.grant('guest','usage','universe') +cn:close() +cn = remote.connect(box.cfg.listen) + +cn:call('unexists_procedure') +cn:call('test_foo', {'a', 'b', 'c'}) +cn:call(nil, {'a', 'b', 'c'}) +cn:eval('return 2+2') +cn:eval('return 1, 2, 3') +cn:eval('return ...', {1, 2, 3}) +cn:eval('return { k = "v1" }, true, { xx = 10, yy = 15 }, nil') +cn:eval('return nil') +cn:eval('return') +cn:eval('error("exception")') +cn:eval('box.error(0)') +cn:eval('!invalid expression') + +-- box.commit() missing at return of CALL/EVAL +function no_commit() box.begin() fiber.sleep(0.001) end +cn:call('no_commit') +cn:eval('no_commit()') + +remote.self:eval('return 1+1, 2+2') +remote.self:eval('return') +remote.self:eval('error("exception")') +remote.self:eval('box.error(0)') +remote.self:eval('!invalid expression') + +box.schema.user.revoke('guest', 'execute', 'universe') + +cn:close() diff --git a/test/box/net.box_pseudo_objects_gh-2401.result b/test/box/net.box_pseudo_objects_gh-2401.result new file mode 100644 index 000000000..46730368f --- /dev/null +++ b/test/box/net.box_pseudo_objects_gh-2401.result @@ -0,0 +1,55 @@ +test_run = require('test_run').new() +--- +... +net = require('net.box') +--- +... +test_run:cmd('create server connecter with script = "box/proxy.lua"') +--- +- true +... +-- +-- gh-2401 update pseudo objects not replace them +-- +space = box.schema.space.create('test') +--- +... +box.schema.user.grant('guest', 'read', 'space', 'test') +--- +... +c = net.connect(box.cfg.listen) +--- +... +cspace = c.space.test +--- +... +space.index.test_index == nil +--- +- true +... +cspace.index.test_index == nil +--- +- true +... +_ = space:create_index("test_index", {parts={1, 'string'}}) +--- +... +c:reload_schema() +--- +... +space.index.test_index ~= nil +--- +- true +... +cspace.index.test_index ~= nil +--- +- true +... +c.space.test.index.test_index ~= nil +--- +- true +... +-- cleanup +space:drop() +--- +... diff --git a/test/box/net.box_pseudo_objects_gh-2401.test.lua b/test/box/net.box_pseudo_objects_gh-2401.test.lua new file mode 100644 index 000000000..b9277ae94 --- /dev/null +++ b/test/box/net.box_pseudo_objects_gh-2401.test.lua @@ -0,0 +1,23 @@ +test_run = require('test_run').new() +net = require('net.box') + +test_run:cmd('create server connecter with script = "box/proxy.lua"') + +-- +-- gh-2401 update pseudo objects not replace them +-- +space = box.schema.space.create('test') +box.schema.user.grant('guest', 'read', 'space', 'test') +c = net.connect(box.cfg.listen) +cspace = c.space.test +space.index.test_index == nil +cspace.index.test_index == nil +_ = space:create_index("test_index", {parts={1, 'string'}}) +c:reload_schema() +space.index.test_index ~= nil +cspace.index.test_index ~= nil +c.space.test.index.test_index ~= nil + +-- cleanup + +space:drop() diff --git a/test/box/net.box_raw_response_gh-3107.result b/test/box/net.box_raw_response_gh-3107.result new file mode 100644 index 000000000..85fef9daf --- /dev/null +++ b/test/box/net.box_raw_response_gh-3107.result @@ -0,0 +1,123 @@ +fiber = require 'fiber' +--- +... +msgpack = require 'msgpack' +--- +... +net = require('net.box') +--- +... +-- +-- gh-3107: fiber-async netbox. +-- +cond = nil +--- +... +box.schema.func.create('long_function') +--- +... +box.schema.user.grant('guest', 'execute', 'function', 'long_function') +--- +... +function long_function(...) cond = fiber.cond() cond:wait() return ... end +--- +... +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end +--- +... +s = box.schema.create_space('test') +--- +... +pk = s:create_index('pk') +--- +... +s:replace{1} +--- +- [1] +... +s:replace{2} +--- +- [2] +... +s:replace{3} +--- +- [3] +... +s:replace{4} +--- +- [4] +... +c = net:connect(box.cfg.listen) +--- +... +-- +-- Ensure a request can be finalized from non-caller fibers. +-- +future = c:call('long_function', {1, 2, 3}, {is_async = true}) +--- +... +ret = {} +--- +... +count = 0 +--- +... +for i = 1, 10 do fiber.create(function() ret[i] = future:wait_result(1000) count = count + 1 end) end +--- +... +future:wait_result(0.01) -- Must fail on timeout. +--- +- null +- Timeout exceeded +... +finalize_long() +--- +... +while count ~= 10 do fiber.sleep(0.1) end +--- +... +ret +--- +- - &0 [1, 2, 3] + - *0 + - *0 + - *0 + - *0 + - *0 + - *0 + - *0 + - *0 + - *0 +... +-- +-- Test raw response getting. +-- +ibuf = require('buffer').ibuf() +--- +... +future = c:call('long_function', {1, 2, 3}, {is_async = true, buffer = ibuf}) +--- +... +finalize_long() +--- +... +future:wait_result(100) +--- +- 10 +... +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +--- +... +result +--- +- {48: [1, 2, 3]} +... +box.schema.func.drop('long_function') +--- +... +c:close() +--- +... +s:drop() +--- +... diff --git a/test/box/net.box_raw_response_gh-3107.test.lua b/test/box/net.box_raw_response_gh-3107.test.lua new file mode 100644 index 000000000..fa477d6d7 --- /dev/null +++ b/test/box/net.box_raw_response_gh-3107.test.lua @@ -0,0 +1,46 @@ +fiber = require 'fiber' +msgpack = require 'msgpack' +net = require('net.box') + +-- +-- gh-3107: fiber-async netbox. +-- +cond = nil +box.schema.func.create('long_function') +box.schema.user.grant('guest', 'execute', 'function', 'long_function') +function long_function(...) cond = fiber.cond() cond:wait() return ... end +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end +s = box.schema.create_space('test') +pk = s:create_index('pk') +s:replace{1} +s:replace{2} +s:replace{3} +s:replace{4} +c = net:connect(box.cfg.listen) + +-- +-- Ensure a request can be finalized from non-caller fibers. +-- +future = c:call('long_function', {1, 2, 3}, {is_async = true}) +ret = {} +count = 0 +for i = 1, 10 do fiber.create(function() ret[i] = future:wait_result(1000) count = count + 1 end) end +future:wait_result(0.01) -- Must fail on timeout. +finalize_long() +while count ~= 10 do fiber.sleep(0.1) end +ret + +-- +-- Test raw response getting. +-- +ibuf = require('buffer').ibuf() +future = c:call('long_function', {1, 2, 3}, {is_async = true, buffer = ibuf}) +finalize_long() +future:wait_result(100) +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) +result + +box.schema.func.drop('long_function') + +c:close() +s:drop() diff --git a/test/box/net.box_readahead_gh-3958.result b/test/box/net.box_readahead_gh-3958.result new file mode 100644 index 000000000..fc2093531 --- /dev/null +++ b/test/box/net.box_readahead_gh-3958.result @@ -0,0 +1,55 @@ +test_run = require('test_run').new() +--- +... +net = require('net.box') +--- +... +-- +-- gh-3958 updating box.cfg.readahead doesn't affect existing connections. +-- +readahead = box.cfg.readahead +--- +... +box.cfg{readahead = 128} +--- +... +s = box.schema.space.create("test") +--- +... +_ = s:create_index("pk") +--- +... +box.schema.user.grant("guest", "read,write", "space", "test") +--- +... +-- connection is created with small readahead value, +-- make sure it is updated if box.cfg.readahead is changed. +c = net.connect(box.cfg.listen) +--- +... +box.cfg{readahead = 100 * 1024} +--- +... +box.error.injection.set("ERRINJ_WAL_DELAY", true) +--- +- ok +... +pad = string.rep('x', 8192) +--- +... +for i = 1, 5 do c.space.test:replace({i, pad}, {is_async = true}) end +--- +... +box.error.injection.set("ERRINJ_WAL_DELAY", false) +--- +- ok +... +test_run:wait_log('default', 'readahead limit is reached', 1024, 0.1) +--- +... +s:drop() +--- +... +box.cfg{readahead = readahead} +--- +... diff --git a/test/box/net.box_readahead_gh-3958.test.lua b/test/box/net.box_readahead_gh-3958.test.lua new file mode 100644 index 000000000..1e33a84cb --- /dev/null +++ b/test/box/net.box_readahead_gh-3958.test.lua @@ -0,0 +1,29 @@ +test_run = require('test_run').new() +net = require('net.box') + +-- +-- gh-3958 updating box.cfg.readahead doesn't affect existing connections. +-- +readahead = box.cfg.readahead + +box.cfg{readahead = 128} + +s = box.schema.space.create("test") +_ = s:create_index("pk") +box.schema.user.grant("guest", "read,write", "space", "test") + +-- connection is created with small readahead value, +-- make sure it is updated if box.cfg.readahead is changed. +c = net.connect(box.cfg.listen) + +box.cfg{readahead = 100 * 1024} + +box.error.injection.set("ERRINJ_WAL_DELAY", true) +pad = string.rep('x', 8192) +for i = 1, 5 do c.space.test:replace({i, pad}, {is_async = true}) end +box.error.injection.set("ERRINJ_WAL_DELAY", false) + +test_run:wait_log('default', 'readahead limit is reached', 1024, 0.1) + +s:drop() +box.cfg{readahead = readahead} diff --git a/test/box/net.box_reconnect_after.result b/test/box/net.box_reconnect_after.result new file mode 100644 index 000000000..a75f9dc5c --- /dev/null +++ b/test/box/net.box_reconnect_after.result @@ -0,0 +1,32 @@ +fiber = require 'fiber' +--- +... +net = require('net.box') +--- +... +box.schema.user.grant('guest', 'execute', 'universe') +--- +... +-- +-- Test a case, when netbox can not connect first time, but +-- reconnect_after is set. +-- +c = net.connect('localhost:33333', {reconnect_after = 0.1, wait_connected = false}) +--- +... +while c.state ~= 'error_reconnect' do fiber.sleep(0.01) end +--- +... +c:close() +--- +... +box.schema.user.revoke('guest', 'execute', 'universe') +--- +... +c.state +--- +- closed +... +c = nil +--- +... diff --git a/test/box/net.box_reconnect_after.test.lua b/test/box/net.box_reconnect_after.test.lua new file mode 100644 index 000000000..8ad870475 --- /dev/null +++ b/test/box/net.box_reconnect_after.test.lua @@ -0,0 +1,16 @@ +fiber = require 'fiber' +net = require('net.box') + +box.schema.user.grant('guest', 'execute', 'universe') + +-- +-- Test a case, when netbox can not connect first time, but +-- reconnect_after is set. +-- +c = net.connect('localhost:33333', {reconnect_after = 0.1, wait_connected = false}) +while c.state ~= 'error_reconnect' do fiber.sleep(0.01) end +c:close() + +box.schema.user.revoke('guest', 'execute', 'universe') +c.state +c = nil diff --git a/test/box/net.box_reconnect_after_gh-3164.result b/test/box/net.box_reconnect_after_gh-3164.result new file mode 100644 index 000000000..216ce0366 --- /dev/null +++ b/test/box/net.box_reconnect_after_gh-3164.result @@ -0,0 +1,119 @@ +fiber = require 'fiber' +--- +... +log = require 'log' +--- +... +test_run = require('test_run').new() +--- +... +net = require('net.box') +--- +... +test_run:cmd('create server connecter with script = "box/proxy.lua"') +--- +- true +... +-- +-- gh-3164: netbox connection is not closed and garbage collected +-- ever, if reconnect_after is set. +-- +test_run:cmd('start server connecter') +--- +- true +... +test_run:cmd("set variable connect_to to 'connecter.listen'") +--- +- true +... +weak = setmetatable({}, {__mode = 'v'}) +--- +... +-- Create strong and weak reference. Weak is valid until strong +-- is valid too. +strong = net.connect(connect_to, {reconnect_after = 0.1}) +--- +... +weak.c = strong +--- +... +weak.c:ping() +--- +- true +... +test_run:cmd('stop server connecter') +--- +- true +... +test_run:cmd('cleanup server connecter') +--- +- true +... +-- Check the connection tries to reconnect at least two times. +-- 'Cannot assign requested address' is the crutch for running the +-- tests in a docker. This error emits instead of +-- 'Connection refused' inside a docker. +old_log_level = box.cfg.log_level +--- +... +box.cfg{log_level = 6} +--- +... +log.info(string.rep('a', 1000)) +--- +... +test_run:cmd("setopt delimiter ';'") +--- +- true +... +while test_run:grep_log('default', 'Network is unreachable', 1000) == nil and + test_run:grep_log('default', 'Connection refused', 1000) == nil and + test_run:grep_log('default', 'Cannot assign requested address', 1000) == nil do + fiber.sleep(0.1) +end; +--- +... +log.info(string.rep('a', 1000)); +--- +... +while test_run:grep_log('default', 'Network is unreachable', 1000) == nil and + test_run:grep_log('default', 'Connection refused', 1000) == nil and + test_run:grep_log('default', 'Cannot assign requested address', 1000) == nil do + fiber.sleep(0.1) +end; +--- +... +test_run:cmd("setopt delimiter ''"); +--- +- true +... +box.cfg{log_level = old_log_level} +--- +... +collectgarbage('collect') +--- +- 0 +... +strong.state +--- +- error_reconnect +... +strong == weak.c +--- +- true +... +-- Remove single strong reference. Now connection must be garbage +-- collected. +strong = nil +--- +... +collectgarbage('collect') +--- +- 0 +... +-- Now weak.c is null, because it was weak reference, and the +-- connection is deleted by 'collect'. +weak.c +--- +- null +... diff --git a/test/box/net.box_reconnect_after_gh-3164.test.lua b/test/box/net.box_reconnect_after_gh-3164.test.lua new file mode 100644 index 000000000..dc2747080 --- /dev/null +++ b/test/box/net.box_reconnect_after_gh-3164.test.lua @@ -0,0 +1,52 @@ +fiber = require 'fiber' +log = require 'log' +test_run = require('test_run').new() +net = require('net.box') + +test_run:cmd('create server connecter with script = "box/proxy.lua"') + +-- +-- gh-3164: netbox connection is not closed and garbage collected +-- ever, if reconnect_after is set. +-- +test_run:cmd('start server connecter') +test_run:cmd("set variable connect_to to 'connecter.listen'") +weak = setmetatable({}, {__mode = 'v'}) +-- Create strong and weak reference. Weak is valid until strong +-- is valid too. +strong = net.connect(connect_to, {reconnect_after = 0.1}) +weak.c = strong +weak.c:ping() +test_run:cmd('stop server connecter') +test_run:cmd('cleanup server connecter') +-- Check the connection tries to reconnect at least two times. +-- 'Cannot assign requested address' is the crutch for running the +-- tests in a docker. This error emits instead of +-- 'Connection refused' inside a docker. +old_log_level = box.cfg.log_level +box.cfg{log_level = 6} +log.info(string.rep('a', 1000)) +test_run:cmd("setopt delimiter ';'") +while test_run:grep_log('default', 'Network is unreachable', 1000) == nil and + test_run:grep_log('default', 'Connection refused', 1000) == nil and + test_run:grep_log('default', 'Cannot assign requested address', 1000) == nil do + fiber.sleep(0.1) +end; +log.info(string.rep('a', 1000)); +while test_run:grep_log('default', 'Network is unreachable', 1000) == nil and + test_run:grep_log('default', 'Connection refused', 1000) == nil and + test_run:grep_log('default', 'Cannot assign requested address', 1000) == nil do + fiber.sleep(0.1) +end; +test_run:cmd("setopt delimiter ''"); +box.cfg{log_level = old_log_level} +collectgarbage('collect') +strong.state +strong == weak.c +-- Remove single strong reference. Now connection must be garbage +-- collected. +strong = nil +collectgarbage('collect') +-- Now weak.c is null, because it was weak reference, and the +-- connection is deleted by 'collect'. +weak.c diff --git a/test/box/net.box_reload_schema_gh-636.result b/test/box/net.box_reload_schema_gh-636.result new file mode 100644 index 000000000..43e8e8b29 --- /dev/null +++ b/test/box/net.box_reload_schema_gh-636.result @@ -0,0 +1,108 @@ +remote = require 'net.box' +--- +... +fiber = require 'fiber' +--- +... +test_run = require('test_run').new() +--- +... +-- #636: Reload schema on demand +sp = box.schema.space.create('test_old') +--- +... +_ = sp:create_index('primary') +--- +... +sp:insert{1, 2, 3} +--- +- [1, 2, 3] +... +box.schema.user.grant('guest', 'read', 'space', 'test_old') +--- +... +con = remote.new(box.cfg.listen) +--- +... +con:ping() +--- +- true +... +con.space.test_old:select{} +--- +- - [1, 2, 3] +... +con.space.test == nil +--- +- true +... +sp = box.schema.space.create('test') +--- +... +_ = sp:create_index('primary') +--- +... +sp:insert{2, 3, 4} +--- +- [2, 3, 4] +... +box.schema.user.grant('guest', 'read', 'space', 'test') +--- +... +con.space.test == nil +--- +- true +... +con:reload_schema() +--- +... +con.space.test:select{} +--- +- - [2, 3, 4] +... +box.space.test:drop() +--- +... +box.space.test_old:drop() +--- +... +con:close() +--- +... +name = string.match(arg[0], "([^,]+)%.lua") +--- +... +file_log = require('fio').open(name .. '.log', {'O_RDONLY', 'O_NONBLOCK'}) +--- +... +file_log:seek(0, 'SEEK_END') ~= 0 +--- +- true +... +box.schema.user.grant('guest', 'execute', 'universe') +--- +... +test_run:cmd("setopt delimiter ';'") +--- +- true +... +_ = fiber.create( + function() + local conn = require('net.box').new(box.cfg.listen) + conn:call('no_such_function', {}) + conn:close() + end +); +--- +... +test_run:cmd("setopt delimiter ''"); +--- +- true +... +test_run:wait_log('default', 'ER_NO_SUCH_PROC', nil, 10) +--- +- ER_NO_SUCH_PROC +... +box.schema.user.revoke('guest', 'execute', 'universe') +--- +... diff --git a/test/box/net.box_reload_schema_gh-636.test.lua b/test/box/net.box_reload_schema_gh-636.test.lua new file mode 100644 index 000000000..d7431ee6c --- /dev/null +++ b/test/box/net.box_reload_schema_gh-636.test.lua @@ -0,0 +1,46 @@ +remote = require 'net.box' +fiber = require 'fiber' +test_run = require('test_run').new() + +-- #636: Reload schema on demand +sp = box.schema.space.create('test_old') +_ = sp:create_index('primary') +sp:insert{1, 2, 3} + +box.schema.user.grant('guest', 'read', 'space', 'test_old') +con = remote.new(box.cfg.listen) +con:ping() +con.space.test_old:select{} +con.space.test == nil + +sp = box.schema.space.create('test') +_ = sp:create_index('primary') +sp:insert{2, 3, 4} + +box.schema.user.grant('guest', 'read', 'space', 'test') + +con.space.test == nil +con:reload_schema() +con.space.test:select{} + +box.space.test:drop() +box.space.test_old:drop() +con:close() + +name = string.match(arg[0], "([^,]+)%.lua") +file_log = require('fio').open(name .. '.log', {'O_RDONLY', 'O_NONBLOCK'}) +file_log:seek(0, 'SEEK_END') ~= 0 + +box.schema.user.grant('guest', 'execute', 'universe') +test_run:cmd("setopt delimiter ';'") + +_ = fiber.create( + function() + local conn = require('net.box').new(box.cfg.listen) + conn:call('no_such_function', {}) + conn:close() + end +); +test_run:cmd("setopt delimiter ''"); +test_run:wait_log('default', 'ER_NO_SUCH_PROC', nil, 10) +box.schema.user.revoke('guest', 'execute', 'universe') diff --git a/test/box/net.box_remote_method_gh-544.result b/test/box/net.box_remote_method_gh-544.result new file mode 100644 index 000000000..bb92ba998 --- /dev/null +++ b/test/box/net.box_remote_method_gh-544.result @@ -0,0 +1,95 @@ +remote = require 'net.box' +--- +... +LISTEN = require('uri').parse(box.cfg.listen) +--- +... +box.schema.user.create('netbox', { password = 'test' }) +--- +... +-- #544 usage for remote[point]method +cn = remote.connect(LISTEN.host, LISTEN.service) +--- +... +box.schema.user.grant('guest', 'execute', 'universe') +--- +... +cn:close() +--- +... +cn = remote.connect(LISTEN.host, LISTEN.service) +--- +... +cn:eval('return true') +--- +- true +... +cn.eval('return true') +--- +- error: 'Use remote:eval(...) instead of remote.eval(...):' +... +cn.ping() +--- +- error: 'Use remote:ping(...) instead of remote.ping(...):' +... +cn:close() +--- +... +remote.self:eval('return true') +--- +- true +... +remote.self.eval('return true') +--- +- error: 'Use remote:eval(...) instead of remote.eval(...):' +... +box.schema.user.revoke('guest', 'execute', 'universe') +--- +... +-- uri as the first argument +uri = string.format('%s:%s@%s:%s', 'netbox', 'test', LISTEN.host, LISTEN.service) +--- +... +cn = remote.new(uri) +--- +... +cn:ping() +--- +- true +... +cn:close() +--- +... +uri = string.format('%s@%s:%s', 'netbox', LISTEN.host, LISTEN.service) +--- +... +cn = remote.new(uri) +--- +... +cn ~= nil, cn.state, cn.error +--- +- true +- error +- Incorrect password supplied for user 'netbox' +... +cn:close() +--- +... +-- don't merge creds from uri & opts +remote.new(uri, { password = 'test' }) +--- +- error: 'net.box: user is not defined' +... +cn = remote.new(uri, { user = 'netbox', password = 'test' }) +--- +... +cn:ping() +--- +- true +... +cn:close() +--- +... +box.schema.user.drop('netbox') +--- +... diff --git a/test/box/net.box_remote_method_gh-544.test.lua b/test/box/net.box_remote_method_gh-544.test.lua new file mode 100644 index 000000000..cfd883be0 --- /dev/null +++ b/test/box/net.box_remote_method_gh-544.test.lua @@ -0,0 +1,40 @@ +remote = require 'net.box' + +LISTEN = require('uri').parse(box.cfg.listen) +box.schema.user.create('netbox', { password = 'test' }) + +-- #544 usage for remote[point]method +cn = remote.connect(LISTEN.host, LISTEN.service) + +box.schema.user.grant('guest', 'execute', 'universe') +cn:close() +cn = remote.connect(LISTEN.host, LISTEN.service) +cn:eval('return true') +cn.eval('return true') + +cn.ping() + +cn:close() + +remote.self:eval('return true') +remote.self.eval('return true') +box.schema.user.revoke('guest', 'execute', 'universe') + +-- uri as the first argument +uri = string.format('%s:%s@%s:%s', 'netbox', 'test', LISTEN.host, LISTEN.service) + +cn = remote.new(uri) +cn:ping() +cn:close() + +uri = string.format('%s@%s:%s', 'netbox', LISTEN.host, LISTEN.service) +cn = remote.new(uri) +cn ~= nil, cn.state, cn.error +cn:close() +-- don't merge creds from uri & opts +remote.new(uri, { password = 'test' }) +cn = remote.new(uri, { user = 'netbox', password = 'test' }) +cn:ping() +cn:close() + +box.schema.user.drop('netbox') diff --git a/test/box/net.box_roll_back_gh-822.result b/test/box/net.box_roll_back_gh-822.result new file mode 100644 index 000000000..5a0550e39 --- /dev/null +++ b/test/box/net.box_roll_back_gh-822.result @@ -0,0 +1,68 @@ +remote = require 'net.box' +--- +... +test_run = require('test_run').new() +--- +... +-- +-- gh-822: net.box.call should roll back local transaction on error +-- +_ = box.schema.space.create('gh822') +--- +... +_ = box.space.gh822:create_index('primary') +--- +... +test_run:cmd("setopt delimiter ';'") +--- +- true +... +-- rollback on invalid function +function rollback_on_invalid_function() + box.begin() + box.space.gh822:insert{1, "netbox_test"} + pcall(remote.self.call, remote.self, 'invalid_function') + return box.space.gh822:get(1) == nil +end; +--- +... +rollback_on_invalid_function(); +--- +- true +... +-- rollback on call error +function test_error() error('Some error') end; +--- +... +function rollback_on_call_error() + box.begin() + box.space.gh822:insert{1, "netbox_test"} + pcall(remote.self.call, remote.self, 'test_error') + return box.space.gh822:get(1) == nil +end; +--- +... +rollback_on_call_error(); +--- +- true +... +-- rollback on eval +function rollback_on_eval_error() + box.begin() + box.space.gh822:insert{1, "netbox_test"} + pcall(remote.self.eval, remote.self, "error('Some error')") + return box.space.gh822:get(1) == nil +end; +--- +... +rollback_on_eval_error(); +--- +- true +... +test_run:cmd("setopt delimiter ''"); +--- +- true +... +box.space.gh822:drop() +--- +... diff --git a/test/box/net.box_roll_back_gh-822.test.lua b/test/box/net.box_roll_back_gh-822.test.lua new file mode 100644 index 000000000..8f4754902 --- /dev/null +++ b/test/box/net.box_roll_back_gh-822.test.lua @@ -0,0 +1,42 @@ +remote = require 'net.box' +test_run = require('test_run').new() + +-- +-- gh-822: net.box.call should roll back local transaction on error +-- + +_ = box.schema.space.create('gh822') +_ = box.space.gh822:create_index('primary') + +test_run:cmd("setopt delimiter ';'") + +-- rollback on invalid function +function rollback_on_invalid_function() + box.begin() + box.space.gh822:insert{1, "netbox_test"} + pcall(remote.self.call, remote.self, 'invalid_function') + return box.space.gh822:get(1) == nil +end; +rollback_on_invalid_function(); + +-- rollback on call error +function test_error() error('Some error') end; +function rollback_on_call_error() + box.begin() + box.space.gh822:insert{1, "netbox_test"} + pcall(remote.self.call, remote.self, 'test_error') + return box.space.gh822:get(1) == nil +end; +rollback_on_call_error(); + +-- rollback on eval +function rollback_on_eval_error() + box.begin() + box.space.gh822:insert{1, "netbox_test"} + pcall(remote.self.eval, remote.self, "error('Some error')") + return box.space.gh822:get(1) == nil +end; +rollback_on_eval_error(); + +test_run:cmd("setopt delimiter ''"); +box.space.gh822:drop() diff --git a/test/box/net.box_schema_change_gh-2666.result b/test/box/net.box_schema_change_gh-2666.result new file mode 100644 index 000000000..bce46bd59 --- /dev/null +++ b/test/box/net.box_schema_change_gh-2666.result @@ -0,0 +1,79 @@ +net = require('net.box') +--- +... +-- +-- gh-2666: check that netbox.call is not repeated on schema +-- change. +-- +box.schema.user.grant('guest', 'write', 'space', '_space') +--- +... +box.schema.user.grant('guest', 'write', 'space', '_schema') +--- +... +box.schema.user.grant('guest', 'create', 'universe') +--- +... +count = 0 +--- +... +function create_space(name) count = count + 1 box.schema.create_space(name) return true end +--- +... +box.schema.func.create('create_space') +--- +... +box.schema.user.grant('guest', 'execute', 'function', 'create_space') +--- +... +c = net.connect(box.cfg.listen) +--- +... +c:call('create_space', {'test1'}) +--- +- true +... +count +--- +- 1 +... +c:call('create_space', {'test2'}) +--- +- true +... +count +--- +- 2 +... +c:call('create_space', {'test3'}) +--- +- true +... +count +--- +- 3 +... +box.space.test1:drop() +--- +... +box.space.test2:drop() +--- +... +box.space.test3:drop() +--- +... +box.schema.user.revoke('guest', 'write', 'space', '_space') +--- +... +box.schema.user.revoke('guest', 'write', 'space', '_schema') +--- +... +box.schema.user.revoke('guest', 'create', 'universe') +--- +... +c:close() +--- +... +box.schema.func.drop('create_space') +--- +... diff --git a/test/box/net.box_schema_change_gh-2666.test.lua b/test/box/net.box_schema_change_gh-2666.test.lua new file mode 100644 index 000000000..16e28e092 --- /dev/null +++ b/test/box/net.box_schema_change_gh-2666.test.lua @@ -0,0 +1,28 @@ +net = require('net.box') + +-- +-- gh-2666: check that netbox.call is not repeated on schema +-- change. +-- +box.schema.user.grant('guest', 'write', 'space', '_space') +box.schema.user.grant('guest', 'write', 'space', '_schema') +box.schema.user.grant('guest', 'create', 'universe') +count = 0 +function create_space(name) count = count + 1 box.schema.create_space(name) return true end +box.schema.func.create('create_space') +box.schema.user.grant('guest', 'execute', 'function', 'create_space') +c = net.connect(box.cfg.listen) +c:call('create_space', {'test1'}) +count +c:call('create_space', {'test2'}) +count +c:call('create_space', {'test3'}) +count +box.space.test1:drop() +box.space.test2:drop() +box.space.test3:drop() +box.schema.user.revoke('guest', 'write', 'space', '_space') +box.schema.user.revoke('guest', 'write', 'space', '_schema') +box.schema.user.revoke('guest', 'create', 'universe') +c:close() +box.schema.func.drop('create_space') diff --git a/test/box/net.box_schema_change_gh-3107.result b/test/box/net.box_schema_change_gh-3107.result new file mode 100644 index 000000000..233c83307 --- /dev/null +++ b/test/box/net.box_schema_change_gh-3107.result @@ -0,0 +1,151 @@ +fiber = require 'fiber' +--- +... +net = require('net.box') +--- +... +-- +-- gh-3107: fiber-async netbox. +-- +cond = nil +--- +... +box.schema.func.create('long_function') +--- +... +box.schema.user.grant('guest', 'execute', 'function', 'long_function') +--- +... +function long_function(...) cond = fiber.cond() cond:wait() return ... end +--- +... +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end +--- +... +s = box.schema.create_space('test') +--- +... +pk = s:create_index('pk') +--- +... +s:replace{1} +--- +- [1] +... +s:replace{2} +--- +- [2] +... +s:replace{3} +--- +- [3] +... +s:replace{4} +--- +- [4] +... +c = net:connect(box.cfg.listen) +--- +... +-- +-- Ensure a request can be finalized from non-caller fibers. +-- +future = c:call('long_function', {1, 2, 3}, {is_async = true}) +--- +... +ret = {} +--- +... +count = 0 +--- +... +for i = 1, 10 do fiber.create(function() ret[i] = future:wait_result(1000) count = count + 1 end) end +--- +... +future:wait_result(0.01) -- Must fail on timeout. +--- +- null +- Timeout exceeded +... +finalize_long() +--- +... +while count ~= 10 do fiber.sleep(0.1) end +--- +... +ret +--- +- - &0 [1, 2, 3] + - *0 + - *0 + - *0 + - *0 + - *0 + - *0 + - *0 + - *0 + - *0 +... +box.schema.func.drop('long_function') +--- +... +-- +-- Test async schema version change. +-- +function change_schema(i) local tmp = box.schema.create_space('test'..i) return 'ok' end +--- +... +box.schema.func.create('change_schema') +--- +... +box.schema.user.grant('guest', 'execute', 'function', 'change_schema') +--- +... +box.schema.user.grant('guest', 'write', 'space', '_schema') +--- +... +box.schema.user.grant('guest', 'read,write', 'space', '_space') +--- +... +box.schema.user.grant('guest', 'create', 'space') +--- +... +future1 = c:call('change_schema', {'1'}, {is_async = true}) +--- +... +future2 = c:call('change_schema', {'2'}, {is_async = true}) +--- +... +future3 = c:call('change_schema', {'3'}, {is_async = true}) +--- +... +future1:wait_result() +--- +- ['ok'] +... +future2:wait_result() +--- +- ['ok'] +... +future3:wait_result() +--- +- ['ok'] +... +c:close() +--- +... +s:drop() +--- +... +box.schema.func.drop('change_schema') +--- +... +box.schema.user.revoke('guest', 'write', 'space', '_schema') +--- +... +box.schema.user.revoke('guest', 'read,write', 'space', '_space') +--- +... +box.schema.user.revoke('guest', 'create', 'space') +--- +... diff --git a/test/box/net.box_schema_change_gh-3107.test.lua b/test/box/net.box_schema_change_gh-3107.test.lua new file mode 100644 index 000000000..c73788455 --- /dev/null +++ b/test/box/net.box_schema_change_gh-3107.test.lua @@ -0,0 +1,55 @@ +fiber = require 'fiber' +net = require('net.box') + +-- +-- gh-3107: fiber-async netbox. +-- +cond = nil +box.schema.func.create('long_function') +box.schema.user.grant('guest', 'execute', 'function', 'long_function') +function long_function(...) cond = fiber.cond() cond:wait() return ... end +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end +s = box.schema.create_space('test') +pk = s:create_index('pk') +s:replace{1} +s:replace{2} +s:replace{3} +s:replace{4} +c = net:connect(box.cfg.listen) + +-- +-- Ensure a request can be finalized from non-caller fibers. +-- +future = c:call('long_function', {1, 2, 3}, {is_async = true}) +ret = {} +count = 0 +for i = 1, 10 do fiber.create(function() ret[i] = future:wait_result(1000) count = count + 1 end) end +future:wait_result(0.01) -- Must fail on timeout. +finalize_long() +while count ~= 10 do fiber.sleep(0.1) end +ret + +box.schema.func.drop('long_function') + +-- +-- Test async schema version change. +-- +function change_schema(i) local tmp = box.schema.create_space('test'..i) return 'ok' end +box.schema.func.create('change_schema') +box.schema.user.grant('guest', 'execute', 'function', 'change_schema') +box.schema.user.grant('guest', 'write', 'space', '_schema') +box.schema.user.grant('guest', 'read,write', 'space', '_space') +box.schema.user.grant('guest', 'create', 'space') +future1 = c:call('change_schema', {'1'}, {is_async = true}) +future2 = c:call('change_schema', {'2'}, {is_async = true}) +future3 = c:call('change_schema', {'3'}, {is_async = true}) +future1:wait_result() +future2:wait_result() +future3:wait_result() + +c:close() +s:drop() +box.schema.func.drop('change_schema') +box.schema.user.revoke('guest', 'write', 'space', '_schema') +box.schema.user.revoke('guest', 'read,write', 'space', '_space') +box.schema.user.revoke('guest', 'create', 'space') diff --git a/test/box/net.box_session_type_gh-2642.result b/test/box/net.box_session_type_gh-2642.result new file mode 100644 index 000000000..0e043f6e5 --- /dev/null +++ b/test/box/net.box_session_type_gh-2642.result @@ -0,0 +1,22 @@ +net = require('net.box') +--- +... +-- +-- gh-2642: box.session.type() +-- +box.schema.user.grant('guest','execute','universe') +--- +... +c = net.connect(box.cfg.listen) +--- +... +c:call("box.session.type") +--- +- binary +... +c:close() +--- +... +box.schema.user.revoke('guest', 'execute', 'universe') +--- +... diff --git a/test/box/net.box_session_type_gh-2642.test.lua b/test/box/net.box_session_type_gh-2642.test.lua new file mode 100644 index 000000000..4e3cf5265 --- /dev/null +++ b/test/box/net.box_session_type_gh-2642.test.lua @@ -0,0 +1,11 @@ +net = require('net.box') + +-- +-- gh-2642: box.session.type() +-- + +box.schema.user.grant('guest','execute','universe') +c = net.connect(box.cfg.listen) +c:call("box.session.type") +c:close() +box.schema.user.revoke('guest', 'execute', 'universe') diff --git a/test/box/net.box_space_format_gh-2402.result b/test/box/net.box_space_format_gh-2402.result new file mode 100644 index 000000000..c66665c73 --- /dev/null +++ b/test/box/net.box_space_format_gh-2402.result @@ -0,0 +1,49 @@ +net = require('net.box') +--- +... +-- +-- gh-2402 net.box doesn't support space:format() +-- +space = box.schema.space.create('test', {format={{name="id", type="unsigned"}}}) +--- +... +space ~= nil +--- +- true +... +_ = box.space.test:create_index('primary') +--- +... +box.schema.user.grant('guest', 'read', 'space', 'test') +--- +... +c = net.connect(box.cfg.listen) +--- +... +c:ping() +--- +- true +... +c.space.test ~= nil +--- +- true +... +format = c.space.test:format() +--- +... +format[1] ~= nil +--- +- true +... +format[1].name == "id" +--- +- true +... +format[1].type == "unsigned" +--- +- true +... +c.space.test:format({}) +--- +- error: net.box does not support setting space format +... diff --git a/test/box/net.box_space_format_gh-2402.test.lua b/test/box/net.box_space_format_gh-2402.test.lua new file mode 100644 index 000000000..020f20da6 --- /dev/null +++ b/test/box/net.box_space_format_gh-2402.test.lua @@ -0,0 +1,23 @@ +net = require('net.box') + +-- +-- gh-2402 net.box doesn't support space:format() +-- + +space = box.schema.space.create('test', {format={{name="id", type="unsigned"}}}) +space ~= nil +_ = box.space.test:create_index('primary') +box.schema.user.grant('guest', 'read', 'space', 'test') + +c = net.connect(box.cfg.listen) + +c:ping() +c.space.test ~= nil + +format = c.space.test:format() + +format[1] ~= nil +format[1].name == "id" +format[1].type == "unsigned" + +c.space.test:format({}) diff --git a/test/box/net.box_timeout-gh-3107.result b/test/box/net.box_timeout-gh-3107.result new file mode 100644 index 000000000..be7f9606c --- /dev/null +++ b/test/box/net.box_timeout-gh-3107.result @@ -0,0 +1,125 @@ +-- test-run result file version 2 +fiber = require 'fiber' + | --- + | ... +net = require('net.box') + | --- + | ... + +-- +-- gh-3107: fiber-async netbox. +-- +cond = nil + | --- + | ... +box.schema.func.create('long_function') + | --- + | ... +box.schema.user.grant('guest', 'execute', 'function', 'long_function') + | --- + | ... +function long_function(...) cond = fiber.cond() cond:wait() return ... end + | --- + | ... +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end + | --- + | ... +s = box.schema.create_space('test') + | --- + | ... +pk = s:create_index('pk') + | --- + | ... +s:replace{1} + | --- + | - [1] + | ... +s:replace{2} + | --- + | - [2] + | ... +s:replace{3} + | --- + | - [3] + | ... +s:replace{4} + | --- + | - [4] + | ... +c = net:connect(box.cfg.listen) + | --- + | ... + +-- +-- Check infinity timeout. +-- +ret = nil + | --- + | ... +_ = fiber.create(function() ret = c:call('long_function', {1, 2, 3}, {is_async = true}):wait_result() end) + | --- + | ... +finalize_long() + | --- + | ... +while not ret do fiber.sleep(0.01) end + | --- + | ... +ret + | --- + | - [1, 2, 3] + | ... +c:close() + | --- + | ... +box.schema.user.grant('guest', 'execute', 'universe') + | --- + | ... +c = net:connect(box.cfg.listen) + | --- + | ... +future = c:eval('return long_function(...)', {1, 2, 3}, {is_async = true}) + | --- + | ... +future:result() + | --- + | - null + | - Response is not ready + | ... +future:wait_result(0.01) -- Must fail on timeout. + | --- + | - null + | - Timeout exceeded + | ... +finalize_long() + | --- + | ... +future:wait_result(100) + | --- + | - [1, 2, 3] + | ... + +c:close() + | --- + | ... +-- +-- Check that is_async does not work on a closed connection. +-- +c:call('any_func', {}, {is_async = true}) + | --- + | - error: Connection closed + | ... + +box.schema.user.revoke('guest', 'execute', 'universe') + | --- + | ... +c = net:connect(box.cfg.listen) + | --- + | ... + +c:close() + | --- + | ... +s:drop() + | --- + | ... diff --git a/test/box/net.box_timeout-gh-3107.test.lua b/test/box/net.box_timeout-gh-3107.test.lua new file mode 100644 index 000000000..08fa039db --- /dev/null +++ b/test/box/net.box_timeout-gh-3107.test.lua @@ -0,0 +1,47 @@ +fiber = require 'fiber' +net = require('net.box') + +-- +-- gh-3107: fiber-async netbox. +-- +cond = nil +box.schema.func.create('long_function') +box.schema.user.grant('guest', 'execute', 'function', 'long_function') +function long_function(...) cond = fiber.cond() cond:wait() return ... end +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end +s = box.schema.create_space('test') +pk = s:create_index('pk') +s:replace{1} +s:replace{2} +s:replace{3} +s:replace{4} +c = net:connect(box.cfg.listen) + +-- +-- Check infinity timeout. +-- +ret = nil +_ = fiber.create(function() ret = c:call('long_function', {1, 2, 3}, {is_async = true}):wait_result() end) +finalize_long() +while not ret do fiber.sleep(0.01) end +ret +c:close() +box.schema.user.grant('guest', 'execute', 'universe') +c = net:connect(box.cfg.listen) +future = c:eval('return long_function(...)', {1, 2, 3}, {is_async = true}) +future:result() +future:wait_result(0.01) -- Must fail on timeout. +finalize_long() +future:wait_result(100) + +c:close() +-- +-- Check that is_async does not work on a closed connection. +-- +c:call('any_func', {}, {is_async = true}) + +box.schema.user.revoke('guest', 'execute', 'universe') +c = net:connect(box.cfg.listen) + +c:close() +s:drop() diff --git a/test/box/net.box_timeout_gh-1533.result b/test/box/net.box_timeout_gh-1533.result new file mode 100644 index 000000000..10dccd74f --- /dev/null +++ b/test/box/net.box_timeout_gh-1533.result @@ -0,0 +1,89 @@ +fiber = require 'fiber' +--- +... +test_run = require('test_run').new() +--- +... +net = require('net.box') +--- +... +-- Tarantool < 1.7.1 compatibility (gh-1533) +c = net.new(box.cfg.listen) +--- +... +c:ping() +--- +- true +... +c:close() +--- +... +-- Test for connect_timeout > 0 in netbox connect +test_run:cmd("setopt delimiter ';'"); +--- +- true +... +need_stop = false; +--- +... +greeting = +"Tarantool 1.7.3 (Lua console)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" .. +"type 'help' for interactive help~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"; +--- +... +socket = require('socket'); +--- +... +srv = socket.tcp_server('localhost', 0, { + handler = function(fd) + local fiber = require('fiber') + while not need_stop do + fiber.sleep(0.01) + end + fd:write(greeting) + end +}); +--- +... +-- we must get timeout +port = srv:name().port +nb = net.new('localhost:' .. port, { + wait_connected = true, console = true, + connect_timeout = 0.1 +}); +--- +... +nb.error:find('timed out') ~= nil; +--- +- true +... +need_stop = true +nb:close(); +--- +... +-- we must get peer closed +nb = net.new('localhost:' .. port, { + wait_connected = true, console = true, + connect_timeout = 0.2 +}); +--- +... +nb.error ~= "Timeout exceeded"; +--- +- true +... +nb:close(); +--- +... +test_run:cmd("setopt delimiter ''"); +--- +- true +... +srv:close() +--- +- true +... +test_run:cmd("clear filter") +--- +- true +... diff --git a/test/box/net.box_timeout_gh-1533.test.lua b/test/box/net.box_timeout_gh-1533.test.lua new file mode 100644 index 000000000..08fddb0bb --- /dev/null +++ b/test/box/net.box_timeout_gh-1533.test.lua @@ -0,0 +1,45 @@ +fiber = require 'fiber' +test_run = require('test_run').new() +net = require('net.box') + +-- Tarantool < 1.7.1 compatibility (gh-1533) +c = net.new(box.cfg.listen) +c:ping() +c:close() + +-- Test for connect_timeout > 0 in netbox connect +test_run:cmd("setopt delimiter ';'"); +need_stop = false; +greeting = +"Tarantool 1.7.3 (Lua console)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" .. +"type 'help' for interactive help~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"; +socket = require('socket'); +srv = socket.tcp_server('localhost', 0, { + handler = function(fd) + local fiber = require('fiber') + while not need_stop do + fiber.sleep(0.01) + end + fd:write(greeting) + end +}); +port = srv:name().port +-- we must get timeout +nb = net.new('localhost:' .. port, { + wait_connected = true, console = true, + connect_timeout = 0.1 +}); +nb.error:find('timed out') ~= nil; +need_stop = true +nb:close(); +-- we must get peer closed +nb = net.new('localhost:' .. port, { + wait_connected = true, console = true, + connect_timeout = 0.2 +}); +nb.error ~= "Timeout exceeded"; +nb:close(); +test_run:cmd("setopt delimiter ''"); +srv:close() + +test_run:cmd("clear filter") diff --git a/test/box/net.box_upsert_gh-970.result b/test/box/net.box_upsert_gh-970.result new file mode 100644 index 000000000..d3ec20c23 --- /dev/null +++ b/test/box/net.box_upsert_gh-970.result @@ -0,0 +1,49 @@ +net = require('net.box') +--- +... +-- gh-970 gh-971 UPSERT over network +_ = box.schema.space.create('test') +--- +... +_ = box.space.test:create_index('primary', {type = 'TREE', parts = {1,'unsigned'}}) +--- +... +_ = box.space.test:create_index('covering', {type = 'TREE', parts = {1,'unsigned',3,'string',2,'unsigned'}}) +--- +... +_ = box.space.test:insert{1, 2, "string"} +--- +... +box.schema.user.grant('guest', 'read,write', 'space', 'test') +--- +... +c = net:connect(box.cfg.listen) +--- +... +c.space.test:select{} +--- +- - [1, 2, 'string'] +... +c.space.test:upsert({1, 2, 'nothing'}, {{'+', 2, 1}}) -- common update +--- +... +c.space.test:select{} +--- +- - [1, 3, 'string'] +... +c.space.test:upsert({2, 4, 'something'}, {{'+', 2, 1}}) -- insert +--- +... +c.space.test:select{} +--- +- - [1, 3, 'string'] + - [2, 4, 'something'] +... +c.space.test:upsert({2, 4, 'nothing'}, {{'+', 3, 100500}}) -- wrong operation +--- +... +c.space.test:select{} +--- +- - [1, 3, 'string'] + - [2, 4, 'something'] +... diff --git a/test/box/net.box_upsert_gh-970.test.lua b/test/box/net.box_upsert_gh-970.test.lua new file mode 100644 index 000000000..0ea9092eb --- /dev/null +++ b/test/box/net.box_upsert_gh-970.test.lua @@ -0,0 +1,16 @@ +net = require('net.box') + +-- gh-970 gh-971 UPSERT over network +_ = box.schema.space.create('test') +_ = box.space.test:create_index('primary', {type = 'TREE', parts = {1,'unsigned'}}) +_ = box.space.test:create_index('covering', {type = 'TREE', parts = {1,'unsigned',3,'string',2,'unsigned'}}) +_ = box.space.test:insert{1, 2, "string"} +box.schema.user.grant('guest', 'read,write', 'space', 'test') +c = net:connect(box.cfg.listen) +c.space.test:select{} +c.space.test:upsert({1, 2, 'nothing'}, {{'+', 2, 1}}) -- common update +c.space.test:select{} +c.space.test:upsert({2, 4, 'something'}, {{'+', 2, 1}}) -- insert +c.space.test:select{} +c.space.test:upsert({2, 4, 'nothing'}, {{'+', 3, 100500}}) -- wrong operation +c.space.test:select{} diff --git a/test/box/net.box_wait_connected_gh-3856.result b/test/box/net.box_wait_connected_gh-3856.result new file mode 100644 index 000000000..9234e6cb9 --- /dev/null +++ b/test/box/net.box_wait_connected_gh-3856.result @@ -0,0 +1,20 @@ +net = require('net.box') +--- +... +-- +-- gh-3856: wait_connected = false is ignored. +-- +c = net.connect('8.8.8.8:123456', {wait_connected = false}) +--- +... +c +--- +- opts: + wait_connected: false + host: 8.8.8.8 + state: initial + port: '123456' +... +c:close() +--- +... diff --git a/test/box/net.box_wait_connected_gh-3856.test.lua b/test/box/net.box_wait_connected_gh-3856.test.lua new file mode 100644 index 000000000..29e997fb5 --- /dev/null +++ b/test/box/net.box_wait_connected_gh-3856.test.lua @@ -0,0 +1,8 @@ +net = require('net.box') + +-- +-- gh-3856: wait_connected = false is ignored. +-- +c = net.connect('8.8.8.8:123456', {wait_connected = false}) +c +c:close() -- 2.17.1 ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Tarantool-patches] [PATCH v1] Divide test box/net.box 2020-04-02 6:38 [Tarantool-patches] [PATCH v1] Divide test box/net.box Alexander V. Tikhonov @ 2020-04-02 15:44 ` Sergey Bronnikov 2020-05-15 17:04 ` Alexander V. Tikhonov 0 siblings, 1 reply; 8+ messages in thread From: Sergey Bronnikov @ 2020-04-02 15:44 UTC (permalink / raw) To: Alexander V. Tikhonov; +Cc: Oleg Piskunov, tarantool-patches Hello! before splitting test we had a net.box.skipcond file due to an issue https://github.com/tarantool/tarantool/issues/4271. I believe that file is useless now and we should add similar files for a new tests. I have looked on tests without postfix "gh-xxx" in a filenames. LGTM for them: net.box_connect_triggers.test.lua net.box_permissions.test.lua net.box_reconnect_after.test.lua net.box_get_connection_object.test.lua I propose to run tests with postfix "gh-xxx" in filenames on commits before fix where bug covered by test was added. Broken test would mean it still works. Sergey On 09:38 Thu 02 Apr , Alexander V. Tikhonov wrote: > box/net.box_bad_argument_gh-594.test.lua > box/net.box_call_blocks_gh-946.test.lua > box/net.box_collectgarbage_gh-3107.test.lua > box/net.box_connect_triggers.test.lua > box/net.box_console_connections_gh-2677.test.lua > box/net.box_count_inconsistent_gh-3262.test.lua > box/net.box_discard_gh-3107.test.lua > box/net.box_disconnect_gh-3859.test.lua > box/net.box_fiber-async_gh-3107.test.lua > box/net.box_field_names_gh-2978.test.lua > box/net.box_get_connection_object.test.lua > box/net.box_gibberish_gh-3900.test.lua > box/net.box_huge_data_gh-983.test.lua > box/net.box_incompatible_index-gh-1729.test.lua > box/net.box_incorrect_iterator_gh-841.test.lua > box/net.box_index_unique_flag_gh-4091.test.lua > box/net.box_iproto_hangs_gh-3464.test.lua > box/net.box_is_nullable_gh-3256.test.lua > box/net.box_leaks_gh-3629.test.lua > box/net.box_log_corrupted_rows_gh-4040.test.lua > box/net.box_long-poll_input_gh-3400.test.lua > box/net.box_methods_gh-3107.test.lua > box/net.box_msgpack_gh-2195.test.lua > box/net.box_on_schema_reload-gh-1904.test.lua > box/net.box_password_gh-1545.test.lua > box/net.box_permissions.test.lua > box/net.box_pseudo_objects_gh-2401.test.lua > box/net.box_raw_response_gh-3107.test.lua > box/net.box_readahead_gh-3958.test.lua > box/net.box_reconnect_after_gh-3164.test.lua > box/net.box_reconnect_after.test.lua > box/net.box_reload_schema_gh-636.test.lua > box/net.box_remote_method_gh-544.test.lua > box/net.box_roll_back_gh-822.test.lua > box/net.box_schema_change_gh-2666.test.lua > box/net.box_schema_change_gh-3107.test.lua > box/net.box_session_type_gh-2642.test.lua > box/net.box_space_format_gh-2402.test.lua > box/net.box_timeout_gh-1533.test.lua > box/net.box_timeout-gh-3107.test.lua > box/net.box_upsert_gh-970.test.lua > box/net.box_wait_connected_gh-3856.test.lua > --- > > Github: https://github.com/tarantool/tarantool/tree/avtikhon/divide_tests > > test/box/gh-3107_rest1_net.box.result | 119 + > test/box/net.box.result | 3932 ----------------- > test/box/net.box.test.lua | 1585 ------- > test/box/net.box_bad_argument_gh-594.result | 38 + > test/box/net.box_bad_argument_gh-594.test.lua | 17 + > test/box/net.box_call_blocks_gh-946.result | 124 + > test/box/net.box_call_blocks_gh-946.test.lua | 67 + > .../box/net.box_collectgarbage_gh-3107.result | 120 + > .../net.box_collectgarbage_gh-3107.test.lua | 44 + > test/box/net.box_connect_triggers.result | 82 + > test/box/net.box_connect_triggers.test.lua | 27 + > ...net.box_console_connections_gh-2677.result | 95 + > ...t.box_console_connections_gh-2677.test.lua | 39 + > .../net.box_count_inconsistent_gh-3262.result | 488 ++ > ...et.box_count_inconsistent_gh-3262.test.lua | 182 + > test/box/net.box_discard_gh-3107.result | 119 + > test/box/net.box_discard_gh-3107.test.lua | 44 + > test/box/net.box_disconnect_gh-3859.result | 113 + > test/box/net.box_disconnect_gh-3859.test.lua | 50 + > test/box/net.box_fiber-async_gh-3107.result | 115 + > test/box/net.box_fiber-async_gh-3107.test.lua | 42 + > test/box/net.box_field_names_gh-2978.result | 101 + > test/box/net.box_field_names_gh-2978.test.lua | 29 + > test/box/net.box_get_connection_object.result | 40 + > .../net.box_get_connection_object.test.lua | 19 + > test/box/net.box_gibberish_gh-3900.result | 31 + > test/box/net.box_gibberish_gh-3900.test.lua | 13 + > test/box/net.box_huge_data_gh-983.result | 30 + > test/box/net.box_huge_data_gh-983.test.lua | 16 + > .../net.box_incompatible_index-gh-1729.result | 99 + > ...et.box_incompatible_index-gh-1729.test.lua | 33 + > .../net.box_incorrect_iterator_gh-841.result | 497 +++ > ...net.box_incorrect_iterator_gh-841.test.lua | 182 + > .../net.box_index_unique_flag_gh-4091.result | 28 + > ...net.box_index_unique_flag_gh-4091.test.lua | 15 + > test/box/net.box_iproto_hangs_gh-3464.result | 31 + > .../box/net.box_iproto_hangs_gh-3464.test.lua | 13 + > test/box/net.box_is_nullable_gh-3256.result | 97 + > test/box/net.box_is_nullable_gh-3256.test.lua | 36 + > test/box/net.box_leaks_gh-3629.result | 51 + > test/box/net.box_leaks_gh-3629.test.lua | 20 + > .../net.box_log_corrupted_rows_gh-4040.result | 72 + > ...et.box_log_corrupted_rows_gh-4040.test.lua | 31 + > .../net.box_long-poll_input_gh-3400.result | 35 + > .../net.box_long-poll_input_gh-3400.test.lua | 19 + > test/box/net.box_methods_gh-3107.result | 277 ++ > test/box/net.box_methods_gh-3107.test.lua | 96 + > test/box/net.box_msgpack_gh-2195.result | 527 +++ > test/box/net.box_msgpack_gh-2195.test.lua | 192 + > .../net.box_on_schema_reload-gh-1904.result | 102 + > .../net.box_on_schema_reload-gh-1904.test.lua | 65 + > test/box/net.box_password_gh-1545.result | 28 + > test/box/net.box_password_gh-1545.test.lua | 10 + > test/box/net.box_permissions.result | 186 + > test/box/net.box_permissions.test.lua | 66 + > .../box/net.box_pseudo_objects_gh-2401.result | 55 + > .../net.box_pseudo_objects_gh-2401.test.lua | 23 + > test/box/net.box_raw_response_gh-3107.result | 123 + > .../box/net.box_raw_response_gh-3107.test.lua | 46 + > test/box/net.box_readahead_gh-3958.result | 55 + > test/box/net.box_readahead_gh-3958.test.lua | 29 + > test/box/net.box_reconnect_after.result | 32 + > test/box/net.box_reconnect_after.test.lua | 16 + > .../net.box_reconnect_after_gh-3164.result | 119 + > .../net.box_reconnect_after_gh-3164.test.lua | 52 + > test/box/net.box_reload_schema_gh-636.result | 108 + > .../box/net.box_reload_schema_gh-636.test.lua | 46 + > test/box/net.box_remote_method_gh-544.result | 95 + > .../box/net.box_remote_method_gh-544.test.lua | 40 + > test/box/net.box_roll_back_gh-822.result | 68 + > test/box/net.box_roll_back_gh-822.test.lua | 42 + > test/box/net.box_schema_change_gh-2666.result | 79 + > .../net.box_schema_change_gh-2666.test.lua | 28 + > test/box/net.box_schema_change_gh-3107.result | 151 + > .../net.box_schema_change_gh-3107.test.lua | 55 + > test/box/net.box_session_type_gh-2642.result | 22 + > .../box/net.box_session_type_gh-2642.test.lua | 11 + > test/box/net.box_space_format_gh-2402.result | 49 + > .../box/net.box_space_format_gh-2402.test.lua | 23 + > test/box/net.box_timeout-gh-3107.result | 125 + > test/box/net.box_timeout-gh-3107.test.lua | 47 + > test/box/net.box_timeout_gh-1533.result | 89 + > test/box/net.box_timeout_gh-1533.test.lua | 45 + > test/box/net.box_upsert_gh-970.result | 49 + > test/box/net.box_upsert_gh-970.test.lua | 16 + > .../box/net.box_wait_connected_gh-3856.result | 20 + > .../net.box_wait_connected_gh-3856.test.lua | 8 + > 87 files changed, 6778 insertions(+), 5517 deletions(-) > create mode 100644 test/box/gh-3107_rest1_net.box.result > delete mode 100644 test/box/net.box.result > delete mode 100644 test/box/net.box.test.lua > create mode 100644 test/box/net.box_bad_argument_gh-594.result > create mode 100644 test/box/net.box_bad_argument_gh-594.test.lua > create mode 100644 test/box/net.box_call_blocks_gh-946.result > create mode 100644 test/box/net.box_call_blocks_gh-946.test.lua > create mode 100644 test/box/net.box_collectgarbage_gh-3107.result > create mode 100644 test/box/net.box_collectgarbage_gh-3107.test.lua > create mode 100644 test/box/net.box_connect_triggers.result > create mode 100644 test/box/net.box_connect_triggers.test.lua > create mode 100644 test/box/net.box_console_connections_gh-2677.result > create mode 100644 test/box/net.box_console_connections_gh-2677.test.lua > create mode 100644 test/box/net.box_count_inconsistent_gh-3262.result > create mode 100644 test/box/net.box_count_inconsistent_gh-3262.test.lua > create mode 100644 test/box/net.box_discard_gh-3107.result > create mode 100644 test/box/net.box_discard_gh-3107.test.lua > create mode 100644 test/box/net.box_disconnect_gh-3859.result > create mode 100644 test/box/net.box_disconnect_gh-3859.test.lua > create mode 100644 test/box/net.box_fiber-async_gh-3107.result > create mode 100644 test/box/net.box_fiber-async_gh-3107.test.lua > create mode 100644 test/box/net.box_field_names_gh-2978.result > create mode 100644 test/box/net.box_field_names_gh-2978.test.lua > create mode 100644 test/box/net.box_get_connection_object.result > create mode 100644 test/box/net.box_get_connection_object.test.lua > create mode 100644 test/box/net.box_gibberish_gh-3900.result > create mode 100644 test/box/net.box_gibberish_gh-3900.test.lua > create mode 100644 test/box/net.box_huge_data_gh-983.result > create mode 100644 test/box/net.box_huge_data_gh-983.test.lua > create mode 100644 test/box/net.box_incompatible_index-gh-1729.result > create mode 100644 test/box/net.box_incompatible_index-gh-1729.test.lua > create mode 100644 test/box/net.box_incorrect_iterator_gh-841.result > create mode 100644 test/box/net.box_incorrect_iterator_gh-841.test.lua > create mode 100644 test/box/net.box_index_unique_flag_gh-4091.result > create mode 100644 test/box/net.box_index_unique_flag_gh-4091.test.lua > create mode 100644 test/box/net.box_iproto_hangs_gh-3464.result > create mode 100644 test/box/net.box_iproto_hangs_gh-3464.test.lua > create mode 100644 test/box/net.box_is_nullable_gh-3256.result > create mode 100644 test/box/net.box_is_nullable_gh-3256.test.lua > create mode 100644 test/box/net.box_leaks_gh-3629.result > create mode 100644 test/box/net.box_leaks_gh-3629.test.lua > create mode 100644 test/box/net.box_log_corrupted_rows_gh-4040.result > create mode 100644 test/box/net.box_log_corrupted_rows_gh-4040.test.lua > create mode 100644 test/box/net.box_long-poll_input_gh-3400.result > create mode 100644 test/box/net.box_long-poll_input_gh-3400.test.lua > create mode 100644 test/box/net.box_methods_gh-3107.result > create mode 100644 test/box/net.box_methods_gh-3107.test.lua > create mode 100644 test/box/net.box_msgpack_gh-2195.result > create mode 100644 test/box/net.box_msgpack_gh-2195.test.lua > create mode 100644 test/box/net.box_on_schema_reload-gh-1904.result > create mode 100644 test/box/net.box_on_schema_reload-gh-1904.test.lua > create mode 100644 test/box/net.box_password_gh-1545.result > create mode 100644 test/box/net.box_password_gh-1545.test.lua > create mode 100644 test/box/net.box_permissions.result > create mode 100644 test/box/net.box_permissions.test.lua > create mode 100644 test/box/net.box_pseudo_objects_gh-2401.result > create mode 100644 test/box/net.box_pseudo_objects_gh-2401.test.lua > create mode 100644 test/box/net.box_raw_response_gh-3107.result > create mode 100644 test/box/net.box_raw_response_gh-3107.test.lua > create mode 100644 test/box/net.box_readahead_gh-3958.result > create mode 100644 test/box/net.box_readahead_gh-3958.test.lua > create mode 100644 test/box/net.box_reconnect_after.result > create mode 100644 test/box/net.box_reconnect_after.test.lua > create mode 100644 test/box/net.box_reconnect_after_gh-3164.result > create mode 100644 test/box/net.box_reconnect_after_gh-3164.test.lua > create mode 100644 test/box/net.box_reload_schema_gh-636.result > create mode 100644 test/box/net.box_reload_schema_gh-636.test.lua > create mode 100644 test/box/net.box_remote_method_gh-544.result > create mode 100644 test/box/net.box_remote_method_gh-544.test.lua > create mode 100644 test/box/net.box_roll_back_gh-822.result > create mode 100644 test/box/net.box_roll_back_gh-822.test.lua > create mode 100644 test/box/net.box_schema_change_gh-2666.result > create mode 100644 test/box/net.box_schema_change_gh-2666.test.lua > create mode 100644 test/box/net.box_schema_change_gh-3107.result > create mode 100644 test/box/net.box_schema_change_gh-3107.test.lua > create mode 100644 test/box/net.box_session_type_gh-2642.result > create mode 100644 test/box/net.box_session_type_gh-2642.test.lua > create mode 100644 test/box/net.box_space_format_gh-2402.result > create mode 100644 test/box/net.box_space_format_gh-2402.test.lua > create mode 100644 test/box/net.box_timeout-gh-3107.result > create mode 100644 test/box/net.box_timeout-gh-3107.test.lua > create mode 100644 test/box/net.box_timeout_gh-1533.result > create mode 100644 test/box/net.box_timeout_gh-1533.test.lua > create mode 100644 test/box/net.box_upsert_gh-970.result > create mode 100644 test/box/net.box_upsert_gh-970.test.lua > create mode 100644 test/box/net.box_wait_connected_gh-3856.result > create mode 100644 test/box/net.box_wait_connected_gh-3856.test.lua > > diff --git a/test/box/gh-3107_rest1_net.box.result b/test/box/gh-3107_rest1_net.box.result > new file mode 100644 > index 000000000..d9c59d1cf > --- /dev/null > +++ b/test/box/gh-3107_rest1_net.box.result > @@ -0,0 +1,119 @@ > +fiber = require 'fiber' > +--- > +... > +net = require('net.box') > +--- > +... > +-- > +-- gh-3107: fiber-async netbox. > +-- > +cond = nil > +--- > +... > +box.schema.func.create('long_function') > +--- > +... > +box.schema.user.grant('guest', 'execute', 'function', 'long_function') > +--- > +... > +function long_function(...) cond = fiber.cond() cond:wait() return ... end > +--- > +... > +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end > +--- > +... > +s = box.schema.create_space('test') > +--- > +... > +pk = s:create_index('pk') > +--- > +... > +s:replace{1} > +--- > +- [1] > +... > +s:replace{2} > +--- > +- [2] > +... > +s:replace{3} > +--- > +- [3] > +... > +s:replace{4} > +--- > +- [4] > +... > +c = net:connect(box.cfg.listen) > +--- > +... > +-- > +-- Check infinity timeout. > +-- > +ret = nil > +--- > +... > +_ = fiber.create(function() ret = c:call('long_function', {1, 2, 3}, {is_async = true}):wait_result() end) > +--- > +... > +finalize_long() > +--- > +... > +while not ret do fiber.sleep(0.01) end > +--- > +... > +ret > +--- > +- [1, 2, 3] > +... > +c:close() > +--- > +... > +box.schema.user.grant('guest', 'execute', 'universe') > +--- > +... > +c = net:connect(box.cfg.listen) > +--- > +... > +future = c:eval('return long_function(...)', {1, 2, 3}, {is_async = true}) > +--- > +... > +future:result() > +--- > +- null > +- Response is not ready > +... > +future:wait_result(0.01) -- Must fail on timeout. > +--- > +- null > +- Timeout exceeded > +... > +finalize_long() > +--- > +... > +future:wait_result(100) > +--- > +- [1, 2, 3] > +... > +c:close() > +--- > +... > +-- > +-- Check that is_async does not work on a closed connection. > +-- > +c:call('any_func', {}, {is_async = true}) > +--- > +- error: Connection closed > +... > +box.schema.user.revoke('guest', 'execute', 'universe') > +--- > +... > +c = net:connect(box.cfg.listen) > +--- > +... > +c:close() > +--- > +... > +s:drop() > +--- > +... > diff --git a/test/box/net.box.result b/test/box/net.box.result > deleted file mode 100644 > index e3dabf7d9..000000000 > --- a/test/box/net.box.result > +++ /dev/null > @@ -1,3932 +0,0 @@ > -remote = require 'net.box' > ---- > -... > -fiber = require 'fiber' > ---- > -... > -log = require 'log' > ---- > -... > -msgpack = require 'msgpack' > ---- > -... > -env = require('test_run') > ---- > -... > -test_run = env.new() > ---- > -... > -test_run:cmd("push filter ".."'\\.lua.*:[0-9]+: ' to '.lua...\"]:<line>: '") > ---- > -- true > -... > -test_run:cmd("setopt delimiter ';'") > ---- > -- true > -... > -function x_select(cn, space_id, index_id, iterator, offset, limit, key, opts) > - local ret = cn:_request('select', opts, nil, space_id, index_id, iterator, > - offset, limit, key) > - return ret > -end > -function x_fatal(cn) cn._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') end > -test_run:cmd("setopt delimiter ''"); > ---- > -... > -LISTEN = require('uri').parse(box.cfg.listen) > ---- > -... > -space = box.schema.space.create('net_box_test_space') > ---- > -... > -index = space:create_index('primary', { type = 'tree' }) > ---- > -... > --- low level connection > -log.info("create connection") > ---- > -... > -cn = remote.connect(LISTEN.host, LISTEN.service) > ---- > -... > -log.info("state is %s", cn.state) > ---- > -... > -cn:ping() > ---- > -- true > -... > -log.info("ping is done") > ---- > -... > -cn:ping() > ---- > -- true > -... > -log.info("ping is done") > ---- > -... > -cn:ping() > ---- > -- true > -... > --- check permissions > -cn:call('unexists_procedure') > ---- > -- error: Execute access to function 'unexists_procedure' is denied for user 'guest' > -... > -function test_foo(a,b,c) return { {{ [a] = 1 }}, {{ [b] = 2 }}, c } end > ---- > -... > -cn:call('test_foo', {'a', 'b', 'c'}) > ---- > -- error: Execute access to function 'test_foo' is denied for user 'guest' > -... > -cn:eval('return 2+2') > ---- > -- error: Execute access to universe '' is denied for user 'guest' > -... > -cn:close() > ---- > -... > --- connect and call without usage access > -box.schema.user.grant('guest','execute','universe') > ---- > -... > -box.schema.user.revoke('guest','usage','universe') > ---- > -... > -box.session.su("guest") > ---- > -... > -cn = remote.connect(LISTEN.host, LISTEN.service) > ---- > -... > -cn:call('test_foo', {'a', 'b', 'c'}) > ---- > -- error: Usage access to universe '' is denied for user 'guest' > -... > -box.session.su("admin") > ---- > -... > -box.schema.user.grant('guest','usage','universe') > ---- > -... > -cn:close() > ---- > -... > -cn = remote.connect(box.cfg.listen) > ---- > -... > -cn:call('unexists_procedure') > ---- > -- error: Procedure 'unexists_procedure' is not defined > -... > -cn:call('test_foo', {'a', 'b', 'c'}) > ---- > -- [[{'a': 1}], [{'b': 2}], 'c'] > -... > -cn:call(nil, {'a', 'b', 'c'}) > ---- > -- error: Procedure 'nil' is not defined > -... > -cn:eval('return 2+2') > ---- > -- 4 > -... > -cn:eval('return 1, 2, 3') > ---- > -- 1 > -- 2 > -- 3 > -... > -cn:eval('return ...', {1, 2, 3}) > ---- > -- 1 > -- 2 > -- 3 > -... > -cn:eval('return { k = "v1" }, true, { xx = 10, yy = 15 }, nil') > ---- > -- {'k': 'v1'} > -- true > -- {'yy': 15, 'xx': 10} > -- null > -... > -cn:eval('return nil') > ---- > -- null > -... > -cn:eval('return') > ---- > -... > -cn:eval('error("exception")') > ---- > -- error: 'eval:1: exception' > -... > -cn:eval('box.error(0)') > ---- > -- error: Unknown error > -... > -cn:eval('!invalid expression') > ---- > -- error: 'eval:1: unexpected symbol near ''!''' > -... > --- box.commit() missing at return of CALL/EVAL > -function no_commit() box.begin() fiber.sleep(0.001) end > ---- > -... > -cn:call('no_commit') > ---- > -- error: Transaction is active at return from function > -... > -cn:eval('no_commit()') > ---- > -- error: Transaction is active at return from function > -... > -remote.self:eval('return 1+1, 2+2') > ---- > -- 2 > -- 4 > -... > -remote.self:eval('return') > ---- > -... > -remote.self:eval('error("exception")') > ---- > -- error: '[string "error("exception")"]:1: exception' > -... > -remote.self:eval('box.error(0)') > ---- > -- error: Unknown error > -... > -remote.self:eval('!invalid expression') > ---- > -- error: '[string "return !invalid expression"]:1: unexpected symbol near ''!''' > -... > -box.schema.user.revoke('guest', 'execute', 'universe') > ---- > -... > --- > --- gh-822: net.box.call should roll back local transaction on error > --- > -_ = box.schema.space.create('gh822') > ---- > -... > -_ = box.space.gh822:create_index('primary') > ---- > -... > -test_run:cmd("setopt delimiter ';'") > ---- > -- true > -... > --- rollback on invalid function > -function rollback_on_invalid_function() > - box.begin() > - box.space.gh822:insert{1, "netbox_test"} > - pcall(remote.self.call, remote.self, 'invalid_function') > - return box.space.gh822:get(1) == nil > -end; > ---- > -... > -rollback_on_invalid_function(); > ---- > -- true > -... > --- rollback on call error > -function test_error() error('Some error') end; > ---- > -... > -function rollback_on_call_error() > - box.begin() > - box.space.gh822:insert{1, "netbox_test"} > - pcall(remote.self.call, remote.self, 'test_error') > - return box.space.gh822:get(1) == nil > -end; > ---- > -... > -rollback_on_call_error(); > ---- > -- true > -... > --- rollback on eval > -function rollback_on_eval_error() > - box.begin() > - box.space.gh822:insert{1, "netbox_test"} > - pcall(remote.self.eval, remote.self, "error('Some error')") > - return box.space.gh822:get(1) == nil > -end; > ---- > -... > -rollback_on_eval_error(); > ---- > -- true > -... > -test_run:cmd("setopt delimiter ''"); > ---- > -- true > -... > -box.space.gh822:drop() > ---- > -... > -box.schema.user.grant('guest', 'read,write', 'space', 'net_box_test_space') > ---- > -... > -box.schema.user.grant('guest', 'execute', 'universe') > ---- > -... > -cn:close() > ---- > -... > -cn = remote.connect(box.cfg.listen) > ---- > -... > -x_select(cn, space.id, space.index.primary.id, box.index.EQ, 0, 0xFFFFFFFF, 123) > ---- > -- [] > -... > -space:insert{123, 345} > ---- > -- [123, 345] > -... > -x_select(cn, space.id, space.index.primary.id, box.index.EQ, 0, 0, 123) > ---- > -- [] > -... > -x_select(cn, space.id, space.index.primary.id, box.index.EQ, 0, 1, 123) > ---- > -- - [123, 345] > -... > -x_select(cn, space.id, space.index.primary.id, box.index.EQ, 1, 1, 123) > ---- > -- [] > -... > -cn.space[space.id] ~= nil > ---- > -- true > -... > -cn.space.net_box_test_space ~= nil > ---- > -- true > -... > -cn.space.net_box_test_space ~= nil > ---- > -- true > -... > -cn.space.net_box_test_space.index ~= nil > ---- > -- true > -... > -cn.space.net_box_test_space.index.primary ~= nil > ---- > -- true > -... > -cn.space.net_box_test_space.index[space.index.primary.id] ~= nil > ---- > -- true > -... > -cn.space.net_box_test_space.index.primary:select(123) > ---- > -- - [123, 345] > -... > -cn.space.net_box_test_space.index.primary:select(123, { limit = 0 }) > ---- > -- [] > -... > -cn.space.net_box_test_space.index.primary:select(nil, { limit = 1, }) > ---- > -- - [123, 345] > -... > -cn.space.net_box_test_space:insert{234, 1,2,3} > ---- > -- [234, 1, 2, 3] > -... > -cn.space.net_box_test_space:insert{234, 1,2,3} > ---- > -- error: Duplicate key exists in unique index 'primary' in space 'net_box_test_space' > -... > -cn.space.net_box_test_space.insert{234, 1,2,3} > ---- > -- error: 'builtin/box/schema.lua..."]:<line>: Use space:insert(...) instead of space.insert(...)' > -... > -cn.space.net_box_test_space:replace{354, 1,2,3} > ---- > -- [354, 1, 2, 3] > -... > -cn.space.net_box_test_space:replace{354, 1,2,4} > ---- > -- [354, 1, 2, 4] > -... > -cn.space.net_box_test_space:select{123} > ---- > -- - [123, 345] > -... > -space:select({123}, { iterator = 'GE' }) > ---- > -- - [123, 345] > - - [234, 1, 2, 3] > - - [354, 1, 2, 4] > -... > -cn.space.net_box_test_space:select({123}, { iterator = 'GE' }) > ---- > -- - [123, 345] > - - [234, 1, 2, 3] > - - [354, 1, 2, 4] > -... > -cn.space.net_box_test_space:select({123}, { iterator = 'GT' }) > ---- > -- - [234, 1, 2, 3] > - - [354, 1, 2, 4] > -... > -cn.space.net_box_test_space:select({123}, { iterator = 'GT', limit = 1 }) > ---- > -- - [234, 1, 2, 3] > -... > -cn.space.net_box_test_space:select({123}, { iterator = 'GT', limit = 1, offset = 1 }) > ---- > -- - [354, 1, 2, 4] > -... > -cn.space.net_box_test_space:select{123} > ---- > -- - [123, 345] > -... > -cn.space.net_box_test_space:update({123}, { { '+', 2, 1 } }) > ---- > -- [123, 346] > -... > -cn.space.net_box_test_space:update(123, { { '+', 2, 1 } }) > ---- > -- [123, 347] > -... > -cn.space.net_box_test_space:select{123} > ---- > -- - [123, 347] > -... > -cn.space.net_box_test_space:insert(cn.space.net_box_test_space:get{123}:update{ { '=', 1, 2 } }) > ---- > -- [2, 347] > -... > -cn.space.net_box_test_space:delete{123} > ---- > -- [123, 347] > -... > -cn.space.net_box_test_space:select{2} > ---- > -- - [2, 347] > -... > -cn.space.net_box_test_space:select({234}, { iterator = 'LT' }) > ---- > -- - [2, 347] > -... > -cn.space.net_box_test_space:update({1}, { { '+', 2, 2 } }) > ---- > -... > -cn.space.net_box_test_space:delete{1} > ---- > -... > -cn.space.net_box_test_space:delete{2} > ---- > -- [2, 347] > -... > -cn.space.net_box_test_space:delete{2} > ---- > -... > --- test one-based indexing in splice operation (see update.test.lua) > -cn.space.net_box_test_space:replace({10, 'abcde'}) > ---- > -- [10, 'abcde'] > -... > -cn.space.net_box_test_space:update(10, {{':', 2, 0, 0, '!'}}) > ---- > -- error: 'SPLICE error on field 2: offset is out of bound' > -... > -cn.space.net_box_test_space:update(10, {{':', 2, 1, 0, '('}}) > ---- > -- [10, '(abcde'] > -... > -cn.space.net_box_test_space:update(10, {{':', 2, 2, 0, '({'}}) > ---- > -- [10, '(({abcde'] > -... > -cn.space.net_box_test_space:update(10, {{':', 2, -1, 0, ')'}}) > ---- > -- [10, '(({abcde)'] > -... > -cn.space.net_box_test_space:update(10, {{':', 2, -2, 0, '})'}}) > ---- > -- [10, '(({abcde}))'] > -... > -cn.space.net_box_test_space:delete{10} > ---- > -- [10, '(({abcde}))'] > -... > -cn.space.net_box_test_space:select({}, { iterator = 'ALL' }) > ---- > -- - [234, 1, 2, 3] > - - [354, 1, 2, 4] > -... > --- gh-841: net.box uses incorrect iterator type for select with no arguments > -cn.space.net_box_test_space:select() > ---- > -- - [234, 1, 2, 3] > - - [354, 1, 2, 4] > -... > -cn.space.net_box_test_space.index.primary:min() > ---- > -- [234, 1, 2, 3] > -... > -cn.space.net_box_test_space.index.primary:min(354) > ---- > -- [354, 1, 2, 4] > -... > -cn.space.net_box_test_space.index.primary:max() > ---- > -- [354, 1, 2, 4] > -... > -cn.space.net_box_test_space.index.primary:max(234) > ---- > -- [234, 1, 2, 3] > -... > -cn.space.net_box_test_space.index.primary:count() > ---- > -- 2 > -... > -cn.space.net_box_test_space.index.primary:count(354) > ---- > -- 1 > -... > -cn.space.net_box_test_space:get(354) > ---- > -- [354, 1, 2, 4] > -... > --- reconnects after errors > -box.schema.user.revoke('guest', 'execute', 'universe') > ---- > -... > -box.schema.func.create('test_foo') > ---- > -... > -box.schema.user.grant('guest', 'execute', 'function', 'test_foo') > ---- > -... > --- -- 1. no reconnect > -x_fatal(cn) > ---- > -... > -cn.state > ---- > -- error > -... > -cn:ping() > ---- > -- false > -... > -cn:call('test_foo') > ---- > -- error: Peer closed > -... > -cn:wait_state('active') > ---- > -- false > -... > --- -- 2 reconnect > -cn = remote.connect(LISTEN.host, LISTEN.service, { reconnect_after = .1 }) > ---- > -... > -cn.space ~= nil > ---- > -- true > -... > -cn.space.net_box_test_space:select({}, { iterator = 'ALL' }) > ---- > -- - [234, 1, 2, 3] > - - [354, 1, 2, 4] > -... > -x_fatal(cn) > ---- > -... > -cn:wait_connected() > ---- > -- true > -... > -cn:wait_state('active') > ---- > -- true > -... > -cn:wait_state({active=true}) > ---- > -- true > -... > -cn:ping() > ---- > -- true > -... > -cn.state > ---- > -- active > -... > -cn.space.net_box_test_space:select({}, { iterator = 'ALL' }) > ---- > -- - [234, 1, 2, 3] > - - [354, 1, 2, 4] > -... > -x_fatal(cn) > ---- > -... > -x_select(cn, space.id, 0, box.index.ALL, 0, 0xFFFFFFFF, {}) > ---- > -- - [234, 1, 2, 3] > - - [354, 1, 2, 4] > -... > -cn.state > ---- > -- active > -... > -cn:ping() > ---- > -- true > -... > --- -- dot-new-method > -cn1 = remote.new(LISTEN.host, LISTEN.service) > ---- > -... > -x_select(cn1, space.id, 0, box.index.ALL, 0, 0xFFFFFFF, {}) > ---- > -- - [234, 1, 2, 3] > - - [354, 1, 2, 4] > -... > -cn1:close() > ---- > -... > --- -- error while waiting for response > -type(fiber.create(function() fiber.sleep(.5) x_fatal(cn) end)) > ---- > -- userdata > -... > -function pause() fiber.sleep(10) return true end > ---- > -... > -box.schema.func.create('pause') > ---- > -... > -box.schema.user.grant('guest', 'execute', 'function', 'pause') > ---- > -... > -cn:call('pause') > ---- > -- error: Peer closed > -... > -cn:call('test_foo', {'a', 'b', 'c'}) > ---- > -- [[{'a': 1}], [{'b': 2}], 'c'] > -... > -box.schema.func.drop('pause') > ---- > -... > --- call > -remote.self:call('test_foo', {'a', 'b', 'c'}) > ---- > -- - - a: 1 > - - - b: 2 > - - c > -... > -cn:call('test_foo', {'a', 'b', 'c'}) > ---- > -- [[{'a': 1}], [{'b': 2}], 'c'] > -... > -box.schema.func.drop('test_foo') > ---- > -... > -box.schema.func.create('long_rep') > ---- > -... > -box.schema.user.grant('guest', 'execute', 'function', 'long_rep') > ---- > -... > --- long replies > -function long_rep() return { 1, string.rep('a', 5000) } end > ---- > -... > -res = cn:call('long_rep') > ---- > -... > -res[1] == 1 > ---- > -- true > -... > -res[2] == string.rep('a', 5000) > ---- > -- true > -... > -function long_rep() return { 1, string.rep('a', 50000) } end > ---- > -... > -res = cn:call('long_rep') > ---- > -... > -res[1] == 1 > ---- > -- true > -... > -res[2] == string.rep('a', 50000) > ---- > -- true > -... > -box.schema.func.drop('long_rep') > ---- > -... > --- a.b.c.d > -u = '84F7BCFA-079C-46CC-98B4-F0C821BE833E' > ---- > -... > -X = {} > ---- > -... > -X.X = X > ---- > -... > -function X.fn(x,y) return y or x end > ---- > -... > -box.schema.user.grant('guest', 'execute', 'universe') > ---- > -... > -cn:close() > ---- > -... > -cn = remote.connect(LISTEN.host, LISTEN.service) > ---- > -... > -cn:call('X.fn', {u}) > ---- > -- 84F7BCFA-079C-46CC-98B4-F0C821BE833E > -... > -cn:call('X.X.X.X.X.X.X.fn', {u}) > ---- > -- 84F7BCFA-079C-46CC-98B4-F0C821BE833E > -... > -cn:call('X.X.X.X:fn', {u}) > ---- > -- 84F7BCFA-079C-46CC-98B4-F0C821BE833E > -... > -box.schema.user.revoke('guest', 'execute', 'universe') > ---- > -... > -cn:close() > ---- > -... > --- auth > -cn = remote.connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123', wait_connected = true }) > ---- > -... > -cn:is_connected() > ---- > -- false > -... > -cn.error > ---- > -- User 'netbox' is not found > -... > -cn.state > ---- > -- error > -... > -box.schema.user.create('netbox', { password = 'test' }) > ---- > -... > -box.schema.user.grant('netbox', 'read,write', 'space', 'net_box_test_space') > ---- > -... > -box.schema.user.grant('netbox', 'execute', 'universe') > ---- > -... > -cn = remote.connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = 'test' }) > ---- > -... > -cn.state > ---- > -- active > -... > -cn.error > ---- > -- null > -... > -cn:ping() > ---- > -- true > -... > -function ret_after(to) fiber.sleep(to) return {{to}} end > ---- > -... > -cn:ping({timeout = 1.00}) > ---- > -- true > -... > -cn:ping({timeout = 1e-9}) > ---- > -- false > -... > -cn:ping() > ---- > -- true > -... > -remote_space = cn.space.net_box_test_space > ---- > -... > -remote_pk = remote_space.index.primary > ---- > -... > -remote_space:insert({0}, { timeout = 1.00 }) > ---- > -- [0] > -... > -remote_space:insert({1}, { timeout = 1e-9 }) > ---- > -- error: Timeout exceeded > -... > -remote_space:insert({2}) > ---- > -- [2] > -... > -remote_space:replace({0}, { timeout = 1e-9 }) > ---- > -- error: Timeout exceeded > -... > -remote_space:replace({1}) > ---- > -- [1] > -... > -remote_space:replace({2}, { timeout = 1.00 }) > ---- > -- [2] > -... > -remote_space:upsert({3}, {}, { timeout = 1e-9 }) > ---- > -- error: Timeout exceeded > -... > -remote_space:upsert({4}, {}) > ---- > -... > -remote_space:upsert({5}, {}, { timeout = 1.00 }) > ---- > -... > -remote_space:upsert({3}, {}) > ---- > -... > -remote_space:update({3}, {}, { timeout = 1e-9 }) > ---- > -- error: Timeout exceeded > -... > -remote_space:update({4}, {}) > ---- > -- [4] > -... > -remote_space:update({5}, {}, { timeout = 1.00 }) > ---- > -- [5] > -... > -remote_space:update({3}, {}) > ---- > -- [3] > -... > -remote_pk:update({5}, {}, { timeout = 1e-9 }) > ---- > -- error: Timeout exceeded > -... > -remote_pk:update({4}, {}) > ---- > -- [4] > -... > -remote_pk:update({3}, {}, { timeout = 1.00 }) > ---- > -- [3] > -... > -remote_pk:update({5}, {}) > ---- > -- [5] > -... > -remote_space:get({0}) > ---- > -- [0] > -... > -remote_space:get({1}, { timeout = 1.00 }) > ---- > -- [1] > -... > -remote_space:get({2}, { timeout = 1e-9 }) > ---- > -- error: Timeout exceeded > -... > -remote_pk:get({3}, { timeout = 1e-9 }) > ---- > -- error: Timeout exceeded > -... > -remote_pk:get({4}) > ---- > -- [4] > -... > -remote_pk:get({5}, { timeout = 1.00 }) > ---- > -- [5] > -... > -remote_space:select({2}, { timeout = 1e-9 }) > ---- > -- error: Timeout exceeded > -... > -remote_space:select({2}, { timeout = 1.00 }) > ---- > -- - [2] > -... > -remote_space:select({2}) > ---- > -- - [2] > -... > -remote_pk:select({2}, { timeout = 1.00 }) > ---- > -- - [2] > -... > -remote_pk:select({2}, { timeout = 1e-9 }) > ---- > -- error: Timeout exceeded > -... > -remote_pk:select({2}) > ---- > -- - [2] > -... > -remote_space:select({5}, { timeout = 1.00, iterator = 'LE', limit = 5 }) > ---- > -- - [5] > - - [4] > - - [3] > - - [2] > - - [1] > -... > -remote_space:select({5}, { iterator = 'LE', limit = 5}) > ---- > -- - [5] > - - [4] > - - [3] > - - [2] > - - [1] > -... > -remote_space:select({5}, { timeout = 1e-9, iterator = 'LE', limit = 5 }) > ---- > -- error: Timeout exceeded > -... > -remote_pk:select({2}, { timeout = 1.00, iterator = 'LE', limit = 5 }) > ---- > -- - [2] > - - [1] > - - [0] > -... > -remote_pk:select({2}, { iterator = 'LE', limit = 5}) > ---- > -- - [2] > - - [1] > - - [0] > -... > -remote_pk:select({2}, { timeout = 1e-9, iterator = 'LE', limit = 5 }) > ---- > -- error: Timeout exceeded > -... > -remote_pk:count({2}, { timeout = 1.00}) > ---- > -- 1 > -... > -remote_pk:count({2}, { timeout = 1e-9}) > ---- > -- error: Timeout exceeded > -... > -remote_pk:count({2}) > ---- > -- 1 > -... > -remote_pk:count({2}, { timeout = 1.00, iterator = 'LE' }) > ---- > -- 3 > -... > -remote_pk:count({2}, { iterator = 'LE'}) > ---- > -- 3 > -... > -remote_pk:count({2}, { timeout = 1e-9, iterator = 'LE' }) > ---- > -- error: Timeout exceeded > -... > -remote_pk:min(nil, { timeout = 1.00 }) > ---- > -- [0] > -... > -remote_pk:min(nil, { timeout = 1e-9 }) > ---- > -- error: Timeout exceeded > -... > -remote_pk:min(nil) > ---- > -- [0] > -... > -remote_pk:min({0}, { timeout = 1e-9 }) > ---- > -- error: Timeout exceeded > -... > -remote_pk:min({1}) > ---- > -- [1] > -... > -remote_pk:min({2}, { timeout = 1.00 }) > ---- > -- [2] > -... > -remote_pk:max(nil) > ---- > -- [354, 1, 2, 4] > -... > -remote_pk:max(nil, { timeout = 1e-9 }) > ---- > -- error: Timeout exceeded > -... > -remote_pk:max(nil, { timeout = 1.00 }) > ---- > -- [354, 1, 2, 4] > -... > -remote_pk:max({0}, { timeout = 1.00 }) > ---- > -- [0] > -... > -remote_pk:max({1}, { timeout = 1e-9 }) > ---- > -- error: Timeout exceeded > -... > -remote_pk:max({2}) > ---- > -- [2] > -... > --- > --- gh-3262: index:count() inconsistent results > --- > -test_run:cmd("setopt delimiter ';'") > ---- > -- true > -... > -function do_count_test(min, it) > - local r1 = remote_pk:count(min, {iterator = it} ) > - local r2 = box.space.net_box_test_space.index.primary:count(min, {iterator = it} ) > - local r3 = remote.self.space.net_box_test_space.index.primary:count(min, {iterator = it} ) > - return r1 == r2 and r2 == r3 > -end; > ---- > -... > -data = remote_pk:select(); > ---- > -... > -for _, v in pairs(data) do > - local itrs = {'GE', 'GT', 'LE', 'LT' } > - for _, it in pairs(itrs) do > - assert(do_count_test(v[0], it) == true) > - end > -end; > ---- > -... > -test_run:cmd("setopt delimiter ''"); > ---- > -- true > -... > -_ = remote_space:delete({0}, { timeout = 1e-9 }) > ---- > -- error: Timeout exceeded > -... > -_ = remote_pk:delete({0}, { timeout = 1.00 }) > ---- > -... > -_ = remote_space:delete({1}, { timeout = 1.00 }) > ---- > -... > -_ = remote_pk:delete({1}, { timeout = 1e-9 }) > ---- > -- error: Timeout exceeded > -... > -_ = remote_space:delete({2}, { timeout = 1e-9 }) > ---- > -- error: Timeout exceeded > -... > -_ = remote_pk:delete({2}) > ---- > -... > -_ = remote_pk:delete({3}) > ---- > -... > -_ = remote_pk:delete({4}) > ---- > -... > -_ = remote_pk:delete({5}) > ---- > -... > -remote_space:get(0) > ---- > -... > -remote_space:get(1) > ---- > -... > -remote_space:get(2) > ---- > -... > -remote_space = nil > ---- > -... > -cn:call('ret_after', {0.01}, { timeout = 1.00 }) > ---- > -- [[0.01]] > -... > -cn:call('ret_after', {1.00}, { timeout = 1e-9 }) > ---- > -- error: Timeout exceeded > -... > -cn:eval('return ret_after(...)', {0.01}, { timeout = 1.00 }) > ---- > -- [[0.01]] > -... > -cn:eval('return ret_after(...)', {1.00}, { timeout = 1e-9 }) > ---- > -- error: Timeout exceeded > -... > --- > --- :timeout() > --- @deprecated since 1.7.4 > --- > -cn:timeout(1).space.net_box_test_space.index.primary:select{234} > ---- > -- - [234, 1, 2, 3] > -... > -cn:call('ret_after', {.01}) > ---- > -- [[0.01]] > -... > -cn:timeout(1):call('ret_after', {.01}) > ---- > -- [[0.01]] > -... > -cn:timeout(.01):call('ret_after', {1}) > ---- > -- error: Timeout exceeded > -... > -cn = remote:timeout(0.0000000001):connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123' }) > ---- > -... > -cn:close() > ---- > -... > -cn = remote:timeout(1):connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123' }) > ---- > -... > -remote.self:ping() > ---- > -- true > -... > -remote.self.space.net_box_test_space:select{234} > ---- > -- - [234, 1, 2, 3] > -... > -remote.self:timeout(123).space.net_box_test_space:select{234} > ---- > -- - [234, 1, 2, 3] > -... > -remote.self:is_connected() > ---- > -- true > -... > -remote.self:wait_connected() > ---- > -- true > -... > -cn:close() > ---- > -... > --- cleanup database after tests > -space:drop() > ---- > -... > --- #1545 empty password > -cn = remote.connect(LISTEN.host, LISTEN.service, { user = 'test' }) > ---- > -... > -cn ~= nil > ---- > -- true > -... > -cn:close() > ---- > -... > -cn = remote.connect(LISTEN.host, LISTEN.service, { password = 'test' }) > ---- > -- error: 'net.box: user is not defined' > -... > -cn ~= nil > ---- > -- true > -... > -cn:close() > ---- > -... > --- #544 usage for remote[point]method > -cn = remote.connect(LISTEN.host, LISTEN.service) > ---- > -... > -box.schema.user.grant('guest', 'execute', 'universe') > ---- > -... > -cn:close() > ---- > -... > -cn = remote.connect(LISTEN.host, LISTEN.service) > ---- > -... > -cn:eval('return true') > ---- > -- true > -... > -cn.eval('return true') > ---- > -- error: 'Use remote:eval(...) instead of remote.eval(...):' > -... > -cn.ping() > ---- > -- error: 'Use remote:ping(...) instead of remote.ping(...):' > -... > -cn:close() > ---- > -... > -remote.self:eval('return true') > ---- > -- true > -... > -remote.self.eval('return true') > ---- > -- error: 'Use remote:eval(...) instead of remote.eval(...):' > -... > -box.schema.user.revoke('guest', 'execute', 'universe') > ---- > -... > --- uri as the first argument > -uri = string.format('%s:%s@%s:%s', 'netbox', 'test', LISTEN.host, LISTEN.service) > ---- > -... > -cn = remote.new(uri) > ---- > -... > -cn:ping() > ---- > -- true > -... > -cn:close() > ---- > -... > -uri = string.format('%s@%s:%s', 'netbox', LISTEN.host, LISTEN.service) > ---- > -... > -cn = remote.new(uri) > ---- > -... > -cn ~= nil, cn.state, cn.error > ---- > -- true > -- error > -- Incorrect password supplied for user 'netbox' > -... > -cn:close() > ---- > -... > --- don't merge creds from uri & opts > -remote.new(uri, { password = 'test' }) > ---- > -- error: 'net.box: user is not defined' > -... > -cn = remote.new(uri, { user = 'netbox', password = 'test' }) > ---- > -... > -cn:ping() > ---- > -- true > -... > -cn:close() > ---- > -... > -box.schema.user.drop('netbox') > ---- > -... > --- #594: bad argument #1 to 'setmetatable' (table expected, got number) > -box.schema.func.create('dostring') > ---- > -... > -box.schema.user.grant('guest', 'execute', 'function', 'dostring') > ---- > -... > -test_run:cmd("setopt delimiter ';'") > ---- > -- true > -... > -function gh594() > - local cn = remote.connect(box.cfg.listen) > - local ping = fiber.create(function() cn:ping() end) > - cn:call('dostring', {'return 2 + 2'}) > - cn:close() > -end; > ---- > -... > -test_run:cmd("setopt delimiter ''"); > ---- > -- true > -... > -gh594() > ---- > -... > -box.schema.func.drop('dostring') > ---- > -... > --- #636: Reload schema on demand > -sp = box.schema.space.create('test_old') > ---- > -... > -_ = sp:create_index('primary') > ---- > -... > -sp:insert{1, 2, 3} > ---- > -- [1, 2, 3] > -... > -box.schema.user.grant('guest', 'read', 'space', 'test_old') > ---- > -... > -con = remote.new(box.cfg.listen) > ---- > -... > -con:ping() > ---- > -- true > -... > -con.space.test_old:select{} > ---- > -- - [1, 2, 3] > -... > -con.space.test == nil > ---- > -- true > -... > -sp = box.schema.space.create('test') > ---- > -... > -_ = sp:create_index('primary') > ---- > -... > -sp:insert{2, 3, 4} > ---- > -- [2, 3, 4] > -... > -box.schema.user.grant('guest', 'read', 'space', 'test') > ---- > -... > -con.space.test == nil > ---- > -- true > -... > -con:reload_schema() > ---- > -... > -con.space.test:select{} > ---- > -- - [2, 3, 4] > -... > -box.space.test:drop() > ---- > -... > -box.space.test_old:drop() > ---- > -... > -con:close() > ---- > -... > -name = string.match(arg[0], "([^,]+)%.lua") > ---- > -... > -file_log = require('fio').open(name .. '.log', {'O_RDONLY', 'O_NONBLOCK'}) > ---- > -... > -file_log:seek(0, 'SEEK_END') ~= 0 > ---- > -- true > -... > -box.schema.user.grant('guest', 'execute', 'universe') > ---- > -... > -test_run:cmd("setopt delimiter ';'") > ---- > -- true > -... > -_ = fiber.create( > - function() > - local conn = require('net.box').new(box.cfg.listen) > - conn:call('no_such_function', {}) > - conn:close() > - end > -); > ---- > -... > -test_run:cmd("setopt delimiter ''"); > ---- > -- true > -... > -test_run:wait_log('default', 'ER_NO_SUCH_PROC', nil, 10) > ---- > -- ER_NO_SUCH_PROC > -... > -box.schema.user.revoke('guest', 'execute', 'universe') > ---- > -... > --- > --- gh-3900: tarantool can be crashed by sending gibberish to a > --- binary socket > --- > -socket = require("socket") > ---- > -... > -sock = socket.tcp_connect(LISTEN.host, LISTEN.service) > ---- > -... > -data = string.fromhex("6783000000000000000000000000000000000000000000800000C8000000000000000000000000000000000000000000FFFF210100373208000000FFFF000055AAEB66486472530D02000000000010A0350001008000001000000000000000000000000000D05700") > ---- > -... > -sock:write(data) > ---- > -- 104 > -... > -test_run:wait_log('default', 'ER_INVALID_MSGPACK: Invalid MsgPack %- packet body', nil, 10) > ---- > -- 'ER_INVALID_MSGPACK: Invalid MsgPack - packet body' > -... > -sock:close() > ---- > -- true > -... > --- gh-983 selecting a lot of data crashes the server or hangs the > --- connection > --- gh-983 test case: iproto connection selecting a lot of data > -_ = box.schema.space.create('test', { temporary = true }) > ---- > -... > -_ = box.space.test:create_index('primary', {type = 'TREE', parts = {1,'unsigned'}}) > ---- > -... > -data1k = "aaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhh" > ---- > -... > -for i = 0,10000 do box.space.test:insert{i, data1k} end > ---- > -... > -box.schema.user.grant('guest', 'read', 'space', 'test') > ---- > -... > -net = require('net.box') > ---- > -... > -c = net:connect(box.cfg.listen) > ---- > -... > -r = c.space.test:select(nil, {limit=5000}) > ---- > -... > -box.space.test:drop() > ---- > -... > --- gh-970 gh-971 UPSERT over network > -_ = box.schema.space.create('test') > ---- > -... > -_ = box.space.test:create_index('primary', {type = 'TREE', parts = {1,'unsigned'}}) > ---- > -... > -_ = box.space.test:create_index('covering', {type = 'TREE', parts = {1,'unsigned',3,'string',2,'unsigned'}}) > ---- > -... > -_ = box.space.test:insert{1, 2, "string"} > ---- > -... > -box.schema.user.grant('guest', 'read,write', 'space', 'test') > ---- > -... > -c = net:connect(box.cfg.listen) > ---- > -... > -c.space.test:select{} > ---- > -- - [1, 2, 'string'] > -... > -c.space.test:upsert({1, 2, 'nothing'}, {{'+', 2, 1}}) -- common update > ---- > -... > -c.space.test:select{} > ---- > -- - [1, 3, 'string'] > -... > -c.space.test:upsert({2, 4, 'something'}, {{'+', 2, 1}}) -- insert > ---- > -... > -c.space.test:select{} > ---- > -- - [1, 3, 'string'] > - - [2, 4, 'something'] > -... > -c.space.test:upsert({2, 4, 'nothing'}, {{'+', 3, 100500}}) -- wrong operation > ---- > -... > -c.space.test:select{} > ---- > -- - [1, 3, 'string'] > - - [2, 4, 'something'] > -... > --- gh-1729 net.box index metadata incompatible with local metadata > -c.space.test.index.primary.parts > ---- > -- - type: unsigned > - is_nullable: false > - fieldno: 1 > -... > -c.space.test.index.covering.parts > ---- > -- - type: unsigned > - is_nullable: false > - fieldno: 1 > - - type: string > - is_nullable: false > - fieldno: 3 > - - type: unsigned > - is_nullable: false > - fieldno: 2 > -... > -box.space.test:drop() > ---- > -... > --- CALL vs CALL_16 in connect options > -function echo(...) return ... end > ---- > -... > -box.schema.user.grant('guest', 'execute', 'universe') > ---- > -... > -c = net.connect(box.cfg.listen) > ---- > -... > -c:call('echo', {42}) > ---- > -- 42 > -... > -c:eval('return echo(...)', {42}) > ---- > -- 42 > -... > --- invalid arguments > -c:call('echo', 42) > ---- > -- error: 'builtin/box/net_box.lua..."]:<line>: Use remote:call(func_name, {arg1, arg2, ...}, > - opts) instead of remote:call(func_name, arg1, arg2, ...)' > -... > -c:eval('return echo(...)', 42) > ---- > -- error: 'builtin/box/net_box.lua..."]:<line>: Use remote:eval(expression, {arg1, arg2, ...}, > - opts) instead of remote:eval(expression, arg1, arg2, ...)' > -... > -c:close() > ---- > -... > -c = net.connect(box.cfg.listen, {call_16 = true}) > ---- > -... > -c:call('echo', 42) > ---- > -- - [42] > -... > -c:eval('return echo(...)', 42) > ---- > -- 42 > -... > -c:close() > ---- > -... > -box.schema.user.revoke('guest', 'execute', 'universe') > ---- > -... > --- > --- gh-2195 export pure msgpack from net.box > --- > -space = box.schema.space.create('test') > ---- > -... > -_ = box.space.test:create_index('primary') > ---- > -... > -box.schema.user.grant('guest', 'read,write', 'space', 'test') > ---- > -... > -box.schema.user.grant('guest', 'execute', 'universe') > ---- > -... > -c = net.connect(box.cfg.listen) > ---- > -... > -ibuf = require('buffer').ibuf() > ---- > -... > -c:ping() > ---- > -- true > -... > -c.space.test ~= nil > ---- > -- true > -... > -c.space.test:replace({1, 'hello'}) > ---- > -- [1, 'hello'] > -... > --- replace > -c.space.test:replace({2}, {buffer = ibuf}) > ---- > -- 9 > -... > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > ---- > -... > -result > ---- > -- {48: [[2]]} > -... > --- replace + skip_header > -c.space.test:replace({2}, {buffer = ibuf, skip_header = true}) > ---- > -- 7 > -... > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > ---- > -... > -result > ---- > -- [[2]] > -... > --- insert > -c.space.test:insert({3}, {buffer = ibuf}) > ---- > -- 9 > -... > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > ---- > -... > -result > ---- > -- {48: [[3]]} > -... > --- insert + skip_header > -_ = space:delete({3}) > ---- > -... > -c.space.test:insert({3}, {buffer = ibuf, skip_header = true}) > ---- > -- 7 > -... > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > ---- > -... > -result > ---- > -- [[3]] > -... > --- update > -c.space.test:update({3}, {}, {buffer = ibuf}) > ---- > -- 9 > -... > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > ---- > -... > -result > ---- > -- {48: [[3]]} > -... > -c.space.test.index.primary:update({3}, {}, {buffer = ibuf}) > ---- > -- 9 > -... > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > ---- > -... > -result > ---- > -- {48: [[3]]} > -... > --- update + skip_header > -c.space.test:update({3}, {}, {buffer = ibuf, skip_header = true}) > ---- > -- 7 > -... > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > ---- > -... > -result > ---- > -- [[3]] > -... > -c.space.test.index.primary:update({3}, {}, {buffer = ibuf, skip_header = true}) > ---- > -- 7 > -... > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > ---- > -... > -result > ---- > -- [[3]] > -... > --- upsert > -c.space.test:upsert({4}, {}, {buffer = ibuf}) > ---- > -- 7 > -... > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > ---- > -... > -result > ---- > -- {48: []} > -... > --- upsert + skip_header > -c.space.test:upsert({4}, {}, {buffer = ibuf, skip_header = true}) > ---- > -- 5 > -... > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > ---- > -... > -result > ---- > -- [] > -... > --- delete > -c.space.test:upsert({4}, {}, {buffer = ibuf}) > ---- > -- 7 > -... > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > ---- > -... > -result > ---- > -- {48: []} > -... > --- delete + skip_header > -c.space.test:upsert({4}, {}, {buffer = ibuf, skip_header = true}) > ---- > -- 5 > -... > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > ---- > -... > -result > ---- > -- [] > -... > --- select > -c.space.test.index.primary:select({3}, {iterator = 'LE', buffer = ibuf}) > ---- > -- 19 > -... > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > ---- > -... > -result > ---- > -- {48: [[3], [2], [1, 'hello']]} > -... > --- select + skip_header > -c.space.test.index.primary:select({3}, {iterator = 'LE', buffer = ibuf, skip_header = true}) > ---- > -- 17 > -... > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > ---- > -... > -result > ---- > -- [[3], [2], [1, 'hello']] > -... > --- select > -len = c.space.test:select({}, {buffer = ibuf}) > ---- > -... > -ibuf.rpos + len == ibuf.wpos > ---- > -- true > -... > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > ---- > -... > -ibuf.rpos == ibuf.wpos > ---- > -- true > -... > -len > ---- > -- 21 > -... > -result > ---- > -- {48: [[1, 'hello'], [2], [3], [4]]} > -... > --- select + skip_header > -len = c.space.test:select({}, {buffer = ibuf, skip_header = true}) > ---- > -... > -ibuf.rpos + len == ibuf.wpos > ---- > -- true > -... > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > ---- > -... > -ibuf.rpos == ibuf.wpos > ---- > -- true > -... > -len > ---- > -- 19 > -... > -result > ---- > -- [[1, 'hello'], [2], [3], [4]] > -... > --- call > -c:call("echo", {1, 2, 3}, {buffer = ibuf}) > ---- > -- 10 > -... > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > ---- > -... > -result > ---- > -- {48: [1, 2, 3]} > -... > -c:call("echo", {}, {buffer = ibuf}) > ---- > -- 7 > -... > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > ---- > -... > -result > ---- > -- {48: []} > -... > -c:call("echo", nil, {buffer = ibuf}) > ---- > -- 7 > -... > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > ---- > -... > -result > ---- > -- {48: []} > -... > --- call + skip_header > -c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > ---- > -- 8 > -... > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > ---- > -... > -result > ---- > -- [1, 2, 3] > -... > -c:call("echo", {}, {buffer = ibuf, skip_header = true}) > ---- > -- 5 > -... > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > ---- > -... > -result > ---- > -- [] > -... > -c:call("echo", nil, {buffer = ibuf, skip_header = true}) > ---- > -- 5 > -... > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > ---- > -... > -result > ---- > -- [] > -... > --- eval > -c:eval("echo(...)", {1, 2, 3}, {buffer = ibuf}) > ---- > -- 7 > -... > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > ---- > -... > -result > ---- > -- {48: []} > -... > -c:eval("echo(...)", {}, {buffer = ibuf}) > ---- > -- 7 > -... > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > ---- > -... > -result > ---- > -- {48: []} > -... > -c:eval("echo(...)", nil, {buffer = ibuf}) > ---- > -- 7 > -... > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > ---- > -... > -result > ---- > -- {48: []} > -... > --- eval + skip_header > -c:eval("echo(...)", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > ---- > -- 5 > -... > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > ---- > -... > -result > ---- > -- [] > -... > -c:eval("echo(...)", {}, {buffer = ibuf, skip_header = true}) > ---- > -- 5 > -... > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > ---- > -... > -result > ---- > -- [] > -... > -c:eval("echo(...)", nil, {buffer = ibuf, skip_header = true}) > ---- > -- 5 > -... > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > ---- > -... > -result > ---- > -- [] > -... > --- make several request into a buffer with skip_header, then read > --- results > -c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > ---- > -- 8 > -... > -c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > ---- > -- 8 > -... > -c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > ---- > -- 8 > -... > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > ---- > -... > -result > ---- > -- [1, 2, 3] > -... > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > ---- > -... > -result > ---- > -- [1, 2, 3] > -... > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > ---- > -... > -result > ---- > -- [1, 2, 3] > -... > --- unsupported methods > -c.space.test:get({1}, { buffer = ibuf}) > ---- > -- error: 'builtin/box/net_box.lua..."]:<line>: index:get() doesn''t support `buffer` argument' > -... > -c.space.test.index.primary:min({}, { buffer = ibuf}) > ---- > -- error: 'builtin/box/net_box.lua..."]:<line>: index:min() doesn''t support `buffer` argument' > -... > -c.space.test.index.primary:max({}, { buffer = ibuf}) > ---- > -- error: 'builtin/box/net_box.lua..."]:<line>: index:max() doesn''t support `buffer` argument' > -... > -c.space.test.index.primary:count({}, { buffer = ibuf}) > ---- > -- error: 'builtin/box/net_box.lua..."]:<line>: index:count() doesn''t support `buffer` argument' > -... > -c.space.test.index.primary:get({1}, { buffer = ibuf}) > ---- > -- error: 'builtin/box/net_box.lua..."]:<line>: index:get() doesn''t support `buffer` argument' > -... > --- error handling > -rpos, wpos = ibuf.rpos, ibuf.wpos > ---- > -... > -c.space.test:insert({1}, {buffer = ibuf}) > ---- > -- error: Duplicate key exists in unique index 'primary' in space 'test' > -... > -ibuf.rpos == rpos, ibuf.wpos == wpos > ---- > -- true > -- true > -... > -ibuf = nil > ---- > -... > -c:close() > ---- > -... > -space:drop() > ---- > -... > -box.schema.user.revoke('guest', 'execute', 'universe') > ---- > -... > --- gh-1904 net.box hangs in :close() if a fiber was cancelled > --- while blocked in :_wait_state() in :_request() > -options = {user = 'netbox', password = 'badpass', wait_connected = false, reconnect_after = 0.01} > ---- > -... > -c = net:new(box.cfg.listen, options) > ---- > -... > -f = fiber.create(function() c:call("") end) > ---- > -... > -fiber.sleep(0.01) > ---- > -... > -f:cancel(); c:close() > ---- > -... > -box.schema.user.grant('guest', 'read', 'space', '_schema') > ---- > -... > --- check for on_schema_reload callback > -test_run:cmd("setopt delimiter ';'") > ---- > -- true > -... > -do > - local a = 0 > - function osr_cb() > - a = a + 1 > - end > - local con = net.new(box.cfg.listen, { > - wait_connected = false > - }) > - con:on_schema_reload(osr_cb) > - con:wait_connected() > - con.space._schema:select{} > - box.schema.space.create('misisipi') > - box.space.misisipi:drop() > - con.space._schema:select{} > - con:close() > - con = nil > - > - return a > -end; > ---- > -- 2 > -... > -do > - local a = 0 > - function osr_cb() > - a = a + 1 > - end > - local con = net.new(box.cfg.listen, { > - wait_connected = true > - }) > - con:on_schema_reload(osr_cb) > - con.space._schema:select{} > - box.schema.space.create('misisipi') > - box.space.misisipi:drop() > - con.space._schema:select{} > - con:close() > - con = nil > - > - return a > -end; > ---- > -- 1 > -... > -test_run:cmd("setopt delimiter ''"); > ---- > -- true > -... > -box.schema.user.revoke('guest', 'read', 'space', '_schema') > ---- > -... > --- Tarantool < 1.7.1 compatibility (gh-1533) > -c = net.new(box.cfg.listen) > ---- > -... > -c:ping() > ---- > -- true > -... > -c:close() > ---- > -... > --- Test for connect_timeout > 0 in netbox connect > -test_run:cmd("setopt delimiter ';'"); > ---- > -- true > -... > -need_stop = false; > ---- > -... > -greeting = > -"Tarantool 1.7.3 (Lua console)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" .. > -"type 'help' for interactive help~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"; > ---- > -... > -socket = require('socket'); > ---- > -... > -srv = socket.tcp_server('localhost', 0, { > - handler = function(fd) > - local fiber = require('fiber') > - while not need_stop do > - fiber.sleep(0.01) > - end > - fd:write(greeting) > - end > -}); > ---- > -... > --- we must get timeout > -port = srv:name().port > -nb = net.new('localhost:' .. port, { > - wait_connected = true, console = true, > - connect_timeout = 0.1 > -}); > ---- > -... > -nb.error:find('timed out') ~= nil; > ---- > -- true > -... > -need_stop = true > -nb:close(); > ---- > -... > --- we must get peer closed > -nb = net.new('localhost:' .. port, { > - wait_connected = true, console = true, > - connect_timeout = 0.2 > -}); > ---- > -... > -nb.error ~= "Timeout exceeded"; > ---- > -- true > -... > -nb:close(); > ---- > -... > -test_run:cmd("setopt delimiter ''"); > ---- > -- true > -... > -srv:close() > ---- > -- true > -... > -test_run:cmd("clear filter") > ---- > -- true > -... > --- > --- gh-2402 net.box doesn't support space:format() > --- > -space = box.schema.space.create('test', {format={{name="id", type="unsigned"}}}) > ---- > -... > -space ~= nil > ---- > -- true > -... > -_ = box.space.test:create_index('primary') > ---- > -... > -box.schema.user.grant('guest', 'read', 'space', 'test') > ---- > -... > -c = net.connect(box.cfg.listen) > ---- > -... > -c:ping() > ---- > -- true > -... > -c.space.test ~= nil > ---- > -- true > -... > -format = c.space.test:format() > ---- > -... > -format[1] ~= nil > ---- > -- true > -... > -format[1].name == "id" > ---- > -- true > -... > -format[1].type == "unsigned" > ---- > -- true > -... > -c.space.test:format({}) > ---- > -- error: net.box does not support setting space format > -... > --- > --- gh-4091: index unique flag is always false. > --- > -c.space.test.index.primary.unique > ---- > -- true > -... > -c:close() > ---- > -... > -space:drop() > ---- > -... > --- > --- Check that it's possible to get connection object form net.box space > --- > -space = box.schema.space.create('test', {format={{name="id", type="unsigned"}}}) > ---- > -... > -space ~= nil > ---- > -- true > -... > -_ = box.space.test:create_index('primary') > ---- > -... > -box.schema.user.grant('guest','read,write,execute','space', 'test') > ---- > -... > -c = net.connect(box.cfg.listen) > ---- > -... > -c:ping() > ---- > -- true > -... > -c.space.test ~= nil > ---- > -- true > -... > -c.space.test.connection == c > ---- > -- true > -... > -box.schema.user.revoke('guest','read,write,execute','space', 'test') > ---- > -... > -c:close() > ---- > -... > --- > --- gh-2642: box.session.type() > --- > -box.schema.user.grant('guest','execute','universe') > ---- > -... > -c = net.connect(box.cfg.listen) > ---- > -... > -c:call("box.session.type") > ---- > -- binary > -... > -c:close() > ---- > -... > -box.schema.user.revoke('guest', 'execute', 'universe') > ---- > -... > --- > --- On_connect/disconnect triggers. > --- > -test_run:cmd('create server connecter with script = "box/proxy.lua"') > ---- > -- true > -... > -test_run:cmd('start server connecter') > ---- > -- true > -... > -test_run:cmd("set variable connect_to to 'connecter.listen'") > ---- > -- true > -... > -conn = net.connect(connect_to, { reconnect_after = 0.1 }) > ---- > -... > -conn.state > ---- > -- active > -... > -connected_cnt = 0 > ---- > -... > -disconnected_cnt = 0 > ---- > -... > -function on_connect() connected_cnt = connected_cnt + 1 end > ---- > -... > -function on_disconnect() disconnected_cnt = disconnected_cnt + 1 end > ---- > -... > -conn:on_connect(on_connect) > ---- > -... > -conn:on_disconnect(on_disconnect) > ---- > -... > -test_run:cmd('stop server connecter') > ---- > -- true > -... > -test_run:cmd('start server connecter') > ---- > -- true > -... > -while conn.state ~= 'active' do fiber.sleep(0.1) end > ---- > -... > -connected_cnt > ---- > -- 1 > -... > -old_disconnected_cnt = disconnected_cnt > ---- > -... > -disconnected_cnt >= 1 > ---- > -- true > -... > -conn:close() > ---- > -... > -disconnected_cnt == old_disconnected_cnt + 1 > ---- > -- true > -... > -test_run:cmd('stop server connecter') > ---- > -- true > -... > --- > --- gh-2401 update pseudo objects not replace them > --- > -space:drop() > ---- > -... > -space = box.schema.space.create('test') > ---- > -... > -box.schema.user.grant('guest', 'read', 'space', 'test') > ---- > -... > -c = net.connect(box.cfg.listen) > ---- > -... > -cspace = c.space.test > ---- > -... > -space.index.test_index == nil > ---- > -- true > -... > -cspace.index.test_index == nil > ---- > -- true > -... > -_ = space:create_index("test_index", {parts={1, 'string'}}) > ---- > -... > -c:reload_schema() > ---- > -... > -space.index.test_index ~= nil > ---- > -- true > -... > -cspace.index.test_index ~= nil > ---- > -- true > -... > -c.space.test.index.test_index ~= nil > ---- > -- true > -... > --- cleanup > -space:drop() > ---- > -... > --- > --- gh-946: long polling CALL blocks input > --- > -box.schema.func.create('fast_call') > ---- > -... > -box.schema.func.create('long_call') > ---- > -... > -box.schema.func.create('wait_signal') > ---- > -... > -box.schema.user.grant('guest', 'execute', 'function', 'fast_call') > ---- > -... > -box.schema.user.grant('guest', 'execute', 'function', 'long_call') > ---- > -... > -box.schema.user.grant('guest', 'execute', 'function', 'wait_signal') > ---- > -... > -c = net.connect(box.cfg.listen) > ---- > -... > -N = 100 > ---- > -... > -pad = string.rep('x', 1024) > ---- > -... > -long_call_cond = fiber.cond() > ---- > -... > -long_call_channel = fiber.channel() > ---- > -... > -fast_call_channel = fiber.channel() > ---- > -... > -function fast_call(x) return x end > ---- > -... > -function long_call(x) long_call_cond:wait() return x * 2 end > ---- > -... > -test_run:cmd("setopt delimiter ';'") > ---- > -- true > -... > -for i = 1, N do > - fiber.create(function() > - fast_call_channel:put(c:call('fast_call', {i, pad})) > - end) > - fiber.create(function() > - long_call_channel:put(c:call('long_call', {i, pad})) > - end) > -end > -test_run:cmd("setopt delimiter ''"); > ---- > -... > -x = 0 > ---- > -... > -for i = 1, N do x = x + fast_call_channel:get() end > ---- > -... > -x > ---- > -- 5050 > -... > -long_call_cond:broadcast() > ---- > -... > -x = 0 > ---- > -... > -for i = 1, N do x = x + long_call_channel:get() end > ---- > -... > -x > ---- > -- 10100 > -... > --- > --- Check that a connection does not leak if there is > --- a long CALL in progress when it is closed. > --- > -disconnected = false > ---- > -... > -function on_disconnect() disconnected = true end > ---- > -... > --- Make sure all dangling connections are collected so > --- that on_disconnect trigger isn't called spuriously. > -collectgarbage('collect') > ---- > -- 0 > -... > -fiber.sleep(0) > ---- > -... > -box.session.on_disconnect(on_disconnect) == on_disconnect > ---- > -- true > -... > --- > --- gh-3859: on_disconnect is called only after all requests are > --- processed, but should be called right after disconnect and > --- only once. > --- > -ch1 = fiber.channel(1) > ---- > -... > -ch2 = fiber.channel(1) > ---- > -... > -function wait_signal() ch1:put(true) ch2:get() end > ---- > -... > -_ = fiber.create(function() c:call('wait_signal') end) > ---- > -... > -ch1:get() > ---- > -- true > -... > -c:close() > ---- > -... > -fiber.sleep(0) > ---- > -... > -while disconnected == false do fiber.sleep(0.01) end > ---- > -... > -disconnected -- true > ---- > -- true > -... > -disconnected = nil > ---- > -... > -ch2:put(true) > ---- > -- true > -... > -fiber.sleep(0) > ---- > -... > -disconnected -- nil, on_disconnect is not called second time. > ---- > -- null > -... > -box.session.on_disconnect(nil, on_disconnect) > ---- > -... > -box.schema.func.drop('long_call') > ---- > -... > -box.schema.func.drop('fast_call') > ---- > -... > -box.schema.func.drop('wait_signal') > ---- > -... > --- > --- gh-2666: check that netbox.call is not repeated on schema > --- change. > --- > -box.schema.user.grant('guest', 'write', 'space', '_space') > ---- > -... > -box.schema.user.grant('guest', 'write', 'space', '_schema') > ---- > -... > -box.schema.user.grant('guest', 'create', 'universe') > ---- > -... > -count = 0 > ---- > -... > -function create_space(name) count = count + 1 box.schema.create_space(name) return true end > ---- > -... > -box.schema.func.create('create_space') > ---- > -... > -box.schema.user.grant('guest', 'execute', 'function', 'create_space') > ---- > -... > -c = net.connect(box.cfg.listen) > ---- > -... > -c:call('create_space', {'test1'}) > ---- > -- true > -... > -count > ---- > -- 1 > -... > -c:call('create_space', {'test2'}) > ---- > -- true > -... > -count > ---- > -- 2 > -... > -c:call('create_space', {'test3'}) > ---- > -- true > -... > -count > ---- > -- 3 > -... > -box.space.test1:drop() > ---- > -... > -box.space.test2:drop() > ---- > -... > -box.space.test3:drop() > ---- > -... > -box.schema.user.revoke('guest', 'write', 'space', '_space') > ---- > -... > -box.schema.user.revoke('guest', 'write', 'space', '_schema') > ---- > -... > -box.schema.user.revoke('guest', 'create', 'universe') > ---- > -... > -c:close() > ---- > -... > -box.schema.func.drop('create_space') > ---- > -... > --- > --- gh-3164: netbox connection is not closed and garbage collected > --- ever, if reconnect_after is set. > --- > -test_run:cmd('start server connecter') > ---- > -- true > -... > -test_run:cmd("set variable connect_to to 'connecter.listen'") > ---- > -- true > -... > -weak = setmetatable({}, {__mode = 'v'}) > ---- > -... > --- Create strong and weak reference. Weak is valid until strong > --- is valid too. > -strong = net.connect(connect_to, {reconnect_after = 0.1}) > ---- > -... > -weak.c = strong > ---- > -... > -weak.c:ping() > ---- > -- true > -... > -test_run:cmd('stop server connecter') > ---- > -- true > -... > -test_run:cmd('cleanup server connecter') > ---- > -- true > -... > --- Check the connection tries to reconnect at least two times. > --- 'Cannot assign requested address' is the crutch for running the > --- tests in a docker. This error emits instead of > --- 'Connection refused' inside a docker. > -old_log_level = box.cfg.log_level > ---- > -... > -box.cfg{log_level = 6} > ---- > -... > -log.info(string.rep('a', 1000)) > ---- > -... > -test_run:cmd("setopt delimiter ';'") > ---- > -- true > -... > -while test_run:grep_log('default', 'Network is unreachable', 1000) == nil and > - test_run:grep_log('default', 'Connection refused', 1000) == nil and > - test_run:grep_log('default', 'Cannot assign requested address', 1000) == nil do > - fiber.sleep(0.1) > -end; > ---- > -... > -log.info(string.rep('a', 1000)); > ---- > -... > -while test_run:grep_log('default', 'Network is unreachable', 1000) == nil and > - test_run:grep_log('default', 'Connection refused', 1000) == nil and > - test_run:grep_log('default', 'Cannot assign requested address', 1000) == nil do > - fiber.sleep(0.1) > -end; > ---- > -... > -test_run:cmd("setopt delimiter ''"); > ---- > -- true > -... > -box.cfg{log_level = old_log_level} > ---- > -... > -collectgarbage('collect') > ---- > -- 0 > -... > -strong.state > ---- > -- error_reconnect > -... > -strong == weak.c > ---- > -- true > -... > --- Remove single strong reference. Now connection must be garbage > --- collected. > -strong = nil > ---- > -... > -collectgarbage('collect') > ---- > -- 0 > -... > --- Now weak.c is null, because it was weak reference, and the > --- connection is deleted by 'collect'. > -weak.c > ---- > -- null > -... > --- > --- gh-2677: netbox supports console connections, that complicates > --- both console and netbox. It was necessary because before a > --- connection is established, a console does not known is it > --- binary or text protocol, and netbox could not be created from > --- existing socket. > --- > -box.schema.user.grant('guest', 'execute', 'universe') > ---- > -... > -urilib = require('uri') > ---- > -... > -uri = urilib.parse(tostring(box.cfg.listen)) > ---- > -... > -s, greeting = net.establish_connection(uri.host, uri.service) > ---- > -... > -c = net.wrap(s, greeting, uri.host, uri.service, {reconnect_after = 0.01}) > ---- > -... > -c.state > ---- > -- active > -... > -a = 100 > ---- > -... > -function kek(args) return {1, 2, 3, args} end > ---- > -... > -c:eval('a = 200') > ---- > -... > -a > ---- > -- 200 > -... > -c:call('kek', {300}) > ---- > -- [1, 2, 3, 300] > -... > -s = box.schema.create_space('test') > ---- > -... > -box.schema.user.grant('guest', 'read,write', 'space', 'test') > ---- > -... > -pk = s:create_index('pk') > ---- > -... > -c:reload_schema() > ---- > -... > -c.space.test:replace{1} > ---- > -- [1] > -... > -c.space.test:get{1} > ---- > -- [1] > -... > -c.space.test:delete{1} > ---- > -- [1] > -... > --- > --- Break a connection to test reconnect_after. > --- > -_ = c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') > ---- > -... > -while not c:is_connected() do fiber.sleep(0.01) end > ---- > -... > -c:ping() > ---- > -- true > -... > -s:drop() > ---- > -... > -c:close() > ---- > -... > --- > --- Test a case, when netbox can not connect first time, but > --- reconnect_after is set. > --- > -c = net.connect('localhost:33333', {reconnect_after = 0.1, wait_connected = false}) > ---- > -... > -while c.state ~= 'error_reconnect' do fiber.sleep(0.01) end > ---- > -... > -c:close() > ---- > -... > -box.schema.user.revoke('guest', 'execute', 'universe') > ---- > -... > -c.state > ---- > -- closed > -... > -c = nil > ---- > -... > --- > --- gh-3256 net.box is_nullable and collation options output > --- > -space = box.schema.create_space('test') > ---- > -... > -box.schema.user.grant('guest', 'read', 'space', 'test') > ---- > -... > -_ = space:create_index('pk') > ---- > -... > -_ = space:create_index('sk', {parts = {{2, 'unsigned', is_nullable = true}}}) > ---- > -... > -c = net:connect(box.cfg.listen) > ---- > -... > -c.space.test.index.sk.parts > ---- > -- - type: unsigned > - is_nullable: true > - fieldno: 2 > -... > -space:drop() > ---- > -... > -space = box.schema.create_space('test') > ---- > -... > -c:close() > ---- > -... > -box.schema.user.grant('guest', 'read', 'space', 'test') > ---- > -... > -c = net:connect(box.cfg.listen) > ---- > -... > -box.internal.collation.create('test', 'ICU', 'ru-RU') > ---- > -... > -collation_id = box.internal.collation.id_by_name('test') > ---- > -... > -_ = space:create_index('sk', { type = 'tree', parts = {{1, 'str', collation = 'test'}}, unique = true }) > ---- > -... > -c:reload_schema() > ---- > -... > -parts = c.space.test.index.sk.parts > ---- > -... > -#parts == 1 > ---- > -- true > -... > -parts[1].fieldno == 1 > ---- > -- true > -... > -parts[1].type == 'string' > ---- > -- true > -... > -parts[1].is_nullable == false > ---- > -- true > -... > -if _TARANTOOL >= '2.2.1' then \ > - return parts[1].collation == 'test' \ > -else \ > - return parts[1].collation_id == collation_id \ > -end > ---- > -- true > -... > -c:close() > ---- > -... > -box.internal.collation.drop('test') > ---- > -... > -space:drop() > ---- > -... > -c.state > ---- > -- closed > -... > -c = nil > ---- > -... > --- > --- gh-3107: fiber-async netbox. > --- > -cond = nil > ---- > -... > -box.schema.func.create('long_function') > ---- > -... > -box.schema.user.grant('guest', 'execute', 'function', 'long_function') > ---- > -... > -function long_function(...) cond = fiber.cond() cond:wait() return ... end > ---- > -... > -function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end > ---- > -... > -s = box.schema.create_space('test') > ---- > -... > -pk = s:create_index('pk') > ---- > -... > -s:replace{1} > ---- > -- [1] > -... > -s:replace{2} > ---- > -- [2] > -... > -s:replace{3} > ---- > -- [3] > -... > -s:replace{4} > ---- > -- [4] > -... > -c = net:connect(box.cfg.listen) > ---- > -... > --- > --- Check long connections, multiple wait_result(). > --- > -future = c:call('long_function', {1, 2, 3}, {is_async = true}) > ---- > -... > -future:result() > ---- > -- null > -- Response is not ready > -... > -future:is_ready() > ---- > -- false > -... > -future:wait_result(0.01) -- Must fail on timeout. > ---- > -- null > -- Timeout exceeded > -... > -finalize_long() > ---- > -... > -ret = future:wait_result(100) > ---- > -... > -future:is_ready() > ---- > -- true > -... > --- Any timeout is ok - response is received already. > -future:wait_result(0) > ---- > -- [1, 2, 3] > -... > -future:wait_result(0.01) > ---- > -- [1, 2, 3] > -... > -ret > ---- > -- [1, 2, 3] > -... > -_, err = pcall(future.wait_result, future, true) > ---- > -... > -err:find('Usage') ~= nil > ---- > -- true > -... > -_, err = pcall(future.wait_result, future, '100') > ---- > -... > -err:find('Usage') ~= nil > ---- > -- true > -... > --- > --- Check infinity timeout. > --- > -ret = nil > ---- > -... > -_ = fiber.create(function() ret = c:call('long_function', {1, 2, 3}, {is_async = true}):wait_result() end) > ---- > -... > -finalize_long() > ---- > -... > -while not ret do fiber.sleep(0.01) end > ---- > -... > -ret > ---- > -- [1, 2, 3] > -... > -c:close() > ---- > -... > -box.schema.user.grant('guest', 'execute', 'universe') > ---- > -... > -c = net:connect(box.cfg.listen) > ---- > -... > -future = c:eval('return long_function(...)', {1, 2, 3}, {is_async = true}) > ---- > -... > -future:result() > ---- > -- null > -- Response is not ready > -... > -future:wait_result(0.01) -- Must fail on timeout. > ---- > -- null > -- Timeout exceeded > -... > -finalize_long() > ---- > -... > -future:wait_result(100) > ---- > -- [1, 2, 3] > -... > -c:close() > ---- > -... > --- > --- Check that is_async does not work on a closed connection. > --- > -c:call('any_func', {}, {is_async = true}) > ---- > -- error: Connection closed > -... > -box.schema.user.revoke('guest', 'execute', 'universe') > ---- > -... > -c = net:connect(box.cfg.listen) > ---- > -... > --- > --- Ensure the request is garbage collected both if is not used and > --- if is. > --- > -gc_test = setmetatable({}, {__mode = 'v'}) > ---- > -... > -gc_test.future = c:call('long_function', {1, 2, 3}, {is_async = true}) > ---- > -... > -gc_test.future ~= nil > ---- > -- true > -... > -collectgarbage() > ---- > -- 0 > -... > -gc_test > ---- > -- [] > -... > -finalize_long() > ---- > -... > -future = c:call('long_function', {1, 2, 3}, {is_async = true}) > ---- > -... > -collectgarbage() > ---- > -- 0 > -... > -future ~= nil > ---- > -- true > -... > -finalize_long() > ---- > -... > -future:wait_result(1000) > ---- > -- [1, 2, 3] > -... > -collectgarbage() > ---- > -- 0 > -... > -future ~= nil > ---- > -- true > -... > -gc_test.future = future > ---- > -... > -future = nil > ---- > -... > -collectgarbage() > ---- > -- 0 > -... > -gc_test > ---- > -- [] > -... > --- > --- Ensure a request can be finalized from non-caller fibers. > --- > -future = c:call('long_function', {1, 2, 3}, {is_async = true}) > ---- > -... > -ret = {} > ---- > -... > -count = 0 > ---- > -... > -for i = 1, 10 do fiber.create(function() ret[i] = future:wait_result(1000) count = count + 1 end) end > ---- > -... > -future:wait_result(0.01) -- Must fail on timeout. > ---- > -- null > -- Timeout exceeded > -... > -finalize_long() > ---- > -... > -while count ~= 10 do fiber.sleep(0.1) end > ---- > -... > -ret > ---- > -- - &0 [1, 2, 3] > - - *0 > - - *0 > - - *0 > - - *0 > - - *0 > - - *0 > - - *0 > - - *0 > - - *0 > -... > --- > --- Test space methods. > --- > -c:close() > ---- > -... > -box.schema.user.grant('guest', 'read,write', 'space', 'test') > ---- > -... > -c = net:connect(box.cfg.listen) > ---- > -... > -future = c.space.test:select({1}, {is_async = true}) > ---- > -... > -ret = future:wait_result(100) > ---- > -... > -ret > ---- > -- - [1] > -... > -type(ret[1]) > ---- > -- cdata > -... > -future = c.space.test:insert({5}, {is_async = true}) > ---- > -... > -future:wait_result(100) > ---- > -- [5] > -... > -s:get{5} > ---- > -- [5] > -... > -future = c.space.test:replace({6}, {is_async = true}) > ---- > -... > -future:wait_result(100) > ---- > -- [6] > -... > -s:get{6} > ---- > -- [6] > -... > -future = c.space.test:delete({6}, {is_async = true}) > ---- > -... > -future:wait_result(100) > ---- > -- [6] > -... > -s:get{6} > ---- > -... > -future = c.space.test:update({5}, {{'=', 2, 5}}, {is_async = true}) > ---- > -... > -future:wait_result(100) > ---- > -- [5, 5] > -... > -s:get{5} > ---- > -- [5, 5] > -... > -future = c.space.test:upsert({5}, {{'=', 2, 6}}, {is_async = true}) > ---- > -... > -future:wait_result(100) > ---- > -- null > -... > -s:get{5} > ---- > -- [5, 6] > -... > -future = c.space.test:get({5}, {is_async = true}) > ---- > -... > -future:wait_result(100) > ---- > -- [5, 6] > -... > --- > --- Test index methods. > --- > -future = c.space.test.index.pk:select({1}, {is_async = true}) > ---- > -... > -future:wait_result(100) > ---- > -- - [1] > -... > -future = c.space.test.index.pk:get({2}, {is_async = true}) > ---- > -... > -future:wait_result(100) > ---- > -- [2] > -... > -future = c.space.test.index.pk:min({}, {is_async = true}) > ---- > -... > -future:wait_result(100) > ---- > -- [1] > -... > -future = c.space.test.index.pk:max({}, {is_async = true}) > ---- > -... > -future:wait_result(100) > ---- > -- [5, 6] > -... > -c:close() > ---- > -... > -box.schema.user.grant('guest', 'execute', 'universe') > ---- > -... > -c = net:connect(box.cfg.listen) > ---- > -... > -future = c.space.test.index.pk:count({3}, {is_async = true}) > ---- > -... > -future:wait_result(100) > ---- > -- 1 > -... > -c:close() > ---- > -... > -box.schema.user.revoke('guest', 'execute', 'universe') > ---- > -... > -c = net:connect(box.cfg.listen) > ---- > -... > -future = c.space.test.index.pk:delete({3}, {is_async = true}) > ---- > -... > -future:wait_result(100) > ---- > -- [3] > -... > -s:get{3} > ---- > -... > -future = c.space.test.index.pk:update({4}, {{'=', 2, 6}}, {is_async = true}) > ---- > -... > -future:wait_result(100) > ---- > -- [4, 6] > -... > -s:get{4} > ---- > -- [4, 6] > -... > --- > --- Test async errors. > --- > -future = c.space.test:insert({1}, {is_async = true}) > ---- > -... > -future:wait_result() > ---- > -- null > -- Duplicate key exists in unique index 'pk' in space 'test' > -... > -future:result() > ---- > -- null > -- Duplicate key exists in unique index 'pk' in space 'test' > -... > --- > --- Test discard. > --- > -future = c:call('long_function', {1, 2, 3}, {is_async = true}) > ---- > -... > -future:discard() > ---- > -... > -finalize_long() > ---- > -... > -future:result() > ---- > -- null > -- Response is discarded > -... > -future:wait_result(100) > ---- > -- null > -- Response is discarded > -... > --- > --- Test closed connection. > --- > -future = c:call('long_function', {1, 2, 3}, {is_async = true}) > ---- > -... > -finalize_long() > ---- > -... > -future:wait_result(100) > ---- > -- [1, 2, 3] > -... > -future2 = c:call('long_function', {1, 2, 3}, {is_async = true}) > ---- > -... > -c:close() > ---- > -... > -future2:wait_result(100) > ---- > -- null > -- Connection closed > -... > -future2:result() > ---- > -- null > -- Connection closed > -... > -future2:discard() > ---- > -... > --- Already successful result must be available. > -future:wait_result(100) > ---- > -- [1, 2, 3] > -... > -future:result() > ---- > -- [1, 2, 3] > -... > -future:is_ready() > ---- > -- true > -... > -finalize_long() > ---- > -... > --- > --- Test reconnect. > --- > -c = net:connect(box.cfg.listen, {reconnect_after = 0.01}) > ---- > -... > -future = c:call('long_function', {1, 2, 3}, {is_async = true}) > ---- > -... > -_ = c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') > ---- > -... > -while not c:is_connected() do fiber.sleep(0.01) end > ---- > -... > -finalize_long() > ---- > -... > -future:wait_result(100) > ---- > -- null > -- Peer closed > -... > -future:result() > ---- > -- null > -- Peer closed > -... > -future = c:call('long_function', {1, 2, 3}, {is_async = true}) > ---- > -... > -finalize_long() > ---- > -... > -future:wait_result(100) > ---- > -- [1, 2, 3] > -... > --- > --- Test raw response getting. > --- > -ibuf = require('buffer').ibuf() > ---- > -... > -future = c:call('long_function', {1, 2, 3}, {is_async = true, buffer = ibuf}) > ---- > -... > -finalize_long() > ---- > -... > -future:wait_result(100) > ---- > -- 10 > -... > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > ---- > -... > -result > ---- > -- {48: [1, 2, 3]} > -... > -box.schema.func.drop('long_function') > ---- > -... > --- > --- Test async schema version change. > --- > -function change_schema(i) local tmp = box.schema.create_space('test'..i) return 'ok' end > ---- > -... > -box.schema.func.create('change_schema') > ---- > -... > -box.schema.user.grant('guest', 'execute', 'function', 'change_schema') > ---- > -... > -box.schema.user.grant('guest', 'write', 'space', '_schema') > ---- > -... > -box.schema.user.grant('guest', 'read,write', 'space', '_space') > ---- > -... > -box.schema.user.grant('guest', 'create', 'space') > ---- > -... > -future1 = c:call('change_schema', {'1'}, {is_async = true}) > ---- > -... > -future2 = c:call('change_schema', {'2'}, {is_async = true}) > ---- > -... > -future3 = c:call('change_schema', {'3'}, {is_async = true}) > ---- > -... > -future1:wait_result() > ---- > -- ['ok'] > -... > -future2:wait_result() > ---- > -- ['ok'] > -... > -future3:wait_result() > ---- > -- ['ok'] > -... > -c:close() > ---- > -... > -s:drop() > ---- > -... > -box.space.test1:drop() > ---- > -... > -box.space.test2:drop() > ---- > -... > -box.space.test3:drop() > ---- > -... > -box.schema.func.drop('change_schema') > ---- > -... > --- > --- gh-2978: field names for tuples received from netbox. > --- > -_ = box.schema.create_space("named", {format = {{name = "id"}, {name="abc"}}}) > ---- > -... > -_ = box.space.named:create_index('id', {parts = {{1, 'unsigned'}}}) > ---- > -... > -box.space.named:insert({1, 1}) > ---- > -- [1, 1] > -... > -box.schema.user.grant('guest', 'read, write, execute', 'space') > ---- > -... > -cn = net.connect(box.cfg.listen) > ---- > -... > -s = cn.space.named > ---- > -... > -s:get{1}.id > ---- > -- 1 > -... > -s:get{1}:tomap() > ---- > -- 1: 1 > - 2: 1 > - abc: 1 > - id: 1 > -... > -s:insert{2,3}:tomap() > ---- > -- 1: 2 > - 2: 3 > - abc: 3 > - id: 2 > -... > -s:replace{2,14}:tomap() > ---- > -- 1: 2 > - 2: 14 > - abc: 14 > - id: 2 > -... > -s:update(1, {{'+', 2, 10}}):tomap() > ---- > -- 1: 1 > - 2: 11 > - abc: 11 > - id: 1 > -... > -s:select()[1]:tomap() > ---- > -- 1: 1 > - 2: 11 > - abc: 11 > - id: 1 > -... > -s:delete({2}):tomap() > ---- > -- 1: 2 > - 2: 14 > - abc: 14 > - id: 2 > -... > --- Check that formats changes after reload. > -box.space.named:format({{name = "id2"}, {name="abc2"}}) > ---- > -... > -s:select()[1]:tomap() > ---- > -- 1: 1 > - 2: 11 > - abc: 11 > - id: 1 > -... > -cn:reload_schema() > ---- > -... > -s:select()[1]:tomap() > ---- > -- 1: 1 > - 2: 11 > - id2: 1 > - abc2: 11 > -... > -cn:close() > ---- > -... > -box.space.named:drop() > ---- > -... > -box.schema.user.revoke('guest', 'read, write, execute', 'space') > ---- > -... > --- > --- gh-3400: long-poll input discard must not touch event loop of > --- a closed connection. > --- > -function long() fiber.yield() return 100 end > ---- > -... > -c = net.connect(box.cfg.listen) > ---- > -... > -c:ping() > ---- > -- true > -... > --- Create batch of two requests. First request is sent to TX > --- thread, second one terminates connection. The preceeding > --- request discards input, and this operation must not trigger > --- new attempts to read any data - the connection is closed > --- already. > --- > -f = fiber.create(c._transport.perform_request, nil, nil, false, 'call_17', nil, nil, nil, 'long', {}) c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') > ---- > -... > -while f:status() ~= 'dead' do fiber.sleep(0.01) end > ---- > -... > -c:close() > ---- > -... > --- > --- gh-3464: iproto hangs in 100% CPU when too big packet size > --- is received due to size_t overflow. > --- > -c = net:connect(box.cfg.listen) > ---- > -... > -data = msgpack.encode(18400000000000000000)..'aaaaaaa' > ---- > -... > -c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, data) > ---- > -- null > -- Peer closed > -... > -c:close() > ---- > -... > -test_run:grep_log('default', 'too big packet size in the header') ~= nil > ---- > -- true > -... > --- > --- gh-3629: netbox leaks when a connection is closed deliberately > --- and it has non-finished requests. > --- > -ready = false > ---- > -... > -ok = nil > ---- > -... > -err = nil > ---- > -... > -c = net:connect(box.cfg.listen) > ---- > -... > -function do_long() while not ready do fiber.sleep(0.01) end end > ---- > -... > -box.schema.func.create('do_long') > ---- > -... > -box.schema.user.grant('guest', 'execute', 'function', 'do_long') > ---- > -... > -f = fiber.create(function() ok, err = pcall(c.call, c, 'do_long') end) > ---- > -... > -while f:status() ~= 'suspended' do fiber.sleep(0.01) end > ---- > -... > -c:close() > ---- > -... > -ready = true > ---- > -... > -while not err do fiber.sleep(0.01) end > ---- > -... > -ok, err > ---- > -- false > -- Connection closed > -... > --- > --- gh-3856: wait_connected = false is ignored. > --- > -c = net.connect('8.8.8.8:123456', {wait_connected = false}) > ---- > -... > -c > ---- > -- opts: > - wait_connected: false > - host: 8.8.8.8 > - state: initial > - port: '123456' > -... > -c:close() > ---- > -... > -box.schema.func.drop('do_long') > ---- > -... > -box.schema.user.revoke('guest', 'write', 'space', '_schema') > ---- > -... > -box.schema.user.revoke('guest', 'read,write', 'space', '_space') > ---- > -... > -box.schema.user.revoke('guest', 'create', 'space') > ---- > -... > --- > --- gh-3958 updating box.cfg.readahead doesn't affect existing connections. > --- > -readahead = box.cfg.readahead > ---- > -... > -box.cfg{readahead = 128} > ---- > -... > -s = box.schema.space.create("test") > ---- > -... > -_ = s:create_index("pk") > ---- > -... > -box.schema.user.grant("guest", "read,write", "space", "test") > ---- > -... > --- connection is created with small readahead value, > --- make sure it is updated if box.cfg.readahead is changed. > -c = net.connect(box.cfg.listen) > ---- > -... > -box.cfg{readahead = 100 * 1024} > ---- > -... > -box.error.injection.set("ERRINJ_WAL_DELAY", true) > ---- > -- ok > -... > -pad = string.rep('x', 8192) > ---- > -... > -for i = 1, 5 do c.space.test:replace({i, pad}, {is_async = true}) end > ---- > -... > -box.error.injection.set("ERRINJ_WAL_DELAY", false) > ---- > -- ok > -... > -test_run:wait_log('default', 'readahead limit is reached', 1024, 0.1) > ---- > -... > -s:drop() > ---- > -... > -box.cfg{readahead = readahead} > ---- > -... > --- > --- related to gh-4040: log corrupted rows > --- > -log_level = box.cfg.log_level > ---- > -... > -box.cfg{log_level=6} > ---- > -... > -sock = socket.tcp_connect(LISTEN.host, LISTEN.service) > ---- > -... > -sock:read(9) > ---- > -- Tarantool > -... > --- we need to have a packet with correctly encoded length, > --- so that it bypasses iproto length check, but cannot be > --- decoded in xrow_header_decode > --- 0x3C = 60, sha1 digest is 20 bytes long > -data = string.fromhex('3C'..string.rep(require('digest').sha1_hex('bcde'), 3)) > ---- > -... > -sock:write(data) > ---- > -- 61 > -... > -sock:close() > ---- > -- true > -... > -test_run:wait_log('default', 'Got a corrupted row.*', nil, 10) > ---- > -- 'Got a corrupted row:' > -... > -test_run:wait_log('default', '00000000:.*', nil, 10) > ---- > -- '00000000: A3 02 D6 5A E4 D9 E7 68 A1 53 8D 53 60 5F 20 3F ' > -... > -test_run:wait_log('default', '00000010:.*', nil, 10) > ---- > -- '00000010: D8 E2 D6 E2 A3 02 D6 5A E4 D9 E7 68 A1 53 8D 53 ' > -... > -test_run:wait_log('default', '00000020:.*', nil, 10) > ---- > -- '00000020: 60 5F 20 3F D8 E2 D6 E2 A3 02 D6 5A E4 D9 E7 68 ' > -... > -test_run:wait_log('default', '00000030:.*', nil, 10) > ---- > -- '00000030: A1 53 8D 53 60 5F 20 3F D8 E2 D6 E2 ' > -... > --- we expect nothing below, so don't wait > -test_run:grep_log('default', '00000040:.*') > ---- > -- null > -... > -box.cfg{log_level=log_level} > ---- > -... > diff --git a/test/box/net.box.test.lua b/test/box/net.box.test.lua > deleted file mode 100644 > index 8e65ff470..000000000 > --- a/test/box/net.box.test.lua > +++ /dev/null > @@ -1,1585 +0,0 @@ > -remote = require 'net.box' > -fiber = require 'fiber' > -log = require 'log' > -msgpack = require 'msgpack' > -env = require('test_run') > -test_run = env.new() > -test_run:cmd("push filter ".."'\\.lua.*:[0-9]+: ' to '.lua...\"]:<line>: '") > - > -test_run:cmd("setopt delimiter ';'") > -function x_select(cn, space_id, index_id, iterator, offset, limit, key, opts) > - local ret = cn:_request('select', opts, nil, space_id, index_id, iterator, > - offset, limit, key) > - return ret > -end > -function x_fatal(cn) cn._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') end > -test_run:cmd("setopt delimiter ''"); > - > -LISTEN = require('uri').parse(box.cfg.listen) > -space = box.schema.space.create('net_box_test_space') > -index = space:create_index('primary', { type = 'tree' }) > - > --- low level connection > -log.info("create connection") > -cn = remote.connect(LISTEN.host, LISTEN.service) > -log.info("state is %s", cn.state) > - > -cn:ping() > -log.info("ping is done") > -cn:ping() > -log.info("ping is done") > - > - > -cn:ping() > - > - > --- check permissions > -cn:call('unexists_procedure') > -function test_foo(a,b,c) return { {{ [a] = 1 }}, {{ [b] = 2 }}, c } end > -cn:call('test_foo', {'a', 'b', 'c'}) > -cn:eval('return 2+2') > -cn:close() > --- connect and call without usage access > -box.schema.user.grant('guest','execute','universe') > -box.schema.user.revoke('guest','usage','universe') > -box.session.su("guest") > -cn = remote.connect(LISTEN.host, LISTEN.service) > -cn:call('test_foo', {'a', 'b', 'c'}) > -box.session.su("admin") > -box.schema.user.grant('guest','usage','universe') > -cn:close() > -cn = remote.connect(box.cfg.listen) > - > -cn:call('unexists_procedure') > -cn:call('test_foo', {'a', 'b', 'c'}) > -cn:call(nil, {'a', 'b', 'c'}) > -cn:eval('return 2+2') > -cn:eval('return 1, 2, 3') > -cn:eval('return ...', {1, 2, 3}) > -cn:eval('return { k = "v1" }, true, { xx = 10, yy = 15 }, nil') > -cn:eval('return nil') > -cn:eval('return') > -cn:eval('error("exception")') > -cn:eval('box.error(0)') > -cn:eval('!invalid expression') > - > --- box.commit() missing at return of CALL/EVAL > -function no_commit() box.begin() fiber.sleep(0.001) end > -cn:call('no_commit') > -cn:eval('no_commit()') > - > -remote.self:eval('return 1+1, 2+2') > -remote.self:eval('return') > -remote.self:eval('error("exception")') > -remote.self:eval('box.error(0)') > -remote.self:eval('!invalid expression') > - > -box.schema.user.revoke('guest', 'execute', 'universe') > - > --- > --- gh-822: net.box.call should roll back local transaction on error > --- > - > -_ = box.schema.space.create('gh822') > -_ = box.space.gh822:create_index('primary') > - > -test_run:cmd("setopt delimiter ';'") > - > --- rollback on invalid function > -function rollback_on_invalid_function() > - box.begin() > - box.space.gh822:insert{1, "netbox_test"} > - pcall(remote.self.call, remote.self, 'invalid_function') > - return box.space.gh822:get(1) == nil > -end; > -rollback_on_invalid_function(); > - > --- rollback on call error > -function test_error() error('Some error') end; > -function rollback_on_call_error() > - box.begin() > - box.space.gh822:insert{1, "netbox_test"} > - pcall(remote.self.call, remote.self, 'test_error') > - return box.space.gh822:get(1) == nil > -end; > -rollback_on_call_error(); > - > --- rollback on eval > -function rollback_on_eval_error() > - box.begin() > - box.space.gh822:insert{1, "netbox_test"} > - pcall(remote.self.eval, remote.self, "error('Some error')") > - return box.space.gh822:get(1) == nil > -end; > -rollback_on_eval_error(); > - > -test_run:cmd("setopt delimiter ''"); > -box.space.gh822:drop() > - > -box.schema.user.grant('guest', 'read,write', 'space', 'net_box_test_space') > -box.schema.user.grant('guest', 'execute', 'universe') > - > -cn:close() > -cn = remote.connect(box.cfg.listen) > - > -x_select(cn, space.id, space.index.primary.id, box.index.EQ, 0, 0xFFFFFFFF, 123) > -space:insert{123, 345} > -x_select(cn, space.id, space.index.primary.id, box.index.EQ, 0, 0, 123) > -x_select(cn, space.id, space.index.primary.id, box.index.EQ, 0, 1, 123) > -x_select(cn, space.id, space.index.primary.id, box.index.EQ, 1, 1, 123) > - > -cn.space[space.id] ~= nil > -cn.space.net_box_test_space ~= nil > -cn.space.net_box_test_space ~= nil > -cn.space.net_box_test_space.index ~= nil > -cn.space.net_box_test_space.index.primary ~= nil > -cn.space.net_box_test_space.index[space.index.primary.id] ~= nil > - > - > -cn.space.net_box_test_space.index.primary:select(123) > -cn.space.net_box_test_space.index.primary:select(123, { limit = 0 }) > -cn.space.net_box_test_space.index.primary:select(nil, { limit = 1, }) > -cn.space.net_box_test_space:insert{234, 1,2,3} > -cn.space.net_box_test_space:insert{234, 1,2,3} > -cn.space.net_box_test_space.insert{234, 1,2,3} > - > -cn.space.net_box_test_space:replace{354, 1,2,3} > -cn.space.net_box_test_space:replace{354, 1,2,4} > - > -cn.space.net_box_test_space:select{123} > -space:select({123}, { iterator = 'GE' }) > -cn.space.net_box_test_space:select({123}, { iterator = 'GE' }) > -cn.space.net_box_test_space:select({123}, { iterator = 'GT' }) > -cn.space.net_box_test_space:select({123}, { iterator = 'GT', limit = 1 }) > -cn.space.net_box_test_space:select({123}, { iterator = 'GT', limit = 1, offset = 1 }) > - > -cn.space.net_box_test_space:select{123} > -cn.space.net_box_test_space:update({123}, { { '+', 2, 1 } }) > -cn.space.net_box_test_space:update(123, { { '+', 2, 1 } }) > -cn.space.net_box_test_space:select{123} > - > -cn.space.net_box_test_space:insert(cn.space.net_box_test_space:get{123}:update{ { '=', 1, 2 } }) > -cn.space.net_box_test_space:delete{123} > -cn.space.net_box_test_space:select{2} > -cn.space.net_box_test_space:select({234}, { iterator = 'LT' }) > - > -cn.space.net_box_test_space:update({1}, { { '+', 2, 2 } }) > - > -cn.space.net_box_test_space:delete{1} > -cn.space.net_box_test_space:delete{2} > -cn.space.net_box_test_space:delete{2} > - > --- test one-based indexing in splice operation (see update.test.lua) > -cn.space.net_box_test_space:replace({10, 'abcde'}) > -cn.space.net_box_test_space:update(10, {{':', 2, 0, 0, '!'}}) > -cn.space.net_box_test_space:update(10, {{':', 2, 1, 0, '('}}) > -cn.space.net_box_test_space:update(10, {{':', 2, 2, 0, '({'}}) > -cn.space.net_box_test_space:update(10, {{':', 2, -1, 0, ')'}}) > -cn.space.net_box_test_space:update(10, {{':', 2, -2, 0, '})'}}) > -cn.space.net_box_test_space:delete{10} > - > -cn.space.net_box_test_space:select({}, { iterator = 'ALL' }) > --- gh-841: net.box uses incorrect iterator type for select with no arguments > -cn.space.net_box_test_space:select() > - > -cn.space.net_box_test_space.index.primary:min() > -cn.space.net_box_test_space.index.primary:min(354) > -cn.space.net_box_test_space.index.primary:max() > -cn.space.net_box_test_space.index.primary:max(234) > -cn.space.net_box_test_space.index.primary:count() > -cn.space.net_box_test_space.index.primary:count(354) > - > -cn.space.net_box_test_space:get(354) > - > --- reconnects after errors > - > -box.schema.user.revoke('guest', 'execute', 'universe') > -box.schema.func.create('test_foo') > -box.schema.user.grant('guest', 'execute', 'function', 'test_foo') > - > --- -- 1. no reconnect > -x_fatal(cn) > -cn.state > -cn:ping() > -cn:call('test_foo') > -cn:wait_state('active') > - > --- -- 2 reconnect > -cn = remote.connect(LISTEN.host, LISTEN.service, { reconnect_after = .1 }) > -cn.space ~= nil > - > -cn.space.net_box_test_space:select({}, { iterator = 'ALL' }) > -x_fatal(cn) > -cn:wait_connected() > -cn:wait_state('active') > -cn:wait_state({active=true}) > -cn:ping() > -cn.state > -cn.space.net_box_test_space:select({}, { iterator = 'ALL' }) > - > -x_fatal(cn) > -x_select(cn, space.id, 0, box.index.ALL, 0, 0xFFFFFFFF, {}) > - > -cn.state > -cn:ping() > - > --- -- dot-new-method > - > -cn1 = remote.new(LISTEN.host, LISTEN.service) > -x_select(cn1, space.id, 0, box.index.ALL, 0, 0xFFFFFFF, {}) > -cn1:close() > --- -- error while waiting for response > -type(fiber.create(function() fiber.sleep(.5) x_fatal(cn) end)) > -function pause() fiber.sleep(10) return true end > - > -box.schema.func.create('pause') > -box.schema.user.grant('guest', 'execute', 'function', 'pause') > -cn:call('pause') > -cn:call('test_foo', {'a', 'b', 'c'}) > -box.schema.func.drop('pause') > - > --- call > -remote.self:call('test_foo', {'a', 'b', 'c'}) > -cn:call('test_foo', {'a', 'b', 'c'}) > -box.schema.func.drop('test_foo') > - > -box.schema.func.create('long_rep') > -box.schema.user.grant('guest', 'execute', 'function', 'long_rep') > - > --- long replies > -function long_rep() return { 1, string.rep('a', 5000) } end > -res = cn:call('long_rep') > -res[1] == 1 > -res[2] == string.rep('a', 5000) > - > -function long_rep() return { 1, string.rep('a', 50000) } end > -res = cn:call('long_rep') > -res[1] == 1 > -res[2] == string.rep('a', 50000) > - > -box.schema.func.drop('long_rep') > - > --- a.b.c.d > -u = '84F7BCFA-079C-46CC-98B4-F0C821BE833E' > -X = {} > -X.X = X > -function X.fn(x,y) return y or x end > -box.schema.user.grant('guest', 'execute', 'universe') > -cn:close() > -cn = remote.connect(LISTEN.host, LISTEN.service) > -cn:call('X.fn', {u}) > -cn:call('X.X.X.X.X.X.X.fn', {u}) > -cn:call('X.X.X.X:fn', {u}) > -box.schema.user.revoke('guest', 'execute', 'universe') > -cn:close() > - > --- auth > - > -cn = remote.connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123', wait_connected = true }) > -cn:is_connected() > -cn.error > -cn.state > - > - > -box.schema.user.create('netbox', { password = 'test' }) > -box.schema.user.grant('netbox', 'read,write', 'space', 'net_box_test_space') > -box.schema.user.grant('netbox', 'execute', 'universe') > -cn = remote.connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = 'test' }) > -cn.state > -cn.error > -cn:ping() > - > -function ret_after(to) fiber.sleep(to) return {{to}} end > - > -cn:ping({timeout = 1.00}) > -cn:ping({timeout = 1e-9}) > -cn:ping() > - > -remote_space = cn.space.net_box_test_space > -remote_pk = remote_space.index.primary > - > -remote_space:insert({0}, { timeout = 1.00 }) > -remote_space:insert({1}, { timeout = 1e-9 }) > -remote_space:insert({2}) > - > -remote_space:replace({0}, { timeout = 1e-9 }) > -remote_space:replace({1}) > -remote_space:replace({2}, { timeout = 1.00 }) > - > -remote_space:upsert({3}, {}, { timeout = 1e-9 }) > -remote_space:upsert({4}, {}) > -remote_space:upsert({5}, {}, { timeout = 1.00 }) > -remote_space:upsert({3}, {}) > - > -remote_space:update({3}, {}, { timeout = 1e-9 }) > -remote_space:update({4}, {}) > -remote_space:update({5}, {}, { timeout = 1.00 }) > -remote_space:update({3}, {}) > - > -remote_pk:update({5}, {}, { timeout = 1e-9 }) > -remote_pk:update({4}, {}) > -remote_pk:update({3}, {}, { timeout = 1.00 }) > -remote_pk:update({5}, {}) > - > -remote_space:get({0}) > -remote_space:get({1}, { timeout = 1.00 }) > -remote_space:get({2}, { timeout = 1e-9 }) > - > -remote_pk:get({3}, { timeout = 1e-9 }) > -remote_pk:get({4}) > -remote_pk:get({5}, { timeout = 1.00 }) > - > -remote_space:select({2}, { timeout = 1e-9 }) > -remote_space:select({2}, { timeout = 1.00 }) > -remote_space:select({2}) > - > -remote_pk:select({2}, { timeout = 1.00 }) > -remote_pk:select({2}, { timeout = 1e-9 }) > -remote_pk:select({2}) > - > -remote_space:select({5}, { timeout = 1.00, iterator = 'LE', limit = 5 }) > -remote_space:select({5}, { iterator = 'LE', limit = 5}) > -remote_space:select({5}, { timeout = 1e-9, iterator = 'LE', limit = 5 }) > - > -remote_pk:select({2}, { timeout = 1.00, iterator = 'LE', limit = 5 }) > -remote_pk:select({2}, { iterator = 'LE', limit = 5}) > -remote_pk:select({2}, { timeout = 1e-9, iterator = 'LE', limit = 5 }) > - > -remote_pk:count({2}, { timeout = 1.00}) > -remote_pk:count({2}, { timeout = 1e-9}) > -remote_pk:count({2}) > - > -remote_pk:count({2}, { timeout = 1.00, iterator = 'LE' }) > -remote_pk:count({2}, { iterator = 'LE'}) > -remote_pk:count({2}, { timeout = 1e-9, iterator = 'LE' }) > - > -remote_pk:min(nil, { timeout = 1.00 }) > -remote_pk:min(nil, { timeout = 1e-9 }) > -remote_pk:min(nil) > - > -remote_pk:min({0}, { timeout = 1e-9 }) > -remote_pk:min({1}) > -remote_pk:min({2}, { timeout = 1.00 }) > - > -remote_pk:max(nil) > -remote_pk:max(nil, { timeout = 1e-9 }) > -remote_pk:max(nil, { timeout = 1.00 }) > - > -remote_pk:max({0}, { timeout = 1.00 }) > -remote_pk:max({1}, { timeout = 1e-9 }) > -remote_pk:max({2}) > - > --- > --- gh-3262: index:count() inconsistent results > --- > -test_run:cmd("setopt delimiter ';'") > - > -function do_count_test(min, it) > - local r1 = remote_pk:count(min, {iterator = it} ) > - local r2 = box.space.net_box_test_space.index.primary:count(min, {iterator = it} ) > - local r3 = remote.self.space.net_box_test_space.index.primary:count(min, {iterator = it} ) > - return r1 == r2 and r2 == r3 > -end; > - > -data = remote_pk:select(); > - > -for _, v in pairs(data) do > - local itrs = {'GE', 'GT', 'LE', 'LT' } > - for _, it in pairs(itrs) do > - assert(do_count_test(v[0], it) == true) > - end > -end; > - > -test_run:cmd("setopt delimiter ''"); > - > -_ = remote_space:delete({0}, { timeout = 1e-9 }) > -_ = remote_pk:delete({0}, { timeout = 1.00 }) > -_ = remote_space:delete({1}, { timeout = 1.00 }) > -_ = remote_pk:delete({1}, { timeout = 1e-9 }) > -_ = remote_space:delete({2}, { timeout = 1e-9 }) > -_ = remote_pk:delete({2}) > -_ = remote_pk:delete({3}) > -_ = remote_pk:delete({4}) > -_ = remote_pk:delete({5}) > - > -remote_space:get(0) > -remote_space:get(1) > -remote_space:get(2) > - > -remote_space = nil > - > -cn:call('ret_after', {0.01}, { timeout = 1.00 }) > -cn:call('ret_after', {1.00}, { timeout = 1e-9 }) > - > -cn:eval('return ret_after(...)', {0.01}, { timeout = 1.00 }) > -cn:eval('return ret_after(...)', {1.00}, { timeout = 1e-9 }) > - > --- > --- :timeout() > --- @deprecated since 1.7.4 > --- > - > -cn:timeout(1).space.net_box_test_space.index.primary:select{234} > -cn:call('ret_after', {.01}) > -cn:timeout(1):call('ret_after', {.01}) > -cn:timeout(.01):call('ret_after', {1}) > - > -cn = remote:timeout(0.0000000001):connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123' }) > -cn:close() > -cn = remote:timeout(1):connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123' }) > - > -remote.self:ping() > -remote.self.space.net_box_test_space:select{234} > -remote.self:timeout(123).space.net_box_test_space:select{234} > -remote.self:is_connected() > -remote.self:wait_connected() > - > -cn:close() > --- cleanup database after tests > -space:drop() > - > --- #1545 empty password > -cn = remote.connect(LISTEN.host, LISTEN.service, { user = 'test' }) > -cn ~= nil > -cn:close() > -cn = remote.connect(LISTEN.host, LISTEN.service, { password = 'test' }) > -cn ~= nil > -cn:close() > - > --- #544 usage for remote[point]method > -cn = remote.connect(LISTEN.host, LISTEN.service) > - > -box.schema.user.grant('guest', 'execute', 'universe') > -cn:close() > -cn = remote.connect(LISTEN.host, LISTEN.service) > -cn:eval('return true') > -cn.eval('return true') > - > -cn.ping() > - > -cn:close() > - > -remote.self:eval('return true') > -remote.self.eval('return true') > -box.schema.user.revoke('guest', 'execute', 'universe') > - > --- uri as the first argument > -uri = string.format('%s:%s@%s:%s', 'netbox', 'test', LISTEN.host, LISTEN.service) > - > -cn = remote.new(uri) > -cn:ping() > -cn:close() > - > -uri = string.format('%s@%s:%s', 'netbox', LISTEN.host, LISTEN.service) > -cn = remote.new(uri) > -cn ~= nil, cn.state, cn.error > -cn:close() > --- don't merge creds from uri & opts > -remote.new(uri, { password = 'test' }) > -cn = remote.new(uri, { user = 'netbox', password = 'test' }) > -cn:ping() > -cn:close() > - > -box.schema.user.drop('netbox') > - > --- #594: bad argument #1 to 'setmetatable' (table expected, got number) > -box.schema.func.create('dostring') > -box.schema.user.grant('guest', 'execute', 'function', 'dostring') > -test_run:cmd("setopt delimiter ';'") > -function gh594() > - local cn = remote.connect(box.cfg.listen) > - local ping = fiber.create(function() cn:ping() end) > - cn:call('dostring', {'return 2 + 2'}) > - cn:close() > -end; > -test_run:cmd("setopt delimiter ''"); > -gh594() > -box.schema.func.drop('dostring') > - > - > --- #636: Reload schema on demand > -sp = box.schema.space.create('test_old') > -_ = sp:create_index('primary') > -sp:insert{1, 2, 3} > - > -box.schema.user.grant('guest', 'read', 'space', 'test_old') > -con = remote.new(box.cfg.listen) > -con:ping() > -con.space.test_old:select{} > -con.space.test == nil > - > -sp = box.schema.space.create('test') > -_ = sp:create_index('primary') > -sp:insert{2, 3, 4} > - > -box.schema.user.grant('guest', 'read', 'space', 'test') > - > -con.space.test == nil > -con:reload_schema() > -con.space.test:select{} > - > -box.space.test:drop() > -box.space.test_old:drop() > -con:close() > - > -name = string.match(arg[0], "([^,]+)%.lua") > -file_log = require('fio').open(name .. '.log', {'O_RDONLY', 'O_NONBLOCK'}) > -file_log:seek(0, 'SEEK_END') ~= 0 > - > -box.schema.user.grant('guest', 'execute', 'universe') > -test_run:cmd("setopt delimiter ';'") > - > -_ = fiber.create( > - function() > - local conn = require('net.box').new(box.cfg.listen) > - conn:call('no_such_function', {}) > - conn:close() > - end > -); > -test_run:cmd("setopt delimiter ''"); > -test_run:wait_log('default', 'ER_NO_SUCH_PROC', nil, 10) > -box.schema.user.revoke('guest', 'execute', 'universe') > - > --- > --- gh-3900: tarantool can be crashed by sending gibberish to a > --- binary socket > --- > -socket = require("socket") > -sock = socket.tcp_connect(LISTEN.host, LISTEN.service) > -data = string.fromhex("6783000000000000000000000000000000000000000000800000C8000000000000000000000000000000000000000000FFFF210100373208000000FFFF000055AAEB66486472530D02000000000010A0350001008000001000000000000000000000000000D05700") > -sock:write(data) > -test_run:wait_log('default', 'ER_INVALID_MSGPACK: Invalid MsgPack %- packet body', nil, 10) > -sock:close() > - > --- gh-983 selecting a lot of data crashes the server or hangs the > --- connection > - > --- gh-983 test case: iproto connection selecting a lot of data > -_ = box.schema.space.create('test', { temporary = true }) > -_ = box.space.test:create_index('primary', {type = 'TREE', parts = {1,'unsigned'}}) > - > -data1k = "aaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhh" > - > -for i = 0,10000 do box.space.test:insert{i, data1k} end > - > -box.schema.user.grant('guest', 'read', 'space', 'test') > -net = require('net.box') > -c = net:connect(box.cfg.listen) > -r = c.space.test:select(nil, {limit=5000}) > -box.space.test:drop() > - > --- gh-970 gh-971 UPSERT over network > -_ = box.schema.space.create('test') > -_ = box.space.test:create_index('primary', {type = 'TREE', parts = {1,'unsigned'}}) > -_ = box.space.test:create_index('covering', {type = 'TREE', parts = {1,'unsigned',3,'string',2,'unsigned'}}) > -_ = box.space.test:insert{1, 2, "string"} > -box.schema.user.grant('guest', 'read,write', 'space', 'test') > -c = net:connect(box.cfg.listen) > -c.space.test:select{} > -c.space.test:upsert({1, 2, 'nothing'}, {{'+', 2, 1}}) -- common update > -c.space.test:select{} > -c.space.test:upsert({2, 4, 'something'}, {{'+', 2, 1}}) -- insert > -c.space.test:select{} > -c.space.test:upsert({2, 4, 'nothing'}, {{'+', 3, 100500}}) -- wrong operation > -c.space.test:select{} > - > --- gh-1729 net.box index metadata incompatible with local metadata > -c.space.test.index.primary.parts > -c.space.test.index.covering.parts > - > -box.space.test:drop() > - > --- CALL vs CALL_16 in connect options > -function echo(...) return ... end > -box.schema.user.grant('guest', 'execute', 'universe') > -c = net.connect(box.cfg.listen) > -c:call('echo', {42}) > -c:eval('return echo(...)', {42}) > --- invalid arguments > -c:call('echo', 42) > -c:eval('return echo(...)', 42) > -c:close() > -c = net.connect(box.cfg.listen, {call_16 = true}) > -c:call('echo', 42) > -c:eval('return echo(...)', 42) > -c:close() > -box.schema.user.revoke('guest', 'execute', 'universe') > - > --- > --- gh-2195 export pure msgpack from net.box > --- > - > -space = box.schema.space.create('test') > -_ = box.space.test:create_index('primary') > -box.schema.user.grant('guest', 'read,write', 'space', 'test') > -box.schema.user.grant('guest', 'execute', 'universe') > -c = net.connect(box.cfg.listen) > -ibuf = require('buffer').ibuf() > - > -c:ping() > -c.space.test ~= nil > - > -c.space.test:replace({1, 'hello'}) > - > --- replace > -c.space.test:replace({2}, {buffer = ibuf}) > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > -result > - > --- replace + skip_header > -c.space.test:replace({2}, {buffer = ibuf, skip_header = true}) > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > -result > - > --- insert > -c.space.test:insert({3}, {buffer = ibuf}) > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > -result > - > --- insert + skip_header > -_ = space:delete({3}) > -c.space.test:insert({3}, {buffer = ibuf, skip_header = true}) > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > -result > - > --- update > -c.space.test:update({3}, {}, {buffer = ibuf}) > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > -result > -c.space.test.index.primary:update({3}, {}, {buffer = ibuf}) > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > -result > - > --- update + skip_header > -c.space.test:update({3}, {}, {buffer = ibuf, skip_header = true}) > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > -result > -c.space.test.index.primary:update({3}, {}, {buffer = ibuf, skip_header = true}) > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > -result > - > --- upsert > -c.space.test:upsert({4}, {}, {buffer = ibuf}) > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > -result > - > --- upsert + skip_header > -c.space.test:upsert({4}, {}, {buffer = ibuf, skip_header = true}) > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > -result > - > --- delete > -c.space.test:upsert({4}, {}, {buffer = ibuf}) > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > -result > - > --- delete + skip_header > -c.space.test:upsert({4}, {}, {buffer = ibuf, skip_header = true}) > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > -result > - > --- select > -c.space.test.index.primary:select({3}, {iterator = 'LE', buffer = ibuf}) > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > -result > - > --- select + skip_header > -c.space.test.index.primary:select({3}, {iterator = 'LE', buffer = ibuf, skip_header = true}) > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > -result > - > --- select > -len = c.space.test:select({}, {buffer = ibuf}) > -ibuf.rpos + len == ibuf.wpos > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > -ibuf.rpos == ibuf.wpos > -len > -result > - > --- select + skip_header > -len = c.space.test:select({}, {buffer = ibuf, skip_header = true}) > -ibuf.rpos + len == ibuf.wpos > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > -ibuf.rpos == ibuf.wpos > -len > -result > - > --- call > -c:call("echo", {1, 2, 3}, {buffer = ibuf}) > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > -result > -c:call("echo", {}, {buffer = ibuf}) > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > -result > -c:call("echo", nil, {buffer = ibuf}) > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > -result > - > --- call + skip_header > -c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > -result > -c:call("echo", {}, {buffer = ibuf, skip_header = true}) > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > -result > -c:call("echo", nil, {buffer = ibuf, skip_header = true}) > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > -result > - > --- eval > -c:eval("echo(...)", {1, 2, 3}, {buffer = ibuf}) > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > -result > -c:eval("echo(...)", {}, {buffer = ibuf}) > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > -result > -c:eval("echo(...)", nil, {buffer = ibuf}) > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > -result > - > --- eval + skip_header > -c:eval("echo(...)", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > -result > -c:eval("echo(...)", {}, {buffer = ibuf, skip_header = true}) > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > -result > -c:eval("echo(...)", nil, {buffer = ibuf, skip_header = true}) > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > -result > - > --- make several request into a buffer with skip_header, then read > --- results > -c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > -c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > -c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > -result > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > -result > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > -result > - > --- unsupported methods > -c.space.test:get({1}, { buffer = ibuf}) > -c.space.test.index.primary:min({}, { buffer = ibuf}) > -c.space.test.index.primary:max({}, { buffer = ibuf}) > -c.space.test.index.primary:count({}, { buffer = ibuf}) > -c.space.test.index.primary:get({1}, { buffer = ibuf}) > - > --- error handling > -rpos, wpos = ibuf.rpos, ibuf.wpos > -c.space.test:insert({1}, {buffer = ibuf}) > -ibuf.rpos == rpos, ibuf.wpos == wpos > - > -ibuf = nil > -c:close() > -space:drop() > -box.schema.user.revoke('guest', 'execute', 'universe') > - > --- gh-1904 net.box hangs in :close() if a fiber was cancelled > --- while blocked in :_wait_state() in :_request() > -options = {user = 'netbox', password = 'badpass', wait_connected = false, reconnect_after = 0.01} > -c = net:new(box.cfg.listen, options) > -f = fiber.create(function() c:call("") end) > -fiber.sleep(0.01) > -f:cancel(); c:close() > - > -box.schema.user.grant('guest', 'read', 'space', '_schema') > - > --- check for on_schema_reload callback > -test_run:cmd("setopt delimiter ';'") > -do > - local a = 0 > - function osr_cb() > - a = a + 1 > - end > - local con = net.new(box.cfg.listen, { > - wait_connected = false > - }) > - con:on_schema_reload(osr_cb) > - con:wait_connected() > - con.space._schema:select{} > - box.schema.space.create('misisipi') > - box.space.misisipi:drop() > - con.space._schema:select{} > - con:close() > - con = nil > - > - return a > -end; > -do > - local a = 0 > - function osr_cb() > - a = a + 1 > - end > - local con = net.new(box.cfg.listen, { > - wait_connected = true > - }) > - con:on_schema_reload(osr_cb) > - con.space._schema:select{} > - box.schema.space.create('misisipi') > - box.space.misisipi:drop() > - con.space._schema:select{} > - con:close() > - con = nil > - > - return a > -end; > -test_run:cmd("setopt delimiter ''"); > - > -box.schema.user.revoke('guest', 'read', 'space', '_schema') > - > --- Tarantool < 1.7.1 compatibility (gh-1533) > -c = net.new(box.cfg.listen) > -c:ping() > -c:close() > - > --- Test for connect_timeout > 0 in netbox connect > -test_run:cmd("setopt delimiter ';'"); > -need_stop = false; > -greeting = > -"Tarantool 1.7.3 (Lua console)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" .. > -"type 'help' for interactive help~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"; > -socket = require('socket'); > -srv = socket.tcp_server('localhost', 0, { > - handler = function(fd) > - local fiber = require('fiber') > - while not need_stop do > - fiber.sleep(0.01) > - end > - fd:write(greeting) > - end > -}); > -port = srv:name().port > --- we must get timeout > -nb = net.new('localhost:' .. port, { > - wait_connected = true, console = true, > - connect_timeout = 0.1 > -}); > -nb.error:find('timed out') ~= nil; > -need_stop = true > -nb:close(); > --- we must get peer closed > -nb = net.new('localhost:' .. port, { > - wait_connected = true, console = true, > - connect_timeout = 0.2 > -}); > -nb.error ~= "Timeout exceeded"; > -nb:close(); > -test_run:cmd("setopt delimiter ''"); > -srv:close() > - > -test_run:cmd("clear filter") > - > --- > --- gh-2402 net.box doesn't support space:format() > --- > - > -space = box.schema.space.create('test', {format={{name="id", type="unsigned"}}}) > -space ~= nil > -_ = box.space.test:create_index('primary') > -box.schema.user.grant('guest', 'read', 'space', 'test') > - > -c = net.connect(box.cfg.listen) > - > -c:ping() > -c.space.test ~= nil > - > -format = c.space.test:format() > - > -format[1] ~= nil > -format[1].name == "id" > -format[1].type == "unsigned" > - > -c.space.test:format({}) > - > --- > --- gh-4091: index unique flag is always false. > --- > -c.space.test.index.primary.unique > - > -c:close() > -space:drop() > - > --- > --- Check that it's possible to get connection object form net.box space > --- > - > -space = box.schema.space.create('test', {format={{name="id", type="unsigned"}}}) > -space ~= nil > -_ = box.space.test:create_index('primary') > -box.schema.user.grant('guest','read,write,execute','space', 'test') > - > -c = net.connect(box.cfg.listen) > - > -c:ping() > -c.space.test ~= nil > - > -c.space.test.connection == c > -box.schema.user.revoke('guest','read,write,execute','space', 'test') > -c:close() > - > --- > --- gh-2642: box.session.type() > --- > - > -box.schema.user.grant('guest','execute','universe') > -c = net.connect(box.cfg.listen) > -c:call("box.session.type") > -c:close() > -box.schema.user.revoke('guest', 'execute', 'universe') > - > - > --- > --- On_connect/disconnect triggers. > --- > -test_run:cmd('create server connecter with script = "box/proxy.lua"') > -test_run:cmd('start server connecter') > -test_run:cmd("set variable connect_to to 'connecter.listen'") > -conn = net.connect(connect_to, { reconnect_after = 0.1 }) > -conn.state > -connected_cnt = 0 > -disconnected_cnt = 0 > -function on_connect() connected_cnt = connected_cnt + 1 end > -function on_disconnect() disconnected_cnt = disconnected_cnt + 1 end > -conn:on_connect(on_connect) > -conn:on_disconnect(on_disconnect) > -test_run:cmd('stop server connecter') > -test_run:cmd('start server connecter') > -while conn.state ~= 'active' do fiber.sleep(0.1) end > -connected_cnt > -old_disconnected_cnt = disconnected_cnt > -disconnected_cnt >= 1 > -conn:close() > -disconnected_cnt == old_disconnected_cnt + 1 > -test_run:cmd('stop server connecter') > - > --- > --- gh-2401 update pseudo objects not replace them > --- > -space:drop() > -space = box.schema.space.create('test') > -box.schema.user.grant('guest', 'read', 'space', 'test') > -c = net.connect(box.cfg.listen) > -cspace = c.space.test > -space.index.test_index == nil > -cspace.index.test_index == nil > -_ = space:create_index("test_index", {parts={1, 'string'}}) > -c:reload_schema() > -space.index.test_index ~= nil > -cspace.index.test_index ~= nil > -c.space.test.index.test_index ~= nil > - > --- cleanup > - > -space:drop() > - > --- > --- gh-946: long polling CALL blocks input > --- > -box.schema.func.create('fast_call') > -box.schema.func.create('long_call') > -box.schema.func.create('wait_signal') > -box.schema.user.grant('guest', 'execute', 'function', 'fast_call') > -box.schema.user.grant('guest', 'execute', 'function', 'long_call') > -box.schema.user.grant('guest', 'execute', 'function', 'wait_signal') > -c = net.connect(box.cfg.listen) > - > -N = 100 > - > -pad = string.rep('x', 1024) > - > -long_call_cond = fiber.cond() > -long_call_channel = fiber.channel() > -fast_call_channel = fiber.channel() > - > -function fast_call(x) return x end > -function long_call(x) long_call_cond:wait() return x * 2 end > - > -test_run:cmd("setopt delimiter ';'") > -for i = 1, N do > - fiber.create(function() > - fast_call_channel:put(c:call('fast_call', {i, pad})) > - end) > - fiber.create(function() > - long_call_channel:put(c:call('long_call', {i, pad})) > - end) > -end > -test_run:cmd("setopt delimiter ''"); > - > -x = 0 > -for i = 1, N do x = x + fast_call_channel:get() end > -x > - > -long_call_cond:broadcast() > - > -x = 0 > -for i = 1, N do x = x + long_call_channel:get() end > -x > - > --- > --- Check that a connection does not leak if there is > --- a long CALL in progress when it is closed. > --- > -disconnected = false > -function on_disconnect() disconnected = true end > - > --- Make sure all dangling connections are collected so > --- that on_disconnect trigger isn't called spuriously. > -collectgarbage('collect') > -fiber.sleep(0) > - > -box.session.on_disconnect(on_disconnect) == on_disconnect > - > --- > --- gh-3859: on_disconnect is called only after all requests are > --- processed, but should be called right after disconnect and > --- only once. > --- > -ch1 = fiber.channel(1) > -ch2 = fiber.channel(1) > -function wait_signal() ch1:put(true) ch2:get() end > -_ = fiber.create(function() c:call('wait_signal') end) > -ch1:get() > - > -c:close() > -fiber.sleep(0) > -while disconnected == false do fiber.sleep(0.01) end > -disconnected -- true > -disconnected = nil > - > -ch2:put(true) > -fiber.sleep(0) > -disconnected -- nil, on_disconnect is not called second time. > - > -box.session.on_disconnect(nil, on_disconnect) > - > -box.schema.func.drop('long_call') > -box.schema.func.drop('fast_call') > -box.schema.func.drop('wait_signal') > --- > --- gh-2666: check that netbox.call is not repeated on schema > --- change. > --- > -box.schema.user.grant('guest', 'write', 'space', '_space') > -box.schema.user.grant('guest', 'write', 'space', '_schema') > -box.schema.user.grant('guest', 'create', 'universe') > -count = 0 > -function create_space(name) count = count + 1 box.schema.create_space(name) return true end > -box.schema.func.create('create_space') > -box.schema.user.grant('guest', 'execute', 'function', 'create_space') > -c = net.connect(box.cfg.listen) > -c:call('create_space', {'test1'}) > -count > -c:call('create_space', {'test2'}) > -count > -c:call('create_space', {'test3'}) > -count > -box.space.test1:drop() > -box.space.test2:drop() > -box.space.test3:drop() > -box.schema.user.revoke('guest', 'write', 'space', '_space') > -box.schema.user.revoke('guest', 'write', 'space', '_schema') > -box.schema.user.revoke('guest', 'create', 'universe') > -c:close() > -box.schema.func.drop('create_space') > - > --- > --- gh-3164: netbox connection is not closed and garbage collected > --- ever, if reconnect_after is set. > --- > -test_run:cmd('start server connecter') > -test_run:cmd("set variable connect_to to 'connecter.listen'") > -weak = setmetatable({}, {__mode = 'v'}) > --- Create strong and weak reference. Weak is valid until strong > --- is valid too. > -strong = net.connect(connect_to, {reconnect_after = 0.1}) > -weak.c = strong > -weak.c:ping() > -test_run:cmd('stop server connecter') > -test_run:cmd('cleanup server connecter') > --- Check the connection tries to reconnect at least two times. > --- 'Cannot assign requested address' is the crutch for running the > --- tests in a docker. This error emits instead of > --- 'Connection refused' inside a docker. > -old_log_level = box.cfg.log_level > -box.cfg{log_level = 6} > -log.info(string.rep('a', 1000)) > -test_run:cmd("setopt delimiter ';'") > -while test_run:grep_log('default', 'Network is unreachable', 1000) == nil and > - test_run:grep_log('default', 'Connection refused', 1000) == nil and > - test_run:grep_log('default', 'Cannot assign requested address', 1000) == nil do > - fiber.sleep(0.1) > -end; > -log.info(string.rep('a', 1000)); > -while test_run:grep_log('default', 'Network is unreachable', 1000) == nil and > - test_run:grep_log('default', 'Connection refused', 1000) == nil and > - test_run:grep_log('default', 'Cannot assign requested address', 1000) == nil do > - fiber.sleep(0.1) > -end; > -test_run:cmd("setopt delimiter ''"); > -box.cfg{log_level = old_log_level} > -collectgarbage('collect') > -strong.state > -strong == weak.c > --- Remove single strong reference. Now connection must be garbage > --- collected. > -strong = nil > -collectgarbage('collect') > --- Now weak.c is null, because it was weak reference, and the > --- connection is deleted by 'collect'. > -weak.c > - > --- > --- gh-2677: netbox supports console connections, that complicates > --- both console and netbox. It was necessary because before a > --- connection is established, a console does not known is it > --- binary or text protocol, and netbox could not be created from > --- existing socket. > --- > -box.schema.user.grant('guest', 'execute', 'universe') > -urilib = require('uri') > -uri = urilib.parse(tostring(box.cfg.listen)) > -s, greeting = net.establish_connection(uri.host, uri.service) > -c = net.wrap(s, greeting, uri.host, uri.service, {reconnect_after = 0.01}) > -c.state > - > -a = 100 > -function kek(args) return {1, 2, 3, args} end > -c:eval('a = 200') > -a > -c:call('kek', {300}) > -s = box.schema.create_space('test') > -box.schema.user.grant('guest', 'read,write', 'space', 'test') > -pk = s:create_index('pk') > -c:reload_schema() > -c.space.test:replace{1} > -c.space.test:get{1} > -c.space.test:delete{1} > --- > --- Break a connection to test reconnect_after. > --- > -_ = c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') > -while not c:is_connected() do fiber.sleep(0.01) end > -c:ping() > - > -s:drop() > -c:close() > - > --- > --- Test a case, when netbox can not connect first time, but > --- reconnect_after is set. > --- > -c = net.connect('localhost:33333', {reconnect_after = 0.1, wait_connected = false}) > -while c.state ~= 'error_reconnect' do fiber.sleep(0.01) end > -c:close() > - > -box.schema.user.revoke('guest', 'execute', 'universe') > -c.state > -c = nil > - > --- > --- gh-3256 net.box is_nullable and collation options output > --- > -space = box.schema.create_space('test') > -box.schema.user.grant('guest', 'read', 'space', 'test') > -_ = space:create_index('pk') > -_ = space:create_index('sk', {parts = {{2, 'unsigned', is_nullable = true}}}) > -c = net:connect(box.cfg.listen) > -c.space.test.index.sk.parts > -space:drop() > - > -space = box.schema.create_space('test') > -c:close() > -box.schema.user.grant('guest', 'read', 'space', 'test') > -c = net:connect(box.cfg.listen) > -box.internal.collation.create('test', 'ICU', 'ru-RU') > -collation_id = box.internal.collation.id_by_name('test') > -_ = space:create_index('sk', { type = 'tree', parts = {{1, 'str', collation = 'test'}}, unique = true }) > -c:reload_schema() > -parts = c.space.test.index.sk.parts > -#parts == 1 > -parts[1].fieldno == 1 > -parts[1].type == 'string' > -parts[1].is_nullable == false > -if _TARANTOOL >= '2.2.1' then \ > - return parts[1].collation == 'test' \ > -else \ > - return parts[1].collation_id == collation_id \ > -end > -c:close() > -box.internal.collation.drop('test') > -space:drop() > -c.state > -c = nil > - > --- > --- gh-3107: fiber-async netbox. > --- > -cond = nil > -box.schema.func.create('long_function') > -box.schema.user.grant('guest', 'execute', 'function', 'long_function') > -function long_function(...) cond = fiber.cond() cond:wait() return ... end > -function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end > -s = box.schema.create_space('test') > -pk = s:create_index('pk') > -s:replace{1} > -s:replace{2} > -s:replace{3} > -s:replace{4} > -c = net:connect(box.cfg.listen) > --- > --- Check long connections, multiple wait_result(). > --- > -future = c:call('long_function', {1, 2, 3}, {is_async = true}) > -future:result() > -future:is_ready() > -future:wait_result(0.01) -- Must fail on timeout. > -finalize_long() > -ret = future:wait_result(100) > -future:is_ready() > --- Any timeout is ok - response is received already. > -future:wait_result(0) > -future:wait_result(0.01) > -ret > - > -_, err = pcall(future.wait_result, future, true) > -err:find('Usage') ~= nil > -_, err = pcall(future.wait_result, future, '100') > -err:find('Usage') ~= nil > - > --- > --- Check infinity timeout. > --- > -ret = nil > -_ = fiber.create(function() ret = c:call('long_function', {1, 2, 3}, {is_async = true}):wait_result() end) > -finalize_long() > -while not ret do fiber.sleep(0.01) end > -ret > -c:close() > -box.schema.user.grant('guest', 'execute', 'universe') > -c = net:connect(box.cfg.listen) > -future = c:eval('return long_function(...)', {1, 2, 3}, {is_async = true}) > -future:result() > -future:wait_result(0.01) -- Must fail on timeout. > -finalize_long() > -future:wait_result(100) > - > -c:close() > --- > --- Check that is_async does not work on a closed connection. > --- > -c:call('any_func', {}, {is_async = true}) > - > -box.schema.user.revoke('guest', 'execute', 'universe') > -c = net:connect(box.cfg.listen) > - > --- > --- Ensure the request is garbage collected both if is not used and > --- if is. > --- > -gc_test = setmetatable({}, {__mode = 'v'}) > -gc_test.future = c:call('long_function', {1, 2, 3}, {is_async = true}) > -gc_test.future ~= nil > -collectgarbage() > -gc_test > -finalize_long() > - > -future = c:call('long_function', {1, 2, 3}, {is_async = true}) > -collectgarbage() > -future ~= nil > -finalize_long() > -future:wait_result(1000) > -collectgarbage() > -future ~= nil > -gc_test.future = future > -future = nil > -collectgarbage() > -gc_test > - > --- > --- Ensure a request can be finalized from non-caller fibers. > --- > -future = c:call('long_function', {1, 2, 3}, {is_async = true}) > -ret = {} > -count = 0 > -for i = 1, 10 do fiber.create(function() ret[i] = future:wait_result(1000) count = count + 1 end) end > -future:wait_result(0.01) -- Must fail on timeout. > -finalize_long() > -while count ~= 10 do fiber.sleep(0.1) end > -ret > - > --- > --- Test space methods. > --- > -c:close() > -box.schema.user.grant('guest', 'read,write', 'space', 'test') > -c = net:connect(box.cfg.listen) > -future = c.space.test:select({1}, {is_async = true}) > -ret = future:wait_result(100) > -ret > -type(ret[1]) > -future = c.space.test:insert({5}, {is_async = true}) > -future:wait_result(100) > -s:get{5} > -future = c.space.test:replace({6}, {is_async = true}) > -future:wait_result(100) > -s:get{6} > -future = c.space.test:delete({6}, {is_async = true}) > -future:wait_result(100) > -s:get{6} > -future = c.space.test:update({5}, {{'=', 2, 5}}, {is_async = true}) > -future:wait_result(100) > -s:get{5} > -future = c.space.test:upsert({5}, {{'=', 2, 6}}, {is_async = true}) > -future:wait_result(100) > -s:get{5} > -future = c.space.test:get({5}, {is_async = true}) > -future:wait_result(100) > - > --- > --- Test index methods. > --- > -future = c.space.test.index.pk:select({1}, {is_async = true}) > -future:wait_result(100) > -future = c.space.test.index.pk:get({2}, {is_async = true}) > -future:wait_result(100) > -future = c.space.test.index.pk:min({}, {is_async = true}) > -future:wait_result(100) > -future = c.space.test.index.pk:max({}, {is_async = true}) > -future:wait_result(100) > -c:close() > -box.schema.user.grant('guest', 'execute', 'universe') > -c = net:connect(box.cfg.listen) > -future = c.space.test.index.pk:count({3}, {is_async = true}) > -future:wait_result(100) > -c:close() > -box.schema.user.revoke('guest', 'execute', 'universe') > -c = net:connect(box.cfg.listen) > -future = c.space.test.index.pk:delete({3}, {is_async = true}) > -future:wait_result(100) > -s:get{3} > -future = c.space.test.index.pk:update({4}, {{'=', 2, 6}}, {is_async = true}) > -future:wait_result(100) > -s:get{4} > - > --- > --- Test async errors. > --- > -future = c.space.test:insert({1}, {is_async = true}) > -future:wait_result() > -future:result() > - > --- > --- Test discard. > --- > -future = c:call('long_function', {1, 2, 3}, {is_async = true}) > -future:discard() > -finalize_long() > -future:result() > -future:wait_result(100) > - > --- > --- Test closed connection. > --- > -future = c:call('long_function', {1, 2, 3}, {is_async = true}) > -finalize_long() > -future:wait_result(100) > -future2 = c:call('long_function', {1, 2, 3}, {is_async = true}) > -c:close() > -future2:wait_result(100) > -future2:result() > -future2:discard() > --- Already successful result must be available. > -future:wait_result(100) > -future:result() > -future:is_ready() > -finalize_long() > - > --- > --- Test reconnect. > --- > -c = net:connect(box.cfg.listen, {reconnect_after = 0.01}) > -future = c:call('long_function', {1, 2, 3}, {is_async = true}) > -_ = c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') > -while not c:is_connected() do fiber.sleep(0.01) end > -finalize_long() > -future:wait_result(100) > -future:result() > -future = c:call('long_function', {1, 2, 3}, {is_async = true}) > -finalize_long() > -future:wait_result(100) > - > --- > --- Test raw response getting. > --- > -ibuf = require('buffer').ibuf() > -future = c:call('long_function', {1, 2, 3}, {is_async = true, buffer = ibuf}) > -finalize_long() > -future:wait_result(100) > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > -result > - > -box.schema.func.drop('long_function') > - > --- > --- Test async schema version change. > --- > -function change_schema(i) local tmp = box.schema.create_space('test'..i) return 'ok' end > -box.schema.func.create('change_schema') > -box.schema.user.grant('guest', 'execute', 'function', 'change_schema') > -box.schema.user.grant('guest', 'write', 'space', '_schema') > -box.schema.user.grant('guest', 'read,write', 'space', '_space') > -box.schema.user.grant('guest', 'create', 'space') > -future1 = c:call('change_schema', {'1'}, {is_async = true}) > -future2 = c:call('change_schema', {'2'}, {is_async = true}) > -future3 = c:call('change_schema', {'3'}, {is_async = true}) > -future1:wait_result() > -future2:wait_result() > -future3:wait_result() > - > -c:close() > -s:drop() > -box.space.test1:drop() > -box.space.test2:drop() > -box.space.test3:drop() > -box.schema.func.drop('change_schema') > - > --- > --- gh-2978: field names for tuples received from netbox. > --- > -_ = box.schema.create_space("named", {format = {{name = "id"}, {name="abc"}}}) > -_ = box.space.named:create_index('id', {parts = {{1, 'unsigned'}}}) > -box.space.named:insert({1, 1}) > -box.schema.user.grant('guest', 'read, write, execute', 'space') > -cn = net.connect(box.cfg.listen) > - > -s = cn.space.named > -s:get{1}.id > -s:get{1}:tomap() > -s:insert{2,3}:tomap() > -s:replace{2,14}:tomap() > -s:update(1, {{'+', 2, 10}}):tomap() > -s:select()[1]:tomap() > -s:delete({2}):tomap() > - > --- Check that formats changes after reload. > -box.space.named:format({{name = "id2"}, {name="abc2"}}) > -s:select()[1]:tomap() > -cn:reload_schema() > -s:select()[1]:tomap() > - > -cn:close() > -box.space.named:drop() > -box.schema.user.revoke('guest', 'read, write, execute', 'space') > - > --- > --- gh-3400: long-poll input discard must not touch event loop of > --- a closed connection. > --- > -function long() fiber.yield() return 100 end > -c = net.connect(box.cfg.listen) > -c:ping() > --- Create batch of two requests. First request is sent to TX > --- thread, second one terminates connection. The preceeding > --- request discards input, and this operation must not trigger > --- new attempts to read any data - the connection is closed > --- already. > --- > -f = fiber.create(c._transport.perform_request, nil, nil, false, 'call_17', nil, nil, nil, 'long', {}) c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') > -while f:status() ~= 'dead' do fiber.sleep(0.01) end > -c:close() > - > --- > --- gh-3464: iproto hangs in 100% CPU when too big packet size > --- is received due to size_t overflow. > --- > -c = net:connect(box.cfg.listen) > -data = msgpack.encode(18400000000000000000)..'aaaaaaa' > -c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, data) > -c:close() > -test_run:grep_log('default', 'too big packet size in the header') ~= nil > - > - > --- > --- gh-3629: netbox leaks when a connection is closed deliberately > --- and it has non-finished requests. > --- > -ready = false > -ok = nil > -err = nil > -c = net:connect(box.cfg.listen) > -function do_long() while not ready do fiber.sleep(0.01) end end > -box.schema.func.create('do_long') > -box.schema.user.grant('guest', 'execute', 'function', 'do_long') > -f = fiber.create(function() ok, err = pcall(c.call, c, 'do_long') end) > -while f:status() ~= 'suspended' do fiber.sleep(0.01) end > -c:close() > -ready = true > -while not err do fiber.sleep(0.01) end > -ok, err > - > --- > --- gh-3856: wait_connected = false is ignored. > --- > -c = net.connect('8.8.8.8:123456', {wait_connected = false}) > -c > -c:close() > - > -box.schema.func.drop('do_long') > -box.schema.user.revoke('guest', 'write', 'space', '_schema') > -box.schema.user.revoke('guest', 'read,write', 'space', '_space') > -box.schema.user.revoke('guest', 'create', 'space') > - > --- > --- gh-3958 updating box.cfg.readahead doesn't affect existing connections. > --- > -readahead = box.cfg.readahead > - > -box.cfg{readahead = 128} > - > -s = box.schema.space.create("test") > -_ = s:create_index("pk") > -box.schema.user.grant("guest", "read,write", "space", "test") > - > --- connection is created with small readahead value, > --- make sure it is updated if box.cfg.readahead is changed. > -c = net.connect(box.cfg.listen) > - > -box.cfg{readahead = 100 * 1024} > - > -box.error.injection.set("ERRINJ_WAL_DELAY", true) > -pad = string.rep('x', 8192) > -for i = 1, 5 do c.space.test:replace({i, pad}, {is_async = true}) end > -box.error.injection.set("ERRINJ_WAL_DELAY", false) > - > -test_run:wait_log('default', 'readahead limit is reached', 1024, 0.1) > - > -s:drop() > -box.cfg{readahead = readahead} > - > --- > --- related to gh-4040: log corrupted rows > --- > -log_level = box.cfg.log_level > -box.cfg{log_level=6} > -sock = socket.tcp_connect(LISTEN.host, LISTEN.service) > -sock:read(9) > --- we need to have a packet with correctly encoded length, > --- so that it bypasses iproto length check, but cannot be > --- decoded in xrow_header_decode > --- 0x3C = 60, sha1 digest is 20 bytes long > -data = string.fromhex('3C'..string.rep(require('digest').sha1_hex('bcde'), 3)) > -sock:write(data) > -sock:close() > - > -test_run:wait_log('default', 'Got a corrupted row.*', nil, 10) > -test_run:wait_log('default', '00000000:.*', nil, 10) > -test_run:wait_log('default', '00000010:.*', nil, 10) > -test_run:wait_log('default', '00000020:.*', nil, 10) > -test_run:wait_log('default', '00000030:.*', nil, 10) > --- we expect nothing below, so don't wait > -test_run:grep_log('default', '00000040:.*') > - > -box.cfg{log_level=log_level} > diff --git a/test/box/net.box_bad_argument_gh-594.result b/test/box/net.box_bad_argument_gh-594.result > new file mode 100644 > index 000000000..339886eaa > --- /dev/null > +++ b/test/box/net.box_bad_argument_gh-594.result > @@ -0,0 +1,38 @@ > +remote = require 'net.box' > +--- > +... > +fiber = require 'fiber' > +--- > +... > +test_run = require('test_run').new() > +--- > +... > +-- #594: bad argument #1 to 'setmetatable' (table expected, got number) > +box.schema.func.create('dostring') > +--- > +... > +box.schema.user.grant('guest', 'execute', 'function', 'dostring') > +--- > +... > +test_run:cmd("setopt delimiter ';'") > +--- > +- true > +... > +function gh594() > + local cn = remote.connect(box.cfg.listen) > + local ping = fiber.create(function() cn:ping() end) > + cn:call('dostring', {'return 2 + 2'}) > + cn:close() > +end; > +--- > +... > +test_run:cmd("setopt delimiter ''"); > +--- > +- true > +... > +gh594() > +--- > +... > +box.schema.func.drop('dostring') > +--- > +... > diff --git a/test/box/net.box_bad_argument_gh-594.test.lua b/test/box/net.box_bad_argument_gh-594.test.lua > new file mode 100644 > index 000000000..65265cbb5 > --- /dev/null > +++ b/test/box/net.box_bad_argument_gh-594.test.lua > @@ -0,0 +1,17 @@ > +remote = require 'net.box' > +fiber = require 'fiber' > +test_run = require('test_run').new() > + > +-- #594: bad argument #1 to 'setmetatable' (table expected, got number) > +box.schema.func.create('dostring') > +box.schema.user.grant('guest', 'execute', 'function', 'dostring') > +test_run:cmd("setopt delimiter ';'") > +function gh594() > + local cn = remote.connect(box.cfg.listen) > + local ping = fiber.create(function() cn:ping() end) > + cn:call('dostring', {'return 2 + 2'}) > + cn:close() > +end; > +test_run:cmd("setopt delimiter ''"); > +gh594() > +box.schema.func.drop('dostring') > diff --git a/test/box/net.box_call_blocks_gh-946.result b/test/box/net.box_call_blocks_gh-946.result > new file mode 100644 > index 000000000..40afec416 > --- /dev/null > +++ b/test/box/net.box_call_blocks_gh-946.result > @@ -0,0 +1,124 @@ > +fiber = require 'fiber' > +--- > +... > +test_run = require('test_run').new() > +--- > +... > +--space = box.schema.space.create('net_box_test_space') > +--index = space:create_index('primary', { type = 'tree' }) > +net = require('net.box') > +--- > +... > +socket = require('socket'); > +--- > +... > +test_run:cmd('create server connecter with script = "box/proxy.lua"') > +--- > +- true > +... > +-- > +-- gh-946: long polling CALL blocks input > +-- > +box.schema.func.create('fast_call') > +--- > +... > +box.schema.func.create('long_call') > +--- > +... > +box.schema.func.create('wait_signal') > +--- > +... > +box.schema.user.grant('guest', 'execute', 'function', 'fast_call') > +--- > +... > +box.schema.user.grant('guest', 'execute', 'function', 'long_call') > +--- > +... > +box.schema.user.grant('guest', 'execute', 'function', 'wait_signal') > +--- > +... > +c = net.connect(box.cfg.listen) > +--- > +... > +N = 100 > +--- > +... > +pad = string.rep('x', 1024) > +--- > +... > +long_call_cond = fiber.cond() > +--- > +... > +long_call_channel = fiber.channel() > +--- > +... > +fast_call_channel = fiber.channel() > +--- > +... > +function fast_call(x) return x end > +--- > +... > +function long_call(x) long_call_cond:wait() return x * 2 end > +--- > +... > +test_run:cmd("setopt delimiter ';'") > +--- > +- true > +... > +for i = 1, N do > + fiber.create(function() > + fast_call_channel:put(c:call('fast_call', {i, pad})) > + end) > + fiber.create(function() > + long_call_channel:put(c:call('long_call', {i, pad})) > + end) > +end > +test_run:cmd("setopt delimiter ''"); > +--- > +... > +x = 0 > +--- > +... > +for i = 1, N do x = x + fast_call_channel:get() end > +--- > +... > +x > +--- > +- 5050 > +... > +long_call_cond:broadcast() > +--- > +... > +x = 0 > +--- > +... > +for i = 1, N do x = x + long_call_channel:get() end > +--- > +... > +x > +--- > +- 10100 > +... > +-- > +-- Check that a connection does not leak if there is > +-- a long CALL in progress when it is closed. > +-- > +disconnected = false > +--- > +... > +function on_disconnect() disconnected = true end > +--- > +... > +-- Make sure all dangling connections are collected so > +-- that on_disconnect trigger isn't called spuriously. > +collectgarbage('collect') > +--- > +- 0 > +... > +fiber.sleep(0) > +--- > +... > +box.session.on_disconnect(on_disconnect) == on_disconnect > +--- > +- true > +... > diff --git a/test/box/net.box_call_blocks_gh-946.test.lua b/test/box/net.box_call_blocks_gh-946.test.lua > new file mode 100644 > index 000000000..f3cd3f305 > --- /dev/null > +++ b/test/box/net.box_call_blocks_gh-946.test.lua > @@ -0,0 +1,67 @@ > +fiber = require 'fiber' > +test_run = require('test_run').new() > + > +--space = box.schema.space.create('net_box_test_space') > +--index = space:create_index('primary', { type = 'tree' }) > + > +net = require('net.box') > +socket = require('socket'); > + > +test_run:cmd('create server connecter with script = "box/proxy.lua"') > + > +-- > +-- gh-946: long polling CALL blocks input > +-- > +box.schema.func.create('fast_call') > +box.schema.func.create('long_call') > +box.schema.func.create('wait_signal') > +box.schema.user.grant('guest', 'execute', 'function', 'fast_call') > +box.schema.user.grant('guest', 'execute', 'function', 'long_call') > +box.schema.user.grant('guest', 'execute', 'function', 'wait_signal') > +c = net.connect(box.cfg.listen) > + > +N = 100 > + > +pad = string.rep('x', 1024) > + > +long_call_cond = fiber.cond() > +long_call_channel = fiber.channel() > +fast_call_channel = fiber.channel() > + > +function fast_call(x) return x end > +function long_call(x) long_call_cond:wait() return x * 2 end > + > +test_run:cmd("setopt delimiter ';'") > +for i = 1, N do > + fiber.create(function() > + fast_call_channel:put(c:call('fast_call', {i, pad})) > + end) > + fiber.create(function() > + long_call_channel:put(c:call('long_call', {i, pad})) > + end) > +end > +test_run:cmd("setopt delimiter ''"); > + > +x = 0 > +for i = 1, N do x = x + fast_call_channel:get() end > +x > + > +long_call_cond:broadcast() > + > +x = 0 > +for i = 1, N do x = x + long_call_channel:get() end > +x > + > +-- > +-- Check that a connection does not leak if there is > +-- a long CALL in progress when it is closed. > +-- > +disconnected = false > +function on_disconnect() disconnected = true end > + > +-- Make sure all dangling connections are collected so > +-- that on_disconnect trigger isn't called spuriously. > +collectgarbage('collect') > +fiber.sleep(0) > + > +box.session.on_disconnect(on_disconnect) == on_disconnect > diff --git a/test/box/net.box_collectgarbage_gh-3107.result b/test/box/net.box_collectgarbage_gh-3107.result > new file mode 100644 > index 000000000..240a472de > --- /dev/null > +++ b/test/box/net.box_collectgarbage_gh-3107.result > @@ -0,0 +1,120 @@ > +fiber = require 'fiber' > +--- > +... > +net = require('net.box') > +--- > +... > +-- > +-- gh-3107: fiber-async netbox. > +-- > +cond = nil > +--- > +... > +box.schema.func.create('long_function') > +--- > +... > +box.schema.user.grant('guest', 'execute', 'function', 'long_function') > +--- > +... > +function long_function(...) cond = fiber.cond() cond:wait() return ... end > +--- > +... > +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end > +--- > +... > +s = box.schema.create_space('test') > +--- > +... > +pk = s:create_index('pk') > +--- > +... > +s:replace{1} > +--- > +- [1] > +... > +s:replace{2} > +--- > +- [2] > +... > +s:replace{3} > +--- > +- [3] > +... > +s:replace{4} > +--- > +- [4] > +... > +c = net:connect(box.cfg.listen) > +--- > +... > +-- > +-- Ensure the request is garbage collected both if is not used and > +-- if is. > +-- > +gc_test = setmetatable({}, {__mode = 'v'}) > +--- > +... > +gc_test.future = c:call('long_function', {1, 2, 3}, {is_async = true}) > +--- > +... > +gc_test.future ~= nil > +--- > +- true > +... > +collectgarbage() > +--- > +- 0 > +... > +gc_test > +--- > +- [] > +... > +finalize_long() > +--- > +... > +future = c:call('long_function', {1, 2, 3}, {is_async = true}) > +--- > +... > +collectgarbage() > +--- > +- 0 > +... > +future ~= nil > +--- > +- true > +... > +finalize_long() > +--- > +... > +future:wait_result(1000) > +--- > +- [1, 2, 3] > +... > +collectgarbage() > +--- > +- 0 > +... > +future ~= nil > +--- > +- true > +... > +gc_test.future = future > +--- > +... > +future = nil > +--- > +... > +collectgarbage() > +--- > +- 0 > +... > +gc_test > +--- > +- [] > +... > +c:close() > +--- > +... > +s:drop() > +--- > +... > diff --git a/test/box/net.box_collectgarbage_gh-3107.test.lua b/test/box/net.box_collectgarbage_gh-3107.test.lua > new file mode 100644 > index 000000000..cfe333757 > --- /dev/null > +++ b/test/box/net.box_collectgarbage_gh-3107.test.lua > @@ -0,0 +1,44 @@ > +fiber = require 'fiber' > +net = require('net.box') > + > +-- > +-- gh-3107: fiber-async netbox. > +-- > +cond = nil > +box.schema.func.create('long_function') > +box.schema.user.grant('guest', 'execute', 'function', 'long_function') > +function long_function(...) cond = fiber.cond() cond:wait() return ... end > +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end > +s = box.schema.create_space('test') > +pk = s:create_index('pk') > +s:replace{1} > +s:replace{2} > +s:replace{3} > +s:replace{4} > +c = net:connect(box.cfg.listen) > + > +-- > +-- Ensure the request is garbage collected both if is not used and > +-- if is. > +-- > +gc_test = setmetatable({}, {__mode = 'v'}) > +gc_test.future = c:call('long_function', {1, 2, 3}, {is_async = true}) > +gc_test.future ~= nil > +collectgarbage() > +gc_test > +finalize_long() > + > +future = c:call('long_function', {1, 2, 3}, {is_async = true}) > +collectgarbage() > +future ~= nil > +finalize_long() > +future:wait_result(1000) > +collectgarbage() > +future ~= nil > +gc_test.future = future > +future = nil > +collectgarbage() > +gc_test > + > +c:close() > +s:drop() > diff --git a/test/box/net.box_connect_triggers.result b/test/box/net.box_connect_triggers.result > new file mode 100644 > index 000000000..c5b1ef6db > --- /dev/null > +++ b/test/box/net.box_connect_triggers.result > @@ -0,0 +1,82 @@ > +fiber = require 'fiber' > +--- > +... > +test_run = require('test_run').new() > +--- > +... > +net = require('net.box') > +--- > +... > +-- > +-- On_connect/disconnect triggers. > +-- > +test_run:cmd('create server connecter with script = "box/proxy.lua"') > +--- > +- true > +... > +test_run:cmd('start server connecter') > +--- > +- true > +... > +test_run:cmd("set variable connect_to to 'connecter.listen'") > +--- > +- true > +... > +conn = net.connect(connect_to, { reconnect_after = 0.1 }) > +--- > +... > +conn.state > +--- > +- active > +... > +connected_cnt = 0 > +--- > +... > +disconnected_cnt = 0 > +--- > +... > +function on_connect() connected_cnt = connected_cnt + 1 end > +--- > +... > +function on_disconnect() disconnected_cnt = disconnected_cnt + 1 end > +--- > +... > +conn:on_connect(on_connect) > +--- > +... > +conn:on_disconnect(on_disconnect) > +--- > +... > +test_run:cmd('stop server connecter') > +--- > +- true > +... > +test_run:cmd('start server connecter') > +--- > +- true > +... > +while conn.state ~= 'active' do fiber.sleep(0.1) end > +--- > +... > +connected_cnt > +--- > +- 1 > +... > +old_disconnected_cnt = disconnected_cnt > +--- > +... > +disconnected_cnt >= 1 > +--- > +- true > +... > +conn:close() > +--- > +... > +disconnected_cnt == old_disconnected_cnt + 1 > +--- > +- true > +... > +test_run:cmd('stop server connecter') > +--- > +- true > +... > diff --git a/test/box/net.box_connect_triggers.test.lua b/test/box/net.box_connect_triggers.test.lua > new file mode 100644 > index 000000000..86794035e > --- /dev/null > +++ b/test/box/net.box_connect_triggers.test.lua > @@ -0,0 +1,27 @@ > +fiber = require 'fiber' > +test_run = require('test_run').new() > +net = require('net.box') > + > +-- > +-- On_connect/disconnect triggers. > +-- > +test_run:cmd('create server connecter with script = "box/proxy.lua"') > +test_run:cmd('start server connecter') > +test_run:cmd("set variable connect_to to 'connecter.listen'") > +conn = net.connect(connect_to, { reconnect_after = 0.1 }) > +conn.state > +connected_cnt = 0 > +disconnected_cnt = 0 > +function on_connect() connected_cnt = connected_cnt + 1 end > +function on_disconnect() disconnected_cnt = disconnected_cnt + 1 end > +conn:on_connect(on_connect) > +conn:on_disconnect(on_disconnect) > +test_run:cmd('stop server connecter') > +test_run:cmd('start server connecter') > +while conn.state ~= 'active' do fiber.sleep(0.1) end > +connected_cnt > +old_disconnected_cnt = disconnected_cnt > +disconnected_cnt >= 1 > +conn:close() > +disconnected_cnt == old_disconnected_cnt + 1 > +test_run:cmd('stop server connecter') > diff --git a/test/box/net.box_console_connections_gh-2677.result b/test/box/net.box_console_connections_gh-2677.result > new file mode 100644 > index 000000000..c9116e5d4 > --- /dev/null > +++ b/test/box/net.box_console_connections_gh-2677.result > @@ -0,0 +1,95 @@ > +fiber = require 'fiber' > +--- > +... > +net = require('net.box') > +--- > +... > +-- > +-- gh-2677: netbox supports console connections, that complicates > +-- both console and netbox. It was necessary because before a > +-- connection is established, a console does not known is it > +-- binary or text protocol, and netbox could not be created from > +-- existing socket. > +-- > +box.schema.user.grant('guest', 'execute', 'universe') > +--- > +... > +urilib = require('uri') > +--- > +... > +uri = urilib.parse(tostring(box.cfg.listen)) > +--- > +... > +s, greeting = net.establish_connection(uri.host, uri.service) > +--- > +... > +c = net.wrap(s, greeting, uri.host, uri.service, {reconnect_after = 0.01}) > +--- > +... > +c.state > +--- > +- active > +... > +a = 100 > +--- > +... > +function kek(args) return {1, 2, 3, args} end > +--- > +... > +c:eval('a = 200') > +--- > +... > +a > +--- > +- 200 > +... > +c:call('kek', {300}) > +--- > +- [1, 2, 3, 300] > +... > +s = box.schema.create_space('test') > +--- > +... > +box.schema.user.grant('guest', 'read,write', 'space', 'test') > +--- > +... > +pk = s:create_index('pk') > +--- > +... > +c:reload_schema() > +--- > +... > +c.space.test:replace{1} > +--- > +- [1] > +... > +c.space.test:get{1} > +--- > +- [1] > +... > +c.space.test:delete{1} > +--- > +- [1] > +... > +-- > +-- Break a connection to test reconnect_after. > +-- > +_ = c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') > +--- > +... > +while not c:is_connected() do fiber.sleep(0.01) end > +--- > +... > +c:ping() > +--- > +- true > +... > +s:drop() > +--- > +... > +c:close() > +--- > +... > +box.schema.user.revoke('guest', 'execute', 'universe') > +--- > +... > diff --git a/test/box/net.box_console_connections_gh-2677.test.lua b/test/box/net.box_console_connections_gh-2677.test.lua > new file mode 100644 > index 000000000..c6c9ea846 > --- /dev/null > +++ b/test/box/net.box_console_connections_gh-2677.test.lua > @@ -0,0 +1,39 @@ > +fiber = require 'fiber' > +net = require('net.box') > + > +-- > +-- gh-2677: netbox supports console connections, that complicates > +-- both console and netbox. It was necessary because before a > +-- connection is established, a console does not known is it > +-- binary or text protocol, and netbox could not be created from > +-- existing socket. > +-- > +box.schema.user.grant('guest', 'execute', 'universe') > +urilib = require('uri') > +uri = urilib.parse(tostring(box.cfg.listen)) > +s, greeting = net.establish_connection(uri.host, uri.service) > +c = net.wrap(s, greeting, uri.host, uri.service, {reconnect_after = 0.01}) > +c.state > + > +a = 100 > +function kek(args) return {1, 2, 3, args} end > +c:eval('a = 200') > +a > +c:call('kek', {300}) > +s = box.schema.create_space('test') > +box.schema.user.grant('guest', 'read,write', 'space', 'test') > +pk = s:create_index('pk') > +c:reload_schema() > +c.space.test:replace{1} > +c.space.test:get{1} > +c.space.test:delete{1} > +-- > +-- Break a connection to test reconnect_after. > +-- > +_ = c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') > +while not c:is_connected() do fiber.sleep(0.01) end > +c:ping() > + > +s:drop() > +c:close() > +box.schema.user.revoke('guest', 'execute', 'universe') > diff --git a/test/box/net.box_count_inconsistent_gh-3262.result b/test/box/net.box_count_inconsistent_gh-3262.result > new file mode 100644 > index 000000000..c77677625 > --- /dev/null > +++ b/test/box/net.box_count_inconsistent_gh-3262.result > @@ -0,0 +1,488 @@ > +remote = require 'net.box' > +--- > +... > +fiber = require 'fiber' > +--- > +... > +test_run = require('test_run').new() > +--- > +... > +LISTEN = require('uri').parse(box.cfg.listen) > +--- > +... > +space = box.schema.space.create('net_box_test_space') > +--- > +... > +index = space:create_index('primary', { type = 'tree' }) > +--- > +... > +box.schema.user.grant('guest', 'read,write', 'space', 'net_box_test_space') > +--- > +... > +box.schema.user.grant('guest', 'execute', 'universe') > +--- > +... > +cn = remote.connect(box.cfg.listen) > +--- > +... > +cn.space[space.id] ~= nil > +--- > +- true > +... > +cn.space.net_box_test_space ~= nil > +--- > +- true > +... > +cn.space.net_box_test_space ~= nil > +--- > +- true > +... > +cn.space.net_box_test_space.index ~= nil > +--- > +- true > +... > +cn.space.net_box_test_space.index.primary ~= nil > +--- > +- true > +... > +cn.space.net_box_test_space.index[space.index.primary.id] ~= nil > +--- > +- true > +... > +cn.space.net_box_test_space:insert{234, 1,2,3} > +--- > +- [234, 1, 2, 3] > +... > +cn.space.net_box_test_space:replace{354, 1,2,4} > +--- > +- [354, 1, 2, 4] > +... > +cn.space.net_box_test_space.index.primary:min(354) > +--- > +- [354, 1, 2, 4] > +... > +cn.space.net_box_test_space.index.primary:max(234) > +--- > +- [234, 1, 2, 3] > +... > +cn.space.net_box_test_space.index.primary:count(354) > +--- > +- 1 > +... > +box.schema.user.create('netbox', { password = 'test' }) > +--- > +... > +box.schema.user.grant('netbox', 'read,write', 'space', 'net_box_test_space') > +--- > +... > +box.schema.user.grant('netbox', 'execute', 'universe') > +--- > +... > +cn = remote.connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = 'test' }) > +--- > +... > +cn.state > +--- > +- active > +... > +cn.error > +--- > +- null > +... > +cn:ping() > +--- > +- true > +... > +function ret_after(to) fiber.sleep(to) return {{to}} end > +--- > +... > +cn:ping({timeout = 1.00}) > +--- > +- true > +... > +cn:ping({timeout = 1e-9}) > +--- > +- false > +... > +cn:ping() > +--- > +- true > +... > +remote_space = cn.space.net_box_test_space > +--- > +... > +remote_pk = remote_space.index.primary > +--- > +... > +remote_space:insert({0}, { timeout = 1.00 }) > +--- > +- [0] > +... > +remote_space:insert({1}, { timeout = 1e-9 }) > +--- > +- error: Timeout exceeded > +... > +remote_space:insert({2}) > +--- > +- [2] > +... > +remote_space:replace({0}, { timeout = 1e-9 }) > +--- > +- error: Timeout exceeded > +... > +remote_space:replace({1}) > +--- > +- [1] > +... > +remote_space:replace({2}, { timeout = 1.00 }) > +--- > +- [2] > +... > +remote_space:upsert({3}, {}, { timeout = 1e-9 }) > +--- > +- error: Timeout exceeded > +... > +remote_space:upsert({4}, {}) > +--- > +... > +remote_space:upsert({5}, {}, { timeout = 1.00 }) > +--- > +... > +remote_space:upsert({3}, {}) > +--- > +... > +remote_space:update({3}, {}, { timeout = 1e-9 }) > +--- > +- error: Timeout exceeded > +... > +remote_space:update({4}, {}) > +--- > +- [4] > +... > +remote_space:update({5}, {}, { timeout = 1.00 }) > +--- > +- [5] > +... > +remote_space:update({3}, {}) > +--- > +- [3] > +... > +remote_pk:update({5}, {}, { timeout = 1e-9 }) > +--- > +- error: Timeout exceeded > +... > +remote_pk:update({4}, {}) > +--- > +- [4] > +... > +remote_pk:update({3}, {}, { timeout = 1.00 }) > +--- > +- [3] > +... > +remote_pk:update({5}, {}) > +--- > +- [5] > +... > +remote_space:get({0}) > +--- > +- [0] > +... > +remote_space:get({1}, { timeout = 1.00 }) > +--- > +- [1] > +... > +remote_space:get({2}, { timeout = 1e-9 }) > +--- > +- error: Timeout exceeded > +... > +remote_pk:get({3}, { timeout = 1e-9 }) > +--- > +- error: Timeout exceeded > +... > +remote_pk:get({4}) > +--- > +- [4] > +... > +remote_pk:get({5}, { timeout = 1.00 }) > +--- > +- [5] > +... > +remote_space:select({2}, { timeout = 1e-9 }) > +--- > +- error: Timeout exceeded > +... > +remote_space:select({2}, { timeout = 1.00 }) > +--- > +- - [2] > +... > +remote_space:select({2}) > +--- > +- - [2] > +... > +remote_pk:select({2}, { timeout = 1.00 }) > +--- > +- - [2] > +... > +remote_pk:select({2}, { timeout = 1e-9 }) > +--- > +- error: Timeout exceeded > +... > +remote_pk:select({2}) > +--- > +- - [2] > +... > +remote_space:select({5}, { timeout = 1.00, iterator = 'LE', limit = 5 }) > +--- > +- - [5] > + - [4] > + - [3] > + - [2] > + - [1] > +... > +remote_space:select({5}, { iterator = 'LE', limit = 5}) > +--- > +- - [5] > + - [4] > + - [3] > + - [2] > + - [1] > +... > +remote_space:select({5}, { timeout = 1e-9, iterator = 'LE', limit = 5 }) > +--- > +- error: Timeout exceeded > +... > +remote_pk:select({2}, { timeout = 1.00, iterator = 'LE', limit = 5 }) > +--- > +- - [2] > + - [1] > + - [0] > +... > +remote_pk:select({2}, { iterator = 'LE', limit = 5}) > +--- > +- - [2] > + - [1] > + - [0] > +... > +remote_pk:select({2}, { timeout = 1e-9, iterator = 'LE', limit = 5 }) > +--- > +- error: Timeout exceeded > +... > +remote_pk:count({2}, { timeout = 1.00}) > +--- > +- 1 > +... > +remote_pk:count({2}, { timeout = 1e-9}) > +--- > +- error: Timeout exceeded > +... > +remote_pk:count({2}) > +--- > +- 1 > +... > +remote_pk:count({2}, { timeout = 1.00, iterator = 'LE' }) > +--- > +- 3 > +... > +remote_pk:count({2}, { iterator = 'LE'}) > +--- > +- 3 > +... > +remote_pk:count({2}, { timeout = 1e-9, iterator = 'LE' }) > +--- > +- error: Timeout exceeded > +... > +remote_pk:min(nil, { timeout = 1.00 }) > +--- > +- [0] > +... > +remote_pk:min(nil, { timeout = 1e-9 }) > +--- > +- error: Timeout exceeded > +... > +remote_pk:min(nil) > +--- > +- [0] > +... > +remote_pk:min({0}, { timeout = 1e-9 }) > +--- > +- error: Timeout exceeded > +... > +remote_pk:min({1}) > +--- > +- [1] > +... > +remote_pk:min({2}, { timeout = 1.00 }) > +--- > +- [2] > +... > +remote_pk:max(nil) > +--- > +- [354, 1, 2, 4] > +... > +remote_pk:max(nil, { timeout = 1e-9 }) > +--- > +- error: Timeout exceeded > +... > +remote_pk:max(nil, { timeout = 1.00 }) > +--- > +- [354, 1, 2, 4] > +... > +remote_pk:max({0}, { timeout = 1.00 }) > +--- > +- [0] > +... > +remote_pk:max({1}, { timeout = 1e-9 }) > +--- > +- error: Timeout exceeded > +... > +remote_pk:max({2}) > +--- > +- [2] > +... > +-- > +-- gh-3262: index:count() inconsistent results > +-- > +test_run:cmd("setopt delimiter ';'") > +--- > +- true > +... > +function do_count_test(min, it) > + local r1 = remote_pk:count(min, {iterator = it} ) > + local r2 = box.space.net_box_test_space.index.primary:count(min, {iterator = it} ) > + local r3 = remote.self.space.net_box_test_space.index.primary:count(min, {iterator = it} ) > + return r1 == r2 and r2 == r3 > +end; > +--- > +... > +data = remote_pk:select(); > +--- > +... > +for _, v in pairs(data) do > + local itrs = {'GE', 'GT', 'LE', 'LT' } > + for _, it in pairs(itrs) do > + assert(do_count_test(v[0], it) == true) > + end > +end; > +--- > +... > +test_run:cmd("setopt delimiter ''"); > +--- > +- true > +... > +_ = remote_space:delete({0}, { timeout = 1e-9 }) > +--- > +- error: Timeout exceeded > +... > +_ = remote_pk:delete({0}, { timeout = 1.00 }) > +--- > +... > +_ = remote_space:delete({1}, { timeout = 1.00 }) > +--- > +... > +_ = remote_pk:delete({1}, { timeout = 1e-9 }) > +--- > +- error: Timeout exceeded > +... > +_ = remote_space:delete({2}, { timeout = 1e-9 }) > +--- > +- error: Timeout exceeded > +... > +_ = remote_pk:delete({2}) > +--- > +... > +_ = remote_pk:delete({3}) > +--- > +... > +_ = remote_pk:delete({4}) > +--- > +... > +_ = remote_pk:delete({5}) > +--- > +... > +remote_space:get(0) > +--- > +... > +remote_space:get(1) > +--- > +... > +remote_space:get(2) > +--- > +... > +remote_space = nil > +--- > +... > +cn:call('ret_after', {0.01}, { timeout = 1.00 }) > +--- > +- [[0.01]] > +... > +cn:call('ret_after', {1.00}, { timeout = 1e-9 }) > +--- > +- error: Timeout exceeded > +... > +cn:eval('return ret_after(...)', {0.01}, { timeout = 1.00 }) > +--- > +- [[0.01]] > +... > +cn:eval('return ret_after(...)', {1.00}, { timeout = 1e-9 }) > +--- > +- error: Timeout exceeded > +... > +-- > +-- :timeout() > +-- @deprecated since 1.7.4 > +-- > +cn:timeout(1).space.net_box_test_space.index.primary:select{234} > +--- > +- - [234, 1, 2, 3] > +... > +cn:call('ret_after', {.01}) > +--- > +- [[0.01]] > +... > +cn:timeout(1):call('ret_after', {.01}) > +--- > +- [[0.01]] > +... > +cn:timeout(.01):call('ret_after', {1}) > +--- > +- error: Timeout exceeded > +... > +cn = remote:timeout(0.0000000001):connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123' }) > +--- > +... > +cn:close() > +--- > +... > +cn = remote:timeout(1):connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123' }) > +--- > +... > +remote.self:ping() > +--- > +- true > +... > +remote.self.space.net_box_test_space:select{234} > +--- > +- - [234, 1, 2, 3] > +... > +remote.self:timeout(123).space.net_box_test_space:select{234} > +--- > +- - [234, 1, 2, 3] > +... > +remote.self:is_connected() > +--- > +- true > +... > +remote.self:wait_connected() > +--- > +- true > +... > +cn:close() > +--- > +... > +-- cleanup database after tests > +space:drop() > +--- > +... > +box.schema.user.revoke('guest', 'execute', 'universe') > +--- > +... > diff --git a/test/box/net.box_count_inconsistent_gh-3262.test.lua b/test/box/net.box_count_inconsistent_gh-3262.test.lua > new file mode 100644 > index 000000000..e84e85cf3 > --- /dev/null > +++ b/test/box/net.box_count_inconsistent_gh-3262.test.lua > @@ -0,0 +1,182 @@ > +remote = require 'net.box' > +fiber = require 'fiber' > +test_run = require('test_run').new() > + > +LISTEN = require('uri').parse(box.cfg.listen) > +space = box.schema.space.create('net_box_test_space') > +index = space:create_index('primary', { type = 'tree' }) > + > +box.schema.user.grant('guest', 'read,write', 'space', 'net_box_test_space') > +box.schema.user.grant('guest', 'execute', 'universe') > + > +cn = remote.connect(box.cfg.listen) > +cn.space[space.id] ~= nil > +cn.space.net_box_test_space ~= nil > +cn.space.net_box_test_space ~= nil > +cn.space.net_box_test_space.index ~= nil > +cn.space.net_box_test_space.index.primary ~= nil > +cn.space.net_box_test_space.index[space.index.primary.id] ~= nil > +cn.space.net_box_test_space:insert{234, 1,2,3} > +cn.space.net_box_test_space:replace{354, 1,2,4} > +cn.space.net_box_test_space.index.primary:min(354) > +cn.space.net_box_test_space.index.primary:max(234) > +cn.space.net_box_test_space.index.primary:count(354) > + > +box.schema.user.create('netbox', { password = 'test' }) > +box.schema.user.grant('netbox', 'read,write', 'space', 'net_box_test_space') > +box.schema.user.grant('netbox', 'execute', 'universe') > +cn = remote.connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = 'test' }) > +cn.state > +cn.error > +cn:ping() > + > +function ret_after(to) fiber.sleep(to) return {{to}} end > + > +cn:ping({timeout = 1.00}) > +cn:ping({timeout = 1e-9}) > +cn:ping() > + > +remote_space = cn.space.net_box_test_space > +remote_pk = remote_space.index.primary > + > +remote_space:insert({0}, { timeout = 1.00 }) > +remote_space:insert({1}, { timeout = 1e-9 }) > +remote_space:insert({2}) > + > +remote_space:replace({0}, { timeout = 1e-9 }) > +remote_space:replace({1}) > +remote_space:replace({2}, { timeout = 1.00 }) > + > +remote_space:upsert({3}, {}, { timeout = 1e-9 }) > +remote_space:upsert({4}, {}) > +remote_space:upsert({5}, {}, { timeout = 1.00 }) > +remote_space:upsert({3}, {}) > + > +remote_space:update({3}, {}, { timeout = 1e-9 }) > +remote_space:update({4}, {}) > +remote_space:update({5}, {}, { timeout = 1.00 }) > +remote_space:update({3}, {}) > + > +remote_pk:update({5}, {}, { timeout = 1e-9 }) > +remote_pk:update({4}, {}) > +remote_pk:update({3}, {}, { timeout = 1.00 }) > +remote_pk:update({5}, {}) > + > +remote_space:get({0}) > +remote_space:get({1}, { timeout = 1.00 }) > +remote_space:get({2}, { timeout = 1e-9 }) > + > +remote_pk:get({3}, { timeout = 1e-9 }) > +remote_pk:get({4}) > +remote_pk:get({5}, { timeout = 1.00 }) > + > +remote_space:select({2}, { timeout = 1e-9 }) > +remote_space:select({2}, { timeout = 1.00 }) > +remote_space:select({2}) > + > +remote_pk:select({2}, { timeout = 1.00 }) > +remote_pk:select({2}, { timeout = 1e-9 }) > +remote_pk:select({2}) > + > +remote_space:select({5}, { timeout = 1.00, iterator = 'LE', limit = 5 }) > +remote_space:select({5}, { iterator = 'LE', limit = 5}) > +remote_space:select({5}, { timeout = 1e-9, iterator = 'LE', limit = 5 }) > + > +remote_pk:select({2}, { timeout = 1.00, iterator = 'LE', limit = 5 }) > +remote_pk:select({2}, { iterator = 'LE', limit = 5}) > +remote_pk:select({2}, { timeout = 1e-9, iterator = 'LE', limit = 5 }) > + > +remote_pk:count({2}, { timeout = 1.00}) > +remote_pk:count({2}, { timeout = 1e-9}) > +remote_pk:count({2}) > + > +remote_pk:count({2}, { timeout = 1.00, iterator = 'LE' }) > +remote_pk:count({2}, { iterator = 'LE'}) > +remote_pk:count({2}, { timeout = 1e-9, iterator = 'LE' }) > + > +remote_pk:min(nil, { timeout = 1.00 }) > +remote_pk:min(nil, { timeout = 1e-9 }) > +remote_pk:min(nil) > + > +remote_pk:min({0}, { timeout = 1e-9 }) > +remote_pk:min({1}) > +remote_pk:min({2}, { timeout = 1.00 }) > + > +remote_pk:max(nil) > +remote_pk:max(nil, { timeout = 1e-9 }) > +remote_pk:max(nil, { timeout = 1.00 }) > + > +remote_pk:max({0}, { timeout = 1.00 }) > +remote_pk:max({1}, { timeout = 1e-9 }) > +remote_pk:max({2}) > + > +-- > +-- gh-3262: index:count() inconsistent results > +-- > +test_run:cmd("setopt delimiter ';'") > + > +function do_count_test(min, it) > + local r1 = remote_pk:count(min, {iterator = it} ) > + local r2 = box.space.net_box_test_space.index.primary:count(min, {iterator = it} ) > + local r3 = remote.self.space.net_box_test_space.index.primary:count(min, {iterator = it} ) > + return r1 == r2 and r2 == r3 > +end; > + > +data = remote_pk:select(); > + > +for _, v in pairs(data) do > + local itrs = {'GE', 'GT', 'LE', 'LT' } > + for _, it in pairs(itrs) do > + assert(do_count_test(v[0], it) == true) > + end > +end; > + > +test_run:cmd("setopt delimiter ''"); > + > +_ = remote_space:delete({0}, { timeout = 1e-9 }) > +_ = remote_pk:delete({0}, { timeout = 1.00 }) > +_ = remote_space:delete({1}, { timeout = 1.00 }) > +_ = remote_pk:delete({1}, { timeout = 1e-9 }) > +_ = remote_space:delete({2}, { timeout = 1e-9 }) > +_ = remote_pk:delete({2}) > +_ = remote_pk:delete({3}) > +_ = remote_pk:delete({4}) > +_ = remote_pk:delete({5}) > + > +remote_space:get(0) > +remote_space:get(1) > +remote_space:get(2) > + > +remote_space = nil > + > +cn:call('ret_after', {0.01}, { timeout = 1.00 }) > +cn:call('ret_after', {1.00}, { timeout = 1e-9 }) > + > +cn:eval('return ret_after(...)', {0.01}, { timeout = 1.00 }) > +cn:eval('return ret_after(...)', {1.00}, { timeout = 1e-9 }) > + > +-- > +-- :timeout() > +-- @deprecated since 1.7.4 > +-- > + > +cn:timeout(1).space.net_box_test_space.index.primary:select{234} > +cn:call('ret_after', {.01}) > +cn:timeout(1):call('ret_after', {.01}) > +cn:timeout(.01):call('ret_after', {1}) > + > +cn = remote:timeout(0.0000000001):connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123' }) > +cn:close() > +cn = remote:timeout(1):connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123' }) > + > +remote.self:ping() > +remote.self.space.net_box_test_space:select{234} > +remote.self:timeout(123).space.net_box_test_space:select{234} > +remote.self:is_connected() > +remote.self:wait_connected() > + > +cn:close() > +-- cleanup database after tests > +space:drop() > + > +box.schema.user.revoke('guest', 'execute', 'universe') > diff --git a/test/box/net.box_discard_gh-3107.result b/test/box/net.box_discard_gh-3107.result > new file mode 100644 > index 000000000..3498c9d5a > --- /dev/null > +++ b/test/box/net.box_discard_gh-3107.result > @@ -0,0 +1,119 @@ > +fiber = require 'fiber' > +--- > +... > +net = require('net.box') > +--- > +... > +-- > +-- gh-3107: fiber-async netbox. > +-- > +cond = nil > +--- > +... > +box.schema.func.create('long_function') > +--- > +... > +box.schema.user.grant('guest', 'execute', 'function', 'long_function') > +--- > +... > +function long_function(...) cond = fiber.cond() cond:wait() return ... end > +--- > +... > +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end > +--- > +... > +s = box.schema.create_space('test') > +--- > +... > +pk = s:create_index('pk') > +--- > +... > +s:replace{1} > +--- > +- [1] > +... > +s:replace{2} > +--- > +- [2] > +... > +s:replace{3} > +--- > +- [3] > +... > +s:replace{4} > +--- > +- [4] > +... > +c = net:connect(box.cfg.listen) > +--- > +... > +-- > +-- Ensure a request can be finalized from non-caller fibers. > +-- > +future = c:call('long_function', {1, 2, 3}, {is_async = true}) > +--- > +... > +ret = {} > +--- > +... > +count = 0 > +--- > +... > +for i = 1, 10 do fiber.create(function() ret[i] = future:wait_result(1000) count = count + 1 end) end > +--- > +... > +future:wait_result(0.01) -- Must fail on timeout. > +--- > +- null > +- Timeout exceeded > +... > +finalize_long() > +--- > +... > +while count ~= 10 do fiber.sleep(0.1) end > +--- > +... > +ret > +--- > +- - &0 [1, 2, 3] > + - *0 > + - *0 > + - *0 > + - *0 > + - *0 > + - *0 > + - *0 > + - *0 > + - *0 > +... > +-- > +-- Test discard. > +-- > +future = c:call('long_function', {1, 2, 3}, {is_async = true}) > +--- > +... > +future:discard() > +--- > +... > +finalize_long() > +--- > +... > +future:result() > +--- > +- null > +- Response is discarded > +... > +future:wait_result(100) > +--- > +- null > +- Response is discarded > +... > +box.schema.func.drop('long_function') > +--- > +... > +c:close() > +--- > +... > +s:drop() > +--- > +... > diff --git a/test/box/net.box_discard_gh-3107.test.lua b/test/box/net.box_discard_gh-3107.test.lua > new file mode 100644 > index 000000000..71f08a411 > --- /dev/null > +++ b/test/box/net.box_discard_gh-3107.test.lua > @@ -0,0 +1,44 @@ > +fiber = require 'fiber' > +net = require('net.box') > + > +-- > +-- gh-3107: fiber-async netbox. > +-- > +cond = nil > +box.schema.func.create('long_function') > +box.schema.user.grant('guest', 'execute', 'function', 'long_function') > +function long_function(...) cond = fiber.cond() cond:wait() return ... end > +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end > +s = box.schema.create_space('test') > +pk = s:create_index('pk') > +s:replace{1} > +s:replace{2} > +s:replace{3} > +s:replace{4} > +c = net:connect(box.cfg.listen) > + > +-- > +-- Ensure a request can be finalized from non-caller fibers. > +-- > +future = c:call('long_function', {1, 2, 3}, {is_async = true}) > +ret = {} > +count = 0 > +for i = 1, 10 do fiber.create(function() ret[i] = future:wait_result(1000) count = count + 1 end) end > +future:wait_result(0.01) -- Must fail on timeout. > +finalize_long() > +while count ~= 10 do fiber.sleep(0.1) end > +ret > + > +-- > +-- Test discard. > +-- > +future = c:call('long_function', {1, 2, 3}, {is_async = true}) > +future:discard() > +finalize_long() > +future:result() > +future:wait_result(100) > + > +box.schema.func.drop('long_function') > + > +c:close() > +s:drop() > diff --git a/test/box/net.box_disconnect_gh-3859.result b/test/box/net.box_disconnect_gh-3859.result > new file mode 100644 > index 000000000..eae259740 > --- /dev/null > +++ b/test/box/net.box_disconnect_gh-3859.result > @@ -0,0 +1,113 @@ > +fiber = require 'fiber' > +--- > +... > +test_run = require('test_run').new() > +--- > +... > +net = require('net.box') > +--- > +... > +test_run:cmd('create server connecter with script = "box/proxy.lua"') > +--- > +- true > +... > +box.schema.func.create('fast_call') > +--- > +... > +box.schema.func.create('long_call') > +--- > +... > +box.schema.func.create('wait_signal') > +--- > +... > +box.schema.user.grant('guest', 'execute', 'function', 'fast_call') > +--- > +... > +box.schema.user.grant('guest', 'execute', 'function', 'long_call') > +--- > +... > +box.schema.user.grant('guest', 'execute', 'function', 'wait_signal') > +--- > +... > +c = net.connect(box.cfg.listen) > +--- > +... > +disconnected = false > +--- > +... > +function on_disconnect() disconnected = true end > +--- > +... > +-- Make sure all dangling connections are collected so > +-- that on_disconnect trigger isn't called spuriously. > +collectgarbage('collect') > +--- > +- 0 > +... > +fiber.sleep(0) > +--- > +... > +box.session.on_disconnect(on_disconnect) == on_disconnect > +--- > +- true > +... > +-- > +-- gh-3859: on_disconnect is called only after all requests are > +-- processed, but should be called right after disconnect and > +-- only once. > +-- > +ch1 = fiber.channel(1) > +--- > +... > +ch2 = fiber.channel(1) > +--- > +... > +function wait_signal() ch1:put(true) ch2:get() end > +--- > +... > +_ = fiber.create(function() c:call('wait_signal') end) > +--- > +... > +ch1:get() > +--- > +- true > +... > +c:close() > +--- > +... > +fiber.sleep(0) > +--- > +... > +while disconnected == false do fiber.sleep(0.01) end > +--- > +... > +disconnected -- true > +--- > +- true > +... > +disconnected = nil > +--- > +... > +ch2:put(true) > +--- > +- true > +... > +fiber.sleep(0) > +--- > +... > +disconnected -- nil, on_disconnect is not called second time. > +--- > +- null > +... > +box.session.on_disconnect(nil, on_disconnect) > +--- > +... > +box.schema.func.drop('long_call') > +--- > +... > +box.schema.func.drop('fast_call') > +--- > +... > +box.schema.func.drop('wait_signal') > +--- > +... > diff --git a/test/box/net.box_disconnect_gh-3859.test.lua b/test/box/net.box_disconnect_gh-3859.test.lua > new file mode 100644 > index 000000000..e0ec1a8ea > --- /dev/null > +++ b/test/box/net.box_disconnect_gh-3859.test.lua > @@ -0,0 +1,50 @@ > +fiber = require 'fiber' > +test_run = require('test_run').new() > +net = require('net.box') > + > +test_run:cmd('create server connecter with script = "box/proxy.lua"') > + > +box.schema.func.create('fast_call') > +box.schema.func.create('long_call') > +box.schema.func.create('wait_signal') > +box.schema.user.grant('guest', 'execute', 'function', 'fast_call') > +box.schema.user.grant('guest', 'execute', 'function', 'long_call') > +box.schema.user.grant('guest', 'execute', 'function', 'wait_signal') > +c = net.connect(box.cfg.listen) > + > +disconnected = false > +function on_disconnect() disconnected = true end > + > +-- Make sure all dangling connections are collected so > +-- that on_disconnect trigger isn't called spuriously. > +collectgarbage('collect') > +fiber.sleep(0) > + > +box.session.on_disconnect(on_disconnect) == on_disconnect > + > +-- > +-- gh-3859: on_disconnect is called only after all requests are > +-- processed, but should be called right after disconnect and > +-- only once. > +-- > +ch1 = fiber.channel(1) > +ch2 = fiber.channel(1) > +function wait_signal() ch1:put(true) ch2:get() end > +_ = fiber.create(function() c:call('wait_signal') end) > +ch1:get() > + > +c:close() > +fiber.sleep(0) > +while disconnected == false do fiber.sleep(0.01) end > +disconnected -- true > +disconnected = nil > + > +ch2:put(true) > +fiber.sleep(0) > +disconnected -- nil, on_disconnect is not called second time. > + > +box.session.on_disconnect(nil, on_disconnect) > + > +box.schema.func.drop('long_call') > +box.schema.func.drop('fast_call') > +box.schema.func.drop('wait_signal') > diff --git a/test/box/net.box_fiber-async_gh-3107.result b/test/box/net.box_fiber-async_gh-3107.result > new file mode 100644 > index 000000000..aaaca351a > --- /dev/null > +++ b/test/box/net.box_fiber-async_gh-3107.result > @@ -0,0 +1,115 @@ > +fiber = require 'fiber' > +--- > +... > +net = require('net.box') > +--- > +... > +-- > +-- gh-3107: fiber-async netbox. > +-- > +cond = nil > +--- > +... > +box.schema.func.create('long_function') > +--- > +... > +box.schema.user.grant('guest', 'execute', 'function', 'long_function') > +--- > +... > +function long_function(...) cond = fiber.cond() cond:wait() return ... end > +--- > +... > +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end > +--- > +... > +s = box.schema.create_space('test') > +--- > +... > +pk = s:create_index('pk') > +--- > +... > +s:replace{1} > +--- > +- [1] > +... > +s:replace{2} > +--- > +- [2] > +... > +s:replace{3} > +--- > +- [3] > +... > +s:replace{4} > +--- > +- [4] > +... > +c = net:connect(box.cfg.listen) > +--- > +... > +-- > +-- Check long connections, multiple wait_result(). > +-- > +future = c:call('long_function', {1, 2, 3}, {is_async = true}) > +--- > +... > +future:result() > +--- > +- null > +- Response is not ready > +... > +future:is_ready() > +--- > +- false > +... > +future:wait_result(0.01) -- Must fail on timeout. > +--- > +- null > +- Timeout exceeded > +... > +finalize_long() > +--- > +... > +ret = future:wait_result(100) > +--- > +... > +future:is_ready() > +--- > +- true > +... > +-- Any timeout is ok - response is received already. > +future:wait_result(0) > +--- > +- [1, 2, 3] > +... > +future:wait_result(0.01) > +--- > +- [1, 2, 3] > +... > +ret > +--- > +- [1, 2, 3] > +... > +_, err = pcall(future.wait_result, future, true) > +--- > +... > +err:find('Usage') ~= nil > +--- > +- true > +... > +_, err = pcall(future.wait_result, future, '100') > +--- > +... > +err:find('Usage') ~= nil > +--- > +- true > +... > +box.schema.func.drop('long_function') > +--- > +... > +c:close() > +--- > +... > +s:drop() > +--- > +... > diff --git a/test/box/net.box_fiber-async_gh-3107.test.lua b/test/box/net.box_fiber-async_gh-3107.test.lua > new file mode 100644 > index 000000000..d23f368cb > --- /dev/null > +++ b/test/box/net.box_fiber-async_gh-3107.test.lua > @@ -0,0 +1,42 @@ > +fiber = require 'fiber' > +net = require('net.box') > + > +-- > +-- gh-3107: fiber-async netbox. > +-- > +cond = nil > +box.schema.func.create('long_function') > +box.schema.user.grant('guest', 'execute', 'function', 'long_function') > +function long_function(...) cond = fiber.cond() cond:wait() return ... end > +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end > +s = box.schema.create_space('test') > +pk = s:create_index('pk') > +s:replace{1} > +s:replace{2} > +s:replace{3} > +s:replace{4} > +c = net:connect(box.cfg.listen) > +-- > +-- Check long connections, multiple wait_result(). > +-- > +future = c:call('long_function', {1, 2, 3}, {is_async = true}) > +future:result() > +future:is_ready() > +future:wait_result(0.01) -- Must fail on timeout. > +finalize_long() > +ret = future:wait_result(100) > +future:is_ready() > +-- Any timeout is ok - response is received already. > +future:wait_result(0) > +future:wait_result(0.01) > +ret > + > +_, err = pcall(future.wait_result, future, true) > +err:find('Usage') ~= nil > +_, err = pcall(future.wait_result, future, '100') > +err:find('Usage') ~= nil > + > +box.schema.func.drop('long_function') > + > +c:close() > +s:drop() > diff --git a/test/box/net.box_field_names_gh-2978.result b/test/box/net.box_field_names_gh-2978.result > new file mode 100644 > index 000000000..2b6ea9c44 > --- /dev/null > +++ b/test/box/net.box_field_names_gh-2978.result > @@ -0,0 +1,101 @@ > +net = require('net.box') > +--- > +... > +-- > +-- gh-2978: field names for tuples received from netbox. > +-- > +_ = box.schema.create_space("named", {format = {{name = "id"}, {name="abc"}}}) > +--- > +... > +_ = box.space.named:create_index('id', {parts = {{1, 'unsigned'}}}) > +--- > +... > +box.space.named:insert({1, 1}) > +--- > +- [1, 1] > +... > +box.schema.user.grant('guest', 'read, write, execute', 'space') > +--- > +... > +cn = net.connect(box.cfg.listen) > +--- > +... > +s = cn.space.named > +--- > +... > +s:get{1}.id > +--- > +- 1 > +... > +s:get{1}:tomap() > +--- > +- 1: 1 > + 2: 1 > + abc: 1 > + id: 1 > +... > +s:insert{2,3}:tomap() > +--- > +- 1: 2 > + 2: 3 > + abc: 3 > + id: 2 > +... > +s:replace{2,14}:tomap() > +--- > +- 1: 2 > + 2: 14 > + abc: 14 > + id: 2 > +... > +s:update(1, {{'+', 2, 10}}):tomap() > +--- > +- 1: 1 > + 2: 11 > + abc: 11 > + id: 1 > +... > +s:select()[1]:tomap() > +--- > +- 1: 1 > + 2: 11 > + abc: 11 > + id: 1 > +... > +s:delete({2}):tomap() > +--- > +- 1: 2 > + 2: 14 > + abc: 14 > + id: 2 > +... > +-- Check that formats changes after reload. > +box.space.named:format({{name = "id2"}, {name="abc2"}}) > +--- > +... > +s:select()[1]:tomap() > +--- > +- 1: 1 > + 2: 11 > + abc: 11 > + id: 1 > +... > +cn:reload_schema() > +--- > +... > +s:select()[1]:tomap() > +--- > +- 1: 1 > + 2: 11 > + id2: 1 > + abc2: 11 > +... > +cn:close() > +--- > +... > +box.space.named:drop() > +--- > +... > +box.schema.user.revoke('guest', 'read, write, execute', 'space') > +--- > +... > diff --git a/test/box/net.box_field_names_gh-2978.test.lua b/test/box/net.box_field_names_gh-2978.test.lua > new file mode 100644 > index 000000000..a5dccf16a > --- /dev/null > +++ b/test/box/net.box_field_names_gh-2978.test.lua > @@ -0,0 +1,29 @@ > +net = require('net.box') > + > +-- > +-- gh-2978: field names for tuples received from netbox. > +-- > +_ = box.schema.create_space("named", {format = {{name = "id"}, {name="abc"}}}) > +_ = box.space.named:create_index('id', {parts = {{1, 'unsigned'}}}) > +box.space.named:insert({1, 1}) > +box.schema.user.grant('guest', 'read, write, execute', 'space') > +cn = net.connect(box.cfg.listen) > + > +s = cn.space.named > +s:get{1}.id > +s:get{1}:tomap() > +s:insert{2,3}:tomap() > +s:replace{2,14}:tomap() > +s:update(1, {{'+', 2, 10}}):tomap() > +s:select()[1]:tomap() > +s:delete({2}):tomap() > + > +-- Check that formats changes after reload. > +box.space.named:format({{name = "id2"}, {name="abc2"}}) > +s:select()[1]:tomap() > +cn:reload_schema() > +s:select()[1]:tomap() > + > +cn:close() > +box.space.named:drop() > +box.schema.user.revoke('guest', 'read, write, execute', 'space') > diff --git a/test/box/net.box_get_connection_object.result b/test/box/net.box_get_connection_object.result > new file mode 100644 > index 000000000..f461477ed > --- /dev/null > +++ b/test/box/net.box_get_connection_object.result > @@ -0,0 +1,40 @@ > +net = require('net.box') > +--- > +... > +-- > +-- Check that it's possible to get connection object form net.box space > +-- > +space = box.schema.space.create('test', {format={{name="id", type="unsigned"}}}) > +--- > +... > +space ~= nil > +--- > +- true > +... > +_ = box.space.test:create_index('primary') > +--- > +... > +box.schema.user.grant('guest','read,write,execute','space', 'test') > +--- > +... > +c = net.connect(box.cfg.listen) > +--- > +... > +c:ping() > +--- > +- true > +... > +c.space.test ~= nil > +--- > +- true > +... > +c.space.test.connection == c > +--- > +- true > +... > +box.schema.user.revoke('guest','read,write,execute','space', 'test') > +--- > +... > +c:close() > +--- > +... > diff --git a/test/box/net.box_get_connection_object.test.lua b/test/box/net.box_get_connection_object.test.lua > new file mode 100644 > index 000000000..71ed110b9 > --- /dev/null > +++ b/test/box/net.box_get_connection_object.test.lua > @@ -0,0 +1,19 @@ > +net = require('net.box') > + > +-- > +-- Check that it's possible to get connection object form net.box space > +-- > + > +space = box.schema.space.create('test', {format={{name="id", type="unsigned"}}}) > +space ~= nil > +_ = box.space.test:create_index('primary') > +box.schema.user.grant('guest','read,write,execute','space', 'test') > + > +c = net.connect(box.cfg.listen) > + > +c:ping() > +c.space.test ~= nil > + > +c.space.test.connection == c > +box.schema.user.revoke('guest','read,write,execute','space', 'test') > +c:close() > diff --git a/test/box/net.box_gibberish_gh-3900.result b/test/box/net.box_gibberish_gh-3900.result > new file mode 100644 > index 000000000..302c74c9f > --- /dev/null > +++ b/test/box/net.box_gibberish_gh-3900.result > @@ -0,0 +1,31 @@ > +test_run = require('test_run').new() > +--- > +... > +LISTEN = require('uri').parse(box.cfg.listen) > +--- > +... > +-- > +-- gh-3900: tarantool can be crashed by sending gibberish to a > +-- binary socket > +-- > +socket = require("socket") > +--- > +... > +sock = socket.tcp_connect(LISTEN.host, LISTEN.service) > +--- > +... > +data = string.fromhex("6783000000000000000000000000000000000000000000800000C8000000000000000000000000000000000000000000FFFF210100373208000000FFFF000055AAEB66486472530D02000000000010A0350001008000001000000000000000000000000000D05700") > +--- > +... > +sock:write(data) > +--- > +- 104 > +... > +test_run:wait_log('default', 'ER_INVALID_MSGPACK: Invalid MsgPack %- packet body', nil, 10) > +--- > +- 'ER_INVALID_MSGPACK: Invalid MsgPack - packet body' > +... > +sock:close() > +--- > +- true > +... > diff --git a/test/box/net.box_gibberish_gh-3900.test.lua b/test/box/net.box_gibberish_gh-3900.test.lua > new file mode 100644 > index 000000000..7debfd4b3 > --- /dev/null > +++ b/test/box/net.box_gibberish_gh-3900.test.lua > @@ -0,0 +1,13 @@ > +test_run = require('test_run').new() > +LISTEN = require('uri').parse(box.cfg.listen) > + > +-- > +-- gh-3900: tarantool can be crashed by sending gibberish to a > +-- binary socket > +-- > +socket = require("socket") > +sock = socket.tcp_connect(LISTEN.host, LISTEN.service) > +data = string.fromhex("6783000000000000000000000000000000000000000000800000C8000000000000000000000000000000000000000000FFFF210100373208000000FFFF000055AAEB66486472530D02000000000010A0350001008000001000000000000000000000000000D05700") > +sock:write(data) > +test_run:wait_log('default', 'ER_INVALID_MSGPACK: Invalid MsgPack %- packet body', nil, 10) > +sock:close() > diff --git a/test/box/net.box_huge_data_gh-983.result b/test/box/net.box_huge_data_gh-983.result > new file mode 100644 > index 000000000..e9b470e28 > --- /dev/null > +++ b/test/box/net.box_huge_data_gh-983.result > @@ -0,0 +1,30 @@ > +-- gh-983 selecting a lot of data crashes the server or hangs the > +-- connection > +-- gh-983 test case: iproto connection selecting a lot of data > +_ = box.schema.space.create('test', { temporary = true }) > +--- > +... > +_ = box.space.test:create_index('primary', {type = 'TREE', parts = {1,'unsigned'}}) > +--- > +... > +data1k = "aaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhh" > +--- > +... > +for i = 0,10000 do box.space.test:insert{i, data1k} end > +--- > +... > +box.schema.user.grant('guest', 'read', 'space', 'test') > +--- > +... > +net = require('net.box') > +--- > +... > +c = net:connect(box.cfg.listen) > +--- > +... > +r = c.space.test:select(nil, {limit=5000}) > +--- > +... > +box.space.test:drop() > +--- > +... > diff --git a/test/box/net.box_huge_data_gh-983.test.lua b/test/box/net.box_huge_data_gh-983.test.lua > new file mode 100644 > index 000000000..93df08834 > --- /dev/null > +++ b/test/box/net.box_huge_data_gh-983.test.lua > @@ -0,0 +1,16 @@ > +-- gh-983 selecting a lot of data crashes the server or hangs the > +-- connection > + > +-- gh-983 test case: iproto connection selecting a lot of data > +_ = box.schema.space.create('test', { temporary = true }) > +_ = box.space.test:create_index('primary', {type = 'TREE', parts = {1,'unsigned'}}) > + > +data1k = "aaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhh" > + > +for i = 0,10000 do box.space.test:insert{i, data1k} end > + > +box.schema.user.grant('guest', 'read', 'space', 'test') > +net = require('net.box') > +c = net:connect(box.cfg.listen) > +r = c.space.test:select(nil, {limit=5000}) > +box.space.test:drop() > diff --git a/test/box/net.box_incompatible_index-gh-1729.result b/test/box/net.box_incompatible_index-gh-1729.result > new file mode 100644 > index 000000000..1d9fa542e > --- /dev/null > +++ b/test/box/net.box_incompatible_index-gh-1729.result > @@ -0,0 +1,99 @@ > +test_run = require('test_run').new() > +--- > +... > +net = require('net.box') > +--- > +... > +test_run:cmd("push filter ".."'\\.lua.*:[0-9]+: ' to '.lua...\"]:<line>: '") > +--- > +- true > +... > +_ = box.schema.space.create('test') > +--- > +... > +_ = box.space.test:create_index('primary', {type = 'TREE', parts = {1,'unsigned'}}) > +--- > +... > +_ = box.space.test:create_index('covering', {type = 'TREE', parts = {1,'unsigned',3,'string',2,'unsigned'}}) > +--- > +... > +_ = box.space.test:insert{1, 2, "string"} > +--- > +... > +box.schema.user.grant('guest', 'read,write', 'space', 'test') > +--- > +... > +c = net:connect(box.cfg.listen) > +--- > +... > +-- gh-1729 net.box index metadata incompatible with local metadata > +c.space.test.index.primary.parts > +--- > +- - type: unsigned > + is_nullable: false > + fieldno: 1 > +... > +c.space.test.index.covering.parts > +--- > +- - type: unsigned > + is_nullable: false > + fieldno: 1 > + - type: string > + is_nullable: false > + fieldno: 3 > + - type: unsigned > + is_nullable: false > + fieldno: 2 > +... > +box.space.test:drop() > +--- > +... > +-- CALL vs CALL_16 in connect options > +function echo(...) return ... end > +--- > +... > +box.schema.user.grant('guest', 'execute', 'universe') > +--- > +... > +c = net.connect(box.cfg.listen) > +--- > +... > +c:call('echo', {42}) > +--- > +- 42 > +... > +c:eval('return echo(...)', {42}) > +--- > +- 42 > +... > +-- invalid arguments > +c:call('echo', 42) > +--- > +- error: 'builtin/box/net_box.lua..."]:<line>: Use remote:call(func_name, {arg1, arg2, ...}, > + opts) instead of remote:call(func_name, arg1, arg2, ...)' > +... > +c:eval('return echo(...)', 42) > +--- > +- error: 'builtin/box/net_box.lua..."]:<line>: Use remote:eval(expression, {arg1, arg2, ...}, > + opts) instead of remote:eval(expression, arg1, arg2, ...)' > +... > +c:close() > +--- > +... > +c = net.connect(box.cfg.listen, {call_16 = true}) > +--- > +... > +c:call('echo', 42) > +--- > +- - [42] > +... > +c:eval('return echo(...)', 42) > +--- > +- 42 > +... > +c:close() > +--- > +... > +box.schema.user.revoke('guest', 'execute', 'universe') > +--- > +... > diff --git a/test/box/net.box_incompatible_index-gh-1729.test.lua b/test/box/net.box_incompatible_index-gh-1729.test.lua > new file mode 100644 > index 000000000..2d25b9017 > --- /dev/null > +++ b/test/box/net.box_incompatible_index-gh-1729.test.lua > @@ -0,0 +1,33 @@ > +test_run = require('test_run').new() > +net = require('net.box') > + > +test_run:cmd("push filter ".."'\\.lua.*:[0-9]+: ' to '.lua...\"]:<line>: '") > + > +_ = box.schema.space.create('test') > +_ = box.space.test:create_index('primary', {type = 'TREE', parts = {1,'unsigned'}}) > +_ = box.space.test:create_index('covering', {type = 'TREE', parts = {1,'unsigned',3,'string',2,'unsigned'}}) > +_ = box.space.test:insert{1, 2, "string"} > +box.schema.user.grant('guest', 'read,write', 'space', 'test') > +c = net:connect(box.cfg.listen) > + > +-- gh-1729 net.box index metadata incompatible with local metadata > +c.space.test.index.primary.parts > +c.space.test.index.covering.parts > + > +box.space.test:drop() > + > +-- CALL vs CALL_16 in connect options > +function echo(...) return ... end > +box.schema.user.grant('guest', 'execute', 'universe') > +c = net.connect(box.cfg.listen) > +c:call('echo', {42}) > +c:eval('return echo(...)', {42}) > +-- invalid arguments > +c:call('echo', 42) > +c:eval('return echo(...)', 42) > +c:close() > +c = net.connect(box.cfg.listen, {call_16 = true}) > +c:call('echo', 42) > +c:eval('return echo(...)', 42) > +c:close() > +box.schema.user.revoke('guest', 'execute', 'universe') > diff --git a/test/box/net.box_incorrect_iterator_gh-841.result b/test/box/net.box_incorrect_iterator_gh-841.result > new file mode 100644 > index 000000000..4bdd1afa3 > --- /dev/null > +++ b/test/box/net.box_incorrect_iterator_gh-841.result > @@ -0,0 +1,497 @@ > +remote = require 'net.box' > +--- > +... > +fiber = require 'fiber' > +--- > +... > +test_run = require('test_run').new() > +--- > +... > +test_run:cmd("push filter ".."'\\.lua.*:[0-9]+: ' to '.lua...\"]:<line>: '") > +--- > +- true > +... > +test_run:cmd("setopt delimiter ';'") > +--- > +- true > +... > +function x_select(cn, space_id, index_id, iterator, offset, limit, key, opts) > + local ret = cn:_request('select', opts, nil, space_id, index_id, iterator, > + offset, limit, key) > + return ret > +end > +function x_fatal(cn) cn._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') end > +test_run:cmd("setopt delimiter ''"); > +--- > +... > +LISTEN = require('uri').parse(box.cfg.listen) > +--- > +... > +space = box.schema.space.create('net_box_test_space') > +--- > +... > +index = space:create_index('primary', { type = 'tree' }) > +--- > +... > +function test_foo(a,b,c) return { {{ [a] = 1 }}, {{ [b] = 2 }}, c } end > +--- > +... > +box.schema.user.grant('guest', 'read,write', 'space', 'net_box_test_space') > +--- > +... > +box.schema.user.grant('guest', 'execute', 'universe') > +--- > +... > +cn = remote.connect(box.cfg.listen) > +--- > +... > +x_select(cn, space.id, space.index.primary.id, box.index.EQ, 0, 0xFFFFFFFF, 123) > +--- > +- [] > +... > +space:insert{123, 345} > +--- > +- [123, 345] > +... > +x_select(cn, space.id, space.index.primary.id, box.index.EQ, 0, 0, 123) > +--- > +- [] > +... > +x_select(cn, space.id, space.index.primary.id, box.index.EQ, 0, 1, 123) > +--- > +- - [123, 345] > +... > +x_select(cn, space.id, space.index.primary.id, box.index.EQ, 1, 1, 123) > +--- > +- [] > +... > +cn.space[space.id] ~= nil > +--- > +- true > +... > +cn.space.net_box_test_space ~= nil > +--- > +- true > +... > +cn.space.net_box_test_space ~= nil > +--- > +- true > +... > +cn.space.net_box_test_space.index ~= nil > +--- > +- true > +... > +cn.space.net_box_test_space.index.primary ~= nil > +--- > +- true > +... > +cn.space.net_box_test_space.index[space.index.primary.id] ~= nil > +--- > +- true > +... > +cn.space.net_box_test_space.index.primary:select(123) > +--- > +- - [123, 345] > +... > +cn.space.net_box_test_space.index.primary:select(123, { limit = 0 }) > +--- > +- [] > +... > +cn.space.net_box_test_space.index.primary:select(nil, { limit = 1, }) > +--- > +- - [123, 345] > +... > +cn.space.net_box_test_space:insert{234, 1,2,3} > +--- > +- [234, 1, 2, 3] > +... > +cn.space.net_box_test_space:insert{234, 1,2,3} > +--- > +- error: Duplicate key exists in unique index 'primary' in space 'net_box_test_space' > +... > +cn.space.net_box_test_space.insert{234, 1,2,3} > +--- > +- error: 'builtin/box/schema.lua..."]:<line>: Use space:insert(...) instead of space.insert(...)' > +... > +cn.space.net_box_test_space:replace{354, 1,2,3} > +--- > +- [354, 1, 2, 3] > +... > +cn.space.net_box_test_space:replace{354, 1,2,4} > +--- > +- [354, 1, 2, 4] > +... > +cn.space.net_box_test_space:select{123} > +--- > +- - [123, 345] > +... > +space:select({123}, { iterator = 'GE' }) > +--- > +- - [123, 345] > + - [234, 1, 2, 3] > + - [354, 1, 2, 4] > +... > +cn.space.net_box_test_space:select({123}, { iterator = 'GE' }) > +--- > +- - [123, 345] > + - [234, 1, 2, 3] > + - [354, 1, 2, 4] > +... > +cn.space.net_box_test_space:select({123}, { iterator = 'GT' }) > +--- > +- - [234, 1, 2, 3] > + - [354, 1, 2, 4] > +... > +cn.space.net_box_test_space:select({123}, { iterator = 'GT', limit = 1 }) > +--- > +- - [234, 1, 2, 3] > +... > +cn.space.net_box_test_space:select({123}, { iterator = 'GT', limit = 1, offset = 1 }) > +--- > +- - [354, 1, 2, 4] > +... > +cn.space.net_box_test_space:select{123} > +--- > +- - [123, 345] > +... > +cn.space.net_box_test_space:update({123}, { { '+', 2, 1 } }) > +--- > +- [123, 346] > +... > +cn.space.net_box_test_space:update(123, { { '+', 2, 1 } }) > +--- > +- [123, 347] > +... > +cn.space.net_box_test_space:select{123} > +--- > +- - [123, 347] > +... > +cn.space.net_box_test_space:insert(cn.space.net_box_test_space:get{123}:update{ { '=', 1, 2 } }) > +--- > +- [2, 347] > +... > +cn.space.net_box_test_space:delete{123} > +--- > +- [123, 347] > +... > +cn.space.net_box_test_space:select{2} > +--- > +- - [2, 347] > +... > +cn.space.net_box_test_space:select({234}, { iterator = 'LT' }) > +--- > +- - [2, 347] > +... > +cn.space.net_box_test_space:update({1}, { { '+', 2, 2 } }) > +--- > +... > +cn.space.net_box_test_space:delete{1} > +--- > +... > +cn.space.net_box_test_space:delete{2} > +--- > +- [2, 347] > +... > +cn.space.net_box_test_space:delete{2} > +--- > +... > +-- test one-based indexing in splice operation (see update.test.lua) > +cn.space.net_box_test_space:replace({10, 'abcde'}) > +--- > +- [10, 'abcde'] > +... > +cn.space.net_box_test_space:update(10, {{':', 2, 0, 0, '!'}}) > +--- > +- error: 'SPLICE error on field 2: offset is out of bound' > +... > +cn.space.net_box_test_space:update(10, {{':', 2, 1, 0, '('}}) > +--- > +- [10, '(abcde'] > +... > +cn.space.net_box_test_space:update(10, {{':', 2, 2, 0, '({'}}) > +--- > +- [10, '(({abcde'] > +... > +cn.space.net_box_test_space:update(10, {{':', 2, -1, 0, ')'}}) > +--- > +- [10, '(({abcde)'] > +... > +cn.space.net_box_test_space:update(10, {{':', 2, -2, 0, '})'}}) > +--- > +- [10, '(({abcde}))'] > +... > +cn.space.net_box_test_space:delete{10} > +--- > +- [10, '(({abcde}))'] > +... > +cn.space.net_box_test_space:select({}, { iterator = 'ALL' }) > +--- > +- - [234, 1, 2, 3] > + - [354, 1, 2, 4] > +... > +-- gh-841: net.box uses incorrect iterator type for select with no arguments > +cn.space.net_box_test_space:select() > +--- > +- - [234, 1, 2, 3] > + - [354, 1, 2, 4] > +... > +cn.space.net_box_test_space.index.primary:min() > +--- > +- [234, 1, 2, 3] > +... > +cn.space.net_box_test_space.index.primary:min(354) > +--- > +- [354, 1, 2, 4] > +... > +cn.space.net_box_test_space.index.primary:max() > +--- > +- [354, 1, 2, 4] > +... > +cn.space.net_box_test_space.index.primary:max(234) > +--- > +- [234, 1, 2, 3] > +... > +cn.space.net_box_test_space.index.primary:count() > +--- > +- 2 > +... > +cn.space.net_box_test_space.index.primary:count(354) > +--- > +- 1 > +... > +cn.space.net_box_test_space:get(354) > +--- > +- [354, 1, 2, 4] > +... > +-- reconnects after errors > +box.schema.user.revoke('guest', 'execute', 'universe') > +--- > +... > +box.schema.func.create('test_foo') > +--- > +... > +box.schema.user.grant('guest', 'execute', 'function', 'test_foo') > +--- > +... > +-- -- 1. no reconnect > +x_fatal(cn) > +--- > +... > +cn.state > +--- > +- error > +... > +cn:ping() > +--- > +- false > +... > +cn:call('test_foo') > +--- > +- error: Peer closed > +... > +cn:wait_state('active') > +--- > +- false > +... > +-- -- 2 reconnect > +cn = remote.connect(LISTEN.host, LISTEN.service, { reconnect_after = .1 }) > +--- > +... > +cn.space ~= nil > +--- > +- true > +... > +cn.space.net_box_test_space:select({}, { iterator = 'ALL' }) > +--- > +- - [234, 1, 2, 3] > + - [354, 1, 2, 4] > +... > +x_fatal(cn) > +--- > +... > +cn:wait_connected() > +--- > +- true > +... > +cn:wait_state('active') > +--- > +- true > +... > +cn:wait_state({active=true}) > +--- > +- true > +... > +cn:ping() > +--- > +- true > +... > +cn.state > +--- > +- active > +... > +cn.space.net_box_test_space:select({}, { iterator = 'ALL' }) > +--- > +- - [234, 1, 2, 3] > + - [354, 1, 2, 4] > +... > +x_fatal(cn) > +--- > +... > +x_select(cn, space.id, 0, box.index.ALL, 0, 0xFFFFFFFF, {}) > +--- > +- - [234, 1, 2, 3] > + - [354, 1, 2, 4] > +... > +cn.state > +--- > +- active > +... > +cn:ping() > +--- > +- true > +... > +-- -- dot-new-method > +cn1 = remote.new(LISTEN.host, LISTEN.service) > +--- > +... > +x_select(cn1, space.id, 0, box.index.ALL, 0, 0xFFFFFFF, {}) > +--- > +- - [234, 1, 2, 3] > + - [354, 1, 2, 4] > +... > +cn1:close() > +--- > +... > +-- -- error while waiting for response > +type(fiber.create(function() fiber.sleep(.5) x_fatal(cn) end)) > +--- > +- userdata > +... > +function pause() fiber.sleep(10) return true end > +--- > +... > +box.schema.func.create('pause') > +--- > +... > +box.schema.user.grant('guest', 'execute', 'function', 'pause') > +--- > +... > +cn:call('pause') > +--- > +- error: Peer closed > +... > +cn:call('test_foo', {'a', 'b', 'c'}) > +--- > +- [[{'a': 1}], [{'b': 2}], 'c'] > +... > +box.schema.func.drop('pause') > +--- > +... > +-- call > +remote.self:call('test_foo', {'a', 'b', 'c'}) > +--- > +- - - a: 1 > + - - b: 2 > + - c > +... > +cn:call('test_foo', {'a', 'b', 'c'}) > +--- > +- [[{'a': 1}], [{'b': 2}], 'c'] > +... > +box.schema.func.drop('test_foo') > +--- > +... > +box.schema.func.create('long_rep') > +--- > +... > +box.schema.user.grant('guest', 'execute', 'function', 'long_rep') > +--- > +... > +-- long replies > +function long_rep() return { 1, string.rep('a', 5000) } end > +--- > +... > +res = cn:call('long_rep') > +--- > +... > +res[1] == 1 > +--- > +- true > +... > +res[2] == string.rep('a', 5000) > +--- > +- true > +... > +function long_rep() return { 1, string.rep('a', 50000) } end > +--- > +... > +res = cn:call('long_rep') > +--- > +... > +res[1] == 1 > +--- > +- true > +... > +res[2] == string.rep('a', 50000) > +--- > +- true > +... > +box.schema.func.drop('long_rep') > +--- > +... > +-- a.b.c.d > +u = '84F7BCFA-079C-46CC-98B4-F0C821BE833E' > +--- > +... > +X = {} > +--- > +... > +X.X = X > +--- > +... > +function X.fn(x,y) return y or x end > +--- > +... > +box.schema.user.grant('guest', 'execute', 'universe') > +--- > +... > +cn:close() > +--- > +... > +cn = remote.connect(LISTEN.host, LISTEN.service) > +--- > +... > +cn:call('X.fn', {u}) > +--- > +- 84F7BCFA-079C-46CC-98B4-F0C821BE833E > +... > +cn:call('X.X.X.X.X.X.X.fn', {u}) > +--- > +- 84F7BCFA-079C-46CC-98B4-F0C821BE833E > +... > +cn:call('X.X.X.X:fn', {u}) > +--- > +- 84F7BCFA-079C-46CC-98B4-F0C821BE833E > +... > +box.schema.user.revoke('guest', 'execute', 'universe') > +--- > +... > +cn:close() > +--- > +... > +-- auth > +cn = remote.connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123', wait_connected = true }) > +--- > +... > +cn:is_connected() > +--- > +- false > +... > +cn.error > +--- > +- User 'netbox' is not found > +... > +cn.state > +--- > +- error > +... > diff --git a/test/box/net.box_incorrect_iterator_gh-841.test.lua b/test/box/net.box_incorrect_iterator_gh-841.test.lua > new file mode 100644 > index 000000000..cd431a57a > --- /dev/null > +++ b/test/box/net.box_incorrect_iterator_gh-841.test.lua > @@ -0,0 +1,182 @@ > +remote = require 'net.box' > +fiber = require 'fiber' > +test_run = require('test_run').new() > +test_run:cmd("push filter ".."'\\.lua.*:[0-9]+: ' to '.lua...\"]:<line>: '") > + > +test_run:cmd("setopt delimiter ';'") > +function x_select(cn, space_id, index_id, iterator, offset, limit, key, opts) > + local ret = cn:_request('select', opts, nil, space_id, index_id, iterator, > + offset, limit, key) > + return ret > +end > +function x_fatal(cn) cn._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') end > +test_run:cmd("setopt delimiter ''"); > + > +LISTEN = require('uri').parse(box.cfg.listen) > +space = box.schema.space.create('net_box_test_space') > +index = space:create_index('primary', { type = 'tree' }) > + > +function test_foo(a,b,c) return { {{ [a] = 1 }}, {{ [b] = 2 }}, c } end > + > +box.schema.user.grant('guest', 'read,write', 'space', 'net_box_test_space') > +box.schema.user.grant('guest', 'execute', 'universe') > + > +cn = remote.connect(box.cfg.listen) > + > +x_select(cn, space.id, space.index.primary.id, box.index.EQ, 0, 0xFFFFFFFF, 123) > +space:insert{123, 345} > +x_select(cn, space.id, space.index.primary.id, box.index.EQ, 0, 0, 123) > +x_select(cn, space.id, space.index.primary.id, box.index.EQ, 0, 1, 123) > +x_select(cn, space.id, space.index.primary.id, box.index.EQ, 1, 1, 123) > + > +cn.space[space.id] ~= nil > +cn.space.net_box_test_space ~= nil > +cn.space.net_box_test_space ~= nil > +cn.space.net_box_test_space.index ~= nil > +cn.space.net_box_test_space.index.primary ~= nil > +cn.space.net_box_test_space.index[space.index.primary.id] ~= nil > + > + > +cn.space.net_box_test_space.index.primary:select(123) > +cn.space.net_box_test_space.index.primary:select(123, { limit = 0 }) > +cn.space.net_box_test_space.index.primary:select(nil, { limit = 1, }) > +cn.space.net_box_test_space:insert{234, 1,2,3} > +cn.space.net_box_test_space:insert{234, 1,2,3} > +cn.space.net_box_test_space.insert{234, 1,2,3} > + > +cn.space.net_box_test_space:replace{354, 1,2,3} > +cn.space.net_box_test_space:replace{354, 1,2,4} > + > +cn.space.net_box_test_space:select{123} > +space:select({123}, { iterator = 'GE' }) > +cn.space.net_box_test_space:select({123}, { iterator = 'GE' }) > +cn.space.net_box_test_space:select({123}, { iterator = 'GT' }) > +cn.space.net_box_test_space:select({123}, { iterator = 'GT', limit = 1 }) > +cn.space.net_box_test_space:select({123}, { iterator = 'GT', limit = 1, offset = 1 }) > + > +cn.space.net_box_test_space:select{123} > +cn.space.net_box_test_space:update({123}, { { '+', 2, 1 } }) > +cn.space.net_box_test_space:update(123, { { '+', 2, 1 } }) > +cn.space.net_box_test_space:select{123} > + > +cn.space.net_box_test_space:insert(cn.space.net_box_test_space:get{123}:update{ { '=', 1, 2 } }) > +cn.space.net_box_test_space:delete{123} > +cn.space.net_box_test_space:select{2} > +cn.space.net_box_test_space:select({234}, { iterator = 'LT' }) > + > +cn.space.net_box_test_space:update({1}, { { '+', 2, 2 } }) > + > +cn.space.net_box_test_space:delete{1} > +cn.space.net_box_test_space:delete{2} > +cn.space.net_box_test_space:delete{2} > + > +-- test one-based indexing in splice operation (see update.test.lua) > +cn.space.net_box_test_space:replace({10, 'abcde'}) > +cn.space.net_box_test_space:update(10, {{':', 2, 0, 0, '!'}}) > +cn.space.net_box_test_space:update(10, {{':', 2, 1, 0, '('}}) > +cn.space.net_box_test_space:update(10, {{':', 2, 2, 0, '({'}}) > +cn.space.net_box_test_space:update(10, {{':', 2, -1, 0, ')'}}) > +cn.space.net_box_test_space:update(10, {{':', 2, -2, 0, '})'}}) > +cn.space.net_box_test_space:delete{10} > + > +cn.space.net_box_test_space:select({}, { iterator = 'ALL' }) > +-- gh-841: net.box uses incorrect iterator type for select with no arguments > +cn.space.net_box_test_space:select() > + > +cn.space.net_box_test_space.index.primary:min() > +cn.space.net_box_test_space.index.primary:min(354) > +cn.space.net_box_test_space.index.primary:max() > +cn.space.net_box_test_space.index.primary:max(234) > +cn.space.net_box_test_space.index.primary:count() > +cn.space.net_box_test_space.index.primary:count(354) > + > +cn.space.net_box_test_space:get(354) > + > +-- reconnects after errors > + > +box.schema.user.revoke('guest', 'execute', 'universe') > +box.schema.func.create('test_foo') > +box.schema.user.grant('guest', 'execute', 'function', 'test_foo') > + > +-- -- 1. no reconnect > +x_fatal(cn) > +cn.state > +cn:ping() > +cn:call('test_foo') > +cn:wait_state('active') > + > +-- -- 2 reconnect > +cn = remote.connect(LISTEN.host, LISTEN.service, { reconnect_after = .1 }) > +cn.space ~= nil > + > +cn.space.net_box_test_space:select({}, { iterator = 'ALL' }) > +x_fatal(cn) > +cn:wait_connected() > +cn:wait_state('active') > +cn:wait_state({active=true}) > +cn:ping() > +cn.state > +cn.space.net_box_test_space:select({}, { iterator = 'ALL' }) > + > +x_fatal(cn) > +x_select(cn, space.id, 0, box.index.ALL, 0, 0xFFFFFFFF, {}) > + > +cn.state > +cn:ping() > + > +-- -- dot-new-method > + > +cn1 = remote.new(LISTEN.host, LISTEN.service) > +x_select(cn1, space.id, 0, box.index.ALL, 0, 0xFFFFFFF, {}) > +cn1:close() > +-- -- error while waiting for response > +type(fiber.create(function() fiber.sleep(.5) x_fatal(cn) end)) > +function pause() fiber.sleep(10) return true end > + > +box.schema.func.create('pause') > +box.schema.user.grant('guest', 'execute', 'function', 'pause') > +cn:call('pause') > +cn:call('test_foo', {'a', 'b', 'c'}) > +box.schema.func.drop('pause') > + > +-- call > +remote.self:call('test_foo', {'a', 'b', 'c'}) > +cn:call('test_foo', {'a', 'b', 'c'}) > +box.schema.func.drop('test_foo') > + > +box.schema.func.create('long_rep') > +box.schema.user.grant('guest', 'execute', 'function', 'long_rep') > + > +-- long replies > +function long_rep() return { 1, string.rep('a', 5000) } end > +res = cn:call('long_rep') > +res[1] == 1 > +res[2] == string.rep('a', 5000) > + > +function long_rep() return { 1, string.rep('a', 50000) } end > +res = cn:call('long_rep') > +res[1] == 1 > +res[2] == string.rep('a', 50000) > + > +box.schema.func.drop('long_rep') > + > +-- a.b.c.d > +u = '84F7BCFA-079C-46CC-98B4-F0C821BE833E' > +X = {} > +X.X = X > +function X.fn(x,y) return y or x end > +box.schema.user.grant('guest', 'execute', 'universe') > +cn:close() > +cn = remote.connect(LISTEN.host, LISTEN.service) > +cn:call('X.fn', {u}) > +cn:call('X.X.X.X.X.X.X.fn', {u}) > +cn:call('X.X.X.X:fn', {u}) > +box.schema.user.revoke('guest', 'execute', 'universe') > +cn:close() > + > +-- auth > + > +cn = remote.connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123', wait_connected = true }) > +cn:is_connected() > +cn.error > +cn.state > diff --git a/test/box/net.box_index_unique_flag_gh-4091.result b/test/box/net.box_index_unique_flag_gh-4091.result > new file mode 100644 > index 000000000..a72c32c74 > --- /dev/null > +++ b/test/box/net.box_index_unique_flag_gh-4091.result > @@ -0,0 +1,28 @@ > +net = require('net.box') > +--- > +... > +space = box.schema.space.create('test', {format={{name="id", type="unsigned"}}}) > +--- > +... > +_ = box.space.test:create_index('primary') > +--- > +... > +box.schema.user.grant('guest', 'read', 'space', 'test') > +--- > +... > +c = net.connect(box.cfg.listen) > +--- > +... > +-- > +-- gh-4091: index unique flag is always false. > +-- > +c.space.test.index.primary.unique > +--- > +- true > +... > +c:close() > +--- > +... > +space:drop() > +--- > +... > diff --git a/test/box/net.box_index_unique_flag_gh-4091.test.lua b/test/box/net.box_index_unique_flag_gh-4091.test.lua > new file mode 100644 > index 000000000..7027b1e33 > --- /dev/null > +++ b/test/box/net.box_index_unique_flag_gh-4091.test.lua > @@ -0,0 +1,15 @@ > +net = require('net.box') > + > +space = box.schema.space.create('test', {format={{name="id", type="unsigned"}}}) > +_ = box.space.test:create_index('primary') > +box.schema.user.grant('guest', 'read', 'space', 'test') > + > +c = net.connect(box.cfg.listen) > + > +-- > +-- gh-4091: index unique flag is always false. > +-- > +c.space.test.index.primary.unique > + > +c:close() > +space:drop() > diff --git a/test/box/net.box_iproto_hangs_gh-3464.result b/test/box/net.box_iproto_hangs_gh-3464.result > new file mode 100644 > index 000000000..d425bf78c > --- /dev/null > +++ b/test/box/net.box_iproto_hangs_gh-3464.result > @@ -0,0 +1,31 @@ > +msgpack = require 'msgpack' > +--- > +... > +test_run = require('test_run').new() > +--- > +... > +net = require('net.box') > +--- > +... > +-- > +-- gh-3464: iproto hangs in 100% CPU when too big packet size > +-- is received due to size_t overflow. > +-- > +c = net:connect(box.cfg.listen) > +--- > +... > +data = msgpack.encode(18400000000000000000)..'aaaaaaa' > +--- > +... > +c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, data) > +--- > +- null > +- Peer closed > +... > +c:close() > +--- > +... > +test_run:grep_log('default', 'too big packet size in the header') ~= nil > +--- > +- true > +... > diff --git a/test/box/net.box_iproto_hangs_gh-3464.test.lua b/test/box/net.box_iproto_hangs_gh-3464.test.lua > new file mode 100644 > index 000000000..77551e415 > --- /dev/null > +++ b/test/box/net.box_iproto_hangs_gh-3464.test.lua > @@ -0,0 +1,13 @@ > +msgpack = require 'msgpack' > +test_run = require('test_run').new() > +net = require('net.box') > + > +-- > +-- gh-3464: iproto hangs in 100% CPU when too big packet size > +-- is received due to size_t overflow. > +-- > +c = net:connect(box.cfg.listen) > +data = msgpack.encode(18400000000000000000)..'aaaaaaa' > +c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, data) > +c:close() > +test_run:grep_log('default', 'too big packet size in the header') ~= nil > diff --git a/test/box/net.box_is_nullable_gh-3256.result b/test/box/net.box_is_nullable_gh-3256.result > new file mode 100644 > index 000000000..5d6dc4b94 > --- /dev/null > +++ b/test/box/net.box_is_nullable_gh-3256.result > @@ -0,0 +1,97 @@ > +net = require('net.box') > +--- > +... > +-- > +-- gh-3256 net.box is_nullable and collation options output > +-- > +space = box.schema.create_space('test') > +--- > +... > +box.schema.user.grant('guest', 'read', 'space', 'test') > +--- > +... > +_ = space:create_index('pk') > +--- > +... > +_ = space:create_index('sk', {parts = {{2, 'unsigned', is_nullable = true}}}) > +--- > +... > +c = net:connect(box.cfg.listen) > +--- > +... > +c.space.test.index.sk.parts > +--- > +- - type: unsigned > + is_nullable: true > + fieldno: 2 > +... > +space:drop() > +--- > +... > +space = box.schema.create_space('test') > +--- > +... > +c:close() > +--- > +... > +box.schema.user.grant('guest', 'read', 'space', 'test') > +--- > +... > +c = net:connect(box.cfg.listen) > +--- > +... > +box.internal.collation.create('test', 'ICU', 'ru-RU') > +--- > +... > +collation_id = box.internal.collation.id_by_name('test') > +--- > +... > +_ = space:create_index('sk', { type = 'tree', parts = {{1, 'str', collation = 'test'}}, unique = true }) > +--- > +... > +c:reload_schema() > +--- > +... > +parts = c.space.test.index.sk.parts > +--- > +... > +#parts == 1 > +--- > +- true > +... > +parts[1].fieldno == 1 > +--- > +- true > +... > +parts[1].type == 'string' > +--- > +- true > +... > +parts[1].is_nullable == false > +--- > +- true > +... > +if _TARANTOOL >= '2.2.1' then \ > + return parts[1].collation == 'test' \ > +else \ > + return parts[1].collation_id == collation_id \ > +end > +--- > +- true > +... > +c:close() > +--- > +... > +box.internal.collation.drop('test') > +--- > +... > +space:drop() > +--- > +... > +c.state > +--- > +- closed > +... > +c = nil > +--- > +... > diff --git a/test/box/net.box_is_nullable_gh-3256.test.lua b/test/box/net.box_is_nullable_gh-3256.test.lua > new file mode 100644 > index 000000000..3c5ee3971 > --- /dev/null > +++ b/test/box/net.box_is_nullable_gh-3256.test.lua > @@ -0,0 +1,36 @@ > +net = require('net.box') > + > +-- > +-- gh-3256 net.box is_nullable and collation options output > +-- > +space = box.schema.create_space('test') > +box.schema.user.grant('guest', 'read', 'space', 'test') > +_ = space:create_index('pk') > +_ = space:create_index('sk', {parts = {{2, 'unsigned', is_nullable = true}}}) > +c = net:connect(box.cfg.listen) > +c.space.test.index.sk.parts > +space:drop() > + > +space = box.schema.create_space('test') > +c:close() > +box.schema.user.grant('guest', 'read', 'space', 'test') > +c = net:connect(box.cfg.listen) > +box.internal.collation.create('test', 'ICU', 'ru-RU') > +collation_id = box.internal.collation.id_by_name('test') > +_ = space:create_index('sk', { type = 'tree', parts = {{1, 'str', collation = 'test'}}, unique = true }) > +c:reload_schema() > +parts = c.space.test.index.sk.parts > +#parts == 1 > +parts[1].fieldno == 1 > +parts[1].type == 'string' > +parts[1].is_nullable == false > +if _TARANTOOL >= '2.2.1' then \ > + return parts[1].collation == 'test' \ > +else \ > + return parts[1].collation_id == collation_id \ > +end > +c:close() > +box.internal.collation.drop('test') > +space:drop() > +c.state > +c = nil > diff --git a/test/box/net.box_leaks_gh-3629.result b/test/box/net.box_leaks_gh-3629.result > new file mode 100644 > index 000000000..4c6688bf2 > --- /dev/null > +++ b/test/box/net.box_leaks_gh-3629.result > @@ -0,0 +1,51 @@ > +fiber = require 'fiber' > +--- > +... > +net = require('net.box') > +--- > +... > +-- > +-- gh-3629: netbox leaks when a connection is closed deliberately > +-- and it has non-finished requests. > +-- > +ready = false > +--- > +... > +ok = nil > +--- > +... > +err = nil > +--- > +... > +c = net:connect(box.cfg.listen) > +--- > +... > +function do_long() while not ready do fiber.sleep(0.01) end end > +--- > +... > +box.schema.func.create('do_long') > +--- > +... > +box.schema.user.grant('guest', 'execute', 'function', 'do_long') > +--- > +... > +f = fiber.create(function() ok, err = pcall(c.call, c, 'do_long') end) > +--- > +... > +while f:status() ~= 'suspended' do fiber.sleep(0.01) end > +--- > +... > +c:close() > +--- > +... > +ready = true > +--- > +... > +while not err do fiber.sleep(0.01) end > +--- > +... > +ok, err > +--- > +- false > +- Connection closed > +... > diff --git a/test/box/net.box_leaks_gh-3629.test.lua b/test/box/net.box_leaks_gh-3629.test.lua > new file mode 100644 > index 000000000..03b5a2327 > --- /dev/null > +++ b/test/box/net.box_leaks_gh-3629.test.lua > @@ -0,0 +1,20 @@ > +fiber = require 'fiber' > +net = require('net.box') > + > +-- > +-- gh-3629: netbox leaks when a connection is closed deliberately > +-- and it has non-finished requests. > +-- > +ready = false > +ok = nil > +err = nil > +c = net:connect(box.cfg.listen) > +function do_long() while not ready do fiber.sleep(0.01) end end > +box.schema.func.create('do_long') > +box.schema.user.grant('guest', 'execute', 'function', 'do_long') > +f = fiber.create(function() ok, err = pcall(c.call, c, 'do_long') end) > +while f:status() ~= 'suspended' do fiber.sleep(0.01) end > +c:close() > +ready = true > +while not err do fiber.sleep(0.01) end > +ok, err > diff --git a/test/box/net.box_log_corrupted_rows_gh-4040.result b/test/box/net.box_log_corrupted_rows_gh-4040.result > new file mode 100644 > index 000000000..603de0f13 > --- /dev/null > +++ b/test/box/net.box_log_corrupted_rows_gh-4040.result > @@ -0,0 +1,72 @@ > +test_run = require('test_run').new() > +--- > +... > +socket = require('socket'); > +--- > +... > +LISTEN = require('uri').parse(box.cfg.listen) > +--- > +... > +test_run:cmd('create server connecter with script = "box/proxy.lua"') > +--- > +- true > +... > +-- > +-- related to gh-4040: log corrupted rows > +-- > +log_level = box.cfg.log_level > +--- > +... > +box.cfg{log_level=6} > +--- > +... > +sock = socket.tcp_connect(LISTEN.host, LISTEN.service) > +--- > +... > +sock:read(9) > +--- > +- Tarantool > +... > +-- we need to have a packet with correctly encoded length, > +-- so that it bypasses iproto length check, but cannot be > +-- decoded in xrow_header_decode > +-- 0x3C = 60, sha1 digest is 20 bytes long > +data = string.fromhex('3C'..string.rep(require('digest').sha1_hex('bcde'), 3)) > +--- > +... > +sock:write(data) > +--- > +- 61 > +... > +sock:close() > +--- > +- true > +... > +test_run:wait_log('default', 'Got a corrupted row.*', nil, 10) > +--- > +- 'Got a corrupted row:' > +... > +test_run:wait_log('default', '00000000:.*', nil, 10) > +--- > +- '00000000: A3 02 D6 5A E4 D9 E7 68 A1 53 8D 53 60 5F 20 3F ' > +... > +test_run:wait_log('default', '00000010:.*', nil, 10) > +--- > +- '00000010: D8 E2 D6 E2 A3 02 D6 5A E4 D9 E7 68 A1 53 8D 53 ' > +... > +test_run:wait_log('default', '00000020:.*', nil, 10) > +--- > +- '00000020: 60 5F 20 3F D8 E2 D6 E2 A3 02 D6 5A E4 D9 E7 68 ' > +... > +test_run:wait_log('default', '00000030:.*', nil, 10) > +--- > +- '00000030: A1 53 8D 53 60 5F 20 3F D8 E2 D6 E2 ' > +... > +-- we expect nothing below, so don't wait > +test_run:grep_log('default', '00000040:.*') > +--- > +- null > +... > +box.cfg{log_level=log_level} > +--- > +... > diff --git a/test/box/net.box_log_corrupted_rows_gh-4040.test.lua b/test/box/net.box_log_corrupted_rows_gh-4040.test.lua > new file mode 100644 > index 000000000..a30b4a254 > --- /dev/null > +++ b/test/box/net.box_log_corrupted_rows_gh-4040.test.lua > @@ -0,0 +1,31 @@ > +test_run = require('test_run').new() > +socket = require('socket'); > + > +LISTEN = require('uri').parse(box.cfg.listen) > + > +test_run:cmd('create server connecter with script = "box/proxy.lua"') > + > +-- > +-- related to gh-4040: log corrupted rows > +-- > +log_level = box.cfg.log_level > +box.cfg{log_level=6} > +sock = socket.tcp_connect(LISTEN.host, LISTEN.service) > +sock:read(9) > +-- we need to have a packet with correctly encoded length, > +-- so that it bypasses iproto length check, but cannot be > +-- decoded in xrow_header_decode > +-- 0x3C = 60, sha1 digest is 20 bytes long > +data = string.fromhex('3C'..string.rep(require('digest').sha1_hex('bcde'), 3)) > +sock:write(data) > +sock:close() > + > +test_run:wait_log('default', 'Got a corrupted row.*', nil, 10) > +test_run:wait_log('default', '00000000:.*', nil, 10) > +test_run:wait_log('default', '00000010:.*', nil, 10) > +test_run:wait_log('default', '00000020:.*', nil, 10) > +test_run:wait_log('default', '00000030:.*', nil, 10) > +-- we expect nothing below, so don't wait > +test_run:grep_log('default', '00000040:.*') > + > +box.cfg{log_level=log_level} > diff --git a/test/box/net.box_long-poll_input_gh-3400.result b/test/box/net.box_long-poll_input_gh-3400.result > new file mode 100644 > index 000000000..062bd563a > --- /dev/null > +++ b/test/box/net.box_long-poll_input_gh-3400.result > @@ -0,0 +1,35 @@ > +fiber = require 'fiber' > +--- > +... > +net = require('net.box') > +--- > +... > +-- > +-- gh-3400: long-poll input discard must not touch event loop of > +-- a closed connection. > +-- > +function long() fiber.yield() return 100 end > +--- > +... > +c = net.connect(box.cfg.listen) > +--- > +... > +c:ping() > +--- > +- true > +... > +-- Create batch of two requests. First request is sent to TX > +-- thread, second one terminates connection. The preceeding > +-- request discards input, and this operation must not trigger > +-- new attempts to read any data - the connection is closed > +-- already. > +-- > +f = fiber.create(c._transport.perform_request, nil, nil, false, 'call_17', nil, nil, nil, 'long', {}) c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') > +--- > +... > +while f:status() ~= 'dead' do fiber.sleep(0.01) end > +--- > +... > +c:close() > +--- > +... > diff --git a/test/box/net.box_long-poll_input_gh-3400.test.lua b/test/box/net.box_long-poll_input_gh-3400.test.lua > new file mode 100644 > index 000000000..bc9db1e69 > --- /dev/null > +++ b/test/box/net.box_long-poll_input_gh-3400.test.lua > @@ -0,0 +1,19 @@ > +fiber = require 'fiber' > +net = require('net.box') > + > +-- > +-- gh-3400: long-poll input discard must not touch event loop of > +-- a closed connection. > +-- > +function long() fiber.yield() return 100 end > +c = net.connect(box.cfg.listen) > +c:ping() > +-- Create batch of two requests. First request is sent to TX > +-- thread, second one terminates connection. The preceeding > +-- request discards input, and this operation must not trigger > +-- new attempts to read any data - the connection is closed > +-- already. > +-- > +f = fiber.create(c._transport.perform_request, nil, nil, false, 'call_17', nil, nil, nil, 'long', {}) c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') > +while f:status() ~= 'dead' do fiber.sleep(0.01) end > +c:close() > diff --git a/test/box/net.box_methods_gh-3107.result b/test/box/net.box_methods_gh-3107.result > new file mode 100644 > index 000000000..8ff69ebd6 > --- /dev/null > +++ b/test/box/net.box_methods_gh-3107.result > @@ -0,0 +1,277 @@ > +fiber = require 'fiber' > +--- > +... > +net = require('net.box') > +--- > +... > +-- > +-- gh-3107: fiber-async netbox. > +-- > +cond = nil > +--- > +... > +box.schema.func.create('long_function') > +--- > +... > +box.schema.user.grant('guest', 'execute', 'function', 'long_function') > +--- > +... > +function long_function(...) cond = fiber.cond() cond:wait() return ... end > +--- > +... > +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end > +--- > +... > +s = box.schema.create_space('test') > +--- > +... > +pk = s:create_index('pk') > +--- > +... > +s:replace{1} > +--- > +- [1] > +... > +s:replace{2} > +--- > +- [2] > +... > +s:replace{3} > +--- > +- [3] > +... > +s:replace{4} > +--- > +- [4] > +... > +c = net:connect(box.cfg.listen) > +--- > +... > +-- > +-- Ensure a request can be finalized from non-caller fibers. > +-- > +future = c:call('long_function', {1, 2, 3}, {is_async = true}) > +--- > +... > +ret = {} > +--- > +... > +count = 0 > +--- > +... > +for i = 1, 10 do fiber.create(function() ret[i] = future:wait_result(1000) count = count + 1 end) end > +--- > +... > +future:wait_result(0.01) -- Must fail on timeout. > +--- > +- null > +- Timeout exceeded > +... > +finalize_long() > +--- > +... > +while count ~= 10 do fiber.sleep(0.1) end > +--- > +... > +ret > +--- > +- - &0 [1, 2, 3] > + - *0 > + - *0 > + - *0 > + - *0 > + - *0 > + - *0 > + - *0 > + - *0 > + - *0 > +... > +-- > +-- Test space methods. > +-- > +c:close() > +--- > +... > +box.schema.user.grant('guest', 'read,write', 'space', 'test') > +--- > +... > +c = net:connect(box.cfg.listen) > +--- > +... > +future = c.space.test:select({1}, {is_async = true}) > +--- > +... > +ret = future:wait_result(100) > +--- > +... > +ret > +--- > +- - [1] > +... > +type(ret[1]) > +--- > +- cdata > +... > +future = c.space.test:insert({5}, {is_async = true}) > +--- > +... > +future:wait_result(100) > +--- > +- [5] > +... > +s:get{5} > +--- > +- [5] > +... > +future = c.space.test:replace({6}, {is_async = true}) > +--- > +... > +future:wait_result(100) > +--- > +- [6] > +... > +s:get{6} > +--- > +- [6] > +... > +future = c.space.test:delete({6}, {is_async = true}) > +--- > +... > +future:wait_result(100) > +--- > +- [6] > +... > +s:get{6} > +--- > +... > +future = c.space.test:update({5}, {{'=', 2, 5}}, {is_async = true}) > +--- > +... > +future:wait_result(100) > +--- > +- [5, 5] > +... > +s:get{5} > +--- > +- [5, 5] > +... > +future = c.space.test:upsert({5}, {{'=', 2, 6}}, {is_async = true}) > +--- > +... > +future:wait_result(100) > +--- > +- null > +... > +s:get{5} > +--- > +- [5, 6] > +... > +future = c.space.test:get({5}, {is_async = true}) > +--- > +... > +future:wait_result(100) > +--- > +- [5, 6] > +... > +-- > +-- Test index methods. > +-- > +future = c.space.test.index.pk:select({1}, {is_async = true}) > +--- > +... > +future:wait_result(100) > +--- > +- - [1] > +... > +future = c.space.test.index.pk:get({2}, {is_async = true}) > +--- > +... > +future:wait_result(100) > +--- > +- [2] > +... > +future = c.space.test.index.pk:min({}, {is_async = true}) > +--- > +... > +future:wait_result(100) > +--- > +- [1] > +... > +future = c.space.test.index.pk:max({}, {is_async = true}) > +--- > +... > +future:wait_result(100) > +--- > +- [5, 6] > +... > +c:close() > +--- > +... > +box.schema.user.grant('guest', 'execute', 'universe') > +--- > +... > +c = net:connect(box.cfg.listen) > +--- > +... > +future = c.space.test.index.pk:count({3}, {is_async = true}) > +--- > +... > +future:wait_result(100) > +--- > +- 1 > +... > +c:close() > +--- > +... > +box.schema.user.revoke('guest', 'execute', 'universe') > +--- > +... > +c = net:connect(box.cfg.listen) > +--- > +... > +future = c.space.test.index.pk:delete({3}, {is_async = true}) > +--- > +... > +future:wait_result(100) > +--- > +- [3] > +... > +s:get{3} > +--- > +... > +future = c.space.test.index.pk:update({4}, {{'=', 2, 6}}, {is_async = true}) > +--- > +... > +future:wait_result(100) > +--- > +- [4, 6] > +... > +s:get{4} > +--- > +- [4, 6] > +... > +-- > +-- Test async errors. > +-- > +future = c.space.test:insert({1}, {is_async = true}) > +--- > +... > +future:wait_result() > +--- > +- null > +- Duplicate key exists in unique index 'pk' in space 'test' > +... > +future:result() > +--- > +- null > +- Duplicate key exists in unique index 'pk' in space 'test' > +... > +box.schema.func.drop('long_function') > +--- > +... > +c:close() > +--- > +... > +s:drop() > +--- > +... > diff --git a/test/box/net.box_methods_gh-3107.test.lua b/test/box/net.box_methods_gh-3107.test.lua > new file mode 100644 > index 000000000..364a72ed3 > --- /dev/null > +++ b/test/box/net.box_methods_gh-3107.test.lua > @@ -0,0 +1,96 @@ > +fiber = require 'fiber' > +net = require('net.box') > + > +-- > +-- gh-3107: fiber-async netbox. > +-- > +cond = nil > +box.schema.func.create('long_function') > +box.schema.user.grant('guest', 'execute', 'function', 'long_function') > +function long_function(...) cond = fiber.cond() cond:wait() return ... end > +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end > +s = box.schema.create_space('test') > +pk = s:create_index('pk') > +s:replace{1} > +s:replace{2} > +s:replace{3} > +s:replace{4} > +c = net:connect(box.cfg.listen) > + > +-- > +-- Ensure a request can be finalized from non-caller fibers. > +-- > +future = c:call('long_function', {1, 2, 3}, {is_async = true}) > +ret = {} > +count = 0 > +for i = 1, 10 do fiber.create(function() ret[i] = future:wait_result(1000) count = count + 1 end) end > +future:wait_result(0.01) -- Must fail on timeout. > +finalize_long() > +while count ~= 10 do fiber.sleep(0.1) end > +ret > + > +-- > +-- Test space methods. > +-- > +c:close() > +box.schema.user.grant('guest', 'read,write', 'space', 'test') > +c = net:connect(box.cfg.listen) > +future = c.space.test:select({1}, {is_async = true}) > +ret = future:wait_result(100) > +ret > +type(ret[1]) > +future = c.space.test:insert({5}, {is_async = true}) > +future:wait_result(100) > +s:get{5} > +future = c.space.test:replace({6}, {is_async = true}) > +future:wait_result(100) > +s:get{6} > +future = c.space.test:delete({6}, {is_async = true}) > +future:wait_result(100) > +s:get{6} > +future = c.space.test:update({5}, {{'=', 2, 5}}, {is_async = true}) > +future:wait_result(100) > +s:get{5} > +future = c.space.test:upsert({5}, {{'=', 2, 6}}, {is_async = true}) > +future:wait_result(100) > +s:get{5} > +future = c.space.test:get({5}, {is_async = true}) > +future:wait_result(100) > + > +-- > +-- Test index methods. > +-- > +future = c.space.test.index.pk:select({1}, {is_async = true}) > +future:wait_result(100) > +future = c.space.test.index.pk:get({2}, {is_async = true}) > +future:wait_result(100) > +future = c.space.test.index.pk:min({}, {is_async = true}) > +future:wait_result(100) > +future = c.space.test.index.pk:max({}, {is_async = true}) > +future:wait_result(100) > +c:close() > +box.schema.user.grant('guest', 'execute', 'universe') > +c = net:connect(box.cfg.listen) > +future = c.space.test.index.pk:count({3}, {is_async = true}) > +future:wait_result(100) > +c:close() > +box.schema.user.revoke('guest', 'execute', 'universe') > +c = net:connect(box.cfg.listen) > +future = c.space.test.index.pk:delete({3}, {is_async = true}) > +future:wait_result(100) > +s:get{3} > +future = c.space.test.index.pk:update({4}, {{'=', 2, 6}}, {is_async = true}) > +future:wait_result(100) > +s:get{4} > + > +-- > +-- Test async errors. > +-- > +future = c.space.test:insert({1}, {is_async = true}) > +future:wait_result() > +future:result() > + > +box.schema.func.drop('long_function') > + > +c:close() > +s:drop() > diff --git a/test/box/net.box_msgpack_gh-2195.result b/test/box/net.box_msgpack_gh-2195.result > new file mode 100644 > index 000000000..a4c851334 > --- /dev/null > +++ b/test/box/net.box_msgpack_gh-2195.result > @@ -0,0 +1,527 @@ > +msgpack = require 'msgpack' > +--- > +... > +test_run = require('test_run').new() > +--- > +... > +test_run:cmd("push filter ".."'\\.lua.*:[0-9]+: ' to '.lua...\"]:<line>: '") > +--- > +- true > +... > +net = require('net.box') > +--- > +... > +-- CALL vs CALL_16 in connect options > +function echo(...) return ... end > +--- > +... > +box.schema.user.grant('guest', 'execute', 'universe') > +--- > +... > +c = net.connect(box.cfg.listen) > +--- > +... > +c:call('echo', {42}) > +--- > +- 42 > +... > +c:eval('return echo(...)', {42}) > +--- > +- 42 > +... > +-- invalid arguments > +c:call('echo', 42) > +--- > +- error: 'builtin/box/net_box.lua..."]:<line>: Use remote:call(func_name, {arg1, arg2, ...}, > + opts) instead of remote:call(func_name, arg1, arg2, ...)' > +... > +c:eval('return echo(...)', 42) > +--- > +- error: 'builtin/box/net_box.lua..."]:<line>: Use remote:eval(expression, {arg1, arg2, ...}, > + opts) instead of remote:eval(expression, arg1, arg2, ...)' > +... > +c:close() > +--- > +... > +c = net.connect(box.cfg.listen, {call_16 = true}) > +--- > +... > +c:call('echo', 42) > +--- > +- - [42] > +... > +c:eval('return echo(...)', 42) > +--- > +- 42 > +... > +c:close() > +--- > +... > +box.schema.user.revoke('guest', 'execute', 'universe') > +--- > +... > +-- > +-- gh-2195 export pure msgpack from net.box > +-- > +space = box.schema.space.create('test') > +--- > +... > +_ = box.space.test:create_index('primary') > +--- > +... > +box.schema.user.grant('guest', 'read,write', 'space', 'test') > +--- > +... > +box.schema.user.grant('guest', 'execute', 'universe') > +--- > +... > +c = net.connect(box.cfg.listen) > +--- > +... > +ibuf = require('buffer').ibuf() > +--- > +... > +c:ping() > +--- > +- true > +... > +c.space.test ~= nil > +--- > +- true > +... > +c.space.test:replace({1, 'hello'}) > +--- > +- [1, 'hello'] > +... > +-- replace > +c.space.test:replace({2}, {buffer = ibuf}) > +--- > +- 9 > +... > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +--- > +... > +result > +--- > +- {48: [[2]]} > +... > +-- replace + skip_header > +c.space.test:replace({2}, {buffer = ibuf, skip_header = true}) > +--- > +- 7 > +... > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +--- > +... > +result > +--- > +- [[2]] > +... > +-- insert > +c.space.test:insert({3}, {buffer = ibuf}) > +--- > +- 9 > +... > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +--- > +... > +result > +--- > +- {48: [[3]]} > +... > +-- insert + skip_header > +_ = space:delete({3}) > +--- > +... > +c.space.test:insert({3}, {buffer = ibuf, skip_header = true}) > +--- > +- 7 > +... > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +--- > +... > +result > +--- > +- [[3]] > +... > +-- update > +c.space.test:update({3}, {}, {buffer = ibuf}) > +--- > +- 9 > +... > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +--- > +... > +result > +--- > +- {48: [[3]]} > +... > +c.space.test.index.primary:update({3}, {}, {buffer = ibuf}) > +--- > +- 9 > +... > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +--- > +... > +result > +--- > +- {48: [[3]]} > +... > +-- update + skip_header > +c.space.test:update({3}, {}, {buffer = ibuf, skip_header = true}) > +--- > +- 7 > +... > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +--- > +... > +result > +--- > +- [[3]] > +... > +c.space.test.index.primary:update({3}, {}, {buffer = ibuf, skip_header = true}) > +--- > +- 7 > +... > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +--- > +... > +result > +--- > +- [[3]] > +... > +-- upsert > +c.space.test:upsert({4}, {}, {buffer = ibuf}) > +--- > +- 7 > +... > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +--- > +... > +result > +--- > +- {48: []} > +... > +-- upsert + skip_header > +c.space.test:upsert({4}, {}, {buffer = ibuf, skip_header = true}) > +--- > +- 5 > +... > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +--- > +... > +result > +--- > +- [] > +... > +-- delete > +c.space.test:upsert({4}, {}, {buffer = ibuf}) > +--- > +- 7 > +... > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +--- > +... > +result > +--- > +- {48: []} > +... > +-- delete + skip_header > +c.space.test:upsert({4}, {}, {buffer = ibuf, skip_header = true}) > +--- > +- 5 > +... > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +--- > +... > +result > +--- > +- [] > +... > +-- select > +c.space.test.index.primary:select({3}, {iterator = 'LE', buffer = ibuf}) > +--- > +- 19 > +... > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +--- > +... > +result > +--- > +- {48: [[3], [2], [1, 'hello']]} > +... > +-- select + skip_header > +c.space.test.index.primary:select({3}, {iterator = 'LE', buffer = ibuf, skip_header = true}) > +--- > +- 17 > +... > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +--- > +... > +result > +--- > +- [[3], [2], [1, 'hello']] > +... > +-- select > +len = c.space.test:select({}, {buffer = ibuf}) > +--- > +... > +ibuf.rpos + len == ibuf.wpos > +--- > +- true > +... > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +--- > +... > +ibuf.rpos == ibuf.wpos > +--- > +- true > +... > +len > +--- > +- 21 > +... > +result > +--- > +- {48: [[1, 'hello'], [2], [3], [4]]} > +... > +-- select + skip_header > +len = c.space.test:select({}, {buffer = ibuf, skip_header = true}) > +--- > +... > +ibuf.rpos + len == ibuf.wpos > +--- > +- true > +... > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +--- > +... > +ibuf.rpos == ibuf.wpos > +--- > +- true > +... > +len > +--- > +- 19 > +... > +result > +--- > +- [[1, 'hello'], [2], [3], [4]] > +... > +-- call > +c:call("echo", {1, 2, 3}, {buffer = ibuf}) > +--- > +- 10 > +... > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +--- > +... > +result > +--- > +- {48: [1, 2, 3]} > +... > +c:call("echo", {}, {buffer = ibuf}) > +--- > +- 7 > +... > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +--- > +... > +result > +--- > +- {48: []} > +... > +c:call("echo", nil, {buffer = ibuf}) > +--- > +- 7 > +... > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +--- > +... > +result > +--- > +- {48: []} > +... > +-- call + skip_header > +c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > +--- > +- 8 > +... > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +--- > +... > +result > +--- > +- [1, 2, 3] > +... > +c:call("echo", {}, {buffer = ibuf, skip_header = true}) > +--- > +- 5 > +... > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +--- > +... > +result > +--- > +- [] > +... > +c:call("echo", nil, {buffer = ibuf, skip_header = true}) > +--- > +- 5 > +... > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +--- > +... > +result > +--- > +- [] > +... > +-- eval > +c:eval("echo(...)", {1, 2, 3}, {buffer = ibuf}) > +--- > +- 7 > +... > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +--- > +... > +result > +--- > +- {48: []} > +... > +c:eval("echo(...)", {}, {buffer = ibuf}) > +--- > +- 7 > +... > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +--- > +... > +result > +--- > +- {48: []} > +... > +c:eval("echo(...)", nil, {buffer = ibuf}) > +--- > +- 7 > +... > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +--- > +... > +result > +--- > +- {48: []} > +... > +-- eval + skip_header > +c:eval("echo(...)", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > +--- > +- 5 > +... > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +--- > +... > +result > +--- > +- [] > +... > +c:eval("echo(...)", {}, {buffer = ibuf, skip_header = true}) > +--- > +- 5 > +... > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +--- > +... > +result > +--- > +- [] > +... > +c:eval("echo(...)", nil, {buffer = ibuf, skip_header = true}) > +--- > +- 5 > +... > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +--- > +... > +result > +--- > +- [] > +... > +-- make several request into a buffer with skip_header, then read > +-- results > +c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > +--- > +- 8 > +... > +c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > +--- > +- 8 > +... > +c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > +--- > +- 8 > +... > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +--- > +... > +result > +--- > +- [1, 2, 3] > +... > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +--- > +... > +result > +--- > +- [1, 2, 3] > +... > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +--- > +... > +result > +--- > +- [1, 2, 3] > +... > +-- unsupported methods > +c.space.test:get({1}, { buffer = ibuf}) > +--- > +- error: 'builtin/box/net_box.lua..."]:<line>: index:get() doesn''t support `buffer` argument' > +... > +c.space.test.index.primary:min({}, { buffer = ibuf}) > +--- > +- error: 'builtin/box/net_box.lua..."]:<line>: index:min() doesn''t support `buffer` argument' > +... > +c.space.test.index.primary:max({}, { buffer = ibuf}) > +--- > +- error: 'builtin/box/net_box.lua..."]:<line>: index:max() doesn''t support `buffer` argument' > +... > +c.space.test.index.primary:count({}, { buffer = ibuf}) > +--- > +- error: 'builtin/box/net_box.lua..."]:<line>: index:count() doesn''t support `buffer` argument' > +... > +c.space.test.index.primary:get({1}, { buffer = ibuf}) > +--- > +- error: 'builtin/box/net_box.lua..."]:<line>: index:get() doesn''t support `buffer` argument' > +... > +-- error handling > +rpos, wpos = ibuf.rpos, ibuf.wpos > +--- > +... > +c.space.test:insert({1}, {buffer = ibuf}) > +--- > +- error: Duplicate key exists in unique index 'primary' in space 'test' > +... > +ibuf.rpos == rpos, ibuf.wpos == wpos > +--- > +- true > +- true > +... > +ibuf = nil > +--- > +... > +c:close() > +--- > +... > +space:drop() > +--- > +... > +box.schema.user.revoke('guest', 'execute', 'universe') > +--- > +... > diff --git a/test/box/net.box_msgpack_gh-2195.test.lua b/test/box/net.box_msgpack_gh-2195.test.lua > new file mode 100644 > index 000000000..8c14b4b43 > --- /dev/null > +++ b/test/box/net.box_msgpack_gh-2195.test.lua > @@ -0,0 +1,192 @@ > +msgpack = require 'msgpack' > +test_run = require('test_run').new() > +test_run:cmd("push filter ".."'\\.lua.*:[0-9]+: ' to '.lua...\"]:<line>: '") > +net = require('net.box') > + > +-- CALL vs CALL_16 in connect options > +function echo(...) return ... end > +box.schema.user.grant('guest', 'execute', 'universe') > +c = net.connect(box.cfg.listen) > +c:call('echo', {42}) > +c:eval('return echo(...)', {42}) > +-- invalid arguments > +c:call('echo', 42) > +c:eval('return echo(...)', 42) > +c:close() > +c = net.connect(box.cfg.listen, {call_16 = true}) > +c:call('echo', 42) > +c:eval('return echo(...)', 42) > +c:close() > +box.schema.user.revoke('guest', 'execute', 'universe') > + > +-- > +-- gh-2195 export pure msgpack from net.box > +-- > + > +space = box.schema.space.create('test') > +_ = box.space.test:create_index('primary') > +box.schema.user.grant('guest', 'read,write', 'space', 'test') > +box.schema.user.grant('guest', 'execute', 'universe') > +c = net.connect(box.cfg.listen) > +ibuf = require('buffer').ibuf() > + > +c:ping() > +c.space.test ~= nil > + > +c.space.test:replace({1, 'hello'}) > + > +-- replace > +c.space.test:replace({2}, {buffer = ibuf}) > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +result > + > +-- replace + skip_header > +c.space.test:replace({2}, {buffer = ibuf, skip_header = true}) > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +result > + > +-- insert > +c.space.test:insert({3}, {buffer = ibuf}) > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +result > + > +-- insert + skip_header > +_ = space:delete({3}) > +c.space.test:insert({3}, {buffer = ibuf, skip_header = true}) > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +result > + > +-- update > +c.space.test:update({3}, {}, {buffer = ibuf}) > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +result > +c.space.test.index.primary:update({3}, {}, {buffer = ibuf}) > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +result > + > +-- update + skip_header > +c.space.test:update({3}, {}, {buffer = ibuf, skip_header = true}) > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +result > +c.space.test.index.primary:update({3}, {}, {buffer = ibuf, skip_header = true}) > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +result > + > +-- upsert > +c.space.test:upsert({4}, {}, {buffer = ibuf}) > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +result > + > +-- upsert + skip_header > +c.space.test:upsert({4}, {}, {buffer = ibuf, skip_header = true}) > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +result > + > +-- delete > +c.space.test:upsert({4}, {}, {buffer = ibuf}) > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +result > + > +-- delete + skip_header > +c.space.test:upsert({4}, {}, {buffer = ibuf, skip_header = true}) > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +result > + > +-- select > +c.space.test.index.primary:select({3}, {iterator = 'LE', buffer = ibuf}) > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +result > + > +-- select + skip_header > +c.space.test.index.primary:select({3}, {iterator = 'LE', buffer = ibuf, skip_header = true}) > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +result > + > +-- select > +len = c.space.test:select({}, {buffer = ibuf}) > +ibuf.rpos + len == ibuf.wpos > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +ibuf.rpos == ibuf.wpos > +len > +result > + > +-- select + skip_header > +len = c.space.test:select({}, {buffer = ibuf, skip_header = true}) > +ibuf.rpos + len == ibuf.wpos > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +ibuf.rpos == ibuf.wpos > +len > +result > + > +-- call > +c:call("echo", {1, 2, 3}, {buffer = ibuf}) > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +result > +c:call("echo", {}, {buffer = ibuf}) > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +result > +c:call("echo", nil, {buffer = ibuf}) > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +result > + > +-- call + skip_header > +c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +result > +c:call("echo", {}, {buffer = ibuf, skip_header = true}) > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +result > +c:call("echo", nil, {buffer = ibuf, skip_header = true}) > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +result > + > +-- eval > +c:eval("echo(...)", {1, 2, 3}, {buffer = ibuf}) > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +result > +c:eval("echo(...)", {}, {buffer = ibuf}) > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +result > +c:eval("echo(...)", nil, {buffer = ibuf}) > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +result > + > +-- eval + skip_header > +c:eval("echo(...)", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +result > +c:eval("echo(...)", {}, {buffer = ibuf, skip_header = true}) > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +result > +c:eval("echo(...)", nil, {buffer = ibuf, skip_header = true}) > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +result > + > +-- make several request into a buffer with skip_header, then read > +-- results > +c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > +c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > +c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +result > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +result > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +result > + > +-- unsupported methods > +c.space.test:get({1}, { buffer = ibuf}) > +c.space.test.index.primary:min({}, { buffer = ibuf}) > +c.space.test.index.primary:max({}, { buffer = ibuf}) > +c.space.test.index.primary:count({}, { buffer = ibuf}) > +c.space.test.index.primary:get({1}, { buffer = ibuf}) > + > +-- error handling > +rpos, wpos = ibuf.rpos, ibuf.wpos > +c.space.test:insert({1}, {buffer = ibuf}) > +ibuf.rpos == rpos, ibuf.wpos == wpos > + > +ibuf = nil > +c:close() > +space:drop() > +box.schema.user.revoke('guest', 'execute', 'universe') > diff --git a/test/box/net.box_on_schema_reload-gh-1904.result b/test/box/net.box_on_schema_reload-gh-1904.result > new file mode 100644 > index 000000000..5029684bf > --- /dev/null > +++ b/test/box/net.box_on_schema_reload-gh-1904.result > @@ -0,0 +1,102 @@ > +fiber = require 'fiber' > +--- > +... > +test_run = require('test_run').new() > +--- > +... > +LISTEN = require('uri').parse(box.cfg.listen) > +--- > +... > +space = box.schema.space.create('net_box_test_space') > +--- > +... > +index = space:create_index('primary', { type = 'tree' }) > +--- > +... > +box.schema.user.create('netbox', { password = 'test' }) > +--- > +... > +box.schema.user.grant('netbox', 'read,write', 'space', 'net_box_test_space') > +--- > +... > +box.schema.user.grant('netbox', 'execute', 'universe') > +--- > +... > +net = require('net.box') > +--- > +... > +-- gh-1904 net.box hangs in :close() if a fiber was cancelled > +-- while blocked in :_wait_state() in :_request() > +options = {user = 'netbox', password = 'badpass', wait_connected = false, reconnect_after = 0.01} > +--- > +... > +c = net:new(box.cfg.listen, options) > +--- > +... > +f = fiber.create(function() c:call("") end) > +--- > +... > +fiber.sleep(0.01) > +--- > +... > +f:cancel(); c:close() > +--- > +... > +box.schema.user.grant('guest', 'read', 'space', '_schema') > +--- > +... > +-- check for on_schema_reload callback > +test_run:cmd("setopt delimiter ';'") > +--- > +- true > +... > +do > + local a = 0 > + function osr_cb() > + a = a + 1 > + end > + local con = net.new(box.cfg.listen, { > + wait_connected = false > + }) > + con:on_schema_reload(osr_cb) > + con:wait_connected() > + con.space._schema:select{} > + box.schema.space.create('misisipi') > + box.space.misisipi:drop() > + con.space._schema:select{} > + con:close() > + con = nil > + > + return a > +end; > +--- > +- 2 > +... > +do > + local a = 0 > + function osr_cb() > + a = a + 1 > + end > + local con = net.new(box.cfg.listen, { > + wait_connected = true > + }) > + con:on_schema_reload(osr_cb) > + con.space._schema:select{} > + box.schema.space.create('misisipi') > + box.space.misisipi:drop() > + con.space._schema:select{} > + con:close() > + con = nil > + > + return a > +end; > +--- > +- 1 > +... > +test_run:cmd("setopt delimiter ''"); > +--- > +- true > +... > +box.schema.user.revoke('guest', 'read', 'space', '_schema') > +--- > +... > diff --git a/test/box/net.box_on_schema_reload-gh-1904.test.lua b/test/box/net.box_on_schema_reload-gh-1904.test.lua > new file mode 100644 > index 000000000..eeb9def65 > --- /dev/null > +++ b/test/box/net.box_on_schema_reload-gh-1904.test.lua > @@ -0,0 +1,65 @@ > +fiber = require 'fiber' > +test_run = require('test_run').new() > + > +LISTEN = require('uri').parse(box.cfg.listen) > +space = box.schema.space.create('net_box_test_space') > +index = space:create_index('primary', { type = 'tree' }) > + > +box.schema.user.create('netbox', { password = 'test' }) > +box.schema.user.grant('netbox', 'read,write', 'space', 'net_box_test_space') > +box.schema.user.grant('netbox', 'execute', 'universe') > + > +net = require('net.box') > + > +-- gh-1904 net.box hangs in :close() if a fiber was cancelled > +-- while blocked in :_wait_state() in :_request() > +options = {user = 'netbox', password = 'badpass', wait_connected = false, reconnect_after = 0.01} > +c = net:new(box.cfg.listen, options) > +f = fiber.create(function() c:call("") end) > +fiber.sleep(0.01) > +f:cancel(); c:close() > + > +box.schema.user.grant('guest', 'read', 'space', '_schema') > + > +-- check for on_schema_reload callback > +test_run:cmd("setopt delimiter ';'") > +do > + local a = 0 > + function osr_cb() > + a = a + 1 > + end > + local con = net.new(box.cfg.listen, { > + wait_connected = false > + }) > + con:on_schema_reload(osr_cb) > + con:wait_connected() > + con.space._schema:select{} > + box.schema.space.create('misisipi') > + box.space.misisipi:drop() > + con.space._schema:select{} > + con:close() > + con = nil > + > + return a > +end; > +do > + local a = 0 > + function osr_cb() > + a = a + 1 > + end > + local con = net.new(box.cfg.listen, { > + wait_connected = true > + }) > + con:on_schema_reload(osr_cb) > + con.space._schema:select{} > + box.schema.space.create('misisipi') > + box.space.misisipi:drop() > + con.space._schema:select{} > + con:close() > + con = nil > + > + return a > +end; > +test_run:cmd("setopt delimiter ''"); > + > +box.schema.user.revoke('guest', 'read', 'space', '_schema') > diff --git a/test/box/net.box_password_gh-1545.result b/test/box/net.box_password_gh-1545.result > new file mode 100644 > index 000000000..984084cae > --- /dev/null > +++ b/test/box/net.box_password_gh-1545.result > @@ -0,0 +1,28 @@ > +remote = require 'net.box' > +--- > +... > +LISTEN = require('uri').parse(box.cfg.listen) > +--- > +... > +-- #1545 empty password > +cn = remote.connect(LISTEN.host, LISTEN.service, { user = 'test' }) > +--- > +... > +cn ~= nil > +--- > +- true > +... > +cn:close() > +--- > +... > +cn = remote.connect(LISTEN.host, LISTEN.service, { password = 'test' }) > +--- > +- error: 'net.box: user is not defined' > +... > +cn ~= nil > +--- > +- true > +... > +cn:close() > +--- > +... > diff --git a/test/box/net.box_password_gh-1545.test.lua b/test/box/net.box_password_gh-1545.test.lua > new file mode 100644 > index 000000000..86d496432 > --- /dev/null > +++ b/test/box/net.box_password_gh-1545.test.lua > @@ -0,0 +1,10 @@ > +remote = require 'net.box' > +LISTEN = require('uri').parse(box.cfg.listen) > + > +-- #1545 empty password > +cn = remote.connect(LISTEN.host, LISTEN.service, { user = 'test' }) > +cn ~= nil > +cn:close() > +cn = remote.connect(LISTEN.host, LISTEN.service, { password = 'test' }) > +cn ~= nil > +cn:close() > diff --git a/test/box/net.box_permissions.result b/test/box/net.box_permissions.result > new file mode 100644 > index 000000000..04729dccb > --- /dev/null > +++ b/test/box/net.box_permissions.result > @@ -0,0 +1,186 @@ > +remote = require 'net.box' > +--- > +... > +fiber = require 'fiber' > +--- > +... > +log = require 'log' > +--- > +... > +LISTEN = require('uri').parse(box.cfg.listen) > +--- > +... > +space = box.schema.space.create('net_box_test_space') > +--- > +... > +index = space:create_index('primary', { type = 'tree' }) > +--- > +... > +-- low level connection > +log.info("create connection") > +--- > +... > +cn = remote.connect(LISTEN.host, LISTEN.service) > +--- > +... > +log.info("state is %s", cn.state) > +--- > +... > +cn:ping() > +--- > +- true > +... > +log.info("ping is done") > +--- > +... > +cn:ping() > +--- > +- true > +... > +log.info("ping is done") > +--- > +... > +cn:ping() > +--- > +- true > +... > +-- check permissions > +cn:call('unexists_procedure') > +--- > +- error: Execute access to function 'unexists_procedure' is denied for user 'guest' > +... > +function test_foo(a,b,c) return { {{ [a] = 1 }}, {{ [b] = 2 }}, c } end > +--- > +... > +cn:call('test_foo', {'a', 'b', 'c'}) > +--- > +- error: Execute access to function 'test_foo' is denied for user 'guest' > +... > +cn:eval('return 2+2') > +--- > +- error: Execute access to universe '' is denied for user 'guest' > +... > +cn:close() > +--- > +... > +-- connect and call without usage access > +box.schema.user.grant('guest','execute','universe') > +--- > +... > +box.schema.user.revoke('guest','usage','universe') > +--- > +... > +box.session.su("guest") > +--- > +... > +cn = remote.connect(LISTEN.host, LISTEN.service) > +--- > +... > +cn:call('test_foo', {'a', 'b', 'c'}) > +--- > +- error: Usage access to universe '' is denied for user 'guest' > +... > +box.session.su("admin") > +--- > +... > +box.schema.user.grant('guest','usage','universe') > +--- > +... > +cn:close() > +--- > +... > +cn = remote.connect(box.cfg.listen) > +--- > +... > +cn:call('unexists_procedure') > +--- > +- error: Procedure 'unexists_procedure' is not defined > +... > +cn:call('test_foo', {'a', 'b', 'c'}) > +--- > +- [[{'a': 1}], [{'b': 2}], 'c'] > +... > +cn:call(nil, {'a', 'b', 'c'}) > +--- > +- error: Procedure 'nil' is not defined > +... > +cn:eval('return 2+2') > +--- > +- 4 > +... > +cn:eval('return 1, 2, 3') > +--- > +- 1 > +- 2 > +- 3 > +... > +cn:eval('return ...', {1, 2, 3}) > +--- > +- 1 > +- 2 > +- 3 > +... > +cn:eval('return { k = "v1" }, true, { xx = 10, yy = 15 }, nil') > +--- > +- {'k': 'v1'} > +- true > +- {'yy': 15, 'xx': 10} > +- null > +... > +cn:eval('return nil') > +--- > +- null > +... > +cn:eval('return') > +--- > +... > +cn:eval('error("exception")') > +--- > +- error: 'eval:1: exception' > +... > +cn:eval('box.error(0)') > +--- > +- error: Unknown error > +... > +cn:eval('!invalid expression') > +--- > +- error: 'eval:1: unexpected symbol near ''!''' > +... > +-- box.commit() missing at return of CALL/EVAL > +function no_commit() box.begin() fiber.sleep(0.001) end > +--- > +... > +cn:call('no_commit') > +--- > +- error: Transaction is active at return from function > +... > +cn:eval('no_commit()') > +--- > +- error: Transaction is active at return from function > +... > +remote.self:eval('return 1+1, 2+2') > +--- > +- 2 > +- 4 > +... > +remote.self:eval('return') > +--- > +... > +remote.self:eval('error("exception")') > +--- > +- error: '[string "error("exception")"]:1: exception' > +... > +remote.self:eval('box.error(0)') > +--- > +- error: Unknown error > +... > +remote.self:eval('!invalid expression') > +--- > +- error: '[string "return !invalid expression"]:1: unexpected symbol near ''!''' > +... > +box.schema.user.revoke('guest', 'execute', 'universe') > +--- > +... > +cn:close() > +--- > +... > diff --git a/test/box/net.box_permissions.test.lua b/test/box/net.box_permissions.test.lua > new file mode 100644 > index 000000000..249604f64 > --- /dev/null > +++ b/test/box/net.box_permissions.test.lua > @@ -0,0 +1,66 @@ > +remote = require 'net.box' > +fiber = require 'fiber' > +log = require 'log' > + > +LISTEN = require('uri').parse(box.cfg.listen) > +space = box.schema.space.create('net_box_test_space') > +index = space:create_index('primary', { type = 'tree' }) > + > +-- low level connection > +log.info("create connection") > +cn = remote.connect(LISTEN.host, LISTEN.service) > +log.info("state is %s", cn.state) > + > +cn:ping() > +log.info("ping is done") > +cn:ping() > +log.info("ping is done") > + > + > +cn:ping() > + > + > +-- check permissions > +cn:call('unexists_procedure') > +function test_foo(a,b,c) return { {{ [a] = 1 }}, {{ [b] = 2 }}, c } end > +cn:call('test_foo', {'a', 'b', 'c'}) > +cn:eval('return 2+2') > +cn:close() > +-- connect and call without usage access > +box.schema.user.grant('guest','execute','universe') > +box.schema.user.revoke('guest','usage','universe') > +box.session.su("guest") > +cn = remote.connect(LISTEN.host, LISTEN.service) > +cn:call('test_foo', {'a', 'b', 'c'}) > +box.session.su("admin") > +box.schema.user.grant('guest','usage','universe') > +cn:close() > +cn = remote.connect(box.cfg.listen) > + > +cn:call('unexists_procedure') > +cn:call('test_foo', {'a', 'b', 'c'}) > +cn:call(nil, {'a', 'b', 'c'}) > +cn:eval('return 2+2') > +cn:eval('return 1, 2, 3') > +cn:eval('return ...', {1, 2, 3}) > +cn:eval('return { k = "v1" }, true, { xx = 10, yy = 15 }, nil') > +cn:eval('return nil') > +cn:eval('return') > +cn:eval('error("exception")') > +cn:eval('box.error(0)') > +cn:eval('!invalid expression') > + > +-- box.commit() missing at return of CALL/EVAL > +function no_commit() box.begin() fiber.sleep(0.001) end > +cn:call('no_commit') > +cn:eval('no_commit()') > + > +remote.self:eval('return 1+1, 2+2') > +remote.self:eval('return') > +remote.self:eval('error("exception")') > +remote.self:eval('box.error(0)') > +remote.self:eval('!invalid expression') > + > +box.schema.user.revoke('guest', 'execute', 'universe') > + > +cn:close() > diff --git a/test/box/net.box_pseudo_objects_gh-2401.result b/test/box/net.box_pseudo_objects_gh-2401.result > new file mode 100644 > index 000000000..46730368f > --- /dev/null > +++ b/test/box/net.box_pseudo_objects_gh-2401.result > @@ -0,0 +1,55 @@ > +test_run = require('test_run').new() > +--- > +... > +net = require('net.box') > +--- > +... > +test_run:cmd('create server connecter with script = "box/proxy.lua"') > +--- > +- true > +... > +-- > +-- gh-2401 update pseudo objects not replace them > +-- > +space = box.schema.space.create('test') > +--- > +... > +box.schema.user.grant('guest', 'read', 'space', 'test') > +--- > +... > +c = net.connect(box.cfg.listen) > +--- > +... > +cspace = c.space.test > +--- > +... > +space.index.test_index == nil > +--- > +- true > +... > +cspace.index.test_index == nil > +--- > +- true > +... > +_ = space:create_index("test_index", {parts={1, 'string'}}) > +--- > +... > +c:reload_schema() > +--- > +... > +space.index.test_index ~= nil > +--- > +- true > +... > +cspace.index.test_index ~= nil > +--- > +- true > +... > +c.space.test.index.test_index ~= nil > +--- > +- true > +... > +-- cleanup > +space:drop() > +--- > +... > diff --git a/test/box/net.box_pseudo_objects_gh-2401.test.lua b/test/box/net.box_pseudo_objects_gh-2401.test.lua > new file mode 100644 > index 000000000..b9277ae94 > --- /dev/null > +++ b/test/box/net.box_pseudo_objects_gh-2401.test.lua > @@ -0,0 +1,23 @@ > +test_run = require('test_run').new() > +net = require('net.box') > + > +test_run:cmd('create server connecter with script = "box/proxy.lua"') > + > +-- > +-- gh-2401 update pseudo objects not replace them > +-- > +space = box.schema.space.create('test') > +box.schema.user.grant('guest', 'read', 'space', 'test') > +c = net.connect(box.cfg.listen) > +cspace = c.space.test > +space.index.test_index == nil > +cspace.index.test_index == nil > +_ = space:create_index("test_index", {parts={1, 'string'}}) > +c:reload_schema() > +space.index.test_index ~= nil > +cspace.index.test_index ~= nil > +c.space.test.index.test_index ~= nil > + > +-- cleanup > + > +space:drop() > diff --git a/test/box/net.box_raw_response_gh-3107.result b/test/box/net.box_raw_response_gh-3107.result > new file mode 100644 > index 000000000..85fef9daf > --- /dev/null > +++ b/test/box/net.box_raw_response_gh-3107.result > @@ -0,0 +1,123 @@ > +fiber = require 'fiber' > +--- > +... > +msgpack = require 'msgpack' > +--- > +... > +net = require('net.box') > +--- > +... > +-- > +-- gh-3107: fiber-async netbox. > +-- > +cond = nil > +--- > +... > +box.schema.func.create('long_function') > +--- > +... > +box.schema.user.grant('guest', 'execute', 'function', 'long_function') > +--- > +... > +function long_function(...) cond = fiber.cond() cond:wait() return ... end > +--- > +... > +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end > +--- > +... > +s = box.schema.create_space('test') > +--- > +... > +pk = s:create_index('pk') > +--- > +... > +s:replace{1} > +--- > +- [1] > +... > +s:replace{2} > +--- > +- [2] > +... > +s:replace{3} > +--- > +- [3] > +... > +s:replace{4} > +--- > +- [4] > +... > +c = net:connect(box.cfg.listen) > +--- > +... > +-- > +-- Ensure a request can be finalized from non-caller fibers. > +-- > +future = c:call('long_function', {1, 2, 3}, {is_async = true}) > +--- > +... > +ret = {} > +--- > +... > +count = 0 > +--- > +... > +for i = 1, 10 do fiber.create(function() ret[i] = future:wait_result(1000) count = count + 1 end) end > +--- > +... > +future:wait_result(0.01) -- Must fail on timeout. > +--- > +- null > +- Timeout exceeded > +... > +finalize_long() > +--- > +... > +while count ~= 10 do fiber.sleep(0.1) end > +--- > +... > +ret > +--- > +- - &0 [1, 2, 3] > + - *0 > + - *0 > + - *0 > + - *0 > + - *0 > + - *0 > + - *0 > + - *0 > + - *0 > +... > +-- > +-- Test raw response getting. > +-- > +ibuf = require('buffer').ibuf() > +--- > +... > +future = c:call('long_function', {1, 2, 3}, {is_async = true, buffer = ibuf}) > +--- > +... > +finalize_long() > +--- > +... > +future:wait_result(100) > +--- > +- 10 > +... > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +--- > +... > +result > +--- > +- {48: [1, 2, 3]} > +... > +box.schema.func.drop('long_function') > +--- > +... > +c:close() > +--- > +... > +s:drop() > +--- > +... > diff --git a/test/box/net.box_raw_response_gh-3107.test.lua b/test/box/net.box_raw_response_gh-3107.test.lua > new file mode 100644 > index 000000000..fa477d6d7 > --- /dev/null > +++ b/test/box/net.box_raw_response_gh-3107.test.lua > @@ -0,0 +1,46 @@ > +fiber = require 'fiber' > +msgpack = require 'msgpack' > +net = require('net.box') > + > +-- > +-- gh-3107: fiber-async netbox. > +-- > +cond = nil > +box.schema.func.create('long_function') > +box.schema.user.grant('guest', 'execute', 'function', 'long_function') > +function long_function(...) cond = fiber.cond() cond:wait() return ... end > +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end > +s = box.schema.create_space('test') > +pk = s:create_index('pk') > +s:replace{1} > +s:replace{2} > +s:replace{3} > +s:replace{4} > +c = net:connect(box.cfg.listen) > + > +-- > +-- Ensure a request can be finalized from non-caller fibers. > +-- > +future = c:call('long_function', {1, 2, 3}, {is_async = true}) > +ret = {} > +count = 0 > +for i = 1, 10 do fiber.create(function() ret[i] = future:wait_result(1000) count = count + 1 end) end > +future:wait_result(0.01) -- Must fail on timeout. > +finalize_long() > +while count ~= 10 do fiber.sleep(0.1) end > +ret > + > +-- > +-- Test raw response getting. > +-- > +ibuf = require('buffer').ibuf() > +future = c:call('long_function', {1, 2, 3}, {is_async = true, buffer = ibuf}) > +finalize_long() > +future:wait_result(100) > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > +result > + > +box.schema.func.drop('long_function') > + > +c:close() > +s:drop() > diff --git a/test/box/net.box_readahead_gh-3958.result b/test/box/net.box_readahead_gh-3958.result > new file mode 100644 > index 000000000..fc2093531 > --- /dev/null > +++ b/test/box/net.box_readahead_gh-3958.result > @@ -0,0 +1,55 @@ > +test_run = require('test_run').new() > +--- > +... > +net = require('net.box') > +--- > +... > +-- > +-- gh-3958 updating box.cfg.readahead doesn't affect existing connections. > +-- > +readahead = box.cfg.readahead > +--- > +... > +box.cfg{readahead = 128} > +--- > +... > +s = box.schema.space.create("test") > +--- > +... > +_ = s:create_index("pk") > +--- > +... > +box.schema.user.grant("guest", "read,write", "space", "test") > +--- > +... > +-- connection is created with small readahead value, > +-- make sure it is updated if box.cfg.readahead is changed. > +c = net.connect(box.cfg.listen) > +--- > +... > +box.cfg{readahead = 100 * 1024} > +--- > +... > +box.error.injection.set("ERRINJ_WAL_DELAY", true) > +--- > +- ok > +... > +pad = string.rep('x', 8192) > +--- > +... > +for i = 1, 5 do c.space.test:replace({i, pad}, {is_async = true}) end > +--- > +... > +box.error.injection.set("ERRINJ_WAL_DELAY", false) > +--- > +- ok > +... > +test_run:wait_log('default', 'readahead limit is reached', 1024, 0.1) > +--- > +... > +s:drop() > +--- > +... > +box.cfg{readahead = readahead} > +--- > +... > diff --git a/test/box/net.box_readahead_gh-3958.test.lua b/test/box/net.box_readahead_gh-3958.test.lua > new file mode 100644 > index 000000000..1e33a84cb > --- /dev/null > +++ b/test/box/net.box_readahead_gh-3958.test.lua > @@ -0,0 +1,29 @@ > +test_run = require('test_run').new() > +net = require('net.box') > + > +-- > +-- gh-3958 updating box.cfg.readahead doesn't affect existing connections. > +-- > +readahead = box.cfg.readahead > + > +box.cfg{readahead = 128} > + > +s = box.schema.space.create("test") > +_ = s:create_index("pk") > +box.schema.user.grant("guest", "read,write", "space", "test") > + > +-- connection is created with small readahead value, > +-- make sure it is updated if box.cfg.readahead is changed. > +c = net.connect(box.cfg.listen) > + > +box.cfg{readahead = 100 * 1024} > + > +box.error.injection.set("ERRINJ_WAL_DELAY", true) > +pad = string.rep('x', 8192) > +for i = 1, 5 do c.space.test:replace({i, pad}, {is_async = true}) end > +box.error.injection.set("ERRINJ_WAL_DELAY", false) > + > +test_run:wait_log('default', 'readahead limit is reached', 1024, 0.1) > + > +s:drop() > +box.cfg{readahead = readahead} > diff --git a/test/box/net.box_reconnect_after.result b/test/box/net.box_reconnect_after.result > new file mode 100644 > index 000000000..a75f9dc5c > --- /dev/null > +++ b/test/box/net.box_reconnect_after.result > @@ -0,0 +1,32 @@ > +fiber = require 'fiber' > +--- > +... > +net = require('net.box') > +--- > +... > +box.schema.user.grant('guest', 'execute', 'universe') > +--- > +... > +-- > +-- Test a case, when netbox can not connect first time, but > +-- reconnect_after is set. > +-- > +c = net.connect('localhost:33333', {reconnect_after = 0.1, wait_connected = false}) > +--- > +... > +while c.state ~= 'error_reconnect' do fiber.sleep(0.01) end > +--- > +... > +c:close() > +--- > +... > +box.schema.user.revoke('guest', 'execute', 'universe') > +--- > +... > +c.state > +--- > +- closed > +... > +c = nil > +--- > +... > diff --git a/test/box/net.box_reconnect_after.test.lua b/test/box/net.box_reconnect_after.test.lua > new file mode 100644 > index 000000000..8ad870475 > --- /dev/null > +++ b/test/box/net.box_reconnect_after.test.lua > @@ -0,0 +1,16 @@ > +fiber = require 'fiber' > +net = require('net.box') > + > +box.schema.user.grant('guest', 'execute', 'universe') > + > +-- > +-- Test a case, when netbox can not connect first time, but > +-- reconnect_after is set. > +-- > +c = net.connect('localhost:33333', {reconnect_after = 0.1, wait_connected = false}) > +while c.state ~= 'error_reconnect' do fiber.sleep(0.01) end > +c:close() > + > +box.schema.user.revoke('guest', 'execute', 'universe') > +c.state > +c = nil > diff --git a/test/box/net.box_reconnect_after_gh-3164.result b/test/box/net.box_reconnect_after_gh-3164.result > new file mode 100644 > index 000000000..216ce0366 > --- /dev/null > +++ b/test/box/net.box_reconnect_after_gh-3164.result > @@ -0,0 +1,119 @@ > +fiber = require 'fiber' > +--- > +... > +log = require 'log' > +--- > +... > +test_run = require('test_run').new() > +--- > +... > +net = require('net.box') > +--- > +... > +test_run:cmd('create server connecter with script = "box/proxy.lua"') > +--- > +- true > +... > +-- > +-- gh-3164: netbox connection is not closed and garbage collected > +-- ever, if reconnect_after is set. > +-- > +test_run:cmd('start server connecter') > +--- > +- true > +... > +test_run:cmd("set variable connect_to to 'connecter.listen'") > +--- > +- true > +... > +weak = setmetatable({}, {__mode = 'v'}) > +--- > +... > +-- Create strong and weak reference. Weak is valid until strong > +-- is valid too. > +strong = net.connect(connect_to, {reconnect_after = 0.1}) > +--- > +... > +weak.c = strong > +--- > +... > +weak.c:ping() > +--- > +- true > +... > +test_run:cmd('stop server connecter') > +--- > +- true > +... > +test_run:cmd('cleanup server connecter') > +--- > +- true > +... > +-- Check the connection tries to reconnect at least two times. > +-- 'Cannot assign requested address' is the crutch for running the > +-- tests in a docker. This error emits instead of > +-- 'Connection refused' inside a docker. > +old_log_level = box.cfg.log_level > +--- > +... > +box.cfg{log_level = 6} > +--- > +... > +log.info(string.rep('a', 1000)) > +--- > +... > +test_run:cmd("setopt delimiter ';'") > +--- > +- true > +... > +while test_run:grep_log('default', 'Network is unreachable', 1000) == nil and > + test_run:grep_log('default', 'Connection refused', 1000) == nil and > + test_run:grep_log('default', 'Cannot assign requested address', 1000) == nil do > + fiber.sleep(0.1) > +end; > +--- > +... > +log.info(string.rep('a', 1000)); > +--- > +... > +while test_run:grep_log('default', 'Network is unreachable', 1000) == nil and > + test_run:grep_log('default', 'Connection refused', 1000) == nil and > + test_run:grep_log('default', 'Cannot assign requested address', 1000) == nil do > + fiber.sleep(0.1) > +end; > +--- > +... > +test_run:cmd("setopt delimiter ''"); > +--- > +- true > +... > +box.cfg{log_level = old_log_level} > +--- > +... > +collectgarbage('collect') > +--- > +- 0 > +... > +strong.state > +--- > +- error_reconnect > +... > +strong == weak.c > +--- > +- true > +... > +-- Remove single strong reference. Now connection must be garbage > +-- collected. > +strong = nil > +--- > +... > +collectgarbage('collect') > +--- > +- 0 > +... > +-- Now weak.c is null, because it was weak reference, and the > +-- connection is deleted by 'collect'. > +weak.c > +--- > +- null > +... > diff --git a/test/box/net.box_reconnect_after_gh-3164.test.lua b/test/box/net.box_reconnect_after_gh-3164.test.lua > new file mode 100644 > index 000000000..dc2747080 > --- /dev/null > +++ b/test/box/net.box_reconnect_after_gh-3164.test.lua > @@ -0,0 +1,52 @@ > +fiber = require 'fiber' > +log = require 'log' > +test_run = require('test_run').new() > +net = require('net.box') > + > +test_run:cmd('create server connecter with script = "box/proxy.lua"') > + > +-- > +-- gh-3164: netbox connection is not closed and garbage collected > +-- ever, if reconnect_after is set. > +-- > +test_run:cmd('start server connecter') > +test_run:cmd("set variable connect_to to 'connecter.listen'") > +weak = setmetatable({}, {__mode = 'v'}) > +-- Create strong and weak reference. Weak is valid until strong > +-- is valid too. > +strong = net.connect(connect_to, {reconnect_after = 0.1}) > +weak.c = strong > +weak.c:ping() > +test_run:cmd('stop server connecter') > +test_run:cmd('cleanup server connecter') > +-- Check the connection tries to reconnect at least two times. > +-- 'Cannot assign requested address' is the crutch for running the > +-- tests in a docker. This error emits instead of > +-- 'Connection refused' inside a docker. > +old_log_level = box.cfg.log_level > +box.cfg{log_level = 6} > +log.info(string.rep('a', 1000)) > +test_run:cmd("setopt delimiter ';'") > +while test_run:grep_log('default', 'Network is unreachable', 1000) == nil and > + test_run:grep_log('default', 'Connection refused', 1000) == nil and > + test_run:grep_log('default', 'Cannot assign requested address', 1000) == nil do > + fiber.sleep(0.1) > +end; > +log.info(string.rep('a', 1000)); > +while test_run:grep_log('default', 'Network is unreachable', 1000) == nil and > + test_run:grep_log('default', 'Connection refused', 1000) == nil and > + test_run:grep_log('default', 'Cannot assign requested address', 1000) == nil do > + fiber.sleep(0.1) > +end; > +test_run:cmd("setopt delimiter ''"); > +box.cfg{log_level = old_log_level} > +collectgarbage('collect') > +strong.state > +strong == weak.c > +-- Remove single strong reference. Now connection must be garbage > +-- collected. > +strong = nil > +collectgarbage('collect') > +-- Now weak.c is null, because it was weak reference, and the > +-- connection is deleted by 'collect'. > +weak.c > diff --git a/test/box/net.box_reload_schema_gh-636.result b/test/box/net.box_reload_schema_gh-636.result > new file mode 100644 > index 000000000..43e8e8b29 > --- /dev/null > +++ b/test/box/net.box_reload_schema_gh-636.result > @@ -0,0 +1,108 @@ > +remote = require 'net.box' > +--- > +... > +fiber = require 'fiber' > +--- > +... > +test_run = require('test_run').new() > +--- > +... > +-- #636: Reload schema on demand > +sp = box.schema.space.create('test_old') > +--- > +... > +_ = sp:create_index('primary') > +--- > +... > +sp:insert{1, 2, 3} > +--- > +- [1, 2, 3] > +... > +box.schema.user.grant('guest', 'read', 'space', 'test_old') > +--- > +... > +con = remote.new(box.cfg.listen) > +--- > +... > +con:ping() > +--- > +- true > +... > +con.space.test_old:select{} > +--- > +- - [1, 2, 3] > +... > +con.space.test == nil > +--- > +- true > +... > +sp = box.schema.space.create('test') > +--- > +... > +_ = sp:create_index('primary') > +--- > +... > +sp:insert{2, 3, 4} > +--- > +- [2, 3, 4] > +... > +box.schema.user.grant('guest', 'read', 'space', 'test') > +--- > +... > +con.space.test == nil > +--- > +- true > +... > +con:reload_schema() > +--- > +... > +con.space.test:select{} > +--- > +- - [2, 3, 4] > +... > +box.space.test:drop() > +--- > +... > +box.space.test_old:drop() > +--- > +... > +con:close() > +--- > +... > +name = string.match(arg[0], "([^,]+)%.lua") > +--- > +... > +file_log = require('fio').open(name .. '.log', {'O_RDONLY', 'O_NONBLOCK'}) > +--- > +... > +file_log:seek(0, 'SEEK_END') ~= 0 > +--- > +- true > +... > +box.schema.user.grant('guest', 'execute', 'universe') > +--- > +... > +test_run:cmd("setopt delimiter ';'") > +--- > +- true > +... > +_ = fiber.create( > + function() > + local conn = require('net.box').new(box.cfg.listen) > + conn:call('no_such_function', {}) > + conn:close() > + end > +); > +--- > +... > +test_run:cmd("setopt delimiter ''"); > +--- > +- true > +... > +test_run:wait_log('default', 'ER_NO_SUCH_PROC', nil, 10) > +--- > +- ER_NO_SUCH_PROC > +... > +box.schema.user.revoke('guest', 'execute', 'universe') > +--- > +... > diff --git a/test/box/net.box_reload_schema_gh-636.test.lua b/test/box/net.box_reload_schema_gh-636.test.lua > new file mode 100644 > index 000000000..d7431ee6c > --- /dev/null > +++ b/test/box/net.box_reload_schema_gh-636.test.lua > @@ -0,0 +1,46 @@ > +remote = require 'net.box' > +fiber = require 'fiber' > +test_run = require('test_run').new() > + > +-- #636: Reload schema on demand > +sp = box.schema.space.create('test_old') > +_ = sp:create_index('primary') > +sp:insert{1, 2, 3} > + > +box.schema.user.grant('guest', 'read', 'space', 'test_old') > +con = remote.new(box.cfg.listen) > +con:ping() > +con.space.test_old:select{} > +con.space.test == nil > + > +sp = box.schema.space.create('test') > +_ = sp:create_index('primary') > +sp:insert{2, 3, 4} > + > +box.schema.user.grant('guest', 'read', 'space', 'test') > + > +con.space.test == nil > +con:reload_schema() > +con.space.test:select{} > + > +box.space.test:drop() > +box.space.test_old:drop() > +con:close() > + > +name = string.match(arg[0], "([^,]+)%.lua") > +file_log = require('fio').open(name .. '.log', {'O_RDONLY', 'O_NONBLOCK'}) > +file_log:seek(0, 'SEEK_END') ~= 0 > + > +box.schema.user.grant('guest', 'execute', 'universe') > +test_run:cmd("setopt delimiter ';'") > + > +_ = fiber.create( > + function() > + local conn = require('net.box').new(box.cfg.listen) > + conn:call('no_such_function', {}) > + conn:close() > + end > +); > +test_run:cmd("setopt delimiter ''"); > +test_run:wait_log('default', 'ER_NO_SUCH_PROC', nil, 10) > +box.schema.user.revoke('guest', 'execute', 'universe') > diff --git a/test/box/net.box_remote_method_gh-544.result b/test/box/net.box_remote_method_gh-544.result > new file mode 100644 > index 000000000..bb92ba998 > --- /dev/null > +++ b/test/box/net.box_remote_method_gh-544.result > @@ -0,0 +1,95 @@ > +remote = require 'net.box' > +--- > +... > +LISTEN = require('uri').parse(box.cfg.listen) > +--- > +... > +box.schema.user.create('netbox', { password = 'test' }) > +--- > +... > +-- #544 usage for remote[point]method > +cn = remote.connect(LISTEN.host, LISTEN.service) > +--- > +... > +box.schema.user.grant('guest', 'execute', 'universe') > +--- > +... > +cn:close() > +--- > +... > +cn = remote.connect(LISTEN.host, LISTEN.service) > +--- > +... > +cn:eval('return true') > +--- > +- true > +... > +cn.eval('return true') > +--- > +- error: 'Use remote:eval(...) instead of remote.eval(...):' > +... > +cn.ping() > +--- > +- error: 'Use remote:ping(...) instead of remote.ping(...):' > +... > +cn:close() > +--- > +... > +remote.self:eval('return true') > +--- > +- true > +... > +remote.self.eval('return true') > +--- > +- error: 'Use remote:eval(...) instead of remote.eval(...):' > +... > +box.schema.user.revoke('guest', 'execute', 'universe') > +--- > +... > +-- uri as the first argument > +uri = string.format('%s:%s@%s:%s', 'netbox', 'test', LISTEN.host, LISTEN.service) > +--- > +... > +cn = remote.new(uri) > +--- > +... > +cn:ping() > +--- > +- true > +... > +cn:close() > +--- > +... > +uri = string.format('%s@%s:%s', 'netbox', LISTEN.host, LISTEN.service) > +--- > +... > +cn = remote.new(uri) > +--- > +... > +cn ~= nil, cn.state, cn.error > +--- > +- true > +- error > +- Incorrect password supplied for user 'netbox' > +... > +cn:close() > +--- > +... > +-- don't merge creds from uri & opts > +remote.new(uri, { password = 'test' }) > +--- > +- error: 'net.box: user is not defined' > +... > +cn = remote.new(uri, { user = 'netbox', password = 'test' }) > +--- > +... > +cn:ping() > +--- > +- true > +... > +cn:close() > +--- > +... > +box.schema.user.drop('netbox') > +--- > +... > diff --git a/test/box/net.box_remote_method_gh-544.test.lua b/test/box/net.box_remote_method_gh-544.test.lua > new file mode 100644 > index 000000000..cfd883be0 > --- /dev/null > +++ b/test/box/net.box_remote_method_gh-544.test.lua > @@ -0,0 +1,40 @@ > +remote = require 'net.box' > + > +LISTEN = require('uri').parse(box.cfg.listen) > +box.schema.user.create('netbox', { password = 'test' }) > + > +-- #544 usage for remote[point]method > +cn = remote.connect(LISTEN.host, LISTEN.service) > + > +box.schema.user.grant('guest', 'execute', 'universe') > +cn:close() > +cn = remote.connect(LISTEN.host, LISTEN.service) > +cn:eval('return true') > +cn.eval('return true') > + > +cn.ping() > + > +cn:close() > + > +remote.self:eval('return true') > +remote.self.eval('return true') > +box.schema.user.revoke('guest', 'execute', 'universe') > + > +-- uri as the first argument > +uri = string.format('%s:%s@%s:%s', 'netbox', 'test', LISTEN.host, LISTEN.service) > + > +cn = remote.new(uri) > +cn:ping() > +cn:close() > + > +uri = string.format('%s@%s:%s', 'netbox', LISTEN.host, LISTEN.service) > +cn = remote.new(uri) > +cn ~= nil, cn.state, cn.error > +cn:close() > +-- don't merge creds from uri & opts > +remote.new(uri, { password = 'test' }) > +cn = remote.new(uri, { user = 'netbox', password = 'test' }) > +cn:ping() > +cn:close() > + > +box.schema.user.drop('netbox') > diff --git a/test/box/net.box_roll_back_gh-822.result b/test/box/net.box_roll_back_gh-822.result > new file mode 100644 > index 000000000..5a0550e39 > --- /dev/null > +++ b/test/box/net.box_roll_back_gh-822.result > @@ -0,0 +1,68 @@ > +remote = require 'net.box' > +--- > +... > +test_run = require('test_run').new() > +--- > +... > +-- > +-- gh-822: net.box.call should roll back local transaction on error > +-- > +_ = box.schema.space.create('gh822') > +--- > +... > +_ = box.space.gh822:create_index('primary') > +--- > +... > +test_run:cmd("setopt delimiter ';'") > +--- > +- true > +... > +-- rollback on invalid function > +function rollback_on_invalid_function() > + box.begin() > + box.space.gh822:insert{1, "netbox_test"} > + pcall(remote.self.call, remote.self, 'invalid_function') > + return box.space.gh822:get(1) == nil > +end; > +--- > +... > +rollback_on_invalid_function(); > +--- > +- true > +... > +-- rollback on call error > +function test_error() error('Some error') end; > +--- > +... > +function rollback_on_call_error() > + box.begin() > + box.space.gh822:insert{1, "netbox_test"} > + pcall(remote.self.call, remote.self, 'test_error') > + return box.space.gh822:get(1) == nil > +end; > +--- > +... > +rollback_on_call_error(); > +--- > +- true > +... > +-- rollback on eval > +function rollback_on_eval_error() > + box.begin() > + box.space.gh822:insert{1, "netbox_test"} > + pcall(remote.self.eval, remote.self, "error('Some error')") > + return box.space.gh822:get(1) == nil > +end; > +--- > +... > +rollback_on_eval_error(); > +--- > +- true > +... > +test_run:cmd("setopt delimiter ''"); > +--- > +- true > +... > +box.space.gh822:drop() > +--- > +... > diff --git a/test/box/net.box_roll_back_gh-822.test.lua b/test/box/net.box_roll_back_gh-822.test.lua > new file mode 100644 > index 000000000..8f4754902 > --- /dev/null > +++ b/test/box/net.box_roll_back_gh-822.test.lua > @@ -0,0 +1,42 @@ > +remote = require 'net.box' > +test_run = require('test_run').new() > + > +-- > +-- gh-822: net.box.call should roll back local transaction on error > +-- > + > +_ = box.schema.space.create('gh822') > +_ = box.space.gh822:create_index('primary') > + > +test_run:cmd("setopt delimiter ';'") > + > +-- rollback on invalid function > +function rollback_on_invalid_function() > + box.begin() > + box.space.gh822:insert{1, "netbox_test"} > + pcall(remote.self.call, remote.self, 'invalid_function') > + return box.space.gh822:get(1) == nil > +end; > +rollback_on_invalid_function(); > + > +-- rollback on call error > +function test_error() error('Some error') end; > +function rollback_on_call_error() > + box.begin() > + box.space.gh822:insert{1, "netbox_test"} > + pcall(remote.self.call, remote.self, 'test_error') > + return box.space.gh822:get(1) == nil > +end; > +rollback_on_call_error(); > + > +-- rollback on eval > +function rollback_on_eval_error() > + box.begin() > + box.space.gh822:insert{1, "netbox_test"} > + pcall(remote.self.eval, remote.self, "error('Some error')") > + return box.space.gh822:get(1) == nil > +end; > +rollback_on_eval_error(); > + > +test_run:cmd("setopt delimiter ''"); > +box.space.gh822:drop() > diff --git a/test/box/net.box_schema_change_gh-2666.result b/test/box/net.box_schema_change_gh-2666.result > new file mode 100644 > index 000000000..bce46bd59 > --- /dev/null > +++ b/test/box/net.box_schema_change_gh-2666.result > @@ -0,0 +1,79 @@ > +net = require('net.box') > +--- > +... > +-- > +-- gh-2666: check that netbox.call is not repeated on schema > +-- change. > +-- > +box.schema.user.grant('guest', 'write', 'space', '_space') > +--- > +... > +box.schema.user.grant('guest', 'write', 'space', '_schema') > +--- > +... > +box.schema.user.grant('guest', 'create', 'universe') > +--- > +... > +count = 0 > +--- > +... > +function create_space(name) count = count + 1 box.schema.create_space(name) return true end > +--- > +... > +box.schema.func.create('create_space') > +--- > +... > +box.schema.user.grant('guest', 'execute', 'function', 'create_space') > +--- > +... > +c = net.connect(box.cfg.listen) > +--- > +... > +c:call('create_space', {'test1'}) > +--- > +- true > +... > +count > +--- > +- 1 > +... > +c:call('create_space', {'test2'}) > +--- > +- true > +... > +count > +--- > +- 2 > +... > +c:call('create_space', {'test3'}) > +--- > +- true > +... > +count > +--- > +- 3 > +... > +box.space.test1:drop() > +--- > +... > +box.space.test2:drop() > +--- > +... > +box.space.test3:drop() > +--- > +... > +box.schema.user.revoke('guest', 'write', 'space', '_space') > +--- > +... > +box.schema.user.revoke('guest', 'write', 'space', '_schema') > +--- > +... > +box.schema.user.revoke('guest', 'create', 'universe') > +--- > +... > +c:close() > +--- > +... > +box.schema.func.drop('create_space') > +--- > +... > diff --git a/test/box/net.box_schema_change_gh-2666.test.lua b/test/box/net.box_schema_change_gh-2666.test.lua > new file mode 100644 > index 000000000..16e28e092 > --- /dev/null > +++ b/test/box/net.box_schema_change_gh-2666.test.lua > @@ -0,0 +1,28 @@ > +net = require('net.box') > + > +-- > +-- gh-2666: check that netbox.call is not repeated on schema > +-- change. > +-- > +box.schema.user.grant('guest', 'write', 'space', '_space') > +box.schema.user.grant('guest', 'write', 'space', '_schema') > +box.schema.user.grant('guest', 'create', 'universe') > +count = 0 > +function create_space(name) count = count + 1 box.schema.create_space(name) return true end > +box.schema.func.create('create_space') > +box.schema.user.grant('guest', 'execute', 'function', 'create_space') > +c = net.connect(box.cfg.listen) > +c:call('create_space', {'test1'}) > +count > +c:call('create_space', {'test2'}) > +count > +c:call('create_space', {'test3'}) > +count > +box.space.test1:drop() > +box.space.test2:drop() > +box.space.test3:drop() > +box.schema.user.revoke('guest', 'write', 'space', '_space') > +box.schema.user.revoke('guest', 'write', 'space', '_schema') > +box.schema.user.revoke('guest', 'create', 'universe') > +c:close() > +box.schema.func.drop('create_space') > diff --git a/test/box/net.box_schema_change_gh-3107.result b/test/box/net.box_schema_change_gh-3107.result > new file mode 100644 > index 000000000..233c83307 > --- /dev/null > +++ b/test/box/net.box_schema_change_gh-3107.result > @@ -0,0 +1,151 @@ > +fiber = require 'fiber' > +--- > +... > +net = require('net.box') > +--- > +... > +-- > +-- gh-3107: fiber-async netbox. > +-- > +cond = nil > +--- > +... > +box.schema.func.create('long_function') > +--- > +... > +box.schema.user.grant('guest', 'execute', 'function', 'long_function') > +--- > +... > +function long_function(...) cond = fiber.cond() cond:wait() return ... end > +--- > +... > +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end > +--- > +... > +s = box.schema.create_space('test') > +--- > +... > +pk = s:create_index('pk') > +--- > +... > +s:replace{1} > +--- > +- [1] > +... > +s:replace{2} > +--- > +- [2] > +... > +s:replace{3} > +--- > +- [3] > +... > +s:replace{4} > +--- > +- [4] > +... > +c = net:connect(box.cfg.listen) > +--- > +... > +-- > +-- Ensure a request can be finalized from non-caller fibers. > +-- > +future = c:call('long_function', {1, 2, 3}, {is_async = true}) > +--- > +... > +ret = {} > +--- > +... > +count = 0 > +--- > +... > +for i = 1, 10 do fiber.create(function() ret[i] = future:wait_result(1000) count = count + 1 end) end > +--- > +... > +future:wait_result(0.01) -- Must fail on timeout. > +--- > +- null > +- Timeout exceeded > +... > +finalize_long() > +--- > +... > +while count ~= 10 do fiber.sleep(0.1) end > +--- > +... > +ret > +--- > +- - &0 [1, 2, 3] > + - *0 > + - *0 > + - *0 > + - *0 > + - *0 > + - *0 > + - *0 > + - *0 > + - *0 > +... > +box.schema.func.drop('long_function') > +--- > +... > +-- > +-- Test async schema version change. > +-- > +function change_schema(i) local tmp = box.schema.create_space('test'..i) return 'ok' end > +--- > +... > +box.schema.func.create('change_schema') > +--- > +... > +box.schema.user.grant('guest', 'execute', 'function', 'change_schema') > +--- > +... > +box.schema.user.grant('guest', 'write', 'space', '_schema') > +--- > +... > +box.schema.user.grant('guest', 'read,write', 'space', '_space') > +--- > +... > +box.schema.user.grant('guest', 'create', 'space') > +--- > +... > +future1 = c:call('change_schema', {'1'}, {is_async = true}) > +--- > +... > +future2 = c:call('change_schema', {'2'}, {is_async = true}) > +--- > +... > +future3 = c:call('change_schema', {'3'}, {is_async = true}) > +--- > +... > +future1:wait_result() > +--- > +- ['ok'] > +... > +future2:wait_result() > +--- > +- ['ok'] > +... > +future3:wait_result() > +--- > +- ['ok'] > +... > +c:close() > +--- > +... > +s:drop() > +--- > +... > +box.schema.func.drop('change_schema') > +--- > +... > +box.schema.user.revoke('guest', 'write', 'space', '_schema') > +--- > +... > +box.schema.user.revoke('guest', 'read,write', 'space', '_space') > +--- > +... > +box.schema.user.revoke('guest', 'create', 'space') > +--- > +... > diff --git a/test/box/net.box_schema_change_gh-3107.test.lua b/test/box/net.box_schema_change_gh-3107.test.lua > new file mode 100644 > index 000000000..c73788455 > --- /dev/null > +++ b/test/box/net.box_schema_change_gh-3107.test.lua > @@ -0,0 +1,55 @@ > +fiber = require 'fiber' > +net = require('net.box') > + > +-- > +-- gh-3107: fiber-async netbox. > +-- > +cond = nil > +box.schema.func.create('long_function') > +box.schema.user.grant('guest', 'execute', 'function', 'long_function') > +function long_function(...) cond = fiber.cond() cond:wait() return ... end > +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end > +s = box.schema.create_space('test') > +pk = s:create_index('pk') > +s:replace{1} > +s:replace{2} > +s:replace{3} > +s:replace{4} > +c = net:connect(box.cfg.listen) > + > +-- > +-- Ensure a request can be finalized from non-caller fibers. > +-- > +future = c:call('long_function', {1, 2, 3}, {is_async = true}) > +ret = {} > +count = 0 > +for i = 1, 10 do fiber.create(function() ret[i] = future:wait_result(1000) count = count + 1 end) end > +future:wait_result(0.01) -- Must fail on timeout. > +finalize_long() > +while count ~= 10 do fiber.sleep(0.1) end > +ret > + > +box.schema.func.drop('long_function') > + > +-- > +-- Test async schema version change. > +-- > +function change_schema(i) local tmp = box.schema.create_space('test'..i) return 'ok' end > +box.schema.func.create('change_schema') > +box.schema.user.grant('guest', 'execute', 'function', 'change_schema') > +box.schema.user.grant('guest', 'write', 'space', '_schema') > +box.schema.user.grant('guest', 'read,write', 'space', '_space') > +box.schema.user.grant('guest', 'create', 'space') > +future1 = c:call('change_schema', {'1'}, {is_async = true}) > +future2 = c:call('change_schema', {'2'}, {is_async = true}) > +future3 = c:call('change_schema', {'3'}, {is_async = true}) > +future1:wait_result() > +future2:wait_result() > +future3:wait_result() > + > +c:close() > +s:drop() > +box.schema.func.drop('change_schema') > +box.schema.user.revoke('guest', 'write', 'space', '_schema') > +box.schema.user.revoke('guest', 'read,write', 'space', '_space') > +box.schema.user.revoke('guest', 'create', 'space') > diff --git a/test/box/net.box_session_type_gh-2642.result b/test/box/net.box_session_type_gh-2642.result > new file mode 100644 > index 000000000..0e043f6e5 > --- /dev/null > +++ b/test/box/net.box_session_type_gh-2642.result > @@ -0,0 +1,22 @@ > +net = require('net.box') > +--- > +... > +-- > +-- gh-2642: box.session.type() > +-- > +box.schema.user.grant('guest','execute','universe') > +--- > +... > +c = net.connect(box.cfg.listen) > +--- > +... > +c:call("box.session.type") > +--- > +- binary > +... > +c:close() > +--- > +... > +box.schema.user.revoke('guest', 'execute', 'universe') > +--- > +... > diff --git a/test/box/net.box_session_type_gh-2642.test.lua b/test/box/net.box_session_type_gh-2642.test.lua > new file mode 100644 > index 000000000..4e3cf5265 > --- /dev/null > +++ b/test/box/net.box_session_type_gh-2642.test.lua > @@ -0,0 +1,11 @@ > +net = require('net.box') > + > +-- > +-- gh-2642: box.session.type() > +-- > + > +box.schema.user.grant('guest','execute','universe') > +c = net.connect(box.cfg.listen) > +c:call("box.session.type") > +c:close() > +box.schema.user.revoke('guest', 'execute', 'universe') > diff --git a/test/box/net.box_space_format_gh-2402.result b/test/box/net.box_space_format_gh-2402.result > new file mode 100644 > index 000000000..c66665c73 > --- /dev/null > +++ b/test/box/net.box_space_format_gh-2402.result > @@ -0,0 +1,49 @@ > +net = require('net.box') > +--- > +... > +-- > +-- gh-2402 net.box doesn't support space:format() > +-- > +space = box.schema.space.create('test', {format={{name="id", type="unsigned"}}}) > +--- > +... > +space ~= nil > +--- > +- true > +... > +_ = box.space.test:create_index('primary') > +--- > +... > +box.schema.user.grant('guest', 'read', 'space', 'test') > +--- > +... > +c = net.connect(box.cfg.listen) > +--- > +... > +c:ping() > +--- > +- true > +... > +c.space.test ~= nil > +--- > +- true > +... > +format = c.space.test:format() > +--- > +... > +format[1] ~= nil > +--- > +- true > +... > +format[1].name == "id" > +--- > +- true > +... > +format[1].type == "unsigned" > +--- > +- true > +... > +c.space.test:format({}) > +--- > +- error: net.box does not support setting space format > +... > diff --git a/test/box/net.box_space_format_gh-2402.test.lua b/test/box/net.box_space_format_gh-2402.test.lua > new file mode 100644 > index 000000000..020f20da6 > --- /dev/null > +++ b/test/box/net.box_space_format_gh-2402.test.lua > @@ -0,0 +1,23 @@ > +net = require('net.box') > + > +-- > +-- gh-2402 net.box doesn't support space:format() > +-- > + > +space = box.schema.space.create('test', {format={{name="id", type="unsigned"}}}) > +space ~= nil > +_ = box.space.test:create_index('primary') > +box.schema.user.grant('guest', 'read', 'space', 'test') > + > +c = net.connect(box.cfg.listen) > + > +c:ping() > +c.space.test ~= nil > + > +format = c.space.test:format() > + > +format[1] ~= nil > +format[1].name == "id" > +format[1].type == "unsigned" > + > +c.space.test:format({}) > diff --git a/test/box/net.box_timeout-gh-3107.result b/test/box/net.box_timeout-gh-3107.result > new file mode 100644 > index 000000000..be7f9606c > --- /dev/null > +++ b/test/box/net.box_timeout-gh-3107.result > @@ -0,0 +1,125 @@ > +-- test-run result file version 2 > +fiber = require 'fiber' > + | --- > + | ... > +net = require('net.box') > + | --- > + | ... > + > +-- > +-- gh-3107: fiber-async netbox. > +-- > +cond = nil > + | --- > + | ... > +box.schema.func.create('long_function') > + | --- > + | ... > +box.schema.user.grant('guest', 'execute', 'function', 'long_function') > + | --- > + | ... > +function long_function(...) cond = fiber.cond() cond:wait() return ... end > + | --- > + | ... > +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end > + | --- > + | ... > +s = box.schema.create_space('test') > + | --- > + | ... > +pk = s:create_index('pk') > + | --- > + | ... > +s:replace{1} > + | --- > + | - [1] > + | ... > +s:replace{2} > + | --- > + | - [2] > + | ... > +s:replace{3} > + | --- > + | - [3] > + | ... > +s:replace{4} > + | --- > + | - [4] > + | ... > +c = net:connect(box.cfg.listen) > + | --- > + | ... > + > +-- > +-- Check infinity timeout. > +-- > +ret = nil > + | --- > + | ... > +_ = fiber.create(function() ret = c:call('long_function', {1, 2, 3}, {is_async = true}):wait_result() end) > + | --- > + | ... > +finalize_long() > + | --- > + | ... > +while not ret do fiber.sleep(0.01) end > + | --- > + | ... > +ret > + | --- > + | - [1, 2, 3] > + | ... > +c:close() > + | --- > + | ... > +box.schema.user.grant('guest', 'execute', 'universe') > + | --- > + | ... > +c = net:connect(box.cfg.listen) > + | --- > + | ... > +future = c:eval('return long_function(...)', {1, 2, 3}, {is_async = true}) > + | --- > + | ... > +future:result() > + | --- > + | - null > + | - Response is not ready > + | ... > +future:wait_result(0.01) -- Must fail on timeout. > + | --- > + | - null > + | - Timeout exceeded > + | ... > +finalize_long() > + | --- > + | ... > +future:wait_result(100) > + | --- > + | - [1, 2, 3] > + | ... > + > +c:close() > + | --- > + | ... > +-- > +-- Check that is_async does not work on a closed connection. > +-- > +c:call('any_func', {}, {is_async = true}) > + | --- > + | - error: Connection closed > + | ... > + > +box.schema.user.revoke('guest', 'execute', 'universe') > + | --- > + | ... > +c = net:connect(box.cfg.listen) > + | --- > + | ... > + > +c:close() > + | --- > + | ... > +s:drop() > + | --- > + | ... > diff --git a/test/box/net.box_timeout-gh-3107.test.lua b/test/box/net.box_timeout-gh-3107.test.lua > new file mode 100644 > index 000000000..08fa039db > --- /dev/null > +++ b/test/box/net.box_timeout-gh-3107.test.lua > @@ -0,0 +1,47 @@ > +fiber = require 'fiber' > +net = require('net.box') > + > +-- > +-- gh-3107: fiber-async netbox. > +-- > +cond = nil > +box.schema.func.create('long_function') > +box.schema.user.grant('guest', 'execute', 'function', 'long_function') > +function long_function(...) cond = fiber.cond() cond:wait() return ... end > +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end > +s = box.schema.create_space('test') > +pk = s:create_index('pk') > +s:replace{1} > +s:replace{2} > +s:replace{3} > +s:replace{4} > +c = net:connect(box.cfg.listen) > + > +-- > +-- Check infinity timeout. > +-- > +ret = nil > +_ = fiber.create(function() ret = c:call('long_function', {1, 2, 3}, {is_async = true}):wait_result() end) > +finalize_long() > +while not ret do fiber.sleep(0.01) end > +ret > +c:close() > +box.schema.user.grant('guest', 'execute', 'universe') > +c = net:connect(box.cfg.listen) > +future = c:eval('return long_function(...)', {1, 2, 3}, {is_async = true}) > +future:result() > +future:wait_result(0.01) -- Must fail on timeout. > +finalize_long() > +future:wait_result(100) > + > +c:close() > +-- > +-- Check that is_async does not work on a closed connection. > +-- > +c:call('any_func', {}, {is_async = true}) > + > +box.schema.user.revoke('guest', 'execute', 'universe') > +c = net:connect(box.cfg.listen) > + > +c:close() > +s:drop() > diff --git a/test/box/net.box_timeout_gh-1533.result b/test/box/net.box_timeout_gh-1533.result > new file mode 100644 > index 000000000..10dccd74f > --- /dev/null > +++ b/test/box/net.box_timeout_gh-1533.result > @@ -0,0 +1,89 @@ > +fiber = require 'fiber' > +--- > +... > +test_run = require('test_run').new() > +--- > +... > +net = require('net.box') > +--- > +... > +-- Tarantool < 1.7.1 compatibility (gh-1533) > +c = net.new(box.cfg.listen) > +--- > +... > +c:ping() > +--- > +- true > +... > +c:close() > +--- > +... > +-- Test for connect_timeout > 0 in netbox connect > +test_run:cmd("setopt delimiter ';'"); > +--- > +- true > +... > +need_stop = false; > +--- > +... > +greeting = > +"Tarantool 1.7.3 (Lua console)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" .. > +"type 'help' for interactive help~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"; > +--- > +... > +socket = require('socket'); > +--- > +... > +srv = socket.tcp_server('localhost', 0, { > + handler = function(fd) > + local fiber = require('fiber') > + while not need_stop do > + fiber.sleep(0.01) > + end > + fd:write(greeting) > + end > +}); > +--- > +... > +-- we must get timeout > +port = srv:name().port > +nb = net.new('localhost:' .. port, { > + wait_connected = true, console = true, > + connect_timeout = 0.1 > +}); > +--- > +... > +nb.error:find('timed out') ~= nil; > +--- > +- true > +... > +need_stop = true > +nb:close(); > +--- > +... > +-- we must get peer closed > +nb = net.new('localhost:' .. port, { > + wait_connected = true, console = true, > + connect_timeout = 0.2 > +}); > +--- > +... > +nb.error ~= "Timeout exceeded"; > +--- > +- true > +... > +nb:close(); > +--- > +... > +test_run:cmd("setopt delimiter ''"); > +--- > +- true > +... > +srv:close() > +--- > +- true > +... > +test_run:cmd("clear filter") > +--- > +- true > +... > diff --git a/test/box/net.box_timeout_gh-1533.test.lua b/test/box/net.box_timeout_gh-1533.test.lua > new file mode 100644 > index 000000000..08fddb0bb > --- /dev/null > +++ b/test/box/net.box_timeout_gh-1533.test.lua > @@ -0,0 +1,45 @@ > +fiber = require 'fiber' > +test_run = require('test_run').new() > +net = require('net.box') > + > +-- Tarantool < 1.7.1 compatibility (gh-1533) > +c = net.new(box.cfg.listen) > +c:ping() > +c:close() > + > +-- Test for connect_timeout > 0 in netbox connect > +test_run:cmd("setopt delimiter ';'"); > +need_stop = false; > +greeting = > +"Tarantool 1.7.3 (Lua console)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" .. > +"type 'help' for interactive help~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"; > +socket = require('socket'); > +srv = socket.tcp_server('localhost', 0, { > + handler = function(fd) > + local fiber = require('fiber') > + while not need_stop do > + fiber.sleep(0.01) > + end > + fd:write(greeting) > + end > +}); > +port = srv:name().port > +-- we must get timeout > +nb = net.new('localhost:' .. port, { > + wait_connected = true, console = true, > + connect_timeout = 0.1 > +}); > +nb.error:find('timed out') ~= nil; > +need_stop = true > +nb:close(); > +-- we must get peer closed > +nb = net.new('localhost:' .. port, { > + wait_connected = true, console = true, > + connect_timeout = 0.2 > +}); > +nb.error ~= "Timeout exceeded"; > +nb:close(); > +test_run:cmd("setopt delimiter ''"); > +srv:close() > + > +test_run:cmd("clear filter") > diff --git a/test/box/net.box_upsert_gh-970.result b/test/box/net.box_upsert_gh-970.result > new file mode 100644 > index 000000000..d3ec20c23 > --- /dev/null > +++ b/test/box/net.box_upsert_gh-970.result > @@ -0,0 +1,49 @@ > +net = require('net.box') > +--- > +... > +-- gh-970 gh-971 UPSERT over network > +_ = box.schema.space.create('test') > +--- > +... > +_ = box.space.test:create_index('primary', {type = 'TREE', parts = {1,'unsigned'}}) > +--- > +... > +_ = box.space.test:create_index('covering', {type = 'TREE', parts = {1,'unsigned',3,'string',2,'unsigned'}}) > +--- > +... > +_ = box.space.test:insert{1, 2, "string"} > +--- > +... > +box.schema.user.grant('guest', 'read,write', 'space', 'test') > +--- > +... > +c = net:connect(box.cfg.listen) > +--- > +... > +c.space.test:select{} > +--- > +- - [1, 2, 'string'] > +... > +c.space.test:upsert({1, 2, 'nothing'}, {{'+', 2, 1}}) -- common update > +--- > +... > +c.space.test:select{} > +--- > +- - [1, 3, 'string'] > +... > +c.space.test:upsert({2, 4, 'something'}, {{'+', 2, 1}}) -- insert > +--- > +... > +c.space.test:select{} > +--- > +- - [1, 3, 'string'] > + - [2, 4, 'something'] > +... > +c.space.test:upsert({2, 4, 'nothing'}, {{'+', 3, 100500}}) -- wrong operation > +--- > +... > +c.space.test:select{} > +--- > +- - [1, 3, 'string'] > + - [2, 4, 'something'] > +... > diff --git a/test/box/net.box_upsert_gh-970.test.lua b/test/box/net.box_upsert_gh-970.test.lua > new file mode 100644 > index 000000000..0ea9092eb > --- /dev/null > +++ b/test/box/net.box_upsert_gh-970.test.lua > @@ -0,0 +1,16 @@ > +net = require('net.box') > + > +-- gh-970 gh-971 UPSERT over network > +_ = box.schema.space.create('test') > +_ = box.space.test:create_index('primary', {type = 'TREE', parts = {1,'unsigned'}}) > +_ = box.space.test:create_index('covering', {type = 'TREE', parts = {1,'unsigned',3,'string',2,'unsigned'}}) > +_ = box.space.test:insert{1, 2, "string"} > +box.schema.user.grant('guest', 'read,write', 'space', 'test') > +c = net:connect(box.cfg.listen) > +c.space.test:select{} > +c.space.test:upsert({1, 2, 'nothing'}, {{'+', 2, 1}}) -- common update > +c.space.test:select{} > +c.space.test:upsert({2, 4, 'something'}, {{'+', 2, 1}}) -- insert > +c.space.test:select{} > +c.space.test:upsert({2, 4, 'nothing'}, {{'+', 3, 100500}}) -- wrong operation > +c.space.test:select{} > diff --git a/test/box/net.box_wait_connected_gh-3856.result b/test/box/net.box_wait_connected_gh-3856.result > new file mode 100644 > index 000000000..9234e6cb9 > --- /dev/null > +++ b/test/box/net.box_wait_connected_gh-3856.result > @@ -0,0 +1,20 @@ > +net = require('net.box') > +--- > +... > +-- > +-- gh-3856: wait_connected = false is ignored. > +-- > +c = net.connect('8.8.8.8:123456', {wait_connected = false}) > +--- > +... > +c > +--- > +- opts: > + wait_connected: false > + host: 8.8.8.8 > + state: initial > + port: '123456' > +... > +c:close() > +--- > +... > diff --git a/test/box/net.box_wait_connected_gh-3856.test.lua b/test/box/net.box_wait_connected_gh-3856.test.lua > new file mode 100644 > index 000000000..29e997fb5 > --- /dev/null > +++ b/test/box/net.box_wait_connected_gh-3856.test.lua > @@ -0,0 +1,8 @@ > +net = require('net.box') > + > +-- > +-- gh-3856: wait_connected = false is ignored. > +-- > +c = net.connect('8.8.8.8:123456', {wait_connected = false}) > +c > +c:close() > -- > 2.17.1 > -- sergeyb@ ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Tarantool-patches] [PATCH v1] Divide test box/net.box 2020-04-02 15:44 ` Sergey Bronnikov @ 2020-05-15 17:04 ` Alexander V. Tikhonov 2020-05-18 10:00 ` Sergey Bronnikov 0 siblings, 1 reply; 8+ messages in thread From: Alexander V. Tikhonov @ 2020-05-15 17:04 UTC (permalink / raw) To: Sergey Bronnikov; +Cc: tarantool-patches Hi Sergey, thanks a lot for the review. As we discussed the ability to reproduce the issues on the fixing commits I've checked group of tests: 10 tests as you asked in the issue and 3 that I've already checked. Whithin these tests results were: 3 tests: all reproduced the issue 10 tests: 4 - reproduced the issue 1 - didn't show the issue 5 - couldn't build and test too old fixes committed in 1.6 Tarantool version. To see the results with names please check the issue in github, where I've created the table of results for the checked tests. On Thu, Apr 02, 2020 at 06:44:44PM +0300, Sergey Bronnikov wrote: > Hello! > > before splitting test we had a net.box.skipcond file due to an issue > https://github.com/tarantool/tarantool/issues/4271. I believe that file > is useless now and we should add similar files for a new tests. > > I have looked on tests without postfix "gh-xxx" in a filenames. > LGTM for them: > > net.box_connect_triggers.test.lua > net.box_permissions.test.lua > net.box_reconnect_after.test.lua > net.box_get_connection_object.test.lua > > I propose to run tests with postfix "gh-xxx" in filenames on commits > before fix where bug covered by test was added. Broken test would mean > it still works. > > Sergey > > On 09:38 Thu 02 Apr , Alexander V. Tikhonov wrote: > > box/net.box_bad_argument_gh-594.test.lua > > box/net.box_call_blocks_gh-946.test.lua > > box/net.box_collectgarbage_gh-3107.test.lua > > box/net.box_connect_triggers.test.lua > > box/net.box_console_connections_gh-2677.test.lua > > box/net.box_count_inconsistent_gh-3262.test.lua > > box/net.box_discard_gh-3107.test.lua > > box/net.box_disconnect_gh-3859.test.lua > > box/net.box_fiber-async_gh-3107.test.lua > > box/net.box_field_names_gh-2978.test.lua > > box/net.box_get_connection_object.test.lua > > box/net.box_gibberish_gh-3900.test.lua > > box/net.box_huge_data_gh-983.test.lua > > box/net.box_incompatible_index-gh-1729.test.lua > > box/net.box_incorrect_iterator_gh-841.test.lua > > box/net.box_index_unique_flag_gh-4091.test.lua > > box/net.box_iproto_hangs_gh-3464.test.lua > > box/net.box_is_nullable_gh-3256.test.lua > > box/net.box_leaks_gh-3629.test.lua > > box/net.box_log_corrupted_rows_gh-4040.test.lua > > box/net.box_long-poll_input_gh-3400.test.lua > > box/net.box_methods_gh-3107.test.lua > > box/net.box_msgpack_gh-2195.test.lua > > box/net.box_on_schema_reload-gh-1904.test.lua > > box/net.box_password_gh-1545.test.lua > > box/net.box_permissions.test.lua > > box/net.box_pseudo_objects_gh-2401.test.lua > > box/net.box_raw_response_gh-3107.test.lua > > box/net.box_readahead_gh-3958.test.lua > > box/net.box_reconnect_after_gh-3164.test.lua > > box/net.box_reconnect_after.test.lua > > box/net.box_reload_schema_gh-636.test.lua > > box/net.box_remote_method_gh-544.test.lua > > box/net.box_roll_back_gh-822.test.lua > > box/net.box_schema_change_gh-2666.test.lua > > box/net.box_schema_change_gh-3107.test.lua > > box/net.box_session_type_gh-2642.test.lua > > box/net.box_space_format_gh-2402.test.lua > > box/net.box_timeout_gh-1533.test.lua > > box/net.box_timeout-gh-3107.test.lua > > box/net.box_upsert_gh-970.test.lua > > box/net.box_wait_connected_gh-3856.test.lua > > --- > > > > Github: https://github.com/tarantool/tarantool/tree/avtikhon/divide_tests > > > > test/box/gh-3107_rest1_net.box.result | 119 + > > test/box/net.box.result | 3932 ----------------- > > test/box/net.box.test.lua | 1585 ------- > > test/box/net.box_bad_argument_gh-594.result | 38 + > > test/box/net.box_bad_argument_gh-594.test.lua | 17 + > > test/box/net.box_call_blocks_gh-946.result | 124 + > > test/box/net.box_call_blocks_gh-946.test.lua | 67 + > > .../box/net.box_collectgarbage_gh-3107.result | 120 + > > .../net.box_collectgarbage_gh-3107.test.lua | 44 + > > test/box/net.box_connect_triggers.result | 82 + > > test/box/net.box_connect_triggers.test.lua | 27 + > > ...net.box_console_connections_gh-2677.result | 95 + > > ...t.box_console_connections_gh-2677.test.lua | 39 + > > .../net.box_count_inconsistent_gh-3262.result | 488 ++ > > ...et.box_count_inconsistent_gh-3262.test.lua | 182 + > > test/box/net.box_discard_gh-3107.result | 119 + > > test/box/net.box_discard_gh-3107.test.lua | 44 + > > test/box/net.box_disconnect_gh-3859.result | 113 + > > test/box/net.box_disconnect_gh-3859.test.lua | 50 + > > test/box/net.box_fiber-async_gh-3107.result | 115 + > > test/box/net.box_fiber-async_gh-3107.test.lua | 42 + > > test/box/net.box_field_names_gh-2978.result | 101 + > > test/box/net.box_field_names_gh-2978.test.lua | 29 + > > test/box/net.box_get_connection_object.result | 40 + > > .../net.box_get_connection_object.test.lua | 19 + > > test/box/net.box_gibberish_gh-3900.result | 31 + > > test/box/net.box_gibberish_gh-3900.test.lua | 13 + > > test/box/net.box_huge_data_gh-983.result | 30 + > > test/box/net.box_huge_data_gh-983.test.lua | 16 + > > .../net.box_incompatible_index-gh-1729.result | 99 + > > ...et.box_incompatible_index-gh-1729.test.lua | 33 + > > .../net.box_incorrect_iterator_gh-841.result | 497 +++ > > ...net.box_incorrect_iterator_gh-841.test.lua | 182 + > > .../net.box_index_unique_flag_gh-4091.result | 28 + > > ...net.box_index_unique_flag_gh-4091.test.lua | 15 + > > test/box/net.box_iproto_hangs_gh-3464.result | 31 + > > .../box/net.box_iproto_hangs_gh-3464.test.lua | 13 + > > test/box/net.box_is_nullable_gh-3256.result | 97 + > > test/box/net.box_is_nullable_gh-3256.test.lua | 36 + > > test/box/net.box_leaks_gh-3629.result | 51 + > > test/box/net.box_leaks_gh-3629.test.lua | 20 + > > .../net.box_log_corrupted_rows_gh-4040.result | 72 + > > ...et.box_log_corrupted_rows_gh-4040.test.lua | 31 + > > .../net.box_long-poll_input_gh-3400.result | 35 + > > .../net.box_long-poll_input_gh-3400.test.lua | 19 + > > test/box/net.box_methods_gh-3107.result | 277 ++ > > test/box/net.box_methods_gh-3107.test.lua | 96 + > > test/box/net.box_msgpack_gh-2195.result | 527 +++ > > test/box/net.box_msgpack_gh-2195.test.lua | 192 + > > .../net.box_on_schema_reload-gh-1904.result | 102 + > > .../net.box_on_schema_reload-gh-1904.test.lua | 65 + > > test/box/net.box_password_gh-1545.result | 28 + > > test/box/net.box_password_gh-1545.test.lua | 10 + > > test/box/net.box_permissions.result | 186 + > > test/box/net.box_permissions.test.lua | 66 + > > .../box/net.box_pseudo_objects_gh-2401.result | 55 + > > .../net.box_pseudo_objects_gh-2401.test.lua | 23 + > > test/box/net.box_raw_response_gh-3107.result | 123 + > > .../box/net.box_raw_response_gh-3107.test.lua | 46 + > > test/box/net.box_readahead_gh-3958.result | 55 + > > test/box/net.box_readahead_gh-3958.test.lua | 29 + > > test/box/net.box_reconnect_after.result | 32 + > > test/box/net.box_reconnect_after.test.lua | 16 + > > .../net.box_reconnect_after_gh-3164.result | 119 + > > .../net.box_reconnect_after_gh-3164.test.lua | 52 + > > test/box/net.box_reload_schema_gh-636.result | 108 + > > .../box/net.box_reload_schema_gh-636.test.lua | 46 + > > test/box/net.box_remote_method_gh-544.result | 95 + > > .../box/net.box_remote_method_gh-544.test.lua | 40 + > > test/box/net.box_roll_back_gh-822.result | 68 + > > test/box/net.box_roll_back_gh-822.test.lua | 42 + > > test/box/net.box_schema_change_gh-2666.result | 79 + > > .../net.box_schema_change_gh-2666.test.lua | 28 + > > test/box/net.box_schema_change_gh-3107.result | 151 + > > .../net.box_schema_change_gh-3107.test.lua | 55 + > > test/box/net.box_session_type_gh-2642.result | 22 + > > .../box/net.box_session_type_gh-2642.test.lua | 11 + > > test/box/net.box_space_format_gh-2402.result | 49 + > > .../box/net.box_space_format_gh-2402.test.lua | 23 + > > test/box/net.box_timeout-gh-3107.result | 125 + > > test/box/net.box_timeout-gh-3107.test.lua | 47 + > > test/box/net.box_timeout_gh-1533.result | 89 + > > test/box/net.box_timeout_gh-1533.test.lua | 45 + > > test/box/net.box_upsert_gh-970.result | 49 + > > test/box/net.box_upsert_gh-970.test.lua | 16 + > > .../box/net.box_wait_connected_gh-3856.result | 20 + > > .../net.box_wait_connected_gh-3856.test.lua | 8 + > > 87 files changed, 6778 insertions(+), 5517 deletions(-) > > create mode 100644 test/box/gh-3107_rest1_net.box.result > > delete mode 100644 test/box/net.box.result > > delete mode 100644 test/box/net.box.test.lua > > create mode 100644 test/box/net.box_bad_argument_gh-594.result > > create mode 100644 test/box/net.box_bad_argument_gh-594.test.lua > > create mode 100644 test/box/net.box_call_blocks_gh-946.result > > create mode 100644 test/box/net.box_call_blocks_gh-946.test.lua > > create mode 100644 test/box/net.box_collectgarbage_gh-3107.result > > create mode 100644 test/box/net.box_collectgarbage_gh-3107.test.lua > > create mode 100644 test/box/net.box_connect_triggers.result > > create mode 100644 test/box/net.box_connect_triggers.test.lua > > create mode 100644 test/box/net.box_console_connections_gh-2677.result > > create mode 100644 test/box/net.box_console_connections_gh-2677.test.lua > > create mode 100644 test/box/net.box_count_inconsistent_gh-3262.result > > create mode 100644 test/box/net.box_count_inconsistent_gh-3262.test.lua > > create mode 100644 test/box/net.box_discard_gh-3107.result > > create mode 100644 test/box/net.box_discard_gh-3107.test.lua > > create mode 100644 test/box/net.box_disconnect_gh-3859.result > > create mode 100644 test/box/net.box_disconnect_gh-3859.test.lua > > create mode 100644 test/box/net.box_fiber-async_gh-3107.result > > create mode 100644 test/box/net.box_fiber-async_gh-3107.test.lua > > create mode 100644 test/box/net.box_field_names_gh-2978.result > > create mode 100644 test/box/net.box_field_names_gh-2978.test.lua > > create mode 100644 test/box/net.box_get_connection_object.result > > create mode 100644 test/box/net.box_get_connection_object.test.lua > > create mode 100644 test/box/net.box_gibberish_gh-3900.result > > create mode 100644 test/box/net.box_gibberish_gh-3900.test.lua > > create mode 100644 test/box/net.box_huge_data_gh-983.result > > create mode 100644 test/box/net.box_huge_data_gh-983.test.lua > > create mode 100644 test/box/net.box_incompatible_index-gh-1729.result > > create mode 100644 test/box/net.box_incompatible_index-gh-1729.test.lua > > create mode 100644 test/box/net.box_incorrect_iterator_gh-841.result > > create mode 100644 test/box/net.box_incorrect_iterator_gh-841.test.lua > > create mode 100644 test/box/net.box_index_unique_flag_gh-4091.result > > create mode 100644 test/box/net.box_index_unique_flag_gh-4091.test.lua > > create mode 100644 test/box/net.box_iproto_hangs_gh-3464.result > > create mode 100644 test/box/net.box_iproto_hangs_gh-3464.test.lua > > create mode 100644 test/box/net.box_is_nullable_gh-3256.result > > create mode 100644 test/box/net.box_is_nullable_gh-3256.test.lua > > create mode 100644 test/box/net.box_leaks_gh-3629.result > > create mode 100644 test/box/net.box_leaks_gh-3629.test.lua > > create mode 100644 test/box/net.box_log_corrupted_rows_gh-4040.result > > create mode 100644 test/box/net.box_log_corrupted_rows_gh-4040.test.lua > > create mode 100644 test/box/net.box_long-poll_input_gh-3400.result > > create mode 100644 test/box/net.box_long-poll_input_gh-3400.test.lua > > create mode 100644 test/box/net.box_methods_gh-3107.result > > create mode 100644 test/box/net.box_methods_gh-3107.test.lua > > create mode 100644 test/box/net.box_msgpack_gh-2195.result > > create mode 100644 test/box/net.box_msgpack_gh-2195.test.lua > > create mode 100644 test/box/net.box_on_schema_reload-gh-1904.result > > create mode 100644 test/box/net.box_on_schema_reload-gh-1904.test.lua > > create mode 100644 test/box/net.box_password_gh-1545.result > > create mode 100644 test/box/net.box_password_gh-1545.test.lua > > create mode 100644 test/box/net.box_permissions.result > > create mode 100644 test/box/net.box_permissions.test.lua > > create mode 100644 test/box/net.box_pseudo_objects_gh-2401.result > > create mode 100644 test/box/net.box_pseudo_objects_gh-2401.test.lua > > create mode 100644 test/box/net.box_raw_response_gh-3107.result > > create mode 100644 test/box/net.box_raw_response_gh-3107.test.lua > > create mode 100644 test/box/net.box_readahead_gh-3958.result > > create mode 100644 test/box/net.box_readahead_gh-3958.test.lua > > create mode 100644 test/box/net.box_reconnect_after.result > > create mode 100644 test/box/net.box_reconnect_after.test.lua > > create mode 100644 test/box/net.box_reconnect_after_gh-3164.result > > create mode 100644 test/box/net.box_reconnect_after_gh-3164.test.lua > > create mode 100644 test/box/net.box_reload_schema_gh-636.result > > create mode 100644 test/box/net.box_reload_schema_gh-636.test.lua > > create mode 100644 test/box/net.box_remote_method_gh-544.result > > create mode 100644 test/box/net.box_remote_method_gh-544.test.lua > > create mode 100644 test/box/net.box_roll_back_gh-822.result > > create mode 100644 test/box/net.box_roll_back_gh-822.test.lua > > create mode 100644 test/box/net.box_schema_change_gh-2666.result > > create mode 100644 test/box/net.box_schema_change_gh-2666.test.lua > > create mode 100644 test/box/net.box_schema_change_gh-3107.result > > create mode 100644 test/box/net.box_schema_change_gh-3107.test.lua > > create mode 100644 test/box/net.box_session_type_gh-2642.result > > create mode 100644 test/box/net.box_session_type_gh-2642.test.lua > > create mode 100644 test/box/net.box_space_format_gh-2402.result > > create mode 100644 test/box/net.box_space_format_gh-2402.test.lua > > create mode 100644 test/box/net.box_timeout-gh-3107.result > > create mode 100644 test/box/net.box_timeout-gh-3107.test.lua > > create mode 100644 test/box/net.box_timeout_gh-1533.result > > create mode 100644 test/box/net.box_timeout_gh-1533.test.lua > > create mode 100644 test/box/net.box_upsert_gh-970.result > > create mode 100644 test/box/net.box_upsert_gh-970.test.lua > > create mode 100644 test/box/net.box_wait_connected_gh-3856.result > > create mode 100644 test/box/net.box_wait_connected_gh-3856.test.lua > > > > diff --git a/test/box/gh-3107_rest1_net.box.result b/test/box/gh-3107_rest1_net.box.result > > new file mode 100644 > > index 000000000..d9c59d1cf > > --- /dev/null > > +++ b/test/box/gh-3107_rest1_net.box.result > > @@ -0,0 +1,119 @@ > > +fiber = require 'fiber' > > +--- > > +... > > +net = require('net.box') > > +--- > > +... > > +-- > > +-- gh-3107: fiber-async netbox. > > +-- > > +cond = nil > > +--- > > +... > > +box.schema.func.create('long_function') > > +--- > > +... > > +box.schema.user.grant('guest', 'execute', 'function', 'long_function') > > +--- > > +... > > +function long_function(...) cond = fiber.cond() cond:wait() return ... end > > +--- > > +... > > +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end > > +--- > > +... > > +s = box.schema.create_space('test') > > +--- > > +... > > +pk = s:create_index('pk') > > +--- > > +... > > +s:replace{1} > > +--- > > +- [1] > > +... > > +s:replace{2} > > +--- > > +- [2] > > +... > > +s:replace{3} > > +--- > > +- [3] > > +... > > +s:replace{4} > > +--- > > +- [4] > > +... > > +c = net:connect(box.cfg.listen) > > +--- > > +... > > +-- > > +-- Check infinity timeout. > > +-- > > +ret = nil > > +--- > > +... > > +_ = fiber.create(function() ret = c:call('long_function', {1, 2, 3}, {is_async = true}):wait_result() end) > > +--- > > +... > > +finalize_long() > > +--- > > +... > > +while not ret do fiber.sleep(0.01) end > > +--- > > +... > > +ret > > +--- > > +- [1, 2, 3] > > +... > > +c:close() > > +--- > > +... > > +box.schema.user.grant('guest', 'execute', 'universe') > > +--- > > +... > > +c = net:connect(box.cfg.listen) > > +--- > > +... > > +future = c:eval('return long_function(...)', {1, 2, 3}, {is_async = true}) > > +--- > > +... > > +future:result() > > +--- > > +- null > > +- Response is not ready > > +... > > +future:wait_result(0.01) -- Must fail on timeout. > > +--- > > +- null > > +- Timeout exceeded > > +... > > +finalize_long() > > +--- > > +... > > +future:wait_result(100) > > +--- > > +- [1, 2, 3] > > +... > > +c:close() > > +--- > > +... > > +-- > > +-- Check that is_async does not work on a closed connection. > > +-- > > +c:call('any_func', {}, {is_async = true}) > > +--- > > +- error: Connection closed > > +... > > +box.schema.user.revoke('guest', 'execute', 'universe') > > +--- > > +... > > +c = net:connect(box.cfg.listen) > > +--- > > +... > > +c:close() > > +--- > > +... > > +s:drop() > > +--- > > +... > > diff --git a/test/box/net.box.result b/test/box/net.box.result > > deleted file mode 100644 > > index e3dabf7d9..000000000 > > --- a/test/box/net.box.result > > +++ /dev/null > > @@ -1,3932 +0,0 @@ > > -remote = require 'net.box' > > ---- > > -... > > -fiber = require 'fiber' > > ---- > > -... > > -log = require 'log' > > ---- > > -... > > -msgpack = require 'msgpack' > > ---- > > -... > > -env = require('test_run') > > ---- > > -... > > -test_run = env.new() > > ---- > > -... > > -test_run:cmd("push filter ".."'\\.lua.*:[0-9]+: ' to '.lua...\"]:<line>: '") > > ---- > > -- true > > -... > > -test_run:cmd("setopt delimiter ';'") > > ---- > > -- true > > -... > > -function x_select(cn, space_id, index_id, iterator, offset, limit, key, opts) > > - local ret = cn:_request('select', opts, nil, space_id, index_id, iterator, > > - offset, limit, key) > > - return ret > > -end > > -function x_fatal(cn) cn._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') end > > -test_run:cmd("setopt delimiter ''"); > > ---- > > -... > > -LISTEN = require('uri').parse(box.cfg.listen) > > ---- > > -... > > -space = box.schema.space.create('net_box_test_space') > > ---- > > -... > > -index = space:create_index('primary', { type = 'tree' }) > > ---- > > -... > > --- low level connection > > -log.info("create connection") > > ---- > > -... > > -cn = remote.connect(LISTEN.host, LISTEN.service) > > ---- > > -... > > -log.info("state is %s", cn.state) > > ---- > > -... > > -cn:ping() > > ---- > > -- true > > -... > > -log.info("ping is done") > > ---- > > -... > > -cn:ping() > > ---- > > -- true > > -... > > -log.info("ping is done") > > ---- > > -... > > -cn:ping() > > ---- > > -- true > > -... > > --- check permissions > > -cn:call('unexists_procedure') > > ---- > > -- error: Execute access to function 'unexists_procedure' is denied for user 'guest' > > -... > > -function test_foo(a,b,c) return { {{ [a] = 1 }}, {{ [b] = 2 }}, c } end > > ---- > > -... > > -cn:call('test_foo', {'a', 'b', 'c'}) > > ---- > > -- error: Execute access to function 'test_foo' is denied for user 'guest' > > -... > > -cn:eval('return 2+2') > > ---- > > -- error: Execute access to universe '' is denied for user 'guest' > > -... > > -cn:close() > > ---- > > -... > > --- connect and call without usage access > > -box.schema.user.grant('guest','execute','universe') > > ---- > > -... > > -box.schema.user.revoke('guest','usage','universe') > > ---- > > -... > > -box.session.su("guest") > > ---- > > -... > > -cn = remote.connect(LISTEN.host, LISTEN.service) > > ---- > > -... > > -cn:call('test_foo', {'a', 'b', 'c'}) > > ---- > > -- error: Usage access to universe '' is denied for user 'guest' > > -... > > -box.session.su("admin") > > ---- > > -... > > -box.schema.user.grant('guest','usage','universe') > > ---- > > -... > > -cn:close() > > ---- > > -... > > -cn = remote.connect(box.cfg.listen) > > ---- > > -... > > -cn:call('unexists_procedure') > > ---- > > -- error: Procedure 'unexists_procedure' is not defined > > -... > > -cn:call('test_foo', {'a', 'b', 'c'}) > > ---- > > -- [[{'a': 1}], [{'b': 2}], 'c'] > > -... > > -cn:call(nil, {'a', 'b', 'c'}) > > ---- > > -- error: Procedure 'nil' is not defined > > -... > > -cn:eval('return 2+2') > > ---- > > -- 4 > > -... > > -cn:eval('return 1, 2, 3') > > ---- > > -- 1 > > -- 2 > > -- 3 > > -... > > -cn:eval('return ...', {1, 2, 3}) > > ---- > > -- 1 > > -- 2 > > -- 3 > > -... > > -cn:eval('return { k = "v1" }, true, { xx = 10, yy = 15 }, nil') > > ---- > > -- {'k': 'v1'} > > -- true > > -- {'yy': 15, 'xx': 10} > > -- null > > -... > > -cn:eval('return nil') > > ---- > > -- null > > -... > > -cn:eval('return') > > ---- > > -... > > -cn:eval('error("exception")') > > ---- > > -- error: 'eval:1: exception' > > -... > > -cn:eval('box.error(0)') > > ---- > > -- error: Unknown error > > -... > > -cn:eval('!invalid expression') > > ---- > > -- error: 'eval:1: unexpected symbol near ''!''' > > -... > > --- box.commit() missing at return of CALL/EVAL > > -function no_commit() box.begin() fiber.sleep(0.001) end > > ---- > > -... > > -cn:call('no_commit') > > ---- > > -- error: Transaction is active at return from function > > -... > > -cn:eval('no_commit()') > > ---- > > -- error: Transaction is active at return from function > > -... > > -remote.self:eval('return 1+1, 2+2') > > ---- > > -- 2 > > -- 4 > > -... > > -remote.self:eval('return') > > ---- > > -... > > -remote.self:eval('error("exception")') > > ---- > > -- error: '[string "error("exception")"]:1: exception' > > -... > > -remote.self:eval('box.error(0)') > > ---- > > -- error: Unknown error > > -... > > -remote.self:eval('!invalid expression') > > ---- > > -- error: '[string "return !invalid expression"]:1: unexpected symbol near ''!''' > > -... > > -box.schema.user.revoke('guest', 'execute', 'universe') > > ---- > > -... > > --- > > --- gh-822: net.box.call should roll back local transaction on error > > --- > > -_ = box.schema.space.create('gh822') > > ---- > > -... > > -_ = box.space.gh822:create_index('primary') > > ---- > > -... > > -test_run:cmd("setopt delimiter ';'") > > ---- > > -- true > > -... > > --- rollback on invalid function > > -function rollback_on_invalid_function() > > - box.begin() > > - box.space.gh822:insert{1, "netbox_test"} > > - pcall(remote.self.call, remote.self, 'invalid_function') > > - return box.space.gh822:get(1) == nil > > -end; > > ---- > > -... > > -rollback_on_invalid_function(); > > ---- > > -- true > > -... > > --- rollback on call error > > -function test_error() error('Some error') end; > > ---- > > -... > > -function rollback_on_call_error() > > - box.begin() > > - box.space.gh822:insert{1, "netbox_test"} > > - pcall(remote.self.call, remote.self, 'test_error') > > - return box.space.gh822:get(1) == nil > > -end; > > ---- > > -... > > -rollback_on_call_error(); > > ---- > > -- true > > -... > > --- rollback on eval > > -function rollback_on_eval_error() > > - box.begin() > > - box.space.gh822:insert{1, "netbox_test"} > > - pcall(remote.self.eval, remote.self, "error('Some error')") > > - return box.space.gh822:get(1) == nil > > -end; > > ---- > > -... > > -rollback_on_eval_error(); > > ---- > > -- true > > -... > > -test_run:cmd("setopt delimiter ''"); > > ---- > > -- true > > -... > > -box.space.gh822:drop() > > ---- > > -... > > -box.schema.user.grant('guest', 'read,write', 'space', 'net_box_test_space') > > ---- > > -... > > -box.schema.user.grant('guest', 'execute', 'universe') > > ---- > > -... > > -cn:close() > > ---- > > -... > > -cn = remote.connect(box.cfg.listen) > > ---- > > -... > > -x_select(cn, space.id, space.index.primary.id, box.index.EQ, 0, 0xFFFFFFFF, 123) > > ---- > > -- [] > > -... > > -space:insert{123, 345} > > ---- > > -- [123, 345] > > -... > > -x_select(cn, space.id, space.index.primary.id, box.index.EQ, 0, 0, 123) > > ---- > > -- [] > > -... > > -x_select(cn, space.id, space.index.primary.id, box.index.EQ, 0, 1, 123) > > ---- > > -- - [123, 345] > > -... > > -x_select(cn, space.id, space.index.primary.id, box.index.EQ, 1, 1, 123) > > ---- > > -- [] > > -... > > -cn.space[space.id] ~= nil > > ---- > > -- true > > -... > > -cn.space.net_box_test_space ~= nil > > ---- > > -- true > > -... > > -cn.space.net_box_test_space ~= nil > > ---- > > -- true > > -... > > -cn.space.net_box_test_space.index ~= nil > > ---- > > -- true > > -... > > -cn.space.net_box_test_space.index.primary ~= nil > > ---- > > -- true > > -... > > -cn.space.net_box_test_space.index[space.index.primary.id] ~= nil > > ---- > > -- true > > -... > > -cn.space.net_box_test_space.index.primary:select(123) > > ---- > > -- - [123, 345] > > -... > > -cn.space.net_box_test_space.index.primary:select(123, { limit = 0 }) > > ---- > > -- [] > > -... > > -cn.space.net_box_test_space.index.primary:select(nil, { limit = 1, }) > > ---- > > -- - [123, 345] > > -... > > -cn.space.net_box_test_space:insert{234, 1,2,3} > > ---- > > -- [234, 1, 2, 3] > > -... > > -cn.space.net_box_test_space:insert{234, 1,2,3} > > ---- > > -- error: Duplicate key exists in unique index 'primary' in space 'net_box_test_space' > > -... > > -cn.space.net_box_test_space.insert{234, 1,2,3} > > ---- > > -- error: 'builtin/box/schema.lua..."]:<line>: Use space:insert(...) instead of space.insert(...)' > > -... > > -cn.space.net_box_test_space:replace{354, 1,2,3} > > ---- > > -- [354, 1, 2, 3] > > -... > > -cn.space.net_box_test_space:replace{354, 1,2,4} > > ---- > > -- [354, 1, 2, 4] > > -... > > -cn.space.net_box_test_space:select{123} > > ---- > > -- - [123, 345] > > -... > > -space:select({123}, { iterator = 'GE' }) > > ---- > > -- - [123, 345] > > - - [234, 1, 2, 3] > > - - [354, 1, 2, 4] > > -... > > -cn.space.net_box_test_space:select({123}, { iterator = 'GE' }) > > ---- > > -- - [123, 345] > > - - [234, 1, 2, 3] > > - - [354, 1, 2, 4] > > -... > > -cn.space.net_box_test_space:select({123}, { iterator = 'GT' }) > > ---- > > -- - [234, 1, 2, 3] > > - - [354, 1, 2, 4] > > -... > > -cn.space.net_box_test_space:select({123}, { iterator = 'GT', limit = 1 }) > > ---- > > -- - [234, 1, 2, 3] > > -... > > -cn.space.net_box_test_space:select({123}, { iterator = 'GT', limit = 1, offset = 1 }) > > ---- > > -- - [354, 1, 2, 4] > > -... > > -cn.space.net_box_test_space:select{123} > > ---- > > -- - [123, 345] > > -... > > -cn.space.net_box_test_space:update({123}, { { '+', 2, 1 } }) > > ---- > > -- [123, 346] > > -... > > -cn.space.net_box_test_space:update(123, { { '+', 2, 1 } }) > > ---- > > -- [123, 347] > > -... > > -cn.space.net_box_test_space:select{123} > > ---- > > -- - [123, 347] > > -... > > -cn.space.net_box_test_space:insert(cn.space.net_box_test_space:get{123}:update{ { '=', 1, 2 } }) > > ---- > > -- [2, 347] > > -... > > -cn.space.net_box_test_space:delete{123} > > ---- > > -- [123, 347] > > -... > > -cn.space.net_box_test_space:select{2} > > ---- > > -- - [2, 347] > > -... > > -cn.space.net_box_test_space:select({234}, { iterator = 'LT' }) > > ---- > > -- - [2, 347] > > -... > > -cn.space.net_box_test_space:update({1}, { { '+', 2, 2 } }) > > ---- > > -... > > -cn.space.net_box_test_space:delete{1} > > ---- > > -... > > -cn.space.net_box_test_space:delete{2} > > ---- > > -- [2, 347] > > -... > > -cn.space.net_box_test_space:delete{2} > > ---- > > -... > > --- test one-based indexing in splice operation (see update.test.lua) > > -cn.space.net_box_test_space:replace({10, 'abcde'}) > > ---- > > -- [10, 'abcde'] > > -... > > -cn.space.net_box_test_space:update(10, {{':', 2, 0, 0, '!'}}) > > ---- > > -- error: 'SPLICE error on field 2: offset is out of bound' > > -... > > -cn.space.net_box_test_space:update(10, {{':', 2, 1, 0, '('}}) > > ---- > > -- [10, '(abcde'] > > -... > > -cn.space.net_box_test_space:update(10, {{':', 2, 2, 0, '({'}}) > > ---- > > -- [10, '(({abcde'] > > -... > > -cn.space.net_box_test_space:update(10, {{':', 2, -1, 0, ')'}}) > > ---- > > -- [10, '(({abcde)'] > > -... > > -cn.space.net_box_test_space:update(10, {{':', 2, -2, 0, '})'}}) > > ---- > > -- [10, '(({abcde}))'] > > -... > > -cn.space.net_box_test_space:delete{10} > > ---- > > -- [10, '(({abcde}))'] > > -... > > -cn.space.net_box_test_space:select({}, { iterator = 'ALL' }) > > ---- > > -- - [234, 1, 2, 3] > > - - [354, 1, 2, 4] > > -... > > --- gh-841: net.box uses incorrect iterator type for select with no arguments > > -cn.space.net_box_test_space:select() > > ---- > > -- - [234, 1, 2, 3] > > - - [354, 1, 2, 4] > > -... > > -cn.space.net_box_test_space.index.primary:min() > > ---- > > -- [234, 1, 2, 3] > > -... > > -cn.space.net_box_test_space.index.primary:min(354) > > ---- > > -- [354, 1, 2, 4] > > -... > > -cn.space.net_box_test_space.index.primary:max() > > ---- > > -- [354, 1, 2, 4] > > -... > > -cn.space.net_box_test_space.index.primary:max(234) > > ---- > > -- [234, 1, 2, 3] > > -... > > -cn.space.net_box_test_space.index.primary:count() > > ---- > > -- 2 > > -... > > -cn.space.net_box_test_space.index.primary:count(354) > > ---- > > -- 1 > > -... > > -cn.space.net_box_test_space:get(354) > > ---- > > -- [354, 1, 2, 4] > > -... > > --- reconnects after errors > > -box.schema.user.revoke('guest', 'execute', 'universe') > > ---- > > -... > > -box.schema.func.create('test_foo') > > ---- > > -... > > -box.schema.user.grant('guest', 'execute', 'function', 'test_foo') > > ---- > > -... > > --- -- 1. no reconnect > > -x_fatal(cn) > > ---- > > -... > > -cn.state > > ---- > > -- error > > -... > > -cn:ping() > > ---- > > -- false > > -... > > -cn:call('test_foo') > > ---- > > -- error: Peer closed > > -... > > -cn:wait_state('active') > > ---- > > -- false > > -... > > --- -- 2 reconnect > > -cn = remote.connect(LISTEN.host, LISTEN.service, { reconnect_after = .1 }) > > ---- > > -... > > -cn.space ~= nil > > ---- > > -- true > > -... > > -cn.space.net_box_test_space:select({}, { iterator = 'ALL' }) > > ---- > > -- - [234, 1, 2, 3] > > - - [354, 1, 2, 4] > > -... > > -x_fatal(cn) > > ---- > > -... > > -cn:wait_connected() > > ---- > > -- true > > -... > > -cn:wait_state('active') > > ---- > > -- true > > -... > > -cn:wait_state({active=true}) > > ---- > > -- true > > -... > > -cn:ping() > > ---- > > -- true > > -... > > -cn.state > > ---- > > -- active > > -... > > -cn.space.net_box_test_space:select({}, { iterator = 'ALL' }) > > ---- > > -- - [234, 1, 2, 3] > > - - [354, 1, 2, 4] > > -... > > -x_fatal(cn) > > ---- > > -... > > -x_select(cn, space.id, 0, box.index.ALL, 0, 0xFFFFFFFF, {}) > > ---- > > -- - [234, 1, 2, 3] > > - - [354, 1, 2, 4] > > -... > > -cn.state > > ---- > > -- active > > -... > > -cn:ping() > > ---- > > -- true > > -... > > --- -- dot-new-method > > -cn1 = remote.new(LISTEN.host, LISTEN.service) > > ---- > > -... > > -x_select(cn1, space.id, 0, box.index.ALL, 0, 0xFFFFFFF, {}) > > ---- > > -- - [234, 1, 2, 3] > > - - [354, 1, 2, 4] > > -... > > -cn1:close() > > ---- > > -... > > --- -- error while waiting for response > > -type(fiber.create(function() fiber.sleep(.5) x_fatal(cn) end)) > > ---- > > -- userdata > > -... > > -function pause() fiber.sleep(10) return true end > > ---- > > -... > > -box.schema.func.create('pause') > > ---- > > -... > > -box.schema.user.grant('guest', 'execute', 'function', 'pause') > > ---- > > -... > > -cn:call('pause') > > ---- > > -- error: Peer closed > > -... > > -cn:call('test_foo', {'a', 'b', 'c'}) > > ---- > > -- [[{'a': 1}], [{'b': 2}], 'c'] > > -... > > -box.schema.func.drop('pause') > > ---- > > -... > > --- call > > -remote.self:call('test_foo', {'a', 'b', 'c'}) > > ---- > > -- - - a: 1 > > - - - b: 2 > > - - c > > -... > > -cn:call('test_foo', {'a', 'b', 'c'}) > > ---- > > -- [[{'a': 1}], [{'b': 2}], 'c'] > > -... > > -box.schema.func.drop('test_foo') > > ---- > > -... > > -box.schema.func.create('long_rep') > > ---- > > -... > > -box.schema.user.grant('guest', 'execute', 'function', 'long_rep') > > ---- > > -... > > --- long replies > > -function long_rep() return { 1, string.rep('a', 5000) } end > > ---- > > -... > > -res = cn:call('long_rep') > > ---- > > -... > > -res[1] == 1 > > ---- > > -- true > > -... > > -res[2] == string.rep('a', 5000) > > ---- > > -- true > > -... > > -function long_rep() return { 1, string.rep('a', 50000) } end > > ---- > > -... > > -res = cn:call('long_rep') > > ---- > > -... > > -res[1] == 1 > > ---- > > -- true > > -... > > -res[2] == string.rep('a', 50000) > > ---- > > -- true > > -... > > -box.schema.func.drop('long_rep') > > ---- > > -... > > --- a.b.c.d > > -u = '84F7BCFA-079C-46CC-98B4-F0C821BE833E' > > ---- > > -... > > -X = {} > > ---- > > -... > > -X.X = X > > ---- > > -... > > -function X.fn(x,y) return y or x end > > ---- > > -... > > -box.schema.user.grant('guest', 'execute', 'universe') > > ---- > > -... > > -cn:close() > > ---- > > -... > > -cn = remote.connect(LISTEN.host, LISTEN.service) > > ---- > > -... > > -cn:call('X.fn', {u}) > > ---- > > -- 84F7BCFA-079C-46CC-98B4-F0C821BE833E > > -... > > -cn:call('X.X.X.X.X.X.X.fn', {u}) > > ---- > > -- 84F7BCFA-079C-46CC-98B4-F0C821BE833E > > -... > > -cn:call('X.X.X.X:fn', {u}) > > ---- > > -- 84F7BCFA-079C-46CC-98B4-F0C821BE833E > > -... > > -box.schema.user.revoke('guest', 'execute', 'universe') > > ---- > > -... > > -cn:close() > > ---- > > -... > > --- auth > > -cn = remote.connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123', wait_connected = true }) > > ---- > > -... > > -cn:is_connected() > > ---- > > -- false > > -... > > -cn.error > > ---- > > -- User 'netbox' is not found > > -... > > -cn.state > > ---- > > -- error > > -... > > -box.schema.user.create('netbox', { password = 'test' }) > > ---- > > -... > > -box.schema.user.grant('netbox', 'read,write', 'space', 'net_box_test_space') > > ---- > > -... > > -box.schema.user.grant('netbox', 'execute', 'universe') > > ---- > > -... > > -cn = remote.connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = 'test' }) > > ---- > > -... > > -cn.state > > ---- > > -- active > > -... > > -cn.error > > ---- > > -- null > > -... > > -cn:ping() > > ---- > > -- true > > -... > > -function ret_after(to) fiber.sleep(to) return {{to}} end > > ---- > > -... > > -cn:ping({timeout = 1.00}) > > ---- > > -- true > > -... > > -cn:ping({timeout = 1e-9}) > > ---- > > -- false > > -... > > -cn:ping() > > ---- > > -- true > > -... > > -remote_space = cn.space.net_box_test_space > > ---- > > -... > > -remote_pk = remote_space.index.primary > > ---- > > -... > > -remote_space:insert({0}, { timeout = 1.00 }) > > ---- > > -- [0] > > -... > > -remote_space:insert({1}, { timeout = 1e-9 }) > > ---- > > -- error: Timeout exceeded > > -... > > -remote_space:insert({2}) > > ---- > > -- [2] > > -... > > -remote_space:replace({0}, { timeout = 1e-9 }) > > ---- > > -- error: Timeout exceeded > > -... > > -remote_space:replace({1}) > > ---- > > -- [1] > > -... > > -remote_space:replace({2}, { timeout = 1.00 }) > > ---- > > -- [2] > > -... > > -remote_space:upsert({3}, {}, { timeout = 1e-9 }) > > ---- > > -- error: Timeout exceeded > > -... > > -remote_space:upsert({4}, {}) > > ---- > > -... > > -remote_space:upsert({5}, {}, { timeout = 1.00 }) > > ---- > > -... > > -remote_space:upsert({3}, {}) > > ---- > > -... > > -remote_space:update({3}, {}, { timeout = 1e-9 }) > > ---- > > -- error: Timeout exceeded > > -... > > -remote_space:update({4}, {}) > > ---- > > -- [4] > > -... > > -remote_space:update({5}, {}, { timeout = 1.00 }) > > ---- > > -- [5] > > -... > > -remote_space:update({3}, {}) > > ---- > > -- [3] > > -... > > -remote_pk:update({5}, {}, { timeout = 1e-9 }) > > ---- > > -- error: Timeout exceeded > > -... > > -remote_pk:update({4}, {}) > > ---- > > -- [4] > > -... > > -remote_pk:update({3}, {}, { timeout = 1.00 }) > > ---- > > -- [3] > > -... > > -remote_pk:update({5}, {}) > > ---- > > -- [5] > > -... > > -remote_space:get({0}) > > ---- > > -- [0] > > -... > > -remote_space:get({1}, { timeout = 1.00 }) > > ---- > > -- [1] > > -... > > -remote_space:get({2}, { timeout = 1e-9 }) > > ---- > > -- error: Timeout exceeded > > -... > > -remote_pk:get({3}, { timeout = 1e-9 }) > > ---- > > -- error: Timeout exceeded > > -... > > -remote_pk:get({4}) > > ---- > > -- [4] > > -... > > -remote_pk:get({5}, { timeout = 1.00 }) > > ---- > > -- [5] > > -... > > -remote_space:select({2}, { timeout = 1e-9 }) > > ---- > > -- error: Timeout exceeded > > -... > > -remote_space:select({2}, { timeout = 1.00 }) > > ---- > > -- - [2] > > -... > > -remote_space:select({2}) > > ---- > > -- - [2] > > -... > > -remote_pk:select({2}, { timeout = 1.00 }) > > ---- > > -- - [2] > > -... > > -remote_pk:select({2}, { timeout = 1e-9 }) > > ---- > > -- error: Timeout exceeded > > -... > > -remote_pk:select({2}) > > ---- > > -- - [2] > > -... > > -remote_space:select({5}, { timeout = 1.00, iterator = 'LE', limit = 5 }) > > ---- > > -- - [5] > > - - [4] > > - - [3] > > - - [2] > > - - [1] > > -... > > -remote_space:select({5}, { iterator = 'LE', limit = 5}) > > ---- > > -- - [5] > > - - [4] > > - - [3] > > - - [2] > > - - [1] > > -... > > -remote_space:select({5}, { timeout = 1e-9, iterator = 'LE', limit = 5 }) > > ---- > > -- error: Timeout exceeded > > -... > > -remote_pk:select({2}, { timeout = 1.00, iterator = 'LE', limit = 5 }) > > ---- > > -- - [2] > > - - [1] > > - - [0] > > -... > > -remote_pk:select({2}, { iterator = 'LE', limit = 5}) > > ---- > > -- - [2] > > - - [1] > > - - [0] > > -... > > -remote_pk:select({2}, { timeout = 1e-9, iterator = 'LE', limit = 5 }) > > ---- > > -- error: Timeout exceeded > > -... > > -remote_pk:count({2}, { timeout = 1.00}) > > ---- > > -- 1 > > -... > > -remote_pk:count({2}, { timeout = 1e-9}) > > ---- > > -- error: Timeout exceeded > > -... > > -remote_pk:count({2}) > > ---- > > -- 1 > > -... > > -remote_pk:count({2}, { timeout = 1.00, iterator = 'LE' }) > > ---- > > -- 3 > > -... > > -remote_pk:count({2}, { iterator = 'LE'}) > > ---- > > -- 3 > > -... > > -remote_pk:count({2}, { timeout = 1e-9, iterator = 'LE' }) > > ---- > > -- error: Timeout exceeded > > -... > > -remote_pk:min(nil, { timeout = 1.00 }) > > ---- > > -- [0] > > -... > > -remote_pk:min(nil, { timeout = 1e-9 }) > > ---- > > -- error: Timeout exceeded > > -... > > -remote_pk:min(nil) > > ---- > > -- [0] > > -... > > -remote_pk:min({0}, { timeout = 1e-9 }) > > ---- > > -- error: Timeout exceeded > > -... > > -remote_pk:min({1}) > > ---- > > -- [1] > > -... > > -remote_pk:min({2}, { timeout = 1.00 }) > > ---- > > -- [2] > > -... > > -remote_pk:max(nil) > > ---- > > -- [354, 1, 2, 4] > > -... > > -remote_pk:max(nil, { timeout = 1e-9 }) > > ---- > > -- error: Timeout exceeded > > -... > > -remote_pk:max(nil, { timeout = 1.00 }) > > ---- > > -- [354, 1, 2, 4] > > -... > > -remote_pk:max({0}, { timeout = 1.00 }) > > ---- > > -- [0] > > -... > > -remote_pk:max({1}, { timeout = 1e-9 }) > > ---- > > -- error: Timeout exceeded > > -... > > -remote_pk:max({2}) > > ---- > > -- [2] > > -... > > --- > > --- gh-3262: index:count() inconsistent results > > --- > > -test_run:cmd("setopt delimiter ';'") > > ---- > > -- true > > -... > > -function do_count_test(min, it) > > - local r1 = remote_pk:count(min, {iterator = it} ) > > - local r2 = box.space.net_box_test_space.index.primary:count(min, {iterator = it} ) > > - local r3 = remote.self.space.net_box_test_space.index.primary:count(min, {iterator = it} ) > > - return r1 == r2 and r2 == r3 > > -end; > > ---- > > -... > > -data = remote_pk:select(); > > ---- > > -... > > -for _, v in pairs(data) do > > - local itrs = {'GE', 'GT', 'LE', 'LT' } > > - for _, it in pairs(itrs) do > > - assert(do_count_test(v[0], it) == true) > > - end > > -end; > > ---- > > -... > > -test_run:cmd("setopt delimiter ''"); > > ---- > > -- true > > -... > > -_ = remote_space:delete({0}, { timeout = 1e-9 }) > > ---- > > -- error: Timeout exceeded > > -... > > -_ = remote_pk:delete({0}, { timeout = 1.00 }) > > ---- > > -... > > -_ = remote_space:delete({1}, { timeout = 1.00 }) > > ---- > > -... > > -_ = remote_pk:delete({1}, { timeout = 1e-9 }) > > ---- > > -- error: Timeout exceeded > > -... > > -_ = remote_space:delete({2}, { timeout = 1e-9 }) > > ---- > > -- error: Timeout exceeded > > -... > > -_ = remote_pk:delete({2}) > > ---- > > -... > > -_ = remote_pk:delete({3}) > > ---- > > -... > > -_ = remote_pk:delete({4}) > > ---- > > -... > > -_ = remote_pk:delete({5}) > > ---- > > -... > > -remote_space:get(0) > > ---- > > -... > > -remote_space:get(1) > > ---- > > -... > > -remote_space:get(2) > > ---- > > -... > > -remote_space = nil > > ---- > > -... > > -cn:call('ret_after', {0.01}, { timeout = 1.00 }) > > ---- > > -- [[0.01]] > > -... > > -cn:call('ret_after', {1.00}, { timeout = 1e-9 }) > > ---- > > -- error: Timeout exceeded > > -... > > -cn:eval('return ret_after(...)', {0.01}, { timeout = 1.00 }) > > ---- > > -- [[0.01]] > > -... > > -cn:eval('return ret_after(...)', {1.00}, { timeout = 1e-9 }) > > ---- > > -- error: Timeout exceeded > > -... > > --- > > --- :timeout() > > --- @deprecated since 1.7.4 > > --- > > -cn:timeout(1).space.net_box_test_space.index.primary:select{234} > > ---- > > -- - [234, 1, 2, 3] > > -... > > -cn:call('ret_after', {.01}) > > ---- > > -- [[0.01]] > > -... > > -cn:timeout(1):call('ret_after', {.01}) > > ---- > > -- [[0.01]] > > -... > > -cn:timeout(.01):call('ret_after', {1}) > > ---- > > -- error: Timeout exceeded > > -... > > -cn = remote:timeout(0.0000000001):connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123' }) > > ---- > > -... > > -cn:close() > > ---- > > -... > > -cn = remote:timeout(1):connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123' }) > > ---- > > -... > > -remote.self:ping() > > ---- > > -- true > > -... > > -remote.self.space.net_box_test_space:select{234} > > ---- > > -- - [234, 1, 2, 3] > > -... > > -remote.self:timeout(123).space.net_box_test_space:select{234} > > ---- > > -- - [234, 1, 2, 3] > > -... > > -remote.self:is_connected() > > ---- > > -- true > > -... > > -remote.self:wait_connected() > > ---- > > -- true > > -... > > -cn:close() > > ---- > > -... > > --- cleanup database after tests > > -space:drop() > > ---- > > -... > > --- #1545 empty password > > -cn = remote.connect(LISTEN.host, LISTEN.service, { user = 'test' }) > > ---- > > -... > > -cn ~= nil > > ---- > > -- true > > -... > > -cn:close() > > ---- > > -... > > -cn = remote.connect(LISTEN.host, LISTEN.service, { password = 'test' }) > > ---- > > -- error: 'net.box: user is not defined' > > -... > > -cn ~= nil > > ---- > > -- true > > -... > > -cn:close() > > ---- > > -... > > --- #544 usage for remote[point]method > > -cn = remote.connect(LISTEN.host, LISTEN.service) > > ---- > > -... > > -box.schema.user.grant('guest', 'execute', 'universe') > > ---- > > -... > > -cn:close() > > ---- > > -... > > -cn = remote.connect(LISTEN.host, LISTEN.service) > > ---- > > -... > > -cn:eval('return true') > > ---- > > -- true > > -... > > -cn.eval('return true') > > ---- > > -- error: 'Use remote:eval(...) instead of remote.eval(...):' > > -... > > -cn.ping() > > ---- > > -- error: 'Use remote:ping(...) instead of remote.ping(...):' > > -... > > -cn:close() > > ---- > > -... > > -remote.self:eval('return true') > > ---- > > -- true > > -... > > -remote.self.eval('return true') > > ---- > > -- error: 'Use remote:eval(...) instead of remote.eval(...):' > > -... > > -box.schema.user.revoke('guest', 'execute', 'universe') > > ---- > > -... > > --- uri as the first argument > > -uri = string.format('%s:%s@%s:%s', 'netbox', 'test', LISTEN.host, LISTEN.service) > > ---- > > -... > > -cn = remote.new(uri) > > ---- > > -... > > -cn:ping() > > ---- > > -- true > > -... > > -cn:close() > > ---- > > -... > > -uri = string.format('%s@%s:%s', 'netbox', LISTEN.host, LISTEN.service) > > ---- > > -... > > -cn = remote.new(uri) > > ---- > > -... > > -cn ~= nil, cn.state, cn.error > > ---- > > -- true > > -- error > > -- Incorrect password supplied for user 'netbox' > > -... > > -cn:close() > > ---- > > -... > > --- don't merge creds from uri & opts > > -remote.new(uri, { password = 'test' }) > > ---- > > -- error: 'net.box: user is not defined' > > -... > > -cn = remote.new(uri, { user = 'netbox', password = 'test' }) > > ---- > > -... > > -cn:ping() > > ---- > > -- true > > -... > > -cn:close() > > ---- > > -... > > -box.schema.user.drop('netbox') > > ---- > > -... > > --- #594: bad argument #1 to 'setmetatable' (table expected, got number) > > -box.schema.func.create('dostring') > > ---- > > -... > > -box.schema.user.grant('guest', 'execute', 'function', 'dostring') > > ---- > > -... > > -test_run:cmd("setopt delimiter ';'") > > ---- > > -- true > > -... > > -function gh594() > > - local cn = remote.connect(box.cfg.listen) > > - local ping = fiber.create(function() cn:ping() end) > > - cn:call('dostring', {'return 2 + 2'}) > > - cn:close() > > -end; > > ---- > > -... > > -test_run:cmd("setopt delimiter ''"); > > ---- > > -- true > > -... > > -gh594() > > ---- > > -... > > -box.schema.func.drop('dostring') > > ---- > > -... > > --- #636: Reload schema on demand > > -sp = box.schema.space.create('test_old') > > ---- > > -... > > -_ = sp:create_index('primary') > > ---- > > -... > > -sp:insert{1, 2, 3} > > ---- > > -- [1, 2, 3] > > -... > > -box.schema.user.grant('guest', 'read', 'space', 'test_old') > > ---- > > -... > > -con = remote.new(box.cfg.listen) > > ---- > > -... > > -con:ping() > > ---- > > -- true > > -... > > -con.space.test_old:select{} > > ---- > > -- - [1, 2, 3] > > -... > > -con.space.test == nil > > ---- > > -- true > > -... > > -sp = box.schema.space.create('test') > > ---- > > -... > > -_ = sp:create_index('primary') > > ---- > > -... > > -sp:insert{2, 3, 4} > > ---- > > -- [2, 3, 4] > > -... > > -box.schema.user.grant('guest', 'read', 'space', 'test') > > ---- > > -... > > -con.space.test == nil > > ---- > > -- true > > -... > > -con:reload_schema() > > ---- > > -... > > -con.space.test:select{} > > ---- > > -- - [2, 3, 4] > > -... > > -box.space.test:drop() > > ---- > > -... > > -box.space.test_old:drop() > > ---- > > -... > > -con:close() > > ---- > > -... > > -name = string.match(arg[0], "([^,]+)%.lua") > > ---- > > -... > > -file_log = require('fio').open(name .. '.log', {'O_RDONLY', 'O_NONBLOCK'}) > > ---- > > -... > > -file_log:seek(0, 'SEEK_END') ~= 0 > > ---- > > -- true > > -... > > -box.schema.user.grant('guest', 'execute', 'universe') > > ---- > > -... > > -test_run:cmd("setopt delimiter ';'") > > ---- > > -- true > > -... > > -_ = fiber.create( > > - function() > > - local conn = require('net.box').new(box.cfg.listen) > > - conn:call('no_such_function', {}) > > - conn:close() > > - end > > -); > > ---- > > -... > > -test_run:cmd("setopt delimiter ''"); > > ---- > > -- true > > -... > > -test_run:wait_log('default', 'ER_NO_SUCH_PROC', nil, 10) > > ---- > > -- ER_NO_SUCH_PROC > > -... > > -box.schema.user.revoke('guest', 'execute', 'universe') > > ---- > > -... > > --- > > --- gh-3900: tarantool can be crashed by sending gibberish to a > > --- binary socket > > --- > > -socket = require("socket") > > ---- > > -... > > -sock = socket.tcp_connect(LISTEN.host, LISTEN.service) > > ---- > > -... > > -data = string.fromhex("6783000000000000000000000000000000000000000000800000C8000000000000000000000000000000000000000000FFFF210100373208000000FFFF000055AAEB66486472530D02000000000010A0350001008000001000000000000000000000000000D05700") > > ---- > > -... > > -sock:write(data) > > ---- > > -- 104 > > -... > > -test_run:wait_log('default', 'ER_INVALID_MSGPACK: Invalid MsgPack %- packet body', nil, 10) > > ---- > > -- 'ER_INVALID_MSGPACK: Invalid MsgPack - packet body' > > -... > > -sock:close() > > ---- > > -- true > > -... > > --- gh-983 selecting a lot of data crashes the server or hangs the > > --- connection > > --- gh-983 test case: iproto connection selecting a lot of data > > -_ = box.schema.space.create('test', { temporary = true }) > > ---- > > -... > > -_ = box.space.test:create_index('primary', {type = 'TREE', parts = {1,'unsigned'}}) > > ---- > > -... > > -data1k = "aaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhh" > > ---- > > -... > > -for i = 0,10000 do box.space.test:insert{i, data1k} end > > ---- > > -... > > -box.schema.user.grant('guest', 'read', 'space', 'test') > > ---- > > -... > > -net = require('net.box') > > ---- > > -... > > -c = net:connect(box.cfg.listen) > > ---- > > -... > > -r = c.space.test:select(nil, {limit=5000}) > > ---- > > -... > > -box.space.test:drop() > > ---- > > -... > > --- gh-970 gh-971 UPSERT over network > > -_ = box.schema.space.create('test') > > ---- > > -... > > -_ = box.space.test:create_index('primary', {type = 'TREE', parts = {1,'unsigned'}}) > > ---- > > -... > > -_ = box.space.test:create_index('covering', {type = 'TREE', parts = {1,'unsigned',3,'string',2,'unsigned'}}) > > ---- > > -... > > -_ = box.space.test:insert{1, 2, "string"} > > ---- > > -... > > -box.schema.user.grant('guest', 'read,write', 'space', 'test') > > ---- > > -... > > -c = net:connect(box.cfg.listen) > > ---- > > -... > > -c.space.test:select{} > > ---- > > -- - [1, 2, 'string'] > > -... > > -c.space.test:upsert({1, 2, 'nothing'}, {{'+', 2, 1}}) -- common update > > ---- > > -... > > -c.space.test:select{} > > ---- > > -- - [1, 3, 'string'] > > -... > > -c.space.test:upsert({2, 4, 'something'}, {{'+', 2, 1}}) -- insert > > ---- > > -... > > -c.space.test:select{} > > ---- > > -- - [1, 3, 'string'] > > - - [2, 4, 'something'] > > -... > > -c.space.test:upsert({2, 4, 'nothing'}, {{'+', 3, 100500}}) -- wrong operation > > ---- > > -... > > -c.space.test:select{} > > ---- > > -- - [1, 3, 'string'] > > - - [2, 4, 'something'] > > -... > > --- gh-1729 net.box index metadata incompatible with local metadata > > -c.space.test.index.primary.parts > > ---- > > -- - type: unsigned > > - is_nullable: false > > - fieldno: 1 > > -... > > -c.space.test.index.covering.parts > > ---- > > -- - type: unsigned > > - is_nullable: false > > - fieldno: 1 > > - - type: string > > - is_nullable: false > > - fieldno: 3 > > - - type: unsigned > > - is_nullable: false > > - fieldno: 2 > > -... > > -box.space.test:drop() > > ---- > > -... > > --- CALL vs CALL_16 in connect options > > -function echo(...) return ... end > > ---- > > -... > > -box.schema.user.grant('guest', 'execute', 'universe') > > ---- > > -... > > -c = net.connect(box.cfg.listen) > > ---- > > -... > > -c:call('echo', {42}) > > ---- > > -- 42 > > -... > > -c:eval('return echo(...)', {42}) > > ---- > > -- 42 > > -... > > --- invalid arguments > > -c:call('echo', 42) > > ---- > > -- error: 'builtin/box/net_box.lua..."]:<line>: Use remote:call(func_name, {arg1, arg2, ...}, > > - opts) instead of remote:call(func_name, arg1, arg2, ...)' > > -... > > -c:eval('return echo(...)', 42) > > ---- > > -- error: 'builtin/box/net_box.lua..."]:<line>: Use remote:eval(expression, {arg1, arg2, ...}, > > - opts) instead of remote:eval(expression, arg1, arg2, ...)' > > -... > > -c:close() > > ---- > > -... > > -c = net.connect(box.cfg.listen, {call_16 = true}) > > ---- > > -... > > -c:call('echo', 42) > > ---- > > -- - [42] > > -... > > -c:eval('return echo(...)', 42) > > ---- > > -- 42 > > -... > > -c:close() > > ---- > > -... > > -box.schema.user.revoke('guest', 'execute', 'universe') > > ---- > > -... > > --- > > --- gh-2195 export pure msgpack from net.box > > --- > > -space = box.schema.space.create('test') > > ---- > > -... > > -_ = box.space.test:create_index('primary') > > ---- > > -... > > -box.schema.user.grant('guest', 'read,write', 'space', 'test') > > ---- > > -... > > -box.schema.user.grant('guest', 'execute', 'universe') > > ---- > > -... > > -c = net.connect(box.cfg.listen) > > ---- > > -... > > -ibuf = require('buffer').ibuf() > > ---- > > -... > > -c:ping() > > ---- > > -- true > > -... > > -c.space.test ~= nil > > ---- > > -- true > > -... > > -c.space.test:replace({1, 'hello'}) > > ---- > > -- [1, 'hello'] > > -... > > --- replace > > -c.space.test:replace({2}, {buffer = ibuf}) > > ---- > > -- 9 > > -... > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > ---- > > -... > > -result > > ---- > > -- {48: [[2]]} > > -... > > --- replace + skip_header > > -c.space.test:replace({2}, {buffer = ibuf, skip_header = true}) > > ---- > > -- 7 > > -... > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > ---- > > -... > > -result > > ---- > > -- [[2]] > > -... > > --- insert > > -c.space.test:insert({3}, {buffer = ibuf}) > > ---- > > -- 9 > > -... > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > ---- > > -... > > -result > > ---- > > -- {48: [[3]]} > > -... > > --- insert + skip_header > > -_ = space:delete({3}) > > ---- > > -... > > -c.space.test:insert({3}, {buffer = ibuf, skip_header = true}) > > ---- > > -- 7 > > -... > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > ---- > > -... > > -result > > ---- > > -- [[3]] > > -... > > --- update > > -c.space.test:update({3}, {}, {buffer = ibuf}) > > ---- > > -- 9 > > -... > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > ---- > > -... > > -result > > ---- > > -- {48: [[3]]} > > -... > > -c.space.test.index.primary:update({3}, {}, {buffer = ibuf}) > > ---- > > -- 9 > > -... > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > ---- > > -... > > -result > > ---- > > -- {48: [[3]]} > > -... > > --- update + skip_header > > -c.space.test:update({3}, {}, {buffer = ibuf, skip_header = true}) > > ---- > > -- 7 > > -... > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > ---- > > -... > > -result > > ---- > > -- [[3]] > > -... > > -c.space.test.index.primary:update({3}, {}, {buffer = ibuf, skip_header = true}) > > ---- > > -- 7 > > -... > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > ---- > > -... > > -result > > ---- > > -- [[3]] > > -... > > --- upsert > > -c.space.test:upsert({4}, {}, {buffer = ibuf}) > > ---- > > -- 7 > > -... > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > ---- > > -... > > -result > > ---- > > -- {48: []} > > -... > > --- upsert + skip_header > > -c.space.test:upsert({4}, {}, {buffer = ibuf, skip_header = true}) > > ---- > > -- 5 > > -... > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > ---- > > -... > > -result > > ---- > > -- [] > > -... > > --- delete > > -c.space.test:upsert({4}, {}, {buffer = ibuf}) > > ---- > > -- 7 > > -... > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > ---- > > -... > > -result > > ---- > > -- {48: []} > > -... > > --- delete + skip_header > > -c.space.test:upsert({4}, {}, {buffer = ibuf, skip_header = true}) > > ---- > > -- 5 > > -... > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > ---- > > -... > > -result > > ---- > > -- [] > > -... > > --- select > > -c.space.test.index.primary:select({3}, {iterator = 'LE', buffer = ibuf}) > > ---- > > -- 19 > > -... > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > ---- > > -... > > -result > > ---- > > -- {48: [[3], [2], [1, 'hello']]} > > -... > > --- select + skip_header > > -c.space.test.index.primary:select({3}, {iterator = 'LE', buffer = ibuf, skip_header = true}) > > ---- > > -- 17 > > -... > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > ---- > > -... > > -result > > ---- > > -- [[3], [2], [1, 'hello']] > > -... > > --- select > > -len = c.space.test:select({}, {buffer = ibuf}) > > ---- > > -... > > -ibuf.rpos + len == ibuf.wpos > > ---- > > -- true > > -... > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > ---- > > -... > > -ibuf.rpos == ibuf.wpos > > ---- > > -- true > > -... > > -len > > ---- > > -- 21 > > -... > > -result > > ---- > > -- {48: [[1, 'hello'], [2], [3], [4]]} > > -... > > --- select + skip_header > > -len = c.space.test:select({}, {buffer = ibuf, skip_header = true}) > > ---- > > -... > > -ibuf.rpos + len == ibuf.wpos > > ---- > > -- true > > -... > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > ---- > > -... > > -ibuf.rpos == ibuf.wpos > > ---- > > -- true > > -... > > -len > > ---- > > -- 19 > > -... > > -result > > ---- > > -- [[1, 'hello'], [2], [3], [4]] > > -... > > --- call > > -c:call("echo", {1, 2, 3}, {buffer = ibuf}) > > ---- > > -- 10 > > -... > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > ---- > > -... > > -result > > ---- > > -- {48: [1, 2, 3]} > > -... > > -c:call("echo", {}, {buffer = ibuf}) > > ---- > > -- 7 > > -... > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > ---- > > -... > > -result > > ---- > > -- {48: []} > > -... > > -c:call("echo", nil, {buffer = ibuf}) > > ---- > > -- 7 > > -... > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > ---- > > -... > > -result > > ---- > > -- {48: []} > > -... > > --- call + skip_header > > -c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > > ---- > > -- 8 > > -... > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > ---- > > -... > > -result > > ---- > > -- [1, 2, 3] > > -... > > -c:call("echo", {}, {buffer = ibuf, skip_header = true}) > > ---- > > -- 5 > > -... > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > ---- > > -... > > -result > > ---- > > -- [] > > -... > > -c:call("echo", nil, {buffer = ibuf, skip_header = true}) > > ---- > > -- 5 > > -... > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > ---- > > -... > > -result > > ---- > > -- [] > > -... > > --- eval > > -c:eval("echo(...)", {1, 2, 3}, {buffer = ibuf}) > > ---- > > -- 7 > > -... > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > ---- > > -... > > -result > > ---- > > -- {48: []} > > -... > > -c:eval("echo(...)", {}, {buffer = ibuf}) > > ---- > > -- 7 > > -... > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > ---- > > -... > > -result > > ---- > > -- {48: []} > > -... > > -c:eval("echo(...)", nil, {buffer = ibuf}) > > ---- > > -- 7 > > -... > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > ---- > > -... > > -result > > ---- > > -- {48: []} > > -... > > --- eval + skip_header > > -c:eval("echo(...)", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > > ---- > > -- 5 > > -... > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > ---- > > -... > > -result > > ---- > > -- [] > > -... > > -c:eval("echo(...)", {}, {buffer = ibuf, skip_header = true}) > > ---- > > -- 5 > > -... > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > ---- > > -... > > -result > > ---- > > -- [] > > -... > > -c:eval("echo(...)", nil, {buffer = ibuf, skip_header = true}) > > ---- > > -- 5 > > -... > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > ---- > > -... > > -result > > ---- > > -- [] > > -... > > --- make several request into a buffer with skip_header, then read > > --- results > > -c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > > ---- > > -- 8 > > -... > > -c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > > ---- > > -- 8 > > -... > > -c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > > ---- > > -- 8 > > -... > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > ---- > > -... > > -result > > ---- > > -- [1, 2, 3] > > -... > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > ---- > > -... > > -result > > ---- > > -- [1, 2, 3] > > -... > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > ---- > > -... > > -result > > ---- > > -- [1, 2, 3] > > -... > > --- unsupported methods > > -c.space.test:get({1}, { buffer = ibuf}) > > ---- > > -- error: 'builtin/box/net_box.lua..."]:<line>: index:get() doesn''t support `buffer` argument' > > -... > > -c.space.test.index.primary:min({}, { buffer = ibuf}) > > ---- > > -- error: 'builtin/box/net_box.lua..."]:<line>: index:min() doesn''t support `buffer` argument' > > -... > > -c.space.test.index.primary:max({}, { buffer = ibuf}) > > ---- > > -- error: 'builtin/box/net_box.lua..."]:<line>: index:max() doesn''t support `buffer` argument' > > -... > > -c.space.test.index.primary:count({}, { buffer = ibuf}) > > ---- > > -- error: 'builtin/box/net_box.lua..."]:<line>: index:count() doesn''t support `buffer` argument' > > -... > > -c.space.test.index.primary:get({1}, { buffer = ibuf}) > > ---- > > -- error: 'builtin/box/net_box.lua..."]:<line>: index:get() doesn''t support `buffer` argument' > > -... > > --- error handling > > -rpos, wpos = ibuf.rpos, ibuf.wpos > > ---- > > -... > > -c.space.test:insert({1}, {buffer = ibuf}) > > ---- > > -- error: Duplicate key exists in unique index 'primary' in space 'test' > > -... > > -ibuf.rpos == rpos, ibuf.wpos == wpos > > ---- > > -- true > > -- true > > -... > > -ibuf = nil > > ---- > > -... > > -c:close() > > ---- > > -... > > -space:drop() > > ---- > > -... > > -box.schema.user.revoke('guest', 'execute', 'universe') > > ---- > > -... > > --- gh-1904 net.box hangs in :close() if a fiber was cancelled > > --- while blocked in :_wait_state() in :_request() > > -options = {user = 'netbox', password = 'badpass', wait_connected = false, reconnect_after = 0.01} > > ---- > > -... > > -c = net:new(box.cfg.listen, options) > > ---- > > -... > > -f = fiber.create(function() c:call("") end) > > ---- > > -... > > -fiber.sleep(0.01) > > ---- > > -... > > -f:cancel(); c:close() > > ---- > > -... > > -box.schema.user.grant('guest', 'read', 'space', '_schema') > > ---- > > -... > > --- check for on_schema_reload callback > > -test_run:cmd("setopt delimiter ';'") > > ---- > > -- true > > -... > > -do > > - local a = 0 > > - function osr_cb() > > - a = a + 1 > > - end > > - local con = net.new(box.cfg.listen, { > > - wait_connected = false > > - }) > > - con:on_schema_reload(osr_cb) > > - con:wait_connected() > > - con.space._schema:select{} > > - box.schema.space.create('misisipi') > > - box.space.misisipi:drop() > > - con.space._schema:select{} > > - con:close() > > - con = nil > > - > > - return a > > -end; > > ---- > > -- 2 > > -... > > -do > > - local a = 0 > > - function osr_cb() > > - a = a + 1 > > - end > > - local con = net.new(box.cfg.listen, { > > - wait_connected = true > > - }) > > - con:on_schema_reload(osr_cb) > > - con.space._schema:select{} > > - box.schema.space.create('misisipi') > > - box.space.misisipi:drop() > > - con.space._schema:select{} > > - con:close() > > - con = nil > > - > > - return a > > -end; > > ---- > > -- 1 > > -... > > -test_run:cmd("setopt delimiter ''"); > > ---- > > -- true > > -... > > -box.schema.user.revoke('guest', 'read', 'space', '_schema') > > ---- > > -... > > --- Tarantool < 1.7.1 compatibility (gh-1533) > > -c = net.new(box.cfg.listen) > > ---- > > -... > > -c:ping() > > ---- > > -- true > > -... > > -c:close() > > ---- > > -... > > --- Test for connect_timeout > 0 in netbox connect > > -test_run:cmd("setopt delimiter ';'"); > > ---- > > -- true > > -... > > -need_stop = false; > > ---- > > -... > > -greeting = > > -"Tarantool 1.7.3 (Lua console)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" .. > > -"type 'help' for interactive help~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"; > > ---- > > -... > > -socket = require('socket'); > > ---- > > -... > > -srv = socket.tcp_server('localhost', 0, { > > - handler = function(fd) > > - local fiber = require('fiber') > > - while not need_stop do > > - fiber.sleep(0.01) > > - end > > - fd:write(greeting) > > - end > > -}); > > ---- > > -... > > --- we must get timeout > > -port = srv:name().port > > -nb = net.new('localhost:' .. port, { > > - wait_connected = true, console = true, > > - connect_timeout = 0.1 > > -}); > > ---- > > -... > > -nb.error:find('timed out') ~= nil; > > ---- > > -- true > > -... > > -need_stop = true > > -nb:close(); > > ---- > > -... > > --- we must get peer closed > > -nb = net.new('localhost:' .. port, { > > - wait_connected = true, console = true, > > - connect_timeout = 0.2 > > -}); > > ---- > > -... > > -nb.error ~= "Timeout exceeded"; > > ---- > > -- true > > -... > > -nb:close(); > > ---- > > -... > > -test_run:cmd("setopt delimiter ''"); > > ---- > > -- true > > -... > > -srv:close() > > ---- > > -- true > > -... > > -test_run:cmd("clear filter") > > ---- > > -- true > > -... > > --- > > --- gh-2402 net.box doesn't support space:format() > > --- > > -space = box.schema.space.create('test', {format={{name="id", type="unsigned"}}}) > > ---- > > -... > > -space ~= nil > > ---- > > -- true > > -... > > -_ = box.space.test:create_index('primary') > > ---- > > -... > > -box.schema.user.grant('guest', 'read', 'space', 'test') > > ---- > > -... > > -c = net.connect(box.cfg.listen) > > ---- > > -... > > -c:ping() > > ---- > > -- true > > -... > > -c.space.test ~= nil > > ---- > > -- true > > -... > > -format = c.space.test:format() > > ---- > > -... > > -format[1] ~= nil > > ---- > > -- true > > -... > > -format[1].name == "id" > > ---- > > -- true > > -... > > -format[1].type == "unsigned" > > ---- > > -- true > > -... > > -c.space.test:format({}) > > ---- > > -- error: net.box does not support setting space format > > -... > > --- > > --- gh-4091: index unique flag is always false. > > --- > > -c.space.test.index.primary.unique > > ---- > > -- true > > -... > > -c:close() > > ---- > > -... > > -space:drop() > > ---- > > -... > > --- > > --- Check that it's possible to get connection object form net.box space > > --- > > -space = box.schema.space.create('test', {format={{name="id", type="unsigned"}}}) > > ---- > > -... > > -space ~= nil > > ---- > > -- true > > -... > > -_ = box.space.test:create_index('primary') > > ---- > > -... > > -box.schema.user.grant('guest','read,write,execute','space', 'test') > > ---- > > -... > > -c = net.connect(box.cfg.listen) > > ---- > > -... > > -c:ping() > > ---- > > -- true > > -... > > -c.space.test ~= nil > > ---- > > -- true > > -... > > -c.space.test.connection == c > > ---- > > -- true > > -... > > -box.schema.user.revoke('guest','read,write,execute','space', 'test') > > ---- > > -... > > -c:close() > > ---- > > -... > > --- > > --- gh-2642: box.session.type() > > --- > > -box.schema.user.grant('guest','execute','universe') > > ---- > > -... > > -c = net.connect(box.cfg.listen) > > ---- > > -... > > -c:call("box.session.type") > > ---- > > -- binary > > -... > > -c:close() > > ---- > > -... > > -box.schema.user.revoke('guest', 'execute', 'universe') > > ---- > > -... > > --- > > --- On_connect/disconnect triggers. > > --- > > -test_run:cmd('create server connecter with script = "box/proxy.lua"') > > ---- > > -- true > > -... > > -test_run:cmd('start server connecter') > > ---- > > -- true > > -... > > -test_run:cmd("set variable connect_to to 'connecter.listen'") > > ---- > > -- true > > -... > > -conn = net.connect(connect_to, { reconnect_after = 0.1 }) > > ---- > > -... > > -conn.state > > ---- > > -- active > > -... > > -connected_cnt = 0 > > ---- > > -... > > -disconnected_cnt = 0 > > ---- > > -... > > -function on_connect() connected_cnt = connected_cnt + 1 end > > ---- > > -... > > -function on_disconnect() disconnected_cnt = disconnected_cnt + 1 end > > ---- > > -... > > -conn:on_connect(on_connect) > > ---- > > -... > > -conn:on_disconnect(on_disconnect) > > ---- > > -... > > -test_run:cmd('stop server connecter') > > ---- > > -- true > > -... > > -test_run:cmd('start server connecter') > > ---- > > -- true > > -... > > -while conn.state ~= 'active' do fiber.sleep(0.1) end > > ---- > > -... > > -connected_cnt > > ---- > > -- 1 > > -... > > -old_disconnected_cnt = disconnected_cnt > > ---- > > -... > > -disconnected_cnt >= 1 > > ---- > > -- true > > -... > > -conn:close() > > ---- > > -... > > -disconnected_cnt == old_disconnected_cnt + 1 > > ---- > > -- true > > -... > > -test_run:cmd('stop server connecter') > > ---- > > -- true > > -... > > --- > > --- gh-2401 update pseudo objects not replace them > > --- > > -space:drop() > > ---- > > -... > > -space = box.schema.space.create('test') > > ---- > > -... > > -box.schema.user.grant('guest', 'read', 'space', 'test') > > ---- > > -... > > -c = net.connect(box.cfg.listen) > > ---- > > -... > > -cspace = c.space.test > > ---- > > -... > > -space.index.test_index == nil > > ---- > > -- true > > -... > > -cspace.index.test_index == nil > > ---- > > -- true > > -... > > -_ = space:create_index("test_index", {parts={1, 'string'}}) > > ---- > > -... > > -c:reload_schema() > > ---- > > -... > > -space.index.test_index ~= nil > > ---- > > -- true > > -... > > -cspace.index.test_index ~= nil > > ---- > > -- true > > -... > > -c.space.test.index.test_index ~= nil > > ---- > > -- true > > -... > > --- cleanup > > -space:drop() > > ---- > > -... > > --- > > --- gh-946: long polling CALL blocks input > > --- > > -box.schema.func.create('fast_call') > > ---- > > -... > > -box.schema.func.create('long_call') > > ---- > > -... > > -box.schema.func.create('wait_signal') > > ---- > > -... > > -box.schema.user.grant('guest', 'execute', 'function', 'fast_call') > > ---- > > -... > > -box.schema.user.grant('guest', 'execute', 'function', 'long_call') > > ---- > > -... > > -box.schema.user.grant('guest', 'execute', 'function', 'wait_signal') > > ---- > > -... > > -c = net.connect(box.cfg.listen) > > ---- > > -... > > -N = 100 > > ---- > > -... > > -pad = string.rep('x', 1024) > > ---- > > -... > > -long_call_cond = fiber.cond() > > ---- > > -... > > -long_call_channel = fiber.channel() > > ---- > > -... > > -fast_call_channel = fiber.channel() > > ---- > > -... > > -function fast_call(x) return x end > > ---- > > -... > > -function long_call(x) long_call_cond:wait() return x * 2 end > > ---- > > -... > > -test_run:cmd("setopt delimiter ';'") > > ---- > > -- true > > -... > > -for i = 1, N do > > - fiber.create(function() > > - fast_call_channel:put(c:call('fast_call', {i, pad})) > > - end) > > - fiber.create(function() > > - long_call_channel:put(c:call('long_call', {i, pad})) > > - end) > > -end > > -test_run:cmd("setopt delimiter ''"); > > ---- > > -... > > -x = 0 > > ---- > > -... > > -for i = 1, N do x = x + fast_call_channel:get() end > > ---- > > -... > > -x > > ---- > > -- 5050 > > -... > > -long_call_cond:broadcast() > > ---- > > -... > > -x = 0 > > ---- > > -... > > -for i = 1, N do x = x + long_call_channel:get() end > > ---- > > -... > > -x > > ---- > > -- 10100 > > -... > > --- > > --- Check that a connection does not leak if there is > > --- a long CALL in progress when it is closed. > > --- > > -disconnected = false > > ---- > > -... > > -function on_disconnect() disconnected = true end > > ---- > > -... > > --- Make sure all dangling connections are collected so > > --- that on_disconnect trigger isn't called spuriously. > > -collectgarbage('collect') > > ---- > > -- 0 > > -... > > -fiber.sleep(0) > > ---- > > -... > > -box.session.on_disconnect(on_disconnect) == on_disconnect > > ---- > > -- true > > -... > > --- > > --- gh-3859: on_disconnect is called only after all requests are > > --- processed, but should be called right after disconnect and > > --- only once. > > --- > > -ch1 = fiber.channel(1) > > ---- > > -... > > -ch2 = fiber.channel(1) > > ---- > > -... > > -function wait_signal() ch1:put(true) ch2:get() end > > ---- > > -... > > -_ = fiber.create(function() c:call('wait_signal') end) > > ---- > > -... > > -ch1:get() > > ---- > > -- true > > -... > > -c:close() > > ---- > > -... > > -fiber.sleep(0) > > ---- > > -... > > -while disconnected == false do fiber.sleep(0.01) end > > ---- > > -... > > -disconnected -- true > > ---- > > -- true > > -... > > -disconnected = nil > > ---- > > -... > > -ch2:put(true) > > ---- > > -- true > > -... > > -fiber.sleep(0) > > ---- > > -... > > -disconnected -- nil, on_disconnect is not called second time. > > ---- > > -- null > > -... > > -box.session.on_disconnect(nil, on_disconnect) > > ---- > > -... > > -box.schema.func.drop('long_call') > > ---- > > -... > > -box.schema.func.drop('fast_call') > > ---- > > -... > > -box.schema.func.drop('wait_signal') > > ---- > > -... > > --- > > --- gh-2666: check that netbox.call is not repeated on schema > > --- change. > > --- > > -box.schema.user.grant('guest', 'write', 'space', '_space') > > ---- > > -... > > -box.schema.user.grant('guest', 'write', 'space', '_schema') > > ---- > > -... > > -box.schema.user.grant('guest', 'create', 'universe') > > ---- > > -... > > -count = 0 > > ---- > > -... > > -function create_space(name) count = count + 1 box.schema.create_space(name) return true end > > ---- > > -... > > -box.schema.func.create('create_space') > > ---- > > -... > > -box.schema.user.grant('guest', 'execute', 'function', 'create_space') > > ---- > > -... > > -c = net.connect(box.cfg.listen) > > ---- > > -... > > -c:call('create_space', {'test1'}) > > ---- > > -- true > > -... > > -count > > ---- > > -- 1 > > -... > > -c:call('create_space', {'test2'}) > > ---- > > -- true > > -... > > -count > > ---- > > -- 2 > > -... > > -c:call('create_space', {'test3'}) > > ---- > > -- true > > -... > > -count > > ---- > > -- 3 > > -... > > -box.space.test1:drop() > > ---- > > -... > > -box.space.test2:drop() > > ---- > > -... > > -box.space.test3:drop() > > ---- > > -... > > -box.schema.user.revoke('guest', 'write', 'space', '_space') > > ---- > > -... > > -box.schema.user.revoke('guest', 'write', 'space', '_schema') > > ---- > > -... > > -box.schema.user.revoke('guest', 'create', 'universe') > > ---- > > -... > > -c:close() > > ---- > > -... > > -box.schema.func.drop('create_space') > > ---- > > -... > > --- > > --- gh-3164: netbox connection is not closed and garbage collected > > --- ever, if reconnect_after is set. > > --- > > -test_run:cmd('start server connecter') > > ---- > > -- true > > -... > > -test_run:cmd("set variable connect_to to 'connecter.listen'") > > ---- > > -- true > > -... > > -weak = setmetatable({}, {__mode = 'v'}) > > ---- > > -... > > --- Create strong and weak reference. Weak is valid until strong > > --- is valid too. > > -strong = net.connect(connect_to, {reconnect_after = 0.1}) > > ---- > > -... > > -weak.c = strong > > ---- > > -... > > -weak.c:ping() > > ---- > > -- true > > -... > > -test_run:cmd('stop server connecter') > > ---- > > -- true > > -... > > -test_run:cmd('cleanup server connecter') > > ---- > > -- true > > -... > > --- Check the connection tries to reconnect at least two times. > > --- 'Cannot assign requested address' is the crutch for running the > > --- tests in a docker. This error emits instead of > > --- 'Connection refused' inside a docker. > > -old_log_level = box.cfg.log_level > > ---- > > -... > > -box.cfg{log_level = 6} > > ---- > > -... > > -log.info(string.rep('a', 1000)) > > ---- > > -... > > -test_run:cmd("setopt delimiter ';'") > > ---- > > -- true > > -... > > -while test_run:grep_log('default', 'Network is unreachable', 1000) == nil and > > - test_run:grep_log('default', 'Connection refused', 1000) == nil and > > - test_run:grep_log('default', 'Cannot assign requested address', 1000) == nil do > > - fiber.sleep(0.1) > > -end; > > ---- > > -... > > -log.info(string.rep('a', 1000)); > > ---- > > -... > > -while test_run:grep_log('default', 'Network is unreachable', 1000) == nil and > > - test_run:grep_log('default', 'Connection refused', 1000) == nil and > > - test_run:grep_log('default', 'Cannot assign requested address', 1000) == nil do > > - fiber.sleep(0.1) > > -end; > > ---- > > -... > > -test_run:cmd("setopt delimiter ''"); > > ---- > > -- true > > -... > > -box.cfg{log_level = old_log_level} > > ---- > > -... > > -collectgarbage('collect') > > ---- > > -- 0 > > -... > > -strong.state > > ---- > > -- error_reconnect > > -... > > -strong == weak.c > > ---- > > -- true > > -... > > --- Remove single strong reference. Now connection must be garbage > > --- collected. > > -strong = nil > > ---- > > -... > > -collectgarbage('collect') > > ---- > > -- 0 > > -... > > --- Now weak.c is null, because it was weak reference, and the > > --- connection is deleted by 'collect'. > > -weak.c > > ---- > > -- null > > -... > > --- > > --- gh-2677: netbox supports console connections, that complicates > > --- both console and netbox. It was necessary because before a > > --- connection is established, a console does not known is it > > --- binary or text protocol, and netbox could not be created from > > --- existing socket. > > --- > > -box.schema.user.grant('guest', 'execute', 'universe') > > ---- > > -... > > -urilib = require('uri') > > ---- > > -... > > -uri = urilib.parse(tostring(box.cfg.listen)) > > ---- > > -... > > -s, greeting = net.establish_connection(uri.host, uri.service) > > ---- > > -... > > -c = net.wrap(s, greeting, uri.host, uri.service, {reconnect_after = 0.01}) > > ---- > > -... > > -c.state > > ---- > > -- active > > -... > > -a = 100 > > ---- > > -... > > -function kek(args) return {1, 2, 3, args} end > > ---- > > -... > > -c:eval('a = 200') > > ---- > > -... > > -a > > ---- > > -- 200 > > -... > > -c:call('kek', {300}) > > ---- > > -- [1, 2, 3, 300] > > -... > > -s = box.schema.create_space('test') > > ---- > > -... > > -box.schema.user.grant('guest', 'read,write', 'space', 'test') > > ---- > > -... > > -pk = s:create_index('pk') > > ---- > > -... > > -c:reload_schema() > > ---- > > -... > > -c.space.test:replace{1} > > ---- > > -- [1] > > -... > > -c.space.test:get{1} > > ---- > > -- [1] > > -... > > -c.space.test:delete{1} > > ---- > > -- [1] > > -... > > --- > > --- Break a connection to test reconnect_after. > > --- > > -_ = c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') > > ---- > > -... > > -while not c:is_connected() do fiber.sleep(0.01) end > > ---- > > -... > > -c:ping() > > ---- > > -- true > > -... > > -s:drop() > > ---- > > -... > > -c:close() > > ---- > > -... > > --- > > --- Test a case, when netbox can not connect first time, but > > --- reconnect_after is set. > > --- > > -c = net.connect('localhost:33333', {reconnect_after = 0.1, wait_connected = false}) > > ---- > > -... > > -while c.state ~= 'error_reconnect' do fiber.sleep(0.01) end > > ---- > > -... > > -c:close() > > ---- > > -... > > -box.schema.user.revoke('guest', 'execute', 'universe') > > ---- > > -... > > -c.state > > ---- > > -- closed > > -... > > -c = nil > > ---- > > -... > > --- > > --- gh-3256 net.box is_nullable and collation options output > > --- > > -space = box.schema.create_space('test') > > ---- > > -... > > -box.schema.user.grant('guest', 'read', 'space', 'test') > > ---- > > -... > > -_ = space:create_index('pk') > > ---- > > -... > > -_ = space:create_index('sk', {parts = {{2, 'unsigned', is_nullable = true}}}) > > ---- > > -... > > -c = net:connect(box.cfg.listen) > > ---- > > -... > > -c.space.test.index.sk.parts > > ---- > > -- - type: unsigned > > - is_nullable: true > > - fieldno: 2 > > -... > > -space:drop() > > ---- > > -... > > -space = box.schema.create_space('test') > > ---- > > -... > > -c:close() > > ---- > > -... > > -box.schema.user.grant('guest', 'read', 'space', 'test') > > ---- > > -... > > -c = net:connect(box.cfg.listen) > > ---- > > -... > > -box.internal.collation.create('test', 'ICU', 'ru-RU') > > ---- > > -... > > -collation_id = box.internal.collation.id_by_name('test') > > ---- > > -... > > -_ = space:create_index('sk', { type = 'tree', parts = {{1, 'str', collation = 'test'}}, unique = true }) > > ---- > > -... > > -c:reload_schema() > > ---- > > -... > > -parts = c.space.test.index.sk.parts > > ---- > > -... > > -#parts == 1 > > ---- > > -- true > > -... > > -parts[1].fieldno == 1 > > ---- > > -- true > > -... > > -parts[1].type == 'string' > > ---- > > -- true > > -... > > -parts[1].is_nullable == false > > ---- > > -- true > > -... > > -if _TARANTOOL >= '2.2.1' then \ > > - return parts[1].collation == 'test' \ > > -else \ > > - return parts[1].collation_id == collation_id \ > > -end > > ---- > > -- true > > -... > > -c:close() > > ---- > > -... > > -box.internal.collation.drop('test') > > ---- > > -... > > -space:drop() > > ---- > > -... > > -c.state > > ---- > > -- closed > > -... > > -c = nil > > ---- > > -... > > --- > > --- gh-3107: fiber-async netbox. > > --- > > -cond = nil > > ---- > > -... > > -box.schema.func.create('long_function') > > ---- > > -... > > -box.schema.user.grant('guest', 'execute', 'function', 'long_function') > > ---- > > -... > > -function long_function(...) cond = fiber.cond() cond:wait() return ... end > > ---- > > -... > > -function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end > > ---- > > -... > > -s = box.schema.create_space('test') > > ---- > > -... > > -pk = s:create_index('pk') > > ---- > > -... > > -s:replace{1} > > ---- > > -- [1] > > -... > > -s:replace{2} > > ---- > > -- [2] > > -... > > -s:replace{3} > > ---- > > -- [3] > > -... > > -s:replace{4} > > ---- > > -- [4] > > -... > > -c = net:connect(box.cfg.listen) > > ---- > > -... > > --- > > --- Check long connections, multiple wait_result(). > > --- > > -future = c:call('long_function', {1, 2, 3}, {is_async = true}) > > ---- > > -... > > -future:result() > > ---- > > -- null > > -- Response is not ready > > -... > > -future:is_ready() > > ---- > > -- false > > -... > > -future:wait_result(0.01) -- Must fail on timeout. > > ---- > > -- null > > -- Timeout exceeded > > -... > > -finalize_long() > > ---- > > -... > > -ret = future:wait_result(100) > > ---- > > -... > > -future:is_ready() > > ---- > > -- true > > -... > > --- Any timeout is ok - response is received already. > > -future:wait_result(0) > > ---- > > -- [1, 2, 3] > > -... > > -future:wait_result(0.01) > > ---- > > -- [1, 2, 3] > > -... > > -ret > > ---- > > -- [1, 2, 3] > > -... > > -_, err = pcall(future.wait_result, future, true) > > ---- > > -... > > -err:find('Usage') ~= nil > > ---- > > -- true > > -... > > -_, err = pcall(future.wait_result, future, '100') > > ---- > > -... > > -err:find('Usage') ~= nil > > ---- > > -- true > > -... > > --- > > --- Check infinity timeout. > > --- > > -ret = nil > > ---- > > -... > > -_ = fiber.create(function() ret = c:call('long_function', {1, 2, 3}, {is_async = true}):wait_result() end) > > ---- > > -... > > -finalize_long() > > ---- > > -... > > -while not ret do fiber.sleep(0.01) end > > ---- > > -... > > -ret > > ---- > > -- [1, 2, 3] > > -... > > -c:close() > > ---- > > -... > > -box.schema.user.grant('guest', 'execute', 'universe') > > ---- > > -... > > -c = net:connect(box.cfg.listen) > > ---- > > -... > > -future = c:eval('return long_function(...)', {1, 2, 3}, {is_async = true}) > > ---- > > -... > > -future:result() > > ---- > > -- null > > -- Response is not ready > > -... > > -future:wait_result(0.01) -- Must fail on timeout. > > ---- > > -- null > > -- Timeout exceeded > > -... > > -finalize_long() > > ---- > > -... > > -future:wait_result(100) > > ---- > > -- [1, 2, 3] > > -... > > -c:close() > > ---- > > -... > > --- > > --- Check that is_async does not work on a closed connection. > > --- > > -c:call('any_func', {}, {is_async = true}) > > ---- > > -- error: Connection closed > > -... > > -box.schema.user.revoke('guest', 'execute', 'universe') > > ---- > > -... > > -c = net:connect(box.cfg.listen) > > ---- > > -... > > --- > > --- Ensure the request is garbage collected both if is not used and > > --- if is. > > --- > > -gc_test = setmetatable({}, {__mode = 'v'}) > > ---- > > -... > > -gc_test.future = c:call('long_function', {1, 2, 3}, {is_async = true}) > > ---- > > -... > > -gc_test.future ~= nil > > ---- > > -- true > > -... > > -collectgarbage() > > ---- > > -- 0 > > -... > > -gc_test > > ---- > > -- [] > > -... > > -finalize_long() > > ---- > > -... > > -future = c:call('long_function', {1, 2, 3}, {is_async = true}) > > ---- > > -... > > -collectgarbage() > > ---- > > -- 0 > > -... > > -future ~= nil > > ---- > > -- true > > -... > > -finalize_long() > > ---- > > -... > > -future:wait_result(1000) > > ---- > > -- [1, 2, 3] > > -... > > -collectgarbage() > > ---- > > -- 0 > > -... > > -future ~= nil > > ---- > > -- true > > -... > > -gc_test.future = future > > ---- > > -... > > -future = nil > > ---- > > -... > > -collectgarbage() > > ---- > > -- 0 > > -... > > -gc_test > > ---- > > -- [] > > -... > > --- > > --- Ensure a request can be finalized from non-caller fibers. > > --- > > -future = c:call('long_function', {1, 2, 3}, {is_async = true}) > > ---- > > -... > > -ret = {} > > ---- > > -... > > -count = 0 > > ---- > > -... > > -for i = 1, 10 do fiber.create(function() ret[i] = future:wait_result(1000) count = count + 1 end) end > > ---- > > -... > > -future:wait_result(0.01) -- Must fail on timeout. > > ---- > > -- null > > -- Timeout exceeded > > -... > > -finalize_long() > > ---- > > -... > > -while count ~= 10 do fiber.sleep(0.1) end > > ---- > > -... > > -ret > > ---- > > -- - &0 [1, 2, 3] > > - - *0 > > - - *0 > > - - *0 > > - - *0 > > - - *0 > > - - *0 > > - - *0 > > - - *0 > > - - *0 > > -... > > --- > > --- Test space methods. > > --- > > -c:close() > > ---- > > -... > > -box.schema.user.grant('guest', 'read,write', 'space', 'test') > > ---- > > -... > > -c = net:connect(box.cfg.listen) > > ---- > > -... > > -future = c.space.test:select({1}, {is_async = true}) > > ---- > > -... > > -ret = future:wait_result(100) > > ---- > > -... > > -ret > > ---- > > -- - [1] > > -... > > -type(ret[1]) > > ---- > > -- cdata > > -... > > -future = c.space.test:insert({5}, {is_async = true}) > > ---- > > -... > > -future:wait_result(100) > > ---- > > -- [5] > > -... > > -s:get{5} > > ---- > > -- [5] > > -... > > -future = c.space.test:replace({6}, {is_async = true}) > > ---- > > -... > > -future:wait_result(100) > > ---- > > -- [6] > > -... > > -s:get{6} > > ---- > > -- [6] > > -... > > -future = c.space.test:delete({6}, {is_async = true}) > > ---- > > -... > > -future:wait_result(100) > > ---- > > -- [6] > > -... > > -s:get{6} > > ---- > > -... > > -future = c.space.test:update({5}, {{'=', 2, 5}}, {is_async = true}) > > ---- > > -... > > -future:wait_result(100) > > ---- > > -- [5, 5] > > -... > > -s:get{5} > > ---- > > -- [5, 5] > > -... > > -future = c.space.test:upsert({5}, {{'=', 2, 6}}, {is_async = true}) > > ---- > > -... > > -future:wait_result(100) > > ---- > > -- null > > -... > > -s:get{5} > > ---- > > -- [5, 6] > > -... > > -future = c.space.test:get({5}, {is_async = true}) > > ---- > > -... > > -future:wait_result(100) > > ---- > > -- [5, 6] > > -... > > --- > > --- Test index methods. > > --- > > -future = c.space.test.index.pk:select({1}, {is_async = true}) > > ---- > > -... > > -future:wait_result(100) > > ---- > > -- - [1] > > -... > > -future = c.space.test.index.pk:get({2}, {is_async = true}) > > ---- > > -... > > -future:wait_result(100) > > ---- > > -- [2] > > -... > > -future = c.space.test.index.pk:min({}, {is_async = true}) > > ---- > > -... > > -future:wait_result(100) > > ---- > > -- [1] > > -... > > -future = c.space.test.index.pk:max({}, {is_async = true}) > > ---- > > -... > > -future:wait_result(100) > > ---- > > -- [5, 6] > > -... > > -c:close() > > ---- > > -... > > -box.schema.user.grant('guest', 'execute', 'universe') > > ---- > > -... > > -c = net:connect(box.cfg.listen) > > ---- > > -... > > -future = c.space.test.index.pk:count({3}, {is_async = true}) > > ---- > > -... > > -future:wait_result(100) > > ---- > > -- 1 > > -... > > -c:close() > > ---- > > -... > > -box.schema.user.revoke('guest', 'execute', 'universe') > > ---- > > -... > > -c = net:connect(box.cfg.listen) > > ---- > > -... > > -future = c.space.test.index.pk:delete({3}, {is_async = true}) > > ---- > > -... > > -future:wait_result(100) > > ---- > > -- [3] > > -... > > -s:get{3} > > ---- > > -... > > -future = c.space.test.index.pk:update({4}, {{'=', 2, 6}}, {is_async = true}) > > ---- > > -... > > -future:wait_result(100) > > ---- > > -- [4, 6] > > -... > > -s:get{4} > > ---- > > -- [4, 6] > > -... > > --- > > --- Test async errors. > > --- > > -future = c.space.test:insert({1}, {is_async = true}) > > ---- > > -... > > -future:wait_result() > > ---- > > -- null > > -- Duplicate key exists in unique index 'pk' in space 'test' > > -... > > -future:result() > > ---- > > -- null > > -- Duplicate key exists in unique index 'pk' in space 'test' > > -... > > --- > > --- Test discard. > > --- > > -future = c:call('long_function', {1, 2, 3}, {is_async = true}) > > ---- > > -... > > -future:discard() > > ---- > > -... > > -finalize_long() > > ---- > > -... > > -future:result() > > ---- > > -- null > > -- Response is discarded > > -... > > -future:wait_result(100) > > ---- > > -- null > > -- Response is discarded > > -... > > --- > > --- Test closed connection. > > --- > > -future = c:call('long_function', {1, 2, 3}, {is_async = true}) > > ---- > > -... > > -finalize_long() > > ---- > > -... > > -future:wait_result(100) > > ---- > > -- [1, 2, 3] > > -... > > -future2 = c:call('long_function', {1, 2, 3}, {is_async = true}) > > ---- > > -... > > -c:close() > > ---- > > -... > > -future2:wait_result(100) > > ---- > > -- null > > -- Connection closed > > -... > > -future2:result() > > ---- > > -- null > > -- Connection closed > > -... > > -future2:discard() > > ---- > > -... > > --- Already successful result must be available. > > -future:wait_result(100) > > ---- > > -- [1, 2, 3] > > -... > > -future:result() > > ---- > > -- [1, 2, 3] > > -... > > -future:is_ready() > > ---- > > -- true > > -... > > -finalize_long() > > ---- > > -... > > --- > > --- Test reconnect. > > --- > > -c = net:connect(box.cfg.listen, {reconnect_after = 0.01}) > > ---- > > -... > > -future = c:call('long_function', {1, 2, 3}, {is_async = true}) > > ---- > > -... > > -_ = c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') > > ---- > > -... > > -while not c:is_connected() do fiber.sleep(0.01) end > > ---- > > -... > > -finalize_long() > > ---- > > -... > > -future:wait_result(100) > > ---- > > -- null > > -- Peer closed > > -... > > -future:result() > > ---- > > -- null > > -- Peer closed > > -... > > -future = c:call('long_function', {1, 2, 3}, {is_async = true}) > > ---- > > -... > > -finalize_long() > > ---- > > -... > > -future:wait_result(100) > > ---- > > -- [1, 2, 3] > > -... > > --- > > --- Test raw response getting. > > --- > > -ibuf = require('buffer').ibuf() > > ---- > > -... > > -future = c:call('long_function', {1, 2, 3}, {is_async = true, buffer = ibuf}) > > ---- > > -... > > -finalize_long() > > ---- > > -... > > -future:wait_result(100) > > ---- > > -- 10 > > -... > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > ---- > > -... > > -result > > ---- > > -- {48: [1, 2, 3]} > > -... > > -box.schema.func.drop('long_function') > > ---- > > -... > > --- > > --- Test async schema version change. > > --- > > -function change_schema(i) local tmp = box.schema.create_space('test'..i) return 'ok' end > > ---- > > -... > > -box.schema.func.create('change_schema') > > ---- > > -... > > -box.schema.user.grant('guest', 'execute', 'function', 'change_schema') > > ---- > > -... > > -box.schema.user.grant('guest', 'write', 'space', '_schema') > > ---- > > -... > > -box.schema.user.grant('guest', 'read,write', 'space', '_space') > > ---- > > -... > > -box.schema.user.grant('guest', 'create', 'space') > > ---- > > -... > > -future1 = c:call('change_schema', {'1'}, {is_async = true}) > > ---- > > -... > > -future2 = c:call('change_schema', {'2'}, {is_async = true}) > > ---- > > -... > > -future3 = c:call('change_schema', {'3'}, {is_async = true}) > > ---- > > -... > > -future1:wait_result() > > ---- > > -- ['ok'] > > -... > > -future2:wait_result() > > ---- > > -- ['ok'] > > -... > > -future3:wait_result() > > ---- > > -- ['ok'] > > -... > > -c:close() > > ---- > > -... > > -s:drop() > > ---- > > -... > > -box.space.test1:drop() > > ---- > > -... > > -box.space.test2:drop() > > ---- > > -... > > -box.space.test3:drop() > > ---- > > -... > > -box.schema.func.drop('change_schema') > > ---- > > -... > > --- > > --- gh-2978: field names for tuples received from netbox. > > --- > > -_ = box.schema.create_space("named", {format = {{name = "id"}, {name="abc"}}}) > > ---- > > -... > > -_ = box.space.named:create_index('id', {parts = {{1, 'unsigned'}}}) > > ---- > > -... > > -box.space.named:insert({1, 1}) > > ---- > > -- [1, 1] > > -... > > -box.schema.user.grant('guest', 'read, write, execute', 'space') > > ---- > > -... > > -cn = net.connect(box.cfg.listen) > > ---- > > -... > > -s = cn.space.named > > ---- > > -... > > -s:get{1}.id > > ---- > > -- 1 > > -... > > -s:get{1}:tomap() > > ---- > > -- 1: 1 > > - 2: 1 > > - abc: 1 > > - id: 1 > > -... > > -s:insert{2,3}:tomap() > > ---- > > -- 1: 2 > > - 2: 3 > > - abc: 3 > > - id: 2 > > -... > > -s:replace{2,14}:tomap() > > ---- > > -- 1: 2 > > - 2: 14 > > - abc: 14 > > - id: 2 > > -... > > -s:update(1, {{'+', 2, 10}}):tomap() > > ---- > > -- 1: 1 > > - 2: 11 > > - abc: 11 > > - id: 1 > > -... > > -s:select()[1]:tomap() > > ---- > > -- 1: 1 > > - 2: 11 > > - abc: 11 > > - id: 1 > > -... > > -s:delete({2}):tomap() > > ---- > > -- 1: 2 > > - 2: 14 > > - abc: 14 > > - id: 2 > > -... > > --- Check that formats changes after reload. > > -box.space.named:format({{name = "id2"}, {name="abc2"}}) > > ---- > > -... > > -s:select()[1]:tomap() > > ---- > > -- 1: 1 > > - 2: 11 > > - abc: 11 > > - id: 1 > > -... > > -cn:reload_schema() > > ---- > > -... > > -s:select()[1]:tomap() > > ---- > > -- 1: 1 > > - 2: 11 > > - id2: 1 > > - abc2: 11 > > -... > > -cn:close() > > ---- > > -... > > -box.space.named:drop() > > ---- > > -... > > -box.schema.user.revoke('guest', 'read, write, execute', 'space') > > ---- > > -... > > --- > > --- gh-3400: long-poll input discard must not touch event loop of > > --- a closed connection. > > --- > > -function long() fiber.yield() return 100 end > > ---- > > -... > > -c = net.connect(box.cfg.listen) > > ---- > > -... > > -c:ping() > > ---- > > -- true > > -... > > --- Create batch of two requests. First request is sent to TX > > --- thread, second one terminates connection. The preceeding > > --- request discards input, and this operation must not trigger > > --- new attempts to read any data - the connection is closed > > --- already. > > --- > > -f = fiber.create(c._transport.perform_request, nil, nil, false, 'call_17', nil, nil, nil, 'long', {}) c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') > > ---- > > -... > > -while f:status() ~= 'dead' do fiber.sleep(0.01) end > > ---- > > -... > > -c:close() > > ---- > > -... > > --- > > --- gh-3464: iproto hangs in 100% CPU when too big packet size > > --- is received due to size_t overflow. > > --- > > -c = net:connect(box.cfg.listen) > > ---- > > -... > > -data = msgpack.encode(18400000000000000000)..'aaaaaaa' > > ---- > > -... > > -c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, data) > > ---- > > -- null > > -- Peer closed > > -... > > -c:close() > > ---- > > -... > > -test_run:grep_log('default', 'too big packet size in the header') ~= nil > > ---- > > -- true > > -... > > --- > > --- gh-3629: netbox leaks when a connection is closed deliberately > > --- and it has non-finished requests. > > --- > > -ready = false > > ---- > > -... > > -ok = nil > > ---- > > -... > > -err = nil > > ---- > > -... > > -c = net:connect(box.cfg.listen) > > ---- > > -... > > -function do_long() while not ready do fiber.sleep(0.01) end end > > ---- > > -... > > -box.schema.func.create('do_long') > > ---- > > -... > > -box.schema.user.grant('guest', 'execute', 'function', 'do_long') > > ---- > > -... > > -f = fiber.create(function() ok, err = pcall(c.call, c, 'do_long') end) > > ---- > > -... > > -while f:status() ~= 'suspended' do fiber.sleep(0.01) end > > ---- > > -... > > -c:close() > > ---- > > -... > > -ready = true > > ---- > > -... > > -while not err do fiber.sleep(0.01) end > > ---- > > -... > > -ok, err > > ---- > > -- false > > -- Connection closed > > -... > > --- > > --- gh-3856: wait_connected = false is ignored. > > --- > > -c = net.connect('8.8.8.8:123456', {wait_connected = false}) > > ---- > > -... > > -c > > ---- > > -- opts: > > - wait_connected: false > > - host: 8.8.8.8 > > - state: initial > > - port: '123456' > > -... > > -c:close() > > ---- > > -... > > -box.schema.func.drop('do_long') > > ---- > > -... > > -box.schema.user.revoke('guest', 'write', 'space', '_schema') > > ---- > > -... > > -box.schema.user.revoke('guest', 'read,write', 'space', '_space') > > ---- > > -... > > -box.schema.user.revoke('guest', 'create', 'space') > > ---- > > -... > > --- > > --- gh-3958 updating box.cfg.readahead doesn't affect existing connections. > > --- > > -readahead = box.cfg.readahead > > ---- > > -... > > -box.cfg{readahead = 128} > > ---- > > -... > > -s = box.schema.space.create("test") > > ---- > > -... > > -_ = s:create_index("pk") > > ---- > > -... > > -box.schema.user.grant("guest", "read,write", "space", "test") > > ---- > > -... > > --- connection is created with small readahead value, > > --- make sure it is updated if box.cfg.readahead is changed. > > -c = net.connect(box.cfg.listen) > > ---- > > -... > > -box.cfg{readahead = 100 * 1024} > > ---- > > -... > > -box.error.injection.set("ERRINJ_WAL_DELAY", true) > > ---- > > -- ok > > -... > > -pad = string.rep('x', 8192) > > ---- > > -... > > -for i = 1, 5 do c.space.test:replace({i, pad}, {is_async = true}) end > > ---- > > -... > > -box.error.injection.set("ERRINJ_WAL_DELAY", false) > > ---- > > -- ok > > -... > > -test_run:wait_log('default', 'readahead limit is reached', 1024, 0.1) > > ---- > > -... > > -s:drop() > > ---- > > -... > > -box.cfg{readahead = readahead} > > ---- > > -... > > --- > > --- related to gh-4040: log corrupted rows > > --- > > -log_level = box.cfg.log_level > > ---- > > -... > > -box.cfg{log_level=6} > > ---- > > -... > > -sock = socket.tcp_connect(LISTEN.host, LISTEN.service) > > ---- > > -... > > -sock:read(9) > > ---- > > -- Tarantool > > -... > > --- we need to have a packet with correctly encoded length, > > --- so that it bypasses iproto length check, but cannot be > > --- decoded in xrow_header_decode > > --- 0x3C = 60, sha1 digest is 20 bytes long > > -data = string.fromhex('3C'..string.rep(require('digest').sha1_hex('bcde'), 3)) > > ---- > > -... > > -sock:write(data) > > ---- > > -- 61 > > -... > > -sock:close() > > ---- > > -- true > > -... > > -test_run:wait_log('default', 'Got a corrupted row.*', nil, 10) > > ---- > > -- 'Got a corrupted row:' > > -... > > -test_run:wait_log('default', '00000000:.*', nil, 10) > > ---- > > -- '00000000: A3 02 D6 5A E4 D9 E7 68 A1 53 8D 53 60 5F 20 3F ' > > -... > > -test_run:wait_log('default', '00000010:.*', nil, 10) > > ---- > > -- '00000010: D8 E2 D6 E2 A3 02 D6 5A E4 D9 E7 68 A1 53 8D 53 ' > > -... > > -test_run:wait_log('default', '00000020:.*', nil, 10) > > ---- > > -- '00000020: 60 5F 20 3F D8 E2 D6 E2 A3 02 D6 5A E4 D9 E7 68 ' > > -... > > -test_run:wait_log('default', '00000030:.*', nil, 10) > > ---- > > -- '00000030: A1 53 8D 53 60 5F 20 3F D8 E2 D6 E2 ' > > -... > > --- we expect nothing below, so don't wait > > -test_run:grep_log('default', '00000040:.*') > > ---- > > -- null > > -... > > -box.cfg{log_level=log_level} > > ---- > > -... > > diff --git a/test/box/net.box.test.lua b/test/box/net.box.test.lua > > deleted file mode 100644 > > index 8e65ff470..000000000 > > --- a/test/box/net.box.test.lua > > +++ /dev/null > > @@ -1,1585 +0,0 @@ > > -remote = require 'net.box' > > -fiber = require 'fiber' > > -log = require 'log' > > -msgpack = require 'msgpack' > > -env = require('test_run') > > -test_run = env.new() > > -test_run:cmd("push filter ".."'\\.lua.*:[0-9]+: ' to '.lua...\"]:<line>: '") > > - > > -test_run:cmd("setopt delimiter ';'") > > -function x_select(cn, space_id, index_id, iterator, offset, limit, key, opts) > > - local ret = cn:_request('select', opts, nil, space_id, index_id, iterator, > > - offset, limit, key) > > - return ret > > -end > > -function x_fatal(cn) cn._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') end > > -test_run:cmd("setopt delimiter ''"); > > - > > -LISTEN = require('uri').parse(box.cfg.listen) > > -space = box.schema.space.create('net_box_test_space') > > -index = space:create_index('primary', { type = 'tree' }) > > - > > --- low level connection > > -log.info("create connection") > > -cn = remote.connect(LISTEN.host, LISTEN.service) > > -log.info("state is %s", cn.state) > > - > > -cn:ping() > > -log.info("ping is done") > > -cn:ping() > > -log.info("ping is done") > > - > > - > > -cn:ping() > > - > > - > > --- check permissions > > -cn:call('unexists_procedure') > > -function test_foo(a,b,c) return { {{ [a] = 1 }}, {{ [b] = 2 }}, c } end > > -cn:call('test_foo', {'a', 'b', 'c'}) > > -cn:eval('return 2+2') > > -cn:close() > > --- connect and call without usage access > > -box.schema.user.grant('guest','execute','universe') > > -box.schema.user.revoke('guest','usage','universe') > > -box.session.su("guest") > > -cn = remote.connect(LISTEN.host, LISTEN.service) > > -cn:call('test_foo', {'a', 'b', 'c'}) > > -box.session.su("admin") > > -box.schema.user.grant('guest','usage','universe') > > -cn:close() > > -cn = remote.connect(box.cfg.listen) > > - > > -cn:call('unexists_procedure') > > -cn:call('test_foo', {'a', 'b', 'c'}) > > -cn:call(nil, {'a', 'b', 'c'}) > > -cn:eval('return 2+2') > > -cn:eval('return 1, 2, 3') > > -cn:eval('return ...', {1, 2, 3}) > > -cn:eval('return { k = "v1" }, true, { xx = 10, yy = 15 }, nil') > > -cn:eval('return nil') > > -cn:eval('return') > > -cn:eval('error("exception")') > > -cn:eval('box.error(0)') > > -cn:eval('!invalid expression') > > - > > --- box.commit() missing at return of CALL/EVAL > > -function no_commit() box.begin() fiber.sleep(0.001) end > > -cn:call('no_commit') > > -cn:eval('no_commit()') > > - > > -remote.self:eval('return 1+1, 2+2') > > -remote.self:eval('return') > > -remote.self:eval('error("exception")') > > -remote.self:eval('box.error(0)') > > -remote.self:eval('!invalid expression') > > - > > -box.schema.user.revoke('guest', 'execute', 'universe') > > - > > --- > > --- gh-822: net.box.call should roll back local transaction on error > > --- > > - > > -_ = box.schema.space.create('gh822') > > -_ = box.space.gh822:create_index('primary') > > - > > -test_run:cmd("setopt delimiter ';'") > > - > > --- rollback on invalid function > > -function rollback_on_invalid_function() > > - box.begin() > > - box.space.gh822:insert{1, "netbox_test"} > > - pcall(remote.self.call, remote.self, 'invalid_function') > > - return box.space.gh822:get(1) == nil > > -end; > > -rollback_on_invalid_function(); > > - > > --- rollback on call error > > -function test_error() error('Some error') end; > > -function rollback_on_call_error() > > - box.begin() > > - box.space.gh822:insert{1, "netbox_test"} > > - pcall(remote.self.call, remote.self, 'test_error') > > - return box.space.gh822:get(1) == nil > > -end; > > -rollback_on_call_error(); > > - > > --- rollback on eval > > -function rollback_on_eval_error() > > - box.begin() > > - box.space.gh822:insert{1, "netbox_test"} > > - pcall(remote.self.eval, remote.self, "error('Some error')") > > - return box.space.gh822:get(1) == nil > > -end; > > -rollback_on_eval_error(); > > - > > -test_run:cmd("setopt delimiter ''"); > > -box.space.gh822:drop() > > - > > -box.schema.user.grant('guest', 'read,write', 'space', 'net_box_test_space') > > -box.schema.user.grant('guest', 'execute', 'universe') > > - > > -cn:close() > > -cn = remote.connect(box.cfg.listen) > > - > > -x_select(cn, space.id, space.index.primary.id, box.index.EQ, 0, 0xFFFFFFFF, 123) > > -space:insert{123, 345} > > -x_select(cn, space.id, space.index.primary.id, box.index.EQ, 0, 0, 123) > > -x_select(cn, space.id, space.index.primary.id, box.index.EQ, 0, 1, 123) > > -x_select(cn, space.id, space.index.primary.id, box.index.EQ, 1, 1, 123) > > - > > -cn.space[space.id] ~= nil > > -cn.space.net_box_test_space ~= nil > > -cn.space.net_box_test_space ~= nil > > -cn.space.net_box_test_space.index ~= nil > > -cn.space.net_box_test_space.index.primary ~= nil > > -cn.space.net_box_test_space.index[space.index.primary.id] ~= nil > > - > > - > > -cn.space.net_box_test_space.index.primary:select(123) > > -cn.space.net_box_test_space.index.primary:select(123, { limit = 0 }) > > -cn.space.net_box_test_space.index.primary:select(nil, { limit = 1, }) > > -cn.space.net_box_test_space:insert{234, 1,2,3} > > -cn.space.net_box_test_space:insert{234, 1,2,3} > > -cn.space.net_box_test_space.insert{234, 1,2,3} > > - > > -cn.space.net_box_test_space:replace{354, 1,2,3} > > -cn.space.net_box_test_space:replace{354, 1,2,4} > > - > > -cn.space.net_box_test_space:select{123} > > -space:select({123}, { iterator = 'GE' }) > > -cn.space.net_box_test_space:select({123}, { iterator = 'GE' }) > > -cn.space.net_box_test_space:select({123}, { iterator = 'GT' }) > > -cn.space.net_box_test_space:select({123}, { iterator = 'GT', limit = 1 }) > > -cn.space.net_box_test_space:select({123}, { iterator = 'GT', limit = 1, offset = 1 }) > > - > > -cn.space.net_box_test_space:select{123} > > -cn.space.net_box_test_space:update({123}, { { '+', 2, 1 } }) > > -cn.space.net_box_test_space:update(123, { { '+', 2, 1 } }) > > -cn.space.net_box_test_space:select{123} > > - > > -cn.space.net_box_test_space:insert(cn.space.net_box_test_space:get{123}:update{ { '=', 1, 2 } }) > > -cn.space.net_box_test_space:delete{123} > > -cn.space.net_box_test_space:select{2} > > -cn.space.net_box_test_space:select({234}, { iterator = 'LT' }) > > - > > -cn.space.net_box_test_space:update({1}, { { '+', 2, 2 } }) > > - > > -cn.space.net_box_test_space:delete{1} > > -cn.space.net_box_test_space:delete{2} > > -cn.space.net_box_test_space:delete{2} > > - > > --- test one-based indexing in splice operation (see update.test.lua) > > -cn.space.net_box_test_space:replace({10, 'abcde'}) > > -cn.space.net_box_test_space:update(10, {{':', 2, 0, 0, '!'}}) > > -cn.space.net_box_test_space:update(10, {{':', 2, 1, 0, '('}}) > > -cn.space.net_box_test_space:update(10, {{':', 2, 2, 0, '({'}}) > > -cn.space.net_box_test_space:update(10, {{':', 2, -1, 0, ')'}}) > > -cn.space.net_box_test_space:update(10, {{':', 2, -2, 0, '})'}}) > > -cn.space.net_box_test_space:delete{10} > > - > > -cn.space.net_box_test_space:select({}, { iterator = 'ALL' }) > > --- gh-841: net.box uses incorrect iterator type for select with no arguments > > -cn.space.net_box_test_space:select() > > - > > -cn.space.net_box_test_space.index.primary:min() > > -cn.space.net_box_test_space.index.primary:min(354) > > -cn.space.net_box_test_space.index.primary:max() > > -cn.space.net_box_test_space.index.primary:max(234) > > -cn.space.net_box_test_space.index.primary:count() > > -cn.space.net_box_test_space.index.primary:count(354) > > - > > -cn.space.net_box_test_space:get(354) > > - > > --- reconnects after errors > > - > > -box.schema.user.revoke('guest', 'execute', 'universe') > > -box.schema.func.create('test_foo') > > -box.schema.user.grant('guest', 'execute', 'function', 'test_foo') > > - > > --- -- 1. no reconnect > > -x_fatal(cn) > > -cn.state > > -cn:ping() > > -cn:call('test_foo') > > -cn:wait_state('active') > > - > > --- -- 2 reconnect > > -cn = remote.connect(LISTEN.host, LISTEN.service, { reconnect_after = .1 }) > > -cn.space ~= nil > > - > > -cn.space.net_box_test_space:select({}, { iterator = 'ALL' }) > > -x_fatal(cn) > > -cn:wait_connected() > > -cn:wait_state('active') > > -cn:wait_state({active=true}) > > -cn:ping() > > -cn.state > > -cn.space.net_box_test_space:select({}, { iterator = 'ALL' }) > > - > > -x_fatal(cn) > > -x_select(cn, space.id, 0, box.index.ALL, 0, 0xFFFFFFFF, {}) > > - > > -cn.state > > -cn:ping() > > - > > --- -- dot-new-method > > - > > -cn1 = remote.new(LISTEN.host, LISTEN.service) > > -x_select(cn1, space.id, 0, box.index.ALL, 0, 0xFFFFFFF, {}) > > -cn1:close() > > --- -- error while waiting for response > > -type(fiber.create(function() fiber.sleep(.5) x_fatal(cn) end)) > > -function pause() fiber.sleep(10) return true end > > - > > -box.schema.func.create('pause') > > -box.schema.user.grant('guest', 'execute', 'function', 'pause') > > -cn:call('pause') > > -cn:call('test_foo', {'a', 'b', 'c'}) > > -box.schema.func.drop('pause') > > - > > --- call > > -remote.self:call('test_foo', {'a', 'b', 'c'}) > > -cn:call('test_foo', {'a', 'b', 'c'}) > > -box.schema.func.drop('test_foo') > > - > > -box.schema.func.create('long_rep') > > -box.schema.user.grant('guest', 'execute', 'function', 'long_rep') > > - > > --- long replies > > -function long_rep() return { 1, string.rep('a', 5000) } end > > -res = cn:call('long_rep') > > -res[1] == 1 > > -res[2] == string.rep('a', 5000) > > - > > -function long_rep() return { 1, string.rep('a', 50000) } end > > -res = cn:call('long_rep') > > -res[1] == 1 > > -res[2] == string.rep('a', 50000) > > - > > -box.schema.func.drop('long_rep') > > - > > --- a.b.c.d > > -u = '84F7BCFA-079C-46CC-98B4-F0C821BE833E' > > -X = {} > > -X.X = X > > -function X.fn(x,y) return y or x end > > -box.schema.user.grant('guest', 'execute', 'universe') > > -cn:close() > > -cn = remote.connect(LISTEN.host, LISTEN.service) > > -cn:call('X.fn', {u}) > > -cn:call('X.X.X.X.X.X.X.fn', {u}) > > -cn:call('X.X.X.X:fn', {u}) > > -box.schema.user.revoke('guest', 'execute', 'universe') > > -cn:close() > > - > > --- auth > > - > > -cn = remote.connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123', wait_connected = true }) > > -cn:is_connected() > > -cn.error > > -cn.state > > - > > - > > -box.schema.user.create('netbox', { password = 'test' }) > > -box.schema.user.grant('netbox', 'read,write', 'space', 'net_box_test_space') > > -box.schema.user.grant('netbox', 'execute', 'universe') > > -cn = remote.connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = 'test' }) > > -cn.state > > -cn.error > > -cn:ping() > > - > > -function ret_after(to) fiber.sleep(to) return {{to}} end > > - > > -cn:ping({timeout = 1.00}) > > -cn:ping({timeout = 1e-9}) > > -cn:ping() > > - > > -remote_space = cn.space.net_box_test_space > > -remote_pk = remote_space.index.primary > > - > > -remote_space:insert({0}, { timeout = 1.00 }) > > -remote_space:insert({1}, { timeout = 1e-9 }) > > -remote_space:insert({2}) > > - > > -remote_space:replace({0}, { timeout = 1e-9 }) > > -remote_space:replace({1}) > > -remote_space:replace({2}, { timeout = 1.00 }) > > - > > -remote_space:upsert({3}, {}, { timeout = 1e-9 }) > > -remote_space:upsert({4}, {}) > > -remote_space:upsert({5}, {}, { timeout = 1.00 }) > > -remote_space:upsert({3}, {}) > > - > > -remote_space:update({3}, {}, { timeout = 1e-9 }) > > -remote_space:update({4}, {}) > > -remote_space:update({5}, {}, { timeout = 1.00 }) > > -remote_space:update({3}, {}) > > - > > -remote_pk:update({5}, {}, { timeout = 1e-9 }) > > -remote_pk:update({4}, {}) > > -remote_pk:update({3}, {}, { timeout = 1.00 }) > > -remote_pk:update({5}, {}) > > - > > -remote_space:get({0}) > > -remote_space:get({1}, { timeout = 1.00 }) > > -remote_space:get({2}, { timeout = 1e-9 }) > > - > > -remote_pk:get({3}, { timeout = 1e-9 }) > > -remote_pk:get({4}) > > -remote_pk:get({5}, { timeout = 1.00 }) > > - > > -remote_space:select({2}, { timeout = 1e-9 }) > > -remote_space:select({2}, { timeout = 1.00 }) > > -remote_space:select({2}) > > - > > -remote_pk:select({2}, { timeout = 1.00 }) > > -remote_pk:select({2}, { timeout = 1e-9 }) > > -remote_pk:select({2}) > > - > > -remote_space:select({5}, { timeout = 1.00, iterator = 'LE', limit = 5 }) > > -remote_space:select({5}, { iterator = 'LE', limit = 5}) > > -remote_space:select({5}, { timeout = 1e-9, iterator = 'LE', limit = 5 }) > > - > > -remote_pk:select({2}, { timeout = 1.00, iterator = 'LE', limit = 5 }) > > -remote_pk:select({2}, { iterator = 'LE', limit = 5}) > > -remote_pk:select({2}, { timeout = 1e-9, iterator = 'LE', limit = 5 }) > > - > > -remote_pk:count({2}, { timeout = 1.00}) > > -remote_pk:count({2}, { timeout = 1e-9}) > > -remote_pk:count({2}) > > - > > -remote_pk:count({2}, { timeout = 1.00, iterator = 'LE' }) > > -remote_pk:count({2}, { iterator = 'LE'}) > > -remote_pk:count({2}, { timeout = 1e-9, iterator = 'LE' }) > > - > > -remote_pk:min(nil, { timeout = 1.00 }) > > -remote_pk:min(nil, { timeout = 1e-9 }) > > -remote_pk:min(nil) > > - > > -remote_pk:min({0}, { timeout = 1e-9 }) > > -remote_pk:min({1}) > > -remote_pk:min({2}, { timeout = 1.00 }) > > - > > -remote_pk:max(nil) > > -remote_pk:max(nil, { timeout = 1e-9 }) > > -remote_pk:max(nil, { timeout = 1.00 }) > > - > > -remote_pk:max({0}, { timeout = 1.00 }) > > -remote_pk:max({1}, { timeout = 1e-9 }) > > -remote_pk:max({2}) > > - > > --- > > --- gh-3262: index:count() inconsistent results > > --- > > -test_run:cmd("setopt delimiter ';'") > > - > > -function do_count_test(min, it) > > - local r1 = remote_pk:count(min, {iterator = it} ) > > - local r2 = box.space.net_box_test_space.index.primary:count(min, {iterator = it} ) > > - local r3 = remote.self.space.net_box_test_space.index.primary:count(min, {iterator = it} ) > > - return r1 == r2 and r2 == r3 > > -end; > > - > > -data = remote_pk:select(); > > - > > -for _, v in pairs(data) do > > - local itrs = {'GE', 'GT', 'LE', 'LT' } > > - for _, it in pairs(itrs) do > > - assert(do_count_test(v[0], it) == true) > > - end > > -end; > > - > > -test_run:cmd("setopt delimiter ''"); > > - > > -_ = remote_space:delete({0}, { timeout = 1e-9 }) > > -_ = remote_pk:delete({0}, { timeout = 1.00 }) > > -_ = remote_space:delete({1}, { timeout = 1.00 }) > > -_ = remote_pk:delete({1}, { timeout = 1e-9 }) > > -_ = remote_space:delete({2}, { timeout = 1e-9 }) > > -_ = remote_pk:delete({2}) > > -_ = remote_pk:delete({3}) > > -_ = remote_pk:delete({4}) > > -_ = remote_pk:delete({5}) > > - > > -remote_space:get(0) > > -remote_space:get(1) > > -remote_space:get(2) > > - > > -remote_space = nil > > - > > -cn:call('ret_after', {0.01}, { timeout = 1.00 }) > > -cn:call('ret_after', {1.00}, { timeout = 1e-9 }) > > - > > -cn:eval('return ret_after(...)', {0.01}, { timeout = 1.00 }) > > -cn:eval('return ret_after(...)', {1.00}, { timeout = 1e-9 }) > > - > > --- > > --- :timeout() > > --- @deprecated since 1.7.4 > > --- > > - > > -cn:timeout(1).space.net_box_test_space.index.primary:select{234} > > -cn:call('ret_after', {.01}) > > -cn:timeout(1):call('ret_after', {.01}) > > -cn:timeout(.01):call('ret_after', {1}) > > - > > -cn = remote:timeout(0.0000000001):connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123' }) > > -cn:close() > > -cn = remote:timeout(1):connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123' }) > > - > > -remote.self:ping() > > -remote.self.space.net_box_test_space:select{234} > > -remote.self:timeout(123).space.net_box_test_space:select{234} > > -remote.self:is_connected() > > -remote.self:wait_connected() > > - > > -cn:close() > > --- cleanup database after tests > > -space:drop() > > - > > --- #1545 empty password > > -cn = remote.connect(LISTEN.host, LISTEN.service, { user = 'test' }) > > -cn ~= nil > > -cn:close() > > -cn = remote.connect(LISTEN.host, LISTEN.service, { password = 'test' }) > > -cn ~= nil > > -cn:close() > > - > > --- #544 usage for remote[point]method > > -cn = remote.connect(LISTEN.host, LISTEN.service) > > - > > -box.schema.user.grant('guest', 'execute', 'universe') > > -cn:close() > > -cn = remote.connect(LISTEN.host, LISTEN.service) > > -cn:eval('return true') > > -cn.eval('return true') > > - > > -cn.ping() > > - > > -cn:close() > > - > > -remote.self:eval('return true') > > -remote.self.eval('return true') > > -box.schema.user.revoke('guest', 'execute', 'universe') > > - > > --- uri as the first argument > > -uri = string.format('%s:%s@%s:%s', 'netbox', 'test', LISTEN.host, LISTEN.service) > > - > > -cn = remote.new(uri) > > -cn:ping() > > -cn:close() > > - > > -uri = string.format('%s@%s:%s', 'netbox', LISTEN.host, LISTEN.service) > > -cn = remote.new(uri) > > -cn ~= nil, cn.state, cn.error > > -cn:close() > > --- don't merge creds from uri & opts > > -remote.new(uri, { password = 'test' }) > > -cn = remote.new(uri, { user = 'netbox', password = 'test' }) > > -cn:ping() > > -cn:close() > > - > > -box.schema.user.drop('netbox') > > - > > --- #594: bad argument #1 to 'setmetatable' (table expected, got number) > > -box.schema.func.create('dostring') > > -box.schema.user.grant('guest', 'execute', 'function', 'dostring') > > -test_run:cmd("setopt delimiter ';'") > > -function gh594() > > - local cn = remote.connect(box.cfg.listen) > > - local ping = fiber.create(function() cn:ping() end) > > - cn:call('dostring', {'return 2 + 2'}) > > - cn:close() > > -end; > > -test_run:cmd("setopt delimiter ''"); > > -gh594() > > -box.schema.func.drop('dostring') > > - > > - > > --- #636: Reload schema on demand > > -sp = box.schema.space.create('test_old') > > -_ = sp:create_index('primary') > > -sp:insert{1, 2, 3} > > - > > -box.schema.user.grant('guest', 'read', 'space', 'test_old') > > -con = remote.new(box.cfg.listen) > > -con:ping() > > -con.space.test_old:select{} > > -con.space.test == nil > > - > > -sp = box.schema.space.create('test') > > -_ = sp:create_index('primary') > > -sp:insert{2, 3, 4} > > - > > -box.schema.user.grant('guest', 'read', 'space', 'test') > > - > > -con.space.test == nil > > -con:reload_schema() > > -con.space.test:select{} > > - > > -box.space.test:drop() > > -box.space.test_old:drop() > > -con:close() > > - > > -name = string.match(arg[0], "([^,]+)%.lua") > > -file_log = require('fio').open(name .. '.log', {'O_RDONLY', 'O_NONBLOCK'}) > > -file_log:seek(0, 'SEEK_END') ~= 0 > > - > > -box.schema.user.grant('guest', 'execute', 'universe') > > -test_run:cmd("setopt delimiter ';'") > > - > > -_ = fiber.create( > > - function() > > - local conn = require('net.box').new(box.cfg.listen) > > - conn:call('no_such_function', {}) > > - conn:close() > > - end > > -); > > -test_run:cmd("setopt delimiter ''"); > > -test_run:wait_log('default', 'ER_NO_SUCH_PROC', nil, 10) > > -box.schema.user.revoke('guest', 'execute', 'universe') > > - > > --- > > --- gh-3900: tarantool can be crashed by sending gibberish to a > > --- binary socket > > --- > > -socket = require("socket") > > -sock = socket.tcp_connect(LISTEN.host, LISTEN.service) > > -data = string.fromhex("6783000000000000000000000000000000000000000000800000C8000000000000000000000000000000000000000000FFFF210100373208000000FFFF000055AAEB66486472530D02000000000010A0350001008000001000000000000000000000000000D05700") > > -sock:write(data) > > -test_run:wait_log('default', 'ER_INVALID_MSGPACK: Invalid MsgPack %- packet body', nil, 10) > > -sock:close() > > - > > --- gh-983 selecting a lot of data crashes the server or hangs the > > --- connection > > - > > --- gh-983 test case: iproto connection selecting a lot of data > > -_ = box.schema.space.create('test', { temporary = true }) > > -_ = box.space.test:create_index('primary', {type = 'TREE', parts = {1,'unsigned'}}) > > - > > -data1k = "aaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhh" > > - > > -for i = 0,10000 do box.space.test:insert{i, data1k} end > > - > > -box.schema.user.grant('guest', 'read', 'space', 'test') > > -net = require('net.box') > > -c = net:connect(box.cfg.listen) > > -r = c.space.test:select(nil, {limit=5000}) > > -box.space.test:drop() > > - > > --- gh-970 gh-971 UPSERT over network > > -_ = box.schema.space.create('test') > > -_ = box.space.test:create_index('primary', {type = 'TREE', parts = {1,'unsigned'}}) > > -_ = box.space.test:create_index('covering', {type = 'TREE', parts = {1,'unsigned',3,'string',2,'unsigned'}}) > > -_ = box.space.test:insert{1, 2, "string"} > > -box.schema.user.grant('guest', 'read,write', 'space', 'test') > > -c = net:connect(box.cfg.listen) > > -c.space.test:select{} > > -c.space.test:upsert({1, 2, 'nothing'}, {{'+', 2, 1}}) -- common update > > -c.space.test:select{} > > -c.space.test:upsert({2, 4, 'something'}, {{'+', 2, 1}}) -- insert > > -c.space.test:select{} > > -c.space.test:upsert({2, 4, 'nothing'}, {{'+', 3, 100500}}) -- wrong operation > > -c.space.test:select{} > > - > > --- gh-1729 net.box index metadata incompatible with local metadata > > -c.space.test.index.primary.parts > > -c.space.test.index.covering.parts > > - > > -box.space.test:drop() > > - > > --- CALL vs CALL_16 in connect options > > -function echo(...) return ... end > > -box.schema.user.grant('guest', 'execute', 'universe') > > -c = net.connect(box.cfg.listen) > > -c:call('echo', {42}) > > -c:eval('return echo(...)', {42}) > > --- invalid arguments > > -c:call('echo', 42) > > -c:eval('return echo(...)', 42) > > -c:close() > > -c = net.connect(box.cfg.listen, {call_16 = true}) > > -c:call('echo', 42) > > -c:eval('return echo(...)', 42) > > -c:close() > > -box.schema.user.revoke('guest', 'execute', 'universe') > > - > > --- > > --- gh-2195 export pure msgpack from net.box > > --- > > - > > -space = box.schema.space.create('test') > > -_ = box.space.test:create_index('primary') > > -box.schema.user.grant('guest', 'read,write', 'space', 'test') > > -box.schema.user.grant('guest', 'execute', 'universe') > > -c = net.connect(box.cfg.listen) > > -ibuf = require('buffer').ibuf() > > - > > -c:ping() > > -c.space.test ~= nil > > - > > -c.space.test:replace({1, 'hello'}) > > - > > --- replace > > -c.space.test:replace({2}, {buffer = ibuf}) > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > -result > > - > > --- replace + skip_header > > -c.space.test:replace({2}, {buffer = ibuf, skip_header = true}) > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > -result > > - > > --- insert > > -c.space.test:insert({3}, {buffer = ibuf}) > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > -result > > - > > --- insert + skip_header > > -_ = space:delete({3}) > > -c.space.test:insert({3}, {buffer = ibuf, skip_header = true}) > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > -result > > - > > --- update > > -c.space.test:update({3}, {}, {buffer = ibuf}) > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > -result > > -c.space.test.index.primary:update({3}, {}, {buffer = ibuf}) > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > -result > > - > > --- update + skip_header > > -c.space.test:update({3}, {}, {buffer = ibuf, skip_header = true}) > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > -result > > -c.space.test.index.primary:update({3}, {}, {buffer = ibuf, skip_header = true}) > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > -result > > - > > --- upsert > > -c.space.test:upsert({4}, {}, {buffer = ibuf}) > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > -result > > - > > --- upsert + skip_header > > -c.space.test:upsert({4}, {}, {buffer = ibuf, skip_header = true}) > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > -result > > - > > --- delete > > -c.space.test:upsert({4}, {}, {buffer = ibuf}) > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > -result > > - > > --- delete + skip_header > > -c.space.test:upsert({4}, {}, {buffer = ibuf, skip_header = true}) > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > -result > > - > > --- select > > -c.space.test.index.primary:select({3}, {iterator = 'LE', buffer = ibuf}) > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > -result > > - > > --- select + skip_header > > -c.space.test.index.primary:select({3}, {iterator = 'LE', buffer = ibuf, skip_header = true}) > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > -result > > - > > --- select > > -len = c.space.test:select({}, {buffer = ibuf}) > > -ibuf.rpos + len == ibuf.wpos > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > -ibuf.rpos == ibuf.wpos > > -len > > -result > > - > > --- select + skip_header > > -len = c.space.test:select({}, {buffer = ibuf, skip_header = true}) > > -ibuf.rpos + len == ibuf.wpos > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > -ibuf.rpos == ibuf.wpos > > -len > > -result > > - > > --- call > > -c:call("echo", {1, 2, 3}, {buffer = ibuf}) > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > -result > > -c:call("echo", {}, {buffer = ibuf}) > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > -result > > -c:call("echo", nil, {buffer = ibuf}) > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > -result > > - > > --- call + skip_header > > -c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > -result > > -c:call("echo", {}, {buffer = ibuf, skip_header = true}) > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > -result > > -c:call("echo", nil, {buffer = ibuf, skip_header = true}) > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > -result > > - > > --- eval > > -c:eval("echo(...)", {1, 2, 3}, {buffer = ibuf}) > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > -result > > -c:eval("echo(...)", {}, {buffer = ibuf}) > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > -result > > -c:eval("echo(...)", nil, {buffer = ibuf}) > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > -result > > - > > --- eval + skip_header > > -c:eval("echo(...)", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > -result > > -c:eval("echo(...)", {}, {buffer = ibuf, skip_header = true}) > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > -result > > -c:eval("echo(...)", nil, {buffer = ibuf, skip_header = true}) > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > -result > > - > > --- make several request into a buffer with skip_header, then read > > --- results > > -c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > > -c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > > -c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > -result > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > -result > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > -result > > - > > --- unsupported methods > > -c.space.test:get({1}, { buffer = ibuf}) > > -c.space.test.index.primary:min({}, { buffer = ibuf}) > > -c.space.test.index.primary:max({}, { buffer = ibuf}) > > -c.space.test.index.primary:count({}, { buffer = ibuf}) > > -c.space.test.index.primary:get({1}, { buffer = ibuf}) > > - > > --- error handling > > -rpos, wpos = ibuf.rpos, ibuf.wpos > > -c.space.test:insert({1}, {buffer = ibuf}) > > -ibuf.rpos == rpos, ibuf.wpos == wpos > > - > > -ibuf = nil > > -c:close() > > -space:drop() > > -box.schema.user.revoke('guest', 'execute', 'universe') > > - > > --- gh-1904 net.box hangs in :close() if a fiber was cancelled > > --- while blocked in :_wait_state() in :_request() > > -options = {user = 'netbox', password = 'badpass', wait_connected = false, reconnect_after = 0.01} > > -c = net:new(box.cfg.listen, options) > > -f = fiber.create(function() c:call("") end) > > -fiber.sleep(0.01) > > -f:cancel(); c:close() > > - > > -box.schema.user.grant('guest', 'read', 'space', '_schema') > > - > > --- check for on_schema_reload callback > > -test_run:cmd("setopt delimiter ';'") > > -do > > - local a = 0 > > - function osr_cb() > > - a = a + 1 > > - end > > - local con = net.new(box.cfg.listen, { > > - wait_connected = false > > - }) > > - con:on_schema_reload(osr_cb) > > - con:wait_connected() > > - con.space._schema:select{} > > - box.schema.space.create('misisipi') > > - box.space.misisipi:drop() > > - con.space._schema:select{} > > - con:close() > > - con = nil > > - > > - return a > > -end; > > -do > > - local a = 0 > > - function osr_cb() > > - a = a + 1 > > - end > > - local con = net.new(box.cfg.listen, { > > - wait_connected = true > > - }) > > - con:on_schema_reload(osr_cb) > > - con.space._schema:select{} > > - box.schema.space.create('misisipi') > > - box.space.misisipi:drop() > > - con.space._schema:select{} > > - con:close() > > - con = nil > > - > > - return a > > -end; > > -test_run:cmd("setopt delimiter ''"); > > - > > -box.schema.user.revoke('guest', 'read', 'space', '_schema') > > - > > --- Tarantool < 1.7.1 compatibility (gh-1533) > > -c = net.new(box.cfg.listen) > > -c:ping() > > -c:close() > > - > > --- Test for connect_timeout > 0 in netbox connect > > -test_run:cmd("setopt delimiter ';'"); > > -need_stop = false; > > -greeting = > > -"Tarantool 1.7.3 (Lua console)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" .. > > -"type 'help' for interactive help~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"; > > -socket = require('socket'); > > -srv = socket.tcp_server('localhost', 0, { > > - handler = function(fd) > > - local fiber = require('fiber') > > - while not need_stop do > > - fiber.sleep(0.01) > > - end > > - fd:write(greeting) > > - end > > -}); > > -port = srv:name().port > > --- we must get timeout > > -nb = net.new('localhost:' .. port, { > > - wait_connected = true, console = true, > > - connect_timeout = 0.1 > > -}); > > -nb.error:find('timed out') ~= nil; > > -need_stop = true > > -nb:close(); > > --- we must get peer closed > > -nb = net.new('localhost:' .. port, { > > - wait_connected = true, console = true, > > - connect_timeout = 0.2 > > -}); > > -nb.error ~= "Timeout exceeded"; > > -nb:close(); > > -test_run:cmd("setopt delimiter ''"); > > -srv:close() > > - > > -test_run:cmd("clear filter") > > - > > --- > > --- gh-2402 net.box doesn't support space:format() > > --- > > - > > -space = box.schema.space.create('test', {format={{name="id", type="unsigned"}}}) > > -space ~= nil > > -_ = box.space.test:create_index('primary') > > -box.schema.user.grant('guest', 'read', 'space', 'test') > > - > > -c = net.connect(box.cfg.listen) > > - > > -c:ping() > > -c.space.test ~= nil > > - > > -format = c.space.test:format() > > - > > -format[1] ~= nil > > -format[1].name == "id" > > -format[1].type == "unsigned" > > - > > -c.space.test:format({}) > > - > > --- > > --- gh-4091: index unique flag is always false. > > --- > > -c.space.test.index.primary.unique > > - > > -c:close() > > -space:drop() > > - > > --- > > --- Check that it's possible to get connection object form net.box space > > --- > > - > > -space = box.schema.space.create('test', {format={{name="id", type="unsigned"}}}) > > -space ~= nil > > -_ = box.space.test:create_index('primary') > > -box.schema.user.grant('guest','read,write,execute','space', 'test') > > - > > -c = net.connect(box.cfg.listen) > > - > > -c:ping() > > -c.space.test ~= nil > > - > > -c.space.test.connection == c > > -box.schema.user.revoke('guest','read,write,execute','space', 'test') > > -c:close() > > - > > --- > > --- gh-2642: box.session.type() > > --- > > - > > -box.schema.user.grant('guest','execute','universe') > > -c = net.connect(box.cfg.listen) > > -c:call("box.session.type") > > -c:close() > > -box.schema.user.revoke('guest', 'execute', 'universe') > > - > > - > > --- > > --- On_connect/disconnect triggers. > > --- > > -test_run:cmd('create server connecter with script = "box/proxy.lua"') > > -test_run:cmd('start server connecter') > > -test_run:cmd("set variable connect_to to 'connecter.listen'") > > -conn = net.connect(connect_to, { reconnect_after = 0.1 }) > > -conn.state > > -connected_cnt = 0 > > -disconnected_cnt = 0 > > -function on_connect() connected_cnt = connected_cnt + 1 end > > -function on_disconnect() disconnected_cnt = disconnected_cnt + 1 end > > -conn:on_connect(on_connect) > > -conn:on_disconnect(on_disconnect) > > -test_run:cmd('stop server connecter') > > -test_run:cmd('start server connecter') > > -while conn.state ~= 'active' do fiber.sleep(0.1) end > > -connected_cnt > > -old_disconnected_cnt = disconnected_cnt > > -disconnected_cnt >= 1 > > -conn:close() > > -disconnected_cnt == old_disconnected_cnt + 1 > > -test_run:cmd('stop server connecter') > > - > > --- > > --- gh-2401 update pseudo objects not replace them > > --- > > -space:drop() > > -space = box.schema.space.create('test') > > -box.schema.user.grant('guest', 'read', 'space', 'test') > > -c = net.connect(box.cfg.listen) > > -cspace = c.space.test > > -space.index.test_index == nil > > -cspace.index.test_index == nil > > -_ = space:create_index("test_index", {parts={1, 'string'}}) > > -c:reload_schema() > > -space.index.test_index ~= nil > > -cspace.index.test_index ~= nil > > -c.space.test.index.test_index ~= nil > > - > > --- cleanup > > - > > -space:drop() > > - > > --- > > --- gh-946: long polling CALL blocks input > > --- > > -box.schema.func.create('fast_call') > > -box.schema.func.create('long_call') > > -box.schema.func.create('wait_signal') > > -box.schema.user.grant('guest', 'execute', 'function', 'fast_call') > > -box.schema.user.grant('guest', 'execute', 'function', 'long_call') > > -box.schema.user.grant('guest', 'execute', 'function', 'wait_signal') > > -c = net.connect(box.cfg.listen) > > - > > -N = 100 > > - > > -pad = string.rep('x', 1024) > > - > > -long_call_cond = fiber.cond() > > -long_call_channel = fiber.channel() > > -fast_call_channel = fiber.channel() > > - > > -function fast_call(x) return x end > > -function long_call(x) long_call_cond:wait() return x * 2 end > > - > > -test_run:cmd("setopt delimiter ';'") > > -for i = 1, N do > > - fiber.create(function() > > - fast_call_channel:put(c:call('fast_call', {i, pad})) > > - end) > > - fiber.create(function() > > - long_call_channel:put(c:call('long_call', {i, pad})) > > - end) > > -end > > -test_run:cmd("setopt delimiter ''"); > > - > > -x = 0 > > -for i = 1, N do x = x + fast_call_channel:get() end > > -x > > - > > -long_call_cond:broadcast() > > - > > -x = 0 > > -for i = 1, N do x = x + long_call_channel:get() end > > -x > > - > > --- > > --- Check that a connection does not leak if there is > > --- a long CALL in progress when it is closed. > > --- > > -disconnected = false > > -function on_disconnect() disconnected = true end > > - > > --- Make sure all dangling connections are collected so > > --- that on_disconnect trigger isn't called spuriously. > > -collectgarbage('collect') > > -fiber.sleep(0) > > - > > -box.session.on_disconnect(on_disconnect) == on_disconnect > > - > > --- > > --- gh-3859: on_disconnect is called only after all requests are > > --- processed, but should be called right after disconnect and > > --- only once. > > --- > > -ch1 = fiber.channel(1) > > -ch2 = fiber.channel(1) > > -function wait_signal() ch1:put(true) ch2:get() end > > -_ = fiber.create(function() c:call('wait_signal') end) > > -ch1:get() > > - > > -c:close() > > -fiber.sleep(0) > > -while disconnected == false do fiber.sleep(0.01) end > > -disconnected -- true > > -disconnected = nil > > - > > -ch2:put(true) > > -fiber.sleep(0) > > -disconnected -- nil, on_disconnect is not called second time. > > - > > -box.session.on_disconnect(nil, on_disconnect) > > - > > -box.schema.func.drop('long_call') > > -box.schema.func.drop('fast_call') > > -box.schema.func.drop('wait_signal') > > --- > > --- gh-2666: check that netbox.call is not repeated on schema > > --- change. > > --- > > -box.schema.user.grant('guest', 'write', 'space', '_space') > > -box.schema.user.grant('guest', 'write', 'space', '_schema') > > -box.schema.user.grant('guest', 'create', 'universe') > > -count = 0 > > -function create_space(name) count = count + 1 box.schema.create_space(name) return true end > > -box.schema.func.create('create_space') > > -box.schema.user.grant('guest', 'execute', 'function', 'create_space') > > -c = net.connect(box.cfg.listen) > > -c:call('create_space', {'test1'}) > > -count > > -c:call('create_space', {'test2'}) > > -count > > -c:call('create_space', {'test3'}) > > -count > > -box.space.test1:drop() > > -box.space.test2:drop() > > -box.space.test3:drop() > > -box.schema.user.revoke('guest', 'write', 'space', '_space') > > -box.schema.user.revoke('guest', 'write', 'space', '_schema') > > -box.schema.user.revoke('guest', 'create', 'universe') > > -c:close() > > -box.schema.func.drop('create_space') > > - > > --- > > --- gh-3164: netbox connection is not closed and garbage collected > > --- ever, if reconnect_after is set. > > --- > > -test_run:cmd('start server connecter') > > -test_run:cmd("set variable connect_to to 'connecter.listen'") > > -weak = setmetatable({}, {__mode = 'v'}) > > --- Create strong and weak reference. Weak is valid until strong > > --- is valid too. > > -strong = net.connect(connect_to, {reconnect_after = 0.1}) > > -weak.c = strong > > -weak.c:ping() > > -test_run:cmd('stop server connecter') > > -test_run:cmd('cleanup server connecter') > > --- Check the connection tries to reconnect at least two times. > > --- 'Cannot assign requested address' is the crutch for running the > > --- tests in a docker. This error emits instead of > > --- 'Connection refused' inside a docker. > > -old_log_level = box.cfg.log_level > > -box.cfg{log_level = 6} > > -log.info(string.rep('a', 1000)) > > -test_run:cmd("setopt delimiter ';'") > > -while test_run:grep_log('default', 'Network is unreachable', 1000) == nil and > > - test_run:grep_log('default', 'Connection refused', 1000) == nil and > > - test_run:grep_log('default', 'Cannot assign requested address', 1000) == nil do > > - fiber.sleep(0.1) > > -end; > > -log.info(string.rep('a', 1000)); > > -while test_run:grep_log('default', 'Network is unreachable', 1000) == nil and > > - test_run:grep_log('default', 'Connection refused', 1000) == nil and > > - test_run:grep_log('default', 'Cannot assign requested address', 1000) == nil do > > - fiber.sleep(0.1) > > -end; > > -test_run:cmd("setopt delimiter ''"); > > -box.cfg{log_level = old_log_level} > > -collectgarbage('collect') > > -strong.state > > -strong == weak.c > > --- Remove single strong reference. Now connection must be garbage > > --- collected. > > -strong = nil > > -collectgarbage('collect') > > --- Now weak.c is null, because it was weak reference, and the > > --- connection is deleted by 'collect'. > > -weak.c > > - > > --- > > --- gh-2677: netbox supports console connections, that complicates > > --- both console and netbox. It was necessary because before a > > --- connection is established, a console does not known is it > > --- binary or text protocol, and netbox could not be created from > > --- existing socket. > > --- > > -box.schema.user.grant('guest', 'execute', 'universe') > > -urilib = require('uri') > > -uri = urilib.parse(tostring(box.cfg.listen)) > > -s, greeting = net.establish_connection(uri.host, uri.service) > > -c = net.wrap(s, greeting, uri.host, uri.service, {reconnect_after = 0.01}) > > -c.state > > - > > -a = 100 > > -function kek(args) return {1, 2, 3, args} end > > -c:eval('a = 200') > > -a > > -c:call('kek', {300}) > > -s = box.schema.create_space('test') > > -box.schema.user.grant('guest', 'read,write', 'space', 'test') > > -pk = s:create_index('pk') > > -c:reload_schema() > > -c.space.test:replace{1} > > -c.space.test:get{1} > > -c.space.test:delete{1} > > --- > > --- Break a connection to test reconnect_after. > > --- > > -_ = c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') > > -while not c:is_connected() do fiber.sleep(0.01) end > > -c:ping() > > - > > -s:drop() > > -c:close() > > - > > --- > > --- Test a case, when netbox can not connect first time, but > > --- reconnect_after is set. > > --- > > -c = net.connect('localhost:33333', {reconnect_after = 0.1, wait_connected = false}) > > -while c.state ~= 'error_reconnect' do fiber.sleep(0.01) end > > -c:close() > > - > > -box.schema.user.revoke('guest', 'execute', 'universe') > > -c.state > > -c = nil > > - > > --- > > --- gh-3256 net.box is_nullable and collation options output > > --- > > -space = box.schema.create_space('test') > > -box.schema.user.grant('guest', 'read', 'space', 'test') > > -_ = space:create_index('pk') > > -_ = space:create_index('sk', {parts = {{2, 'unsigned', is_nullable = true}}}) > > -c = net:connect(box.cfg.listen) > > -c.space.test.index.sk.parts > > -space:drop() > > - > > -space = box.schema.create_space('test') > > -c:close() > > -box.schema.user.grant('guest', 'read', 'space', 'test') > > -c = net:connect(box.cfg.listen) > > -box.internal.collation.create('test', 'ICU', 'ru-RU') > > -collation_id = box.internal.collation.id_by_name('test') > > -_ = space:create_index('sk', { type = 'tree', parts = {{1, 'str', collation = 'test'}}, unique = true }) > > -c:reload_schema() > > -parts = c.space.test.index.sk.parts > > -#parts == 1 > > -parts[1].fieldno == 1 > > -parts[1].type == 'string' > > -parts[1].is_nullable == false > > -if _TARANTOOL >= '2.2.1' then \ > > - return parts[1].collation == 'test' \ > > -else \ > > - return parts[1].collation_id == collation_id \ > > -end > > -c:close() > > -box.internal.collation.drop('test') > > -space:drop() > > -c.state > > -c = nil > > - > > --- > > --- gh-3107: fiber-async netbox. > > --- > > -cond = nil > > -box.schema.func.create('long_function') > > -box.schema.user.grant('guest', 'execute', 'function', 'long_function') > > -function long_function(...) cond = fiber.cond() cond:wait() return ... end > > -function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end > > -s = box.schema.create_space('test') > > -pk = s:create_index('pk') > > -s:replace{1} > > -s:replace{2} > > -s:replace{3} > > -s:replace{4} > > -c = net:connect(box.cfg.listen) > > --- > > --- Check long connections, multiple wait_result(). > > --- > > -future = c:call('long_function', {1, 2, 3}, {is_async = true}) > > -future:result() > > -future:is_ready() > > -future:wait_result(0.01) -- Must fail on timeout. > > -finalize_long() > > -ret = future:wait_result(100) > > -future:is_ready() > > --- Any timeout is ok - response is received already. > > -future:wait_result(0) > > -future:wait_result(0.01) > > -ret > > - > > -_, err = pcall(future.wait_result, future, true) > > -err:find('Usage') ~= nil > > -_, err = pcall(future.wait_result, future, '100') > > -err:find('Usage') ~= nil > > - > > --- > > --- Check infinity timeout. > > --- > > -ret = nil > > -_ = fiber.create(function() ret = c:call('long_function', {1, 2, 3}, {is_async = true}):wait_result() end) > > -finalize_long() > > -while not ret do fiber.sleep(0.01) end > > -ret > > -c:close() > > -box.schema.user.grant('guest', 'execute', 'universe') > > -c = net:connect(box.cfg.listen) > > -future = c:eval('return long_function(...)', {1, 2, 3}, {is_async = true}) > > -future:result() > > -future:wait_result(0.01) -- Must fail on timeout. > > -finalize_long() > > -future:wait_result(100) > > - > > -c:close() > > --- > > --- Check that is_async does not work on a closed connection. > > --- > > -c:call('any_func', {}, {is_async = true}) > > - > > -box.schema.user.revoke('guest', 'execute', 'universe') > > -c = net:connect(box.cfg.listen) > > - > > --- > > --- Ensure the request is garbage collected both if is not used and > > --- if is. > > --- > > -gc_test = setmetatable({}, {__mode = 'v'}) > > -gc_test.future = c:call('long_function', {1, 2, 3}, {is_async = true}) > > -gc_test.future ~= nil > > -collectgarbage() > > -gc_test > > -finalize_long() > > - > > -future = c:call('long_function', {1, 2, 3}, {is_async = true}) > > -collectgarbage() > > -future ~= nil > > -finalize_long() > > -future:wait_result(1000) > > -collectgarbage() > > -future ~= nil > > -gc_test.future = future > > -future = nil > > -collectgarbage() > > -gc_test > > - > > --- > > --- Ensure a request can be finalized from non-caller fibers. > > --- > > -future = c:call('long_function', {1, 2, 3}, {is_async = true}) > > -ret = {} > > -count = 0 > > -for i = 1, 10 do fiber.create(function() ret[i] = future:wait_result(1000) count = count + 1 end) end > > -future:wait_result(0.01) -- Must fail on timeout. > > -finalize_long() > > -while count ~= 10 do fiber.sleep(0.1) end > > -ret > > - > > --- > > --- Test space methods. > > --- > > -c:close() > > -box.schema.user.grant('guest', 'read,write', 'space', 'test') > > -c = net:connect(box.cfg.listen) > > -future = c.space.test:select({1}, {is_async = true}) > > -ret = future:wait_result(100) > > -ret > > -type(ret[1]) > > -future = c.space.test:insert({5}, {is_async = true}) > > -future:wait_result(100) > > -s:get{5} > > -future = c.space.test:replace({6}, {is_async = true}) > > -future:wait_result(100) > > -s:get{6} > > -future = c.space.test:delete({6}, {is_async = true}) > > -future:wait_result(100) > > -s:get{6} > > -future = c.space.test:update({5}, {{'=', 2, 5}}, {is_async = true}) > > -future:wait_result(100) > > -s:get{5} > > -future = c.space.test:upsert({5}, {{'=', 2, 6}}, {is_async = true}) > > -future:wait_result(100) > > -s:get{5} > > -future = c.space.test:get({5}, {is_async = true}) > > -future:wait_result(100) > > - > > --- > > --- Test index methods. > > --- > > -future = c.space.test.index.pk:select({1}, {is_async = true}) > > -future:wait_result(100) > > -future = c.space.test.index.pk:get({2}, {is_async = true}) > > -future:wait_result(100) > > -future = c.space.test.index.pk:min({}, {is_async = true}) > > -future:wait_result(100) > > -future = c.space.test.index.pk:max({}, {is_async = true}) > > -future:wait_result(100) > > -c:close() > > -box.schema.user.grant('guest', 'execute', 'universe') > > -c = net:connect(box.cfg.listen) > > -future = c.space.test.index.pk:count({3}, {is_async = true}) > > -future:wait_result(100) > > -c:close() > > -box.schema.user.revoke('guest', 'execute', 'universe') > > -c = net:connect(box.cfg.listen) > > -future = c.space.test.index.pk:delete({3}, {is_async = true}) > > -future:wait_result(100) > > -s:get{3} > > -future = c.space.test.index.pk:update({4}, {{'=', 2, 6}}, {is_async = true}) > > -future:wait_result(100) > > -s:get{4} > > - > > --- > > --- Test async errors. > > --- > > -future = c.space.test:insert({1}, {is_async = true}) > > -future:wait_result() > > -future:result() > > - > > --- > > --- Test discard. > > --- > > -future = c:call('long_function', {1, 2, 3}, {is_async = true}) > > -future:discard() > > -finalize_long() > > -future:result() > > -future:wait_result(100) > > - > > --- > > --- Test closed connection. > > --- > > -future = c:call('long_function', {1, 2, 3}, {is_async = true}) > > -finalize_long() > > -future:wait_result(100) > > -future2 = c:call('long_function', {1, 2, 3}, {is_async = true}) > > -c:close() > > -future2:wait_result(100) > > -future2:result() > > -future2:discard() > > --- Already successful result must be available. > > -future:wait_result(100) > > -future:result() > > -future:is_ready() > > -finalize_long() > > - > > --- > > --- Test reconnect. > > --- > > -c = net:connect(box.cfg.listen, {reconnect_after = 0.01}) > > -future = c:call('long_function', {1, 2, 3}, {is_async = true}) > > -_ = c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') > > -while not c:is_connected() do fiber.sleep(0.01) end > > -finalize_long() > > -future:wait_result(100) > > -future:result() > > -future = c:call('long_function', {1, 2, 3}, {is_async = true}) > > -finalize_long() > > -future:wait_result(100) > > - > > --- > > --- Test raw response getting. > > --- > > -ibuf = require('buffer').ibuf() > > -future = c:call('long_function', {1, 2, 3}, {is_async = true, buffer = ibuf}) > > -finalize_long() > > -future:wait_result(100) > > -result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > -result > > - > > -box.schema.func.drop('long_function') > > - > > --- > > --- Test async schema version change. > > --- > > -function change_schema(i) local tmp = box.schema.create_space('test'..i) return 'ok' end > > -box.schema.func.create('change_schema') > > -box.schema.user.grant('guest', 'execute', 'function', 'change_schema') > > -box.schema.user.grant('guest', 'write', 'space', '_schema') > > -box.schema.user.grant('guest', 'read,write', 'space', '_space') > > -box.schema.user.grant('guest', 'create', 'space') > > -future1 = c:call('change_schema', {'1'}, {is_async = true}) > > -future2 = c:call('change_schema', {'2'}, {is_async = true}) > > -future3 = c:call('change_schema', {'3'}, {is_async = true}) > > -future1:wait_result() > > -future2:wait_result() > > -future3:wait_result() > > - > > -c:close() > > -s:drop() > > -box.space.test1:drop() > > -box.space.test2:drop() > > -box.space.test3:drop() > > -box.schema.func.drop('change_schema') > > - > > --- > > --- gh-2978: field names for tuples received from netbox. > > --- > > -_ = box.schema.create_space("named", {format = {{name = "id"}, {name="abc"}}}) > > -_ = box.space.named:create_index('id', {parts = {{1, 'unsigned'}}}) > > -box.space.named:insert({1, 1}) > > -box.schema.user.grant('guest', 'read, write, execute', 'space') > > -cn = net.connect(box.cfg.listen) > > - > > -s = cn.space.named > > -s:get{1}.id > > -s:get{1}:tomap() > > -s:insert{2,3}:tomap() > > -s:replace{2,14}:tomap() > > -s:update(1, {{'+', 2, 10}}):tomap() > > -s:select()[1]:tomap() > > -s:delete({2}):tomap() > > - > > --- Check that formats changes after reload. > > -box.space.named:format({{name = "id2"}, {name="abc2"}}) > > -s:select()[1]:tomap() > > -cn:reload_schema() > > -s:select()[1]:tomap() > > - > > -cn:close() > > -box.space.named:drop() > > -box.schema.user.revoke('guest', 'read, write, execute', 'space') > > - > > --- > > --- gh-3400: long-poll input discard must not touch event loop of > > --- a closed connection. > > --- > > -function long() fiber.yield() return 100 end > > -c = net.connect(box.cfg.listen) > > -c:ping() > > --- Create batch of two requests. First request is sent to TX > > --- thread, second one terminates connection. The preceeding > > --- request discards input, and this operation must not trigger > > --- new attempts to read any data - the connection is closed > > --- already. > > --- > > -f = fiber.create(c._transport.perform_request, nil, nil, false, 'call_17', nil, nil, nil, 'long', {}) c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') > > -while f:status() ~= 'dead' do fiber.sleep(0.01) end > > -c:close() > > - > > --- > > --- gh-3464: iproto hangs in 100% CPU when too big packet size > > --- is received due to size_t overflow. > > --- > > -c = net:connect(box.cfg.listen) > > -data = msgpack.encode(18400000000000000000)..'aaaaaaa' > > -c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, data) > > -c:close() > > -test_run:grep_log('default', 'too big packet size in the header') ~= nil > > - > > - > > --- > > --- gh-3629: netbox leaks when a connection is closed deliberately > > --- and it has non-finished requests. > > --- > > -ready = false > > -ok = nil > > -err = nil > > -c = net:connect(box.cfg.listen) > > -function do_long() while not ready do fiber.sleep(0.01) end end > > -box.schema.func.create('do_long') > > -box.schema.user.grant('guest', 'execute', 'function', 'do_long') > > -f = fiber.create(function() ok, err = pcall(c.call, c, 'do_long') end) > > -while f:status() ~= 'suspended' do fiber.sleep(0.01) end > > -c:close() > > -ready = true > > -while not err do fiber.sleep(0.01) end > > -ok, err > > - > > --- > > --- gh-3856: wait_connected = false is ignored. > > --- > > -c = net.connect('8.8.8.8:123456', {wait_connected = false}) > > -c > > -c:close() > > - > > -box.schema.func.drop('do_long') > > -box.schema.user.revoke('guest', 'write', 'space', '_schema') > > -box.schema.user.revoke('guest', 'read,write', 'space', '_space') > > -box.schema.user.revoke('guest', 'create', 'space') > > - > > --- > > --- gh-3958 updating box.cfg.readahead doesn't affect existing connections. > > --- > > -readahead = box.cfg.readahead > > - > > -box.cfg{readahead = 128} > > - > > -s = box.schema.space.create("test") > > -_ = s:create_index("pk") > > -box.schema.user.grant("guest", "read,write", "space", "test") > > - > > --- connection is created with small readahead value, > > --- make sure it is updated if box.cfg.readahead is changed. > > -c = net.connect(box.cfg.listen) > > - > > -box.cfg{readahead = 100 * 1024} > > - > > -box.error.injection.set("ERRINJ_WAL_DELAY", true) > > -pad = string.rep('x', 8192) > > -for i = 1, 5 do c.space.test:replace({i, pad}, {is_async = true}) end > > -box.error.injection.set("ERRINJ_WAL_DELAY", false) > > - > > -test_run:wait_log('default', 'readahead limit is reached', 1024, 0.1) > > - > > -s:drop() > > -box.cfg{readahead = readahead} > > - > > --- > > --- related to gh-4040: log corrupted rows > > --- > > -log_level = box.cfg.log_level > > -box.cfg{log_level=6} > > -sock = socket.tcp_connect(LISTEN.host, LISTEN.service) > > -sock:read(9) > > --- we need to have a packet with correctly encoded length, > > --- so that it bypasses iproto length check, but cannot be > > --- decoded in xrow_header_decode > > --- 0x3C = 60, sha1 digest is 20 bytes long > > -data = string.fromhex('3C'..string.rep(require('digest').sha1_hex('bcde'), 3)) > > -sock:write(data) > > -sock:close() > > - > > -test_run:wait_log('default', 'Got a corrupted row.*', nil, 10) > > -test_run:wait_log('default', '00000000:.*', nil, 10) > > -test_run:wait_log('default', '00000010:.*', nil, 10) > > -test_run:wait_log('default', '00000020:.*', nil, 10) > > -test_run:wait_log('default', '00000030:.*', nil, 10) > > --- we expect nothing below, so don't wait > > -test_run:grep_log('default', '00000040:.*') > > - > > -box.cfg{log_level=log_level} > > diff --git a/test/box/net.box_bad_argument_gh-594.result b/test/box/net.box_bad_argument_gh-594.result > > new file mode 100644 > > index 000000000..339886eaa > > --- /dev/null > > +++ b/test/box/net.box_bad_argument_gh-594.result > > @@ -0,0 +1,38 @@ > > +remote = require 'net.box' > > +--- > > +... > > +fiber = require 'fiber' > > +--- > > +... > > +test_run = require('test_run').new() > > +--- > > +... > > +-- #594: bad argument #1 to 'setmetatable' (table expected, got number) > > +box.schema.func.create('dostring') > > +--- > > +... > > +box.schema.user.grant('guest', 'execute', 'function', 'dostring') > > +--- > > +... > > +test_run:cmd("setopt delimiter ';'") > > +--- > > +- true > > +... > > +function gh594() > > + local cn = remote.connect(box.cfg.listen) > > + local ping = fiber.create(function() cn:ping() end) > > + cn:call('dostring', {'return 2 + 2'}) > > + cn:close() > > +end; > > +--- > > +... > > +test_run:cmd("setopt delimiter ''"); > > +--- > > +- true > > +... > > +gh594() > > +--- > > +... > > +box.schema.func.drop('dostring') > > +--- > > +... > > diff --git a/test/box/net.box_bad_argument_gh-594.test.lua b/test/box/net.box_bad_argument_gh-594.test.lua > > new file mode 100644 > > index 000000000..65265cbb5 > > --- /dev/null > > +++ b/test/box/net.box_bad_argument_gh-594.test.lua > > @@ -0,0 +1,17 @@ > > +remote = require 'net.box' > > +fiber = require 'fiber' > > +test_run = require('test_run').new() > > + > > +-- #594: bad argument #1 to 'setmetatable' (table expected, got number) > > +box.schema.func.create('dostring') > > +box.schema.user.grant('guest', 'execute', 'function', 'dostring') > > +test_run:cmd("setopt delimiter ';'") > > +function gh594() > > + local cn = remote.connect(box.cfg.listen) > > + local ping = fiber.create(function() cn:ping() end) > > + cn:call('dostring', {'return 2 + 2'}) > > + cn:close() > > +end; > > +test_run:cmd("setopt delimiter ''"); > > +gh594() > > +box.schema.func.drop('dostring') > > diff --git a/test/box/net.box_call_blocks_gh-946.result b/test/box/net.box_call_blocks_gh-946.result > > new file mode 100644 > > index 000000000..40afec416 > > --- /dev/null > > +++ b/test/box/net.box_call_blocks_gh-946.result > > @@ -0,0 +1,124 @@ > > +fiber = require 'fiber' > > +--- > > +... > > +test_run = require('test_run').new() > > +--- > > +... > > +--space = box.schema.space.create('net_box_test_space') > > +--index = space:create_index('primary', { type = 'tree' }) > > +net = require('net.box') > > +--- > > +... > > +socket = require('socket'); > > +--- > > +... > > +test_run:cmd('create server connecter with script = "box/proxy.lua"') > > +--- > > +- true > > +... > > +-- > > +-- gh-946: long polling CALL blocks input > > +-- > > +box.schema.func.create('fast_call') > > +--- > > +... > > +box.schema.func.create('long_call') > > +--- > > +... > > +box.schema.func.create('wait_signal') > > +--- > > +... > > +box.schema.user.grant('guest', 'execute', 'function', 'fast_call') > > +--- > > +... > > +box.schema.user.grant('guest', 'execute', 'function', 'long_call') > > +--- > > +... > > +box.schema.user.grant('guest', 'execute', 'function', 'wait_signal') > > +--- > > +... > > +c = net.connect(box.cfg.listen) > > +--- > > +... > > +N = 100 > > +--- > > +... > > +pad = string.rep('x', 1024) > > +--- > > +... > > +long_call_cond = fiber.cond() > > +--- > > +... > > +long_call_channel = fiber.channel() > > +--- > > +... > > +fast_call_channel = fiber.channel() > > +--- > > +... > > +function fast_call(x) return x end > > +--- > > +... > > +function long_call(x) long_call_cond:wait() return x * 2 end > > +--- > > +... > > +test_run:cmd("setopt delimiter ';'") > > +--- > > +- true > > +... > > +for i = 1, N do > > + fiber.create(function() > > + fast_call_channel:put(c:call('fast_call', {i, pad})) > > + end) > > + fiber.create(function() > > + long_call_channel:put(c:call('long_call', {i, pad})) > > + end) > > +end > > +test_run:cmd("setopt delimiter ''"); > > +--- > > +... > > +x = 0 > > +--- > > +... > > +for i = 1, N do x = x + fast_call_channel:get() end > > +--- > > +... > > +x > > +--- > > +- 5050 > > +... > > +long_call_cond:broadcast() > > +--- > > +... > > +x = 0 > > +--- > > +... > > +for i = 1, N do x = x + long_call_channel:get() end > > +--- > > +... > > +x > > +--- > > +- 10100 > > +... > > +-- > > +-- Check that a connection does not leak if there is > > +-- a long CALL in progress when it is closed. > > +-- > > +disconnected = false > > +--- > > +... > > +function on_disconnect() disconnected = true end > > +--- > > +... > > +-- Make sure all dangling connections are collected so > > +-- that on_disconnect trigger isn't called spuriously. > > +collectgarbage('collect') > > +--- > > +- 0 > > +... > > +fiber.sleep(0) > > +--- > > +... > > +box.session.on_disconnect(on_disconnect) == on_disconnect > > +--- > > +- true > > +... > > diff --git a/test/box/net.box_call_blocks_gh-946.test.lua b/test/box/net.box_call_blocks_gh-946.test.lua > > new file mode 100644 > > index 000000000..f3cd3f305 > > --- /dev/null > > +++ b/test/box/net.box_call_blocks_gh-946.test.lua > > @@ -0,0 +1,67 @@ > > +fiber = require 'fiber' > > +test_run = require('test_run').new() > > + > > +--space = box.schema.space.create('net_box_test_space') > > +--index = space:create_index('primary', { type = 'tree' }) > > + > > +net = require('net.box') > > +socket = require('socket'); > > + > > +test_run:cmd('create server connecter with script = "box/proxy.lua"') > > + > > +-- > > +-- gh-946: long polling CALL blocks input > > +-- > > +box.schema.func.create('fast_call') > > +box.schema.func.create('long_call') > > +box.schema.func.create('wait_signal') > > +box.schema.user.grant('guest', 'execute', 'function', 'fast_call') > > +box.schema.user.grant('guest', 'execute', 'function', 'long_call') > > +box.schema.user.grant('guest', 'execute', 'function', 'wait_signal') > > +c = net.connect(box.cfg.listen) > > + > > +N = 100 > > + > > +pad = string.rep('x', 1024) > > + > > +long_call_cond = fiber.cond() > > +long_call_channel = fiber.channel() > > +fast_call_channel = fiber.channel() > > + > > +function fast_call(x) return x end > > +function long_call(x) long_call_cond:wait() return x * 2 end > > + > > +test_run:cmd("setopt delimiter ';'") > > +for i = 1, N do > > + fiber.create(function() > > + fast_call_channel:put(c:call('fast_call', {i, pad})) > > + end) > > + fiber.create(function() > > + long_call_channel:put(c:call('long_call', {i, pad})) > > + end) > > +end > > +test_run:cmd("setopt delimiter ''"); > > + > > +x = 0 > > +for i = 1, N do x = x + fast_call_channel:get() end > > +x > > + > > +long_call_cond:broadcast() > > + > > +x = 0 > > +for i = 1, N do x = x + long_call_channel:get() end > > +x > > + > > +-- > > +-- Check that a connection does not leak if there is > > +-- a long CALL in progress when it is closed. > > +-- > > +disconnected = false > > +function on_disconnect() disconnected = true end > > + > > +-- Make sure all dangling connections are collected so > > +-- that on_disconnect trigger isn't called spuriously. > > +collectgarbage('collect') > > +fiber.sleep(0) > > + > > +box.session.on_disconnect(on_disconnect) == on_disconnect > > diff --git a/test/box/net.box_collectgarbage_gh-3107.result b/test/box/net.box_collectgarbage_gh-3107.result > > new file mode 100644 > > index 000000000..240a472de > > --- /dev/null > > +++ b/test/box/net.box_collectgarbage_gh-3107.result > > @@ -0,0 +1,120 @@ > > +fiber = require 'fiber' > > +--- > > +... > > +net = require('net.box') > > +--- > > +... > > +-- > > +-- gh-3107: fiber-async netbox. > > +-- > > +cond = nil > > +--- > > +... > > +box.schema.func.create('long_function') > > +--- > > +... > > +box.schema.user.grant('guest', 'execute', 'function', 'long_function') > > +--- > > +... > > +function long_function(...) cond = fiber.cond() cond:wait() return ... end > > +--- > > +... > > +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end > > +--- > > +... > > +s = box.schema.create_space('test') > > +--- > > +... > > +pk = s:create_index('pk') > > +--- > > +... > > +s:replace{1} > > +--- > > +- [1] > > +... > > +s:replace{2} > > +--- > > +- [2] > > +... > > +s:replace{3} > > +--- > > +- [3] > > +... > > +s:replace{4} > > +--- > > +- [4] > > +... > > +c = net:connect(box.cfg.listen) > > +--- > > +... > > +-- > > +-- Ensure the request is garbage collected both if is not used and > > +-- if is. > > +-- > > +gc_test = setmetatable({}, {__mode = 'v'}) > > +--- > > +... > > +gc_test.future = c:call('long_function', {1, 2, 3}, {is_async = true}) > > +--- > > +... > > +gc_test.future ~= nil > > +--- > > +- true > > +... > > +collectgarbage() > > +--- > > +- 0 > > +... > > +gc_test > > +--- > > +- [] > > +... > > +finalize_long() > > +--- > > +... > > +future = c:call('long_function', {1, 2, 3}, {is_async = true}) > > +--- > > +... > > +collectgarbage() > > +--- > > +- 0 > > +... > > +future ~= nil > > +--- > > +- true > > +... > > +finalize_long() > > +--- > > +... > > +future:wait_result(1000) > > +--- > > +- [1, 2, 3] > > +... > > +collectgarbage() > > +--- > > +- 0 > > +... > > +future ~= nil > > +--- > > +- true > > +... > > +gc_test.future = future > > +--- > > +... > > +future = nil > > +--- > > +... > > +collectgarbage() > > +--- > > +- 0 > > +... > > +gc_test > > +--- > > +- [] > > +... > > +c:close() > > +--- > > +... > > +s:drop() > > +--- > > +... > > diff --git a/test/box/net.box_collectgarbage_gh-3107.test.lua b/test/box/net.box_collectgarbage_gh-3107.test.lua > > new file mode 100644 > > index 000000000..cfe333757 > > --- /dev/null > > +++ b/test/box/net.box_collectgarbage_gh-3107.test.lua > > @@ -0,0 +1,44 @@ > > +fiber = require 'fiber' > > +net = require('net.box') > > + > > +-- > > +-- gh-3107: fiber-async netbox. > > +-- > > +cond = nil > > +box.schema.func.create('long_function') > > +box.schema.user.grant('guest', 'execute', 'function', 'long_function') > > +function long_function(...) cond = fiber.cond() cond:wait() return ... end > > +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end > > +s = box.schema.create_space('test') > > +pk = s:create_index('pk') > > +s:replace{1} > > +s:replace{2} > > +s:replace{3} > > +s:replace{4} > > +c = net:connect(box.cfg.listen) > > + > > +-- > > +-- Ensure the request is garbage collected both if is not used and > > +-- if is. > > +-- > > +gc_test = setmetatable({}, {__mode = 'v'}) > > +gc_test.future = c:call('long_function', {1, 2, 3}, {is_async = true}) > > +gc_test.future ~= nil > > +collectgarbage() > > +gc_test > > +finalize_long() > > + > > +future = c:call('long_function', {1, 2, 3}, {is_async = true}) > > +collectgarbage() > > +future ~= nil > > +finalize_long() > > +future:wait_result(1000) > > +collectgarbage() > > +future ~= nil > > +gc_test.future = future > > +future = nil > > +collectgarbage() > > +gc_test > > + > > +c:close() > > +s:drop() > > diff --git a/test/box/net.box_connect_triggers.result b/test/box/net.box_connect_triggers.result > > new file mode 100644 > > index 000000000..c5b1ef6db > > --- /dev/null > > +++ b/test/box/net.box_connect_triggers.result > > @@ -0,0 +1,82 @@ > > +fiber = require 'fiber' > > +--- > > +... > > +test_run = require('test_run').new() > > +--- > > +... > > +net = require('net.box') > > +--- > > +... > > +-- > > +-- On_connect/disconnect triggers. > > +-- > > +test_run:cmd('create server connecter with script = "box/proxy.lua"') > > +--- > > +- true > > +... > > +test_run:cmd('start server connecter') > > +--- > > +- true > > +... > > +test_run:cmd("set variable connect_to to 'connecter.listen'") > > +--- > > +- true > > +... > > +conn = net.connect(connect_to, { reconnect_after = 0.1 }) > > +--- > > +... > > +conn.state > > +--- > > +- active > > +... > > +connected_cnt = 0 > > +--- > > +... > > +disconnected_cnt = 0 > > +--- > > +... > > +function on_connect() connected_cnt = connected_cnt + 1 end > > +--- > > +... > > +function on_disconnect() disconnected_cnt = disconnected_cnt + 1 end > > +--- > > +... > > +conn:on_connect(on_connect) > > +--- > > +... > > +conn:on_disconnect(on_disconnect) > > +--- > > +... > > +test_run:cmd('stop server connecter') > > +--- > > +- true > > +... > > +test_run:cmd('start server connecter') > > +--- > > +- true > > +... > > +while conn.state ~= 'active' do fiber.sleep(0.1) end > > +--- > > +... > > +connected_cnt > > +--- > > +- 1 > > +... > > +old_disconnected_cnt = disconnected_cnt > > +--- > > +... > > +disconnected_cnt >= 1 > > +--- > > +- true > > +... > > +conn:close() > > +--- > > +... > > +disconnected_cnt == old_disconnected_cnt + 1 > > +--- > > +- true > > +... > > +test_run:cmd('stop server connecter') > > +--- > > +- true > > +... > > diff --git a/test/box/net.box_connect_triggers.test.lua b/test/box/net.box_connect_triggers.test.lua > > new file mode 100644 > > index 000000000..86794035e > > --- /dev/null > > +++ b/test/box/net.box_connect_triggers.test.lua > > @@ -0,0 +1,27 @@ > > +fiber = require 'fiber' > > +test_run = require('test_run').new() > > +net = require('net.box') > > + > > +-- > > +-- On_connect/disconnect triggers. > > +-- > > +test_run:cmd('create server connecter with script = "box/proxy.lua"') > > +test_run:cmd('start server connecter') > > +test_run:cmd("set variable connect_to to 'connecter.listen'") > > +conn = net.connect(connect_to, { reconnect_after = 0.1 }) > > +conn.state > > +connected_cnt = 0 > > +disconnected_cnt = 0 > > +function on_connect() connected_cnt = connected_cnt + 1 end > > +function on_disconnect() disconnected_cnt = disconnected_cnt + 1 end > > +conn:on_connect(on_connect) > > +conn:on_disconnect(on_disconnect) > > +test_run:cmd('stop server connecter') > > +test_run:cmd('start server connecter') > > +while conn.state ~= 'active' do fiber.sleep(0.1) end > > +connected_cnt > > +old_disconnected_cnt = disconnected_cnt > > +disconnected_cnt >= 1 > > +conn:close() > > +disconnected_cnt == old_disconnected_cnt + 1 > > +test_run:cmd('stop server connecter') > > diff --git a/test/box/net.box_console_connections_gh-2677.result b/test/box/net.box_console_connections_gh-2677.result > > new file mode 100644 > > index 000000000..c9116e5d4 > > --- /dev/null > > +++ b/test/box/net.box_console_connections_gh-2677.result > > @@ -0,0 +1,95 @@ > > +fiber = require 'fiber' > > +--- > > +... > > +net = require('net.box') > > +--- > > +... > > +-- > > +-- gh-2677: netbox supports console connections, that complicates > > +-- both console and netbox. It was necessary because before a > > +-- connection is established, a console does not known is it > > +-- binary or text protocol, and netbox could not be created from > > +-- existing socket. > > +-- > > +box.schema.user.grant('guest', 'execute', 'universe') > > +--- > > +... > > +urilib = require('uri') > > +--- > > +... > > +uri = urilib.parse(tostring(box.cfg.listen)) > > +--- > > +... > > +s, greeting = net.establish_connection(uri.host, uri.service) > > +--- > > +... > > +c = net.wrap(s, greeting, uri.host, uri.service, {reconnect_after = 0.01}) > > +--- > > +... > > +c.state > > +--- > > +- active > > +... > > +a = 100 > > +--- > > +... > > +function kek(args) return {1, 2, 3, args} end > > +--- > > +... > > +c:eval('a = 200') > > +--- > > +... > > +a > > +--- > > +- 200 > > +... > > +c:call('kek', {300}) > > +--- > > +- [1, 2, 3, 300] > > +... > > +s = box.schema.create_space('test') > > +--- > > +... > > +box.schema.user.grant('guest', 'read,write', 'space', 'test') > > +--- > > +... > > +pk = s:create_index('pk') > > +--- > > +... > > +c:reload_schema() > > +--- > > +... > > +c.space.test:replace{1} > > +--- > > +- [1] > > +... > > +c.space.test:get{1} > > +--- > > +- [1] > > +... > > +c.space.test:delete{1} > > +--- > > +- [1] > > +... > > +-- > > +-- Break a connection to test reconnect_after. > > +-- > > +_ = c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') > > +--- > > +... > > +while not c:is_connected() do fiber.sleep(0.01) end > > +--- > > +... > > +c:ping() > > +--- > > +- true > > +... > > +s:drop() > > +--- > > +... > > +c:close() > > +--- > > +... > > +box.schema.user.revoke('guest', 'execute', 'universe') > > +--- > > +... > > diff --git a/test/box/net.box_console_connections_gh-2677.test.lua b/test/box/net.box_console_connections_gh-2677.test.lua > > new file mode 100644 > > index 000000000..c6c9ea846 > > --- /dev/null > > +++ b/test/box/net.box_console_connections_gh-2677.test.lua > > @@ -0,0 +1,39 @@ > > +fiber = require 'fiber' > > +net = require('net.box') > > + > > +-- > > +-- gh-2677: netbox supports console connections, that complicates > > +-- both console and netbox. It was necessary because before a > > +-- connection is established, a console does not known is it > > +-- binary or text protocol, and netbox could not be created from > > +-- existing socket. > > +-- > > +box.schema.user.grant('guest', 'execute', 'universe') > > +urilib = require('uri') > > +uri = urilib.parse(tostring(box.cfg.listen)) > > +s, greeting = net.establish_connection(uri.host, uri.service) > > +c = net.wrap(s, greeting, uri.host, uri.service, {reconnect_after = 0.01}) > > +c.state > > + > > +a = 100 > > +function kek(args) return {1, 2, 3, args} end > > +c:eval('a = 200') > > +a > > +c:call('kek', {300}) > > +s = box.schema.create_space('test') > > +box.schema.user.grant('guest', 'read,write', 'space', 'test') > > +pk = s:create_index('pk') > > +c:reload_schema() > > +c.space.test:replace{1} > > +c.space.test:get{1} > > +c.space.test:delete{1} > > +-- > > +-- Break a connection to test reconnect_after. > > +-- > > +_ = c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') > > +while not c:is_connected() do fiber.sleep(0.01) end > > +c:ping() > > + > > +s:drop() > > +c:close() > > +box.schema.user.revoke('guest', 'execute', 'universe') > > diff --git a/test/box/net.box_count_inconsistent_gh-3262.result b/test/box/net.box_count_inconsistent_gh-3262.result > > new file mode 100644 > > index 000000000..c77677625 > > --- /dev/null > > +++ b/test/box/net.box_count_inconsistent_gh-3262.result > > @@ -0,0 +1,488 @@ > > +remote = require 'net.box' > > +--- > > +... > > +fiber = require 'fiber' > > +--- > > +... > > +test_run = require('test_run').new() > > +--- > > +... > > +LISTEN = require('uri').parse(box.cfg.listen) > > +--- > > +... > > +space = box.schema.space.create('net_box_test_space') > > +--- > > +... > > +index = space:create_index('primary', { type = 'tree' }) > > +--- > > +... > > +box.schema.user.grant('guest', 'read,write', 'space', 'net_box_test_space') > > +--- > > +... > > +box.schema.user.grant('guest', 'execute', 'universe') > > +--- > > +... > > +cn = remote.connect(box.cfg.listen) > > +--- > > +... > > +cn.space[space.id] ~= nil > > +--- > > +- true > > +... > > +cn.space.net_box_test_space ~= nil > > +--- > > +- true > > +... > > +cn.space.net_box_test_space ~= nil > > +--- > > +- true > > +... > > +cn.space.net_box_test_space.index ~= nil > > +--- > > +- true > > +... > > +cn.space.net_box_test_space.index.primary ~= nil > > +--- > > +- true > > +... > > +cn.space.net_box_test_space.index[space.index.primary.id] ~= nil > > +--- > > +- true > > +... > > +cn.space.net_box_test_space:insert{234, 1,2,3} > > +--- > > +- [234, 1, 2, 3] > > +... > > +cn.space.net_box_test_space:replace{354, 1,2,4} > > +--- > > +- [354, 1, 2, 4] > > +... > > +cn.space.net_box_test_space.index.primary:min(354) > > +--- > > +- [354, 1, 2, 4] > > +... > > +cn.space.net_box_test_space.index.primary:max(234) > > +--- > > +- [234, 1, 2, 3] > > +... > > +cn.space.net_box_test_space.index.primary:count(354) > > +--- > > +- 1 > > +... > > +box.schema.user.create('netbox', { password = 'test' }) > > +--- > > +... > > +box.schema.user.grant('netbox', 'read,write', 'space', 'net_box_test_space') > > +--- > > +... > > +box.schema.user.grant('netbox', 'execute', 'universe') > > +--- > > +... > > +cn = remote.connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = 'test' }) > > +--- > > +... > > +cn.state > > +--- > > +- active > > +... > > +cn.error > > +--- > > +- null > > +... > > +cn:ping() > > +--- > > +- true > > +... > > +function ret_after(to) fiber.sleep(to) return {{to}} end > > +--- > > +... > > +cn:ping({timeout = 1.00}) > > +--- > > +- true > > +... > > +cn:ping({timeout = 1e-9}) > > +--- > > +- false > > +... > > +cn:ping() > > +--- > > +- true > > +... > > +remote_space = cn.space.net_box_test_space > > +--- > > +... > > +remote_pk = remote_space.index.primary > > +--- > > +... > > +remote_space:insert({0}, { timeout = 1.00 }) > > +--- > > +- [0] > > +... > > +remote_space:insert({1}, { timeout = 1e-9 }) > > +--- > > +- error: Timeout exceeded > > +... > > +remote_space:insert({2}) > > +--- > > +- [2] > > +... > > +remote_space:replace({0}, { timeout = 1e-9 }) > > +--- > > +- error: Timeout exceeded > > +... > > +remote_space:replace({1}) > > +--- > > +- [1] > > +... > > +remote_space:replace({2}, { timeout = 1.00 }) > > +--- > > +- [2] > > +... > > +remote_space:upsert({3}, {}, { timeout = 1e-9 }) > > +--- > > +- error: Timeout exceeded > > +... > > +remote_space:upsert({4}, {}) > > +--- > > +... > > +remote_space:upsert({5}, {}, { timeout = 1.00 }) > > +--- > > +... > > +remote_space:upsert({3}, {}) > > +--- > > +... > > +remote_space:update({3}, {}, { timeout = 1e-9 }) > > +--- > > +- error: Timeout exceeded > > +... > > +remote_space:update({4}, {}) > > +--- > > +- [4] > > +... > > +remote_space:update({5}, {}, { timeout = 1.00 }) > > +--- > > +- [5] > > +... > > +remote_space:update({3}, {}) > > +--- > > +- [3] > > +... > > +remote_pk:update({5}, {}, { timeout = 1e-9 }) > > +--- > > +- error: Timeout exceeded > > +... > > +remote_pk:update({4}, {}) > > +--- > > +- [4] > > +... > > +remote_pk:update({3}, {}, { timeout = 1.00 }) > > +--- > > +- [3] > > +... > > +remote_pk:update({5}, {}) > > +--- > > +- [5] > > +... > > +remote_space:get({0}) > > +--- > > +- [0] > > +... > > +remote_space:get({1}, { timeout = 1.00 }) > > +--- > > +- [1] > > +... > > +remote_space:get({2}, { timeout = 1e-9 }) > > +--- > > +- error: Timeout exceeded > > +... > > +remote_pk:get({3}, { timeout = 1e-9 }) > > +--- > > +- error: Timeout exceeded > > +... > > +remote_pk:get({4}) > > +--- > > +- [4] > > +... > > +remote_pk:get({5}, { timeout = 1.00 }) > > +--- > > +- [5] > > +... > > +remote_space:select({2}, { timeout = 1e-9 }) > > +--- > > +- error: Timeout exceeded > > +... > > +remote_space:select({2}, { timeout = 1.00 }) > > +--- > > +- - [2] > > +... > > +remote_space:select({2}) > > +--- > > +- - [2] > > +... > > +remote_pk:select({2}, { timeout = 1.00 }) > > +--- > > +- - [2] > > +... > > +remote_pk:select({2}, { timeout = 1e-9 }) > > +--- > > +- error: Timeout exceeded > > +... > > +remote_pk:select({2}) > > +--- > > +- - [2] > > +... > > +remote_space:select({5}, { timeout = 1.00, iterator = 'LE', limit = 5 }) > > +--- > > +- - [5] > > + - [4] > > + - [3] > > + - [2] > > + - [1] > > +... > > +remote_space:select({5}, { iterator = 'LE', limit = 5}) > > +--- > > +- - [5] > > + - [4] > > + - [3] > > + - [2] > > + - [1] > > +... > > +remote_space:select({5}, { timeout = 1e-9, iterator = 'LE', limit = 5 }) > > +--- > > +- error: Timeout exceeded > > +... > > +remote_pk:select({2}, { timeout = 1.00, iterator = 'LE', limit = 5 }) > > +--- > > +- - [2] > > + - [1] > > + - [0] > > +... > > +remote_pk:select({2}, { iterator = 'LE', limit = 5}) > > +--- > > +- - [2] > > + - [1] > > + - [0] > > +... > > +remote_pk:select({2}, { timeout = 1e-9, iterator = 'LE', limit = 5 }) > > +--- > > +- error: Timeout exceeded > > +... > > +remote_pk:count({2}, { timeout = 1.00}) > > +--- > > +- 1 > > +... > > +remote_pk:count({2}, { timeout = 1e-9}) > > +--- > > +- error: Timeout exceeded > > +... > > +remote_pk:count({2}) > > +--- > > +- 1 > > +... > > +remote_pk:count({2}, { timeout = 1.00, iterator = 'LE' }) > > +--- > > +- 3 > > +... > > +remote_pk:count({2}, { iterator = 'LE'}) > > +--- > > +- 3 > > +... > > +remote_pk:count({2}, { timeout = 1e-9, iterator = 'LE' }) > > +--- > > +- error: Timeout exceeded > > +... > > +remote_pk:min(nil, { timeout = 1.00 }) > > +--- > > +- [0] > > +... > > +remote_pk:min(nil, { timeout = 1e-9 }) > > +--- > > +- error: Timeout exceeded > > +... > > +remote_pk:min(nil) > > +--- > > +- [0] > > +... > > +remote_pk:min({0}, { timeout = 1e-9 }) > > +--- > > +- error: Timeout exceeded > > +... > > +remote_pk:min({1}) > > +--- > > +- [1] > > +... > > +remote_pk:min({2}, { timeout = 1.00 }) > > +--- > > +- [2] > > +... > > +remote_pk:max(nil) > > +--- > > +- [354, 1, 2, 4] > > +... > > +remote_pk:max(nil, { timeout = 1e-9 }) > > +--- > > +- error: Timeout exceeded > > +... > > +remote_pk:max(nil, { timeout = 1.00 }) > > +--- > > +- [354, 1, 2, 4] > > +... > > +remote_pk:max({0}, { timeout = 1.00 }) > > +--- > > +- [0] > > +... > > +remote_pk:max({1}, { timeout = 1e-9 }) > > +--- > > +- error: Timeout exceeded > > +... > > +remote_pk:max({2}) > > +--- > > +- [2] > > +... > > +-- > > +-- gh-3262: index:count() inconsistent results > > +-- > > +test_run:cmd("setopt delimiter ';'") > > +--- > > +- true > > +... > > +function do_count_test(min, it) > > + local r1 = remote_pk:count(min, {iterator = it} ) > > + local r2 = box.space.net_box_test_space.index.primary:count(min, {iterator = it} ) > > + local r3 = remote.self.space.net_box_test_space.index.primary:count(min, {iterator = it} ) > > + return r1 == r2 and r2 == r3 > > +end; > > +--- > > +... > > +data = remote_pk:select(); > > +--- > > +... > > +for _, v in pairs(data) do > > + local itrs = {'GE', 'GT', 'LE', 'LT' } > > + for _, it in pairs(itrs) do > > + assert(do_count_test(v[0], it) == true) > > + end > > +end; > > +--- > > +... > > +test_run:cmd("setopt delimiter ''"); > > +--- > > +- true > > +... > > +_ = remote_space:delete({0}, { timeout = 1e-9 }) > > +--- > > +- error: Timeout exceeded > > +... > > +_ = remote_pk:delete({0}, { timeout = 1.00 }) > > +--- > > +... > > +_ = remote_space:delete({1}, { timeout = 1.00 }) > > +--- > > +... > > +_ = remote_pk:delete({1}, { timeout = 1e-9 }) > > +--- > > +- error: Timeout exceeded > > +... > > +_ = remote_space:delete({2}, { timeout = 1e-9 }) > > +--- > > +- error: Timeout exceeded > > +... > > +_ = remote_pk:delete({2}) > > +--- > > +... > > +_ = remote_pk:delete({3}) > > +--- > > +... > > +_ = remote_pk:delete({4}) > > +--- > > +... > > +_ = remote_pk:delete({5}) > > +--- > > +... > > +remote_space:get(0) > > +--- > > +... > > +remote_space:get(1) > > +--- > > +... > > +remote_space:get(2) > > +--- > > +... > > +remote_space = nil > > +--- > > +... > > +cn:call('ret_after', {0.01}, { timeout = 1.00 }) > > +--- > > +- [[0.01]] > > +... > > +cn:call('ret_after', {1.00}, { timeout = 1e-9 }) > > +--- > > +- error: Timeout exceeded > > +... > > +cn:eval('return ret_after(...)', {0.01}, { timeout = 1.00 }) > > +--- > > +- [[0.01]] > > +... > > +cn:eval('return ret_after(...)', {1.00}, { timeout = 1e-9 }) > > +--- > > +- error: Timeout exceeded > > +... > > +-- > > +-- :timeout() > > +-- @deprecated since 1.7.4 > > +-- > > +cn:timeout(1).space.net_box_test_space.index.primary:select{234} > > +--- > > +- - [234, 1, 2, 3] > > +... > > +cn:call('ret_after', {.01}) > > +--- > > +- [[0.01]] > > +... > > +cn:timeout(1):call('ret_after', {.01}) > > +--- > > +- [[0.01]] > > +... > > +cn:timeout(.01):call('ret_after', {1}) > > +--- > > +- error: Timeout exceeded > > +... > > +cn = remote:timeout(0.0000000001):connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123' }) > > +--- > > +... > > +cn:close() > > +--- > > +... > > +cn = remote:timeout(1):connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123' }) > > +--- > > +... > > +remote.self:ping() > > +--- > > +- true > > +... > > +remote.self.space.net_box_test_space:select{234} > > +--- > > +- - [234, 1, 2, 3] > > +... > > +remote.self:timeout(123).space.net_box_test_space:select{234} > > +--- > > +- - [234, 1, 2, 3] > > +... > > +remote.self:is_connected() > > +--- > > +- true > > +... > > +remote.self:wait_connected() > > +--- > > +- true > > +... > > +cn:close() > > +--- > > +... > > +-- cleanup database after tests > > +space:drop() > > +--- > > +... > > +box.schema.user.revoke('guest', 'execute', 'universe') > > +--- > > +... > > diff --git a/test/box/net.box_count_inconsistent_gh-3262.test.lua b/test/box/net.box_count_inconsistent_gh-3262.test.lua > > new file mode 100644 > > index 000000000..e84e85cf3 > > --- /dev/null > > +++ b/test/box/net.box_count_inconsistent_gh-3262.test.lua > > @@ -0,0 +1,182 @@ > > +remote = require 'net.box' > > +fiber = require 'fiber' > > +test_run = require('test_run').new() > > + > > +LISTEN = require('uri').parse(box.cfg.listen) > > +space = box.schema.space.create('net_box_test_space') > > +index = space:create_index('primary', { type = 'tree' }) > > + > > +box.schema.user.grant('guest', 'read,write', 'space', 'net_box_test_space') > > +box.schema.user.grant('guest', 'execute', 'universe') > > + > > +cn = remote.connect(box.cfg.listen) > > +cn.space[space.id] ~= nil > > +cn.space.net_box_test_space ~= nil > > +cn.space.net_box_test_space ~= nil > > +cn.space.net_box_test_space.index ~= nil > > +cn.space.net_box_test_space.index.primary ~= nil > > +cn.space.net_box_test_space.index[space.index.primary.id] ~= nil > > +cn.space.net_box_test_space:insert{234, 1,2,3} > > +cn.space.net_box_test_space:replace{354, 1,2,4} > > +cn.space.net_box_test_space.index.primary:min(354) > > +cn.space.net_box_test_space.index.primary:max(234) > > +cn.space.net_box_test_space.index.primary:count(354) > > + > > +box.schema.user.create('netbox', { password = 'test' }) > > +box.schema.user.grant('netbox', 'read,write', 'space', 'net_box_test_space') > > +box.schema.user.grant('netbox', 'execute', 'universe') > > +cn = remote.connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = 'test' }) > > +cn.state > > +cn.error > > +cn:ping() > > + > > +function ret_after(to) fiber.sleep(to) return {{to}} end > > + > > +cn:ping({timeout = 1.00}) > > +cn:ping({timeout = 1e-9}) > > +cn:ping() > > + > > +remote_space = cn.space.net_box_test_space > > +remote_pk = remote_space.index.primary > > + > > +remote_space:insert({0}, { timeout = 1.00 }) > > +remote_space:insert({1}, { timeout = 1e-9 }) > > +remote_space:insert({2}) > > + > > +remote_space:replace({0}, { timeout = 1e-9 }) > > +remote_space:replace({1}) > > +remote_space:replace({2}, { timeout = 1.00 }) > > + > > +remote_space:upsert({3}, {}, { timeout = 1e-9 }) > > +remote_space:upsert({4}, {}) > > +remote_space:upsert({5}, {}, { timeout = 1.00 }) > > +remote_space:upsert({3}, {}) > > + > > +remote_space:update({3}, {}, { timeout = 1e-9 }) > > +remote_space:update({4}, {}) > > +remote_space:update({5}, {}, { timeout = 1.00 }) > > +remote_space:update({3}, {}) > > + > > +remote_pk:update({5}, {}, { timeout = 1e-9 }) > > +remote_pk:update({4}, {}) > > +remote_pk:update({3}, {}, { timeout = 1.00 }) > > +remote_pk:update({5}, {}) > > + > > +remote_space:get({0}) > > +remote_space:get({1}, { timeout = 1.00 }) > > +remote_space:get({2}, { timeout = 1e-9 }) > > + > > +remote_pk:get({3}, { timeout = 1e-9 }) > > +remote_pk:get({4}) > > +remote_pk:get({5}, { timeout = 1.00 }) > > + > > +remote_space:select({2}, { timeout = 1e-9 }) > > +remote_space:select({2}, { timeout = 1.00 }) > > +remote_space:select({2}) > > + > > +remote_pk:select({2}, { timeout = 1.00 }) > > +remote_pk:select({2}, { timeout = 1e-9 }) > > +remote_pk:select({2}) > > + > > +remote_space:select({5}, { timeout = 1.00, iterator = 'LE', limit = 5 }) > > +remote_space:select({5}, { iterator = 'LE', limit = 5}) > > +remote_space:select({5}, { timeout = 1e-9, iterator = 'LE', limit = 5 }) > > + > > +remote_pk:select({2}, { timeout = 1.00, iterator = 'LE', limit = 5 }) > > +remote_pk:select({2}, { iterator = 'LE', limit = 5}) > > +remote_pk:select({2}, { timeout = 1e-9, iterator = 'LE', limit = 5 }) > > + > > +remote_pk:count({2}, { timeout = 1.00}) > > +remote_pk:count({2}, { timeout = 1e-9}) > > +remote_pk:count({2}) > > + > > +remote_pk:count({2}, { timeout = 1.00, iterator = 'LE' }) > > +remote_pk:count({2}, { iterator = 'LE'}) > > +remote_pk:count({2}, { timeout = 1e-9, iterator = 'LE' }) > > + > > +remote_pk:min(nil, { timeout = 1.00 }) > > +remote_pk:min(nil, { timeout = 1e-9 }) > > +remote_pk:min(nil) > > + > > +remote_pk:min({0}, { timeout = 1e-9 }) > > +remote_pk:min({1}) > > +remote_pk:min({2}, { timeout = 1.00 }) > > + > > +remote_pk:max(nil) > > +remote_pk:max(nil, { timeout = 1e-9 }) > > +remote_pk:max(nil, { timeout = 1.00 }) > > + > > +remote_pk:max({0}, { timeout = 1.00 }) > > +remote_pk:max({1}, { timeout = 1e-9 }) > > +remote_pk:max({2}) > > + > > +-- > > +-- gh-3262: index:count() inconsistent results > > +-- > > +test_run:cmd("setopt delimiter ';'") > > + > > +function do_count_test(min, it) > > + local r1 = remote_pk:count(min, {iterator = it} ) > > + local r2 = box.space.net_box_test_space.index.primary:count(min, {iterator = it} ) > > + local r3 = remote.self.space.net_box_test_space.index.primary:count(min, {iterator = it} ) > > + return r1 == r2 and r2 == r3 > > +end; > > + > > +data = remote_pk:select(); > > + > > +for _, v in pairs(data) do > > + local itrs = {'GE', 'GT', 'LE', 'LT' } > > + for _, it in pairs(itrs) do > > + assert(do_count_test(v[0], it) == true) > > + end > > +end; > > + > > +test_run:cmd("setopt delimiter ''"); > > + > > +_ = remote_space:delete({0}, { timeout = 1e-9 }) > > +_ = remote_pk:delete({0}, { timeout = 1.00 }) > > +_ = remote_space:delete({1}, { timeout = 1.00 }) > > +_ = remote_pk:delete({1}, { timeout = 1e-9 }) > > +_ = remote_space:delete({2}, { timeout = 1e-9 }) > > +_ = remote_pk:delete({2}) > > +_ = remote_pk:delete({3}) > > +_ = remote_pk:delete({4}) > > +_ = remote_pk:delete({5}) > > + > > +remote_space:get(0) > > +remote_space:get(1) > > +remote_space:get(2) > > + > > +remote_space = nil > > + > > +cn:call('ret_after', {0.01}, { timeout = 1.00 }) > > +cn:call('ret_after', {1.00}, { timeout = 1e-9 }) > > + > > +cn:eval('return ret_after(...)', {0.01}, { timeout = 1.00 }) > > +cn:eval('return ret_after(...)', {1.00}, { timeout = 1e-9 }) > > + > > +-- > > +-- :timeout() > > +-- @deprecated since 1.7.4 > > +-- > > + > > +cn:timeout(1).space.net_box_test_space.index.primary:select{234} > > +cn:call('ret_after', {.01}) > > +cn:timeout(1):call('ret_after', {.01}) > > +cn:timeout(.01):call('ret_after', {1}) > > + > > +cn = remote:timeout(0.0000000001):connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123' }) > > +cn:close() > > +cn = remote:timeout(1):connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123' }) > > + > > +remote.self:ping() > > +remote.self.space.net_box_test_space:select{234} > > +remote.self:timeout(123).space.net_box_test_space:select{234} > > +remote.self:is_connected() > > +remote.self:wait_connected() > > + > > +cn:close() > > +-- cleanup database after tests > > +space:drop() > > + > > +box.schema.user.revoke('guest', 'execute', 'universe') > > diff --git a/test/box/net.box_discard_gh-3107.result b/test/box/net.box_discard_gh-3107.result > > new file mode 100644 > > index 000000000..3498c9d5a > > --- /dev/null > > +++ b/test/box/net.box_discard_gh-3107.result > > @@ -0,0 +1,119 @@ > > +fiber = require 'fiber' > > +--- > > +... > > +net = require('net.box') > > +--- > > +... > > +-- > > +-- gh-3107: fiber-async netbox. > > +-- > > +cond = nil > > +--- > > +... > > +box.schema.func.create('long_function') > > +--- > > +... > > +box.schema.user.grant('guest', 'execute', 'function', 'long_function') > > +--- > > +... > > +function long_function(...) cond = fiber.cond() cond:wait() return ... end > > +--- > > +... > > +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end > > +--- > > +... > > +s = box.schema.create_space('test') > > +--- > > +... > > +pk = s:create_index('pk') > > +--- > > +... > > +s:replace{1} > > +--- > > +- [1] > > +... > > +s:replace{2} > > +--- > > +- [2] > > +... > > +s:replace{3} > > +--- > > +- [3] > > +... > > +s:replace{4} > > +--- > > +- [4] > > +... > > +c = net:connect(box.cfg.listen) > > +--- > > +... > > +-- > > +-- Ensure a request can be finalized from non-caller fibers. > > +-- > > +future = c:call('long_function', {1, 2, 3}, {is_async = true}) > > +--- > > +... > > +ret = {} > > +--- > > +... > > +count = 0 > > +--- > > +... > > +for i = 1, 10 do fiber.create(function() ret[i] = future:wait_result(1000) count = count + 1 end) end > > +--- > > +... > > +future:wait_result(0.01) -- Must fail on timeout. > > +--- > > +- null > > +- Timeout exceeded > > +... > > +finalize_long() > > +--- > > +... > > +while count ~= 10 do fiber.sleep(0.1) end > > +--- > > +... > > +ret > > +--- > > +- - &0 [1, 2, 3] > > + - *0 > > + - *0 > > + - *0 > > + - *0 > > + - *0 > > + - *0 > > + - *0 > > + - *0 > > + - *0 > > +... > > +-- > > +-- Test discard. > > +-- > > +future = c:call('long_function', {1, 2, 3}, {is_async = true}) > > +--- > > +... > > +future:discard() > > +--- > > +... > > +finalize_long() > > +--- > > +... > > +future:result() > > +--- > > +- null > > +- Response is discarded > > +... > > +future:wait_result(100) > > +--- > > +- null > > +- Response is discarded > > +... > > +box.schema.func.drop('long_function') > > +--- > > +... > > +c:close() > > +--- > > +... > > +s:drop() > > +--- > > +... > > diff --git a/test/box/net.box_discard_gh-3107.test.lua b/test/box/net.box_discard_gh-3107.test.lua > > new file mode 100644 > > index 000000000..71f08a411 > > --- /dev/null > > +++ b/test/box/net.box_discard_gh-3107.test.lua > > @@ -0,0 +1,44 @@ > > +fiber = require 'fiber' > > +net = require('net.box') > > + > > +-- > > +-- gh-3107: fiber-async netbox. > > +-- > > +cond = nil > > +box.schema.func.create('long_function') > > +box.schema.user.grant('guest', 'execute', 'function', 'long_function') > > +function long_function(...) cond = fiber.cond() cond:wait() return ... end > > +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end > > +s = box.schema.create_space('test') > > +pk = s:create_index('pk') > > +s:replace{1} > > +s:replace{2} > > +s:replace{3} > > +s:replace{4} > > +c = net:connect(box.cfg.listen) > > + > > +-- > > +-- Ensure a request can be finalized from non-caller fibers. > > +-- > > +future = c:call('long_function', {1, 2, 3}, {is_async = true}) > > +ret = {} > > +count = 0 > > +for i = 1, 10 do fiber.create(function() ret[i] = future:wait_result(1000) count = count + 1 end) end > > +future:wait_result(0.01) -- Must fail on timeout. > > +finalize_long() > > +while count ~= 10 do fiber.sleep(0.1) end > > +ret > > + > > +-- > > +-- Test discard. > > +-- > > +future = c:call('long_function', {1, 2, 3}, {is_async = true}) > > +future:discard() > > +finalize_long() > > +future:result() > > +future:wait_result(100) > > + > > +box.schema.func.drop('long_function') > > + > > +c:close() > > +s:drop() > > diff --git a/test/box/net.box_disconnect_gh-3859.result b/test/box/net.box_disconnect_gh-3859.result > > new file mode 100644 > > index 000000000..eae259740 > > --- /dev/null > > +++ b/test/box/net.box_disconnect_gh-3859.result > > @@ -0,0 +1,113 @@ > > +fiber = require 'fiber' > > +--- > > +... > > +test_run = require('test_run').new() > > +--- > > +... > > +net = require('net.box') > > +--- > > +... > > +test_run:cmd('create server connecter with script = "box/proxy.lua"') > > +--- > > +- true > > +... > > +box.schema.func.create('fast_call') > > +--- > > +... > > +box.schema.func.create('long_call') > > +--- > > +... > > +box.schema.func.create('wait_signal') > > +--- > > +... > > +box.schema.user.grant('guest', 'execute', 'function', 'fast_call') > > +--- > > +... > > +box.schema.user.grant('guest', 'execute', 'function', 'long_call') > > +--- > > +... > > +box.schema.user.grant('guest', 'execute', 'function', 'wait_signal') > > +--- > > +... > > +c = net.connect(box.cfg.listen) > > +--- > > +... > > +disconnected = false > > +--- > > +... > > +function on_disconnect() disconnected = true end > > +--- > > +... > > +-- Make sure all dangling connections are collected so > > +-- that on_disconnect trigger isn't called spuriously. > > +collectgarbage('collect') > > +--- > > +- 0 > > +... > > +fiber.sleep(0) > > +--- > > +... > > +box.session.on_disconnect(on_disconnect) == on_disconnect > > +--- > > +- true > > +... > > +-- > > +-- gh-3859: on_disconnect is called only after all requests are > > +-- processed, but should be called right after disconnect and > > +-- only once. > > +-- > > +ch1 = fiber.channel(1) > > +--- > > +... > > +ch2 = fiber.channel(1) > > +--- > > +... > > +function wait_signal() ch1:put(true) ch2:get() end > > +--- > > +... > > +_ = fiber.create(function() c:call('wait_signal') end) > > +--- > > +... > > +ch1:get() > > +--- > > +- true > > +... > > +c:close() > > +--- > > +... > > +fiber.sleep(0) > > +--- > > +... > > +while disconnected == false do fiber.sleep(0.01) end > > +--- > > +... > > +disconnected -- true > > +--- > > +- true > > +... > > +disconnected = nil > > +--- > > +... > > +ch2:put(true) > > +--- > > +- true > > +... > > +fiber.sleep(0) > > +--- > > +... > > +disconnected -- nil, on_disconnect is not called second time. > > +--- > > +- null > > +... > > +box.session.on_disconnect(nil, on_disconnect) > > +--- > > +... > > +box.schema.func.drop('long_call') > > +--- > > +... > > +box.schema.func.drop('fast_call') > > +--- > > +... > > +box.schema.func.drop('wait_signal') > > +--- > > +... > > diff --git a/test/box/net.box_disconnect_gh-3859.test.lua b/test/box/net.box_disconnect_gh-3859.test.lua > > new file mode 100644 > > index 000000000..e0ec1a8ea > > --- /dev/null > > +++ b/test/box/net.box_disconnect_gh-3859.test.lua > > @@ -0,0 +1,50 @@ > > +fiber = require 'fiber' > > +test_run = require('test_run').new() > > +net = require('net.box') > > + > > +test_run:cmd('create server connecter with script = "box/proxy.lua"') > > + > > +box.schema.func.create('fast_call') > > +box.schema.func.create('long_call') > > +box.schema.func.create('wait_signal') > > +box.schema.user.grant('guest', 'execute', 'function', 'fast_call') > > +box.schema.user.grant('guest', 'execute', 'function', 'long_call') > > +box.schema.user.grant('guest', 'execute', 'function', 'wait_signal') > > +c = net.connect(box.cfg.listen) > > + > > +disconnected = false > > +function on_disconnect() disconnected = true end > > + > > +-- Make sure all dangling connections are collected so > > +-- that on_disconnect trigger isn't called spuriously. > > +collectgarbage('collect') > > +fiber.sleep(0) > > + > > +box.session.on_disconnect(on_disconnect) == on_disconnect > > + > > +-- > > +-- gh-3859: on_disconnect is called only after all requests are > > +-- processed, but should be called right after disconnect and > > +-- only once. > > +-- > > +ch1 = fiber.channel(1) > > +ch2 = fiber.channel(1) > > +function wait_signal() ch1:put(true) ch2:get() end > > +_ = fiber.create(function() c:call('wait_signal') end) > > +ch1:get() > > + > > +c:close() > > +fiber.sleep(0) > > +while disconnected == false do fiber.sleep(0.01) end > > +disconnected -- true > > +disconnected = nil > > + > > +ch2:put(true) > > +fiber.sleep(0) > > +disconnected -- nil, on_disconnect is not called second time. > > + > > +box.session.on_disconnect(nil, on_disconnect) > > + > > +box.schema.func.drop('long_call') > > +box.schema.func.drop('fast_call') > > +box.schema.func.drop('wait_signal') > > diff --git a/test/box/net.box_fiber-async_gh-3107.result b/test/box/net.box_fiber-async_gh-3107.result > > new file mode 100644 > > index 000000000..aaaca351a > > --- /dev/null > > +++ b/test/box/net.box_fiber-async_gh-3107.result > > @@ -0,0 +1,115 @@ > > +fiber = require 'fiber' > > +--- > > +... > > +net = require('net.box') > > +--- > > +... > > +-- > > +-- gh-3107: fiber-async netbox. > > +-- > > +cond = nil > > +--- > > +... > > +box.schema.func.create('long_function') > > +--- > > +... > > +box.schema.user.grant('guest', 'execute', 'function', 'long_function') > > +--- > > +... > > +function long_function(...) cond = fiber.cond() cond:wait() return ... end > > +--- > > +... > > +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end > > +--- > > +... > > +s = box.schema.create_space('test') > > +--- > > +... > > +pk = s:create_index('pk') > > +--- > > +... > > +s:replace{1} > > +--- > > +- [1] > > +... > > +s:replace{2} > > +--- > > +- [2] > > +... > > +s:replace{3} > > +--- > > +- [3] > > +... > > +s:replace{4} > > +--- > > +- [4] > > +... > > +c = net:connect(box.cfg.listen) > > +--- > > +... > > +-- > > +-- Check long connections, multiple wait_result(). > > +-- > > +future = c:call('long_function', {1, 2, 3}, {is_async = true}) > > +--- > > +... > > +future:result() > > +--- > > +- null > > +- Response is not ready > > +... > > +future:is_ready() > > +--- > > +- false > > +... > > +future:wait_result(0.01) -- Must fail on timeout. > > +--- > > +- null > > +- Timeout exceeded > > +... > > +finalize_long() > > +--- > > +... > > +ret = future:wait_result(100) > > +--- > > +... > > +future:is_ready() > > +--- > > +- true > > +... > > +-- Any timeout is ok - response is received already. > > +future:wait_result(0) > > +--- > > +- [1, 2, 3] > > +... > > +future:wait_result(0.01) > > +--- > > +- [1, 2, 3] > > +... > > +ret > > +--- > > +- [1, 2, 3] > > +... > > +_, err = pcall(future.wait_result, future, true) > > +--- > > +... > > +err:find('Usage') ~= nil > > +--- > > +- true > > +... > > +_, err = pcall(future.wait_result, future, '100') > > +--- > > +... > > +err:find('Usage') ~= nil > > +--- > > +- true > > +... > > +box.schema.func.drop('long_function') > > +--- > > +... > > +c:close() > > +--- > > +... > > +s:drop() > > +--- > > +... > > diff --git a/test/box/net.box_fiber-async_gh-3107.test.lua b/test/box/net.box_fiber-async_gh-3107.test.lua > > new file mode 100644 > > index 000000000..d23f368cb > > --- /dev/null > > +++ b/test/box/net.box_fiber-async_gh-3107.test.lua > > @@ -0,0 +1,42 @@ > > +fiber = require 'fiber' > > +net = require('net.box') > > + > > +-- > > +-- gh-3107: fiber-async netbox. > > +-- > > +cond = nil > > +box.schema.func.create('long_function') > > +box.schema.user.grant('guest', 'execute', 'function', 'long_function') > > +function long_function(...) cond = fiber.cond() cond:wait() return ... end > > +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end > > +s = box.schema.create_space('test') > > +pk = s:create_index('pk') > > +s:replace{1} > > +s:replace{2} > > +s:replace{3} > > +s:replace{4} > > +c = net:connect(box.cfg.listen) > > +-- > > +-- Check long connections, multiple wait_result(). > > +-- > > +future = c:call('long_function', {1, 2, 3}, {is_async = true}) > > +future:result() > > +future:is_ready() > > +future:wait_result(0.01) -- Must fail on timeout. > > +finalize_long() > > +ret = future:wait_result(100) > > +future:is_ready() > > +-- Any timeout is ok - response is received already. > > +future:wait_result(0) > > +future:wait_result(0.01) > > +ret > > + > > +_, err = pcall(future.wait_result, future, true) > > +err:find('Usage') ~= nil > > +_, err = pcall(future.wait_result, future, '100') > > +err:find('Usage') ~= nil > > + > > +box.schema.func.drop('long_function') > > + > > +c:close() > > +s:drop() > > diff --git a/test/box/net.box_field_names_gh-2978.result b/test/box/net.box_field_names_gh-2978.result > > new file mode 100644 > > index 000000000..2b6ea9c44 > > --- /dev/null > > +++ b/test/box/net.box_field_names_gh-2978.result > > @@ -0,0 +1,101 @@ > > +net = require('net.box') > > +--- > > +... > > +-- > > +-- gh-2978: field names for tuples received from netbox. > > +-- > > +_ = box.schema.create_space("named", {format = {{name = "id"}, {name="abc"}}}) > > +--- > > +... > > +_ = box.space.named:create_index('id', {parts = {{1, 'unsigned'}}}) > > +--- > > +... > > +box.space.named:insert({1, 1}) > > +--- > > +- [1, 1] > > +... > > +box.schema.user.grant('guest', 'read, write, execute', 'space') > > +--- > > +... > > +cn = net.connect(box.cfg.listen) > > +--- > > +... > > +s = cn.space.named > > +--- > > +... > > +s:get{1}.id > > +--- > > +- 1 > > +... > > +s:get{1}:tomap() > > +--- > > +- 1: 1 > > + 2: 1 > > + abc: 1 > > + id: 1 > > +... > > +s:insert{2,3}:tomap() > > +--- > > +- 1: 2 > > + 2: 3 > > + abc: 3 > > + id: 2 > > +... > > +s:replace{2,14}:tomap() > > +--- > > +- 1: 2 > > + 2: 14 > > + abc: 14 > > + id: 2 > > +... > > +s:update(1, {{'+', 2, 10}}):tomap() > > +--- > > +- 1: 1 > > + 2: 11 > > + abc: 11 > > + id: 1 > > +... > > +s:select()[1]:tomap() > > +--- > > +- 1: 1 > > + 2: 11 > > + abc: 11 > > + id: 1 > > +... > > +s:delete({2}):tomap() > > +--- > > +- 1: 2 > > + 2: 14 > > + abc: 14 > > + id: 2 > > +... > > +-- Check that formats changes after reload. > > +box.space.named:format({{name = "id2"}, {name="abc2"}}) > > +--- > > +... > > +s:select()[1]:tomap() > > +--- > > +- 1: 1 > > + 2: 11 > > + abc: 11 > > + id: 1 > > +... > > +cn:reload_schema() > > +--- > > +... > > +s:select()[1]:tomap() > > +--- > > +- 1: 1 > > + 2: 11 > > + id2: 1 > > + abc2: 11 > > +... > > +cn:close() > > +--- > > +... > > +box.space.named:drop() > > +--- > > +... > > +box.schema.user.revoke('guest', 'read, write, execute', 'space') > > +--- > > +... > > diff --git a/test/box/net.box_field_names_gh-2978.test.lua b/test/box/net.box_field_names_gh-2978.test.lua > > new file mode 100644 > > index 000000000..a5dccf16a > > --- /dev/null > > +++ b/test/box/net.box_field_names_gh-2978.test.lua > > @@ -0,0 +1,29 @@ > > +net = require('net.box') > > + > > +-- > > +-- gh-2978: field names for tuples received from netbox. > > +-- > > +_ = box.schema.create_space("named", {format = {{name = "id"}, {name="abc"}}}) > > +_ = box.space.named:create_index('id', {parts = {{1, 'unsigned'}}}) > > +box.space.named:insert({1, 1}) > > +box.schema.user.grant('guest', 'read, write, execute', 'space') > > +cn = net.connect(box.cfg.listen) > > + > > +s = cn.space.named > > +s:get{1}.id > > +s:get{1}:tomap() > > +s:insert{2,3}:tomap() > > +s:replace{2,14}:tomap() > > +s:update(1, {{'+', 2, 10}}):tomap() > > +s:select()[1]:tomap() > > +s:delete({2}):tomap() > > + > > +-- Check that formats changes after reload. > > +box.space.named:format({{name = "id2"}, {name="abc2"}}) > > +s:select()[1]:tomap() > > +cn:reload_schema() > > +s:select()[1]:tomap() > > + > > +cn:close() > > +box.space.named:drop() > > +box.schema.user.revoke('guest', 'read, write, execute', 'space') > > diff --git a/test/box/net.box_get_connection_object.result b/test/box/net.box_get_connection_object.result > > new file mode 100644 > > index 000000000..f461477ed > > --- /dev/null > > +++ b/test/box/net.box_get_connection_object.result > > @@ -0,0 +1,40 @@ > > +net = require('net.box') > > +--- > > +... > > +-- > > +-- Check that it's possible to get connection object form net.box space > > +-- > > +space = box.schema.space.create('test', {format={{name="id", type="unsigned"}}}) > > +--- > > +... > > +space ~= nil > > +--- > > +- true > > +... > > +_ = box.space.test:create_index('primary') > > +--- > > +... > > +box.schema.user.grant('guest','read,write,execute','space', 'test') > > +--- > > +... > > +c = net.connect(box.cfg.listen) > > +--- > > +... > > +c:ping() > > +--- > > +- true > > +... > > +c.space.test ~= nil > > +--- > > +- true > > +... > > +c.space.test.connection == c > > +--- > > +- true > > +... > > +box.schema.user.revoke('guest','read,write,execute','space', 'test') > > +--- > > +... > > +c:close() > > +--- > > +... > > diff --git a/test/box/net.box_get_connection_object.test.lua b/test/box/net.box_get_connection_object.test.lua > > new file mode 100644 > > index 000000000..71ed110b9 > > --- /dev/null > > +++ b/test/box/net.box_get_connection_object.test.lua > > @@ -0,0 +1,19 @@ > > +net = require('net.box') > > + > > +-- > > +-- Check that it's possible to get connection object form net.box space > > +-- > > + > > +space = box.schema.space.create('test', {format={{name="id", type="unsigned"}}}) > > +space ~= nil > > +_ = box.space.test:create_index('primary') > > +box.schema.user.grant('guest','read,write,execute','space', 'test') > > + > > +c = net.connect(box.cfg.listen) > > + > > +c:ping() > > +c.space.test ~= nil > > + > > +c.space.test.connection == c > > +box.schema.user.revoke('guest','read,write,execute','space', 'test') > > +c:close() > > diff --git a/test/box/net.box_gibberish_gh-3900.result b/test/box/net.box_gibberish_gh-3900.result > > new file mode 100644 > > index 000000000..302c74c9f > > --- /dev/null > > +++ b/test/box/net.box_gibberish_gh-3900.result > > @@ -0,0 +1,31 @@ > > +test_run = require('test_run').new() > > +--- > > +... > > +LISTEN = require('uri').parse(box.cfg.listen) > > +--- > > +... > > +-- > > +-- gh-3900: tarantool can be crashed by sending gibberish to a > > +-- binary socket > > +-- > > +socket = require("socket") > > +--- > > +... > > +sock = socket.tcp_connect(LISTEN.host, LISTEN.service) > > +--- > > +... > > +data = string.fromhex("6783000000000000000000000000000000000000000000800000C8000000000000000000000000000000000000000000FFFF210100373208000000FFFF000055AAEB66486472530D02000000000010A0350001008000001000000000000000000000000000D05700") > > +--- > > +... > > +sock:write(data) > > +--- > > +- 104 > > +... > > +test_run:wait_log('default', 'ER_INVALID_MSGPACK: Invalid MsgPack %- packet body', nil, 10) > > +--- > > +- 'ER_INVALID_MSGPACK: Invalid MsgPack - packet body' > > +... > > +sock:close() > > +--- > > +- true > > +... > > diff --git a/test/box/net.box_gibberish_gh-3900.test.lua b/test/box/net.box_gibberish_gh-3900.test.lua > > new file mode 100644 > > index 000000000..7debfd4b3 > > --- /dev/null > > +++ b/test/box/net.box_gibberish_gh-3900.test.lua > > @@ -0,0 +1,13 @@ > > +test_run = require('test_run').new() > > +LISTEN = require('uri').parse(box.cfg.listen) > > + > > +-- > > +-- gh-3900: tarantool can be crashed by sending gibberish to a > > +-- binary socket > > +-- > > +socket = require("socket") > > +sock = socket.tcp_connect(LISTEN.host, LISTEN.service) > > +data = string.fromhex("6783000000000000000000000000000000000000000000800000C8000000000000000000000000000000000000000000FFFF210100373208000000FFFF000055AAEB66486472530D02000000000010A0350001008000001000000000000000000000000000D05700") > > +sock:write(data) > > +test_run:wait_log('default', 'ER_INVALID_MSGPACK: Invalid MsgPack %- packet body', nil, 10) > > +sock:close() > > diff --git a/test/box/net.box_huge_data_gh-983.result b/test/box/net.box_huge_data_gh-983.result > > new file mode 100644 > > index 000000000..e9b470e28 > > --- /dev/null > > +++ b/test/box/net.box_huge_data_gh-983.result > > @@ -0,0 +1,30 @@ > > +-- gh-983 selecting a lot of data crashes the server or hangs the > > +-- connection > > +-- gh-983 test case: iproto connection selecting a lot of data > > +_ = box.schema.space.create('test', { temporary = true }) > > +--- > > +... > > +_ = box.space.test:create_index('primary', {type = 'TREE', parts = {1,'unsigned'}}) > > +--- > > +... > > +data1k = "aaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhh" > > +--- > > +... > > +for i = 0,10000 do box.space.test:insert{i, data1k} end > > +--- > > +... > > +box.schema.user.grant('guest', 'read', 'space', 'test') > > +--- > > +... > > +net = require('net.box') > > +--- > > +... > > +c = net:connect(box.cfg.listen) > > +--- > > +... > > +r = c.space.test:select(nil, {limit=5000}) > > +--- > > +... > > +box.space.test:drop() > > +--- > > +... > > diff --git a/test/box/net.box_huge_data_gh-983.test.lua b/test/box/net.box_huge_data_gh-983.test.lua > > new file mode 100644 > > index 000000000..93df08834 > > --- /dev/null > > +++ b/test/box/net.box_huge_data_gh-983.test.lua > > @@ -0,0 +1,16 @@ > > +-- gh-983 selecting a lot of data crashes the server or hangs the > > +-- connection > > + > > +-- gh-983 test case: iproto connection selecting a lot of data > > +_ = box.schema.space.create('test', { temporary = true }) > > +_ = box.space.test:create_index('primary', {type = 'TREE', parts = {1,'unsigned'}}) > > + > > +data1k = "aaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhhaaaabbbbccccddddeeeeffffgggghhhh" > > + > > +for i = 0,10000 do box.space.test:insert{i, data1k} end > > + > > +box.schema.user.grant('guest', 'read', 'space', 'test') > > +net = require('net.box') > > +c = net:connect(box.cfg.listen) > > +r = c.space.test:select(nil, {limit=5000}) > > +box.space.test:drop() > > diff --git a/test/box/net.box_incompatible_index-gh-1729.result b/test/box/net.box_incompatible_index-gh-1729.result > > new file mode 100644 > > index 000000000..1d9fa542e > > --- /dev/null > > +++ b/test/box/net.box_incompatible_index-gh-1729.result > > @@ -0,0 +1,99 @@ > > +test_run = require('test_run').new() > > +--- > > +... > > +net = require('net.box') > > +--- > > +... > > +test_run:cmd("push filter ".."'\\.lua.*:[0-9]+: ' to '.lua...\"]:<line>: '") > > +--- > > +- true > > +... > > +_ = box.schema.space.create('test') > > +--- > > +... > > +_ = box.space.test:create_index('primary', {type = 'TREE', parts = {1,'unsigned'}}) > > +--- > > +... > > +_ = box.space.test:create_index('covering', {type = 'TREE', parts = {1,'unsigned',3,'string',2,'unsigned'}}) > > +--- > > +... > > +_ = box.space.test:insert{1, 2, "string"} > > +--- > > +... > > +box.schema.user.grant('guest', 'read,write', 'space', 'test') > > +--- > > +... > > +c = net:connect(box.cfg.listen) > > +--- > > +... > > +-- gh-1729 net.box index metadata incompatible with local metadata > > +c.space.test.index.primary.parts > > +--- > > +- - type: unsigned > > + is_nullable: false > > + fieldno: 1 > > +... > > +c.space.test.index.covering.parts > > +--- > > +- - type: unsigned > > + is_nullable: false > > + fieldno: 1 > > + - type: string > > + is_nullable: false > > + fieldno: 3 > > + - type: unsigned > > + is_nullable: false > > + fieldno: 2 > > +... > > +box.space.test:drop() > > +--- > > +... > > +-- CALL vs CALL_16 in connect options > > +function echo(...) return ... end > > +--- > > +... > > +box.schema.user.grant('guest', 'execute', 'universe') > > +--- > > +... > > +c = net.connect(box.cfg.listen) > > +--- > > +... > > +c:call('echo', {42}) > > +--- > > +- 42 > > +... > > +c:eval('return echo(...)', {42}) > > +--- > > +- 42 > > +... > > +-- invalid arguments > > +c:call('echo', 42) > > +--- > > +- error: 'builtin/box/net_box.lua..."]:<line>: Use remote:call(func_name, {arg1, arg2, ...}, > > + opts) instead of remote:call(func_name, arg1, arg2, ...)' > > +... > > +c:eval('return echo(...)', 42) > > +--- > > +- error: 'builtin/box/net_box.lua..."]:<line>: Use remote:eval(expression, {arg1, arg2, ...}, > > + opts) instead of remote:eval(expression, arg1, arg2, ...)' > > +... > > +c:close() > > +--- > > +... > > +c = net.connect(box.cfg.listen, {call_16 = true}) > > +--- > > +... > > +c:call('echo', 42) > > +--- > > +- - [42] > > +... > > +c:eval('return echo(...)', 42) > > +--- > > +- 42 > > +... > > +c:close() > > +--- > > +... > > +box.schema.user.revoke('guest', 'execute', 'universe') > > +--- > > +... > > diff --git a/test/box/net.box_incompatible_index-gh-1729.test.lua b/test/box/net.box_incompatible_index-gh-1729.test.lua > > new file mode 100644 > > index 000000000..2d25b9017 > > --- /dev/null > > +++ b/test/box/net.box_incompatible_index-gh-1729.test.lua > > @@ -0,0 +1,33 @@ > > +test_run = require('test_run').new() > > +net = require('net.box') > > + > > +test_run:cmd("push filter ".."'\\.lua.*:[0-9]+: ' to '.lua...\"]:<line>: '") > > + > > +_ = box.schema.space.create('test') > > +_ = box.space.test:create_index('primary', {type = 'TREE', parts = {1,'unsigned'}}) > > +_ = box.space.test:create_index('covering', {type = 'TREE', parts = {1,'unsigned',3,'string',2,'unsigned'}}) > > +_ = box.space.test:insert{1, 2, "string"} > > +box.schema.user.grant('guest', 'read,write', 'space', 'test') > > +c = net:connect(box.cfg.listen) > > + > > +-- gh-1729 net.box index metadata incompatible with local metadata > > +c.space.test.index.primary.parts > > +c.space.test.index.covering.parts > > + > > +box.space.test:drop() > > + > > +-- CALL vs CALL_16 in connect options > > +function echo(...) return ... end > > +box.schema.user.grant('guest', 'execute', 'universe') > > +c = net.connect(box.cfg.listen) > > +c:call('echo', {42}) > > +c:eval('return echo(...)', {42}) > > +-- invalid arguments > > +c:call('echo', 42) > > +c:eval('return echo(...)', 42) > > +c:close() > > +c = net.connect(box.cfg.listen, {call_16 = true}) > > +c:call('echo', 42) > > +c:eval('return echo(...)', 42) > > +c:close() > > +box.schema.user.revoke('guest', 'execute', 'universe') > > diff --git a/test/box/net.box_incorrect_iterator_gh-841.result b/test/box/net.box_incorrect_iterator_gh-841.result > > new file mode 100644 > > index 000000000..4bdd1afa3 > > --- /dev/null > > +++ b/test/box/net.box_incorrect_iterator_gh-841.result > > @@ -0,0 +1,497 @@ > > +remote = require 'net.box' > > +--- > > +... > > +fiber = require 'fiber' > > +--- > > +... > > +test_run = require('test_run').new() > > +--- > > +... > > +test_run:cmd("push filter ".."'\\.lua.*:[0-9]+: ' to '.lua...\"]:<line>: '") > > +--- > > +- true > > +... > > +test_run:cmd("setopt delimiter ';'") > > +--- > > +- true > > +... > > +function x_select(cn, space_id, index_id, iterator, offset, limit, key, opts) > > + local ret = cn:_request('select', opts, nil, space_id, index_id, iterator, > > + offset, limit, key) > > + return ret > > +end > > +function x_fatal(cn) cn._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') end > > +test_run:cmd("setopt delimiter ''"); > > +--- > > +... > > +LISTEN = require('uri').parse(box.cfg.listen) > > +--- > > +... > > +space = box.schema.space.create('net_box_test_space') > > +--- > > +... > > +index = space:create_index('primary', { type = 'tree' }) > > +--- > > +... > > +function test_foo(a,b,c) return { {{ [a] = 1 }}, {{ [b] = 2 }}, c } end > > +--- > > +... > > +box.schema.user.grant('guest', 'read,write', 'space', 'net_box_test_space') > > +--- > > +... > > +box.schema.user.grant('guest', 'execute', 'universe') > > +--- > > +... > > +cn = remote.connect(box.cfg.listen) > > +--- > > +... > > +x_select(cn, space.id, space.index.primary.id, box.index.EQ, 0, 0xFFFFFFFF, 123) > > +--- > > +- [] > > +... > > +space:insert{123, 345} > > +--- > > +- [123, 345] > > +... > > +x_select(cn, space.id, space.index.primary.id, box.index.EQ, 0, 0, 123) > > +--- > > +- [] > > +... > > +x_select(cn, space.id, space.index.primary.id, box.index.EQ, 0, 1, 123) > > +--- > > +- - [123, 345] > > +... > > +x_select(cn, space.id, space.index.primary.id, box.index.EQ, 1, 1, 123) > > +--- > > +- [] > > +... > > +cn.space[space.id] ~= nil > > +--- > > +- true > > +... > > +cn.space.net_box_test_space ~= nil > > +--- > > +- true > > +... > > +cn.space.net_box_test_space ~= nil > > +--- > > +- true > > +... > > +cn.space.net_box_test_space.index ~= nil > > +--- > > +- true > > +... > > +cn.space.net_box_test_space.index.primary ~= nil > > +--- > > +- true > > +... > > +cn.space.net_box_test_space.index[space.index.primary.id] ~= nil > > +--- > > +- true > > +... > > +cn.space.net_box_test_space.index.primary:select(123) > > +--- > > +- - [123, 345] > > +... > > +cn.space.net_box_test_space.index.primary:select(123, { limit = 0 }) > > +--- > > +- [] > > +... > > +cn.space.net_box_test_space.index.primary:select(nil, { limit = 1, }) > > +--- > > +- - [123, 345] > > +... > > +cn.space.net_box_test_space:insert{234, 1,2,3} > > +--- > > +- [234, 1, 2, 3] > > +... > > +cn.space.net_box_test_space:insert{234, 1,2,3} > > +--- > > +- error: Duplicate key exists in unique index 'primary' in space 'net_box_test_space' > > +... > > +cn.space.net_box_test_space.insert{234, 1,2,3} > > +--- > > +- error: 'builtin/box/schema.lua..."]:<line>: Use space:insert(...) instead of space.insert(...)' > > +... > > +cn.space.net_box_test_space:replace{354, 1,2,3} > > +--- > > +- [354, 1, 2, 3] > > +... > > +cn.space.net_box_test_space:replace{354, 1,2,4} > > +--- > > +- [354, 1, 2, 4] > > +... > > +cn.space.net_box_test_space:select{123} > > +--- > > +- - [123, 345] > > +... > > +space:select({123}, { iterator = 'GE' }) > > +--- > > +- - [123, 345] > > + - [234, 1, 2, 3] > > + - [354, 1, 2, 4] > > +... > > +cn.space.net_box_test_space:select({123}, { iterator = 'GE' }) > > +--- > > +- - [123, 345] > > + - [234, 1, 2, 3] > > + - [354, 1, 2, 4] > > +... > > +cn.space.net_box_test_space:select({123}, { iterator = 'GT' }) > > +--- > > +- - [234, 1, 2, 3] > > + - [354, 1, 2, 4] > > +... > > +cn.space.net_box_test_space:select({123}, { iterator = 'GT', limit = 1 }) > > +--- > > +- - [234, 1, 2, 3] > > +... > > +cn.space.net_box_test_space:select({123}, { iterator = 'GT', limit = 1, offset = 1 }) > > +--- > > +- - [354, 1, 2, 4] > > +... > > +cn.space.net_box_test_space:select{123} > > +--- > > +- - [123, 345] > > +... > > +cn.space.net_box_test_space:update({123}, { { '+', 2, 1 } }) > > +--- > > +- [123, 346] > > +... > > +cn.space.net_box_test_space:update(123, { { '+', 2, 1 } }) > > +--- > > +- [123, 347] > > +... > > +cn.space.net_box_test_space:select{123} > > +--- > > +- - [123, 347] > > +... > > +cn.space.net_box_test_space:insert(cn.space.net_box_test_space:get{123}:update{ { '=', 1, 2 } }) > > +--- > > +- [2, 347] > > +... > > +cn.space.net_box_test_space:delete{123} > > +--- > > +- [123, 347] > > +... > > +cn.space.net_box_test_space:select{2} > > +--- > > +- - [2, 347] > > +... > > +cn.space.net_box_test_space:select({234}, { iterator = 'LT' }) > > +--- > > +- - [2, 347] > > +... > > +cn.space.net_box_test_space:update({1}, { { '+', 2, 2 } }) > > +--- > > +... > > +cn.space.net_box_test_space:delete{1} > > +--- > > +... > > +cn.space.net_box_test_space:delete{2} > > +--- > > +- [2, 347] > > +... > > +cn.space.net_box_test_space:delete{2} > > +--- > > +... > > +-- test one-based indexing in splice operation (see update.test.lua) > > +cn.space.net_box_test_space:replace({10, 'abcde'}) > > +--- > > +- [10, 'abcde'] > > +... > > +cn.space.net_box_test_space:update(10, {{':', 2, 0, 0, '!'}}) > > +--- > > +- error: 'SPLICE error on field 2: offset is out of bound' > > +... > > +cn.space.net_box_test_space:update(10, {{':', 2, 1, 0, '('}}) > > +--- > > +- [10, '(abcde'] > > +... > > +cn.space.net_box_test_space:update(10, {{':', 2, 2, 0, '({'}}) > > +--- > > +- [10, '(({abcde'] > > +... > > +cn.space.net_box_test_space:update(10, {{':', 2, -1, 0, ')'}}) > > +--- > > +- [10, '(({abcde)'] > > +... > > +cn.space.net_box_test_space:update(10, {{':', 2, -2, 0, '})'}}) > > +--- > > +- [10, '(({abcde}))'] > > +... > > +cn.space.net_box_test_space:delete{10} > > +--- > > +- [10, '(({abcde}))'] > > +... > > +cn.space.net_box_test_space:select({}, { iterator = 'ALL' }) > > +--- > > +- - [234, 1, 2, 3] > > + - [354, 1, 2, 4] > > +... > > +-- gh-841: net.box uses incorrect iterator type for select with no arguments > > +cn.space.net_box_test_space:select() > > +--- > > +- - [234, 1, 2, 3] > > + - [354, 1, 2, 4] > > +... > > +cn.space.net_box_test_space.index.primary:min() > > +--- > > +- [234, 1, 2, 3] > > +... > > +cn.space.net_box_test_space.index.primary:min(354) > > +--- > > +- [354, 1, 2, 4] > > +... > > +cn.space.net_box_test_space.index.primary:max() > > +--- > > +- [354, 1, 2, 4] > > +... > > +cn.space.net_box_test_space.index.primary:max(234) > > +--- > > +- [234, 1, 2, 3] > > +... > > +cn.space.net_box_test_space.index.primary:count() > > +--- > > +- 2 > > +... > > +cn.space.net_box_test_space.index.primary:count(354) > > +--- > > +- 1 > > +... > > +cn.space.net_box_test_space:get(354) > > +--- > > +- [354, 1, 2, 4] > > +... > > +-- reconnects after errors > > +box.schema.user.revoke('guest', 'execute', 'universe') > > +--- > > +... > > +box.schema.func.create('test_foo') > > +--- > > +... > > +box.schema.user.grant('guest', 'execute', 'function', 'test_foo') > > +--- > > +... > > +-- -- 1. no reconnect > > +x_fatal(cn) > > +--- > > +... > > +cn.state > > +--- > > +- error > > +... > > +cn:ping() > > +--- > > +- false > > +... > > +cn:call('test_foo') > > +--- > > +- error: Peer closed > > +... > > +cn:wait_state('active') > > +--- > > +- false > > +... > > +-- -- 2 reconnect > > +cn = remote.connect(LISTEN.host, LISTEN.service, { reconnect_after = .1 }) > > +--- > > +... > > +cn.space ~= nil > > +--- > > +- true > > +... > > +cn.space.net_box_test_space:select({}, { iterator = 'ALL' }) > > +--- > > +- - [234, 1, 2, 3] > > + - [354, 1, 2, 4] > > +... > > +x_fatal(cn) > > +--- > > +... > > +cn:wait_connected() > > +--- > > +- true > > +... > > +cn:wait_state('active') > > +--- > > +- true > > +... > > +cn:wait_state({active=true}) > > +--- > > +- true > > +... > > +cn:ping() > > +--- > > +- true > > +... > > +cn.state > > +--- > > +- active > > +... > > +cn.space.net_box_test_space:select({}, { iterator = 'ALL' }) > > +--- > > +- - [234, 1, 2, 3] > > + - [354, 1, 2, 4] > > +... > > +x_fatal(cn) > > +--- > > +... > > +x_select(cn, space.id, 0, box.index.ALL, 0, 0xFFFFFFFF, {}) > > +--- > > +- - [234, 1, 2, 3] > > + - [354, 1, 2, 4] > > +... > > +cn.state > > +--- > > +- active > > +... > > +cn:ping() > > +--- > > +- true > > +... > > +-- -- dot-new-method > > +cn1 = remote.new(LISTEN.host, LISTEN.service) > > +--- > > +... > > +x_select(cn1, space.id, 0, box.index.ALL, 0, 0xFFFFFFF, {}) > > +--- > > +- - [234, 1, 2, 3] > > + - [354, 1, 2, 4] > > +... > > +cn1:close() > > +--- > > +... > > +-- -- error while waiting for response > > +type(fiber.create(function() fiber.sleep(.5) x_fatal(cn) end)) > > +--- > > +- userdata > > +... > > +function pause() fiber.sleep(10) return true end > > +--- > > +... > > +box.schema.func.create('pause') > > +--- > > +... > > +box.schema.user.grant('guest', 'execute', 'function', 'pause') > > +--- > > +... > > +cn:call('pause') > > +--- > > +- error: Peer closed > > +... > > +cn:call('test_foo', {'a', 'b', 'c'}) > > +--- > > +- [[{'a': 1}], [{'b': 2}], 'c'] > > +... > > +box.schema.func.drop('pause') > > +--- > > +... > > +-- call > > +remote.self:call('test_foo', {'a', 'b', 'c'}) > > +--- > > +- - - a: 1 > > + - - b: 2 > > + - c > > +... > > +cn:call('test_foo', {'a', 'b', 'c'}) > > +--- > > +- [[{'a': 1}], [{'b': 2}], 'c'] > > +... > > +box.schema.func.drop('test_foo') > > +--- > > +... > > +box.schema.func.create('long_rep') > > +--- > > +... > > +box.schema.user.grant('guest', 'execute', 'function', 'long_rep') > > +--- > > +... > > +-- long replies > > +function long_rep() return { 1, string.rep('a', 5000) } end > > +--- > > +... > > +res = cn:call('long_rep') > > +--- > > +... > > +res[1] == 1 > > +--- > > +- true > > +... > > +res[2] == string.rep('a', 5000) > > +--- > > +- true > > +... > > +function long_rep() return { 1, string.rep('a', 50000) } end > > +--- > > +... > > +res = cn:call('long_rep') > > +--- > > +... > > +res[1] == 1 > > +--- > > +- true > > +... > > +res[2] == string.rep('a', 50000) > > +--- > > +- true > > +... > > +box.schema.func.drop('long_rep') > > +--- > > +... > > +-- a.b.c.d > > +u = '84F7BCFA-079C-46CC-98B4-F0C821BE833E' > > +--- > > +... > > +X = {} > > +--- > > +... > > +X.X = X > > +--- > > +... > > +function X.fn(x,y) return y or x end > > +--- > > +... > > +box.schema.user.grant('guest', 'execute', 'universe') > > +--- > > +... > > +cn:close() > > +--- > > +... > > +cn = remote.connect(LISTEN.host, LISTEN.service) > > +--- > > +... > > +cn:call('X.fn', {u}) > > +--- > > +- 84F7BCFA-079C-46CC-98B4-F0C821BE833E > > +... > > +cn:call('X.X.X.X.X.X.X.fn', {u}) > > +--- > > +- 84F7BCFA-079C-46CC-98B4-F0C821BE833E > > +... > > +cn:call('X.X.X.X:fn', {u}) > > +--- > > +- 84F7BCFA-079C-46CC-98B4-F0C821BE833E > > +... > > +box.schema.user.revoke('guest', 'execute', 'universe') > > +--- > > +... > > +cn:close() > > +--- > > +... > > +-- auth > > +cn = remote.connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123', wait_connected = true }) > > +--- > > +... > > +cn:is_connected() > > +--- > > +- false > > +... > > +cn.error > > +--- > > +- User 'netbox' is not found > > +... > > +cn.state > > +--- > > +- error > > +... > > diff --git a/test/box/net.box_incorrect_iterator_gh-841.test.lua b/test/box/net.box_incorrect_iterator_gh-841.test.lua > > new file mode 100644 > > index 000000000..cd431a57a > > --- /dev/null > > +++ b/test/box/net.box_incorrect_iterator_gh-841.test.lua > > @@ -0,0 +1,182 @@ > > +remote = require 'net.box' > > +fiber = require 'fiber' > > +test_run = require('test_run').new() > > +test_run:cmd("push filter ".."'\\.lua.*:[0-9]+: ' to '.lua...\"]:<line>: '") > > + > > +test_run:cmd("setopt delimiter ';'") > > +function x_select(cn, space_id, index_id, iterator, offset, limit, key, opts) > > + local ret = cn:_request('select', opts, nil, space_id, index_id, iterator, > > + offset, limit, key) > > + return ret > > +end > > +function x_fatal(cn) cn._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') end > > +test_run:cmd("setopt delimiter ''"); > > + > > +LISTEN = require('uri').parse(box.cfg.listen) > > +space = box.schema.space.create('net_box_test_space') > > +index = space:create_index('primary', { type = 'tree' }) > > + > > +function test_foo(a,b,c) return { {{ [a] = 1 }}, {{ [b] = 2 }}, c } end > > + > > +box.schema.user.grant('guest', 'read,write', 'space', 'net_box_test_space') > > +box.schema.user.grant('guest', 'execute', 'universe') > > + > > +cn = remote.connect(box.cfg.listen) > > + > > +x_select(cn, space.id, space.index.primary.id, box.index.EQ, 0, 0xFFFFFFFF, 123) > > +space:insert{123, 345} > > +x_select(cn, space.id, space.index.primary.id, box.index.EQ, 0, 0, 123) > > +x_select(cn, space.id, space.index.primary.id, box.index.EQ, 0, 1, 123) > > +x_select(cn, space.id, space.index.primary.id, box.index.EQ, 1, 1, 123) > > + > > +cn.space[space.id] ~= nil > > +cn.space.net_box_test_space ~= nil > > +cn.space.net_box_test_space ~= nil > > +cn.space.net_box_test_space.index ~= nil > > +cn.space.net_box_test_space.index.primary ~= nil > > +cn.space.net_box_test_space.index[space.index.primary.id] ~= nil > > + > > + > > +cn.space.net_box_test_space.index.primary:select(123) > > +cn.space.net_box_test_space.index.primary:select(123, { limit = 0 }) > > +cn.space.net_box_test_space.index.primary:select(nil, { limit = 1, }) > > +cn.space.net_box_test_space:insert{234, 1,2,3} > > +cn.space.net_box_test_space:insert{234, 1,2,3} > > +cn.space.net_box_test_space.insert{234, 1,2,3} > > + > > +cn.space.net_box_test_space:replace{354, 1,2,3} > > +cn.space.net_box_test_space:replace{354, 1,2,4} > > + > > +cn.space.net_box_test_space:select{123} > > +space:select({123}, { iterator = 'GE' }) > > +cn.space.net_box_test_space:select({123}, { iterator = 'GE' }) > > +cn.space.net_box_test_space:select({123}, { iterator = 'GT' }) > > +cn.space.net_box_test_space:select({123}, { iterator = 'GT', limit = 1 }) > > +cn.space.net_box_test_space:select({123}, { iterator = 'GT', limit = 1, offset = 1 }) > > + > > +cn.space.net_box_test_space:select{123} > > +cn.space.net_box_test_space:update({123}, { { '+', 2, 1 } }) > > +cn.space.net_box_test_space:update(123, { { '+', 2, 1 } }) > > +cn.space.net_box_test_space:select{123} > > + > > +cn.space.net_box_test_space:insert(cn.space.net_box_test_space:get{123}:update{ { '=', 1, 2 } }) > > +cn.space.net_box_test_space:delete{123} > > +cn.space.net_box_test_space:select{2} > > +cn.space.net_box_test_space:select({234}, { iterator = 'LT' }) > > + > > +cn.space.net_box_test_space:update({1}, { { '+', 2, 2 } }) > > + > > +cn.space.net_box_test_space:delete{1} > > +cn.space.net_box_test_space:delete{2} > > +cn.space.net_box_test_space:delete{2} > > + > > +-- test one-based indexing in splice operation (see update.test.lua) > > +cn.space.net_box_test_space:replace({10, 'abcde'}) > > +cn.space.net_box_test_space:update(10, {{':', 2, 0, 0, '!'}}) > > +cn.space.net_box_test_space:update(10, {{':', 2, 1, 0, '('}}) > > +cn.space.net_box_test_space:update(10, {{':', 2, 2, 0, '({'}}) > > +cn.space.net_box_test_space:update(10, {{':', 2, -1, 0, ')'}}) > > +cn.space.net_box_test_space:update(10, {{':', 2, -2, 0, '})'}}) > > +cn.space.net_box_test_space:delete{10} > > + > > +cn.space.net_box_test_space:select({}, { iterator = 'ALL' }) > > +-- gh-841: net.box uses incorrect iterator type for select with no arguments > > +cn.space.net_box_test_space:select() > > + > > +cn.space.net_box_test_space.index.primary:min() > > +cn.space.net_box_test_space.index.primary:min(354) > > +cn.space.net_box_test_space.index.primary:max() > > +cn.space.net_box_test_space.index.primary:max(234) > > +cn.space.net_box_test_space.index.primary:count() > > +cn.space.net_box_test_space.index.primary:count(354) > > + > > +cn.space.net_box_test_space:get(354) > > + > > +-- reconnects after errors > > + > > +box.schema.user.revoke('guest', 'execute', 'universe') > > +box.schema.func.create('test_foo') > > +box.schema.user.grant('guest', 'execute', 'function', 'test_foo') > > + > > +-- -- 1. no reconnect > > +x_fatal(cn) > > +cn.state > > +cn:ping() > > +cn:call('test_foo') > > +cn:wait_state('active') > > + > > +-- -- 2 reconnect > > +cn = remote.connect(LISTEN.host, LISTEN.service, { reconnect_after = .1 }) > > +cn.space ~= nil > > + > > +cn.space.net_box_test_space:select({}, { iterator = 'ALL' }) > > +x_fatal(cn) > > +cn:wait_connected() > > +cn:wait_state('active') > > +cn:wait_state({active=true}) > > +cn:ping() > > +cn.state > > +cn.space.net_box_test_space:select({}, { iterator = 'ALL' }) > > + > > +x_fatal(cn) > > +x_select(cn, space.id, 0, box.index.ALL, 0, 0xFFFFFFFF, {}) > > + > > +cn.state > > +cn:ping() > > + > > +-- -- dot-new-method > > + > > +cn1 = remote.new(LISTEN.host, LISTEN.service) > > +x_select(cn1, space.id, 0, box.index.ALL, 0, 0xFFFFFFF, {}) > > +cn1:close() > > +-- -- error while waiting for response > > +type(fiber.create(function() fiber.sleep(.5) x_fatal(cn) end)) > > +function pause() fiber.sleep(10) return true end > > + > > +box.schema.func.create('pause') > > +box.schema.user.grant('guest', 'execute', 'function', 'pause') > > +cn:call('pause') > > +cn:call('test_foo', {'a', 'b', 'c'}) > > +box.schema.func.drop('pause') > > + > > +-- call > > +remote.self:call('test_foo', {'a', 'b', 'c'}) > > +cn:call('test_foo', {'a', 'b', 'c'}) > > +box.schema.func.drop('test_foo') > > + > > +box.schema.func.create('long_rep') > > +box.schema.user.grant('guest', 'execute', 'function', 'long_rep') > > + > > +-- long replies > > +function long_rep() return { 1, string.rep('a', 5000) } end > > +res = cn:call('long_rep') > > +res[1] == 1 > > +res[2] == string.rep('a', 5000) > > + > > +function long_rep() return { 1, string.rep('a', 50000) } end > > +res = cn:call('long_rep') > > +res[1] == 1 > > +res[2] == string.rep('a', 50000) > > + > > +box.schema.func.drop('long_rep') > > + > > +-- a.b.c.d > > +u = '84F7BCFA-079C-46CC-98B4-F0C821BE833E' > > +X = {} > > +X.X = X > > +function X.fn(x,y) return y or x end > > +box.schema.user.grant('guest', 'execute', 'universe') > > +cn:close() > > +cn = remote.connect(LISTEN.host, LISTEN.service) > > +cn:call('X.fn', {u}) > > +cn:call('X.X.X.X.X.X.X.fn', {u}) > > +cn:call('X.X.X.X:fn', {u}) > > +box.schema.user.revoke('guest', 'execute', 'universe') > > +cn:close() > > + > > +-- auth > > + > > +cn = remote.connect(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123', wait_connected = true }) > > +cn:is_connected() > > +cn.error > > +cn.state > > diff --git a/test/box/net.box_index_unique_flag_gh-4091.result b/test/box/net.box_index_unique_flag_gh-4091.result > > new file mode 100644 > > index 000000000..a72c32c74 > > --- /dev/null > > +++ b/test/box/net.box_index_unique_flag_gh-4091.result > > @@ -0,0 +1,28 @@ > > +net = require('net.box') > > +--- > > +... > > +space = box.schema.space.create('test', {format={{name="id", type="unsigned"}}}) > > +--- > > +... > > +_ = box.space.test:create_index('primary') > > +--- > > +... > > +box.schema.user.grant('guest', 'read', 'space', 'test') > > +--- > > +... > > +c = net.connect(box.cfg.listen) > > +--- > > +... > > +-- > > +-- gh-4091: index unique flag is always false. > > +-- > > +c.space.test.index.primary.unique > > +--- > > +- true > > +... > > +c:close() > > +--- > > +... > > +space:drop() > > +--- > > +... > > diff --git a/test/box/net.box_index_unique_flag_gh-4091.test.lua b/test/box/net.box_index_unique_flag_gh-4091.test.lua > > new file mode 100644 > > index 000000000..7027b1e33 > > --- /dev/null > > +++ b/test/box/net.box_index_unique_flag_gh-4091.test.lua > > @@ -0,0 +1,15 @@ > > +net = require('net.box') > > + > > +space = box.schema.space.create('test', {format={{name="id", type="unsigned"}}}) > > +_ = box.space.test:create_index('primary') > > +box.schema.user.grant('guest', 'read', 'space', 'test') > > + > > +c = net.connect(box.cfg.listen) > > + > > +-- > > +-- gh-4091: index unique flag is always false. > > +-- > > +c.space.test.index.primary.unique > > + > > +c:close() > > +space:drop() > > diff --git a/test/box/net.box_iproto_hangs_gh-3464.result b/test/box/net.box_iproto_hangs_gh-3464.result > > new file mode 100644 > > index 000000000..d425bf78c > > --- /dev/null > > +++ b/test/box/net.box_iproto_hangs_gh-3464.result > > @@ -0,0 +1,31 @@ > > +msgpack = require 'msgpack' > > +--- > > +... > > +test_run = require('test_run').new() > > +--- > > +... > > +net = require('net.box') > > +--- > > +... > > +-- > > +-- gh-3464: iproto hangs in 100% CPU when too big packet size > > +-- is received due to size_t overflow. > > +-- > > +c = net:connect(box.cfg.listen) > > +--- > > +... > > +data = msgpack.encode(18400000000000000000)..'aaaaaaa' > > +--- > > +... > > +c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, data) > > +--- > > +- null > > +- Peer closed > > +... > > +c:close() > > +--- > > +... > > +test_run:grep_log('default', 'too big packet size in the header') ~= nil > > +--- > > +- true > > +... > > diff --git a/test/box/net.box_iproto_hangs_gh-3464.test.lua b/test/box/net.box_iproto_hangs_gh-3464.test.lua > > new file mode 100644 > > index 000000000..77551e415 > > --- /dev/null > > +++ b/test/box/net.box_iproto_hangs_gh-3464.test.lua > > @@ -0,0 +1,13 @@ > > +msgpack = require 'msgpack' > > +test_run = require('test_run').new() > > +net = require('net.box') > > + > > +-- > > +-- gh-3464: iproto hangs in 100% CPU when too big packet size > > +-- is received due to size_t overflow. > > +-- > > +c = net:connect(box.cfg.listen) > > +data = msgpack.encode(18400000000000000000)..'aaaaaaa' > > +c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, data) > > +c:close() > > +test_run:grep_log('default', 'too big packet size in the header') ~= nil > > diff --git a/test/box/net.box_is_nullable_gh-3256.result b/test/box/net.box_is_nullable_gh-3256.result > > new file mode 100644 > > index 000000000..5d6dc4b94 > > --- /dev/null > > +++ b/test/box/net.box_is_nullable_gh-3256.result > > @@ -0,0 +1,97 @@ > > +net = require('net.box') > > +--- > > +... > > +-- > > +-- gh-3256 net.box is_nullable and collation options output > > +-- > > +space = box.schema.create_space('test') > > +--- > > +... > > +box.schema.user.grant('guest', 'read', 'space', 'test') > > +--- > > +... > > +_ = space:create_index('pk') > > +--- > > +... > > +_ = space:create_index('sk', {parts = {{2, 'unsigned', is_nullable = true}}}) > > +--- > > +... > > +c = net:connect(box.cfg.listen) > > +--- > > +... > > +c.space.test.index.sk.parts > > +--- > > +- - type: unsigned > > + is_nullable: true > > + fieldno: 2 > > +... > > +space:drop() > > +--- > > +... > > +space = box.schema.create_space('test') > > +--- > > +... > > +c:close() > > +--- > > +... > > +box.schema.user.grant('guest', 'read', 'space', 'test') > > +--- > > +... > > +c = net:connect(box.cfg.listen) > > +--- > > +... > > +box.internal.collation.create('test', 'ICU', 'ru-RU') > > +--- > > +... > > +collation_id = box.internal.collation.id_by_name('test') > > +--- > > +... > > +_ = space:create_index('sk', { type = 'tree', parts = {{1, 'str', collation = 'test'}}, unique = true }) > > +--- > > +... > > +c:reload_schema() > > +--- > > +... > > +parts = c.space.test.index.sk.parts > > +--- > > +... > > +#parts == 1 > > +--- > > +- true > > +... > > +parts[1].fieldno == 1 > > +--- > > +- true > > +... > > +parts[1].type == 'string' > > +--- > > +- true > > +... > > +parts[1].is_nullable == false > > +--- > > +- true > > +... > > +if _TARANTOOL >= '2.2.1' then \ > > + return parts[1].collation == 'test' \ > > +else \ > > + return parts[1].collation_id == collation_id \ > > +end > > +--- > > +- true > > +... > > +c:close() > > +--- > > +... > > +box.internal.collation.drop('test') > > +--- > > +... > > +space:drop() > > +--- > > +... > > +c.state > > +--- > > +- closed > > +... > > +c = nil > > +--- > > +... > > diff --git a/test/box/net.box_is_nullable_gh-3256.test.lua b/test/box/net.box_is_nullable_gh-3256.test.lua > > new file mode 100644 > > index 000000000..3c5ee3971 > > --- /dev/null > > +++ b/test/box/net.box_is_nullable_gh-3256.test.lua > > @@ -0,0 +1,36 @@ > > +net = require('net.box') > > + > > +-- > > +-- gh-3256 net.box is_nullable and collation options output > > +-- > > +space = box.schema.create_space('test') > > +box.schema.user.grant('guest', 'read', 'space', 'test') > > +_ = space:create_index('pk') > > +_ = space:create_index('sk', {parts = {{2, 'unsigned', is_nullable = true}}}) > > +c = net:connect(box.cfg.listen) > > +c.space.test.index.sk.parts > > +space:drop() > > + > > +space = box.schema.create_space('test') > > +c:close() > > +box.schema.user.grant('guest', 'read', 'space', 'test') > > +c = net:connect(box.cfg.listen) > > +box.internal.collation.create('test', 'ICU', 'ru-RU') > > +collation_id = box.internal.collation.id_by_name('test') > > +_ = space:create_index('sk', { type = 'tree', parts = {{1, 'str', collation = 'test'}}, unique = true }) > > +c:reload_schema() > > +parts = c.space.test.index.sk.parts > > +#parts == 1 > > +parts[1].fieldno == 1 > > +parts[1].type == 'string' > > +parts[1].is_nullable == false > > +if _TARANTOOL >= '2.2.1' then \ > > + return parts[1].collation == 'test' \ > > +else \ > > + return parts[1].collation_id == collation_id \ > > +end > > +c:close() > > +box.internal.collation.drop('test') > > +space:drop() > > +c.state > > +c = nil > > diff --git a/test/box/net.box_leaks_gh-3629.result b/test/box/net.box_leaks_gh-3629.result > > new file mode 100644 > > index 000000000..4c6688bf2 > > --- /dev/null > > +++ b/test/box/net.box_leaks_gh-3629.result > > @@ -0,0 +1,51 @@ > > +fiber = require 'fiber' > > +--- > > +... > > +net = require('net.box') > > +--- > > +... > > +-- > > +-- gh-3629: netbox leaks when a connection is closed deliberately > > +-- and it has non-finished requests. > > +-- > > +ready = false > > +--- > > +... > > +ok = nil > > +--- > > +... > > +err = nil > > +--- > > +... > > +c = net:connect(box.cfg.listen) > > +--- > > +... > > +function do_long() while not ready do fiber.sleep(0.01) end end > > +--- > > +... > > +box.schema.func.create('do_long') > > +--- > > +... > > +box.schema.user.grant('guest', 'execute', 'function', 'do_long') > > +--- > > +... > > +f = fiber.create(function() ok, err = pcall(c.call, c, 'do_long') end) > > +--- > > +... > > +while f:status() ~= 'suspended' do fiber.sleep(0.01) end > > +--- > > +... > > +c:close() > > +--- > > +... > > +ready = true > > +--- > > +... > > +while not err do fiber.sleep(0.01) end > > +--- > > +... > > +ok, err > > +--- > > +- false > > +- Connection closed > > +... > > diff --git a/test/box/net.box_leaks_gh-3629.test.lua b/test/box/net.box_leaks_gh-3629.test.lua > > new file mode 100644 > > index 000000000..03b5a2327 > > --- /dev/null > > +++ b/test/box/net.box_leaks_gh-3629.test.lua > > @@ -0,0 +1,20 @@ > > +fiber = require 'fiber' > > +net = require('net.box') > > + > > +-- > > +-- gh-3629: netbox leaks when a connection is closed deliberately > > +-- and it has non-finished requests. > > +-- > > +ready = false > > +ok = nil > > +err = nil > > +c = net:connect(box.cfg.listen) > > +function do_long() while not ready do fiber.sleep(0.01) end end > > +box.schema.func.create('do_long') > > +box.schema.user.grant('guest', 'execute', 'function', 'do_long') > > +f = fiber.create(function() ok, err = pcall(c.call, c, 'do_long') end) > > +while f:status() ~= 'suspended' do fiber.sleep(0.01) end > > +c:close() > > +ready = true > > +while not err do fiber.sleep(0.01) end > > +ok, err > > diff --git a/test/box/net.box_log_corrupted_rows_gh-4040.result b/test/box/net.box_log_corrupted_rows_gh-4040.result > > new file mode 100644 > > index 000000000..603de0f13 > > --- /dev/null > > +++ b/test/box/net.box_log_corrupted_rows_gh-4040.result > > @@ -0,0 +1,72 @@ > > +test_run = require('test_run').new() > > +--- > > +... > > +socket = require('socket'); > > +--- > > +... > > +LISTEN = require('uri').parse(box.cfg.listen) > > +--- > > +... > > +test_run:cmd('create server connecter with script = "box/proxy.lua"') > > +--- > > +- true > > +... > > +-- > > +-- related to gh-4040: log corrupted rows > > +-- > > +log_level = box.cfg.log_level > > +--- > > +... > > +box.cfg{log_level=6} > > +--- > > +... > > +sock = socket.tcp_connect(LISTEN.host, LISTEN.service) > > +--- > > +... > > +sock:read(9) > > +--- > > +- Tarantool > > +... > > +-- we need to have a packet with correctly encoded length, > > +-- so that it bypasses iproto length check, but cannot be > > +-- decoded in xrow_header_decode > > +-- 0x3C = 60, sha1 digest is 20 bytes long > > +data = string.fromhex('3C'..string.rep(require('digest').sha1_hex('bcde'), 3)) > > +--- > > +... > > +sock:write(data) > > +--- > > +- 61 > > +... > > +sock:close() > > +--- > > +- true > > +... > > +test_run:wait_log('default', 'Got a corrupted row.*', nil, 10) > > +--- > > +- 'Got a corrupted row:' > > +... > > +test_run:wait_log('default', '00000000:.*', nil, 10) > > +--- > > +- '00000000: A3 02 D6 5A E4 D9 E7 68 A1 53 8D 53 60 5F 20 3F ' > > +... > > +test_run:wait_log('default', '00000010:.*', nil, 10) > > +--- > > +- '00000010: D8 E2 D6 E2 A3 02 D6 5A E4 D9 E7 68 A1 53 8D 53 ' > > +... > > +test_run:wait_log('default', '00000020:.*', nil, 10) > > +--- > > +- '00000020: 60 5F 20 3F D8 E2 D6 E2 A3 02 D6 5A E4 D9 E7 68 ' > > +... > > +test_run:wait_log('default', '00000030:.*', nil, 10) > > +--- > > +- '00000030: A1 53 8D 53 60 5F 20 3F D8 E2 D6 E2 ' > > +... > > +-- we expect nothing below, so don't wait > > +test_run:grep_log('default', '00000040:.*') > > +--- > > +- null > > +... > > +box.cfg{log_level=log_level} > > +--- > > +... > > diff --git a/test/box/net.box_log_corrupted_rows_gh-4040.test.lua b/test/box/net.box_log_corrupted_rows_gh-4040.test.lua > > new file mode 100644 > > index 000000000..a30b4a254 > > --- /dev/null > > +++ b/test/box/net.box_log_corrupted_rows_gh-4040.test.lua > > @@ -0,0 +1,31 @@ > > +test_run = require('test_run').new() > > +socket = require('socket'); > > + > > +LISTEN = require('uri').parse(box.cfg.listen) > > + > > +test_run:cmd('create server connecter with script = "box/proxy.lua"') > > + > > +-- > > +-- related to gh-4040: log corrupted rows > > +-- > > +log_level = box.cfg.log_level > > +box.cfg{log_level=6} > > +sock = socket.tcp_connect(LISTEN.host, LISTEN.service) > > +sock:read(9) > > +-- we need to have a packet with correctly encoded length, > > +-- so that it bypasses iproto length check, but cannot be > > +-- decoded in xrow_header_decode > > +-- 0x3C = 60, sha1 digest is 20 bytes long > > +data = string.fromhex('3C'..string.rep(require('digest').sha1_hex('bcde'), 3)) > > +sock:write(data) > > +sock:close() > > + > > +test_run:wait_log('default', 'Got a corrupted row.*', nil, 10) > > +test_run:wait_log('default', '00000000:.*', nil, 10) > > +test_run:wait_log('default', '00000010:.*', nil, 10) > > +test_run:wait_log('default', '00000020:.*', nil, 10) > > +test_run:wait_log('default', '00000030:.*', nil, 10) > > +-- we expect nothing below, so don't wait > > +test_run:grep_log('default', '00000040:.*') > > + > > +box.cfg{log_level=log_level} > > diff --git a/test/box/net.box_long-poll_input_gh-3400.result b/test/box/net.box_long-poll_input_gh-3400.result > > new file mode 100644 > > index 000000000..062bd563a > > --- /dev/null > > +++ b/test/box/net.box_long-poll_input_gh-3400.result > > @@ -0,0 +1,35 @@ > > +fiber = require 'fiber' > > +--- > > +... > > +net = require('net.box') > > +--- > > +... > > +-- > > +-- gh-3400: long-poll input discard must not touch event loop of > > +-- a closed connection. > > +-- > > +function long() fiber.yield() return 100 end > > +--- > > +... > > +c = net.connect(box.cfg.listen) > > +--- > > +... > > +c:ping() > > +--- > > +- true > > +... > > +-- Create batch of two requests. First request is sent to TX > > +-- thread, second one terminates connection. The preceeding > > +-- request discards input, and this operation must not trigger > > +-- new attempts to read any data - the connection is closed > > +-- already. > > +-- > > +f = fiber.create(c._transport.perform_request, nil, nil, false, 'call_17', nil, nil, nil, 'long', {}) c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') > > +--- > > +... > > +while f:status() ~= 'dead' do fiber.sleep(0.01) end > > +--- > > +... > > +c:close() > > +--- > > +... > > diff --git a/test/box/net.box_long-poll_input_gh-3400.test.lua b/test/box/net.box_long-poll_input_gh-3400.test.lua > > new file mode 100644 > > index 000000000..bc9db1e69 > > --- /dev/null > > +++ b/test/box/net.box_long-poll_input_gh-3400.test.lua > > @@ -0,0 +1,19 @@ > > +fiber = require 'fiber' > > +net = require('net.box') > > + > > +-- > > +-- gh-3400: long-poll input discard must not touch event loop of > > +-- a closed connection. > > +-- > > +function long() fiber.yield() return 100 end > > +c = net.connect(box.cfg.listen) > > +c:ping() > > +-- Create batch of two requests. First request is sent to TX > > +-- thread, second one terminates connection. The preceeding > > +-- request discards input, and this operation must not trigger > > +-- new attempts to read any data - the connection is closed > > +-- already. > > +-- > > +f = fiber.create(c._transport.perform_request, nil, nil, false, 'call_17', nil, nil, nil, 'long', {}) c._transport.perform_request(nil, nil, false, 'inject', nil, nil, nil, '\x80') > > +while f:status() ~= 'dead' do fiber.sleep(0.01) end > > +c:close() > > diff --git a/test/box/net.box_methods_gh-3107.result b/test/box/net.box_methods_gh-3107.result > > new file mode 100644 > > index 000000000..8ff69ebd6 > > --- /dev/null > > +++ b/test/box/net.box_methods_gh-3107.result > > @@ -0,0 +1,277 @@ > > +fiber = require 'fiber' > > +--- > > +... > > +net = require('net.box') > > +--- > > +... > > +-- > > +-- gh-3107: fiber-async netbox. > > +-- > > +cond = nil > > +--- > > +... > > +box.schema.func.create('long_function') > > +--- > > +... > > +box.schema.user.grant('guest', 'execute', 'function', 'long_function') > > +--- > > +... > > +function long_function(...) cond = fiber.cond() cond:wait() return ... end > > +--- > > +... > > +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end > > +--- > > +... > > +s = box.schema.create_space('test') > > +--- > > +... > > +pk = s:create_index('pk') > > +--- > > +... > > +s:replace{1} > > +--- > > +- [1] > > +... > > +s:replace{2} > > +--- > > +- [2] > > +... > > +s:replace{3} > > +--- > > +- [3] > > +... > > +s:replace{4} > > +--- > > +- [4] > > +... > > +c = net:connect(box.cfg.listen) > > +--- > > +... > > +-- > > +-- Ensure a request can be finalized from non-caller fibers. > > +-- > > +future = c:call('long_function', {1, 2, 3}, {is_async = true}) > > +--- > > +... > > +ret = {} > > +--- > > +... > > +count = 0 > > +--- > > +... > > +for i = 1, 10 do fiber.create(function() ret[i] = future:wait_result(1000) count = count + 1 end) end > > +--- > > +... > > +future:wait_result(0.01) -- Must fail on timeout. > > +--- > > +- null > > +- Timeout exceeded > > +... > > +finalize_long() > > +--- > > +... > > +while count ~= 10 do fiber.sleep(0.1) end > > +--- > > +... > > +ret > > +--- > > +- - &0 [1, 2, 3] > > + - *0 > > + - *0 > > + - *0 > > + - *0 > > + - *0 > > + - *0 > > + - *0 > > + - *0 > > + - *0 > > +... > > +-- > > +-- Test space methods. > > +-- > > +c:close() > > +--- > > +... > > +box.schema.user.grant('guest', 'read,write', 'space', 'test') > > +--- > > +... > > +c = net:connect(box.cfg.listen) > > +--- > > +... > > +future = c.space.test:select({1}, {is_async = true}) > > +--- > > +... > > +ret = future:wait_result(100) > > +--- > > +... > > +ret > > +--- > > +- - [1] > > +... > > +type(ret[1]) > > +--- > > +- cdata > > +... > > +future = c.space.test:insert({5}, {is_async = true}) > > +--- > > +... > > +future:wait_result(100) > > +--- > > +- [5] > > +... > > +s:get{5} > > +--- > > +- [5] > > +... > > +future = c.space.test:replace({6}, {is_async = true}) > > +--- > > +... > > +future:wait_result(100) > > +--- > > +- [6] > > +... > > +s:get{6} > > +--- > > +- [6] > > +... > > +future = c.space.test:delete({6}, {is_async = true}) > > +--- > > +... > > +future:wait_result(100) > > +--- > > +- [6] > > +... > > +s:get{6} > > +--- > > +... > > +future = c.space.test:update({5}, {{'=', 2, 5}}, {is_async = true}) > > +--- > > +... > > +future:wait_result(100) > > +--- > > +- [5, 5] > > +... > > +s:get{5} > > +--- > > +- [5, 5] > > +... > > +future = c.space.test:upsert({5}, {{'=', 2, 6}}, {is_async = true}) > > +--- > > +... > > +future:wait_result(100) > > +--- > > +- null > > +... > > +s:get{5} > > +--- > > +- [5, 6] > > +... > > +future = c.space.test:get({5}, {is_async = true}) > > +--- > > +... > > +future:wait_result(100) > > +--- > > +- [5, 6] > > +... > > +-- > > +-- Test index methods. > > +-- > > +future = c.space.test.index.pk:select({1}, {is_async = true}) > > +--- > > +... > > +future:wait_result(100) > > +--- > > +- - [1] > > +... > > +future = c.space.test.index.pk:get({2}, {is_async = true}) > > +--- > > +... > > +future:wait_result(100) > > +--- > > +- [2] > > +... > > +future = c.space.test.index.pk:min({}, {is_async = true}) > > +--- > > +... > > +future:wait_result(100) > > +--- > > +- [1] > > +... > > +future = c.space.test.index.pk:max({}, {is_async = true}) > > +--- > > +... > > +future:wait_result(100) > > +--- > > +- [5, 6] > > +... > > +c:close() > > +--- > > +... > > +box.schema.user.grant('guest', 'execute', 'universe') > > +--- > > +... > > +c = net:connect(box.cfg.listen) > > +--- > > +... > > +future = c.space.test.index.pk:count({3}, {is_async = true}) > > +--- > > +... > > +future:wait_result(100) > > +--- > > +- 1 > > +... > > +c:close() > > +--- > > +... > > +box.schema.user.revoke('guest', 'execute', 'universe') > > +--- > > +... > > +c = net:connect(box.cfg.listen) > > +--- > > +... > > +future = c.space.test.index.pk:delete({3}, {is_async = true}) > > +--- > > +... > > +future:wait_result(100) > > +--- > > +- [3] > > +... > > +s:get{3} > > +--- > > +... > > +future = c.space.test.index.pk:update({4}, {{'=', 2, 6}}, {is_async = true}) > > +--- > > +... > > +future:wait_result(100) > > +--- > > +- [4, 6] > > +... > > +s:get{4} > > +--- > > +- [4, 6] > > +... > > +-- > > +-- Test async errors. > > +-- > > +future = c.space.test:insert({1}, {is_async = true}) > > +--- > > +... > > +future:wait_result() > > +--- > > +- null > > +- Duplicate key exists in unique index 'pk' in space 'test' > > +... > > +future:result() > > +--- > > +- null > > +- Duplicate key exists in unique index 'pk' in space 'test' > > +... > > +box.schema.func.drop('long_function') > > +--- > > +... > > +c:close() > > +--- > > +... > > +s:drop() > > +--- > > +... > > diff --git a/test/box/net.box_methods_gh-3107.test.lua b/test/box/net.box_methods_gh-3107.test.lua > > new file mode 100644 > > index 000000000..364a72ed3 > > --- /dev/null > > +++ b/test/box/net.box_methods_gh-3107.test.lua > > @@ -0,0 +1,96 @@ > > +fiber = require 'fiber' > > +net = require('net.box') > > + > > +-- > > +-- gh-3107: fiber-async netbox. > > +-- > > +cond = nil > > +box.schema.func.create('long_function') > > +box.schema.user.grant('guest', 'execute', 'function', 'long_function') > > +function long_function(...) cond = fiber.cond() cond:wait() return ... end > > +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end > > +s = box.schema.create_space('test') > > +pk = s:create_index('pk') > > +s:replace{1} > > +s:replace{2} > > +s:replace{3} > > +s:replace{4} > > +c = net:connect(box.cfg.listen) > > + > > +-- > > +-- Ensure a request can be finalized from non-caller fibers. > > +-- > > +future = c:call('long_function', {1, 2, 3}, {is_async = true}) > > +ret = {} > > +count = 0 > > +for i = 1, 10 do fiber.create(function() ret[i] = future:wait_result(1000) count = count + 1 end) end > > +future:wait_result(0.01) -- Must fail on timeout. > > +finalize_long() > > +while count ~= 10 do fiber.sleep(0.1) end > > +ret > > + > > +-- > > +-- Test space methods. > > +-- > > +c:close() > > +box.schema.user.grant('guest', 'read,write', 'space', 'test') > > +c = net:connect(box.cfg.listen) > > +future = c.space.test:select({1}, {is_async = true}) > > +ret = future:wait_result(100) > > +ret > > +type(ret[1]) > > +future = c.space.test:insert({5}, {is_async = true}) > > +future:wait_result(100) > > +s:get{5} > > +future = c.space.test:replace({6}, {is_async = true}) > > +future:wait_result(100) > > +s:get{6} > > +future = c.space.test:delete({6}, {is_async = true}) > > +future:wait_result(100) > > +s:get{6} > > +future = c.space.test:update({5}, {{'=', 2, 5}}, {is_async = true}) > > +future:wait_result(100) > > +s:get{5} > > +future = c.space.test:upsert({5}, {{'=', 2, 6}}, {is_async = true}) > > +future:wait_result(100) > > +s:get{5} > > +future = c.space.test:get({5}, {is_async = true}) > > +future:wait_result(100) > > + > > +-- > > +-- Test index methods. > > +-- > > +future = c.space.test.index.pk:select({1}, {is_async = true}) > > +future:wait_result(100) > > +future = c.space.test.index.pk:get({2}, {is_async = true}) > > +future:wait_result(100) > > +future = c.space.test.index.pk:min({}, {is_async = true}) > > +future:wait_result(100) > > +future = c.space.test.index.pk:max({}, {is_async = true}) > > +future:wait_result(100) > > +c:close() > > +box.schema.user.grant('guest', 'execute', 'universe') > > +c = net:connect(box.cfg.listen) > > +future = c.space.test.index.pk:count({3}, {is_async = true}) > > +future:wait_result(100) > > +c:close() > > +box.schema.user.revoke('guest', 'execute', 'universe') > > +c = net:connect(box.cfg.listen) > > +future = c.space.test.index.pk:delete({3}, {is_async = true}) > > +future:wait_result(100) > > +s:get{3} > > +future = c.space.test.index.pk:update({4}, {{'=', 2, 6}}, {is_async = true}) > > +future:wait_result(100) > > +s:get{4} > > + > > +-- > > +-- Test async errors. > > +-- > > +future = c.space.test:insert({1}, {is_async = true}) > > +future:wait_result() > > +future:result() > > + > > +box.schema.func.drop('long_function') > > + > > +c:close() > > +s:drop() > > diff --git a/test/box/net.box_msgpack_gh-2195.result b/test/box/net.box_msgpack_gh-2195.result > > new file mode 100644 > > index 000000000..a4c851334 > > --- /dev/null > > +++ b/test/box/net.box_msgpack_gh-2195.result > > @@ -0,0 +1,527 @@ > > +msgpack = require 'msgpack' > > +--- > > +... > > +test_run = require('test_run').new() > > +--- > > +... > > +test_run:cmd("push filter ".."'\\.lua.*:[0-9]+: ' to '.lua...\"]:<line>: '") > > +--- > > +- true > > +... > > +net = require('net.box') > > +--- > > +... > > +-- CALL vs CALL_16 in connect options > > +function echo(...) return ... end > > +--- > > +... > > +box.schema.user.grant('guest', 'execute', 'universe') > > +--- > > +... > > +c = net.connect(box.cfg.listen) > > +--- > > +... > > +c:call('echo', {42}) > > +--- > > +- 42 > > +... > > +c:eval('return echo(...)', {42}) > > +--- > > +- 42 > > +... > > +-- invalid arguments > > +c:call('echo', 42) > > +--- > > +- error: 'builtin/box/net_box.lua..."]:<line>: Use remote:call(func_name, {arg1, arg2, ...}, > > + opts) instead of remote:call(func_name, arg1, arg2, ...)' > > +... > > +c:eval('return echo(...)', 42) > > +--- > > +- error: 'builtin/box/net_box.lua..."]:<line>: Use remote:eval(expression, {arg1, arg2, ...}, > > + opts) instead of remote:eval(expression, arg1, arg2, ...)' > > +... > > +c:close() > > +--- > > +... > > +c = net.connect(box.cfg.listen, {call_16 = true}) > > +--- > > +... > > +c:call('echo', 42) > > +--- > > +- - [42] > > +... > > +c:eval('return echo(...)', 42) > > +--- > > +- 42 > > +... > > +c:close() > > +--- > > +... > > +box.schema.user.revoke('guest', 'execute', 'universe') > > +--- > > +... > > +-- > > +-- gh-2195 export pure msgpack from net.box > > +-- > > +space = box.schema.space.create('test') > > +--- > > +... > > +_ = box.space.test:create_index('primary') > > +--- > > +... > > +box.schema.user.grant('guest', 'read,write', 'space', 'test') > > +--- > > +... > > +box.schema.user.grant('guest', 'execute', 'universe') > > +--- > > +... > > +c = net.connect(box.cfg.listen) > > +--- > > +... > > +ibuf = require('buffer').ibuf() > > +--- > > +... > > +c:ping() > > +--- > > +- true > > +... > > +c.space.test ~= nil > > +--- > > +- true > > +... > > +c.space.test:replace({1, 'hello'}) > > +--- > > +- [1, 'hello'] > > +... > > +-- replace > > +c.space.test:replace({2}, {buffer = ibuf}) > > +--- > > +- 9 > > +... > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +--- > > +... > > +result > > +--- > > +- {48: [[2]]} > > +... > > +-- replace + skip_header > > +c.space.test:replace({2}, {buffer = ibuf, skip_header = true}) > > +--- > > +- 7 > > +... > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +--- > > +... > > +result > > +--- > > +- [[2]] > > +... > > +-- insert > > +c.space.test:insert({3}, {buffer = ibuf}) > > +--- > > +- 9 > > +... > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +--- > > +... > > +result > > +--- > > +- {48: [[3]]} > > +... > > +-- insert + skip_header > > +_ = space:delete({3}) > > +--- > > +... > > +c.space.test:insert({3}, {buffer = ibuf, skip_header = true}) > > +--- > > +- 7 > > +... > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +--- > > +... > > +result > > +--- > > +- [[3]] > > +... > > +-- update > > +c.space.test:update({3}, {}, {buffer = ibuf}) > > +--- > > +- 9 > > +... > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +--- > > +... > > +result > > +--- > > +- {48: [[3]]} > > +... > > +c.space.test.index.primary:update({3}, {}, {buffer = ibuf}) > > +--- > > +- 9 > > +... > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +--- > > +... > > +result > > +--- > > +- {48: [[3]]} > > +... > > +-- update + skip_header > > +c.space.test:update({3}, {}, {buffer = ibuf, skip_header = true}) > > +--- > > +- 7 > > +... > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +--- > > +... > > +result > > +--- > > +- [[3]] > > +... > > +c.space.test.index.primary:update({3}, {}, {buffer = ibuf, skip_header = true}) > > +--- > > +- 7 > > +... > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +--- > > +... > > +result > > +--- > > +- [[3]] > > +... > > +-- upsert > > +c.space.test:upsert({4}, {}, {buffer = ibuf}) > > +--- > > +- 7 > > +... > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +--- > > +... > > +result > > +--- > > +- {48: []} > > +... > > +-- upsert + skip_header > > +c.space.test:upsert({4}, {}, {buffer = ibuf, skip_header = true}) > > +--- > > +- 5 > > +... > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +--- > > +... > > +result > > +--- > > +- [] > > +... > > +-- delete > > +c.space.test:upsert({4}, {}, {buffer = ibuf}) > > +--- > > +- 7 > > +... > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +--- > > +... > > +result > > +--- > > +- {48: []} > > +... > > +-- delete + skip_header > > +c.space.test:upsert({4}, {}, {buffer = ibuf, skip_header = true}) > > +--- > > +- 5 > > +... > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +--- > > +... > > +result > > +--- > > +- [] > > +... > > +-- select > > +c.space.test.index.primary:select({3}, {iterator = 'LE', buffer = ibuf}) > > +--- > > +- 19 > > +... > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +--- > > +... > > +result > > +--- > > +- {48: [[3], [2], [1, 'hello']]} > > +... > > +-- select + skip_header > > +c.space.test.index.primary:select({3}, {iterator = 'LE', buffer = ibuf, skip_header = true}) > > +--- > > +- 17 > > +... > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +--- > > +... > > +result > > +--- > > +- [[3], [2], [1, 'hello']] > > +... > > +-- select > > +len = c.space.test:select({}, {buffer = ibuf}) > > +--- > > +... > > +ibuf.rpos + len == ibuf.wpos > > +--- > > +- true > > +... > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +--- > > +... > > +ibuf.rpos == ibuf.wpos > > +--- > > +- true > > +... > > +len > > +--- > > +- 21 > > +... > > +result > > +--- > > +- {48: [[1, 'hello'], [2], [3], [4]]} > > +... > > +-- select + skip_header > > +len = c.space.test:select({}, {buffer = ibuf, skip_header = true}) > > +--- > > +... > > +ibuf.rpos + len == ibuf.wpos > > +--- > > +- true > > +... > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +--- > > +... > > +ibuf.rpos == ibuf.wpos > > +--- > > +- true > > +... > > +len > > +--- > > +- 19 > > +... > > +result > > +--- > > +- [[1, 'hello'], [2], [3], [4]] > > +... > > +-- call > > +c:call("echo", {1, 2, 3}, {buffer = ibuf}) > > +--- > > +- 10 > > +... > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +--- > > +... > > +result > > +--- > > +- {48: [1, 2, 3]} > > +... > > +c:call("echo", {}, {buffer = ibuf}) > > +--- > > +- 7 > > +... > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +--- > > +... > > +result > > +--- > > +- {48: []} > > +... > > +c:call("echo", nil, {buffer = ibuf}) > > +--- > > +- 7 > > +... > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +--- > > +... > > +result > > +--- > > +- {48: []} > > +... > > +-- call + skip_header > > +c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > > +--- > > +- 8 > > +... > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +--- > > +... > > +result > > +--- > > +- [1, 2, 3] > > +... > > +c:call("echo", {}, {buffer = ibuf, skip_header = true}) > > +--- > > +- 5 > > +... > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +--- > > +... > > +result > > +--- > > +- [] > > +... > > +c:call("echo", nil, {buffer = ibuf, skip_header = true}) > > +--- > > +- 5 > > +... > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +--- > > +... > > +result > > +--- > > +- [] > > +... > > +-- eval > > +c:eval("echo(...)", {1, 2, 3}, {buffer = ibuf}) > > +--- > > +- 7 > > +... > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +--- > > +... > > +result > > +--- > > +- {48: []} > > +... > > +c:eval("echo(...)", {}, {buffer = ibuf}) > > +--- > > +- 7 > > +... > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +--- > > +... > > +result > > +--- > > +- {48: []} > > +... > > +c:eval("echo(...)", nil, {buffer = ibuf}) > > +--- > > +- 7 > > +... > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +--- > > +... > > +result > > +--- > > +- {48: []} > > +... > > +-- eval + skip_header > > +c:eval("echo(...)", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > > +--- > > +- 5 > > +... > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +--- > > +... > > +result > > +--- > > +- [] > > +... > > +c:eval("echo(...)", {}, {buffer = ibuf, skip_header = true}) > > +--- > > +- 5 > > +... > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +--- > > +... > > +result > > +--- > > +- [] > > +... > > +c:eval("echo(...)", nil, {buffer = ibuf, skip_header = true}) > > +--- > > +- 5 > > +... > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +--- > > +... > > +result > > +--- > > +- [] > > +... > > +-- make several request into a buffer with skip_header, then read > > +-- results > > +c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > > +--- > > +- 8 > > +... > > +c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > > +--- > > +- 8 > > +... > > +c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > > +--- > > +- 8 > > +... > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +--- > > +... > > +result > > +--- > > +- [1, 2, 3] > > +... > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +--- > > +... > > +result > > +--- > > +- [1, 2, 3] > > +... > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +--- > > +... > > +result > > +--- > > +- [1, 2, 3] > > +... > > +-- unsupported methods > > +c.space.test:get({1}, { buffer = ibuf}) > > +--- > > +- error: 'builtin/box/net_box.lua..."]:<line>: index:get() doesn''t support `buffer` argument' > > +... > > +c.space.test.index.primary:min({}, { buffer = ibuf}) > > +--- > > +- error: 'builtin/box/net_box.lua..."]:<line>: index:min() doesn''t support `buffer` argument' > > +... > > +c.space.test.index.primary:max({}, { buffer = ibuf}) > > +--- > > +- error: 'builtin/box/net_box.lua..."]:<line>: index:max() doesn''t support `buffer` argument' > > +... > > +c.space.test.index.primary:count({}, { buffer = ibuf}) > > +--- > > +- error: 'builtin/box/net_box.lua..."]:<line>: index:count() doesn''t support `buffer` argument' > > +... > > +c.space.test.index.primary:get({1}, { buffer = ibuf}) > > +--- > > +- error: 'builtin/box/net_box.lua..."]:<line>: index:get() doesn''t support `buffer` argument' > > +... > > +-- error handling > > +rpos, wpos = ibuf.rpos, ibuf.wpos > > +--- > > +... > > +c.space.test:insert({1}, {buffer = ibuf}) > > +--- > > +- error: Duplicate key exists in unique index 'primary' in space 'test' > > +... > > +ibuf.rpos == rpos, ibuf.wpos == wpos > > +--- > > +- true > > +- true > > +... > > +ibuf = nil > > +--- > > +... > > +c:close() > > +--- > > +... > > +space:drop() > > +--- > > +... > > +box.schema.user.revoke('guest', 'execute', 'universe') > > +--- > > +... > > diff --git a/test/box/net.box_msgpack_gh-2195.test.lua b/test/box/net.box_msgpack_gh-2195.test.lua > > new file mode 100644 > > index 000000000..8c14b4b43 > > --- /dev/null > > +++ b/test/box/net.box_msgpack_gh-2195.test.lua > > @@ -0,0 +1,192 @@ > > +msgpack = require 'msgpack' > > +test_run = require('test_run').new() > > +test_run:cmd("push filter ".."'\\.lua.*:[0-9]+: ' to '.lua...\"]:<line>: '") > > +net = require('net.box') > > + > > +-- CALL vs CALL_16 in connect options > > +function echo(...) return ... end > > +box.schema.user.grant('guest', 'execute', 'universe') > > +c = net.connect(box.cfg.listen) > > +c:call('echo', {42}) > > +c:eval('return echo(...)', {42}) > > +-- invalid arguments > > +c:call('echo', 42) > > +c:eval('return echo(...)', 42) > > +c:close() > > +c = net.connect(box.cfg.listen, {call_16 = true}) > > +c:call('echo', 42) > > +c:eval('return echo(...)', 42) > > +c:close() > > +box.schema.user.revoke('guest', 'execute', 'universe') > > + > > +-- > > +-- gh-2195 export pure msgpack from net.box > > +-- > > + > > +space = box.schema.space.create('test') > > +_ = box.space.test:create_index('primary') > > +box.schema.user.grant('guest', 'read,write', 'space', 'test') > > +box.schema.user.grant('guest', 'execute', 'universe') > > +c = net.connect(box.cfg.listen) > > +ibuf = require('buffer').ibuf() > > + > > +c:ping() > > +c.space.test ~= nil > > + > > +c.space.test:replace({1, 'hello'}) > > + > > +-- replace > > +c.space.test:replace({2}, {buffer = ibuf}) > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +result > > + > > +-- replace + skip_header > > +c.space.test:replace({2}, {buffer = ibuf, skip_header = true}) > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +result > > + > > +-- insert > > +c.space.test:insert({3}, {buffer = ibuf}) > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +result > > + > > +-- insert + skip_header > > +_ = space:delete({3}) > > +c.space.test:insert({3}, {buffer = ibuf, skip_header = true}) > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +result > > + > > +-- update > > +c.space.test:update({3}, {}, {buffer = ibuf}) > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +result > > +c.space.test.index.primary:update({3}, {}, {buffer = ibuf}) > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +result > > + > > +-- update + skip_header > > +c.space.test:update({3}, {}, {buffer = ibuf, skip_header = true}) > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +result > > +c.space.test.index.primary:update({3}, {}, {buffer = ibuf, skip_header = true}) > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +result > > + > > +-- upsert > > +c.space.test:upsert({4}, {}, {buffer = ibuf}) > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +result > > + > > +-- upsert + skip_header > > +c.space.test:upsert({4}, {}, {buffer = ibuf, skip_header = true}) > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +result > > + > > +-- delete > > +c.space.test:upsert({4}, {}, {buffer = ibuf}) > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +result > > + > > +-- delete + skip_header > > +c.space.test:upsert({4}, {}, {buffer = ibuf, skip_header = true}) > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +result > > + > > +-- select > > +c.space.test.index.primary:select({3}, {iterator = 'LE', buffer = ibuf}) > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +result > > + > > +-- select + skip_header > > +c.space.test.index.primary:select({3}, {iterator = 'LE', buffer = ibuf, skip_header = true}) > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +result > > + > > +-- select > > +len = c.space.test:select({}, {buffer = ibuf}) > > +ibuf.rpos + len == ibuf.wpos > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +ibuf.rpos == ibuf.wpos > > +len > > +result > > + > > +-- select + skip_header > > +len = c.space.test:select({}, {buffer = ibuf, skip_header = true}) > > +ibuf.rpos + len == ibuf.wpos > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +ibuf.rpos == ibuf.wpos > > +len > > +result > > + > > +-- call > > +c:call("echo", {1, 2, 3}, {buffer = ibuf}) > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +result > > +c:call("echo", {}, {buffer = ibuf}) > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +result > > +c:call("echo", nil, {buffer = ibuf}) > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +result > > + > > +-- call + skip_header > > +c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +result > > +c:call("echo", {}, {buffer = ibuf, skip_header = true}) > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +result > > +c:call("echo", nil, {buffer = ibuf, skip_header = true}) > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +result > > + > > +-- eval > > +c:eval("echo(...)", {1, 2, 3}, {buffer = ibuf}) > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +result > > +c:eval("echo(...)", {}, {buffer = ibuf}) > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +result > > +c:eval("echo(...)", nil, {buffer = ibuf}) > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +result > > + > > +-- eval + skip_header > > +c:eval("echo(...)", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +result > > +c:eval("echo(...)", {}, {buffer = ibuf, skip_header = true}) > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +result > > +c:eval("echo(...)", nil, {buffer = ibuf, skip_header = true}) > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +result > > + > > +-- make several request into a buffer with skip_header, then read > > +-- results > > +c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > > +c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > > +c:call("echo", {1, 2, 3}, {buffer = ibuf, skip_header = true}) > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +result > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +result > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +result > > + > > +-- unsupported methods > > +c.space.test:get({1}, { buffer = ibuf}) > > +c.space.test.index.primary:min({}, { buffer = ibuf}) > > +c.space.test.index.primary:max({}, { buffer = ibuf}) > > +c.space.test.index.primary:count({}, { buffer = ibuf}) > > +c.space.test.index.primary:get({1}, { buffer = ibuf}) > > + > > +-- error handling > > +rpos, wpos = ibuf.rpos, ibuf.wpos > > +c.space.test:insert({1}, {buffer = ibuf}) > > +ibuf.rpos == rpos, ibuf.wpos == wpos > > + > > +ibuf = nil > > +c:close() > > +space:drop() > > +box.schema.user.revoke('guest', 'execute', 'universe') > > diff --git a/test/box/net.box_on_schema_reload-gh-1904.result b/test/box/net.box_on_schema_reload-gh-1904.result > > new file mode 100644 > > index 000000000..5029684bf > > --- /dev/null > > +++ b/test/box/net.box_on_schema_reload-gh-1904.result > > @@ -0,0 +1,102 @@ > > +fiber = require 'fiber' > > +--- > > +... > > +test_run = require('test_run').new() > > +--- > > +... > > +LISTEN = require('uri').parse(box.cfg.listen) > > +--- > > +... > > +space = box.schema.space.create('net_box_test_space') > > +--- > > +... > > +index = space:create_index('primary', { type = 'tree' }) > > +--- > > +... > > +box.schema.user.create('netbox', { password = 'test' }) > > +--- > > +... > > +box.schema.user.grant('netbox', 'read,write', 'space', 'net_box_test_space') > > +--- > > +... > > +box.schema.user.grant('netbox', 'execute', 'universe') > > +--- > > +... > > +net = require('net.box') > > +--- > > +... > > +-- gh-1904 net.box hangs in :close() if a fiber was cancelled > > +-- while blocked in :_wait_state() in :_request() > > +options = {user = 'netbox', password = 'badpass', wait_connected = false, reconnect_after = 0.01} > > +--- > > +... > > +c = net:new(box.cfg.listen, options) > > +--- > > +... > > +f = fiber.create(function() c:call("") end) > > +--- > > +... > > +fiber.sleep(0.01) > > +--- > > +... > > +f:cancel(); c:close() > > +--- > > +... > > +box.schema.user.grant('guest', 'read', 'space', '_schema') > > +--- > > +... > > +-- check for on_schema_reload callback > > +test_run:cmd("setopt delimiter ';'") > > +--- > > +- true > > +... > > +do > > + local a = 0 > > + function osr_cb() > > + a = a + 1 > > + end > > + local con = net.new(box.cfg.listen, { > > + wait_connected = false > > + }) > > + con:on_schema_reload(osr_cb) > > + con:wait_connected() > > + con.space._schema:select{} > > + box.schema.space.create('misisipi') > > + box.space.misisipi:drop() > > + con.space._schema:select{} > > + con:close() > > + con = nil > > + > > + return a > > +end; > > +--- > > +- 2 > > +... > > +do > > + local a = 0 > > + function osr_cb() > > + a = a + 1 > > + end > > + local con = net.new(box.cfg.listen, { > > + wait_connected = true > > + }) > > + con:on_schema_reload(osr_cb) > > + con.space._schema:select{} > > + box.schema.space.create('misisipi') > > + box.space.misisipi:drop() > > + con.space._schema:select{} > > + con:close() > > + con = nil > > + > > + return a > > +end; > > +--- > > +- 1 > > +... > > +test_run:cmd("setopt delimiter ''"); > > +--- > > +- true > > +... > > +box.schema.user.revoke('guest', 'read', 'space', '_schema') > > +--- > > +... > > diff --git a/test/box/net.box_on_schema_reload-gh-1904.test.lua b/test/box/net.box_on_schema_reload-gh-1904.test.lua > > new file mode 100644 > > index 000000000..eeb9def65 > > --- /dev/null > > +++ b/test/box/net.box_on_schema_reload-gh-1904.test.lua > > @@ -0,0 +1,65 @@ > > +fiber = require 'fiber' > > +test_run = require('test_run').new() > > + > > +LISTEN = require('uri').parse(box.cfg.listen) > > +space = box.schema.space.create('net_box_test_space') > > +index = space:create_index('primary', { type = 'tree' }) > > + > > +box.schema.user.create('netbox', { password = 'test' }) > > +box.schema.user.grant('netbox', 'read,write', 'space', 'net_box_test_space') > > +box.schema.user.grant('netbox', 'execute', 'universe') > > + > > +net = require('net.box') > > + > > +-- gh-1904 net.box hangs in :close() if a fiber was cancelled > > +-- while blocked in :_wait_state() in :_request() > > +options = {user = 'netbox', password = 'badpass', wait_connected = false, reconnect_after = 0.01} > > +c = net:new(box.cfg.listen, options) > > +f = fiber.create(function() c:call("") end) > > +fiber.sleep(0.01) > > +f:cancel(); c:close() > > + > > +box.schema.user.grant('guest', 'read', 'space', '_schema') > > + > > +-- check for on_schema_reload callback > > +test_run:cmd("setopt delimiter ';'") > > +do > > + local a = 0 > > + function osr_cb() > > + a = a + 1 > > + end > > + local con = net.new(box.cfg.listen, { > > + wait_connected = false > > + }) > > + con:on_schema_reload(osr_cb) > > + con:wait_connected() > > + con.space._schema:select{} > > + box.schema.space.create('misisipi') > > + box.space.misisipi:drop() > > + con.space._schema:select{} > > + con:close() > > + con = nil > > + > > + return a > > +end; > > +do > > + local a = 0 > > + function osr_cb() > > + a = a + 1 > > + end > > + local con = net.new(box.cfg.listen, { > > + wait_connected = true > > + }) > > + con:on_schema_reload(osr_cb) > > + con.space._schema:select{} > > + box.schema.space.create('misisipi') > > + box.space.misisipi:drop() > > + con.space._schema:select{} > > + con:close() > > + con = nil > > + > > + return a > > +end; > > +test_run:cmd("setopt delimiter ''"); > > + > > +box.schema.user.revoke('guest', 'read', 'space', '_schema') > > diff --git a/test/box/net.box_password_gh-1545.result b/test/box/net.box_password_gh-1545.result > > new file mode 100644 > > index 000000000..984084cae > > --- /dev/null > > +++ b/test/box/net.box_password_gh-1545.result > > @@ -0,0 +1,28 @@ > > +remote = require 'net.box' > > +--- > > +... > > +LISTEN = require('uri').parse(box.cfg.listen) > > +--- > > +... > > +-- #1545 empty password > > +cn = remote.connect(LISTEN.host, LISTEN.service, { user = 'test' }) > > +--- > > +... > > +cn ~= nil > > +--- > > +- true > > +... > > +cn:close() > > +--- > > +... > > +cn = remote.connect(LISTEN.host, LISTEN.service, { password = 'test' }) > > +--- > > +- error: 'net.box: user is not defined' > > +... > > +cn ~= nil > > +--- > > +- true > > +... > > +cn:close() > > +--- > > +... > > diff --git a/test/box/net.box_password_gh-1545.test.lua b/test/box/net.box_password_gh-1545.test.lua > > new file mode 100644 > > index 000000000..86d496432 > > --- /dev/null > > +++ b/test/box/net.box_password_gh-1545.test.lua > > @@ -0,0 +1,10 @@ > > +remote = require 'net.box' > > +LISTEN = require('uri').parse(box.cfg.listen) > > + > > +-- #1545 empty password > > +cn = remote.connect(LISTEN.host, LISTEN.service, { user = 'test' }) > > +cn ~= nil > > +cn:close() > > +cn = remote.connect(LISTEN.host, LISTEN.service, { password = 'test' }) > > +cn ~= nil > > +cn:close() > > diff --git a/test/box/net.box_permissions.result b/test/box/net.box_permissions.result > > new file mode 100644 > > index 000000000..04729dccb > > --- /dev/null > > +++ b/test/box/net.box_permissions.result > > @@ -0,0 +1,186 @@ > > +remote = require 'net.box' > > +--- > > +... > > +fiber = require 'fiber' > > +--- > > +... > > +log = require 'log' > > +--- > > +... > > +LISTEN = require('uri').parse(box.cfg.listen) > > +--- > > +... > > +space = box.schema.space.create('net_box_test_space') > > +--- > > +... > > +index = space:create_index('primary', { type = 'tree' }) > > +--- > > +... > > +-- low level connection > > +log.info("create connection") > > +--- > > +... > > +cn = remote.connect(LISTEN.host, LISTEN.service) > > +--- > > +... > > +log.info("state is %s", cn.state) > > +--- > > +... > > +cn:ping() > > +--- > > +- true > > +... > > +log.info("ping is done") > > +--- > > +... > > +cn:ping() > > +--- > > +- true > > +... > > +log.info("ping is done") > > +--- > > +... > > +cn:ping() > > +--- > > +- true > > +... > > +-- check permissions > > +cn:call('unexists_procedure') > > +--- > > +- error: Execute access to function 'unexists_procedure' is denied for user 'guest' > > +... > > +function test_foo(a,b,c) return { {{ [a] = 1 }}, {{ [b] = 2 }}, c } end > > +--- > > +... > > +cn:call('test_foo', {'a', 'b', 'c'}) > > +--- > > +- error: Execute access to function 'test_foo' is denied for user 'guest' > > +... > > +cn:eval('return 2+2') > > +--- > > +- error: Execute access to universe '' is denied for user 'guest' > > +... > > +cn:close() > > +--- > > +... > > +-- connect and call without usage access > > +box.schema.user.grant('guest','execute','universe') > > +--- > > +... > > +box.schema.user.revoke('guest','usage','universe') > > +--- > > +... > > +box.session.su("guest") > > +--- > > +... > > +cn = remote.connect(LISTEN.host, LISTEN.service) > > +--- > > +... > > +cn:call('test_foo', {'a', 'b', 'c'}) > > +--- > > +- error: Usage access to universe '' is denied for user 'guest' > > +... > > +box.session.su("admin") > > +--- > > +... > > +box.schema.user.grant('guest','usage','universe') > > +--- > > +... > > +cn:close() > > +--- > > +... > > +cn = remote.connect(box.cfg.listen) > > +--- > > +... > > +cn:call('unexists_procedure') > > +--- > > +- error: Procedure 'unexists_procedure' is not defined > > +... > > +cn:call('test_foo', {'a', 'b', 'c'}) > > +--- > > +- [[{'a': 1}], [{'b': 2}], 'c'] > > +... > > +cn:call(nil, {'a', 'b', 'c'}) > > +--- > > +- error: Procedure 'nil' is not defined > > +... > > +cn:eval('return 2+2') > > +--- > > +- 4 > > +... > > +cn:eval('return 1, 2, 3') > > +--- > > +- 1 > > +- 2 > > +- 3 > > +... > > +cn:eval('return ...', {1, 2, 3}) > > +--- > > +- 1 > > +- 2 > > +- 3 > > +... > > +cn:eval('return { k = "v1" }, true, { xx = 10, yy = 15 }, nil') > > +--- > > +- {'k': 'v1'} > > +- true > > +- {'yy': 15, 'xx': 10} > > +- null > > +... > > +cn:eval('return nil') > > +--- > > +- null > > +... > > +cn:eval('return') > > +--- > > +... > > +cn:eval('error("exception")') > > +--- > > +- error: 'eval:1: exception' > > +... > > +cn:eval('box.error(0)') > > +--- > > +- error: Unknown error > > +... > > +cn:eval('!invalid expression') > > +--- > > +- error: 'eval:1: unexpected symbol near ''!''' > > +... > > +-- box.commit() missing at return of CALL/EVAL > > +function no_commit() box.begin() fiber.sleep(0.001) end > > +--- > > +... > > +cn:call('no_commit') > > +--- > > +- error: Transaction is active at return from function > > +... > > +cn:eval('no_commit()') > > +--- > > +- error: Transaction is active at return from function > > +... > > +remote.self:eval('return 1+1, 2+2') > > +--- > > +- 2 > > +- 4 > > +... > > +remote.self:eval('return') > > +--- > > +... > > +remote.self:eval('error("exception")') > > +--- > > +- error: '[string "error("exception")"]:1: exception' > > +... > > +remote.self:eval('box.error(0)') > > +--- > > +- error: Unknown error > > +... > > +remote.self:eval('!invalid expression') > > +--- > > +- error: '[string "return !invalid expression"]:1: unexpected symbol near ''!''' > > +... > > +box.schema.user.revoke('guest', 'execute', 'universe') > > +--- > > +... > > +cn:close() > > +--- > > +... > > diff --git a/test/box/net.box_permissions.test.lua b/test/box/net.box_permissions.test.lua > > new file mode 100644 > > index 000000000..249604f64 > > --- /dev/null > > +++ b/test/box/net.box_permissions.test.lua > > @@ -0,0 +1,66 @@ > > +remote = require 'net.box' > > +fiber = require 'fiber' > > +log = require 'log' > > + > > +LISTEN = require('uri').parse(box.cfg.listen) > > +space = box.schema.space.create('net_box_test_space') > > +index = space:create_index('primary', { type = 'tree' }) > > + > > +-- low level connection > > +log.info("create connection") > > +cn = remote.connect(LISTEN.host, LISTEN.service) > > +log.info("state is %s", cn.state) > > + > > +cn:ping() > > +log.info("ping is done") > > +cn:ping() > > +log.info("ping is done") > > + > > + > > +cn:ping() > > + > > + > > +-- check permissions > > +cn:call('unexists_procedure') > > +function test_foo(a,b,c) return { {{ [a] = 1 }}, {{ [b] = 2 }}, c } end > > +cn:call('test_foo', {'a', 'b', 'c'}) > > +cn:eval('return 2+2') > > +cn:close() > > +-- connect and call without usage access > > +box.schema.user.grant('guest','execute','universe') > > +box.schema.user.revoke('guest','usage','universe') > > +box.session.su("guest") > > +cn = remote.connect(LISTEN.host, LISTEN.service) > > +cn:call('test_foo', {'a', 'b', 'c'}) > > +box.session.su("admin") > > +box.schema.user.grant('guest','usage','universe') > > +cn:close() > > +cn = remote.connect(box.cfg.listen) > > + > > +cn:call('unexists_procedure') > > +cn:call('test_foo', {'a', 'b', 'c'}) > > +cn:call(nil, {'a', 'b', 'c'}) > > +cn:eval('return 2+2') > > +cn:eval('return 1, 2, 3') > > +cn:eval('return ...', {1, 2, 3}) > > +cn:eval('return { k = "v1" }, true, { xx = 10, yy = 15 }, nil') > > +cn:eval('return nil') > > +cn:eval('return') > > +cn:eval('error("exception")') > > +cn:eval('box.error(0)') > > +cn:eval('!invalid expression') > > + > > +-- box.commit() missing at return of CALL/EVAL > > +function no_commit() box.begin() fiber.sleep(0.001) end > > +cn:call('no_commit') > > +cn:eval('no_commit()') > > + > > +remote.self:eval('return 1+1, 2+2') > > +remote.self:eval('return') > > +remote.self:eval('error("exception")') > > +remote.self:eval('box.error(0)') > > +remote.self:eval('!invalid expression') > > + > > +box.schema.user.revoke('guest', 'execute', 'universe') > > + > > +cn:close() > > diff --git a/test/box/net.box_pseudo_objects_gh-2401.result b/test/box/net.box_pseudo_objects_gh-2401.result > > new file mode 100644 > > index 000000000..46730368f > > --- /dev/null > > +++ b/test/box/net.box_pseudo_objects_gh-2401.result > > @@ -0,0 +1,55 @@ > > +test_run = require('test_run').new() > > +--- > > +... > > +net = require('net.box') > > +--- > > +... > > +test_run:cmd('create server connecter with script = "box/proxy.lua"') > > +--- > > +- true > > +... > > +-- > > +-- gh-2401 update pseudo objects not replace them > > +-- > > +space = box.schema.space.create('test') > > +--- > > +... > > +box.schema.user.grant('guest', 'read', 'space', 'test') > > +--- > > +... > > +c = net.connect(box.cfg.listen) > > +--- > > +... > > +cspace = c.space.test > > +--- > > +... > > +space.index.test_index == nil > > +--- > > +- true > > +... > > +cspace.index.test_index == nil > > +--- > > +- true > > +... > > +_ = space:create_index("test_index", {parts={1, 'string'}}) > > +--- > > +... > > +c:reload_schema() > > +--- > > +... > > +space.index.test_index ~= nil > > +--- > > +- true > > +... > > +cspace.index.test_index ~= nil > > +--- > > +- true > > +... > > +c.space.test.index.test_index ~= nil > > +--- > > +- true > > +... > > +-- cleanup > > +space:drop() > > +--- > > +... > > diff --git a/test/box/net.box_pseudo_objects_gh-2401.test.lua b/test/box/net.box_pseudo_objects_gh-2401.test.lua > > new file mode 100644 > > index 000000000..b9277ae94 > > --- /dev/null > > +++ b/test/box/net.box_pseudo_objects_gh-2401.test.lua > > @@ -0,0 +1,23 @@ > > +test_run = require('test_run').new() > > +net = require('net.box') > > + > > +test_run:cmd('create server connecter with script = "box/proxy.lua"') > > + > > +-- > > +-- gh-2401 update pseudo objects not replace them > > +-- > > +space = box.schema.space.create('test') > > +box.schema.user.grant('guest', 'read', 'space', 'test') > > +c = net.connect(box.cfg.listen) > > +cspace = c.space.test > > +space.index.test_index == nil > > +cspace.index.test_index == nil > > +_ = space:create_index("test_index", {parts={1, 'string'}}) > > +c:reload_schema() > > +space.index.test_index ~= nil > > +cspace.index.test_index ~= nil > > +c.space.test.index.test_index ~= nil > > + > > +-- cleanup > > + > > +space:drop() > > diff --git a/test/box/net.box_raw_response_gh-3107.result b/test/box/net.box_raw_response_gh-3107.result > > new file mode 100644 > > index 000000000..85fef9daf > > --- /dev/null > > +++ b/test/box/net.box_raw_response_gh-3107.result > > @@ -0,0 +1,123 @@ > > +fiber = require 'fiber' > > +--- > > +... > > +msgpack = require 'msgpack' > > +--- > > +... > > +net = require('net.box') > > +--- > > +... > > +-- > > +-- gh-3107: fiber-async netbox. > > +-- > > +cond = nil > > +--- > > +... > > +box.schema.func.create('long_function') > > +--- > > +... > > +box.schema.user.grant('guest', 'execute', 'function', 'long_function') > > +--- > > +... > > +function long_function(...) cond = fiber.cond() cond:wait() return ... end > > +--- > > +... > > +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end > > +--- > > +... > > +s = box.schema.create_space('test') > > +--- > > +... > > +pk = s:create_index('pk') > > +--- > > +... > > +s:replace{1} > > +--- > > +- [1] > > +... > > +s:replace{2} > > +--- > > +- [2] > > +... > > +s:replace{3} > > +--- > > +- [3] > > +... > > +s:replace{4} > > +--- > > +- [4] > > +... > > +c = net:connect(box.cfg.listen) > > +--- > > +... > > +-- > > +-- Ensure a request can be finalized from non-caller fibers. > > +-- > > +future = c:call('long_function', {1, 2, 3}, {is_async = true}) > > +--- > > +... > > +ret = {} > > +--- > > +... > > +count = 0 > > +--- > > +... > > +for i = 1, 10 do fiber.create(function() ret[i] = future:wait_result(1000) count = count + 1 end) end > > +--- > > +... > > +future:wait_result(0.01) -- Must fail on timeout. > > +--- > > +- null > > +- Timeout exceeded > > +... > > +finalize_long() > > +--- > > +... > > +while count ~= 10 do fiber.sleep(0.1) end > > +--- > > +... > > +ret > > +--- > > +- - &0 [1, 2, 3] > > + - *0 > > + - *0 > > + - *0 > > + - *0 > > + - *0 > > + - *0 > > + - *0 > > + - *0 > > + - *0 > > +... > > +-- > > +-- Test raw response getting. > > +-- > > +ibuf = require('buffer').ibuf() > > +--- > > +... > > +future = c:call('long_function', {1, 2, 3}, {is_async = true, buffer = ibuf}) > > +--- > > +... > > +finalize_long() > > +--- > > +... > > +future:wait_result(100) > > +--- > > +- 10 > > +... > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +--- > > +... > > +result > > +--- > > +- {48: [1, 2, 3]} > > +... > > +box.schema.func.drop('long_function') > > +--- > > +... > > +c:close() > > +--- > > +... > > +s:drop() > > +--- > > +... > > diff --git a/test/box/net.box_raw_response_gh-3107.test.lua b/test/box/net.box_raw_response_gh-3107.test.lua > > new file mode 100644 > > index 000000000..fa477d6d7 > > --- /dev/null > > +++ b/test/box/net.box_raw_response_gh-3107.test.lua > > @@ -0,0 +1,46 @@ > > +fiber = require 'fiber' > > +msgpack = require 'msgpack' > > +net = require('net.box') > > + > > +-- > > +-- gh-3107: fiber-async netbox. > > +-- > > +cond = nil > > +box.schema.func.create('long_function') > > +box.schema.user.grant('guest', 'execute', 'function', 'long_function') > > +function long_function(...) cond = fiber.cond() cond:wait() return ... end > > +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end > > +s = box.schema.create_space('test') > > +pk = s:create_index('pk') > > +s:replace{1} > > +s:replace{2} > > +s:replace{3} > > +s:replace{4} > > +c = net:connect(box.cfg.listen) > > + > > +-- > > +-- Ensure a request can be finalized from non-caller fibers. > > +-- > > +future = c:call('long_function', {1, 2, 3}, {is_async = true}) > > +ret = {} > > +count = 0 > > +for i = 1, 10 do fiber.create(function() ret[i] = future:wait_result(1000) count = count + 1 end) end > > +future:wait_result(0.01) -- Must fail on timeout. > > +finalize_long() > > +while count ~= 10 do fiber.sleep(0.1) end > > +ret > > + > > +-- > > +-- Test raw response getting. > > +-- > > +ibuf = require('buffer').ibuf() > > +future = c:call('long_function', {1, 2, 3}, {is_async = true, buffer = ibuf}) > > +finalize_long() > > +future:wait_result(100) > > +result, ibuf.rpos = msgpack.decode_unchecked(ibuf.rpos) > > +result > > + > > +box.schema.func.drop('long_function') > > + > > +c:close() > > +s:drop() > > diff --git a/test/box/net.box_readahead_gh-3958.result b/test/box/net.box_readahead_gh-3958.result > > new file mode 100644 > > index 000000000..fc2093531 > > --- /dev/null > > +++ b/test/box/net.box_readahead_gh-3958.result > > @@ -0,0 +1,55 @@ > > +test_run = require('test_run').new() > > +--- > > +... > > +net = require('net.box') > > +--- > > +... > > +-- > > +-- gh-3958 updating box.cfg.readahead doesn't affect existing connections. > > +-- > > +readahead = box.cfg.readahead > > +--- > > +... > > +box.cfg{readahead = 128} > > +--- > > +... > > +s = box.schema.space.create("test") > > +--- > > +... > > +_ = s:create_index("pk") > > +--- > > +... > > +box.schema.user.grant("guest", "read,write", "space", "test") > > +--- > > +... > > +-- connection is created with small readahead value, > > +-- make sure it is updated if box.cfg.readahead is changed. > > +c = net.connect(box.cfg.listen) > > +--- > > +... > > +box.cfg{readahead = 100 * 1024} > > +--- > > +... > > +box.error.injection.set("ERRINJ_WAL_DELAY", true) > > +--- > > +- ok > > +... > > +pad = string.rep('x', 8192) > > +--- > > +... > > +for i = 1, 5 do c.space.test:replace({i, pad}, {is_async = true}) end > > +--- > > +... > > +box.error.injection.set("ERRINJ_WAL_DELAY", false) > > +--- > > +- ok > > +... > > +test_run:wait_log('default', 'readahead limit is reached', 1024, 0.1) > > +--- > > +... > > +s:drop() > > +--- > > +... > > +box.cfg{readahead = readahead} > > +--- > > +... > > diff --git a/test/box/net.box_readahead_gh-3958.test.lua b/test/box/net.box_readahead_gh-3958.test.lua > > new file mode 100644 > > index 000000000..1e33a84cb > > --- /dev/null > > +++ b/test/box/net.box_readahead_gh-3958.test.lua > > @@ -0,0 +1,29 @@ > > +test_run = require('test_run').new() > > +net = require('net.box') > > + > > +-- > > +-- gh-3958 updating box.cfg.readahead doesn't affect existing connections. > > +-- > > +readahead = box.cfg.readahead > > + > > +box.cfg{readahead = 128} > > + > > +s = box.schema.space.create("test") > > +_ = s:create_index("pk") > > +box.schema.user.grant("guest", "read,write", "space", "test") > > + > > +-- connection is created with small readahead value, > > +-- make sure it is updated if box.cfg.readahead is changed. > > +c = net.connect(box.cfg.listen) > > + > > +box.cfg{readahead = 100 * 1024} > > + > > +box.error.injection.set("ERRINJ_WAL_DELAY", true) > > +pad = string.rep('x', 8192) > > +for i = 1, 5 do c.space.test:replace({i, pad}, {is_async = true}) end > > +box.error.injection.set("ERRINJ_WAL_DELAY", false) > > + > > +test_run:wait_log('default', 'readahead limit is reached', 1024, 0.1) > > + > > +s:drop() > > +box.cfg{readahead = readahead} > > diff --git a/test/box/net.box_reconnect_after.result b/test/box/net.box_reconnect_after.result > > new file mode 100644 > > index 000000000..a75f9dc5c > > --- /dev/null > > +++ b/test/box/net.box_reconnect_after.result > > @@ -0,0 +1,32 @@ > > +fiber = require 'fiber' > > +--- > > +... > > +net = require('net.box') > > +--- > > +... > > +box.schema.user.grant('guest', 'execute', 'universe') > > +--- > > +... > > +-- > > +-- Test a case, when netbox can not connect first time, but > > +-- reconnect_after is set. > > +-- > > +c = net.connect('localhost:33333', {reconnect_after = 0.1, wait_connected = false}) > > +--- > > +... > > +while c.state ~= 'error_reconnect' do fiber.sleep(0.01) end > > +--- > > +... > > +c:close() > > +--- > > +... > > +box.schema.user.revoke('guest', 'execute', 'universe') > > +--- > > +... > > +c.state > > +--- > > +- closed > > +... > > +c = nil > > +--- > > +... > > diff --git a/test/box/net.box_reconnect_after.test.lua b/test/box/net.box_reconnect_after.test.lua > > new file mode 100644 > > index 000000000..8ad870475 > > --- /dev/null > > +++ b/test/box/net.box_reconnect_after.test.lua > > @@ -0,0 +1,16 @@ > > +fiber = require 'fiber' > > +net = require('net.box') > > + > > +box.schema.user.grant('guest', 'execute', 'universe') > > + > > +-- > > +-- Test a case, when netbox can not connect first time, but > > +-- reconnect_after is set. > > +-- > > +c = net.connect('localhost:33333', {reconnect_after = 0.1, wait_connected = false}) > > +while c.state ~= 'error_reconnect' do fiber.sleep(0.01) end > > +c:close() > > + > > +box.schema.user.revoke('guest', 'execute', 'universe') > > +c.state > > +c = nil > > diff --git a/test/box/net.box_reconnect_after_gh-3164.result b/test/box/net.box_reconnect_after_gh-3164.result > > new file mode 100644 > > index 000000000..216ce0366 > > --- /dev/null > > +++ b/test/box/net.box_reconnect_after_gh-3164.result > > @@ -0,0 +1,119 @@ > > +fiber = require 'fiber' > > +--- > > +... > > +log = require 'log' > > +--- > > +... > > +test_run = require('test_run').new() > > +--- > > +... > > +net = require('net.box') > > +--- > > +... > > +test_run:cmd('create server connecter with script = "box/proxy.lua"') > > +--- > > +- true > > +... > > +-- > > +-- gh-3164: netbox connection is not closed and garbage collected > > +-- ever, if reconnect_after is set. > > +-- > > +test_run:cmd('start server connecter') > > +--- > > +- true > > +... > > +test_run:cmd("set variable connect_to to 'connecter.listen'") > > +--- > > +- true > > +... > > +weak = setmetatable({}, {__mode = 'v'}) > > +--- > > +... > > +-- Create strong and weak reference. Weak is valid until strong > > +-- is valid too. > > +strong = net.connect(connect_to, {reconnect_after = 0.1}) > > +--- > > +... > > +weak.c = strong > > +--- > > +... > > +weak.c:ping() > > +--- > > +- true > > +... > > +test_run:cmd('stop server connecter') > > +--- > > +- true > > +... > > +test_run:cmd('cleanup server connecter') > > +--- > > +- true > > +... > > +-- Check the connection tries to reconnect at least two times. > > +-- 'Cannot assign requested address' is the crutch for running the > > +-- tests in a docker. This error emits instead of > > +-- 'Connection refused' inside a docker. > > +old_log_level = box.cfg.log_level > > +--- > > +... > > +box.cfg{log_level = 6} > > +--- > > +... > > +log.info(string.rep('a', 1000)) > > +--- > > +... > > +test_run:cmd("setopt delimiter ';'") > > +--- > > +- true > > +... > > +while test_run:grep_log('default', 'Network is unreachable', 1000) == nil and > > + test_run:grep_log('default', 'Connection refused', 1000) == nil and > > + test_run:grep_log('default', 'Cannot assign requested address', 1000) == nil do > > + fiber.sleep(0.1) > > +end; > > +--- > > +... > > +log.info(string.rep('a', 1000)); > > +--- > > +... > > +while test_run:grep_log('default', 'Network is unreachable', 1000) == nil and > > + test_run:grep_log('default', 'Connection refused', 1000) == nil and > > + test_run:grep_log('default', 'Cannot assign requested address', 1000) == nil do > > + fiber.sleep(0.1) > > +end; > > +--- > > +... > > +test_run:cmd("setopt delimiter ''"); > > +--- > > +- true > > +... > > +box.cfg{log_level = old_log_level} > > +--- > > +... > > +collectgarbage('collect') > > +--- > > +- 0 > > +... > > +strong.state > > +--- > > +- error_reconnect > > +... > > +strong == weak.c > > +--- > > +- true > > +... > > +-- Remove single strong reference. Now connection must be garbage > > +-- collected. > > +strong = nil > > +--- > > +... > > +collectgarbage('collect') > > +--- > > +- 0 > > +... > > +-- Now weak.c is null, because it was weak reference, and the > > +-- connection is deleted by 'collect'. > > +weak.c > > +--- > > +- null > > +... > > diff --git a/test/box/net.box_reconnect_after_gh-3164.test.lua b/test/box/net.box_reconnect_after_gh-3164.test.lua > > new file mode 100644 > > index 000000000..dc2747080 > > --- /dev/null > > +++ b/test/box/net.box_reconnect_after_gh-3164.test.lua > > @@ -0,0 +1,52 @@ > > +fiber = require 'fiber' > > +log = require 'log' > > +test_run = require('test_run').new() > > +net = require('net.box') > > + > > +test_run:cmd('create server connecter with script = "box/proxy.lua"') > > + > > +-- > > +-- gh-3164: netbox connection is not closed and garbage collected > > +-- ever, if reconnect_after is set. > > +-- > > +test_run:cmd('start server connecter') > > +test_run:cmd("set variable connect_to to 'connecter.listen'") > > +weak = setmetatable({}, {__mode = 'v'}) > > +-- Create strong and weak reference. Weak is valid until strong > > +-- is valid too. > > +strong = net.connect(connect_to, {reconnect_after = 0.1}) > > +weak.c = strong > > +weak.c:ping() > > +test_run:cmd('stop server connecter') > > +test_run:cmd('cleanup server connecter') > > +-- Check the connection tries to reconnect at least two times. > > +-- 'Cannot assign requested address' is the crutch for running the > > +-- tests in a docker. This error emits instead of > > +-- 'Connection refused' inside a docker. > > +old_log_level = box.cfg.log_level > > +box.cfg{log_level = 6} > > +log.info(string.rep('a', 1000)) > > +test_run:cmd("setopt delimiter ';'") > > +while test_run:grep_log('default', 'Network is unreachable', 1000) == nil and > > + test_run:grep_log('default', 'Connection refused', 1000) == nil and > > + test_run:grep_log('default', 'Cannot assign requested address', 1000) == nil do > > + fiber.sleep(0.1) > > +end; > > +log.info(string.rep('a', 1000)); > > +while test_run:grep_log('default', 'Network is unreachable', 1000) == nil and > > + test_run:grep_log('default', 'Connection refused', 1000) == nil and > > + test_run:grep_log('default', 'Cannot assign requested address', 1000) == nil do > > + fiber.sleep(0.1) > > +end; > > +test_run:cmd("setopt delimiter ''"); > > +box.cfg{log_level = old_log_level} > > +collectgarbage('collect') > > +strong.state > > +strong == weak.c > > +-- Remove single strong reference. Now connection must be garbage > > +-- collected. > > +strong = nil > > +collectgarbage('collect') > > +-- Now weak.c is null, because it was weak reference, and the > > +-- connection is deleted by 'collect'. > > +weak.c > > diff --git a/test/box/net.box_reload_schema_gh-636.result b/test/box/net.box_reload_schema_gh-636.result > > new file mode 100644 > > index 000000000..43e8e8b29 > > --- /dev/null > > +++ b/test/box/net.box_reload_schema_gh-636.result > > @@ -0,0 +1,108 @@ > > +remote = require 'net.box' > > +--- > > +... > > +fiber = require 'fiber' > > +--- > > +... > > +test_run = require('test_run').new() > > +--- > > +... > > +-- #636: Reload schema on demand > > +sp = box.schema.space.create('test_old') > > +--- > > +... > > +_ = sp:create_index('primary') > > +--- > > +... > > +sp:insert{1, 2, 3} > > +--- > > +- [1, 2, 3] > > +... > > +box.schema.user.grant('guest', 'read', 'space', 'test_old') > > +--- > > +... > > +con = remote.new(box.cfg.listen) > > +--- > > +... > > +con:ping() > > +--- > > +- true > > +... > > +con.space.test_old:select{} > > +--- > > +- - [1, 2, 3] > > +... > > +con.space.test == nil > > +--- > > +- true > > +... > > +sp = box.schema.space.create('test') > > +--- > > +... > > +_ = sp:create_index('primary') > > +--- > > +... > > +sp:insert{2, 3, 4} > > +--- > > +- [2, 3, 4] > > +... > > +box.schema.user.grant('guest', 'read', 'space', 'test') > > +--- > > +... > > +con.space.test == nil > > +--- > > +- true > > +... > > +con:reload_schema() > > +--- > > +... > > +con.space.test:select{} > > +--- > > +- - [2, 3, 4] > > +... > > +box.space.test:drop() > > +--- > > +... > > +box.space.test_old:drop() > > +--- > > +... > > +con:close() > > +--- > > +... > > +name = string.match(arg[0], "([^,]+)%.lua") > > +--- > > +... > > +file_log = require('fio').open(name .. '.log', {'O_RDONLY', 'O_NONBLOCK'}) > > +--- > > +... > > +file_log:seek(0, 'SEEK_END') ~= 0 > > +--- > > +- true > > +... > > +box.schema.user.grant('guest', 'execute', 'universe') > > +--- > > +... > > +test_run:cmd("setopt delimiter ';'") > > +--- > > +- true > > +... > > +_ = fiber.create( > > + function() > > + local conn = require('net.box').new(box.cfg.listen) > > + conn:call('no_such_function', {}) > > + conn:close() > > + end > > +); > > +--- > > +... > > +test_run:cmd("setopt delimiter ''"); > > +--- > > +- true > > +... > > +test_run:wait_log('default', 'ER_NO_SUCH_PROC', nil, 10) > > +--- > > +- ER_NO_SUCH_PROC > > +... > > +box.schema.user.revoke('guest', 'execute', 'universe') > > +--- > > +... > > diff --git a/test/box/net.box_reload_schema_gh-636.test.lua b/test/box/net.box_reload_schema_gh-636.test.lua > > new file mode 100644 > > index 000000000..d7431ee6c > > --- /dev/null > > +++ b/test/box/net.box_reload_schema_gh-636.test.lua > > @@ -0,0 +1,46 @@ > > +remote = require 'net.box' > > +fiber = require 'fiber' > > +test_run = require('test_run').new() > > + > > +-- #636: Reload schema on demand > > +sp = box.schema.space.create('test_old') > > +_ = sp:create_index('primary') > > +sp:insert{1, 2, 3} > > + > > +box.schema.user.grant('guest', 'read', 'space', 'test_old') > > +con = remote.new(box.cfg.listen) > > +con:ping() > > +con.space.test_old:select{} > > +con.space.test == nil > > + > > +sp = box.schema.space.create('test') > > +_ = sp:create_index('primary') > > +sp:insert{2, 3, 4} > > + > > +box.schema.user.grant('guest', 'read', 'space', 'test') > > + > > +con.space.test == nil > > +con:reload_schema() > > +con.space.test:select{} > > + > > +box.space.test:drop() > > +box.space.test_old:drop() > > +con:close() > > + > > +name = string.match(arg[0], "([^,]+)%.lua") > > +file_log = require('fio').open(name .. '.log', {'O_RDONLY', 'O_NONBLOCK'}) > > +file_log:seek(0, 'SEEK_END') ~= 0 > > + > > +box.schema.user.grant('guest', 'execute', 'universe') > > +test_run:cmd("setopt delimiter ';'") > > + > > +_ = fiber.create( > > + function() > > + local conn = require('net.box').new(box.cfg.listen) > > + conn:call('no_such_function', {}) > > + conn:close() > > + end > > +); > > +test_run:cmd("setopt delimiter ''"); > > +test_run:wait_log('default', 'ER_NO_SUCH_PROC', nil, 10) > > +box.schema.user.revoke('guest', 'execute', 'universe') > > diff --git a/test/box/net.box_remote_method_gh-544.result b/test/box/net.box_remote_method_gh-544.result > > new file mode 100644 > > index 000000000..bb92ba998 > > --- /dev/null > > +++ b/test/box/net.box_remote_method_gh-544.result > > @@ -0,0 +1,95 @@ > > +remote = require 'net.box' > > +--- > > +... > > +LISTEN = require('uri').parse(box.cfg.listen) > > +--- > > +... > > +box.schema.user.create('netbox', { password = 'test' }) > > +--- > > +... > > +-- #544 usage for remote[point]method > > +cn = remote.connect(LISTEN.host, LISTEN.service) > > +--- > > +... > > +box.schema.user.grant('guest', 'execute', 'universe') > > +--- > > +... > > +cn:close() > > +--- > > +... > > +cn = remote.connect(LISTEN.host, LISTEN.service) > > +--- > > +... > > +cn:eval('return true') > > +--- > > +- true > > +... > > +cn.eval('return true') > > +--- > > +- error: 'Use remote:eval(...) instead of remote.eval(...):' > > +... > > +cn.ping() > > +--- > > +- error: 'Use remote:ping(...) instead of remote.ping(...):' > > +... > > +cn:close() > > +--- > > +... > > +remote.self:eval('return true') > > +--- > > +- true > > +... > > +remote.self.eval('return true') > > +--- > > +- error: 'Use remote:eval(...) instead of remote.eval(...):' > > +... > > +box.schema.user.revoke('guest', 'execute', 'universe') > > +--- > > +... > > +-- uri as the first argument > > +uri = string.format('%s:%s@%s:%s', 'netbox', 'test', LISTEN.host, LISTEN.service) > > +--- > > +... > > +cn = remote.new(uri) > > +--- > > +... > > +cn:ping() > > +--- > > +- true > > +... > > +cn:close() > > +--- > > +... > > +uri = string.format('%s@%s:%s', 'netbox', LISTEN.host, LISTEN.service) > > +--- > > +... > > +cn = remote.new(uri) > > +--- > > +... > > +cn ~= nil, cn.state, cn.error > > +--- > > +- true > > +- error > > +- Incorrect password supplied for user 'netbox' > > +... > > +cn:close() > > +--- > > +... > > +-- don't merge creds from uri & opts > > +remote.new(uri, { password = 'test' }) > > +--- > > +- error: 'net.box: user is not defined' > > +... > > +cn = remote.new(uri, { user = 'netbox', password = 'test' }) > > +--- > > +... > > +cn:ping() > > +--- > > +- true > > +... > > +cn:close() > > +--- > > +... > > +box.schema.user.drop('netbox') > > +--- > > +... > > diff --git a/test/box/net.box_remote_method_gh-544.test.lua b/test/box/net.box_remote_method_gh-544.test.lua > > new file mode 100644 > > index 000000000..cfd883be0 > > --- /dev/null > > +++ b/test/box/net.box_remote_method_gh-544.test.lua > > @@ -0,0 +1,40 @@ > > +remote = require 'net.box' > > + > > +LISTEN = require('uri').parse(box.cfg.listen) > > +box.schema.user.create('netbox', { password = 'test' }) > > + > > +-- #544 usage for remote[point]method > > +cn = remote.connect(LISTEN.host, LISTEN.service) > > + > > +box.schema.user.grant('guest', 'execute', 'universe') > > +cn:close() > > +cn = remote.connect(LISTEN.host, LISTEN.service) > > +cn:eval('return true') > > +cn.eval('return true') > > + > > +cn.ping() > > + > > +cn:close() > > + > > +remote.self:eval('return true') > > +remote.self.eval('return true') > > +box.schema.user.revoke('guest', 'execute', 'universe') > > + > > +-- uri as the first argument > > +uri = string.format('%s:%s@%s:%s', 'netbox', 'test', LISTEN.host, LISTEN.service) > > + > > +cn = remote.new(uri) > > +cn:ping() > > +cn:close() > > + > > +uri = string.format('%s@%s:%s', 'netbox', LISTEN.host, LISTEN.service) > > +cn = remote.new(uri) > > +cn ~= nil, cn.state, cn.error > > +cn:close() > > +-- don't merge creds from uri & opts > > +remote.new(uri, { password = 'test' }) > > +cn = remote.new(uri, { user = 'netbox', password = 'test' }) > > +cn:ping() > > +cn:close() > > + > > +box.schema.user.drop('netbox') > > diff --git a/test/box/net.box_roll_back_gh-822.result b/test/box/net.box_roll_back_gh-822.result > > new file mode 100644 > > index 000000000..5a0550e39 > > --- /dev/null > > +++ b/test/box/net.box_roll_back_gh-822.result > > @@ -0,0 +1,68 @@ > > +remote = require 'net.box' > > +--- > > +... > > +test_run = require('test_run').new() > > +--- > > +... > > +-- > > +-- gh-822: net.box.call should roll back local transaction on error > > +-- > > +_ = box.schema.space.create('gh822') > > +--- > > +... > > +_ = box.space.gh822:create_index('primary') > > +--- > > +... > > +test_run:cmd("setopt delimiter ';'") > > +--- > > +- true > > +... > > +-- rollback on invalid function > > +function rollback_on_invalid_function() > > + box.begin() > > + box.space.gh822:insert{1, "netbox_test"} > > + pcall(remote.self.call, remote.self, 'invalid_function') > > + return box.space.gh822:get(1) == nil > > +end; > > +--- > > +... > > +rollback_on_invalid_function(); > > +--- > > +- true > > +... > > +-- rollback on call error > > +function test_error() error('Some error') end; > > +--- > > +... > > +function rollback_on_call_error() > > + box.begin() > > + box.space.gh822:insert{1, "netbox_test"} > > + pcall(remote.self.call, remote.self, 'test_error') > > + return box.space.gh822:get(1) == nil > > +end; > > +--- > > +... > > +rollback_on_call_error(); > > +--- > > +- true > > +... > > +-- rollback on eval > > +function rollback_on_eval_error() > > + box.begin() > > + box.space.gh822:insert{1, "netbox_test"} > > + pcall(remote.self.eval, remote.self, "error('Some error')") > > + return box.space.gh822:get(1) == nil > > +end; > > +--- > > +... > > +rollback_on_eval_error(); > > +--- > > +- true > > +... > > +test_run:cmd("setopt delimiter ''"); > > +--- > > +- true > > +... > > +box.space.gh822:drop() > > +--- > > +... > > diff --git a/test/box/net.box_roll_back_gh-822.test.lua b/test/box/net.box_roll_back_gh-822.test.lua > > new file mode 100644 > > index 000000000..8f4754902 > > --- /dev/null > > +++ b/test/box/net.box_roll_back_gh-822.test.lua > > @@ -0,0 +1,42 @@ > > +remote = require 'net.box' > > +test_run = require('test_run').new() > > + > > +-- > > +-- gh-822: net.box.call should roll back local transaction on error > > +-- > > + > > +_ = box.schema.space.create('gh822') > > +_ = box.space.gh822:create_index('primary') > > + > > +test_run:cmd("setopt delimiter ';'") > > + > > +-- rollback on invalid function > > +function rollback_on_invalid_function() > > + box.begin() > > + box.space.gh822:insert{1, "netbox_test"} > > + pcall(remote.self.call, remote.self, 'invalid_function') > > + return box.space.gh822:get(1) == nil > > +end; > > +rollback_on_invalid_function(); > > + > > +-- rollback on call error > > +function test_error() error('Some error') end; > > +function rollback_on_call_error() > > + box.begin() > > + box.space.gh822:insert{1, "netbox_test"} > > + pcall(remote.self.call, remote.self, 'test_error') > > + return box.space.gh822:get(1) == nil > > +end; > > +rollback_on_call_error(); > > + > > +-- rollback on eval > > +function rollback_on_eval_error() > > + box.begin() > > + box.space.gh822:insert{1, "netbox_test"} > > + pcall(remote.self.eval, remote.self, "error('Some error')") > > + return box.space.gh822:get(1) == nil > > +end; > > +rollback_on_eval_error(); > > + > > +test_run:cmd("setopt delimiter ''"); > > +box.space.gh822:drop() > > diff --git a/test/box/net.box_schema_change_gh-2666.result b/test/box/net.box_schema_change_gh-2666.result > > new file mode 100644 > > index 000000000..bce46bd59 > > --- /dev/null > > +++ b/test/box/net.box_schema_change_gh-2666.result > > @@ -0,0 +1,79 @@ > > +net = require('net.box') > > +--- > > +... > > +-- > > +-- gh-2666: check that netbox.call is not repeated on schema > > +-- change. > > +-- > > +box.schema.user.grant('guest', 'write', 'space', '_space') > > +--- > > +... > > +box.schema.user.grant('guest', 'write', 'space', '_schema') > > +--- > > +... > > +box.schema.user.grant('guest', 'create', 'universe') > > +--- > > +... > > +count = 0 > > +--- > > +... > > +function create_space(name) count = count + 1 box.schema.create_space(name) return true end > > +--- > > +... > > +box.schema.func.create('create_space') > > +--- > > +... > > +box.schema.user.grant('guest', 'execute', 'function', 'create_space') > > +--- > > +... > > +c = net.connect(box.cfg.listen) > > +--- > > +... > > +c:call('create_space', {'test1'}) > > +--- > > +- true > > +... > > +count > > +--- > > +- 1 > > +... > > +c:call('create_space', {'test2'}) > > +--- > > +- true > > +... > > +count > > +--- > > +- 2 > > +... > > +c:call('create_space', {'test3'}) > > +--- > > +- true > > +... > > +count > > +--- > > +- 3 > > +... > > +box.space.test1:drop() > > +--- > > +... > > +box.space.test2:drop() > > +--- > > +... > > +box.space.test3:drop() > > +--- > > +... > > +box.schema.user.revoke('guest', 'write', 'space', '_space') > > +--- > > +... > > +box.schema.user.revoke('guest', 'write', 'space', '_schema') > > +--- > > +... > > +box.schema.user.revoke('guest', 'create', 'universe') > > +--- > > +... > > +c:close() > > +--- > > +... > > +box.schema.func.drop('create_space') > > +--- > > +... > > diff --git a/test/box/net.box_schema_change_gh-2666.test.lua b/test/box/net.box_schema_change_gh-2666.test.lua > > new file mode 100644 > > index 000000000..16e28e092 > > --- /dev/null > > +++ b/test/box/net.box_schema_change_gh-2666.test.lua > > @@ -0,0 +1,28 @@ > > +net = require('net.box') > > + > > +-- > > +-- gh-2666: check that netbox.call is not repeated on schema > > +-- change. > > +-- > > +box.schema.user.grant('guest', 'write', 'space', '_space') > > +box.schema.user.grant('guest', 'write', 'space', '_schema') > > +box.schema.user.grant('guest', 'create', 'universe') > > +count = 0 > > +function create_space(name) count = count + 1 box.schema.create_space(name) return true end > > +box.schema.func.create('create_space') > > +box.schema.user.grant('guest', 'execute', 'function', 'create_space') > > +c = net.connect(box.cfg.listen) > > +c:call('create_space', {'test1'}) > > +count > > +c:call('create_space', {'test2'}) > > +count > > +c:call('create_space', {'test3'}) > > +count > > +box.space.test1:drop() > > +box.space.test2:drop() > > +box.space.test3:drop() > > +box.schema.user.revoke('guest', 'write', 'space', '_space') > > +box.schema.user.revoke('guest', 'write', 'space', '_schema') > > +box.schema.user.revoke('guest', 'create', 'universe') > > +c:close() > > +box.schema.func.drop('create_space') > > diff --git a/test/box/net.box_schema_change_gh-3107.result b/test/box/net.box_schema_change_gh-3107.result > > new file mode 100644 > > index 000000000..233c83307 > > --- /dev/null > > +++ b/test/box/net.box_schema_change_gh-3107.result > > @@ -0,0 +1,151 @@ > > +fiber = require 'fiber' > > +--- > > +... > > +net = require('net.box') > > +--- > > +... > > +-- > > +-- gh-3107: fiber-async netbox. > > +-- > > +cond = nil > > +--- > > +... > > +box.schema.func.create('long_function') > > +--- > > +... > > +box.schema.user.grant('guest', 'execute', 'function', 'long_function') > > +--- > > +... > > +function long_function(...) cond = fiber.cond() cond:wait() return ... end > > +--- > > +... > > +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end > > +--- > > +... > > +s = box.schema.create_space('test') > > +--- > > +... > > +pk = s:create_index('pk') > > +--- > > +... > > +s:replace{1} > > +--- > > +- [1] > > +... > > +s:replace{2} > > +--- > > +- [2] > > +... > > +s:replace{3} > > +--- > > +- [3] > > +... > > +s:replace{4} > > +--- > > +- [4] > > +... > > +c = net:connect(box.cfg.listen) > > +--- > > +... > > +-- > > +-- Ensure a request can be finalized from non-caller fibers. > > +-- > > +future = c:call('long_function', {1, 2, 3}, {is_async = true}) > > +--- > > +... > > +ret = {} > > +--- > > +... > > +count = 0 > > +--- > > +... > > +for i = 1, 10 do fiber.create(function() ret[i] = future:wait_result(1000) count = count + 1 end) end > > +--- > > +... > > +future:wait_result(0.01) -- Must fail on timeout. > > +--- > > +- null > > +- Timeout exceeded > > +... > > +finalize_long() > > +--- > > +... > > +while count ~= 10 do fiber.sleep(0.1) end > > +--- > > +... > > +ret > > +--- > > +- - &0 [1, 2, 3] > > + - *0 > > + - *0 > > + - *0 > > + - *0 > > + - *0 > > + - *0 > > + - *0 > > + - *0 > > + - *0 > > +... > > +box.schema.func.drop('long_function') > > +--- > > +... > > +-- > > +-- Test async schema version change. > > +-- > > +function change_schema(i) local tmp = box.schema.create_space('test'..i) return 'ok' end > > +--- > > +... > > +box.schema.func.create('change_schema') > > +--- > > +... > > +box.schema.user.grant('guest', 'execute', 'function', 'change_schema') > > +--- > > +... > > +box.schema.user.grant('guest', 'write', 'space', '_schema') > > +--- > > +... > > +box.schema.user.grant('guest', 'read,write', 'space', '_space') > > +--- > > +... > > +box.schema.user.grant('guest', 'create', 'space') > > +--- > > +... > > +future1 = c:call('change_schema', {'1'}, {is_async = true}) > > +--- > > +... > > +future2 = c:call('change_schema', {'2'}, {is_async = true}) > > +--- > > +... > > +future3 = c:call('change_schema', {'3'}, {is_async = true}) > > +--- > > +... > > +future1:wait_result() > > +--- > > +- ['ok'] > > +... > > +future2:wait_result() > > +--- > > +- ['ok'] > > +... > > +future3:wait_result() > > +--- > > +- ['ok'] > > +... > > +c:close() > > +--- > > +... > > +s:drop() > > +--- > > +... > > +box.schema.func.drop('change_schema') > > +--- > > +... > > +box.schema.user.revoke('guest', 'write', 'space', '_schema') > > +--- > > +... > > +box.schema.user.revoke('guest', 'read,write', 'space', '_space') > > +--- > > +... > > +box.schema.user.revoke('guest', 'create', 'space') > > +--- > > +... > > diff --git a/test/box/net.box_schema_change_gh-3107.test.lua b/test/box/net.box_schema_change_gh-3107.test.lua > > new file mode 100644 > > index 000000000..c73788455 > > --- /dev/null > > +++ b/test/box/net.box_schema_change_gh-3107.test.lua > > @@ -0,0 +1,55 @@ > > +fiber = require 'fiber' > > +net = require('net.box') > > + > > +-- > > +-- gh-3107: fiber-async netbox. > > +-- > > +cond = nil > > +box.schema.func.create('long_function') > > +box.schema.user.grant('guest', 'execute', 'function', 'long_function') > > +function long_function(...) cond = fiber.cond() cond:wait() return ... end > > +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end > > +s = box.schema.create_space('test') > > +pk = s:create_index('pk') > > +s:replace{1} > > +s:replace{2} > > +s:replace{3} > > +s:replace{4} > > +c = net:connect(box.cfg.listen) > > + > > +-- > > +-- Ensure a request can be finalized from non-caller fibers. > > +-- > > +future = c:call('long_function', {1, 2, 3}, {is_async = true}) > > +ret = {} > > +count = 0 > > +for i = 1, 10 do fiber.create(function() ret[i] = future:wait_result(1000) count = count + 1 end) end > > +future:wait_result(0.01) -- Must fail on timeout. > > +finalize_long() > > +while count ~= 10 do fiber.sleep(0.1) end > > +ret > > + > > +box.schema.func.drop('long_function') > > + > > +-- > > +-- Test async schema version change. > > +-- > > +function change_schema(i) local tmp = box.schema.create_space('test'..i) return 'ok' end > > +box.schema.func.create('change_schema') > > +box.schema.user.grant('guest', 'execute', 'function', 'change_schema') > > +box.schema.user.grant('guest', 'write', 'space', '_schema') > > +box.schema.user.grant('guest', 'read,write', 'space', '_space') > > +box.schema.user.grant('guest', 'create', 'space') > > +future1 = c:call('change_schema', {'1'}, {is_async = true}) > > +future2 = c:call('change_schema', {'2'}, {is_async = true}) > > +future3 = c:call('change_schema', {'3'}, {is_async = true}) > > +future1:wait_result() > > +future2:wait_result() > > +future3:wait_result() > > + > > +c:close() > > +s:drop() > > +box.schema.func.drop('change_schema') > > +box.schema.user.revoke('guest', 'write', 'space', '_schema') > > +box.schema.user.revoke('guest', 'read,write', 'space', '_space') > > +box.schema.user.revoke('guest', 'create', 'space') > > diff --git a/test/box/net.box_session_type_gh-2642.result b/test/box/net.box_session_type_gh-2642.result > > new file mode 100644 > > index 000000000..0e043f6e5 > > --- /dev/null > > +++ b/test/box/net.box_session_type_gh-2642.result > > @@ -0,0 +1,22 @@ > > +net = require('net.box') > > +--- > > +... > > +-- > > +-- gh-2642: box.session.type() > > +-- > > +box.schema.user.grant('guest','execute','universe') > > +--- > > +... > > +c = net.connect(box.cfg.listen) > > +--- > > +... > > +c:call("box.session.type") > > +--- > > +- binary > > +... > > +c:close() > > +--- > > +... > > +box.schema.user.revoke('guest', 'execute', 'universe') > > +--- > > +... > > diff --git a/test/box/net.box_session_type_gh-2642.test.lua b/test/box/net.box_session_type_gh-2642.test.lua > > new file mode 100644 > > index 000000000..4e3cf5265 > > --- /dev/null > > +++ b/test/box/net.box_session_type_gh-2642.test.lua > > @@ -0,0 +1,11 @@ > > +net = require('net.box') > > + > > +-- > > +-- gh-2642: box.session.type() > > +-- > > + > > +box.schema.user.grant('guest','execute','universe') > > +c = net.connect(box.cfg.listen) > > +c:call("box.session.type") > > +c:close() > > +box.schema.user.revoke('guest', 'execute', 'universe') > > diff --git a/test/box/net.box_space_format_gh-2402.result b/test/box/net.box_space_format_gh-2402.result > > new file mode 100644 > > index 000000000..c66665c73 > > --- /dev/null > > +++ b/test/box/net.box_space_format_gh-2402.result > > @@ -0,0 +1,49 @@ > > +net = require('net.box') > > +--- > > +... > > +-- > > +-- gh-2402 net.box doesn't support space:format() > > +-- > > +space = box.schema.space.create('test', {format={{name="id", type="unsigned"}}}) > > +--- > > +... > > +space ~= nil > > +--- > > +- true > > +... > > +_ = box.space.test:create_index('primary') > > +--- > > +... > > +box.schema.user.grant('guest', 'read', 'space', 'test') > > +--- > > +... > > +c = net.connect(box.cfg.listen) > > +--- > > +... > > +c:ping() > > +--- > > +- true > > +... > > +c.space.test ~= nil > > +--- > > +- true > > +... > > +format = c.space.test:format() > > +--- > > +... > > +format[1] ~= nil > > +--- > > +- true > > +... > > +format[1].name == "id" > > +--- > > +- true > > +... > > +format[1].type == "unsigned" > > +--- > > +- true > > +... > > +c.space.test:format({}) > > +--- > > +- error: net.box does not support setting space format > > +... > > diff --git a/test/box/net.box_space_format_gh-2402.test.lua b/test/box/net.box_space_format_gh-2402.test.lua > > new file mode 100644 > > index 000000000..020f20da6 > > --- /dev/null > > +++ b/test/box/net.box_space_format_gh-2402.test.lua > > @@ -0,0 +1,23 @@ > > +net = require('net.box') > > + > > +-- > > +-- gh-2402 net.box doesn't support space:format() > > +-- > > + > > +space = box.schema.space.create('test', {format={{name="id", type="unsigned"}}}) > > +space ~= nil > > +_ = box.space.test:create_index('primary') > > +box.schema.user.grant('guest', 'read', 'space', 'test') > > + > > +c = net.connect(box.cfg.listen) > > + > > +c:ping() > > +c.space.test ~= nil > > + > > +format = c.space.test:format() > > + > > +format[1] ~= nil > > +format[1].name == "id" > > +format[1].type == "unsigned" > > + > > +c.space.test:format({}) > > diff --git a/test/box/net.box_timeout-gh-3107.result b/test/box/net.box_timeout-gh-3107.result > > new file mode 100644 > > index 000000000..be7f9606c > > --- /dev/null > > +++ b/test/box/net.box_timeout-gh-3107.result > > @@ -0,0 +1,125 @@ > > +-- test-run result file version 2 > > +fiber = require 'fiber' > > + | --- > > + | ... > > +net = require('net.box') > > + | --- > > + | ... > > + > > +-- > > +-- gh-3107: fiber-async netbox. > > +-- > > +cond = nil > > + | --- > > + | ... > > +box.schema.func.create('long_function') > > + | --- > > + | ... > > +box.schema.user.grant('guest', 'execute', 'function', 'long_function') > > + | --- > > + | ... > > +function long_function(...) cond = fiber.cond() cond:wait() return ... end > > + | --- > > + | ... > > +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end > > + | --- > > + | ... > > +s = box.schema.create_space('test') > > + | --- > > + | ... > > +pk = s:create_index('pk') > > + | --- > > + | ... > > +s:replace{1} > > + | --- > > + | - [1] > > + | ... > > +s:replace{2} > > + | --- > > + | - [2] > > + | ... > > +s:replace{3} > > + | --- > > + | - [3] > > + | ... > > +s:replace{4} > > + | --- > > + | - [4] > > + | ... > > +c = net:connect(box.cfg.listen) > > + | --- > > + | ... > > + > > +-- > > +-- Check infinity timeout. > > +-- > > +ret = nil > > + | --- > > + | ... > > +_ = fiber.create(function() ret = c:call('long_function', {1, 2, 3}, {is_async = true}):wait_result() end) > > + | --- > > + | ... > > +finalize_long() > > + | --- > > + | ... > > +while not ret do fiber.sleep(0.01) end > > + | --- > > + | ... > > +ret > > + | --- > > + | - [1, 2, 3] > > + | ... > > +c:close() > > + | --- > > + | ... > > +box.schema.user.grant('guest', 'execute', 'universe') > > + | --- > > + | ... > > +c = net:connect(box.cfg.listen) > > + | --- > > + | ... > > +future = c:eval('return long_function(...)', {1, 2, 3}, {is_async = true}) > > + | --- > > + | ... > > +future:result() > > + | --- > > + | - null > > + | - Response is not ready > > + | ... > > +future:wait_result(0.01) -- Must fail on timeout. > > + | --- > > + | - null > > + | - Timeout exceeded > > + | ... > > +finalize_long() > > + | --- > > + | ... > > +future:wait_result(100) > > + | --- > > + | - [1, 2, 3] > > + | ... > > + > > +c:close() > > + | --- > > + | ... > > +-- > > +-- Check that is_async does not work on a closed connection. > > +-- > > +c:call('any_func', {}, {is_async = true}) > > + | --- > > + | - error: Connection closed > > + | ... > > + > > +box.schema.user.revoke('guest', 'execute', 'universe') > > + | --- > > + | ... > > +c = net:connect(box.cfg.listen) > > + | --- > > + | ... > > + > > +c:close() > > + | --- > > + | ... > > +s:drop() > > + | --- > > + | ... > > diff --git a/test/box/net.box_timeout-gh-3107.test.lua b/test/box/net.box_timeout-gh-3107.test.lua > > new file mode 100644 > > index 000000000..08fa039db > > --- /dev/null > > +++ b/test/box/net.box_timeout-gh-3107.test.lua > > @@ -0,0 +1,47 @@ > > +fiber = require 'fiber' > > +net = require('net.box') > > + > > +-- > > +-- gh-3107: fiber-async netbox. > > +-- > > +cond = nil > > +box.schema.func.create('long_function') > > +box.schema.user.grant('guest', 'execute', 'function', 'long_function') > > +function long_function(...) cond = fiber.cond() cond:wait() return ... end > > +function finalize_long() while not cond do fiber.sleep(0.01) end cond:signal() cond = nil end > > +s = box.schema.create_space('test') > > +pk = s:create_index('pk') > > +s:replace{1} > > +s:replace{2} > > +s:replace{3} > > +s:replace{4} > > +c = net:connect(box.cfg.listen) > > + > > +-- > > +-- Check infinity timeout. > > +-- > > +ret = nil > > +_ = fiber.create(function() ret = c:call('long_function', {1, 2, 3}, {is_async = true}):wait_result() end) > > +finalize_long() > > +while not ret do fiber.sleep(0.01) end > > +ret > > +c:close() > > +box.schema.user.grant('guest', 'execute', 'universe') > > +c = net:connect(box.cfg.listen) > > +future = c:eval('return long_function(...)', {1, 2, 3}, {is_async = true}) > > +future:result() > > +future:wait_result(0.01) -- Must fail on timeout. > > +finalize_long() > > +future:wait_result(100) > > + > > +c:close() > > +-- > > +-- Check that is_async does not work on a closed connection. > > +-- > > +c:call('any_func', {}, {is_async = true}) > > + > > +box.schema.user.revoke('guest', 'execute', 'universe') > > +c = net:connect(box.cfg.listen) > > + > > +c:close() > > +s:drop() > > diff --git a/test/box/net.box_timeout_gh-1533.result b/test/box/net.box_timeout_gh-1533.result > > new file mode 100644 > > index 000000000..10dccd74f > > --- /dev/null > > +++ b/test/box/net.box_timeout_gh-1533.result > > @@ -0,0 +1,89 @@ > > +fiber = require 'fiber' > > +--- > > +... > > +test_run = require('test_run').new() > > +--- > > +... > > +net = require('net.box') > > +--- > > +... > > +-- Tarantool < 1.7.1 compatibility (gh-1533) > > +c = net.new(box.cfg.listen) > > +--- > > +... > > +c:ping() > > +--- > > +- true > > +... > > +c:close() > > +--- > > +... > > +-- Test for connect_timeout > 0 in netbox connect > > +test_run:cmd("setopt delimiter ';'"); > > +--- > > +- true > > +... > > +need_stop = false; > > +--- > > +... > > +greeting = > > +"Tarantool 1.7.3 (Lua console)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" .. > > +"type 'help' for interactive help~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"; > > +--- > > +... > > +socket = require('socket'); > > +--- > > +... > > +srv = socket.tcp_server('localhost', 0, { > > + handler = function(fd) > > + local fiber = require('fiber') > > + while not need_stop do > > + fiber.sleep(0.01) > > + end > > + fd:write(greeting) > > + end > > +}); > > +--- > > +... > > +-- we must get timeout > > +port = srv:name().port > > +nb = net.new('localhost:' .. port, { > > + wait_connected = true, console = true, > > + connect_timeout = 0.1 > > +}); > > +--- > > +... > > +nb.error:find('timed out') ~= nil; > > +--- > > +- true > > +... > > +need_stop = true > > +nb:close(); > > +--- > > +... > > +-- we must get peer closed > > +nb = net.new('localhost:' .. port, { > > + wait_connected = true, console = true, > > + connect_timeout = 0.2 > > +}); > > +--- > > +... > > +nb.error ~= "Timeout exceeded"; > > +--- > > +- true > > +... > > +nb:close(); > > +--- > > +... > > +test_run:cmd("setopt delimiter ''"); > > +--- > > +- true > > +... > > +srv:close() > > +--- > > +- true > > +... > > +test_run:cmd("clear filter") > > +--- > > +- true > > +... > > diff --git a/test/box/net.box_timeout_gh-1533.test.lua b/test/box/net.box_timeout_gh-1533.test.lua > > new file mode 100644 > > index 000000000..08fddb0bb > > --- /dev/null > > +++ b/test/box/net.box_timeout_gh-1533.test.lua > > @@ -0,0 +1,45 @@ > > +fiber = require 'fiber' > > +test_run = require('test_run').new() > > +net = require('net.box') > > + > > +-- Tarantool < 1.7.1 compatibility (gh-1533) > > +c = net.new(box.cfg.listen) > > +c:ping() > > +c:close() > > + > > +-- Test for connect_timeout > 0 in netbox connect > > +test_run:cmd("setopt delimiter ';'"); > > +need_stop = false; > > +greeting = > > +"Tarantool 1.7.3 (Lua console)~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n" .. > > +"type 'help' for interactive help~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n"; > > +socket = require('socket'); > > +srv = socket.tcp_server('localhost', 0, { > > + handler = function(fd) > > + local fiber = require('fiber') > > + while not need_stop do > > + fiber.sleep(0.01) > > + end > > + fd:write(greeting) > > + end > > +}); > > +port = srv:name().port > > +-- we must get timeout > > +nb = net.new('localhost:' .. port, { > > + wait_connected = true, console = true, > > + connect_timeout = 0.1 > > +}); > > +nb.error:find('timed out') ~= nil; > > +need_stop = true > > +nb:close(); > > +-- we must get peer closed > > +nb = net.new('localhost:' .. port, { > > + wait_connected = true, console = true, > > + connect_timeout = 0.2 > > +}); > > +nb.error ~= "Timeout exceeded"; > > +nb:close(); > > +test_run:cmd("setopt delimiter ''"); > > +srv:close() > > + > > +test_run:cmd("clear filter") > > diff --git a/test/box/net.box_upsert_gh-970.result b/test/box/net.box_upsert_gh-970.result > > new file mode 100644 > > index 000000000..d3ec20c23 > > --- /dev/null > > +++ b/test/box/net.box_upsert_gh-970.result > > @@ -0,0 +1,49 @@ > > +net = require('net.box') > > +--- > > +... > > +-- gh-970 gh-971 UPSERT over network > > +_ = box.schema.space.create('test') > > +--- > > +... > > +_ = box.space.test:create_index('primary', {type = 'TREE', parts = {1,'unsigned'}}) > > +--- > > +... > > +_ = box.space.test:create_index('covering', {type = 'TREE', parts = {1,'unsigned',3,'string',2,'unsigned'}}) > > +--- > > +... > > +_ = box.space.test:insert{1, 2, "string"} > > +--- > > +... > > +box.schema.user.grant('guest', 'read,write', 'space', 'test') > > +--- > > +... > > +c = net:connect(box.cfg.listen) > > +--- > > +... > > +c.space.test:select{} > > +--- > > +- - [1, 2, 'string'] > > +... > > +c.space.test:upsert({1, 2, 'nothing'}, {{'+', 2, 1}}) -- common update > > +--- > > +... > > +c.space.test:select{} > > +--- > > +- - [1, 3, 'string'] > > +... > > +c.space.test:upsert({2, 4, 'something'}, {{'+', 2, 1}}) -- insert > > +--- > > +... > > +c.space.test:select{} > > +--- > > +- - [1, 3, 'string'] > > + - [2, 4, 'something'] > > +... > > +c.space.test:upsert({2, 4, 'nothing'}, {{'+', 3, 100500}}) -- wrong operation > > +--- > > +... > > +c.space.test:select{} > > +--- > > +- - [1, 3, 'string'] > > + - [2, 4, 'something'] > > +... > > diff --git a/test/box/net.box_upsert_gh-970.test.lua b/test/box/net.box_upsert_gh-970.test.lua > > new file mode 100644 > > index 000000000..0ea9092eb > > --- /dev/null > > +++ b/test/box/net.box_upsert_gh-970.test.lua > > @@ -0,0 +1,16 @@ > > +net = require('net.box') > > + > > +-- gh-970 gh-971 UPSERT over network > > +_ = box.schema.space.create('test') > > +_ = box.space.test:create_index('primary', {type = 'TREE', parts = {1,'unsigned'}}) > > +_ = box.space.test:create_index('covering', {type = 'TREE', parts = {1,'unsigned',3,'string',2,'unsigned'}}) > > +_ = box.space.test:insert{1, 2, "string"} > > +box.schema.user.grant('guest', 'read,write', 'space', 'test') > > +c = net:connect(box.cfg.listen) > > +c.space.test:select{} > > +c.space.test:upsert({1, 2, 'nothing'}, {{'+', 2, 1}}) -- common update > > +c.space.test:select{} > > +c.space.test:upsert({2, 4, 'something'}, {{'+', 2, 1}}) -- insert > > +c.space.test:select{} > > +c.space.test:upsert({2, 4, 'nothing'}, {{'+', 3, 100500}}) -- wrong operation > > +c.space.test:select{} > > diff --git a/test/box/net.box_wait_connected_gh-3856.result b/test/box/net.box_wait_connected_gh-3856.result > > new file mode 100644 > > index 000000000..9234e6cb9 > > --- /dev/null > > +++ b/test/box/net.box_wait_connected_gh-3856.result > > @@ -0,0 +1,20 @@ > > +net = require('net.box') > > +--- > > +... > > +-- > > +-- gh-3856: wait_connected = false is ignored. > > +-- > > +c = net.connect('8.8.8.8:123456', {wait_connected = false}) > > +--- > > +... > > +c > > +--- > > +- opts: > > + wait_connected: false > > + host: 8.8.8.8 > > + state: initial > > + port: '123456' > > +... > > +c:close() > > +--- > > +... > > diff --git a/test/box/net.box_wait_connected_gh-3856.test.lua b/test/box/net.box_wait_connected_gh-3856.test.lua > > new file mode 100644 > > index 000000000..29e997fb5 > > --- /dev/null > > +++ b/test/box/net.box_wait_connected_gh-3856.test.lua > > @@ -0,0 +1,8 @@ > > +net = require('net.box') > > + > > +-- > > +-- gh-3856: wait_connected = false is ignored. > > +-- > > +c = net.connect('8.8.8.8:123456', {wait_connected = false}) > > +c > > +c:close() > > -- > > 2.17.1 > > > > -- > sergeyb@ ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Tarantool-patches] [PATCH v1] Divide test box/net.box 2020-05-15 17:04 ` Alexander V. Tikhonov @ 2020-05-18 10:00 ` Sergey Bronnikov 2020-06-01 9:24 ` Alexander V. Tikhonov 0 siblings, 1 reply; 8+ messages in thread From: Sergey Bronnikov @ 2020-05-18 10:00 UTC (permalink / raw) To: Alexander V. Tikhonov; +Cc: tarantool-patches Hi, Alexander On 20:04 Fri 15 May , Alexander V. Tikhonov wrote: > Hi Sergey, thanks a lot for the review. As we discussed the ability to > reproduce the issues on the fixing commits I've checked group of tests: > 10 tests as you asked in the issue and 3 that I've already checked. > Whithin these tests results were: > 3 tests: all reproduced the issue > 10 tests: > 4 - reproduced the issue > 1 - didn't show the issue could you reproduce issue using original test with source code without fix? > 5 - couldn't build and test too old fixes committed in 1.6 Tarantool > version. could you reproduce them using tarantool from packages? > To see the results with names please check the issue in github, where > I've created the table of results for the checked tests. > > On Thu, Apr 02, 2020 at 06:44:44PM +0300, Sergey Bronnikov wrote: > > Hello! > > > > before splitting test we had a net.box.skipcond file due to an issue > > https://github.com/tarantool/tarantool/issues/4271. I believe that file > > is useless now and we should add similar files for a new tests. > > > > I have looked on tests without postfix "gh-xxx" in a filenames. > > LGTM for them: > > > > net.box_connect_triggers.test.lua > > net.box_permissions.test.lua > > net.box_reconnect_after.test.lua > > net.box_get_connection_object.test.lua > > > > I propose to run tests with postfix "gh-xxx" in filenames on commits > > before fix where bug covered by test was added. Broken test would mean > > it still works. > > > > Sergey > > <snipped> ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Tarantool-patches] [PATCH v1] Divide test box/net.box 2020-05-18 10:00 ` Sergey Bronnikov @ 2020-06-01 9:24 ` Alexander V. Tikhonov 2020-06-04 10:33 ` Sergey Bronnikov 0 siblings, 1 reply; 8+ messages in thread From: Alexander V. Tikhonov @ 2020-06-01 9:24 UTC (permalink / raw) To: Sergey Bronnikov; +Cc: tarantool-patches Hi Sergey, thanks for the suggestions, I've tried to use Tarantool packages 1.6.8 version and older, but met a lot of issue with it's installing. Also the main issue that it's not possible to rebuild Tarantool of the old packages in the new OS. The only found available package fot Ubuntu:14.04, but it has issues with installation dependencies, anyway it's version is later than checking patches. These issues were reported to out team and decided to avoid of checking patches for fixes older than 1.7-1.9 versions. On Mon, May 18, 2020 at 01:00:58PM +0300, Sergey Bronnikov wrote: > Hi, Alexander > > On 20:04 Fri 15 May , Alexander V. Tikhonov wrote: > > Hi Sergey, thanks a lot for the review. As we discussed the ability to > > reproduce the issues on the fixing commits I've checked group of tests: > > 10 tests as you asked in the issue and 3 that I've already checked. > > Whithin these tests results were: > > 3 tests: all reproduced the issue > > 10 tests: > > 4 - reproduced the issue > > 1 - didn't show the issue > > could you reproduce issue using original test with source code without fix? > > > 5 - couldn't build and test too old fixes committed in 1.6 Tarantool > > version. > > could you reproduce them using tarantool from packages? > > > To see the results with names please check the issue in github, where > > I've created the table of results for the checked tests. > > > > On Thu, Apr 02, 2020 at 06:44:44PM +0300, Sergey Bronnikov wrote: > > > Hello! > > > > > > before splitting test we had a net.box.skipcond file due to an issue > > > https://github.com/tarantool/tarantool/issues/4271. I believe that file > > > is useless now and we should add similar files for a new tests. > > > > > > I have looked on tests without postfix "gh-xxx" in a filenames. > > > LGTM for them: > > > > > > net.box_connect_triggers.test.lua > > > net.box_permissions.test.lua > > > net.box_reconnect_after.test.lua > > > net.box_get_connection_object.test.lua > > > > > > I propose to run tests with postfix "gh-xxx" in filenames on commits > > > before fix where bug covered by test was added. Broken test would mean > > > it still works. > > > > > > Sergey > > > > > <snipped> ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Tarantool-patches] [PATCH v1] Divide test box/net.box 2020-06-01 9:24 ` Alexander V. Tikhonov @ 2020-06-04 10:33 ` Sergey Bronnikov 2020-06-04 15:50 ` Alexander V. Tikhonov 0 siblings, 1 reply; 8+ messages in thread From: Sergey Bronnikov @ 2020-06-04 10:33 UTC (permalink / raw) To: Alexander V. Tikhonov; +Cc: tarantool-patches Alexander, I left comments inline, please see below On 12:24 Mon 01 Jun , Alexander V. Tikhonov wrote: > Hi Sergey, thanks for the suggestions, I've tried to use Tarantool > packages 1.6.8 version and older, but met a lot of issue with it's > installing. Also the main issue that it's not possible to rebuild > Tarantool of the old packages in the new OS. The only found available > package fot Ubuntu:14.04, but it has issues with installation > dependencies, anyway it's version is later than checking patches. > > These issues were reported to out team and decided to avoid of checking > patches for fixes older than 1.7-1.9 versions. 1. ok for me, I remember we agreed to skip reproducing on ancient tarantool versions 2. Patch contains a result file test/box/gh-3107_rest1_net.box.result, but there is no test with same name. I've discovered another regression test for the same GH issue - net.box_collectgarbage_gh-3107.test.lua. Please clarify here. 3. Looks like you forgot to remove old test files: net.box.skipcond, net.box.result, net.box.test.lua. --- /dev/null +++ b/test/box/net.box_call_blocks_gh-946.test.lua @@ -0,0 +1,67 @@ +fiber = require 'fiber' +test_run = require('test_run').new() + +--space = box.schema.space.create('net_box_test_space') +--index = space:create_index('primary', { type = 'tree' }) 4. looks like we can remove lines above +net = require('net.box') +socket = require('socket'); --- /dev/null +++ b/test/box/net.box_call_blocks_gh-946.test.lua @@ -0,0 +1,67 @@ +fiber = require 'fiber' +test_run = require('test_run').new() + +--space = box.schema.space.create('net_box_test_space') +--index = space:create_index('primary', { type = 'tree' }) 5. looks like we can remove lines above +net = require('net.box') +socket = require('socket'); 6. It would be more convenient to review if you will split single patch to multiple patches with addition new tests and removing old one. P.S. also code coverage [1] decreased slightly (-0.02%), but I don't think it's a problem. [1] https://coveralls.io/github/tarantool/tarantool?branch=avtikhon/divide_tests > On Mon, May 18, 2020 at 01:00:58PM +0300, Sergey Bronnikov wrote: > > Hi, Alexander > > > > On 20:04 Fri 15 May , Alexander V. Tikhonov wrote: > > > Hi Sergey, thanks a lot for the review. As we discussed the ability to > > > reproduce the issues on the fixing commits I've checked group of tests: > > > 10 tests as you asked in the issue and 3 that I've already checked. > > > Whithin these tests results were: > > > 3 tests: all reproduced the issue > > > 10 tests: > > > 4 - reproduced the issue > > > 1 - didn't show the issue > > > > could you reproduce issue using original test with source code without fix? > > > > > 5 - couldn't build and test too old fixes committed in 1.6 Tarantool > > > version. > > > > could you reproduce them using tarantool from packages? > > > > > To see the results with names please check the issue in github, where > > > I've created the table of results for the checked tests. > > > > > > On Thu, Apr 02, 2020 at 06:44:44PM +0300, Sergey Bronnikov wrote: > > > > Hello! > > > > > > > > before splitting test we had a net.box.skipcond file due to an issue > > > > https://github.com/tarantool/tarantool/issues/4271. I believe that file > > > > is useless now and we should add similar files for a new tests. > > > > > > > > I have looked on tests without postfix "gh-xxx" in a filenames. > > > > LGTM for them: > > > > > > > > net.box_connect_triggers.test.lua > > > > net.box_permissions.test.lua > > > > net.box_reconnect_after.test.lua > > > > net.box_get_connection_object.test.lua > > > > > > > > I propose to run tests with postfix "gh-xxx" in filenames on commits > > > > before fix where bug covered by test was added. Broken test would mean > > > > it still works. > > > > > > > > Sergey > > > > > > > > <snipped> ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Tarantool-patches] [PATCH v1] Divide test box/net.box 2020-06-04 10:33 ` Sergey Bronnikov @ 2020-06-04 15:50 ` Alexander V. Tikhonov 2020-06-08 20:10 ` Sergey Bronnikov 0 siblings, 1 reply; 8+ messages in thread From: Alexander V. Tikhonov @ 2020-06-04 15:50 UTC (permalink / raw) To: Sergey Bronnikov; +Cc: tarantool-patches Hi Sergey, thanks a lot for the review, please check my answers below. On Thu, Jun 04, 2020 at 01:33:11PM +0300, Sergey Bronnikov wrote: > Alexander, > > I left comments inline, please see below > > On 12:24 Mon 01 Jun , Alexander V. Tikhonov wrote: > > Hi Sergey, thanks for the suggestions, I've tried to use Tarantool > > packages 1.6.8 version and older, but met a lot of issue with it's > > installing. Also the main issue that it's not possible to rebuild > > Tarantool of the old packages in the new OS. The only found available > > package fot Ubuntu:14.04, but it has issues with installation > > dependencies, anyway it's version is later than checking patches. > > > > These issues were reported to out team and decided to avoid of checking > > patches for fixes older than 1.7-1.9 versions. > > 1. ok for me, I remember we agreed to skip reproducing on ancient tarantool > versions > > 2. Patch contains a result file test/box/gh-3107_rest1_net.box.result, > but there is no test with same name. I've discovered another regression > test for the same GH issue - net.box_collectgarbage_gh-3107.test.lua. > Please clarify here. > Right, that was draft version of the file test/box/net.box_timeout-gh-3107.result removing. > 3. Looks like you forgot to remove old test files: > net.box.skipcond, net.box.result, net.box.test.lua. > > --- /dev/null > +++ b/test/box/net.box_call_blocks_gh-946.test.lua > @@ -0,0 +1,67 @@ > +fiber = require 'fiber' > +test_run = require('test_run').new() > + > +--space = box.schema.space.create('net_box_test_space') > +--index = space:create_index('primary', { type = 'tree' }) > Right, I've temporary restored it for merging with the new changes and forgot to remove. > 4. looks like we can remove lines above > > +net = require('net.box') > +socket = require('socket'); > > --- /dev/null > +++ b/test/box/net.box_call_blocks_gh-946.test.lua > @@ -0,0 +1,67 @@ > +fiber = require 'fiber' > +test_run = require('test_run').new() > + > +--space = box.schema.space.create('net_box_test_space') > +--index = space:create_index('primary', { type = 'tree' }) > Right, but only 'socket', 'net' stil in use: --- box/net.box_call_blocks_gh-946.result Thu Jun 4 18:43:38 2020 +++ var/001_box/net.box_call_blocks_gh-946.result Thu Jun 4 18:44:00 2020 @@ -31,6 +31,7 @@ ... c = net.connect(box.cfg.listen) --- +- error: '[string "c = net.connect(box.cfg.listen) "]:1: variable ''net'' is not declared' > 5. looks like we can remove lines above > > +net = require('net.box') > +socket = require('socket'); > Removed 'socket' from result file too: test/box/net.box_call_blocks_gh-946.result > 6. It would be more convenient to review if you will split single patch to > multiple patches with addition new tests and removing old one. > Ok. > P.S. also code coverage [1] decreased slightly (-0.02%), but I don't > think it's a problem. > Ok. > [1] https://coveralls.io/github/tarantool/tarantool?branch=avtikhon/divide_tests > > > On Mon, May 18, 2020 at 01:00:58PM +0300, Sergey Bronnikov wrote: > > > Hi, Alexander > > > > > > On 20:04 Fri 15 May , Alexander V. Tikhonov wrote: > > > > Hi Sergey, thanks a lot for the review. As we discussed the ability to > > > > reproduce the issues on the fixing commits I've checked group of tests: > > > > 10 tests as you asked in the issue and 3 that I've already checked. > > > > Whithin these tests results were: > > > > 3 tests: all reproduced the issue > > > > 10 tests: > > > > 4 - reproduced the issue > > > > 1 - didn't show the issue > > > > > > could you reproduce issue using original test with source code without fix? > > > > > > > 5 - couldn't build and test too old fixes committed in 1.6 Tarantool > > > > version. > > > > > > could you reproduce them using tarantool from packages? > > > > > > > To see the results with names please check the issue in github, where > > > > I've created the table of results for the checked tests. > > > > > > > > On Thu, Apr 02, 2020 at 06:44:44PM +0300, Sergey Bronnikov wrote: > > > > > Hello! > > > > > > > > > > before splitting test we had a net.box.skipcond file due to an issue > > > > > https://github.com/tarantool/tarantool/issues/4271. I believe that file > > > > > is useless now and we should add similar files for a new tests. > > > > > > > > > > I have looked on tests without postfix "gh-xxx" in a filenames. > > > > > LGTM for them: > > > > > > > > > > net.box_connect_triggers.test.lua > > > > > net.box_permissions.test.lua > > > > > net.box_reconnect_after.test.lua > > > > > net.box_get_connection_object.test.lua > > > > > > > > > > I propose to run tests with postfix "gh-xxx" in filenames on commits > > > > > before fix where bug covered by test was added. Broken test would mean > > > > > it still works. > > > > > > > > > > Sergey > > > > > > > > > > > <snipped> ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: [Tarantool-patches] [PATCH v1] Divide test box/net.box 2020-06-04 15:50 ` Alexander V. Tikhonov @ 2020-06-08 20:10 ` Sergey Bronnikov 0 siblings, 0 replies; 8+ messages in thread From: Sergey Bronnikov @ 2020-06-08 20:10 UTC (permalink / raw) To: Alexander V. Tikhonov; +Cc: tarantool-patches Hi, Sasha! thanks for update! Please replace "Close #4880" in a commit message to "Closes #4880", as recommended in Developer guidelines [1]. LGTM 1. https://www.tarantool.io/en/doc/2.3/dev_guide/developer_guidelines/ On 18:50 Thu 04 Jun , Alexander V. Tikhonov wrote: > Hi Sergey, thanks a lot for the review, please check my answers below. ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2020-06-08 20:12 UTC | newest] Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2020-04-02 6:38 [Tarantool-patches] [PATCH v1] Divide test box/net.box Alexander V. Tikhonov 2020-04-02 15:44 ` Sergey Bronnikov 2020-05-15 17:04 ` Alexander V. Tikhonov 2020-05-18 10:00 ` Sergey Bronnikov 2020-06-01 9:24 ` Alexander V. Tikhonov 2020-06-04 10:33 ` Sergey Bronnikov 2020-06-04 15:50 ` Alexander V. Tikhonov 2020-06-08 20:10 ` Sergey Bronnikov
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox