[Tarantool-patches] [PATCH v1] Divide test box/net.box

Alexander V. Tikhonov avtikhon at tarantool.org
Fri May 15 20:04:09 MSK 2020


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@


More information about the Tarantool-patches mailing list