commit - 2c71fd7fbb7b483ce8739c90161010523b5347da
commit + af929c2339f3d0da3ef896322d9909157237c4b1
blob - b79c47df76797803d9d027a7d5e02929140da049
blob + 72ded82383c28c0e72e86006e564e884324edaa6
--- .gitignore
+++ .gitignore
src/lua/*.lua.c
src/box/lua/*.lua.c
src/tarantool
-src/trivia/tarantool.h
+src/module.h
tarantool-*.tar.gz
test/lib/
test/unit/*.test
blob - 2060105f5213ca16f62f5d8619f9b4e0f05479e0
blob + 504f1351268dfbb811c78181622dacb61de2983e
--- .travis.yml
+++ .travis.yml
- clang
- gcc
+matrix:
+ exclude:
+ - os: osx
+ compiler: gcc
+
addons:
postgresql: "9.1"
blob - 2faa825ca61e4c77f1384f80f5c05633239e6ca9
blob + 8437eaedf5cf19b28fb123414c824eb8213e7f23
--- Doxyfile.API.in
+++ Doxyfile.API.in
@INCLUDE = @PROJECT_SOURCE_DIR@/Doxyfile
-INPUT = @PROJECT_BINARY_DIR@/src/trivia/tarantool.h
+INPUT = @PROJECT_BINARY_DIR@/src/module.h
OUTPUT_DIRECTORY = @PROJECT_BINARY_DIR@/doc/api/
ENABLED_SECTIONS = public
DISABLE_INDEX = YES
blob - fd3258d46fd1a09d051b363f457031505e22d468
blob + 6b33d62eebc48fbcdb7be41ad8e5cedbb1df9b89
--- FreeBSD/databases/tarantool/pkg-plist
+++ FreeBSD/databases/tarantool/pkg-plist
include/tarantool/luaconf.h
include/tarantool/luajit.h
include/tarantool/lualib.h
-include/tarantool/tarantool.h
+include/tarantool/module.h
man/man1/tarantool.1.gz
man/man1/tarantoolctl.1.gz
%%PORTDOCS%%%%DOCSDIR%%/LICENSE
blob - 25cb8f4934ca5d650869ce533a2b80979f35c14e
blob + 73bf2eb4e402778f8c3501f3a710e96d585d79ef
--- cmake/module.cmake
+++ cmake/module.cmake
# A helper function to extract public API
function(rebuild_module_api)
- set (dstfile "${CMAKE_CURRENT_BINARY_DIR}/tarantool.h")
+ set (dstfile "${CMAKE_CURRENT_BINARY_DIR}/module.h")
set (tmpfile "${dstfile}.new")
set (errcodefile "${CMAKE_CURRENT_BINARY_DIR}/errcode.i")
set (headers)
set (cflags ${cflags} ${CMAKE_C_SYSROOT_FLAG} ${CMAKE_OSX_SYSROOT})
endif()
add_custom_command(OUTPUT ${dstfile}
- COMMAND cat ${CMAKE_CURRENT_SOURCE_DIR}/tarantool_header.h > ${tmpfile}
+ COMMAND cat ${CMAKE_CURRENT_SOURCE_DIR}/module_header.h > ${tmpfile}
COMMAND cat ${headers} | ${CMAKE_SOURCE_DIR}/extra/apigen >> ${tmpfile}
COMMAND ${CMAKE_C_COMPILER}
${cflags}
-E ${CMAKE_SOURCE_DIR}/src/box/errcode.h > ${errcodefile}
COMMAND
grep "enum box_error_code" ${errcodefile} >> ${tmpfile}
- COMMAND cat ${CMAKE_CURRENT_SOURCE_DIR}/tarantool_footer.h >> ${tmpfile}
+ COMMAND cat ${CMAKE_CURRENT_SOURCE_DIR}/module_footer.h >> ${tmpfile}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${tmpfile} ${dstfile}
COMMAND ${CMAKE_COMMAND} -E remove ${errcodefile} ${tmpfile}
DEPENDS ${srcfiles} ${CMAKE_SOURCE_DIR}/src/box/errcode.h
- ${CMAKE_CURRENT_SOURCE_DIR}/tarantool_header.h
- ${CMAKE_CURRENT_SOURCE_DIR}/tarantool_footer.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/module_header.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/module_footer.h
)
add_custom_target(api ALL DEPENDS ${srcfiles} ${dstfile})
install(FILES ${dstfile} DESTINATION ${MODULE_INCLUDEDIR})
endfunction()
-set_source_files_properties("${CMAKE_CURRENT_BINARY_DIR}/tarantool.h" PROPERTIES GENERATED HEADER_FILE_ONLY)
+set_source_files_properties("${CMAKE_CURRENT_BINARY_DIR}/module.h" PROPERTIES GENERATED HEADER_FILE_ONLY)
blob - b4832ed084aad8d2cabba20e75bdec03221da7af
blob + d04191754efcf503c0b312a00dfd32fcb169056b
--- doc/sphinx/reference/capi.rst
+++ doc/sphinx/reference/capi.rst
Module C API
-------------------------------------------------------------------------------
-.. doxygenfile:: tarantool.h
+.. doxygenfile:: module.h
:project: api
blob - 9ee2d4bea1cbe7e79af807d0d2fd41c32abfb766
blob + 1e8ef35df230165b46213b393ab77a94ff0d4e1d
--- extra/rpm/tarantool.rpm.spec.in
+++ extra/rpm/tarantool.rpm.spec.in
"%{_includedir}/tarantool/lua.hpp"
"%{_includedir}/tarantool/luajit.h"
"%{_includedir}/tarantool/lualib.h"
-"%{_includedir}/tarantool/tarantool.h"
+"%{_includedir}/tarantool/module.h"
%files common
%defattr(-,root,root,-)
blob - bc0680466480ecdec857fe89938495cd0164ccde
blob + 1275dc8395e2e52d1d4cfd919115436bff39a639
--- src/CMakeLists.txt
+++ src/CMakeLists.txt
#
enable_tnt_compile_flags()
-add_subdirectory(trivia)
-
include_directories(${LIBEV_INCLUDE_DIR})
include_directories(${LIBEIO_INCLUDE_DIR})
include_directories(${LIBCORO_INCLUDE_DIR})
${lua_sources}
)
+set(api_headers
+ ${CMAKE_BINARY_DIR}/src/trivia/config.h
+ ${CMAKE_SOURCE_DIR}/src/say.h
+ ${CMAKE_SOURCE_DIR}/src/fiber.h
+ ${CMAKE_SOURCE_DIR}/src/coio.h
+ ${CMAKE_SOURCE_DIR}/src/coeio.h
+ ${CMAKE_SOURCE_DIR}/src/lua/utils.h
+ ${CMAKE_SOURCE_DIR}/src/box/txn.h
+ ${CMAKE_SOURCE_DIR}/src/box/tuple.h
+ ${CMAKE_SOURCE_DIR}/src/box/schema.h
+ ${CMAKE_SOURCE_DIR}/src/box/box.h
+ ${CMAKE_SOURCE_DIR}/src/box/index.h
+ ${CMAKE_SOURCE_DIR}/src/box/func.h
+ ${CMAKE_SOURCE_DIR}/src/box/error.h
+ ${CMAKE_SOURCE_DIR}/src/box/lua/call.h
+ ${CMAKE_SOURCE_DIR}/src/latch.h
+ ${CMAKE_SOURCE_DIR}/src/fiber.h
+)
+rebuild_module_api(${api_headers})
+
if (NOT TARGET_OS_DEBIAN_FREEBSD)
if (TARGET_OS_FREEBSD)
set_source_files_properties(
blob - 13df6ee46efc3c5c205667cacbc890aa0b785d01
blob + 609e1df4947de3d85e2f850b631bce03036451f0
--- src/box/alter.cc
+++ src/box/alter.cc
#include <ctype.h>
#include "cluster.h" /* for cluster_set_uuid() */
#include "session.h" /* to fetch the current user. */
+#include "vclock.h" /* VCLOCK_MAX */
/**
* Lock of scheme modification
if (id != old_id) {
/* box.space._cluster:update(old, {{'=', 1, new}} */
cluster_del_server(old_id);
+ cluster_add_server(id, &uuid);
+ } else {
+ cluster_update_server(id, &uuid);
}
+ } else {
+ cluster_add_server(id, &uuid);
}
-
- cluster_set_server(&uuid, id);
}
/**
if (cserver_id_is_reserved(server_id))
tnt_raise(ClientError, ER_SERVER_ID_IS_RESERVED,
(unsigned) server_id);
+ if (server_id >= VCLOCK_MAX)
+ tnt_raise(LoggedError, ER_REPLICA_MAX, server_id);
tt_uuid server_uuid = tuple_field_uuid(new_tuple, 1);
if (tt_uuid_is_nil(&server_uuid))
tnt_raise(ClientError, ER_INVALID_UUID,
blob - 42c5c143f18d3bd05dcf1e36137bbc7009ce3a97
blob + f1083ae99f72db181152eee60d2d1731a24a1f69
--- src/box/box.cc
+++ src/box/box.cc
}
va_end(ap);
assert(data <= buf + sizeof(buf));
- req.tuple = buf;
- req.tuple_end = data;
+ req.tuple = req.key = buf;
+ req.tuple_end = req.key_end = data;
process_rw(&req, NULL);
}
struct tuple *tuple = it->next(it);
/** Assign a new server id. */
uint32_t server_id = tuple ? tuple_field_u32(tuple, 0) + 1 : 1;
- if (server_id >= VCLOCK_MAX)
- tnt_raise(LoggedError, ER_REPLICA_MAX, server_id);
-
boxk(IPROTO_INSERT, BOX_CLUSTER_ID, "%u%s",
(unsigned) server_id, tt_uuid_str(server_uuid));
}
static void
box_set_server_uuid()
{
- struct recovery *r = ::recovery;
- tt_uuid_create(&r->server_uuid);
+ struct recovery *r = recovery;
+
assert(r->server_id == 0);
+
+ /* Unregister local server if it was registered by bootstrap.bin */
if (vclock_has(&r->vclock, 1))
- vclock_del_server(&r->vclock, 1);
- boxk(IPROTO_REPLACE, BOX_CLUSTER_ID, "%u%s",
+ boxk(IPROTO_DELETE, BOX_CLUSTER_ID, "%u", 1);
+ assert(!vclock_has(&r->vclock, 1));
+
+ /* Register local server */
+ tt_uuid_create(&r->server_uuid);
+ boxk(IPROTO_INSERT, BOX_CLUSTER_ID, "%u%s",
1, tt_uuid_str(&r->server_uuid));
+ assert(vclock_has(&r->vclock, 1));
+
/* Remove surrogate server */
vclock_del_server(&r->vclock, 0);
assert(r->server_id == 1);
- assert(vclock_has(&r->vclock, 1));
}
/** Insert a new cluster into _schema */
blob - d69c19133c6086d400cf0e43c3da052e340982d3
blob + 2118f4c502a6ec20c710480232c4f74b055c0ec7
--- src/box/cluster.cc
+++ src/box/cluster.cc
}
void
-cluster_set_server(const tt_uuid *server_uuid, uint32_t server_id)
+cluster_add_server(uint32_t server_id, const struct tt_uuid *server_uuid)
{
struct recovery *r = ::recovery;
/** Checked in the before-commit trigger */
assert(!tt_uuid_is_nil(server_uuid));
- assert(!cserver_id_is_reserved(server_id));
+ assert(!cserver_id_is_reserved(server_id) && server_id < VCLOCK_MAX);
+ assert(!vclock_has(&r->vclock, server_id));
- if (r->server_id == server_id) {
- if (tt_uuid_is_equal(&r->server_uuid, server_uuid))
- return;
- say_warn("server UUID changed to %s",
- tt_uuid_str(server_uuid));
- assert(vclock_has(&r->vclock, server_id));
- memcpy(&r->server_uuid, server_uuid, sizeof(*server_uuid));
- return;
- }
-
/* Add server */
- vclock_add_server(&r->vclock, server_id);
+ vclock_add_server_nothrow(&r->vclock, server_id);
if (tt_uuid_is_equal(&r->server_uuid, server_uuid)) {
/* Assign local server id */
assert(r->server_id == 0);
}
void
+cluster_update_server(uint32_t server_id, const struct tt_uuid *server_uuid)
+{
+ struct recovery *r = ::recovery;
+ /** Checked in the before-commit trigger */
+ assert(!tt_uuid_is_nil(server_uuid));
+ assert(!cserver_id_is_reserved(server_id) && server_id < VCLOCK_MAX);
+ assert(vclock_has(&r->vclock, server_id));
+
+ if (r->server_id == server_id &&
+ !tt_uuid_is_equal(&r->server_uuid, server_uuid)) {
+ say_warn("server UUID changed to %s",
+ tt_uuid_str(server_uuid));
+ r->server_uuid = *server_uuid;
+ }
+}
+
+void
cluster_del_server(uint32_t server_id)
{
struct recovery *r = ::recovery;
+ assert(!cserver_id_is_reserved(server_id) && server_id < VCLOCK_MAX);
+
vclock_del_server(&r->vclock, server_id);
if (r->server_id == server_id) {
r->server_id = 0;
blob - 01f629085d6c970d455e4541398804085e641437
blob + 65aa9cfe93b4f3fc71d0d6b3ed61f17aff78ded4
--- src/box/cluster.h
+++ src/box/cluster.h
* The server is added to the cluster lsn table with LSN 0.
*/
void
-cluster_set_server(const tt_uuid *server_uuid, uint32_t id);
+cluster_add_server(uint32_t server_id, const struct tt_uuid *server_uuid);
+/*
+ * Update UUID of a remote server
+ */
void
+cluster_update_server(uint32_t server_id, const struct tt_uuid *server_uuid);
+
+void
cluster_del_server(uint32_t server_id);
/** }}} **/
blob - 3347d0ae66ebfa222adfa71674a8eeb4b63a961e
blob + 56a0bbffa84edcc861260bcc0c85e41de96c3661
--- src/box/lua/space.cc
+++ src/box/lua/space.cc
#include "box/schema.h"
#include "box/tuple.h"
#include "box/txn.h"
+#include "box/vclock.h" /* VCLOCK_MAX */
/**
* Trigger function for all spaces
lua_setfield(L, -2, "NAME_MAX");
lua_pushnumber(L, FORMAT_ID_MAX);
lua_setfield(L, -2, "FORMAT_ID_MAX");
+ lua_pushnumber(L, VCLOCK_MAX);
+ lua_setfield(L, -2, "REPLICA_MAX");
lua_pop(L, 2); /* box, schema */
}
blob - ccd8bf8b044e87154ed477737710d1169915bbbf
blob + 769201aa17d2f4820c3724ee51272a179f2e6c7b
--- src/box/vclock.h
+++ src/box/vclock.h
static inline void
vclock_add_server_nothrow(struct vclock *vclock, uint32_t server_id)
{
+ assert(server_id < VCLOCK_MAX);
vclock->map |= 1 << server_id;
}
blob - /dev/null
blob + c5920a9f45b215cca06a73e608becd5641ba5a2c (mode 644)
--- /dev/null
+++ src/module_footer.h
+#if defined(__cplusplus)
+} /* extern "C" */
+#endif /* defined(__cplusplus) */
+
+#endif /* TARANTOOL_MODULE_H_INCLUDED */
blob - /dev/null
blob + 8e55e805b38d49272ad40579950f6db691f23be9 (mode 644)
--- /dev/null
+++ src/module_header.h
+#ifndef TARANTOOL_MODULE_H_INCLUDED
+#define TARANTOOL_MODULE_H_INCLUDED
+
+/**
+ * \file
+ */
+
+#include <stddef.h>
+#include <stdarg.h> /* va_list */
+#include <errno.h>
+#include <string.h> /* strerror(3) */
+#include <stdint.h>
+#include <stdbool.h>
+#include <sys/types.h> /* ssize_t */
+
+/** Extern modifier for all public functions */
+#if defined(__cplusplus)
+#define API_EXPORT extern "C" __attribute__ ((visibility ("default")))
+#else
+#define API_EXPORT extern __attribute__ ((visibility ("default")))
+#endif
+
+#if defined(__cplusplus)
+extern "C" {
+#endif /* defined(__cplusplus) */
+
+#include <lua.h> /* does not have extern C wrappers */
blob - 4fb055488047cdcbab21195f5f785c14de00bc78 (mode 644)
blob + /dev/null
--- src/trivia/CMakeLists.txt
+++ /dev/null
-set(api_headers
- ${CMAKE_CURRENT_BINARY_DIR}/config.h
- ${CMAKE_SOURCE_DIR}/src/say.h
- ${CMAKE_SOURCE_DIR}/src/fiber.h
- ${CMAKE_SOURCE_DIR}/src/coio.h
- ${CMAKE_SOURCE_DIR}/src/coeio.h
- ${CMAKE_SOURCE_DIR}/src/lua/utils.h
- ${CMAKE_SOURCE_DIR}/src/box/txn.h
- ${CMAKE_SOURCE_DIR}/src/box/tuple.h
- ${CMAKE_SOURCE_DIR}/src/box/schema.h
- ${CMAKE_SOURCE_DIR}/src/box/box.h
- ${CMAKE_SOURCE_DIR}/src/box/index.h
- ${CMAKE_SOURCE_DIR}/src/box/func.h
- ${CMAKE_SOURCE_DIR}/src/box/error.h
- ${CMAKE_SOURCE_DIR}/src/box/lua/call.h
- ${CMAKE_SOURCE_DIR}/src/latch.h
- ${CMAKE_SOURCE_DIR}/src/fiber.h
-)
-rebuild_module_api(${api_headers})
blob - c5920a9f45b215cca06a73e608becd5641ba5a2c (mode 644)
blob + /dev/null
--- src/trivia/tarantool_footer.h
+++ /dev/null
-#if defined(__cplusplus)
-} /* extern "C" */
-#endif /* defined(__cplusplus) */
-
-#endif /* TARANTOOL_MODULE_H_INCLUDED */
blob - 8e55e805b38d49272ad40579950f6db691f23be9 (mode 644)
blob + /dev/null
--- src/trivia/tarantool_header.h
+++ /dev/null
-#ifndef TARANTOOL_MODULE_H_INCLUDED
-#define TARANTOOL_MODULE_H_INCLUDED
-
-/**
- * \file
- */
-
-#include <stddef.h>
-#include <stdarg.h> /* va_list */
-#include <errno.h>
-#include <string.h> /* strerror(3) */
-#include <stdint.h>
-#include <stdbool.h>
-#include <sys/types.h> /* ssize_t */
-
-/** Extern modifier for all public functions */
-#if defined(__cplusplus)
-#define API_EXPORT extern "C" __attribute__ ((visibility ("default")))
-#else
-#define API_EXPORT extern __attribute__ ((visibility ("default")))
-#endif
-
-#if defined(__cplusplus)
-extern "C" {
-#endif /* defined(__cplusplus) */
-
-#include <lua.h> /* does not have extern C wrappers */
blob - d1561644a8b321253ca40a3c821da0b034a71984
blob + 7427df196fea8ee29b16b17e1d223a89a3d3611f
--- test/CMakeLists.txt
+++ test/CMakeLists.txt
enable_tnt_compile_flags()
-include_directories(${CMAKE_BINARY_DIR}/src/trivia)
function(build_module module files)
add_library(${module} SHARED ${files})
set_target_properties(${module} PROPERTIES PREFIX "")
blob - 2b9744682556b8e36a1cf6be56493e29cdedb3b6
blob + 2d5eff2f16807d852c4bc2c4821326ad6d57e73b
--- test/app/lua/serializer_test.lua
+++ test/app/lua/serializer_test.lua
ffi.cdef[[struct serializer_cdata_test {}]]
local ctype = ffi.typeof('struct serializer_cdata_test')
- --# setopt delimiter ';'
ffi.metatype(ctype, {
__index = {
__serialize = function(obj) return 'unpack' end,
},
__tostring = function(obj) return 'tostring' end
});
- --# setopt delimiter ''
local cdata = ffi.new(ctype)
-- use fiber's userdata for test (supports both __serialize and __tostring)
blob - cf5af20f2331d6fd59404d2f2c4a547608809fe8
blob + f12025201d3cda1ef90cba2e6ee919ed08518394
--- test/app/module_api.c
+++ test/app/module_api.c
#include <stdbool.h>
-#include <tarantool.h>
+#include <module.h>
#include <small/ibuf.h>
blob - a05ebb7ed2a9e7a3b111059ba61a9801ce87f816 (mode 644)
blob + /dev/null
--- test/box/args.result
+++ /dev/null
-tarantool --help
-Tarantool - a Lua application server
-
-Usage: tarantool script.lua [OPTIONS]
-
-All command line options are passed to the interpreted script.
-When no script name is provided, the server responds to:
- -h, --help display this help and exit
- -V, --version print program version and exit
-
-Please visit project home page at http://tarantool.org
-to see online documentation, submit bugs or contribute a patch.
-
-tarantool -h
-Tarantool - a Lua application server
-
-Usage: tarantool script.lua [OPTIONS]
-
-All command line options are passed to the interpreted script.
-When no script name is provided, the server responds to:
- -h, --help display this help and exit
- -V, --version print program version and exit
-
-Please visit project home page at http://tarantool.org
-to see online documentation, submit bugs or contribute a patch.
-
-tarantool -Z
-tarantool: -Z: unknown option
-
-tarantool --no-such-option
-tarantool: --no-such-option: unknown option
-
-tarantool --version --no-such-option
-tarantool: --no-such-option: unknown option
-
-tarantool --version
-Tarantool 1.minor.patch-<rev>-<commit>
-Target: platform <build>
-Build options: flags
-Compiler: cc
-C_FLAGS: flags
-CXX_FLAGS: flags
-
-tarantool -V
-Tarantool 1.minor.patch-<rev>-<commit>
-Target: platform <build>
-Build options: flags
-Compiler: cc
-C_FLAGS: flags
-CXX_FLAGS: flags
-
blob - e5fd0d641e5ccc861c9319dc9020e073a9f271a1 (mode 644)
blob + /dev/null
--- test/box/args.test.py
+++ /dev/null
-import sys
-import os
-
-# mask BFD warnings: https://bugs.launchpad.net/tarantool/+bug/1018356
-sys.stdout.push_filter("unable to read unknown load command 0x2\d+", "")
-server.test_option("--help")
-server.test_option("-h")
-sys.stdout.push_filter("(/\S+)+/tarantool", "tarantool")
-server.test_option("-Z")
-server.test_option("--no-such-option")
-server.test_option("--version --no-such-option")
-sys.stdout.push_filter("(\d)\.\d\.\d(-\d+-\w+)?", "\\1.minor.patch-<rev>-<commit>")
-sys.stdout.push_filter("Target: .*", "Target: platform <build>")
-sys.stdout.push_filter(".*Disable shared arena since.*\n", "")
-sys.stdout.push_filter("Build options: .*", "Build options: flags")
-sys.stdout.push_filter("C_FLAGS:.*", "C_FLAGS: flags")
-sys.stdout.push_filter("CXX_FLAGS:.*", "CXX_FLAGS: flags")
-sys.stdout.push_filter("Compiler: .*", "Compiler: cc")
-
-server.test_option("--version")
-server.test_option("-V ")
-sys.stdout.clear_all_filters()
-
-# Args filter cleanup
-# vim: syntax=python
blob - 5d064b7648a11d7d8ca4fb11acab4fc17043835e (mode 644)
blob + /dev/null
--- test/box/bad_trigger.result
+++ /dev/null
-
- #
- # if on_connect() trigger raises an exception, the connection is dropped
- #
-
-nosuchfunction = nil
----
-...
-function f1() nosuchfunction() end
----
-...
-type(box.session.on_connect(f1))
----
-- function
-...
-greeting: True
-fixheader: True
-error code 32
-error message: [string "function f1() nosuchfunction() end"]:1: attempt to call global 'nosuchfunction' (a nil value)
-eof: True
-box.session.on_connect(nil, f1)
----
-...
blob - 7d200b9218583bf0885ada4226bb81f259d26155 (mode 644)
blob + /dev/null
--- test/box/bad_trigger.test.py
+++ /dev/null
-from lib.box_connection import BoxConnection
-from lib.tarantool_connection import TarantoolConnection
-from tarantool import NetworkError
-from tarantool.const import IPROTO_GREETING_SIZE, IPROTO_CODE, IPROTO_ERROR, \
- REQUEST_TYPE_ERROR
-import socket
-import msgpack
-
-print """
- #
- # if on_connect() trigger raises an exception, the connection is dropped
- #
- """
-
-# silence possible error of strict mode
-server.admin("nosuchfunction = nil")
-server.admin("function f1() nosuchfunction() end")
-server.admin("type(box.session.on_connect(f1))")
-
-unpacker = msgpack.Unpacker(use_list = False)
-
-conn = TarantoolConnection(server.iproto.host, server.iproto.port)
-conn.connect()
-s = conn.socket
-
-# Read greeting
-print 'greeting: ', len(s.recv(IPROTO_GREETING_SIZE)) == IPROTO_GREETING_SIZE
-
-# Read error packet
-IPROTO_FIXHEADER_SIZE = 5
-fixheader = s.recv(IPROTO_FIXHEADER_SIZE)
-print 'fixheader: ', len(fixheader) == IPROTO_FIXHEADER_SIZE
-unpacker.feed(fixheader)
-packet_len = unpacker.unpack()
-packet = s.recv(packet_len)
-unpacker.feed(packet)
-
-# Parse packet
-header = unpacker.unpack()
-body = unpacker.unpack()
-print 'error code', (header[IPROTO_CODE] & (REQUEST_TYPE_ERROR - 1))
-print 'error message: ', body[IPROTO_ERROR]
-print 'eof:', len(s.recv(1024)) == 0
-s.close()
-
-server.admin("box.session.on_connect(nil, f1)")
blob - ded58dba3ff1cd52a779c06cfc3251b4a7ace958 (mode 644)
blob + /dev/null
--- test/box/bootstrap.result
+++ /dev/null
-dofile("<sourcedir>/extra/schema_erase.lua")
----
-...
-box.space._schema:select{}
----
-- - ['cluster', '<cluster uuid>']
-...
-box.space._cluster:select{}
----
-- - [1, '<server uuid>']
-...
-box.space._space:select{}
----
-- []
-...
-box.space._index:select{}
----
-- []
-...
-box.space._user:select{}
----
-- []
-...
-box.space._func:select{}
----
-- []
-...
-box.space._priv:select{}
----
-- []
-...
-dofile("<sourcedir>/extra/schema_fill.lua")
----
-...
-box.snapshot()
----
-- ok
-...
-box.space._schema:select{}
----
-- - ['cluster', '<cluster uuid>']
- - ['max_id', 511]
- - ['version', 1, 6]
-...
-box.space._cluster:select{}
----
-- - [1, '<server uuid>']
-...
-box.space._space:select{}
----
-- - [272, 1, '_schema', 'memtx', 0, '', [{'type': 'str', 'name': 'key'}]]
- - [280, 1, '_space', 'memtx', 0, '', [{'name': 'id', 'type': 'num'}, {'name': 'owner',
- 'type': 'num'}, {'name': 'name', 'type': 'str'}, {'name': 'engine', 'type': 'str'},
- {'name': 'field_count', 'type': 'num'}, {'name': 'flags', 'type': 'str'}, {
- 'name': 'format', 'type': '*'}]]
- - [281, 1, '_vspace', 'sysview', 0, '', [{'name': 'id', 'type': 'num'}, {'name': 'owner',
- 'type': 'num'}, {'name': 'name', 'type': 'str'}, {'name': 'engine', 'type': 'str'},
- {'name': 'field_count', 'type': 'num'}, {'name': 'flags', 'type': 'str'}, {
- 'name': 'format', 'type': '*'}]]
- - [288, 1, '_index', 'memtx', 0, '', [{'name': 'id', 'type': 'num'}, {'name': 'iid',
- 'type': 'num'}, {'name': 'name', 'type': 'str'}, {'name': 'type', 'type': 'str'},
- {'name': 'opts', 'type': 'array'}, {'name': 'parts', 'type': 'array'}]]
- - [289, 1, '_vindex', 'sysview', 0, '', [{'name': 'id', 'type': 'num'}, {'name': 'iid',
- 'type': 'num'}, {'name': 'name', 'type': 'str'}, {'name': 'type', 'type': 'str'},
- {'name': 'opts', 'type': 'array'}, {'name': 'parts', 'type': 'array'}]]
- - [296, 1, '_func', 'memtx', 0, '', [{'name': 'id', 'type': 'num'}, {'name': 'owner',
- 'type': 'num'}, {'name': 'name', 'type': 'str'}, {'name': 'setuid', 'type': 'num'}]]
- - [297, 1, '_vfunc', 'sysview', 0, '', [{'name': 'id', 'type': 'num'}, {'name': 'owner',
- 'type': 'num'}, {'name': 'name', 'type': 'str'}, {'name': 'setuid', 'type': 'num'}]]
- - [304, 1, '_user', 'memtx', 0, '', [{'name': 'id', 'type': 'num'}, {'name': 'owner',
- 'type': 'num'}, {'name': 'name', 'type': 'str'}, {'name': 'type', 'type': 'str'},
- {'name': 'auth', 'type': '*'}]]
- - [305, 1, '_vuser', 'sysview', 0, '', [{'name': 'id', 'type': 'num'}, {'name': 'owner',
- 'type': 'num'}, {'name': 'name', 'type': 'str'}, {'name': 'type', 'type': 'str'},
- {'name': 'auth', 'type': '*'}]]
- - [312, 1, '_priv', 'memtx', 0, '', [{'name': 'grantor', 'type': 'num'}, {'name': 'grantee',
- 'type': 'num'}, {'name': 'object_type', 'type': 'str'}, {'name': 'object_id',
- 'type': 'num'}, {'name': 'privilege', 'type': 'num'}]]
- - [313, 1, '_vpriv', 'sysview', 0, '', [{'name': 'grantor', 'type': 'num'}, {'name': 'grantee',
- 'type': 'num'}, {'name': 'object_type', 'type': 'str'}, {'name': 'object_id',
- 'type': 'num'}, {'name': 'privilege', 'type': 'num'}]]
- - [320, 1, '_cluster', 'memtx', 0, '', [{'name': 'id', 'type': 'num'}, {'name': 'uuid',
- 'type': 'str'}]]
-...
-box.space._index:select{}
----
-- - [272, 0, 'primary', 'tree', {'unique': true}, [[0, 'str']]]
- - [280, 0, 'primary', 'tree', {'unique': true}, [[0, 'num']]]
- - [280, 1, 'owner', 'tree', {'unique': false}, [[1, 'num']]]
- - [280, 2, 'name', 'tree', {'unique': true}, [[2, 'str']]]
- - [281, 0, 'primary', 'tree', {'unique': true}, [[0, 'num']]]
- - [281, 1, 'owner', 'tree', {'unique': false}, [[1, 'num']]]
- - [281, 2, 'name', 'tree', {'unique': true}, [[2, 'str']]]
- - [288, 0, 'primary', 'tree', {'unique': true}, [[0, 'num'], [1, 'num']]]
- - [288, 2, 'name', 'tree', {'unique': true}, [[0, 'num'], [2, 'str']]]
- - [289, 0, 'primary', 'tree', {'unique': true}, [[0, 'num'], [1, 'num']]]
- - [289, 2, 'name', 'tree', {'unique': true}, [[0, 'num'], [2, 'str']]]
- - [296, 0, 'primary', 'tree', {'unique': true}, [[0, 'num']]]
- - [296, 1, 'owner', 'tree', {'unique': false}, [[1, 'num']]]
- - [296, 2, 'name', 'tree', {'unique': true}, [[2, 'str']]]
- - [297, 0, 'primary', 'tree', {'unique': true}, [[0, 'num']]]
- - [297, 1, 'owner', 'tree', {'unique': false}, [[1, 'num']]]
- - [297, 2, 'name', 'tree', {'unique': true}, [[2, 'str']]]
- - [304, 0, 'primary', 'tree', {'unique': true}, [[0, 'num']]]
- - [304, 1, 'owner', 'tree', {'unique': false}, [[1, 'num']]]
- - [304, 2, 'name', 'tree', {'unique': true}, [[2, 'str']]]
- - [305, 0, 'primary', 'tree', {'unique': true}, [[0, 'num']]]
- - [305, 1, 'owner', 'tree', {'unique': false}, [[1, 'num']]]
- - [305, 2, 'name', 'tree', {'unique': true}, [[2, 'str']]]
- - [312, 0, 'primary', 'tree', {'unique': true}, [[1, 'num'], [2, 'str'], [3, 'num']]]
- - [312, 1, 'owner', 'tree', {'unique': false}, [[0, 'num']]]
- - [312, 2, 'object', 'tree', {'unique': false}, [[2, 'str'], [3, 'num']]]
- - [313, 0, 'primary', 'tree', {'unique': true}, [[1, 'num'], [2, 'str'], [3, 'num']]]
- - [313, 1, 'owner', 'tree', {'unique': false}, [[0, 'num']]]
- - [313, 2, 'object', 'tree', {'unique': false}, [[2, 'str'], [3, 'num']]]
- - [320, 0, 'primary', 'tree', {'unique': true}, [[0, 'num']]]
- - [320, 1, 'uuid', 'tree', {'unique': true}, [[1, 'str']]]
-...
-box.space._user:select{}
----
-- - [0, 1, 'guest', 'user']
- - [1, 1, 'admin', 'user']
- - [2, 1, 'public', 'role']
- - [3, 1, 'replication', 'role']
-...
-box.space._func:select{}
----
-- - [1, 1, 'box.schema.user.info', 1]
-...
-box.space._priv:select{}
----
-- - [1, 0, 'role', 2, 4]
- - [1, 1, 'universe', 0, 7]
- - [1, 2, 'function', 1, 4]
- - [1, 2, 'space', 281, 1]
- - [1, 2, 'space', 289, 1]
- - [1, 2, 'space', 297, 1]
- - [1, 2, 'space', 305, 1]
- - [1, 2, 'space', 313, 1]
- - [1, 3, 'space', 320, 2]
- - [1, 3, 'universe', 0, 1]
-...
blob - 3f4e557cc8a61093dc34176f40ed8e813e32199e (mode 644)
blob + /dev/null
--- test/box/bootstrap.test.py
+++ /dev/null
-
-import sys
-import yaml
-
-server_uuid = server.get_param('server')['uuid']
-sys.stdout.push_filter(server_uuid, '<server uuid>')
-cluster_uuid = yaml.load(server.admin('box.space._schema:get("cluster")',
- silent = True))[0][1]
-sys.stdout.push_filter(cluster_uuid, '<cluster uuid>')
-sys.stdout.push_filter(server.sourcedir, '<sourcedir>')
-
-server.admin('dofile("%s/extra/schema_erase.lua")' % server.sourcedir)
-server.admin('box.space._schema:select{}')
-server.admin('box.space._cluster:select{}')
-server.admin('box.space._space:select{}')
-server.admin('box.space._index:select{}')
-server.admin('box.space._user:select{}')
-server.admin('box.space._func:select{}')
-server.admin('box.space._priv:select{}')
-
-server.admin('dofile("%s/extra/schema_fill.lua")' % server.sourcedir)
-server.admin("box.snapshot()")
-server.restart()
-
-server.admin('box.space._schema:select{}')
-server.admin('box.space._cluster:select{}')
-server.admin('box.space._space:select{}')
-server.admin('box.space._index:select{}')
-server.admin('box.space._user:select{}')
-server.admin('box.space._func:select{}')
-server.admin('box.space._priv:select{}')
-
-# Cleanup
-sys.stdout.pop_filter()
blob - 74a128be79979598df94953e5d01807d9ae8cb95 (mode 644)
blob + /dev/null
--- test/box/call.result
+++ /dev/null
-box.schema.user.create('test', { password = 'test' })
----
-...
-box.schema.user.grant('test', 'execute,read,write', 'universe')
----
-...
-exp_notation = 1e123
----
-...
-function f1() return 'testing', 1, false, -1, 1.123, math.abs(exp_notation - 1e123) < 0.1, nil end
----
-...
-f1()
----
-- testing
-- 1
-- false
-- -1
-- 1.123
-- true
-- null
-...
-call f1 ()
-- [testing]
-- [1]
-- [false]
-- [-1]
-- [1.123]
-- [true]
-- [null]
-
-f1=nil
----
-...
-call f1 ()
-error: {code: ER_NO_SUCH_PROC, reason: Procedure 'f1' is not defined}
-
-function f1() return f1 end
----
-...
-call f1 ()
-error: {code: ER_PROC_LUA, reason: unsupported Lua type 'function'}
-
-call box.error (33333, 'Hey!')
-error: {code: U, reason: Unknown error}
-
-
-# A test case for Bug#103491
-# server CALL processing bug with name path longer than two
-# https://bugs.launchpad.net/tarantool/+bug/1034912
-
-f = function() return 'OK' end
----
-...
-test = {}
----
-...
-test.f = f
----
-...
-test.test = {}
----
-...
-test.test.f = f
----
-...
-call f ()
-- [OK]
-
-call test.f ()
-- [OK]
-
-call test.test.f ()
-- [OK]
-
-
-# Test for Bug #955226
-# Lua Numbers are passed back wrongly as strings
-#
-
-function foo() return 1, 2, '1', '2' end
----
-...
-call foo ()
-- [1]
-- [2]
-- ['1']
-- ['2']
-
-function f1(...) return {...} end
----
-...
-function f2(...) return f1({...}) end
----
-...
-call f1 ('test_', 'test_')
-- [test_, test_]
-
-call f2 ('test_', 'test_')
-- [test_, test_]
-
-call f1 ()
-- []
-
-call f2 ()
-- []
-
-function f3() return {{'hello'}, {'world'}} end
----
-...
-call f3 ()
-- [hello]
-- [world]
-
-function f3() return {'hello', {'world'}} end
----
-...
-call f3 ()
-- - hello
- - [world]
-
-function f3() return 'hello', {{'world'}, {'canada'}} end
----
-...
-call f3 ()
-- [hello]
-- - [world]
- - [canada]
-
-function f3() return {}, '123', {{}, {}} end
----
-...
-call f3 ()
-- []
-- ['123']
-- - []
- - []
-
-function f3() return { {{'hello'}} } end
----
-...
-call f3 ()
-- - [hello]
-
-function f3() return { box.tuple.new('hello'), {'world'} } end
----
-...
-call f3 ()
-- [hello]
-- [world]
-
-function f3() return { {'world'}, box.tuple.new('hello') } end
----
-...
-call f3 ()
-- [world]
-- [hello]
-
-function f3() return { { test={1,2,3} }, { test2={1,2,3} } } end
----
-...
-call f3 ()
-- - test: [1, 2, 3]
- - test2: [1, 2, 3]
-
-call f1 ('jason',)
-- [jason]
-
-call f1 ('jason', 1, 'test', 2, 'stewart')
-- [jason, 1, test, 2, stewart]
-
-space = box.schema.space.create('tweedledum', { id = 0 })
----
-...
-index = space:create_index('primary', { type = 'hash' })
----
-...
-function myreplace(...) return space:replace{...} end
----
-...
-function myinsert(...) return space:insert{...} end
----
-...
-call myinsert (1, 'test box delete')
-- [1, test box delete]
-
-call space:delete (1,)
-- [1, test box delete]
-
-call myinsert (1, 'test box delete')
-- [1, test box delete]
-
-call space:delete (1,)
-- [1, test box delete]
-
-call space:delete (1,)
-[]
-
-call myinsert (2, 'test box delete')
-- [2, test box delete]
-
-call space:delete (1,)
-[]
-
-call space:delete (2,)
-- [2, test box delete]
-
-call space:delete (2,)
-[]
-
-space:delete{2}
----
-...
-call myinsert (2, 'test box delete')
-- [2, test box delete]
-
-call space:get (2,)
-- [2, test box delete]
-
-space:delete{2}
----
-- [2, 'test box delete']
-...
-call space:get (2,)
-[]
-
-call myinsert (2, 'test box.select()')
-- [2, test box.select()]
-
-call space:get (2,)
-- [2, test box.select()]
-
-call space:select (2,)
-- [2, test box.select()]
-
-space:get{2}
----
-- [2, 'test box.select()']
-...
-space:select{2}
----
-- - [2, 'test box.select()']
-...
-space:get{1}
----
-...
-space:select{1}
----
-- []
-...
-call myreplace (2, 'hello', 'world')
-- [2, hello, world]
-
-call myreplace (2, 'goodbye', 'universe')
-- [2, goodbye, universe]
-
-call space:get (2,)
-- [2, goodbye, universe]
-
-call space:select (2,)
-- [2, goodbye, universe]
-
-space:get{2}
----
-- [2, 'goodbye', 'universe']
-...
-space:select{2}
----
-- - [2, 'goodbye', 'universe']
-...
-call myreplace (2,)
-- [2]
-
-call space:get (2,)
-- [2]
-
-call space:select (2,)
-- [2]
-
-call space:delete (2,)
-- [2]
-
-call space:delete (2,)
-[]
-
-call myinsert (3, 'old', 2)
-- [3, old, 2]
-
-call myinsert (3, 'old', 2)
-error: {code: ER_TUPLE_FOUND, reason: Duplicate key exists in unique index 'primary'
- in space 'tweedledum'}
-
-space:update({3}, {{'=', 1, 4}, {'=', 2, 'new'}})
----
-- error: Attempt to modify a tuple field which is part of index 'primary' in space
- 'tweedledum'
-...
-space:insert(space:get{3}:update{{'=', 1, 4}, {'=', 2, 'new'}}) space:delete{3}
----
-...
-call space:get (4,)
-- [4, new, 2]
-
-call space:select (4,)
-- [4, new, 2]
-
-space:update({4}, {{'+', 3, 1}})
----
-- [4, 'new', 3]
-...
-space:update({4}, {{'-', 3, 1}})
----
-- [4, 'new', 2]
-...
-call space:get (4,)
-- [4, new, 2]
-
-call space:select (4,)
-- [4, new, 2]
-
-function field_x(key, field_index) return space:get(key)[field_index] end
----
-...
-call field_x (4, 1)
-- [4]
-
-call field_x (4, 2)
-- [new]
-
-call space:delete (4,)
-- [4, new, 2]
-
-space:drop()
----
-...
-space = box.schema.space.create('tweedledum')
----
-...
-index = space:create_index('primary', { type = 'tree' })
----
-...
-eval (return 1)()
----
-[1]
-
-function f(...) return 1 end
----
-...
-call f()
----
-- [1]
-
-eval (return 1, 2, 3)()
----
-[1, 2, 3]
-
-function f(...) return 1, 2, 3 end
----
-...
-call f()
----
-- [1]
-- [2]
-- [3]
-
-eval (return true)()
----
-[true]
-
-function f(...) return true end
----
-...
-call f()
----
-- [true]
-
-eval (return nil)()
----
-[null]
-
-function f(...) return nil end
----
-...
-call f()
----
-- [null]
-
-eval (return )()
----
-[]
-
-function f(...) return end
----
-...
-call f()
----
-[]
-
-eval (return {})()
----
-- []
-
-function f(...) return {} end
----
-...
-call f()
----
-- []
-
-eval (return {1})()
----
-- [1]
-
-function f(...) return {1} end
----
-...
-call f()
----
-- [1]
-
-eval (return {1, 2, 3})()
----
-- [1, 2, 3]
-
-function f(...) return {1, 2, 3} end
----
-...
-call f()
----
-- [1, 2, 3]
-
-eval (return {k1 = 'v1', k2 = 'v2'})()
----
-- {k1: v1, k2: v2}
-
-function f(...) return {k1 = 'v1', k2 = 'v2'} end
----
-...
-call f()
----
-- - {k1: v1, k2: v2}
-
-eval (return {k1 = 'v1', k2 = 'v2'})()
----
-- {k1: v1, k2: v2}
-
-function f(...) return {k1 = 'v1', k2 = 'v2'} end
----
-...
-call f()
----
-- - {k1: v1, k2: v2}
-
-eval (return {s = {1, 1428578535}, u = 1428578535, v = {}, c = {['2'] = {1, 1428578535}, ['106'] = { 1, 1428578535} }, pc = {['2'] = {1, 1428578535, 9243}, ['106'] = {1, 1428578535, 9243}}})()
----
-- c:
- '106': [1, 1428578535]
- '2': [1, 1428578535]
- pc:
- '106': [1, 1428578535, 9243]
- '2': [1, 1428578535, 9243]
- s: [1, 1428578535]
- u: 1428578535
- v: []
-
-function f(...) return {s = {1, 1428578535}, u = 1428578535, v = {}, c = {['2'] = {1, 1428578535}, ['106'] = { 1, 1428578535} }, pc = {['2'] = {1, 1428578535, 9243}, ['106'] = {1, 1428578535, 9243}}} end
----
-...
-call f()
----
-- - c:
- '106': [1, 1428578535]
- '2': [1, 1428578535]
- pc:
- '106': [1, 1428578535, 9243]
- '2': [1, 1428578535, 9243]
- s: [1, 1428578535]
- u: 1428578535
- v: []
-
-eval (return true, {s = {1, 1428578535}, u = 1428578535, v = {}, c = {['2'] = {1, 1428578535}, ['106'] = { 1, 1428578535} }, pc = {['2'] = {1, 1428578535, 9243}, ['106'] = {1, 1428578535, 9243}}})()
----
-- true
-- c:
- '106': [1, 1428578535]
- '2': [1, 1428578535]
- pc:
- '106': [1, 1428578535, 9243]
- '2': [1, 1428578535, 9243]
- s: [1, 1428578535]
- u: 1428578535
- v: []
-
-function f(...) return true, {s = {1, 1428578535}, u = 1428578535, v = {}, c = {['2'] = {1, 1428578535}, ['106'] = { 1, 1428578535} }, pc = {['2'] = {1, 1428578535, 9243}, ['106'] = {1, 1428578535, 9243}}} end
----
-...
-call f()
----
-- [true]
-- - c:
- '106': [1, 1428578535]
- '2': [1, 1428578535]
- pc:
- '106': [1, 1428578535, 9243]
- '2': [1, 1428578535, 9243]
- s: [1, 1428578535]
- u: 1428578535
- v: []
-
-eval (return {s = {1, 1428578535}, u = 1428578535, v = {}, c = {['2'] = {1, 1428578535}, ['106'] = { 1, 1428578535} }, pc = {['2'] = {1, 1428578535, 9243}, ['106'] = {1, 1428578535, 9243}}}, true)()
----
-- c:
- '106': [1, 1428578535]
- '2': [1, 1428578535]
- pc:
- '106': [1, 1428578535, 9243]
- '2': [1, 1428578535, 9243]
- s: [1, 1428578535]
- u: 1428578535
- v: []
-- true
-
-function f(...) return {s = {1, 1428578535}, u = 1428578535, v = {}, c = {['2'] = {1, 1428578535}, ['106'] = { 1, 1428578535} }, pc = {['2'] = {1, 1428578535, 9243}, ['106'] = {1, 1428578535, 9243}}}, true end
----
-...
-call f()
----
-- - c:
- '106': [1, 1428578535]
- '2': [1, 1428578535]
- pc:
- '106': [1, 1428578535, 9243]
- '2': [1, 1428578535, 9243]
- s: [1, 1428578535]
- u: 1428578535
- v: []
-- [true]
-
-t = box.tuple.new('tuple', {1, 2, 3}, { k1 = 'v', k2 = 'v2'})
----
-...
-eval (return t)()
----
-- - tuple
- - [1, 2, 3]
- - {k1: v, k2: v2}
-
-function f(...) return t end
----
-...
-call f()
----
-- - tuple
- - [1, 2, 3]
- - {k1: v, k2: v2}
-
-eval (return t, t, t)()
----
-- - tuple
- - [1, 2, 3]
- - {k1: v, k2: v2}
-- - tuple
- - [1, 2, 3]
- - {k1: v, k2: v2}
-- - tuple
- - [1, 2, 3]
- - {k1: v, k2: v2}
-
-function f(...) return t, t, t end
----
-...
-call f()
----
-- - tuple
- - [1, 2, 3]
- - {k1: v, k2: v2}
-- - tuple
- - [1, 2, 3]
- - {k1: v, k2: v2}
-- - tuple
- - [1, 2, 3]
- - {k1: v, k2: v2}
-
-eval (return {t})()
----
-- - - tuple
- - [1, 2, 3]
- - {k1: v, k2: v2}
-
-function f(...) return {t} end
----
-...
-call f()
----
-- - tuple
- - [1, 2, 3]
- - {k1: v, k2: v2}
-
-eval (return {t, t, t})()
----
-- - - tuple
- - [1, 2, 3]
- - {k1: v, k2: v2}
- - - tuple
- - [1, 2, 3]
- - {k1: v, k2: v2}
- - - tuple
- - [1, 2, 3]
- - {k1: v, k2: v2}
-
-function f(...) return {t, t, t} end
----
-...
-call f()
----
-- - tuple
- - [1, 2, 3]
- - {k1: v, k2: v2}
-- - tuple
- - [1, 2, 3]
- - {k1: v, k2: v2}
-- - tuple
- - [1, 2, 3]
- - {k1: v, k2: v2}
-
-eval (return error('exception'))()
----
-error: {code: ER_PROC_LUA, reason: exception}
-
-function f(...) return error('exception') end
----
-...
-call f()
----
-error: {code: ER_PROC_LUA, reason: exception}
-
-eval (return box.error(0))()
----
-error: {code: ER_OK, reason: Unknown error}
-
-function f(...) return box.error(0) end
----
-...
-call f()
----
-error: {code: ER_OK, reason: Unknown error}
-
-eval (return ...)()
----
-[]
-
-function f(...) return ... end
----
-...
-call f()
----
-[]
-
-eval (return ...)(1,2,3)
----
-[1, 2, 3]
-
-function f(...) return ... end
----
-...
-call f(1,2,3)
----
-- [1]
-- [2]
-- [3]
-
-eval (return ...)(None,None,None)
----
-[null, null, null]
-
-function f(...) return ... end
----
-...
-call f(None,None,None)
----
-- [null]
-- [null]
-- [null]
-
-eval (return ...)({'k2': 'v2', 'k1': 'v1'})
----
-- {k1: v1, k2: v2}
-
-function f(...) return ... end
----
-...
-call f({'k2': 'v2', 'k1': 'v1'})
----
-- - {k1: v1, k2: v2}
-
-eval (return space:auto_increment({"transaction"}))()
----
-- [1, transaction]
-
-function f(...) return space:auto_increment({"transaction"}) end
----
-...
-call f()
----
-- [2, transaction]
-
-eval (return space:select{})()
----
-- - [1, transaction]
- - [2, transaction]
-
-function f(...) return space:select{} end
----
-...
-call f()
----
-- [1, transaction]
-- [2, transaction]
-
-eval (return box.begin(), space:auto_increment({"failed"}), box.rollback())()
----
-- null
-- [3, failed]
-
-function f(...) return box.begin(), space:auto_increment({"failed"}), box.rollback() end
----
-...
-call f()
----
-- [null]
-- [3, failed]
-
-eval (return space:select{})()
----
-- - [1, transaction]
- - [2, transaction]
-
-function f(...) return space:select{} end
----
-...
-call f()
----
-- [1, transaction]
-- [2, transaction]
-
-eval (return require("fiber").sleep(0))()
----
-[]
-
-function f(...) return require("fiber").sleep(0) end
----
-...
-call f()
----
-[]
-
-eval (!invalid expression)()
----
-error: {code: ER_PROC_LUA, reason: 'eval:1: unexpected symbol near ''!'''}
-
-space:drop()
----
-...
-box.schema.user.drop('test')
----
-...
blob - 20f9bce62db5f25bb2e0877cefd70d13360784bc (mode 644)
blob + /dev/null
--- test/box/call.test.py
+++ /dev/null
-import os
-import sys
-
-def call(name, *args):
- return iproto.call(name, *args)
-
-admin("box.schema.user.create('test', { password = 'test' })")
-admin("box.schema.user.grant('test', 'execute,read,write', 'universe')")
-iproto.authenticate('test', 'test')
-# workaround for gh-770 centos 6 float representation
-admin('exp_notation = 1e123')
-admin("function f1() return 'testing', 1, false, -1, 1.123, math.abs(exp_notation - 1e123) < 0.1, nil end")
-admin("f1()")
-call("f1")
-admin("f1=nil")
-call("f1")
-admin("function f1() return f1 end")
-call("f1")
-
-# A test case for https://github.com/tarantool/tarantool/issues/44
-# IPROTO required!
-call("box.error", 33333, 'Hey!')
-
-print """
-# A test case for Bug#103491
-# server CALL processing bug with name path longer than two
-# https://bugs.launchpad.net/tarantool/+bug/1034912
-"""
-admin("f = function() return 'OK' end")
-admin("test = {}")
-admin("test.f = f")
-admin("test.test = {}")
-admin("test.test.f = f")
-call("f")
-call("test.f")
-call("test.test.f")
-
-print """
-# Test for Bug #955226
-# Lua Numbers are passed back wrongly as strings
-#
-"""
-admin("function foo() return 1, 2, '1', '2' end")
-call("foo")
-
-#
-# check how well we can return tables
-#
-admin("function f1(...) return {...} end")
-admin("function f2(...) return f1({...}) end")
-call("f1", 'test_', 'test_')
-call("f2", 'test_', 'test_')
-call("f1")
-call("f2")
-#
-# check multi-tuple return
-#
-admin("function f3() return {{'hello'}, {'world'}} end")
-call("f3")
-admin("function f3() return {'hello', {'world'}} end")
-call("f3")
-admin("function f3() return 'hello', {{'world'}, {'canada'}} end")
-call("f3")
-admin("function f3() return {}, '123', {{}, {}} end")
-call("f3")
-admin("function f3() return { {{'hello'}} } end")
-call("f3")
-admin("function f3() return { box.tuple.new('hello'), {'world'} } end")
-call("f3")
-admin("function f3() return { {'world'}, box.tuple.new('hello') } end")
-call("f3")
-admin("function f3() return { { test={1,2,3} }, { test2={1,2,3} } } end")
-call("f3")
-
-call("f1", 'jason')
-call("f1", 'jason', 1, 'test', 2, 'stewart')
-
-admin("space = box.schema.space.create('tweedledum', { id = 0 })")
-admin("index = space:create_index('primary', { type = 'hash' })")
-
-admin("function myreplace(...) return space:replace{...} end")
-admin("function myinsert(...) return space:insert{...} end")
-
-call("myinsert", 1, 'test box delete')
-call("space:delete", 1)
-call("myinsert", 1, 'test box delete')
-call("space:delete", 1)
-call("space:delete", 1)
-call("myinsert", 2, 'test box delete')
-call("space:delete", 1)
-call("space:delete", 2)
-call("space:delete", 2)
-admin("space:delete{2}")
-
-call("myinsert", 2, 'test box delete')
-call("space:get", 2)
-admin("space:delete{2}")
-call("space:get", 2)
-call("myinsert", 2, 'test box.select()')
-call("space:get", 2)
-call("space:select", 2)
-admin("space:get{2}")
-admin("space:select{2}")
-admin("space:get{1}")
-admin("space:select{1}")
-call("myreplace", 2, 'hello', 'world')
-call("myreplace", 2, 'goodbye', 'universe')
-call("space:get", 2)
-call("space:select", 2)
-admin("space:get{2}")
-admin("space:select{2}")
-call("myreplace", 2)
-call("space:get", 2)
-call("space:select", 2)
-call("space:delete", 2)
-call("space:delete", 2)
-call("myinsert", 3, 'old', 2)
-# test that insert produces a duplicate key error
-call("myinsert", 3, 'old', 2)
-admin("space:update({3}, {{'=', 1, 4}, {'=', 2, 'new'}})")
-admin("space:insert(space:get{3}:update{{'=', 1, 4}, {'=', 2, 'new'}}) space:delete{3}")
-call("space:get", 4)
-call("space:select", 4)
-admin("space:update({4}, {{'+', 3, 1}})")
-admin("space:update({4}, {{'-', 3, 1}})")
-call("space:get", 4)
-call("space:select", 4)
-admin("function field_x(key, field_index) return space:get(key)[field_index] end")
-call("field_x", 4, 1)
-call("field_x", 4, 2)
-call("space:delete", 4)
-admin("space:drop()")
-
-admin("space = box.schema.space.create('tweedledum')")
-admin("index = space:create_index('primary', { type = 'tree' })")
-
-
-def lua_eval(name, *args):
- print 'eval (%s)(%s)' % (name, ','.join([ str(arg) for arg in args]))
- print '---'
- print iproto.py_con.eval(name, args)
-
-def lua_call(name, *args):
- print 'call %s(%s)' % (name, ','.join([ str(arg) for arg in args]))
- print '---'
- print iproto.py_con.call(name, args)
-
-def test(expr, *args):
- lua_eval('return ' + expr, *args)
- admin('function f(...) return ' + expr + ' end')
- lua_call('f', *args)
-
-# Return values
-test("1")
-test("1, 2, 3")
-test("true")
-test("nil")
-test("")
-test("{}")
-test("{1}")
-test("{1, 2, 3}")
-test("{k1 = 'v1', k2 = 'v2'}")
-test("{k1 = 'v1', k2 = 'v2'}")
-# gh-791: maps are wrongly assumed to be arrays
-test("{s = {1, 1428578535}, u = 1428578535, v = {}, c = {['2'] = {1, 1428578535}, ['106'] = { 1, 1428578535} }, pc = {['2'] = {1, 1428578535, 9243}, ['106'] = {1, 1428578535, 9243}}}")
-test("true, {s = {1, 1428578535}, u = 1428578535, v = {}, c = {['2'] = {1, 1428578535}, ['106'] = { 1, 1428578535} }, pc = {['2'] = {1, 1428578535, 9243}, ['106'] = {1, 1428578535, 9243}}}")
-test("{s = {1, 1428578535}, u = 1428578535, v = {}, c = {['2'] = {1, 1428578535}, ['106'] = { 1, 1428578535} }, pc = {['2'] = {1, 1428578535, 9243}, ['106'] = {1, 1428578535, 9243}}}, true")
-admin("t = box.tuple.new('tuple', {1, 2, 3}, { k1 = 'v', k2 = 'v2'})")
-test("t")
-test("t, t, t")
-test("{t}")
-test("{t, t, t}")
-test("error('exception')")
-test("box.error(0)")
-test('...')
-test('...', 1, 2, 3)
-test('...', None, None, None)
-test('...', { 'k1': 'v1', 'k2': 'v2'})
-# Transactions
-test('space:auto_increment({"transaction"})')
-test('space:select{}')
-test('box.begin(), space:auto_increment({"failed"}), box.rollback()')
-test('space:select{}')
-test('require("fiber").sleep(0)')
-# Other
-lua_eval('!invalid expression')
-
-admin("space:drop()")
-admin("box.schema.user.drop('test')")
-
-# Re-connect after removing user
-iproto.py_con.close()
blob - de9e07b9d5e088d21b5520d736f6204f075a3ec3
blob + a9693c6165422dc69c97e2d63f8fe8a4c025417f
--- test/box/function1.c
+++ test/box/function1.c
#include <stdbool.h>
-#include "tarantool.h"
+#include "module.h"
#include <stdio.h>
blob - 678026f3a28c1ca26d1ee8563005da36af1dbb15 (mode 644)
blob + /dev/null
--- test/box/iproto.result
+++ /dev/null
-box.schema.user.grant('guest', 'read,write,execute', 'universe')
----
-...
-
-#
-# iproto packages test
-#
-
-
-# Test bug #899343 (server assertion failure on incorrect packet)
-
-# send the package with invalid length
-12
-# check that is server alive
-True
-
-# Test gh-206 "Segfault if sending IPROTO package without `KEY` field"
-
-IPROTO_SELECT
-query {'IPROTO_CODE': 1} {'IPROTO_SPACE_ID': 280}
-True
-
-
-IPROTO_DELETE
-query {'IPROTO_CODE': 5} {'IPROTO_SPACE_ID': 280}
-True
-
-
-IPROTO_UPDATE
-query {'IPROTO_CODE': 4} {'IPROTO_SPACE_ID': 280}
-True
-query {'IPROTO_CODE': 4} {'IPROTO_SPACE_ID': 280, 'IPROTO_KEY': (1,)}
-True
-
-
-IPROTO_REPLACE
-query {'IPROTO_CODE': 3} {'IPROTO_SPACE_ID': 280}
-True
-
-
-IPROTO_CALL
-query {'IPROTO_CODE': 6} {}
-True
-query {'IPROTO_CODE': 6} {'IPROTO_KEY': ('procname',)}
-True
-
-
-box.cfg.wal_mode
----
-- write
-...
-space = box.schema.space.create('test', { id = 567 })
----
-...
-index = space:create_index('primary', { type = 'hash' })
----
-...
-box.schema.user.grant('guest', 'read,write,execute', 'space', 'test')
----
-...
-- [1, baobab]
-
-- [2, obbaba]
-
-- [1, baobab]
-
-- [3, occama]
-
-- [2, obbaba]
-
-- [4, ockham]
-
-- [1, baobab]
-
-- [2, obbaba]
-
-space:drop()
----
-...
-space = box.schema.space.create('test')
----
-...
-index = space:create_index('primary', { type = 'hash', parts = {1, 'str'}})
----
-...
-STR 1
---
-0xa1 => ok ok ok ok ok ok
-0xd901 => ok ok ok ok ok ok
-0xda0001 => ok ok ok ok ok ok
-0xdb00000001 => ok ok ok ok ok ok
-
-STR 31
---
-0xbf => ok ok ok ok ok ok
-0xd91f => ok ok ok ok ok ok
-0xda001f => ok ok ok ok ok ok
-0xdb0000001f => ok ok ok ok ok ok
-
-STR 32
---
-0xd920 => ok ok ok ok ok
-0xda0020 => ok ok ok ok ok
-0xdb00000020 => ok ok ok ok ok
-
-STR 255
---
-0xd9ff => ok ok ok ok ok
-0xda00ff => ok ok ok ok ok
-0xdb000000ff => ok ok ok ok ok
-
-STR 256
---
-0xda0100 => ok ok ok ok
-0xdb00000100 => ok ok ok ok
-
-STR 65535
---
-0xdaffff => ok ok ok ok
-0xdb0000ffff => ok ok ok ok
-
-STR 65536
---
-0xdb00010000 => ok ok ok
-
-space:drop()
----
-...
-box.schema.user.revoke('guest', 'read,write,execute', 'universe')
----
-...
blob - 85545ee902877f6c04da05d8a5e921a737796132 (mode 644)
blob + /dev/null
--- test/box/iproto.test.py
+++ /dev/null
-import os
-import sys
-import struct
-import socket
-import msgpack
-from tarantool.const import *
-from tarantool import Connection
-from tarantool.request import Request, RequestInsert, RequestSelect
-from tarantool.response import Response
-from lib.tarantool_connection import TarantoolConnection
-
-admin("box.schema.user.grant('guest', 'read,write,execute', 'universe')")
-
-print """
-#
-# iproto packages test
-#
-"""
-
-# opeing new connection to tarantool/box
-conn = TarantoolConnection(server.iproto.host, server.iproto.port)
-conn.connect()
-s = conn.socket
-
-print """
-# Test bug #899343 (server assertion failure on incorrect packet)
-"""
-print "# send the package with invalid length"
-invalid_request = struct.pack('<LLL', 1, 4294967290, 1)
-print s.send(invalid_request)
-print "# check that is server alive"
-print iproto.py_con.ping() > 0
-
-# closing connection
-s.close()
-
-key_names = {}
-for (k,v) in globals().items():
- if type(k) == str and k.startswith('IPROTO_') and type(v) == int:
- key_names[v] = k
-
-def repr_dict(todump):
- d = {}
- for (k, v) in todump.items():
- k_name = key_names.get(k, k)
- d[k_name] = v
- return repr(d)
-
-def test(header, body):
- # Connect and authenticate
- c = Connection('localhost', server.iproto.port)
- c.connect()
- print 'query', repr_dict(header), repr_dict(body)
- header = msgpack.dumps(header)
- body = msgpack.dumps(body)
- query = msgpack.dumps(len(header) + len(body)) + header + body
- # Send raw request using connectred socket
- s = c._socket
- try:
- s.send(query)
- except OSError as e:
- print ' => ', 'Failed to send request'
- c.close()
- print iproto.py_con.ping() > 0
-
-print """
-# Test gh-206 "Segfault if sending IPROTO package without `KEY` field"
-"""
-
-print "IPROTO_SELECT"
-test({ IPROTO_CODE : REQUEST_TYPE_SELECT }, { IPROTO_SPACE_ID: 280 })
-print "\n"
-
-print "IPROTO_DELETE"
-test({ IPROTO_CODE : REQUEST_TYPE_DELETE }, { IPROTO_SPACE_ID: 280 })
-print "\n"
-
-print "IPROTO_UPDATE"
-test({ IPROTO_CODE : REQUEST_TYPE_UPDATE }, { IPROTO_SPACE_ID: 280 })
-test({ IPROTO_CODE : REQUEST_TYPE_UPDATE },
- { IPROTO_SPACE_ID: 280, IPROTO_KEY: (1, )})
-print "\n"
-
-print "IPROTO_REPLACE"
-test({ IPROTO_CODE : REQUEST_TYPE_REPLACE }, { IPROTO_SPACE_ID: 280 })
-print "\n"
-
-print "IPROTO_CALL"
-test({ IPROTO_CODE : REQUEST_TYPE_CALL }, {})
-test({ IPROTO_CODE : REQUEST_TYPE_CALL }, { IPROTO_KEY: ('procname', )})
-print "\n"
-
-# gh-434 Tarantool crashes on multiple iproto requests with WAL enabled
-admin("box.cfg.wal_mode")
-admin("space = box.schema.space.create('test', { id = 567 })")
-admin("index = space:create_index('primary', { type = 'hash' })")
-admin("box.schema.user.grant('guest', 'read,write,execute', 'space', 'test')")
-
-c = Connection('localhost', server.iproto.port)
-c.connect()
-request1 = RequestInsert(c, 567, [1, "baobab"])
-request2 = RequestInsert(c, 567, [2, "obbaba"])
-s = c._socket
-try:
- s.send(bytes(request1) + bytes(request2))
-except OSError as e:
- print ' => ', 'Failed to send request'
-response1 = Response(c, c._read_response())
-response2 = Response(c, c._read_response())
-print response1.__str__()
-print response2.__str__()
-
-request1 = RequestInsert(c, 567, [3, "occama"])
-request2 = RequestSelect(c, 567, 0, [1], 0, 1, 0)
-s = c._socket
-try:
- s.send(bytes(request1) + bytes(request2))
-except OSError as e:
- print ' => ', 'Failed to send request'
-response1 = Response(c, c._read_response())
-response2 = Response(c, c._read_response())
-print response1.__str__()
-print response2.__str__()
-
-request1 = RequestSelect(c, 567, 0, [2], 0, 1, 0)
-request2 = RequestInsert(c, 567, [4, "ockham"])
-s = c._socket
-try:
- s.send(bytes(request1) + bytes(request2))
-except OSError as e:
- print ' => ', 'Failed to send request'
-response1 = Response(c, c._read_response())
-response2 = Response(c, c._read_response())
-print response1.__str__()
-print response2.__str__()
-
-request1 = RequestSelect(c, 567, 0, [1], 0, 1, 0)
-request2 = RequestSelect(c, 567, 0, [2], 0, 1, 0)
-s = c._socket
-try:
- s.send(bytes(request1) + bytes(request2))
-except OSError as e:
- print ' => ', 'Failed to send request'
-response1 = Response(c, c._read_response())
-response2 = Response(c, c._read_response())
-print response1.__str__()
-print response2.__str__()
-
-c.close()
-
-admin("space:drop()")
-
-#
-# gh-522: Broken compatibility with msgpack-python for strings of size 33..255
-#
-admin("space = box.schema.space.create('test')")
-admin("index = space:create_index('primary', { type = 'hash', parts = {1, 'str'}})")
-
-class RawInsert(Request):
- request_type = REQUEST_TYPE_INSERT
- def __init__(self, conn, space_no, blob):
- super(RawInsert, self).__init__(conn)
- request_body = "\x82" + msgpack.dumps(IPROTO_SPACE_ID) + \
- msgpack.dumps(space_id) + msgpack.dumps(IPROTO_TUPLE) + blob
- self._bytes = self.header(len(request_body)) + request_body
-
-class RawSelect(Request):
- request_type = REQUEST_TYPE_SELECT
- def __init__(self, conn, space_no, blob):
- super(RawSelect, self).__init__(conn)
- request_body = "\x83" + msgpack.dumps(IPROTO_SPACE_ID) + \
- msgpack.dumps(space_id) + msgpack.dumps(IPROTO_KEY) + blob + \
- msgpack.dumps(IPROTO_LIMIT) + msgpack.dumps(100);
- self._bytes = self.header(len(request_body)) + request_body
-
-c = iproto.py_con
-space = c.space('test')
-space_id = space.space_no
-
-TESTS = [
- (1, "\xa1", "\xd9\x01", "\xda\x00\x01", "\xdb\x00\x00\x00\x01"),
- (31, "\xbf", "\xd9\x1f", "\xda\x00\x1f", "\xdb\x00\x00\x00\x1f"),
- (32, "\xd9\x20", "\xda\x00\x20", "\xdb\x00\x00\x00\x20"),
- (255, "\xd9\xff", "\xda\x00\xff", "\xdb\x00\x00\x00\xff"),
- (256, "\xda\x01\x00", "\xdb\x00\x00\x01\x00"),
- (65535, "\xda\xff\xff", "\xdb\x00\x00\xff\xff"),
- (65536, "\xdb\x00\x01\x00\x00"),
-]
-
-for test in TESTS:
- it = iter(test)
- size = next(it)
- print 'STR', size
- print '--'
- for fmt in it:
- print '0x' + fmt.encode('hex'), '=>',
- field = '*' * size
- c._send_request(RawInsert(c, space_id, "\x91" + fmt + field))
- tuple = space.select(field)[0]
- print len(tuple[0])== size and 'ok' or 'fail',
- it2 = iter(test)
- next(it2)
- for fmt2 in it2:
- tuple = c._send_request(RawSelect(c, space_id,
- "\x91" + fmt2 + field))[0]
- print len(tuple[0]) == size and 'ok' or 'fail',
- tuple = space.delete(field)[0]
- print len(tuple[0]) == size and 'ok' or 'fail',
- print
- print
-
-admin("space:drop()")
-admin("box.schema.user.revoke('guest', 'read,write,execute', 'universe')")
blob - 13561b67b1892669e764ea9608eb5613f10269d5
blob + 754ef18b47d4db4900d349785bc9d51db573bf73
--- test/box/misc.result
+++ test/box/misc.result
---
- [5, 8, 13]
...
---# restart server default
+test_run:cmd("restart server default")
box.space.test:select{}
---
- - [1, 2, 6]
blob - 507af03d9ac06d0213ae7bc4b3c9bee92fefca72
blob + f1ca900b8e0eab3137448860cc3ee2390af27a2a
--- test/box/misc.test.lua
+++ test/box/misc.test.lua
s:insert{5, 8, 13}
i2:update({2}, {{'+', 3, 3}})
i2:delete{8}
---# restart server default
+test_run:cmd("restart server default")
box.space.test:select{}
box.space.test:drop()
blob - 6e0f52976334ecb38169e4d277a0613dd1965a2f (mode 644)
blob + /dev/null
--- test/box/print.result
+++ /dev/null
-print("Hello, world")
----
-...
-io = require('io')
----
-...
-local f = require('fiber').create(
- function()
- print('Ehllo, world')
- io.flush()
- end
-)
----
-...
-require('fiber').sleep(0.1)
----
-...
-Check log line (Hello):
----
-- "logfile contains "Hello""
-...
-Check log line (Ehllo):
----
-- "logfile contains "Ehllo""
-...
blob - 6f6798fc6191b659d24780552f9e9db29904becf (mode 644)
blob + /dev/null
--- test/box/print.test.py
+++ /dev/null
-import tarantool
-
-import sys
-import os
-import re
-
-log = server.get_log()
-
-admin('print("Hello, world")')
-admin("io = require('io')")
-
-admin("""local f = require('fiber').create(
- function()
- print('Ehllo, world')
- io.flush()
- end
-)""")
-admin("require('fiber').sleep(0.1)")
-
-print("Check log line (Hello):")
-print('---')
-if log.seek_once('Hello') >= 0:
- print('- "logfile contains "Hello""')
-else:
- print('- "logfile does not contain "Hello""')
-print('...')
-
-print("Check log line (Ehllo):")
-print('---')
-if log.seek_once('Ehllo') >= 0:
- print('- "logfile contains "Ehllo""')
-else:
- print('- "logfile does not contain "Ehllo""')
-print('...')
blob - a7b25bb56b4cc6029a961e96341a444c485ef6f0 (mode 644)
blob + /dev/null
--- test/box/snapshot.result
+++ /dev/null
-space = box.schema.space.create('tweedledum', { id = 0 })
----
-...
-index = space:create_index('primary', { type = 'hash' })
----
-...
-#
-# A test case for: http://bugs.launchpad.net/bugs/686411
-# Check that 'box.snapshot()' does not overwrite a snapshot
-# file that already exists. Verify also that any other
-# error that happens when saving snapshot is propagated
-# to the caller.
-
-space:insert{1, 'first tuple'}
----
-- [1, 'first tuple']
-...
-box.snapshot()
----
-- ok
-...
-box.snapshot()
----
-- error: can't save snapshot, errno 17 (File exists)
-...
-space:insert{2, 'second tuple'}
----
-- [2, 'second tuple']
-...
-# Make 'var' directory read-only.
-box.snapshot()
----
-- error: can't save snapshot, errno 13 (Permission denied)
-...
-space:delete{1}
----
-- [1, 'first tuple']
-...
-space:delete{2}
----
-- [2, 'second tuple']
-...
-#
-# A test case for http://bugs.launchpad.net/bugs/727174
-# "tarantool_box crashes when saving snapshot on SIGUSR1"
-#
-
-# Increment the lsn number, to make sure there is no such snapshot yet
-#
-space:insert{1, 'Test tuple'}
----
-- [1, 'Test tuple']
-...
-Snapshot exists.
-space:drop()
----
-...
blob - 6d0eec9319c7d32d5c20d5c8ff8392be3ee0c168 (mode 644)
blob + /dev/null
--- test/box/snapshot.test.py
+++ /dev/null
-import os
-import yaml
-import time
-from signal import SIGUSR1
-
-admin("space = box.schema.space.create('tweedledum', { id = 0 })")
-admin("index = space:create_index('primary', { type = 'hash' })")
-
-print """#
-# A test case for: http://bugs.launchpad.net/bugs/686411
-# Check that 'box.snapshot()' does not overwrite a snapshot
-# file that already exists. Verify also that any other
-# error that happens when saving snapshot is propagated
-# to the caller.
-"""
-admin("space:insert{1, 'first tuple'}")
-admin("box.snapshot()")
-
-# In absence of data modifications, two consecutive
-# 'box.snapshot()' statements will try to write
-# into the same file, since file name is based
-# on LSN.
-# Don't allow to overwrite snapshots.
-admin("box.snapshot()")
-#
-# Increment LSN
-admin("space:insert{2, 'second tuple'}")
-#
-# Check for other errors, e.g. "Permission denied".
-print "# Make 'var' directory read-only."
-data_dir = os.path.join(server.vardir, server.name)
-os.chmod(data_dir, 0555)
-admin("box.snapshot()")
-
-# cleanup
-os.chmod(data_dir, 0755)
-
-admin("space:delete{1}")
-admin("space:delete{2}")
-
-print """#
-# A test case for http://bugs.launchpad.net/bugs/727174
-# "tarantool_box crashes when saving snapshot on SIGUSR1"
-#"""
-
-print """
-# Increment the lsn number, to make sure there is no such snapshot yet
-#"""
-
-admin("space:insert{1, 'Test tuple'}")
-
-pid = int(yaml.load(admin("box.info.pid", silent=True))[0])
-lsn = int(yaml.load(admin("box.info.server.lsn", silent=True))[0])
-
-snapshot = str(lsn).zfill(20) + ".snap"
-snapshot = os.path.join(os.path.join(server.vardir, server.name), snapshot)
-
-iteration = 0
-
-MAX_ITERATIONS = 100
-while not os.access(snapshot, os.F_OK) and iteration < MAX_ITERATIONS:
- if iteration % 10 == 0:
- os.kill(pid, SIGUSR1)
- time.sleep(0.1)
- iteration = iteration + 1
-
-if iteration == 0 or iteration >= MAX_ITERATIONS:
- print "Snapshot is missing."
-else:
- print "Snapshot exists."
-
-admin("space:drop()")
blob - 4b13a72631a20e4b259bdbee40e7090b9c9c8264 (mode 644)
blob + /dev/null
--- test/box/space_crash.result
+++ /dev/null
-#
-# A test case for: http://bugs.launchpad.net/bugs/712456
-# Verify that when trying to access a non-existing or
-# very large space id, no crash occurs.
-#
-
----
-- error:
- errcode: (36)
- errmsg: Space '1' does not exist
-...
----
-- error:
- errcode: (36)
- errmsg: Space '65537' does not exist
-...
----
-- error:
- errcode: (36)
- errmsg: Space '4294967295' does not exist
-...
-#
-# A test case for: http://bugs.launchpad.net/bugs/716683
-# Admin console should not stall on unknown command.
-
-show status
----
-- error: '[string "show status"]:1: ''='' expected near ''status'''
-...
blob - 36a3bca2326252f24cf2259bd8be1868afb5bad4 (mode 644)
blob + /dev/null
--- test/box/space_crash.test.py
+++ /dev/null
-from lib.utils import check_libs
-check_libs()
-from tarantool.request import RequestSelect
-
-errstr = """---
-- error:
- errcode: {0}
- errmsg: {1}
-..."""
-
-def format_error(response):
- return errstr.format(
- "(%d)" % response.return_code,
- response.return_message)
-
-def format_yamllike(response):
- table = ("\n"+"\n".join(["- "+str(list(k)) for k in response])) \
- if len(response) else ""
- return "---{0}\n...".format(table)
-
-def select(conn, space_no, index_no, key, offset=0, limit=0, iterator=0):
- data = RequestSelect(
- conn, space_no, index_no,
- key, offset, limit, iterator
- )
- response = conn._send_request(data)
-
- if response.return_code:
- return format_error(response)
- return format_yamllike(response)
-
-print """#
-# A test case for: http://bugs.launchpad.net/bugs/712456
-# Verify that when trying to access a non-existing or
-# very large space id, no crash occurs.
-#
-"""
-print select(iproto.py_con, 1, 0, [0])
-print select(iproto.py_con, 65537, 0, [0])
-print select(iproto.py_con, 4294967295, 0, [0])
-
-print """#
-# A test case for: http://bugs.launchpad.net/bugs/716683
-# Admin console should not stall on unknown command.
-"""
-admin("show status", simple=True)
blob - 9afa2e91bdce871e0ee2d21bd7d1d117df65173c
blob + 4162db319de149717f43d6b659e0f2f0214fc829
--- test/box/upsert.result
+++ test/box/upsert.result
--UPSERT https://github.com/tarantool/tarantool/issues/905
+env = require('test_run')
+---
+...
+test_run = env.new()
+---
+...
s = box.schema.create_space('tweedledum')
---
...
---
...
--UPSERT https://github.com/tarantool/tarantool/issues/966
---# setopt delimiter ';'
+test_run:cmd("setopt delimiter ';'")
+---
+- true
+...
function anything_to_string(tab)
if tab == nil then
return 'nil'
end;
---
...
---# setopt delimiter ''
+test_run:cmd("setopt delimiter ''");
+---
+- true
+...
engine = 'memtx'
---
...
---
- dump [[1,'1',4,'1'],[2,'2',2,'2'],[3,'3',7,'3']]
...
---# stop server default
---# start server default
---# setopt delimiter ';'
+test_run:cmd("restart server default")
+test_run:cmd("setopt delimiter ';'")
+---
+- true
+...
function anything_to_string(tab)
if tab == nil then
return 'nil'
end;
---
...
---# setopt delimiter ''
+test_run:cmd("setopt delimiter ''");
+---
+- true
+...
s = box.space.s
---
...
blob - 92775f7bd2b5d8a36ea1781944e93e96feb7baa2
blob + 91de6ce0fd6727ecd225195fc3a91334006148d0
--- test/box/upsert.test.lua
+++ test/box/upsert.test.lua
--UPSERT https://github.com/tarantool/tarantool/issues/905
+env = require('test_run')
+test_run = env.new()
s = box.schema.create_space('tweedledum')
index = s:create_index('pk')
s:drop()
--UPSERT https://github.com/tarantool/tarantool/issues/966
---# setopt delimiter ';'
+test_run:cmd("setopt delimiter ';'")
function anything_to_string(tab)
if tab == nil then
return 'nil'
') FAILED, got ' .. anything_to_string(box.space.s:select{}) ..
' expected ' .. anything_to_string(expect)
end;
---# setopt delimiter ''
+test_run:cmd("setopt delimiter ''");
engine = 'memtx'
s = box.schema.space.create('s', {engine = engine})
test(t, {{':', 3, 3, 3, ''}, {'|', 3, 4}}, {{1, '1', 4, '1'}, {2, '2', 2, '2'}, {3, '3', 7, '3'}})
'dump ' .. anything_to_string(box.space.s:select{}) -- (1)
---# stop server default
---# start server default
+test_run:cmd("restart server default")
---# setopt delimiter ';'
+test_run:cmd("setopt delimiter ';'")
function anything_to_string(tab)
if tab == nil then
return 'nil'
str = str .. ']'
return str
end;
---# setopt delimiter ''
+test_run:cmd("setopt delimiter ''");
s = box.space.s
'dump ' .. anything_to_string(box.space.s:select{})-- compare with (1) visually!
blob - fa4c2f0c0368def7ea4f67a9947e3dd955e5c62f (mode 644)
blob + /dev/null
--- test/long_run/finalizers.result
+++ /dev/null
-Expected error: <type 'exceptions.OSError'>
blob - c471892f1770175dc9510225936e84021e865c1a (mode 644)
blob + /dev/null
--- test/long_run/finalizers.test.py
+++ /dev/null
-import os
-import sys
-import re
-import yaml
-from lib.tarantool_server import TarantoolServer
-
-server = TarantoolServer(server.ini)
-server.script = 'long_run/lua/finalizers.lua'
-server.vardir = os.path.join(server.vardir, 'finalizers')
-try:
- server.deploy()
-except:
- print "Expected error:", sys.exc_info()[0]
-else:
- print "Error! exception did not occur"
-
-
blob - 068a3b9b3bc19b4f5b072e478aabe5ff59729609
blob + 25641d2e385f40cca777f0d2770a8faef2bfc7cb
--- test/long_run/lua/finalizers.lua
+++ test/long_run/lua/finalizers.lua
#!/usr/bin/env tarantool
+env = require('test_run')
+test_run = env.new()
---# setopt delimiter ';'
+test_run:cmd("setopt delimiter ';'")
function on_gc(t)
end;
return "done"
end;
---# setopt delimiter ''
+test_run:cmd("setopt delimiter ''")
test_finalizers()
test_finalizers()
blob - /dev/null
blob + a05ebb7ed2a9e7a3b111059ba61a9801ce87f816 (mode 644)
--- /dev/null
+++ test/box-py/args.result
+tarantool --help
+Tarantool - a Lua application server
+
+Usage: tarantool script.lua [OPTIONS]
+
+All command line options are passed to the interpreted script.
+When no script name is provided, the server responds to:
+ -h, --help display this help and exit
+ -V, --version print program version and exit
+
+Please visit project home page at http://tarantool.org
+to see online documentation, submit bugs or contribute a patch.
+
+tarantool -h
+Tarantool - a Lua application server
+
+Usage: tarantool script.lua [OPTIONS]
+
+All command line options are passed to the interpreted script.
+When no script name is provided, the server responds to:
+ -h, --help display this help and exit
+ -V, --version print program version and exit
+
+Please visit project home page at http://tarantool.org
+to see online documentation, submit bugs or contribute a patch.
+
+tarantool -Z
+tarantool: -Z: unknown option
+
+tarantool --no-such-option
+tarantool: --no-such-option: unknown option
+
+tarantool --version --no-such-option
+tarantool: --no-such-option: unknown option
+
+tarantool --version
+Tarantool 1.minor.patch-<rev>-<commit>
+Target: platform <build>
+Build options: flags
+Compiler: cc
+C_FLAGS: flags
+CXX_FLAGS: flags
+
+tarantool -V
+Tarantool 1.minor.patch-<rev>-<commit>
+Target: platform <build>
+Build options: flags
+Compiler: cc
+C_FLAGS: flags
+CXX_FLAGS: flags
+
blob - /dev/null
blob + e5fd0d641e5ccc861c9319dc9020e073a9f271a1 (mode 644)
--- /dev/null
+++ test/box-py/args.test.py
+import sys
+import os
+
+# mask BFD warnings: https://bugs.launchpad.net/tarantool/+bug/1018356
+sys.stdout.push_filter("unable to read unknown load command 0x2\d+", "")
+server.test_option("--help")
+server.test_option("-h")
+sys.stdout.push_filter("(/\S+)+/tarantool", "tarantool")
+server.test_option("-Z")
+server.test_option("--no-such-option")
+server.test_option("--version --no-such-option")
+sys.stdout.push_filter("(\d)\.\d\.\d(-\d+-\w+)?", "\\1.minor.patch-<rev>-<commit>")
+sys.stdout.push_filter("Target: .*", "Target: platform <build>")
+sys.stdout.push_filter(".*Disable shared arena since.*\n", "")
+sys.stdout.push_filter("Build options: .*", "Build options: flags")
+sys.stdout.push_filter("C_FLAGS:.*", "C_FLAGS: flags")
+sys.stdout.push_filter("CXX_FLAGS:.*", "CXX_FLAGS: flags")
+sys.stdout.push_filter("Compiler: .*", "Compiler: cc")
+
+server.test_option("--version")
+server.test_option("-V ")
+sys.stdout.clear_all_filters()
+
+# Args filter cleanup
+# vim: syntax=python
blob - /dev/null
blob + 5d064b7648a11d7d8ca4fb11acab4fc17043835e (mode 644)
--- /dev/null
+++ test/box-py/bad_trigger.result
+
+ #
+ # if on_connect() trigger raises an exception, the connection is dropped
+ #
+
+nosuchfunction = nil
+---
+...
+function f1() nosuchfunction() end
+---
+...
+type(box.session.on_connect(f1))
+---
+- function
+...
+greeting: True
+fixheader: True
+error code 32
+error message: [string "function f1() nosuchfunction() end"]:1: attempt to call global 'nosuchfunction' (a nil value)
+eof: True
+box.session.on_connect(nil, f1)
+---
+...
blob - /dev/null
blob + 7d200b9218583bf0885ada4226bb81f259d26155 (mode 644)
--- /dev/null
+++ test/box-py/bad_trigger.test.py
+from lib.box_connection import BoxConnection
+from lib.tarantool_connection import TarantoolConnection
+from tarantool import NetworkError
+from tarantool.const import IPROTO_GREETING_SIZE, IPROTO_CODE, IPROTO_ERROR, \
+ REQUEST_TYPE_ERROR
+import socket
+import msgpack
+
+print """
+ #
+ # if on_connect() trigger raises an exception, the connection is dropped
+ #
+ """
+
+# silence possible error of strict mode
+server.admin("nosuchfunction = nil")
+server.admin("function f1() nosuchfunction() end")
+server.admin("type(box.session.on_connect(f1))")
+
+unpacker = msgpack.Unpacker(use_list = False)
+
+conn = TarantoolConnection(server.iproto.host, server.iproto.port)
+conn.connect()
+s = conn.socket
+
+# Read greeting
+print 'greeting: ', len(s.recv(IPROTO_GREETING_SIZE)) == IPROTO_GREETING_SIZE
+
+# Read error packet
+IPROTO_FIXHEADER_SIZE = 5
+fixheader = s.recv(IPROTO_FIXHEADER_SIZE)
+print 'fixheader: ', len(fixheader) == IPROTO_FIXHEADER_SIZE
+unpacker.feed(fixheader)
+packet_len = unpacker.unpack()
+packet = s.recv(packet_len)
+unpacker.feed(packet)
+
+# Parse packet
+header = unpacker.unpack()
+body = unpacker.unpack()
+print 'error code', (header[IPROTO_CODE] & (REQUEST_TYPE_ERROR - 1))
+print 'error message: ', body[IPROTO_ERROR]
+print 'eof:', len(s.recv(1024)) == 0
+s.close()
+
+server.admin("box.session.on_connect(nil, f1)")
blob - /dev/null
blob + ded58dba3ff1cd52a779c06cfc3251b4a7ace958 (mode 644)
--- /dev/null
+++ test/box-py/bootstrap.result
+dofile("<sourcedir>/extra/schema_erase.lua")
+---
+...
+box.space._schema:select{}
+---
+- - ['cluster', '<cluster uuid>']
+...
+box.space._cluster:select{}
+---
+- - [1, '<server uuid>']
+...
+box.space._space:select{}
+---
+- []
+...
+box.space._index:select{}
+---
+- []
+...
+box.space._user:select{}
+---
+- []
+...
+box.space._func:select{}
+---
+- []
+...
+box.space._priv:select{}
+---
+- []
+...
+dofile("<sourcedir>/extra/schema_fill.lua")
+---
+...
+box.snapshot()
+---
+- ok
+...
+box.space._schema:select{}
+---
+- - ['cluster', '<cluster uuid>']
+ - ['max_id', 511]
+ - ['version', 1, 6]
+...
+box.space._cluster:select{}
+---
+- - [1, '<server uuid>']
+...
+box.space._space:select{}
+---
+- - [272, 1, '_schema', 'memtx', 0, '', [{'type': 'str', 'name': 'key'}]]
+ - [280, 1, '_space', 'memtx', 0, '', [{'name': 'id', 'type': 'num'}, {'name': 'owner',
+ 'type': 'num'}, {'name': 'name', 'type': 'str'}, {'name': 'engine', 'type': 'str'},
+ {'name': 'field_count', 'type': 'num'}, {'name': 'flags', 'type': 'str'}, {
+ 'name': 'format', 'type': '*'}]]
+ - [281, 1, '_vspace', 'sysview', 0, '', [{'name': 'id', 'type': 'num'}, {'name': 'owner',
+ 'type': 'num'}, {'name': 'name', 'type': 'str'}, {'name': 'engine', 'type': 'str'},
+ {'name': 'field_count', 'type': 'num'}, {'name': 'flags', 'type': 'str'}, {
+ 'name': 'format', 'type': '*'}]]
+ - [288, 1, '_index', 'memtx', 0, '', [{'name': 'id', 'type': 'num'}, {'name': 'iid',
+ 'type': 'num'}, {'name': 'name', 'type': 'str'}, {'name': 'type', 'type': 'str'},
+ {'name': 'opts', 'type': 'array'}, {'name': 'parts', 'type': 'array'}]]
+ - [289, 1, '_vindex', 'sysview', 0, '', [{'name': 'id', 'type': 'num'}, {'name': 'iid',
+ 'type': 'num'}, {'name': 'name', 'type': 'str'}, {'name': 'type', 'type': 'str'},
+ {'name': 'opts', 'type': 'array'}, {'name': 'parts', 'type': 'array'}]]
+ - [296, 1, '_func', 'memtx', 0, '', [{'name': 'id', 'type': 'num'}, {'name': 'owner',
+ 'type': 'num'}, {'name': 'name', 'type': 'str'}, {'name': 'setuid', 'type': 'num'}]]
+ - [297, 1, '_vfunc', 'sysview', 0, '', [{'name': 'id', 'type': 'num'}, {'name': 'owner',
+ 'type': 'num'}, {'name': 'name', 'type': 'str'}, {'name': 'setuid', 'type': 'num'}]]
+ - [304, 1, '_user', 'memtx', 0, '', [{'name': 'id', 'type': 'num'}, {'name': 'owner',
+ 'type': 'num'}, {'name': 'name', 'type': 'str'}, {'name': 'type', 'type': 'str'},
+ {'name': 'auth', 'type': '*'}]]
+ - [305, 1, '_vuser', 'sysview', 0, '', [{'name': 'id', 'type': 'num'}, {'name': 'owner',
+ 'type': 'num'}, {'name': 'name', 'type': 'str'}, {'name': 'type', 'type': 'str'},
+ {'name': 'auth', 'type': '*'}]]
+ - [312, 1, '_priv', 'memtx', 0, '', [{'name': 'grantor', 'type': 'num'}, {'name': 'grantee',
+ 'type': 'num'}, {'name': 'object_type', 'type': 'str'}, {'name': 'object_id',
+ 'type': 'num'}, {'name': 'privilege', 'type': 'num'}]]
+ - [313, 1, '_vpriv', 'sysview', 0, '', [{'name': 'grantor', 'type': 'num'}, {'name': 'grantee',
+ 'type': 'num'}, {'name': 'object_type', 'type': 'str'}, {'name': 'object_id',
+ 'type': 'num'}, {'name': 'privilege', 'type': 'num'}]]
+ - [320, 1, '_cluster', 'memtx', 0, '', [{'name': 'id', 'type': 'num'}, {'name': 'uuid',
+ 'type': 'str'}]]
+...
+box.space._index:select{}
+---
+- - [272, 0, 'primary', 'tree', {'unique': true}, [[0, 'str']]]
+ - [280, 0, 'primary', 'tree', {'unique': true}, [[0, 'num']]]
+ - [280, 1, 'owner', 'tree', {'unique': false}, [[1, 'num']]]
+ - [280, 2, 'name', 'tree', {'unique': true}, [[2, 'str']]]
+ - [281, 0, 'primary', 'tree', {'unique': true}, [[0, 'num']]]
+ - [281, 1, 'owner', 'tree', {'unique': false}, [[1, 'num']]]
+ - [281, 2, 'name', 'tree', {'unique': true}, [[2, 'str']]]
+ - [288, 0, 'primary', 'tree', {'unique': true}, [[0, 'num'], [1, 'num']]]
+ - [288, 2, 'name', 'tree', {'unique': true}, [[0, 'num'], [2, 'str']]]
+ - [289, 0, 'primary', 'tree', {'unique': true}, [[0, 'num'], [1, 'num']]]
+ - [289, 2, 'name', 'tree', {'unique': true}, [[0, 'num'], [2, 'str']]]
+ - [296, 0, 'primary', 'tree', {'unique': true}, [[0, 'num']]]
+ - [296, 1, 'owner', 'tree', {'unique': false}, [[1, 'num']]]
+ - [296, 2, 'name', 'tree', {'unique': true}, [[2, 'str']]]
+ - [297, 0, 'primary', 'tree', {'unique': true}, [[0, 'num']]]
+ - [297, 1, 'owner', 'tree', {'unique': false}, [[1, 'num']]]
+ - [297, 2, 'name', 'tree', {'unique': true}, [[2, 'str']]]
+ - [304, 0, 'primary', 'tree', {'unique': true}, [[0, 'num']]]
+ - [304, 1, 'owner', 'tree', {'unique': false}, [[1, 'num']]]
+ - [304, 2, 'name', 'tree', {'unique': true}, [[2, 'str']]]
+ - [305, 0, 'primary', 'tree', {'unique': true}, [[0, 'num']]]
+ - [305, 1, 'owner', 'tree', {'unique': false}, [[1, 'num']]]
+ - [305, 2, 'name', 'tree', {'unique': true}, [[2, 'str']]]
+ - [312, 0, 'primary', 'tree', {'unique': true}, [[1, 'num'], [2, 'str'], [3, 'num']]]
+ - [312, 1, 'owner', 'tree', {'unique': false}, [[0, 'num']]]
+ - [312, 2, 'object', 'tree', {'unique': false}, [[2, 'str'], [3, 'num']]]
+ - [313, 0, 'primary', 'tree', {'unique': true}, [[1, 'num'], [2, 'str'], [3, 'num']]]
+ - [313, 1, 'owner', 'tree', {'unique': false}, [[0, 'num']]]
+ - [313, 2, 'object', 'tree', {'unique': false}, [[2, 'str'], [3, 'num']]]
+ - [320, 0, 'primary', 'tree', {'unique': true}, [[0, 'num']]]
+ - [320, 1, 'uuid', 'tree', {'unique': true}, [[1, 'str']]]
+...
+box.space._user:select{}
+---
+- - [0, 1, 'guest', 'user']
+ - [1, 1, 'admin', 'user']
+ - [2, 1, 'public', 'role']
+ - [3, 1, 'replication', 'role']
+...
+box.space._func:select{}
+---
+- - [1, 1, 'box.schema.user.info', 1]
+...
+box.space._priv:select{}
+---
+- - [1, 0, 'role', 2, 4]
+ - [1, 1, 'universe', 0, 7]
+ - [1, 2, 'function', 1, 4]
+ - [1, 2, 'space', 281, 1]
+ - [1, 2, 'space', 289, 1]
+ - [1, 2, 'space', 297, 1]
+ - [1, 2, 'space', 305, 1]
+ - [1, 2, 'space', 313, 1]
+ - [1, 3, 'space', 320, 2]
+ - [1, 3, 'universe', 0, 1]
+...
blob - /dev/null
blob + 3f4e557cc8a61093dc34176f40ed8e813e32199e (mode 644)
--- /dev/null
+++ test/box-py/bootstrap.test.py
+
+import sys
+import yaml
+
+server_uuid = server.get_param('server')['uuid']
+sys.stdout.push_filter(server_uuid, '<server uuid>')
+cluster_uuid = yaml.load(server.admin('box.space._schema:get("cluster")',
+ silent = True))[0][1]
+sys.stdout.push_filter(cluster_uuid, '<cluster uuid>')
+sys.stdout.push_filter(server.sourcedir, '<sourcedir>')
+
+server.admin('dofile("%s/extra/schema_erase.lua")' % server.sourcedir)
+server.admin('box.space._schema:select{}')
+server.admin('box.space._cluster:select{}')
+server.admin('box.space._space:select{}')
+server.admin('box.space._index:select{}')
+server.admin('box.space._user:select{}')
+server.admin('box.space._func:select{}')
+server.admin('box.space._priv:select{}')
+
+server.admin('dofile("%s/extra/schema_fill.lua")' % server.sourcedir)
+server.admin("box.snapshot()")
+server.restart()
+
+server.admin('box.space._schema:select{}')
+server.admin('box.space._cluster:select{}')
+server.admin('box.space._space:select{}')
+server.admin('box.space._index:select{}')
+server.admin('box.space._user:select{}')
+server.admin('box.space._func:select{}')
+server.admin('box.space._priv:select{}')
+
+# Cleanup
+sys.stdout.pop_filter()
blob - /dev/null
blob + 3bd8968c20ce6457143be36e51d0231302846692 (mode 644)
--- /dev/null
+++ test/box-py/box.lua
+#!/usr/bin/env tarantool
+os = require('os')
+
+box.cfg{
+ listen = os.getenv("LISTEN"),
+ slab_alloc_arena = 0.1,
+ pid_file = "tarantool.pid",
+ panic_on_wal_error = false,
+ rows_per_wal = 10
+}
+
+require('console').listen(os.getenv('ADMIN'))
blob - /dev/null
blob + 74a128be79979598df94953e5d01807d9ae8cb95 (mode 644)
--- /dev/null
+++ test/box-py/call.result
+box.schema.user.create('test', { password = 'test' })
+---
+...
+box.schema.user.grant('test', 'execute,read,write', 'universe')
+---
+...
+exp_notation = 1e123
+---
+...
+function f1() return 'testing', 1, false, -1, 1.123, math.abs(exp_notation - 1e123) < 0.1, nil end
+---
+...
+f1()
+---
+- testing
+- 1
+- false
+- -1
+- 1.123
+- true
+- null
+...
+call f1 ()
+- [testing]
+- [1]
+- [false]
+- [-1]
+- [1.123]
+- [true]
+- [null]
+
+f1=nil
+---
+...
+call f1 ()
+error: {code: ER_NO_SUCH_PROC, reason: Procedure 'f1' is not defined}
+
+function f1() return f1 end
+---
+...
+call f1 ()
+error: {code: ER_PROC_LUA, reason: unsupported Lua type 'function'}
+
+call box.error (33333, 'Hey!')
+error: {code: U, reason: Unknown error}
+
+
+# A test case for Bug#103491
+# server CALL processing bug with name path longer than two
+# https://bugs.launchpad.net/tarantool/+bug/1034912
+
+f = function() return 'OK' end
+---
+...
+test = {}
+---
+...
+test.f = f
+---
+...
+test.test = {}
+---
+...
+test.test.f = f
+---
+...
+call f ()
+- [OK]
+
+call test.f ()
+- [OK]
+
+call test.test.f ()
+- [OK]
+
+
+# Test for Bug #955226
+# Lua Numbers are passed back wrongly as strings
+#
+
+function foo() return 1, 2, '1', '2' end
+---
+...
+call foo ()
+- [1]
+- [2]
+- ['1']
+- ['2']
+
+function f1(...) return {...} end
+---
+...
+function f2(...) return f1({...}) end
+---
+...
+call f1 ('test_', 'test_')
+- [test_, test_]
+
+call f2 ('test_', 'test_')
+- [test_, test_]
+
+call f1 ()
+- []
+
+call f2 ()
+- []
+
+function f3() return {{'hello'}, {'world'}} end
+---
+...
+call f3 ()
+- [hello]
+- [world]
+
+function f3() return {'hello', {'world'}} end
+---
+...
+call f3 ()
+- - hello
+ - [world]
+
+function f3() return 'hello', {{'world'}, {'canada'}} end
+---
+...
+call f3 ()
+- [hello]
+- - [world]
+ - [canada]
+
+function f3() return {}, '123', {{}, {}} end
+---
+...
+call f3 ()
+- []
+- ['123']
+- - []
+ - []
+
+function f3() return { {{'hello'}} } end
+---
+...
+call f3 ()
+- - [hello]
+
+function f3() return { box.tuple.new('hello'), {'world'} } end
+---
+...
+call f3 ()
+- [hello]
+- [world]
+
+function f3() return { {'world'}, box.tuple.new('hello') } end
+---
+...
+call f3 ()
+- [world]
+- [hello]
+
+function f3() return { { test={1,2,3} }, { test2={1,2,3} } } end
+---
+...
+call f3 ()
+- - test: [1, 2, 3]
+ - test2: [1, 2, 3]
+
+call f1 ('jason',)
+- [jason]
+
+call f1 ('jason', 1, 'test', 2, 'stewart')
+- [jason, 1, test, 2, stewart]
+
+space = box.schema.space.create('tweedledum', { id = 0 })
+---
+...
+index = space:create_index('primary', { type = 'hash' })
+---
+...
+function myreplace(...) return space:replace{...} end
+---
+...
+function myinsert(...) return space:insert{...} end
+---
+...
+call myinsert (1, 'test box delete')
+- [1, test box delete]
+
+call space:delete (1,)
+- [1, test box delete]
+
+call myinsert (1, 'test box delete')
+- [1, test box delete]
+
+call space:delete (1,)
+- [1, test box delete]
+
+call space:delete (1,)
+[]
+
+call myinsert (2, 'test box delete')
+- [2, test box delete]
+
+call space:delete (1,)
+[]
+
+call space:delete (2,)
+- [2, test box delete]
+
+call space:delete (2,)
+[]
+
+space:delete{2}
+---
+...
+call myinsert (2, 'test box delete')
+- [2, test box delete]
+
+call space:get (2,)
+- [2, test box delete]
+
+space:delete{2}
+---
+- [2, 'test box delete']
+...
+call space:get (2,)
+[]
+
+call myinsert (2, 'test box.select()')
+- [2, test box.select()]
+
+call space:get (2,)
+- [2, test box.select()]
+
+call space:select (2,)
+- [2, test box.select()]
+
+space:get{2}
+---
+- [2, 'test box.select()']
+...
+space:select{2}
+---
+- - [2, 'test box.select()']
+...
+space:get{1}
+---
+...
+space:select{1}
+---
+- []
+...
+call myreplace (2, 'hello', 'world')
+- [2, hello, world]
+
+call myreplace (2, 'goodbye', 'universe')
+- [2, goodbye, universe]
+
+call space:get (2,)
+- [2, goodbye, universe]
+
+call space:select (2,)
+- [2, goodbye, universe]
+
+space:get{2}
+---
+- [2, 'goodbye', 'universe']
+...
+space:select{2}
+---
+- - [2, 'goodbye', 'universe']
+...
+call myreplace (2,)
+- [2]
+
+call space:get (2,)
+- [2]
+
+call space:select (2,)
+- [2]
+
+call space:delete (2,)
+- [2]
+
+call space:delete (2,)
+[]
+
+call myinsert (3, 'old', 2)
+- [3, old, 2]
+
+call myinsert (3, 'old', 2)
+error: {code: ER_TUPLE_FOUND, reason: Duplicate key exists in unique index 'primary'
+ in space 'tweedledum'}
+
+space:update({3}, {{'=', 1, 4}, {'=', 2, 'new'}})
+---
+- error: Attempt to modify a tuple field which is part of index 'primary' in space
+ 'tweedledum'
+...
+space:insert(space:get{3}:update{{'=', 1, 4}, {'=', 2, 'new'}}) space:delete{3}
+---
+...
+call space:get (4,)
+- [4, new, 2]
+
+call space:select (4,)
+- [4, new, 2]
+
+space:update({4}, {{'+', 3, 1}})
+---
+- [4, 'new', 3]
+...
+space:update({4}, {{'-', 3, 1}})
+---
+- [4, 'new', 2]
+...
+call space:get (4,)
+- [4, new, 2]
+
+call space:select (4,)
+- [4, new, 2]
+
+function field_x(key, field_index) return space:get(key)[field_index] end
+---
+...
+call field_x (4, 1)
+- [4]
+
+call field_x (4, 2)
+- [new]
+
+call space:delete (4,)
+- [4, new, 2]
+
+space:drop()
+---
+...
+space = box.schema.space.create('tweedledum')
+---
+...
+index = space:create_index('primary', { type = 'tree' })
+---
+...
+eval (return 1)()
+---
+[1]
+
+function f(...) return 1 end
+---
+...
+call f()
+---
+- [1]
+
+eval (return 1, 2, 3)()
+---
+[1, 2, 3]
+
+function f(...) return 1, 2, 3 end
+---
+...
+call f()
+---
+- [1]
+- [2]
+- [3]
+
+eval (return true)()
+---
+[true]
+
+function f(...) return true end
+---
+...
+call f()
+---
+- [true]
+
+eval (return nil)()
+---
+[null]
+
+function f(...) return nil end
+---
+...
+call f()
+---
+- [null]
+
+eval (return )()
+---
+[]
+
+function f(...) return end
+---
+...
+call f()
+---
+[]
+
+eval (return {})()
+---
+- []
+
+function f(...) return {} end
+---
+...
+call f()
+---
+- []
+
+eval (return {1})()
+---
+- [1]
+
+function f(...) return {1} end
+---
+...
+call f()
+---
+- [1]
+
+eval (return {1, 2, 3})()
+---
+- [1, 2, 3]
+
+function f(...) return {1, 2, 3} end
+---
+...
+call f()
+---
+- [1, 2, 3]
+
+eval (return {k1 = 'v1', k2 = 'v2'})()
+---
+- {k1: v1, k2: v2}
+
+function f(...) return {k1 = 'v1', k2 = 'v2'} end
+---
+...
+call f()
+---
+- - {k1: v1, k2: v2}
+
+eval (return {k1 = 'v1', k2 = 'v2'})()
+---
+- {k1: v1, k2: v2}
+
+function f(...) return {k1 = 'v1', k2 = 'v2'} end
+---
+...
+call f()
+---
+- - {k1: v1, k2: v2}
+
+eval (return {s = {1, 1428578535}, u = 1428578535, v = {}, c = {['2'] = {1, 1428578535}, ['106'] = { 1, 1428578535} }, pc = {['2'] = {1, 1428578535, 9243}, ['106'] = {1, 1428578535, 9243}}})()
+---
+- c:
+ '106': [1, 1428578535]
+ '2': [1, 1428578535]
+ pc:
+ '106': [1, 1428578535, 9243]
+ '2': [1, 1428578535, 9243]
+ s: [1, 1428578535]
+ u: 1428578535
+ v: []
+
+function f(...) return {s = {1, 1428578535}, u = 1428578535, v = {}, c = {['2'] = {1, 1428578535}, ['106'] = { 1, 1428578535} }, pc = {['2'] = {1, 1428578535, 9243}, ['106'] = {1, 1428578535, 9243}}} end
+---
+...
+call f()
+---
+- - c:
+ '106': [1, 1428578535]
+ '2': [1, 1428578535]
+ pc:
+ '106': [1, 1428578535, 9243]
+ '2': [1, 1428578535, 9243]
+ s: [1, 1428578535]
+ u: 1428578535
+ v: []
+
+eval (return true, {s = {1, 1428578535}, u = 1428578535, v = {}, c = {['2'] = {1, 1428578535}, ['106'] = { 1, 1428578535} }, pc = {['2'] = {1, 1428578535, 9243}, ['106'] = {1, 1428578535, 9243}}})()
+---
+- true
+- c:
+ '106': [1, 1428578535]
+ '2': [1, 1428578535]
+ pc:
+ '106': [1, 1428578535, 9243]
+ '2': [1, 1428578535, 9243]
+ s: [1, 1428578535]
+ u: 1428578535
+ v: []
+
+function f(...) return true, {s = {1, 1428578535}, u = 1428578535, v = {}, c = {['2'] = {1, 1428578535}, ['106'] = { 1, 1428578535} }, pc = {['2'] = {1, 1428578535, 9243}, ['106'] = {1, 1428578535, 9243}}} end
+---
+...
+call f()
+---
+- [true]
+- - c:
+ '106': [1, 1428578535]
+ '2': [1, 1428578535]
+ pc:
+ '106': [1, 1428578535, 9243]
+ '2': [1, 1428578535, 9243]
+ s: [1, 1428578535]
+ u: 1428578535
+ v: []
+
+eval (return {s = {1, 1428578535}, u = 1428578535, v = {}, c = {['2'] = {1, 1428578535}, ['106'] = { 1, 1428578535} }, pc = {['2'] = {1, 1428578535, 9243}, ['106'] = {1, 1428578535, 9243}}}, true)()
+---
+- c:
+ '106': [1, 1428578535]
+ '2': [1, 1428578535]
+ pc:
+ '106': [1, 1428578535, 9243]
+ '2': [1, 1428578535, 9243]
+ s: [1, 1428578535]
+ u: 1428578535
+ v: []
+- true
+
+function f(...) return {s = {1, 1428578535}, u = 1428578535, v = {}, c = {['2'] = {1, 1428578535}, ['106'] = { 1, 1428578535} }, pc = {['2'] = {1, 1428578535, 9243}, ['106'] = {1, 1428578535, 9243}}}, true end
+---
+...
+call f()
+---
+- - c:
+ '106': [1, 1428578535]
+ '2': [1, 1428578535]
+ pc:
+ '106': [1, 1428578535, 9243]
+ '2': [1, 1428578535, 9243]
+ s: [1, 1428578535]
+ u: 1428578535
+ v: []
+- [true]
+
+t = box.tuple.new('tuple', {1, 2, 3}, { k1 = 'v', k2 = 'v2'})
+---
+...
+eval (return t)()
+---
+- - tuple
+ - [1, 2, 3]
+ - {k1: v, k2: v2}
+
+function f(...) return t end
+---
+...
+call f()
+---
+- - tuple
+ - [1, 2, 3]
+ - {k1: v, k2: v2}
+
+eval (return t, t, t)()
+---
+- - tuple
+ - [1, 2, 3]
+ - {k1: v, k2: v2}
+- - tuple
+ - [1, 2, 3]
+ - {k1: v, k2: v2}
+- - tuple
+ - [1, 2, 3]
+ - {k1: v, k2: v2}
+
+function f(...) return t, t, t end
+---
+...
+call f()
+---
+- - tuple
+ - [1, 2, 3]
+ - {k1: v, k2: v2}
+- - tuple
+ - [1, 2, 3]
+ - {k1: v, k2: v2}
+- - tuple
+ - [1, 2, 3]
+ - {k1: v, k2: v2}
+
+eval (return {t})()
+---
+- - - tuple
+ - [1, 2, 3]
+ - {k1: v, k2: v2}
+
+function f(...) return {t} end
+---
+...
+call f()
+---
+- - tuple
+ - [1, 2, 3]
+ - {k1: v, k2: v2}
+
+eval (return {t, t, t})()
+---
+- - - tuple
+ - [1, 2, 3]
+ - {k1: v, k2: v2}
+ - - tuple
+ - [1, 2, 3]
+ - {k1: v, k2: v2}
+ - - tuple
+ - [1, 2, 3]
+ - {k1: v, k2: v2}
+
+function f(...) return {t, t, t} end
+---
+...
+call f()
+---
+- - tuple
+ - [1, 2, 3]
+ - {k1: v, k2: v2}
+- - tuple
+ - [1, 2, 3]
+ - {k1: v, k2: v2}
+- - tuple
+ - [1, 2, 3]
+ - {k1: v, k2: v2}
+
+eval (return error('exception'))()
+---
+error: {code: ER_PROC_LUA, reason: exception}
+
+function f(...) return error('exception') end
+---
+...
+call f()
+---
+error: {code: ER_PROC_LUA, reason: exception}
+
+eval (return box.error(0))()
+---
+error: {code: ER_OK, reason: Unknown error}
+
+function f(...) return box.error(0) end
+---
+...
+call f()
+---
+error: {code: ER_OK, reason: Unknown error}
+
+eval (return ...)()
+---
+[]
+
+function f(...) return ... end
+---
+...
+call f()
+---
+[]
+
+eval (return ...)(1,2,3)
+---
+[1, 2, 3]
+
+function f(...) return ... end
+---
+...
+call f(1,2,3)
+---
+- [1]
+- [2]
+- [3]
+
+eval (return ...)(None,None,None)
+---
+[null, null, null]
+
+function f(...) return ... end
+---
+...
+call f(None,None,None)
+---
+- [null]
+- [null]
+- [null]
+
+eval (return ...)({'k2': 'v2', 'k1': 'v1'})
+---
+- {k1: v1, k2: v2}
+
+function f(...) return ... end
+---
+...
+call f({'k2': 'v2', 'k1': 'v1'})
+---
+- - {k1: v1, k2: v2}
+
+eval (return space:auto_increment({"transaction"}))()
+---
+- [1, transaction]
+
+function f(...) return space:auto_increment({"transaction"}) end
+---
+...
+call f()
+---
+- [2, transaction]
+
+eval (return space:select{})()
+---
+- - [1, transaction]
+ - [2, transaction]
+
+function f(...) return space:select{} end
+---
+...
+call f()
+---
+- [1, transaction]
+- [2, transaction]
+
+eval (return box.begin(), space:auto_increment({"failed"}), box.rollback())()
+---
+- null
+- [3, failed]
+
+function f(...) return box.begin(), space:auto_increment({"failed"}), box.rollback() end
+---
+...
+call f()
+---
+- [null]
+- [3, failed]
+
+eval (return space:select{})()
+---
+- - [1, transaction]
+ - [2, transaction]
+
+function f(...) return space:select{} end
+---
+...
+call f()
+---
+- [1, transaction]
+- [2, transaction]
+
+eval (return require("fiber").sleep(0))()
+---
+[]
+
+function f(...) return require("fiber").sleep(0) end
+---
+...
+call f()
+---
+[]
+
+eval (!invalid expression)()
+---
+error: {code: ER_PROC_LUA, reason: 'eval:1: unexpected symbol near ''!'''}
+
+space:drop()
+---
+...
+box.schema.user.drop('test')
+---
+...
blob - /dev/null
blob + 20f9bce62db5f25bb2e0877cefd70d13360784bc (mode 644)
--- /dev/null
+++ test/box-py/call.test.py
+import os
+import sys
+
+def call(name, *args):
+ return iproto.call(name, *args)
+
+admin("box.schema.user.create('test', { password = 'test' })")
+admin("box.schema.user.grant('test', 'execute,read,write', 'universe')")
+iproto.authenticate('test', 'test')
+# workaround for gh-770 centos 6 float representation
+admin('exp_notation = 1e123')
+admin("function f1() return 'testing', 1, false, -1, 1.123, math.abs(exp_notation - 1e123) < 0.1, nil end")
+admin("f1()")
+call("f1")
+admin("f1=nil")
+call("f1")
+admin("function f1() return f1 end")
+call("f1")
+
+# A test case for https://github.com/tarantool/tarantool/issues/44
+# IPROTO required!
+call("box.error", 33333, 'Hey!')
+
+print """
+# A test case for Bug#103491
+# server CALL processing bug with name path longer than two
+# https://bugs.launchpad.net/tarantool/+bug/1034912
+"""
+admin("f = function() return 'OK' end")
+admin("test = {}")
+admin("test.f = f")
+admin("test.test = {}")
+admin("test.test.f = f")
+call("f")
+call("test.f")
+call("test.test.f")
+
+print """
+# Test for Bug #955226
+# Lua Numbers are passed back wrongly as strings
+#
+"""
+admin("function foo() return 1, 2, '1', '2' end")
+call("foo")
+
+#
+# check how well we can return tables
+#
+admin("function f1(...) return {...} end")
+admin("function f2(...) return f1({...}) end")
+call("f1", 'test_', 'test_')
+call("f2", 'test_', 'test_')
+call("f1")
+call("f2")
+#
+# check multi-tuple return
+#
+admin("function f3() return {{'hello'}, {'world'}} end")
+call("f3")
+admin("function f3() return {'hello', {'world'}} end")
+call("f3")
+admin("function f3() return 'hello', {{'world'}, {'canada'}} end")
+call("f3")
+admin("function f3() return {}, '123', {{}, {}} end")
+call("f3")
+admin("function f3() return { {{'hello'}} } end")
+call("f3")
+admin("function f3() return { box.tuple.new('hello'), {'world'} } end")
+call("f3")
+admin("function f3() return { {'world'}, box.tuple.new('hello') } end")
+call("f3")
+admin("function f3() return { { test={1,2,3} }, { test2={1,2,3} } } end")
+call("f3")
+
+call("f1", 'jason')
+call("f1", 'jason', 1, 'test', 2, 'stewart')
+
+admin("space = box.schema.space.create('tweedledum', { id = 0 })")
+admin("index = space:create_index('primary', { type = 'hash' })")
+
+admin("function myreplace(...) return space:replace{...} end")
+admin("function myinsert(...) return space:insert{...} end")
+
+call("myinsert", 1, 'test box delete')
+call("space:delete", 1)
+call("myinsert", 1, 'test box delete')
+call("space:delete", 1)
+call("space:delete", 1)
+call("myinsert", 2, 'test box delete')
+call("space:delete", 1)
+call("space:delete", 2)
+call("space:delete", 2)
+admin("space:delete{2}")
+
+call("myinsert", 2, 'test box delete')
+call("space:get", 2)
+admin("space:delete{2}")
+call("space:get", 2)
+call("myinsert", 2, 'test box.select()')
+call("space:get", 2)
+call("space:select", 2)
+admin("space:get{2}")
+admin("space:select{2}")
+admin("space:get{1}")
+admin("space:select{1}")
+call("myreplace", 2, 'hello', 'world')
+call("myreplace", 2, 'goodbye', 'universe')
+call("space:get", 2)
+call("space:select", 2)
+admin("space:get{2}")
+admin("space:select{2}")
+call("myreplace", 2)
+call("space:get", 2)
+call("space:select", 2)
+call("space:delete", 2)
+call("space:delete", 2)
+call("myinsert", 3, 'old', 2)
+# test that insert produces a duplicate key error
+call("myinsert", 3, 'old', 2)
+admin("space:update({3}, {{'=', 1, 4}, {'=', 2, 'new'}})")
+admin("space:insert(space:get{3}:update{{'=', 1, 4}, {'=', 2, 'new'}}) space:delete{3}")
+call("space:get", 4)
+call("space:select", 4)
+admin("space:update({4}, {{'+', 3, 1}})")
+admin("space:update({4}, {{'-', 3, 1}})")
+call("space:get", 4)
+call("space:select", 4)
+admin("function field_x(key, field_index) return space:get(key)[field_index] end")
+call("field_x", 4, 1)
+call("field_x", 4, 2)
+call("space:delete", 4)
+admin("space:drop()")
+
+admin("space = box.schema.space.create('tweedledum')")
+admin("index = space:create_index('primary', { type = 'tree' })")
+
+
+def lua_eval(name, *args):
+ print 'eval (%s)(%s)' % (name, ','.join([ str(arg) for arg in args]))
+ print '---'
+ print iproto.py_con.eval(name, args)
+
+def lua_call(name, *args):
+ print 'call %s(%s)' % (name, ','.join([ str(arg) for arg in args]))
+ print '---'
+ print iproto.py_con.call(name, args)
+
+def test(expr, *args):
+ lua_eval('return ' + expr, *args)
+ admin('function f(...) return ' + expr + ' end')
+ lua_call('f', *args)
+
+# Return values
+test("1")
+test("1, 2, 3")
+test("true")
+test("nil")
+test("")
+test("{}")
+test("{1}")
+test("{1, 2, 3}")
+test("{k1 = 'v1', k2 = 'v2'}")
+test("{k1 = 'v1', k2 = 'v2'}")
+# gh-791: maps are wrongly assumed to be arrays
+test("{s = {1, 1428578535}, u = 1428578535, v = {}, c = {['2'] = {1, 1428578535}, ['106'] = { 1, 1428578535} }, pc = {['2'] = {1, 1428578535, 9243}, ['106'] = {1, 1428578535, 9243}}}")
+test("true, {s = {1, 1428578535}, u = 1428578535, v = {}, c = {['2'] = {1, 1428578535}, ['106'] = { 1, 1428578535} }, pc = {['2'] = {1, 1428578535, 9243}, ['106'] = {1, 1428578535, 9243}}}")
+test("{s = {1, 1428578535}, u = 1428578535, v = {}, c = {['2'] = {1, 1428578535}, ['106'] = { 1, 1428578535} }, pc = {['2'] = {1, 1428578535, 9243}, ['106'] = {1, 1428578535, 9243}}}, true")
+admin("t = box.tuple.new('tuple', {1, 2, 3}, { k1 = 'v', k2 = 'v2'})")
+test("t")
+test("t, t, t")
+test("{t}")
+test("{t, t, t}")
+test("error('exception')")
+test("box.error(0)")
+test('...')
+test('...', 1, 2, 3)
+test('...', None, None, None)
+test('...', { 'k1': 'v1', 'k2': 'v2'})
+# Transactions
+test('space:auto_increment({"transaction"})')
+test('space:select{}')
+test('box.begin(), space:auto_increment({"failed"}), box.rollback()')
+test('space:select{}')
+test('require("fiber").sleep(0)')
+# Other
+lua_eval('!invalid expression')
+
+admin("space:drop()")
+admin("box.schema.user.drop('test')")
+
+# Re-connect after removing user
+iproto.py_con.close()
blob - /dev/null
blob + 678026f3a28c1ca26d1ee8563005da36af1dbb15 (mode 644)
--- /dev/null
+++ test/box-py/iproto.result
+box.schema.user.grant('guest', 'read,write,execute', 'universe')
+---
+...
+
+#
+# iproto packages test
+#
+
+
+# Test bug #899343 (server assertion failure on incorrect packet)
+
+# send the package with invalid length
+12
+# check that is server alive
+True
+
+# Test gh-206 "Segfault if sending IPROTO package without `KEY` field"
+
+IPROTO_SELECT
+query {'IPROTO_CODE': 1} {'IPROTO_SPACE_ID': 280}
+True
+
+
+IPROTO_DELETE
+query {'IPROTO_CODE': 5} {'IPROTO_SPACE_ID': 280}
+True
+
+
+IPROTO_UPDATE
+query {'IPROTO_CODE': 4} {'IPROTO_SPACE_ID': 280}
+True
+query {'IPROTO_CODE': 4} {'IPROTO_SPACE_ID': 280, 'IPROTO_KEY': (1,)}
+True
+
+
+IPROTO_REPLACE
+query {'IPROTO_CODE': 3} {'IPROTO_SPACE_ID': 280}
+True
+
+
+IPROTO_CALL
+query {'IPROTO_CODE': 6} {}
+True
+query {'IPROTO_CODE': 6} {'IPROTO_KEY': ('procname',)}
+True
+
+
+box.cfg.wal_mode
+---
+- write
+...
+space = box.schema.space.create('test', { id = 567 })
+---
+...
+index = space:create_index('primary', { type = 'hash' })
+---
+...
+box.schema.user.grant('guest', 'read,write,execute', 'space', 'test')
+---
+...
+- [1, baobab]
+
+- [2, obbaba]
+
+- [1, baobab]
+
+- [3, occama]
+
+- [2, obbaba]
+
+- [4, ockham]
+
+- [1, baobab]
+
+- [2, obbaba]
+
+space:drop()
+---
+...
+space = box.schema.space.create('test')
+---
+...
+index = space:create_index('primary', { type = 'hash', parts = {1, 'str'}})
+---
+...
+STR 1
+--
+0xa1 => ok ok ok ok ok ok
+0xd901 => ok ok ok ok ok ok
+0xda0001 => ok ok ok ok ok ok
+0xdb00000001 => ok ok ok ok ok ok
+
+STR 31
+--
+0xbf => ok ok ok ok ok ok
+0xd91f => ok ok ok ok ok ok
+0xda001f => ok ok ok ok ok ok
+0xdb0000001f => ok ok ok ok ok ok
+
+STR 32
+--
+0xd920 => ok ok ok ok ok
+0xda0020 => ok ok ok ok ok
+0xdb00000020 => ok ok ok ok ok
+
+STR 255
+--
+0xd9ff => ok ok ok ok ok
+0xda00ff => ok ok ok ok ok
+0xdb000000ff => ok ok ok ok ok
+
+STR 256
+--
+0xda0100 => ok ok ok ok
+0xdb00000100 => ok ok ok ok
+
+STR 65535
+--
+0xdaffff => ok ok ok ok
+0xdb0000ffff => ok ok ok ok
+
+STR 65536
+--
+0xdb00010000 => ok ok ok
+
+space:drop()
+---
+...
+box.schema.user.revoke('guest', 'read,write,execute', 'universe')
+---
+...
blob - /dev/null
blob + 85545ee902877f6c04da05d8a5e921a737796132 (mode 644)
--- /dev/null
+++ test/box-py/iproto.test.py
+import os
+import sys
+import struct
+import socket
+import msgpack
+from tarantool.const import *
+from tarantool import Connection
+from tarantool.request import Request, RequestInsert, RequestSelect
+from tarantool.response import Response
+from lib.tarantool_connection import TarantoolConnection
+
+admin("box.schema.user.grant('guest', 'read,write,execute', 'universe')")
+
+print """
+#
+# iproto packages test
+#
+"""
+
+# opeing new connection to tarantool/box
+conn = TarantoolConnection(server.iproto.host, server.iproto.port)
+conn.connect()
+s = conn.socket
+
+print """
+# Test bug #899343 (server assertion failure on incorrect packet)
+"""
+print "# send the package with invalid length"
+invalid_request = struct.pack('<LLL', 1, 4294967290, 1)
+print s.send(invalid_request)
+print "# check that is server alive"
+print iproto.py_con.ping() > 0
+
+# closing connection
+s.close()
+
+key_names = {}
+for (k,v) in globals().items():
+ if type(k) == str and k.startswith('IPROTO_') and type(v) == int:
+ key_names[v] = k
+
+def repr_dict(todump):
+ d = {}
+ for (k, v) in todump.items():
+ k_name = key_names.get(k, k)
+ d[k_name] = v
+ return repr(d)
+
+def test(header, body):
+ # Connect and authenticate
+ c = Connection('localhost', server.iproto.port)
+ c.connect()
+ print 'query', repr_dict(header), repr_dict(body)
+ header = msgpack.dumps(header)
+ body = msgpack.dumps(body)
+ query = msgpack.dumps(len(header) + len(body)) + header + body
+ # Send raw request using connectred socket
+ s = c._socket
+ try:
+ s.send(query)
+ except OSError as e:
+ print ' => ', 'Failed to send request'
+ c.close()
+ print iproto.py_con.ping() > 0
+
+print """
+# Test gh-206 "Segfault if sending IPROTO package without `KEY` field"
+"""
+
+print "IPROTO_SELECT"
+test({ IPROTO_CODE : REQUEST_TYPE_SELECT }, { IPROTO_SPACE_ID: 280 })
+print "\n"
+
+print "IPROTO_DELETE"
+test({ IPROTO_CODE : REQUEST_TYPE_DELETE }, { IPROTO_SPACE_ID: 280 })
+print "\n"
+
+print "IPROTO_UPDATE"
+test({ IPROTO_CODE : REQUEST_TYPE_UPDATE }, { IPROTO_SPACE_ID: 280 })
+test({ IPROTO_CODE : REQUEST_TYPE_UPDATE },
+ { IPROTO_SPACE_ID: 280, IPROTO_KEY: (1, )})
+print "\n"
+
+print "IPROTO_REPLACE"
+test({ IPROTO_CODE : REQUEST_TYPE_REPLACE }, { IPROTO_SPACE_ID: 280 })
+print "\n"
+
+print "IPROTO_CALL"
+test({ IPROTO_CODE : REQUEST_TYPE_CALL }, {})
+test({ IPROTO_CODE : REQUEST_TYPE_CALL }, { IPROTO_KEY: ('procname', )})
+print "\n"
+
+# gh-434 Tarantool crashes on multiple iproto requests with WAL enabled
+admin("box.cfg.wal_mode")
+admin("space = box.schema.space.create('test', { id = 567 })")
+admin("index = space:create_index('primary', { type = 'hash' })")
+admin("box.schema.user.grant('guest', 'read,write,execute', 'space', 'test')")
+
+c = Connection('localhost', server.iproto.port)
+c.connect()
+request1 = RequestInsert(c, 567, [1, "baobab"])
+request2 = RequestInsert(c, 567, [2, "obbaba"])
+s = c._socket
+try:
+ s.send(bytes(request1) + bytes(request2))
+except OSError as e:
+ print ' => ', 'Failed to send request'
+response1 = Response(c, c._read_response())
+response2 = Response(c, c._read_response())
+print response1.__str__()
+print response2.__str__()
+
+request1 = RequestInsert(c, 567, [3, "occama"])
+request2 = RequestSelect(c, 567, 0, [1], 0, 1, 0)
+s = c._socket
+try:
+ s.send(bytes(request1) + bytes(request2))
+except OSError as e:
+ print ' => ', 'Failed to send request'
+response1 = Response(c, c._read_response())
+response2 = Response(c, c._read_response())
+print response1.__str__()
+print response2.__str__()
+
+request1 = RequestSelect(c, 567, 0, [2], 0, 1, 0)
+request2 = RequestInsert(c, 567, [4, "ockham"])
+s = c._socket
+try:
+ s.send(bytes(request1) + bytes(request2))
+except OSError as e:
+ print ' => ', 'Failed to send request'
+response1 = Response(c, c._read_response())
+response2 = Response(c, c._read_response())
+print response1.__str__()
+print response2.__str__()
+
+request1 = RequestSelect(c, 567, 0, [1], 0, 1, 0)
+request2 = RequestSelect(c, 567, 0, [2], 0, 1, 0)
+s = c._socket
+try:
+ s.send(bytes(request1) + bytes(request2))
+except OSError as e:
+ print ' => ', 'Failed to send request'
+response1 = Response(c, c._read_response())
+response2 = Response(c, c._read_response())
+print response1.__str__()
+print response2.__str__()
+
+c.close()
+
+admin("space:drop()")
+
+#
+# gh-522: Broken compatibility with msgpack-python for strings of size 33..255
+#
+admin("space = box.schema.space.create('test')")
+admin("index = space:create_index('primary', { type = 'hash', parts = {1, 'str'}})")
+
+class RawInsert(Request):
+ request_type = REQUEST_TYPE_INSERT
+ def __init__(self, conn, space_no, blob):
+ super(RawInsert, self).__init__(conn)
+ request_body = "\x82" + msgpack.dumps(IPROTO_SPACE_ID) + \
+ msgpack.dumps(space_id) + msgpack.dumps(IPROTO_TUPLE) + blob
+ self._bytes = self.header(len(request_body)) + request_body
+
+class RawSelect(Request):
+ request_type = REQUEST_TYPE_SELECT
+ def __init__(self, conn, space_no, blob):
+ super(RawSelect, self).__init__(conn)
+ request_body = "\x83" + msgpack.dumps(IPROTO_SPACE_ID) + \
+ msgpack.dumps(space_id) + msgpack.dumps(IPROTO_KEY) + blob + \
+ msgpack.dumps(IPROTO_LIMIT) + msgpack.dumps(100);
+ self._bytes = self.header(len(request_body)) + request_body
+
+c = iproto.py_con
+space = c.space('test')
+space_id = space.space_no
+
+TESTS = [
+ (1, "\xa1", "\xd9\x01", "\xda\x00\x01", "\xdb\x00\x00\x00\x01"),
+ (31, "\xbf", "\xd9\x1f", "\xda\x00\x1f", "\xdb\x00\x00\x00\x1f"),
+ (32, "\xd9\x20", "\xda\x00\x20", "\xdb\x00\x00\x00\x20"),
+ (255, "\xd9\xff", "\xda\x00\xff", "\xdb\x00\x00\x00\xff"),
+ (256, "\xda\x01\x00", "\xdb\x00\x00\x01\x00"),
+ (65535, "\xda\xff\xff", "\xdb\x00\x00\xff\xff"),
+ (65536, "\xdb\x00\x01\x00\x00"),
+]
+
+for test in TESTS:
+ it = iter(test)
+ size = next(it)
+ print 'STR', size
+ print '--'
+ for fmt in it:
+ print '0x' + fmt.encode('hex'), '=>',
+ field = '*' * size
+ c._send_request(RawInsert(c, space_id, "\x91" + fmt + field))
+ tuple = space.select(field)[0]
+ print len(tuple[0])== size and 'ok' or 'fail',
+ it2 = iter(test)
+ next(it2)
+ for fmt2 in it2:
+ tuple = c._send_request(RawSelect(c, space_id,
+ "\x91" + fmt2 + field))[0]
+ print len(tuple[0]) == size and 'ok' or 'fail',
+ tuple = space.delete(field)[0]
+ print len(tuple[0]) == size and 'ok' or 'fail',
+ print
+ print
+
+admin("space:drop()")
+admin("box.schema.user.revoke('guest', 'read,write,execute', 'universe')")
blob - /dev/null
blob + 6e0f52976334ecb38169e4d277a0613dd1965a2f (mode 644)
--- /dev/null
+++ test/box-py/print.result
+print("Hello, world")
+---
+...
+io = require('io')
+---
+...
+local f = require('fiber').create(
+ function()
+ print('Ehllo, world')
+ io.flush()
+ end
+)
+---
+...
+require('fiber').sleep(0.1)
+---
+...
+Check log line (Hello):
+---
+- "logfile contains "Hello""
+...
+Check log line (Ehllo):
+---
+- "logfile contains "Ehllo""
+...
blob - /dev/null
blob + 6f6798fc6191b659d24780552f9e9db29904becf (mode 644)
--- /dev/null
+++ test/box-py/print.test.py
+import tarantool
+
+import sys
+import os
+import re
+
+log = server.get_log()
+
+admin('print("Hello, world")')
+admin("io = require('io')")
+
+admin("""local f = require('fiber').create(
+ function()
+ print('Ehllo, world')
+ io.flush()
+ end
+)""")
+admin("require('fiber').sleep(0.1)")
+
+print("Check log line (Hello):")
+print('---')
+if log.seek_once('Hello') >= 0:
+ print('- "logfile contains "Hello""')
+else:
+ print('- "logfile does not contain "Hello""')
+print('...')
+
+print("Check log line (Ehllo):")
+print('---')
+if log.seek_once('Ehllo') >= 0:
+ print('- "logfile contains "Ehllo""')
+else:
+ print('- "logfile does not contain "Ehllo""')
+print('...')
blob - /dev/null
blob + 3a08208e065f353d7999aebea94592b85e5133c5 (mode 644)
--- /dev/null
+++ test/box-py/replica.lua
+#!/usr/bin/env tarantool
+
+box.cfg({
+ listen = os.getenv("LISTEN"),
+ replication_source = os.getenv("MASTER"),
+ slab_alloc_arena = 0.1,
+})
+
+require('console').listen(os.getenv('ADMIN'))
blob - /dev/null
blob + a7b25bb56b4cc6029a961e96341a444c485ef6f0 (mode 644)
--- /dev/null
+++ test/box-py/snapshot.result
+space = box.schema.space.create('tweedledum', { id = 0 })
+---
+...
+index = space:create_index('primary', { type = 'hash' })
+---
+...
+#
+# A test case for: http://bugs.launchpad.net/bugs/686411
+# Check that 'box.snapshot()' does not overwrite a snapshot
+# file that already exists. Verify also that any other
+# error that happens when saving snapshot is propagated
+# to the caller.
+
+space:insert{1, 'first tuple'}
+---
+- [1, 'first tuple']
+...
+box.snapshot()
+---
+- ok
+...
+box.snapshot()
+---
+- error: can't save snapshot, errno 17 (File exists)
+...
+space:insert{2, 'second tuple'}
+---
+- [2, 'second tuple']
+...
+# Make 'var' directory read-only.
+box.snapshot()
+---
+- error: can't save snapshot, errno 13 (Permission denied)
+...
+space:delete{1}
+---
+- [1, 'first tuple']
+...
+space:delete{2}
+---
+- [2, 'second tuple']
+...
+#
+# A test case for http://bugs.launchpad.net/bugs/727174
+# "tarantool_box crashes when saving snapshot on SIGUSR1"
+#
+
+# Increment the lsn number, to make sure there is no such snapshot yet
+#
+space:insert{1, 'Test tuple'}
+---
+- [1, 'Test tuple']
+...
+Snapshot exists.
+space:drop()
+---
+...
blob - /dev/null
blob + 6d0eec9319c7d32d5c20d5c8ff8392be3ee0c168 (mode 644)
--- /dev/null
+++ test/box-py/snapshot.test.py
+import os
+import yaml
+import time
+from signal import SIGUSR1
+
+admin("space = box.schema.space.create('tweedledum', { id = 0 })")
+admin("index = space:create_index('primary', { type = 'hash' })")
+
+print """#
+# A test case for: http://bugs.launchpad.net/bugs/686411
+# Check that 'box.snapshot()' does not overwrite a snapshot
+# file that already exists. Verify also that any other
+# error that happens when saving snapshot is propagated
+# to the caller.
+"""
+admin("space:insert{1, 'first tuple'}")
+admin("box.snapshot()")
+
+# In absence of data modifications, two consecutive
+# 'box.snapshot()' statements will try to write
+# into the same file, since file name is based
+# on LSN.
+# Don't allow to overwrite snapshots.
+admin("box.snapshot()")
+#
+# Increment LSN
+admin("space:insert{2, 'second tuple'}")
+#
+# Check for other errors, e.g. "Permission denied".
+print "# Make 'var' directory read-only."
+data_dir = os.path.join(server.vardir, server.name)
+os.chmod(data_dir, 0555)
+admin("box.snapshot()")
+
+# cleanup
+os.chmod(data_dir, 0755)
+
+admin("space:delete{1}")
+admin("space:delete{2}")
+
+print """#
+# A test case for http://bugs.launchpad.net/bugs/727174
+# "tarantool_box crashes when saving snapshot on SIGUSR1"
+#"""
+
+print """
+# Increment the lsn number, to make sure there is no such snapshot yet
+#"""
+
+admin("space:insert{1, 'Test tuple'}")
+
+pid = int(yaml.load(admin("box.info.pid", silent=True))[0])
+lsn = int(yaml.load(admin("box.info.server.lsn", silent=True))[0])
+
+snapshot = str(lsn).zfill(20) + ".snap"
+snapshot = os.path.join(os.path.join(server.vardir, server.name), snapshot)
+
+iteration = 0
+
+MAX_ITERATIONS = 100
+while not os.access(snapshot, os.F_OK) and iteration < MAX_ITERATIONS:
+ if iteration % 10 == 0:
+ os.kill(pid, SIGUSR1)
+ time.sleep(0.1)
+ iteration = iteration + 1
+
+if iteration == 0 or iteration >= MAX_ITERATIONS:
+ print "Snapshot is missing."
+else:
+ print "Snapshot exists."
+
+admin("space:drop()")
blob - /dev/null
blob + 4b13a72631a20e4b259bdbee40e7090b9c9c8264 (mode 644)
--- /dev/null
+++ test/box-py/space_crash.result
+#
+# A test case for: http://bugs.launchpad.net/bugs/712456
+# Verify that when trying to access a non-existing or
+# very large space id, no crash occurs.
+#
+
+---
+- error:
+ errcode: (36)
+ errmsg: Space '1' does not exist
+...
+---
+- error:
+ errcode: (36)
+ errmsg: Space '65537' does not exist
+...
+---
+- error:
+ errcode: (36)
+ errmsg: Space '4294967295' does not exist
+...
+#
+# A test case for: http://bugs.launchpad.net/bugs/716683
+# Admin console should not stall on unknown command.
+
+show status
+---
+- error: '[string "show status"]:1: ''='' expected near ''status'''
+...
blob - /dev/null
blob + 36a3bca2326252f24cf2259bd8be1868afb5bad4 (mode 644)
--- /dev/null
+++ test/box-py/space_crash.test.py
+from lib.utils import check_libs
+check_libs()
+from tarantool.request import RequestSelect
+
+errstr = """---
+- error:
+ errcode: {0}
+ errmsg: {1}
+..."""
+
+def format_error(response):
+ return errstr.format(
+ "(%d)" % response.return_code,
+ response.return_message)
+
+def format_yamllike(response):
+ table = ("\n"+"\n".join(["- "+str(list(k)) for k in response])) \
+ if len(response) else ""
+ return "---{0}\n...".format(table)
+
+def select(conn, space_no, index_no, key, offset=0, limit=0, iterator=0):
+ data = RequestSelect(
+ conn, space_no, index_no,
+ key, offset, limit, iterator
+ )
+ response = conn._send_request(data)
+
+ if response.return_code:
+ return format_error(response)
+ return format_yamllike(response)
+
+print """#
+# A test case for: http://bugs.launchpad.net/bugs/712456
+# Verify that when trying to access a non-existing or
+# very large space id, no crash occurs.
+#
+"""
+print select(iproto.py_con, 1, 0, [0])
+print select(iproto.py_con, 65537, 0, [0])
+print select(iproto.py_con, 4294967295, 0, [0])
+
+print """#
+# A test case for: http://bugs.launchpad.net/bugs/716683
+# Admin console should not stall on unknown command.
+"""
+admin("show status", simple=True)
blob - /dev/null
blob + 830cc8fcc5d81fb47745a50678d6c433a2ec43b3 (mode 644)
--- /dev/null
+++ test/box-py/suite.ini
+[default]
+core = tarantool
+description = legacy python tests
+script = box.lua
+lua_libs = lua/fiber.lua lua/fifo.lua
+use_unix_sockets = True
blob - 5200f3f9e154a11d382f51c21a894e478b56029d (mode 644)
blob + /dev/null
--- test/replication/cluster.result
+++ /dev/null
-ok - cluster uuid
--------------------------------------------------------------
- gh-696: Check global READ permissions for replication
--------------------------------------------------------------
-ok - join without read permissions to universe
-ok - subscribe without read permissions to universe
-box.schema.user.grant('guest', 'read', 'universe')
----
-...
-ok - join without write permissions to _cluster
-box.schema.user.grant('guest', 'write', 'space', '_cluster')
----
-...
-ok - join with granted permissions
-box.schema.user.revoke('guest', 'read', 'universe')
----
-...
-box.schema.user.revoke('guest', 'write', 'space', '_cluster')
----
-...
-box.schema.user.grant('guest', 'replication')
----
-...
-ok - join with granted role
--------------------------------------------------------------
-gh-707: Master crashes on JOIN if it does not have snapshot files
-gh-480: If socket is closed while JOIN, replica wont reconnect
--------------------------------------------------------------
-ok - join without snapshots
-ok - _cluster does not changed after unsuccessful JOIN
-box.schema.user.revoke('guest', 'replication')
----
-...
-box.snapshot()
----
-- ok
-...
--------------------------------------------------------------
-gh-434: Assertion if replace _cluster tuple
--------------------------------------------------------------
-box.space._cluster:replace{1, '8c7ff474-65f9-4abe-81a4-a3e1019bb1ae'}
----
-- [1, '8c7ff474-65f9-4abe-81a4-a3e1019bb1ae']
-...
-box.info.server.uuid
----
-- 8c7ff474-65f9-4abe-81a4-a3e1019bb1ae
-...
-check log line for 'server UUID changed to 8c7ff474-65f9-4abe-81a4-a3e1019bb1ae'
-
-'server UUID changed to 8c7ff474-65f9-4abe-81a4-a3e1019bb1ae' exists in server log
-
-box.info.server.uuid
----
-- 8c7ff474-65f9-4abe-81a4-a3e1019bb1ae
-...
-box.snapshot()
----
-- ok
-...
-box.info.server.uuid
----
-- 8c7ff474-65f9-4abe-81a4-a3e1019bb1ae
-...
-box.space._cluster:replace{1, require('uuid').NULL:str()}
----
-- error: 'Invalid UUID: 00000000-0000-0000-0000-000000000000'
-...
--------------------------------------------------------------
-gh-527: update vclock on delete from box.space._cluster
--------------------------------------------------------------
-box.schema.user.grant('guest', 'replication')
----
-...
-box.space._schema:insert{"test", 48}
----
-- ['test', 48]
-...
-box.info.server.id
----
-- 2
-...
-box.info.server.ro
----
-- false
-...
-box.info.server.lsn
----
-- 1
-...
-box.info.vclock[2]
----
-- 1
-...
-box.space._cluster:delete{2}
----
-- [2, '<replica uuid>']
-...
-box.info.server.id
----
-- 0
-...
-box.info.server.ro
----
-- true
-...
-box.info.server.lsn
----
-- -1
-...
-box.info.vclock[2]
----
-- null
-...
-box.space._schema:replace{"test", 48}
----
-- error: Can't modify data because this server is in read-only mode.
-...
-box.space._cluster:insert{10, "<replica uuid>"}
----
-- [10, '<replica uuid>']
-...
-box.info.server.id
----
-- 10
-...
-box.info.server.ro
----
-- false
-...
-box.info.server.lsn
----
-- 0
-...
-box.info.vclock[2]
----
-- null
-...
-box.info.vclock[10]
----
-- 0
-...
-box.space._cluster:update(10, {{'=', 1, 11}})
----
-- error: Attempt to modify a tuple field which is part of index 'primary' in space
- '_cluster'
-...
-box.info.server.id
----
-- 10
-...
-box.info.server.ro
----
-- false
-...
-box.info.server.lsn
----
-- 0
-...
-box.info.vclock[2]
----
-- null
-...
-box.info.vclock[10]
----
-- 0
-...
-box.info.vclock[11]
----
-- null
-...
--------------------------------------------------------------
-gh-806: cant prune old replicas by deleting their server ids
--------------------------------------------------------------
-box.space._schema:insert{'test', 1}
----
-- ['test', 1]
-...
-cluster_len = box.space._cluster:len()
----
-...
-for id, lsn in pairs(box.info.vclock) do if id ~= box.info.server.id then box.space._cluster:delete{id} end end
----
-...
-box.space._cluster:len() < cluster_len
----
-- true
-...
-box.snapshot()
----
-- ok
-...
-box.schema.user.revoke('guest', 'replication')
----
-...
blob - eae175bff4decdd4fd3226d795c4eb0110c0fd82 (mode 644)
blob + /dev/null
--- test/replication/cluster.test.py
+++ /dev/null
-import os
-import sys
-import re
-import yaml
-import uuid
-import glob
-from lib.tarantool_server import TarantoolServer
-
-## Get cluster uuid
-cluster_uuid = ''
-try:
- cluster_uuid = yaml.load(server.admin("box.space._schema:get('cluster')",
- silent = True))[0][1]
- uuid.UUID('{' + cluster_uuid + '}')
- print 'ok - cluster uuid'
-except Exception as e:
- print 'not ok - invalid cluster uuid', e
-
-print '-------------------------------------------------------------'
-print ' gh-696: Check global READ permissions for replication'
-print '-------------------------------------------------------------'
-
-# Generate replica cluster UUID
-replica_uuid = str(uuid.uuid4())
-
-## Universal read permission is required to perform JOIN/SUBSCRIBE
-rows = list(server.iproto.py_con.join(replica_uuid))
-print len(rows) == 1 and rows[0].return_message.find('Read access') >= 0 and \
- 'ok' or 'not ok', '-', 'join without read permissions to universe'
-rows = list(server.iproto.py_con.subscribe(cluster_uuid, replica_uuid))
-print len(rows) == 1 and rows[0].return_message.find('Read access') >= 0 and \
- 'ok' or 'not ok', '-', 'subscribe without read permissions to universe'
-
-## Write permission to space `_cluster` is required to perform JOIN
-server.admin("box.schema.user.grant('guest', 'read', 'universe')")
-server.iproto.py_con.close() # re-connect with new permissions
-rows = list(server.iproto.py_con.join(replica_uuid))
-print len(rows) == 1 and rows[0].return_message.find('Write access') >= 0 and \
- 'ok' or 'not ok', '-', 'join without write permissions to _cluster'
-
-def check_join(msg):
- ok = True
- for resp in server.iproto.py_con.join(replica_uuid):
- if resp.completion_status != 0:
- print 'not ok', '-', msg, resp.return_message
- ok = False
-
- server.iproto.py_con.close() # JOIN brokes protocol
- if not ok:
- return
- tuples = server.iproto.py_con.space('_cluster').select(replica_uuid, index = 1)
- if len(tuples) == 0:
- print 'not ok', '-', msg, 'missing entry in _cluster'
- return
- server_id = tuples[0][0]
- print 'ok', '-', msg
- return server_id
-
-## JOIN with permissions
-server.admin("box.schema.user.grant('guest', 'write', 'space', '_cluster')")
-server.iproto.py_con.close() # re-connect with new permissions
-server_id = check_join('join with granted permissions')
-server.iproto.py_con.space('_cluster').delete(server_id)
-
-# JOIN with granted role
-server.admin("box.schema.user.revoke('guest', 'read', 'universe')")
-server.admin("box.schema.user.revoke('guest', 'write', 'space', '_cluster')")
-server.admin("box.schema.user.grant('guest', 'replication')")
-server.iproto.py_con.close() # re-connect with new permissions
-server_id = check_join('join with granted role')
-server.iproto.py_con.space('_cluster').delete(server_id)
-
-print '-------------------------------------------------------------'
-print 'gh-707: Master crashes on JOIN if it does not have snapshot files'
-print 'gh-480: If socket is closed while JOIN, replica wont reconnect'
-print '-------------------------------------------------------------'
-
-data_dir = os.path.join(server.vardir, server.name)
-for k in glob.glob(os.path.join(data_dir, '*.snap')):
- os.unlink(k)
-
-# remember the number of servers in _cluster table
-server_count = len(server.iproto.py_con.space('_cluster').select(()))
-
-rows = list(server.iproto.py_con.join(replica_uuid))
-print len(rows) == 1 and rows[0].return_message.find('snapshot') >= 0 and \
- 'ok' or 'not ok', '-', 'join without snapshots'
-
-print server_count == len(server.iproto.py_con.space('_cluster').select(())) and\
- 'ok' or 'not ok', '-', '_cluster does not changed after unsuccessful JOIN'
-
-server.admin("box.schema.user.revoke('guest', 'replication')")
-server.admin('box.snapshot()')
-
-print '-------------------------------------------------------------'
-print 'gh-434: Assertion if replace _cluster tuple'
-print '-------------------------------------------------------------'
-server.stop()
-script = server.script
-server.script = "replication/panic.lua"
-server.deploy()
-
-new_uuid = '8c7ff474-65f9-4abe-81a4-a3e1019bb1ae'
-
-# Check log message
-# Requires panic_on_wal_error = false
-server.admin("box.space._cluster:replace{{1, '{0}'}}".format(new_uuid))
-server.admin("box.info.server.uuid")
-
-line = "server UUID changed to " + new_uuid
-print "check log line for '%s'" % line
-print
-if server.logfile_pos.seek_once(line) >= 0:
- print "'%s' exists in server log" % line
-print
-server.admin("box.info.server.uuid")
-
-# Check that new UUID has been saved in snapshot
-server.admin("box.snapshot()")
-server.restart()
-
-server.admin("box.info.server.uuid")
-
-# Invalid UUID
-server.admin("box.space._cluster:replace{1, require('uuid').NULL:str()}")
-
-# Cleanup
-server.stop()
-server.script = script
-server.deploy()
-
-print '-------------------------------------------------------------'
-print 'gh-527: update vclock on delete from box.space._cluster'
-print '-------------------------------------------------------------'
-
-# master server
-master = server
-master_id = master.get_param('server')['id']
-
-master.admin("box.schema.user.grant('guest', 'replication')")
-
-replica = TarantoolServer(server.ini)
-replica.script = 'replication/replica.lua'
-replica.vardir = server.vardir
-replica.rpl_master = master
-replica.deploy()
-replica.wait_lsn(master_id, master.get_lsn(master_id))
-replica_id = replica.get_param('server')['id']
-replica_uuid = replica.get_param('server')['uuid']
-sys.stdout.push_filter(replica_uuid, '<replica uuid>')
-replica.admin('box.space._schema:insert{"test", 48}')
-
-replica.admin('box.info.server.id')
-replica.admin('box.info.server.ro')
-replica.admin('box.info.server.lsn') # 1
-replica.admin('box.info.vclock[%d]' % replica_id)
-
-master.admin('box.space._cluster:delete{%d}' % replica_id)
-replica.wait_lsn(master_id, master.get_lsn(master_id))
-replica.admin('box.info.server.id')
-replica.admin('box.info.server.ro')
-replica.admin('box.info.server.lsn') # -1
-replica.admin('box.info.vclock[%d]' % replica_id)
-# replica is read-only
-replica.admin('box.space._schema:replace{"test", 48}')
-
-replica_id2 = 10
-master.admin('box.space._cluster:insert{%d, "%s"}' %
- (replica_id2, replica_uuid))
-replica.wait_lsn(master_id, master.get_lsn(master_id))
-replica.admin('box.info.server.id')
-replica.admin('box.info.server.ro')
-replica.admin('box.info.server.lsn') # 0
-replica.admin('box.info.vclock[%d]' % replica_id)
-replica.admin('box.info.vclock[%d]' % replica_id2)
-
-replica_id3 = 11
-# Tuple is read-only
-server.admin("box.space._cluster:update(%d, {{'=', 1, %d}})" %
- (replica_id2, replica_id3))
-replica.wait_lsn(master_id, master.get_lsn(master_id))
-replica.admin('box.info.server.id')
-replica.admin('box.info.server.ro')
-replica.admin('box.info.server.lsn') # 0
-replica.admin('box.info.vclock[%d]' % replica_id)
-replica.admin('box.info.vclock[%d]' % replica_id2)
-replica.admin('box.info.vclock[%d]' % replica_id3)
-replica.stop()
-replica.cleanup(True)
-
-print '-------------------------------------------------------------'
-print 'gh-806: cant prune old replicas by deleting their server ids'
-print '-------------------------------------------------------------'
-
-# Rotate xlog
-master.restart()
-master.admin("box.space._schema:insert{'test', 1}")
-
-# Prune old replicas
-master.admin("cluster_len = box.space._cluster:len()")
-# Delete from _cluster for replicas with lsn=0 is safe
-master.admin('for id, lsn in pairs(box.info.vclock) do'
- ' if id ~= box.info.server.id then box.space._cluster:delete{id} end '
- 'end');
-master.admin("box.space._cluster:len() < cluster_len")
-
-# Save a snapshot without removed replicas in vclock
-master.admin("box.snapshot()")
-
-# Master is not crashed then recovering xlog with {replica_id: 0} in header
-master.restart()
-
-# Cleanup
-sys.stdout.pop_filter()
-
-master.admin("box.schema.user.revoke('guest', 'replication')")
blob - 7bc5dceb093750395e51f200ec3cf2a43e8546ca (mode 644)
blob + /dev/null
--- test/replication/conflict.result
+++ /dev/null
-box.schema.user.grant('guest', 'replication')
----
-...
-reset master-master replication
-parallel send: box.space.test:update(1, {{'#', 2, 1}})
-parallel send: box.space.test:update(1, {{'#', 2, 1}})
-replication state is correct
-box.space.test:select{1}
----
-- - [1]
-...
-box.space.test:select{1}
----
-- - [1]
-...
-reset master-master replication
-parallel send: box.space.test:insert{20, 1}
-parallel send: box.space.test:insert{20, 2}
-replication state is correct
-reset master-master replication
-parallel send: box.space.test:update(2, {{'=', 2, 1}})
-parallel send: box.space.test:update(2, {{'=', 2, 2}})
-replication state is correct
-reset master-master replication
-parallel send: box.space.test:update(1, {{'+', 2, 1}})
-parallel send: box.space.test:update(1, {{'+', 2, 2}})
-replication state is correct
-box.space.test:select{1}
----
-- - [1, 4]
-...
-box.space.test:select{1}
----
-- - [1, 4]
-...
-reset master-master replication
-parallel send: box.space.test:delete(999)
-parallel send: box.space.test:delete(999)
-replication state is correct
-box.space.test:select{}
----
-- - [1, 1]
- - [2, 4]
- - [3, 9]
- - [4, 16]
- - [5, 25]
- - [6, 36]
- - [7, 49]
- - [8, 64]
- - [9, 81]
-...
-box.space.test:select{}
----
-- - [1, 1]
- - [2, 4]
- - [3, 9]
- - [4, 16]
- - [5, 25]
- - [6, 36]
- - [7, 49]
- - [8, 64]
- - [9, 81]
-...
blob - 8d6e9347f1eed8ac6d1f43e4cd90c0e66332db32 (mode 644)
blob + /dev/null
--- test/replication/conflict.test.py
+++ /dev/null
-from lib.tarantool_server import TarantoolServer
-from time import sleep
-import yaml
-
-def check_replication(nodes, select_args=''):
- for node in nodes:
- node.admin('box.space.test:select{%s}' % select_args)
-
-master = server
-master.admin("box.schema.user.grant('guest', 'replication')")
-
-replica = TarantoolServer(server.ini)
-replica.script = 'replication/replica.lua'
-replica.vardir = server.vardir
-replica.rpl_master = master
-replica.deploy()
-
-def parallel_run(cmd1, cmd2, compare):
- print 'parallel send: %s' % cmd1
- print 'parallel send: %s' % cmd2
- master.admin.socket.sendall('%s\n' % cmd1)
- replica.admin.socket.sendall('%s\n' % cmd2)
-
- master.admin.socket.recv(2048)
- replica.admin.socket.recv(2048)
-
- # wait for status changing in tarantool
- master_status = yaml.load(master.admin(
- 'box.info().replication.status', silent=True
- ))[0]
- replica_status = yaml.load(replica.admin(
- 'box.info().replication.status', silent=True
- ))[0]
-
- # wait for status
- results = [f(master_status, replica_status) for f in compare]
- while True:
- sleep(0.01)
- if any(results):
- print 'replication state is correct'
- break
-
-def prepare_cluster():
- print 'reset master-master replication'
- master.stop()
- master.cleanup(True)
- master.start()
- master.admin("box.schema.user.grant('guest', 'replication')", silent=True)
-
- replica.stop()
- replica.cleanup(True)
- replica.start()
-
- master.admin("box.cfg{replication_source='%s'}" % replica.iproto.uri, silent=True)
- r1_id = replica.get_param('server')['id']
- r2_id = master.get_param('server')['id']
-
- master.admin("space = box.schema.space.create('test')", silent=True)
- master.admin("index = space:create_index('primary', { type = 'tree'})", silent=True)
- master.admin('for k = 1, 9 do space:insert{k, k*k} end', silent=True)
-
- # wait lsn
- replica.wait_lsn(r2_id, master.get_lsn(r2_id))
- master.wait_lsn(r1_id, replica.get_lsn(r1_id))
-
-# test1: double update in master and replica
-prepare_cluster()
-parallel_run(
- "box.space.test:update(1, {{'#', 2, 1}})",
- "box.space.test:update(1, {{'#', 2, 1}})",
- [
- lambda x,y: x == 'stopped' or y == 'stopped',
- lambda x,y: x == 'follow' and y == 'follow',
- ]
-)
-check_replication([master, replica], '1')
-
-# test2: insert different values with single id
-prepare_cluster()
-parallel_run(
- 'box.space.test:insert{20, 1}',
- 'box.space.test:insert{20, 2}',
- [
- lambda x,y: x == 'stopped' or y == 'stopped',
- lambda x,y: x == 'follow' and y == 'follow',
- ]
-)
-
-# test3: update different values
-prepare_cluster()
-parallel_run(
- "box.space.test:update(2, {{'=', 2, 1}})",
- "box.space.test:update(2, {{'=', 2, 2}})",
- [lambda x,y: x == 'follow' and y == 'follow',]
-)
-
-# test4: CRDT increment with update
-prepare_cluster()
-parallel_run(
- "box.space.test:update(1, {{'+', 2, 1}})",
- "box.space.test:update(1, {{'+', 2, 2}})",
- [lambda x,y: x == 'follow' and y == 'follow',]
-)
-check_replication([master, replica], '1')
-
-# test5: delete not existing key
-prepare_cluster()
-parallel_run(
- "box.space.test:delete(999)",
- "box.space.test:delete(999)",
- [lambda x,y: x == 'follow' and y == 'follow',]
-)
-check_replication([master, replica])
-
-# cleanup
-replica.stop()
-replica.cleanup(True)
-server.stop()
-server.cleanup(True)
-server.deploy()
blob - /dev/null
blob + f8ae138705d84f1abcc8b1acfcd4ed34369ae9a8 (mode 644)
--- /dev/null
+++ test/replication/lua/fast_replica.lua
+
+function join(inspector, n)
+ for i=1,n do
+ local rid = tostring(i)
+ os.execute('mkdir -p tmp')
+ os.execute('cp ../replication/replica.lua ./tmp/replica'..rid..'.lua')
+ os.execute('chmod +x ./tmp/replica'..rid..'.lua')
+ inspector:cmd("create server replica"..rid.." with rpl_master=default, script='./var/tmp/replica"..rid..".lua'")
+ inspector:cmd("start server replica"..rid)
+ end
+end
+
+
+function drop_all(inspector)
+ local all = box.space._cluster:select{}
+ for _, tuple in pairs(all) do
+ local id = tuple[1]
+ if id ~= box.info.server.id then
+ box.space._cluster:delete{id}
+ inspector:cmd('stop server replica'..tostring(id - 1))
+ inspector:cmd('cleanup server replica'..tostring(id - 1))
+ end
+ end
+end
+
+return {
+ join = join;
+ drop_all = drop_all;
+}
blob - 0e27d903be5e858bc77505b35060cde17bb9f502 (mode 644)
blob + /dev/null
--- test/replication/init_storage.result
+++ /dev/null
-box.schema.user.grant('guest', 'replication')
----
-...
-space = box.schema.space.create('test', {id = 42})
----
-...
-index = space:create_index('primary', { type = 'tree'})
----
-...
-for k = 1, 9 do space:insert{k, k*k} end
----
-...
--------------------------------------------------------------
-replica test 1 (no such space)
--------------------------------------------------------------
-box.space.test
----
-- null
-...
--------------------------------------------------------------
-replica JOIN
--------------------------------------------------------------
-box.snapshot()
----
-- ok
-...
-box.space.test:select()
----
-- - [1, 1]
- - [2, 4]
- - [3, 9]
- - [4, 16]
- - [5, 25]
- - [6, 36]
- - [7, 49]
- - [8, 64]
- - [9, 81]
-...
-box.space.test:select()
----
-- - [1, 1]
- - [2, 4]
- - [3, 9]
- - [4, 16]
- - [5, 25]
- - [6, 36]
- - [7, 49]
- - [8, 64]
- - [9, 81]
-...
--------------------------------------------------------------
-replica test 2 (must be ok)
--------------------------------------------------------------
-for k = 10, 19 do box.space[42]:insert{k, k*k*k} end
----
-...
-for k = 20, 29 do box.space[42]:upsert({k}, {}) end
----
-...
-space = box.space.test
----
-...
-space:get{1}
----
-- [1, 1]
-...
-space:get{2}
----
-- [2, 4]
-...
-space:get{3}
----
-- [3, 9]
-...
-space:get{4}
----
-- [4, 16]
-...
-space:get{5}
----
-- [5, 25]
-...
-space:get{6}
----
-- [6, 36]
-...
-space:get{7}
----
-- [7, 49]
-...
-space:get{8}
----
-- [8, 64]
-...
-space:get{9}
----
-- [9, 81]
-...
-space:get{10}
----
-- [10, 1000]
-...
-space:get{11}
----
-- [11, 1331]
-...
-space:get{12}
----
-- [12, 1728]
-...
-space:get{13}
----
-- [13, 2197]
-...
-space:get{14}
----
-- [14, 2744]
-...
-space:get{15}
----
-- [15, 3375]
-...
-space:get{16}
----
-- [16, 4096]
-...
-space:get{17}
----
-- [17, 4913]
-...
-space:get{18}
----
-- [18, 5832]
-...
-space:get{19}
----
-- [19, 6859]
-...
--------------------------------------------------------------
-reconnect on JOIN/SUBSCRIBE
--------------------------------------------------------------
-waiting reconnect on JOIN...
-ok
-waiting reconnect on SUBSCRIBE...
-ok
blob - e59ff14c9c5f6d79cdd13b06742351c30902b1e4 (mode 644)
blob + /dev/null
--- test/replication/init_storage.test.py
+++ /dev/null
-import os
-import glob
-from lib.tarantool_server import TarantoolServer
-
-# master server
-master = server
-master_id = master.get_param('server')['id']
-
-master.admin("box.schema.user.grant('guest', 'replication')")
-master.admin("space = box.schema.space.create('test', {id = 42})")
-master.admin("index = space:create_index('primary', { type = 'tree'})")
-
-master.admin('for k = 1, 9 do space:insert{k, k*k} end')
-data_dir = os.path.join(master.vardir, master.name)
-for k in glob.glob(os.path.join(data_dir, '*.xlog')):
- os.unlink(k)
-
-print '-------------------------------------------------------------'
-print 'replica test 1 (no such space)'
-print '-------------------------------------------------------------'
-
-replica = TarantoolServer(server.ini)
-replica.script = 'replication/replica.lua'
-replica.vardir = server.vardir #os.path.join(server.vardir, 'replica')
-replica.rpl_master = master
-replica.deploy()
-
-replica.admin('box.space.test')
-
-replica.stop()
-replica.cleanup(True)
-
-print '-------------------------------------------------------------'
-print 'replica JOIN'
-print '-------------------------------------------------------------'
-
-master.admin('box.snapshot()')
-master.restart()
-
-replica.deploy()
-replica.wait_lsn(master_id, master.get_lsn(master_id))
-replica.admin('box.space.test:select()')
-
-#
-# gh-484: JOIN doesn't save data to snapshot with TREE index
-#
-
-replica.restart()
-
-replica.admin('box.space.test:select()')
-replica.stop()
-replica.cleanup(True)
-
-print '-------------------------------------------------------------'
-print 'replica test 2 (must be ok)'
-print '-------------------------------------------------------------'
-
-master.restart()
-master.admin('for k = 10, 19 do box.space[42]:insert{k, k*k*k} end')
-master.admin("for k = 20, 29 do box.space[42]:upsert({k}, {}) end")
-lsn = master.get_lsn(master_id)
-
-replica = TarantoolServer(server.ini)
-replica.script = 'replication/replica.lua'
-replica.vardir = server.vardir #os.path.join(server.vardir, 'replica')
-replica.rpl_master = master
-replica.deploy()
-
-replica.admin('space = box.space.test');
-replica.wait_lsn(master_id, lsn)
-for i in range(1, 20):
- replica.admin('space:get{%d}' % i)
-
-replica.stop()
-replica.cleanup(True)
-
-print '-------------------------------------------------------------'
-print 'reconnect on JOIN/SUBSCRIBE'
-print '-------------------------------------------------------------'
-
-server.stop()
-replica = TarantoolServer(server.ini)
-replica.script = 'replication/replica.lua'
-replica.vardir = server.vardir #os.path.join(server.vardir, 'replica')
-replica.rpl_master = master
-replica.deploy(wait=False)
-
-print 'waiting reconnect on JOIN...'
-server.start()
-replica.wait_until_started()
-print 'ok'
-
-replica.stop()
-server.stop()
-
-print 'waiting reconnect on SUBSCRIBE...'
-replica.start(wait=False)
-server.start()
-replica.wait_until_started()
-print 'ok'
-
-replica.stop()
-replica.cleanup(True)
-
-server.stop()
-server.deploy()
blob - /dev/null
blob + 10a7c3579c57fd5d4ce38f599e62f05afaa601d2 (mode 644)
--- /dev/null
+++ test/replication/prune.result
+print '-------------------------------------------------------------'
+---
+...
+print 'gh-806: cant prune old replicas by deleting their server ids'
+---
+...
+print '-------------------------------------------------------------'
+---
+...
+env = require('test_run')
+---
+...
+test_run = env.new('127.0.0.1', 8080)
+---
+...
+replica_set = require('fast_replica')
+---
+...
+fiber = require('fiber')
+---
+...
+box.space._cluster:len() == 1
+---
+- true
+...
+#box.info.vclock == 1
+---
+- true
+...
+box.schema.user.grant('guest', 'read,write,execute', 'universe')
+---
+...
+-- Create space and fill it
+space = box.schema.create_space('test')
+---
+...
+index = box.space.test:create_index('primary')
+---
+...
+for i=1,10 do space:insert{i, 'test'} end
+---
+...
+-- create max number of replicas and check
+replica_set.join(test_run, box.schema.REPLICA_MAX - 2)
+---
+...
+while box.space._cluster:len() ~= box.schema.REPLICA_MAX - 1 do fiber.sleep(0.001) end
+---
+...
+box.space._cluster:len() == box.schema.REPLICA_MAX - 1
+---
+- true
+...
+#box.info.vclock == box.schema.REPLICA_MAX - 1
+---
+- true
+...
+-- try to add one more replica
+uuid = require('uuid')
+---
+...
+box.space._cluster:insert{box.schema.REPLICA_MAX, uuid.str()}
+---
+- error: 'Replica count limit reached: 32'
+...
+-- Delete all replication nodes
+replica_set.drop_all(test_run)
+---
+...
+box.space._cluster:len() == 1
+---
+- true
+...
+#box.info.vclock == 1
+---
+- true
+...
+-- Save a snapshot without removed replicas in vclock
+box.snapshot()
+---
+- ok
+...
+-- Master is not crashed then recovering xlog with {replica_id: 0} in header
+test_run:cmd('restart server default')
+replica_set = require('fast_replica')
+---
+...
+fiber = require('fiber')
+---
+...
+-- Rejoin replica and check
+replica_set.join(test_run, 1)
+---
+...
+while box.space._cluster:len() ~= 2 do fiber.sleep(0.001) end
+---
+...
+-- Check server ids
+test_run:cmd('eval replica1 "return box.info.server.id"')
+---
+- '{"result": [2]}'
+...
+box.space._cluster:len() == 2
+---
+- true
+...
+#box.info.vclock == 2
+---
+- true
+...
+-- Cleanup
+replica_set.drop_all(test_run)
+---
+...
+box.space._cluster:len() == 1
+---
+- true
+...
+#box.info.vclock == 1
+---
+- true
+...
+box.space.test:drop()
+---
+...
+box.schema.user.revoke('guest', 'read,write,execute', 'universe')
+---
+...
blob - /dev/null
blob + da55d6eed19ca20d69b20ee1b5225812403936e5 (mode 644)
--- /dev/null
+++ test/replication/prune.test.lua
+print '-------------------------------------------------------------'
+print 'gh-806: cant prune old replicas by deleting their server ids'
+print '-------------------------------------------------------------'
+
+env = require('test_run')
+test_run = env.new('127.0.0.1', 8080)
+replica_set = require('fast_replica')
+fiber = require('fiber')
+
+box.space._cluster:len() == 1
+#box.info.vclock == 1
+
+box.schema.user.grant('guest', 'read,write,execute', 'universe')
+
+-- Create space and fill it
+space = box.schema.create_space('test')
+index = box.space.test:create_index('primary')
+for i=1,10 do space:insert{i, 'test'} end
+
+-- create max number of replicas and check
+replica_set.join(test_run, box.schema.REPLICA_MAX - 2)
+while box.space._cluster:len() ~= box.schema.REPLICA_MAX - 1 do fiber.sleep(0.001) end
+
+box.space._cluster:len() == box.schema.REPLICA_MAX - 1
+#box.info.vclock == box.schema.REPLICA_MAX - 1
+
+-- try to add one more replica
+uuid = require('uuid')
+box.space._cluster:insert{box.schema.REPLICA_MAX, uuid.str()}
+
+-- Delete all replication nodes
+replica_set.drop_all(test_run)
+box.space._cluster:len() == 1
+#box.info.vclock == 1
+
+-- Save a snapshot without removed replicas in vclock
+box.snapshot()
+-- Master is not crashed then recovering xlog with {replica_id: 0} in header
+test_run:cmd('restart server default')
+replica_set = require('fast_replica')
+fiber = require('fiber')
+
+-- Rejoin replica and check
+replica_set.join(test_run, 1)
+while box.space._cluster:len() ~= 2 do fiber.sleep(0.001) end
+
+-- Check server ids
+test_run:cmd('eval replica1 "return box.info.server.id"')
+
+box.space._cluster:len() == 2
+#box.info.vclock == 2
+
+-- Cleanup
+replica_set.drop_all(test_run)
+box.space._cluster:len() == 1
+#box.info.vclock == 1
+box.space.test:drop()
+box.schema.user.revoke('guest', 'read,write,execute', 'universe')
blob - 6b392325d21d8bb7fb45986d0ee853342c4be5ac (mode 644)
blob + /dev/null
--- test/replication/multi.result
+++ /dev/null
-fiber = require('fiber')
----
-...
-box.schema.user.grant('guest', 'replication')
----
-...
-box.schema.user.grant('guest', 'execute', 'universe')
----
-...
-----------------------------------------------------------------------
-Bootstrap replicas
-----------------------------------------------------------------------
-done
-----------------------------------------------------------------------
-Make a full mesh
-----------------------------------------------------------------------
-server 1 connected
-server 1 connected
-server 1 connected
-box.info.vclock
----
-- - 4
- - 0
- - 0
-...
-server 2 connected
-server 2 connected
-server 2 connected
-box.info.vclock
----
-- - 4
- - 0
- - 0
-...
-server 3 connected
-server 3 connected
-server 3 connected
-box.info.vclock
----
-- - 4
- - 0
- - 0
-...
-done
-----------------------------------------------------------------------
-Test inserts
-----------------------------------------------------------------------
-Create a test space
-_ = box.schema.space.create('test')
----
-...
-_ = box.space.test:create_index('primary')
----
-...
-server 1 is ok
-server 2 is ok
-server 3 is ok
-
-Insert records
-inserted 60 records
-
-Synchronize
-server 3 done
-server 3 done
-server 3 done
-done
-
-Check data
-server 1 is ok
-server 2 is ok
-server 3 is ok
-Done
-
-
-----------------------------------------------------------------------
-Cleanup
-----------------------------------------------------------------------
-server 1 done
-server 2 done
-server 3 done
-
blob - 6a564d9967b626d95feb8445f68a426b99568c97 (mode 644)
blob + /dev/null
--- test/replication/multi.test.py
+++ /dev/null
-import sys
-import os
-from lib.tarantool_server import TarantoolServer
-import yaml
-
-REPLICA_N = 3
-ROW_N = REPLICA_N * 20
-
-##
-
-# master server
-master = server
-master.admin("fiber = require('fiber')")
-master.admin("box.schema.user.grant('guest', 'replication')")
-master.admin("box.schema.user.grant('guest', 'execute', 'universe')")
-
-print '----------------------------------------------------------------------'
-print 'Bootstrap replicas'
-print '----------------------------------------------------------------------'
-
-# Start replicas
-master.id = master.get_param('server')['id']
-master_lsn = master.get_lsn(master.id)
-cluster = [ master ]
-for i in range(REPLICA_N - 1):
- server = TarantoolServer(server.ini)
- server.script = 'replication/replica.lua'
- server.vardir = os.path.join(server.vardir, 'replica', str(master.id + i))
- server.rpl_master = master
- server.deploy()
- # Wait replica to fully bootstrap.
- # Otherwise can get ACCESS_DENIED error.
- server.wait_lsn(master.id, master_lsn)
- cluster.append(server)
-
-# Make a list of servers
-sources = []
-for server in cluster:
- sources.append(yaml.load(server.admin('box.cfg.listen', silent = True))[0])
- server.id = server.get_param('server')['id']
-
-print 'done'
-
-print '----------------------------------------------------------------------'
-print 'Make a full mesh'
-print '----------------------------------------------------------------------'
-
-# Connect each server to each other to make full mesh
-for server in cluster:
- server.iproto.py_con.eval("box.cfg { replication_source = ... }", [sources])
-
-# Wait connections to establish
-for server in cluster:
- for server2 in cluster:
- server.iproto.py_con.eval("""
- while #box.info.vclock[...] ~= nil do
- fiber.sleep(0.01)
- end;""", server2.id)
- print 'server', server.id, "connected"
- server.admin("box.info.vclock")
-
-print 'done'
-
-print '----------------------------------------------------------------------'
-print 'Test inserts'
-print '----------------------------------------------------------------------'
-
-print 'Create a test space'
-master.admin("_ = box.schema.space.create('test')")
-master.admin("_ = box.space.test:create_index('primary')")
-master_lsn = master.get_lsn(master.id)
-# Wait changes to propagate to replicas
-for server in cluster:
- server.wait_lsn(master.id, master_lsn)
- print 'server', server.id, 'is ok'
-print
-
-print 'Insert records'
-for i in range(ROW_N):
- server = cluster[i % REPLICA_N]
- server.admin("box.space.test:insert{%d, %s}" % (i, server.id), silent = True)
-print 'inserted %d records' % ROW_N
-print
-
-print 'Synchronize'
-for server1 in cluster:
- for server2 in cluster:
- server1.wait_lsn(server2.id, server2.get_lsn(server2.id))
- print 'server', server.id, 'done'
-print 'done'
-print
-
-print 'Check data'
-for server in cluster:
- cnt = yaml.load(server.admin("box.space.test:len()", silent = True))[0]
- print 'server', server.id, 'is', cnt == ROW_N and 'ok' or 'not ok'
-print 'Done'
-print
-
-print
-print '----------------------------------------------------------------------'
-print 'Cleanup'
-print '----------------------------------------------------------------------'
-
-for server in cluster:
- server.stop()
- print 'server', server.id, 'done'
-print
-
-master.cleanup()
-master.deploy()
blob - a7848717d0a7bcc1fcea98adc0807cef4fa23889 (mode 644)
blob + /dev/null
--- test/replication/readonly.result
+++ /dev/null
-box.schema.user.grant('guest', 'replication')
----
-...
-box.info.server.id
----
-- 2
-...
-box.info.server.ro
----
-- false
-...
-box.info.server.lsn
----
-- 0
-...
--------------------------------------------------------------
-replica is read-only until receive self server_id in _cluster
--------------------------------------------------------------
-box.cfg{replication_source = ""}
----
-...
-box.info.server.id
----
-- 0
-...
-box.info.server.ro
----
-- true
-...
-box.info.server.lsn
----
-- -1
-...
-space = box.schema.space.create("ro")
----
-- error: Can't modify data because this server is in read-only mode.
-...
-box.info.vclock[2]
----
-- null
-...
blob - 438a81862675ecaac859fd967c7aed89eff2eb01 (mode 644)
blob + /dev/null
--- test/replication/readonly.test.py
+++ /dev/null
-import os
-from glob import iglob as glob
-from lib.tarantool_server import TarantoolServer
-
-# master server
-master = server
-master_id = master.get_param('server')['id']
-
-master.admin("box.schema.user.grant('guest', 'replication')")
-
-replica = TarantoolServer(server.ini)
-replica.script = 'replication/replica.lua'
-replica.vardir = server.vardir #os.path.join(server.vardir, 'replica')
-replica.rpl_master = master
-replica.deploy()
-replica.wait_lsn(master_id, master.get_lsn(master_id))
-replica_id = replica.get_param('server')['id']
-replica.admin('box.info.server.id')
-replica.admin('box.info.server.ro')
-replica.admin('box.info.server.lsn')
-replica.stop()
-
-print '-------------------------------------------------------------'
-print 'replica is read-only until receive self server_id in _cluster'
-print '-------------------------------------------------------------'
-
-# Remove xlog retrived by SUBSCRIBE
-filename = str(0).zfill(20) + ".xlog"
-wal = os.path.join(os.path.join(replica.vardir, replica.name), filename)
-os.remove(wal)
-
-# Start replica without master
-server.stop()
-replica.start()
-replica.admin('box.cfg{replication_source = ""}')
-
-# Check that replica in read-only mode
-replica.admin('box.info.server.id')
-replica.admin('box.info.server.ro')
-replica.admin('box.info.server.lsn')
-replica.admin('space = box.schema.space.create("ro")')
-replica.admin('box.info.vclock[%d]' % replica_id)
-
-replica.stop()
-replica.cleanup(True)
-server.deploy()
blob - 8f17558870b5b236180244de1cc5b48400767f69
blob + aaa1d169bec3ce01893adba28026c7112fade8b9
--- test/replication/s_join.result
+++ test/replication/s_join.result
---
- ok
...
+box.schema.user.revoke('guest', 'replication')
+---
+...
blob - 4a35739b9b1706942db018a200a953de28ebf1c1
blob + 0d5d40aa6ab171bfe2745e031e12016c78791e06
--- test/replication/s_join.test.lua
+++ test/replication/s_join.test.lua
test_run:cmd("cleanup server replica")
space:drop()
box.snapshot()
+box.schema.user.revoke('guest', 'replication')
blob - d3f227e2aa8dffa66143d677753bfba3093a0ed0 (mode 644)
blob + /dev/null
--- test/replication/sophia_join.result
+++ /dev/null
-box.schema.user.grant('guest', 'replication')
----
-...
-space = box.schema.space.create('test', { id = 99999, engine = "sophia" })
----
-...
-index = space:create_index('primary', { type = 'tree'})
----
-...
-for k = 1, 123 do space:insert{k, k*k} end
----
-...
-box.snapshot()
----
-- ok
-...
--------------------------------------------------------------
-replica JOIN
--------------------------------------------------------------
-box.space.test:select()
----
-- - [1, 1]
- - [2, 4]
- - [3, 9]
- - [4, 16]
- - [5, 25]
- - [6, 36]
- - [7, 49]
- - [8, 64]
- - [9, 81]
- - [10, 100]
- - [11, 121]
- - [12, 144]
- - [13, 169]
- - [14, 196]
- - [15, 225]
- - [16, 256]
- - [17, 289]
- - [18, 324]
- - [19, 361]
- - [20, 400]
- - [21, 441]
- - [22, 484]
- - [23, 529]
- - [24, 576]
- - [25, 625]
- - [26, 676]
- - [27, 729]
- - [28, 784]
- - [29, 841]
- - [30, 900]
- - [31, 961]
- - [32, 1024]
- - [33, 1089]
- - [34, 1156]
- - [35, 1225]
- - [36, 1296]
- - [37, 1369]
- - [38, 1444]
- - [39, 1521]
- - [40, 1600]
- - [41, 1681]
- - [42, 1764]
- - [43, 1849]
- - [44, 1936]
- - [45, 2025]
- - [46, 2116]
- - [47, 2209]
- - [48, 2304]
- - [49, 2401]
- - [50, 2500]
- - [51, 2601]
- - [52, 2704]
- - [53, 2809]
- - [54, 2916]
- - [55, 3025]
- - [56, 3136]
- - [57, 3249]
- - [58, 3364]
- - [59, 3481]
- - [60, 3600]
- - [61, 3721]
- - [62, 3844]
- - [63, 3969]
- - [64, 4096]
- - [65, 4225]
- - [66, 4356]
- - [67, 4489]
- - [68, 4624]
- - [69, 4761]
- - [70, 4900]
- - [71, 5041]
- - [72, 5184]
- - [73, 5329]
- - [74, 5476]
- - [75, 5625]
- - [76, 5776]
- - [77, 5929]
- - [78, 6084]
- - [79, 6241]
- - [80, 6400]
- - [81, 6561]
- - [82, 6724]
- - [83, 6889]
- - [84, 7056]
- - [85, 7225]
- - [86, 7396]
- - [87, 7569]
- - [88, 7744]
- - [89, 7921]
- - [90, 8100]
- - [91, 8281]
- - [92, 8464]
- - [93, 8649]
- - [94, 8836]
- - [95, 9025]
- - [96, 9216]
- - [97, 9409]
- - [98, 9604]
- - [99, 9801]
- - [100, 10000]
- - [101, 10201]
- - [102, 10404]
- - [103, 10609]
- - [104, 10816]
- - [105, 11025]
- - [106, 11236]
- - [107, 11449]
- - [108, 11664]
- - [109, 11881]
- - [110, 12100]
- - [111, 12321]
- - [112, 12544]
- - [113, 12769]
- - [114, 12996]
- - [115, 13225]
- - [116, 13456]
- - [117, 13689]
- - [118, 13924]
- - [119, 14161]
- - [120, 14400]
- - [121, 14641]
- - [122, 14884]
- - [123, 15129]
-...
-space:drop()
----
-...
-box.snapshot()
----
-- ok
-...
blob - 9d0a1b3a76a766583b1d5de7b10434e21fa29794 (mode 644)
blob + /dev/null
--- test/replication/sophia_join.test.py
+++ /dev/null
-import os
-import glob
-from lib.tarantool_server import TarantoolServer
-
-# master server
-master = server
-master_id = master.get_param('server')['id']
-
-master.admin("box.schema.user.grant('guest', 'replication')")
-master.admin("space = box.schema.space.create('test', { id = 99999, engine = \"sophia\" })")
-master.admin("index = space:create_index('primary', { type = 'tree'})")
-master.admin('for k = 1, 123 do space:insert{k, k*k} end')
-master.admin('box.snapshot()')
-lsn = master.get_lsn(master_id)
-
-print '-------------------------------------------------------------'
-print 'replica JOIN'
-print '-------------------------------------------------------------'
-
-# replica server
-replica = TarantoolServer(server.ini)
-replica.script = 'replication/replica.lua'
-replica.vardir = server.vardir #os.path.join(server.vardir,'replica')
-replica.rpl_master = master
-replica.deploy()
-replica.wait_lsn(master_id, lsn)
-replica.admin('box.space.test:select()')
-
-replica.stop()
-replica.cleanup(True)
-
-# remove space
-master.admin("space:drop()")
-master.admin('box.snapshot()')
blob - bbb74e36be7aa3556ecb64b3eadfce368cbd31c2
blob + d46347f64e6222738333c64c44b3d148fbee8d55
--- test/replication/status.result
+++ test/replication/status.result
---# set connection default
+env = require('test_run')
+---
+...
+test_run = env.new()
+---
+...
+test_run:cmd('switch default')
+---
+- true
+...
box.schema.user.grant('guest', 'replication')
---
...
---# create server replica with rpl_master=default, script='replication/replica.lua'
---# start server replica
---# set connection replica
+test_run:cmd("create server replica with rpl_master=default, script='replication/replica.lua'")
+---
+- true
+...
+test_run:cmd("start server replica")
+---
+- true
+...
+test_run:cmd('switch replica')
+---
+- true
+...
while box.space['_priv']:len() < 1 do fiber.sleep(0.001) end
---
...
---
- ['dup']
...
---# set connection default
+test_run:cmd('switch default')
+---
+- true
+...
box.space._schema:insert({'dup'})
---
- ['dup']
...
---# set connection replica
+test_run:cmd('switch replica')
+---
+- true
+...
r = box.info.replication
---
...
control_ch = require('fiber').channel(1)
---
...
---# setopt delimiter ';'
+test_run:cmd("setopt delimiter ';'")
+---
+- true
+...
local digest = require('digest')
slowpoke_loop = function(s, peer)
control_ch:get()
end;
---
...
---# setopt delimiter ''
+test_run:cmd("setopt delimiter ''");
+---
+- true
+...
slowpoke = require('socket').tcp_server('127.0.0.1', 0, slowpoke_loop)
---
...
---
- true
...
---# stop server replica
---# cleanup server replica
---# set connection default
+test_run:cmd('switch default')
+---
+- true
+...
box.schema.user.revoke('guest', 'replication')
---
...
+test_run:cmd("stop server replica")
+---
+- true
+...
+test_run:cmd("cleanup server replica")
+---
+- true
+...
blob - 491a611f24b60a0fde44b4216cd709361b625222
blob + b27b997cd9a7018b757c4cc3906ce26df6f7cf40
--- test/replication/status.test.lua
+++ test/replication/status.test.lua
---# set connection default
+env = require('test_run')
+test_run = env.new()
+test_run:cmd('switch default')
box.schema.user.grant('guest', 'replication')
---# create server replica with rpl_master=default, script='replication/replica.lua'
---# start server replica
---# set connection replica
+test_run:cmd("create server replica with rpl_master=default, script='replication/replica.lua'")
+test_run:cmd("start server replica")
+test_run:cmd('switch replica')
while box.space['_priv']:len() < 1 do fiber.sleep(0.001) end
r = box.info.replication
r.idle < 1
box.space._schema:insert({'dup'})
---# set connection default
+test_run:cmd('switch default')
box.space._schema:insert({'dup'})
---# set connection replica
+test_run:cmd('switch replica')
r = box.info.replication
r.status == "stopped"
r.message:match('Duplicate') ~= nil
-- Simulate a slow server to test replication info
control_ch = require('fiber').channel(1)
---# setopt delimiter ';'
+test_run:cmd("setopt delimiter ';'")
local digest = require('digest')
slowpoke_loop = function(s, peer)
control_ch:get()
s:shutdown()
s:close()
end;
---# setopt delimiter ''
+test_run:cmd("setopt delimiter ''");
slowpoke = require('socket').tcp_server('127.0.0.1', 0, slowpoke_loop)
uri = slowpoke:name()
r = box.info.replication
r.idle < 1
---# stop server replica
---# cleanup server replica
---# set connection default
+test_run:cmd('switch default')
box.schema.user.revoke('guest', 'replication')
+test_run:cmd("stop server replica")
+test_run:cmd("cleanup server replica")
blob - ecebdef354ea15c6808256f9ade5e644fcc86d4e
blob + b0874a0eb1b7e5aaf720a48e780448e501b05ce7
--- test/replication/suite.ini
+++ test/replication/suite.ini
description = tarantool/box, replication
disabled = consistent.test.lua
release_disabled = catch.test.lua
+lua_libs = lua/fast_replica.lua
blob - 84bacc69969560584eeb4a3efbe6768cf58f429c (mode 644)
blob + /dev/null
--- test/replication/swap.result
+++ /dev/null
-box.schema.user.create('test', { password = 'pass123456'})
----
-...
-box.schema.user.grant('test', 'read,write,execute', 'universe')
----
-...
-while box.info.server.id == 0 do require('fiber').sleep(0.01) end
----
-...
-while box.space['_priv']:len() < 1 do require('fiber').sleep(0.01) end
----
-...
-s = box.schema.space.create('memtx', { engine = 'memtx'})
----
-...
-index = s:create_index('primary', {type = 'tree'})
----
-...
-s = box.schema.space.create('sophia', { engine = 'sophia'})
----
-...
-index = s:create_index('primary', {type = 'tree'})
----
-...
-test 0 iteration
-box.space.memtx:insert{0, "tuple 0"}
--
-None
-box.space.memtx:insert{1, "tuple 1"}
--
-None
-box.space.memtx:insert{2, "tuple 2"}
--
-None
-box.space.memtx:insert{3, "tuple 3"}
--
-None
-box.space.memtx:insert{4, "tuple 4"}
--
-None
-box.space.sophia:insert{0, "tuple 0"}
--
-None
-box.space.sophia:insert{1, "tuple 1"}
--
-None
-box.space.sophia:insert{2, "tuple 2"}
--
-None
-box.space.sophia:insert{3, "tuple 3"}
--
-None
-box.space.sophia:insert{4, "tuple 4"}
--
-None
-box.space.memtx:select{0}
--
-- [0, tuple 0]
-
-box.space.memtx:select{1}
--
-- [1, tuple 1]
-
-box.space.memtx:select{2}
--
-- [2, tuple 2]
-
-box.space.memtx:select{3}
--
-- [3, tuple 3]
-
-box.space.memtx:select{4}
--
-- [4, tuple 4]
-
-box.space.sophia:select{0}
--
-- [0, tuple 0]
-
-box.space.sophia:select{1}
--
-- [1, tuple 1]
-
-box.space.sophia:select{2}
--
-- [2, tuple 2]
-
-box.space.sophia:select{3}
--
-- [3, tuple 3]
-
-box.space.sophia:select{4}
--
-- [4, tuple 4]
-
-box.space.memtx:insert{5, "tuple 5"}
--
-None
-box.space.memtx:insert{6, "tuple 6"}
--
-None
-box.space.memtx:insert{7, "tuple 7"}
--
-None
-box.space.memtx:insert{8, "tuple 8"}
--
-None
-box.space.memtx:insert{9, "tuple 9"}
--
-None
-box.space.sophia:insert{5, "tuple 5"}
--
-None
-box.space.sophia:insert{6, "tuple 6"}
--
-None
-box.space.sophia:insert{7, "tuple 7"}
--
-None
-box.space.sophia:insert{8, "tuple 8"}
--
-None
-box.space.sophia:insert{9, "tuple 9"}
--
-None
-box.space.memtx:select{5}
--
-- [5, tuple 5]
-
-box.space.memtx:select{6}
--
-- [6, tuple 6]
-
-box.space.memtx:select{7}
--
-- [7, tuple 7]
-
-box.space.memtx:select{8}
--
-- [8, tuple 8]
-
-box.space.memtx:select{9}
--
-- [9, tuple 9]
-
-box.space.sophia:select{5}
--
-- [5, tuple 5]
-
-box.space.sophia:select{6}
--
-- [6, tuple 6]
-
-box.space.sophia:select{7}
--
-- [7, tuple 7]
-
-box.space.sophia:select{8}
--
-- [8, tuple 8]
-
-box.space.sophia:select{9}
--
-- [9, tuple 9]
-
-swap servers
-switch replica to master
-box.cfg{replication_source=''}
----
-...
-switch master to replica
-box.space.memtx:insert{10, "tuple 10"}
--
-None
-box.space.memtx:insert{11, "tuple 11"}
--
-None
-box.space.memtx:insert{12, "tuple 12"}
--
-None
-box.space.memtx:insert{13, "tuple 13"}
--
-None
-box.space.memtx:insert{14, "tuple 14"}
--
-None
-box.space.sophia:insert{10, "tuple 10"}
--
-None
-box.space.sophia:insert{11, "tuple 11"}
--
-None
-box.space.sophia:insert{12, "tuple 12"}
--
-None
-box.space.sophia:insert{13, "tuple 13"}
--
-None
-box.space.sophia:insert{14, "tuple 14"}
--
-None
-box.space.memtx:select{10}
--
-- [10, tuple 10]
-
-box.space.memtx:select{11}
--
-- [11, tuple 11]
-
-box.space.memtx:select{12}
--
-- [12, tuple 12]
-
-box.space.memtx:select{13}
--
-- [13, tuple 13]
-
-box.space.memtx:select{14}
--
-- [14, tuple 14]
-
-box.space.sophia:select{10}
--
-- [10, tuple 10]
-
-box.space.sophia:select{11}
--
-- [11, tuple 11]
-
-box.space.sophia:select{12}
--
-- [12, tuple 12]
-
-box.space.sophia:select{13}
--
-- [13, tuple 13]
-
-box.space.sophia:select{14}
--
-- [14, tuple 14]
-
-box.space.memtx:insert{15, "tuple 15"}
--
-None
-box.space.memtx:insert{16, "tuple 16"}
--
-None
-box.space.memtx:insert{17, "tuple 17"}
--
-None
-box.space.memtx:insert{18, "tuple 18"}
--
-None
-box.space.memtx:insert{19, "tuple 19"}
--
-None
-box.space.sophia:insert{15, "tuple 15"}
--
-None
-box.space.sophia:insert{16, "tuple 16"}
--
-None
-box.space.sophia:insert{17, "tuple 17"}
--
-None
-box.space.sophia:insert{18, "tuple 18"}
--
-None
-box.space.sophia:insert{19, "tuple 19"}
--
-None
-box.space.memtx:select{15}
--
-- [15, tuple 15]
-
-box.space.memtx:select{16}
--
-- [16, tuple 16]
-
-box.space.memtx:select{17}
--
-- [17, tuple 17]
-
-box.space.memtx:select{18}
--
-- [18, tuple 18]
-
-box.space.memtx:select{19}
--
-- [19, tuple 19]
-
-box.space.sophia:select{15}
--
-- [15, tuple 15]
-
-box.space.sophia:select{16}
--
-- [16, tuple 16]
-
-box.space.sophia:select{17}
--
-- [17, tuple 17]
-
-box.space.sophia:select{18}
--
-- [18, tuple 18]
-
-box.space.sophia:select{19}
--
-- [19, tuple 19]
-
-rollback servers configuration
-switch master to master
-box.cfg{replication_source=''}
----
-...
-switch replica to replica
-test 1 iteration
-box.space.memtx:insert{20, "tuple 20"}
--
-None
-box.space.memtx:insert{21, "tuple 21"}
--
-None
-box.space.memtx:insert{22, "tuple 22"}
--
-None
-box.space.memtx:insert{23, "tuple 23"}
--
-None
-box.space.memtx:insert{24, "tuple 24"}
--
-None
-box.space.sophia:insert{20, "tuple 20"}
--
-None
-box.space.sophia:insert{21, "tuple 21"}
--
-None
-box.space.sophia:insert{22, "tuple 22"}
--
-None
-box.space.sophia:insert{23, "tuple 23"}
--
-None
-box.space.sophia:insert{24, "tuple 24"}
--
-None
-box.space.memtx:select{20}
--
-- [20, tuple 20]
-
-box.space.memtx:select{21}
--
-- [21, tuple 21]
-
-box.space.memtx:select{22}
--
-- [22, tuple 22]
-
-box.space.memtx:select{23}
--
-- [23, tuple 23]
-
-box.space.memtx:select{24}
--
-- [24, tuple 24]
-
-box.space.sophia:select{20}
--
-- [20, tuple 20]
-
-box.space.sophia:select{21}
--
-- [21, tuple 21]
-
-box.space.sophia:select{22}
--
-- [22, tuple 22]
-
-box.space.sophia:select{23}
--
-- [23, tuple 23]
-
-box.space.sophia:select{24}
--
-- [24, tuple 24]
-
-box.space.memtx:insert{25, "tuple 25"}
--
-None
-box.space.memtx:insert{26, "tuple 26"}
--
-None
-box.space.memtx:insert{27, "tuple 27"}
--
-None
-box.space.memtx:insert{28, "tuple 28"}
--
-None
-box.space.memtx:insert{29, "tuple 29"}
--
-None
-box.space.sophia:insert{25, "tuple 25"}
--
-None
-box.space.sophia:insert{26, "tuple 26"}
--
-None
-box.space.sophia:insert{27, "tuple 27"}
--
-None
-box.space.sophia:insert{28, "tuple 28"}
--
-None
-box.space.sophia:insert{29, "tuple 29"}
--
-None
-box.space.memtx:select{25}
--
-- [25, tuple 25]
-
-box.space.memtx:select{26}
--
-- [26, tuple 26]
-
-box.space.memtx:select{27}
--
-- [27, tuple 27]
-
-box.space.memtx:select{28}
--
-- [28, tuple 28]
-
-box.space.memtx:select{29}
--
-- [29, tuple 29]
-
-box.space.sophia:select{25}
--
-- [25, tuple 25]
-
-box.space.sophia:select{26}
--
-- [26, tuple 26]
-
-box.space.sophia:select{27}
--
-- [27, tuple 27]
-
-box.space.sophia:select{28}
--
-- [28, tuple 28]
-
-box.space.sophia:select{29}
--
-- [29, tuple 29]
-
-swap servers
-switch replica to master
-box.cfg{replication_source=''}
----
-...
-switch master to replica
-box.space.memtx:insert{30, "tuple 30"}
--
-None
-box.space.memtx:insert{31, "tuple 31"}
--
-None
-box.space.memtx:insert{32, "tuple 32"}
--
-None
-box.space.memtx:insert{33, "tuple 33"}
--
-None
-box.space.memtx:insert{34, "tuple 34"}
--
-None
-box.space.sophia:insert{30, "tuple 30"}
--
-None
-box.space.sophia:insert{31, "tuple 31"}
--
-None
-box.space.sophia:insert{32, "tuple 32"}
--
-None
-box.space.sophia:insert{33, "tuple 33"}
--
-None
-box.space.sophia:insert{34, "tuple 34"}
--
-None
-box.space.memtx:select{30}
--
-- [30, tuple 30]
-
-box.space.memtx:select{31}
--
-- [31, tuple 31]
-
-box.space.memtx:select{32}
--
-- [32, tuple 32]
-
-box.space.memtx:select{33}
--
-- [33, tuple 33]
-
-box.space.memtx:select{34}
--
-- [34, tuple 34]
-
-box.space.sophia:select{30}
--
-- [30, tuple 30]
-
-box.space.sophia:select{31}
--
-- [31, tuple 31]
-
-box.space.sophia:select{32}
--
-- [32, tuple 32]
-
-box.space.sophia:select{33}
--
-- [33, tuple 33]
-
-box.space.sophia:select{34}
--
-- [34, tuple 34]
-
-box.space.memtx:insert{35, "tuple 35"}
--
-None
-box.space.memtx:insert{36, "tuple 36"}
--
-None
-box.space.memtx:insert{37, "tuple 37"}
--
-None
-box.space.memtx:insert{38, "tuple 38"}
--
-None
-box.space.memtx:insert{39, "tuple 39"}
--
-None
-box.space.sophia:insert{35, "tuple 35"}
--
-None
-box.space.sophia:insert{36, "tuple 36"}
--
-None
-box.space.sophia:insert{37, "tuple 37"}
--
-None
-box.space.sophia:insert{38, "tuple 38"}
--
-None
-box.space.sophia:insert{39, "tuple 39"}
--
-None
-box.space.memtx:select{35}
--
-- [35, tuple 35]
-
-box.space.memtx:select{36}
--
-- [36, tuple 36]
-
-box.space.memtx:select{37}
--
-- [37, tuple 37]
-
-box.space.memtx:select{38}
--
-- [38, tuple 38]
-
-box.space.memtx:select{39}
--
-- [39, tuple 39]
-
-box.space.sophia:select{35}
--
-- [35, tuple 35]
-
-box.space.sophia:select{36}
--
-- [36, tuple 36]
-
-box.space.sophia:select{37}
--
-- [37, tuple 37]
-
-box.space.sophia:select{38}
--
-- [38, tuple 38]
-
-box.space.sophia:select{39}
--
-- [39, tuple 39]
-
-rollback servers configuration
-switch master to master
-box.cfg{replication_source=''}
----
-...
-switch replica to replica
-test 2 iteration
-box.space.memtx:insert{40, "tuple 40"}
--
-None
-box.space.memtx:insert{41, "tuple 41"}
--
-None
-box.space.memtx:insert{42, "tuple 42"}
--
-None
-box.space.memtx:insert{43, "tuple 43"}
--
-None
-box.space.memtx:insert{44, "tuple 44"}
--
-None
-box.space.sophia:insert{40, "tuple 40"}
--
-None
-box.space.sophia:insert{41, "tuple 41"}
--
-None
-box.space.sophia:insert{42, "tuple 42"}
--
-None
-box.space.sophia:insert{43, "tuple 43"}
--
-None
-box.space.sophia:insert{44, "tuple 44"}
--
-None
-box.space.memtx:select{40}
--
-- [40, tuple 40]
-
-box.space.memtx:select{41}
--
-- [41, tuple 41]
-
-box.space.memtx:select{42}
--
-- [42, tuple 42]
-
-box.space.memtx:select{43}
--
-- [43, tuple 43]
-
-box.space.memtx:select{44}
--
-- [44, tuple 44]
-
-box.space.sophia:select{40}
--
-- [40, tuple 40]
-
-box.space.sophia:select{41}
--
-- [41, tuple 41]
-
-box.space.sophia:select{42}
--
-- [42, tuple 42]
-
-box.space.sophia:select{43}
--
-- [43, tuple 43]
-
-box.space.sophia:select{44}
--
-- [44, tuple 44]
-
-box.space.memtx:insert{45, "tuple 45"}
--
-None
-box.space.memtx:insert{46, "tuple 46"}
--
-None
-box.space.memtx:insert{47, "tuple 47"}
--
-None
-box.space.memtx:insert{48, "tuple 48"}
--
-None
-box.space.memtx:insert{49, "tuple 49"}
--
-None
-box.space.sophia:insert{45, "tuple 45"}
--
-None
-box.space.sophia:insert{46, "tuple 46"}
--
-None
-box.space.sophia:insert{47, "tuple 47"}
--
-None
-box.space.sophia:insert{48, "tuple 48"}
--
-None
-box.space.sophia:insert{49, "tuple 49"}
--
-None
-box.space.memtx:select{45}
--
-- [45, tuple 45]
-
-box.space.memtx:select{46}
--
-- [46, tuple 46]
-
-box.space.memtx:select{47}
--
-- [47, tuple 47]
-
-box.space.memtx:select{48}
--
-- [48, tuple 48]
-
-box.space.memtx:select{49}
--
-- [49, tuple 49]
-
-box.space.sophia:select{45}
--
-- [45, tuple 45]
-
-box.space.sophia:select{46}
--
-- [46, tuple 46]
-
-box.space.sophia:select{47}
--
-- [47, tuple 47]
-
-box.space.sophia:select{48}
--
-- [48, tuple 48]
-
-box.space.sophia:select{49}
--
-- [49, tuple 49]
-
-swap servers
-switch replica to master
-box.cfg{replication_source=''}
----
-...
-switch master to replica
-box.space.memtx:insert{50, "tuple 50"}
--
-None
-box.space.memtx:insert{51, "tuple 51"}
--
-None
-box.space.memtx:insert{52, "tuple 52"}
--
-None
-box.space.memtx:insert{53, "tuple 53"}
--
-None
-box.space.memtx:insert{54, "tuple 54"}
--
-None
-box.space.sophia:insert{50, "tuple 50"}
--
-None
-box.space.sophia:insert{51, "tuple 51"}
--
-None
-box.space.sophia:insert{52, "tuple 52"}
--
-None
-box.space.sophia:insert{53, "tuple 53"}
--
-None
-box.space.sophia:insert{54, "tuple 54"}
--
-None
-box.space.memtx:select{50}
--
-- [50, tuple 50]
-
-box.space.memtx:select{51}
--
-- [51, tuple 51]
-
-box.space.memtx:select{52}
--
-- [52, tuple 52]
-
-box.space.memtx:select{53}
--
-- [53, tuple 53]
-
-box.space.memtx:select{54}
--
-- [54, tuple 54]
-
-box.space.sophia:select{50}
--
-- [50, tuple 50]
-
-box.space.sophia:select{51}
--
-- [51, tuple 51]
-
-box.space.sophia:select{52}
--
-- [52, tuple 52]
-
-box.space.sophia:select{53}
--
-- [53, tuple 53]
-
-box.space.sophia:select{54}
--
-- [54, tuple 54]
-
-box.space.memtx:insert{55, "tuple 55"}
--
-None
-box.space.memtx:insert{56, "tuple 56"}
--
-None
-box.space.memtx:insert{57, "tuple 57"}
--
-None
-box.space.memtx:insert{58, "tuple 58"}
--
-None
-box.space.memtx:insert{59, "tuple 59"}
--
-None
-box.space.sophia:insert{55, "tuple 55"}
--
-None
-box.space.sophia:insert{56, "tuple 56"}
--
-None
-box.space.sophia:insert{57, "tuple 57"}
--
-None
-box.space.sophia:insert{58, "tuple 58"}
--
-None
-box.space.sophia:insert{59, "tuple 59"}
--
-None
-box.space.memtx:select{55}
--
-- [55, tuple 55]
-
-box.space.memtx:select{56}
--
-- [56, tuple 56]
-
-box.space.memtx:select{57}
--
-- [57, tuple 57]
-
-box.space.memtx:select{58}
--
-- [58, tuple 58]
-
-box.space.memtx:select{59}
--
-- [59, tuple 59]
-
-box.space.sophia:select{55}
--
-- [55, tuple 55]
-
-box.space.sophia:select{56}
--
-- [56, tuple 56]
-
-box.space.sophia:select{57}
--
-- [57, tuple 57]
-
-box.space.sophia:select{58}
--
-- [58, tuple 58]
-
-box.space.sophia:select{59}
--
-- [59, tuple 59]
-
-rollback servers configuration
-switch master to master
-box.cfg{replication_source=''}
----
-...
-switch replica to replica
-test 3 iteration
-box.space.memtx:insert{60, "tuple 60"}
--
-None
-box.space.memtx:insert{61, "tuple 61"}
--
-None
-box.space.memtx:insert{62, "tuple 62"}
--
-None
-box.space.memtx:insert{63, "tuple 63"}
--
-None
-box.space.memtx:insert{64, "tuple 64"}
--
-None
-box.space.sophia:insert{60, "tuple 60"}
--
-None
-box.space.sophia:insert{61, "tuple 61"}
--
-None
-box.space.sophia:insert{62, "tuple 62"}
--
-None
-box.space.sophia:insert{63, "tuple 63"}
--
-None
-box.space.sophia:insert{64, "tuple 64"}
--
-None
-box.space.memtx:select{60}
--
-- [60, tuple 60]
-
-box.space.memtx:select{61}
--
-- [61, tuple 61]
-
-box.space.memtx:select{62}
--
-- [62, tuple 62]
-
-box.space.memtx:select{63}
--
-- [63, tuple 63]
-
-box.space.memtx:select{64}
--
-- [64, tuple 64]
-
-box.space.sophia:select{60}
--
-- [60, tuple 60]
-
-box.space.sophia:select{61}
--
-- [61, tuple 61]
-
-box.space.sophia:select{62}
--
-- [62, tuple 62]
-
-box.space.sophia:select{63}
--
-- [63, tuple 63]
-
-box.space.sophia:select{64}
--
-- [64, tuple 64]
-
-box.space.memtx:insert{65, "tuple 65"}
--
-None
-box.space.memtx:insert{66, "tuple 66"}
--
-None
-box.space.memtx:insert{67, "tuple 67"}
--
-None
-box.space.memtx:insert{68, "tuple 68"}
--
-None
-box.space.memtx:insert{69, "tuple 69"}
--
-None
-box.space.sophia:insert{65, "tuple 65"}
--
-None
-box.space.sophia:insert{66, "tuple 66"}
--
-None
-box.space.sophia:insert{67, "tuple 67"}
--
-None
-box.space.sophia:insert{68, "tuple 68"}
--
-None
-box.space.sophia:insert{69, "tuple 69"}
--
-None
-box.space.memtx:select{65}
--
-- [65, tuple 65]
-
-box.space.memtx:select{66}
--
-- [66, tuple 66]
-
-box.space.memtx:select{67}
--
-- [67, tuple 67]
-
-box.space.memtx:select{68}
--
-- [68, tuple 68]
-
-box.space.memtx:select{69}
--
-- [69, tuple 69]
-
-box.space.sophia:select{65}
--
-- [65, tuple 65]
-
-box.space.sophia:select{66}
--
-- [66, tuple 66]
-
-box.space.sophia:select{67}
--
-- [67, tuple 67]
-
-box.space.sophia:select{68}
--
-- [68, tuple 68]
-
-box.space.sophia:select{69}
--
-- [69, tuple 69]
-
-swap servers
-switch replica to master
-box.cfg{replication_source=''}
----
-...
-switch master to replica
-box.space.memtx:insert{70, "tuple 70"}
--
-None
-box.space.memtx:insert{71, "tuple 71"}
--
-None
-box.space.memtx:insert{72, "tuple 72"}
--
-None
-box.space.memtx:insert{73, "tuple 73"}
--
-None
-box.space.memtx:insert{74, "tuple 74"}
--
-None
-box.space.sophia:insert{70, "tuple 70"}
--
-None
-box.space.sophia:insert{71, "tuple 71"}
--
-None
-box.space.sophia:insert{72, "tuple 72"}
--
-None
-box.space.sophia:insert{73, "tuple 73"}
--
-None
-box.space.sophia:insert{74, "tuple 74"}
--
-None
-box.space.memtx:select{70}
--
-- [70, tuple 70]
-
-box.space.memtx:select{71}
--
-- [71, tuple 71]
-
-box.space.memtx:select{72}
--
-- [72, tuple 72]
-
-box.space.memtx:select{73}
--
-- [73, tuple 73]
-
-box.space.memtx:select{74}
--
-- [74, tuple 74]
-
-box.space.sophia:select{70}
--
-- [70, tuple 70]
-
-box.space.sophia:select{71}
--
-- [71, tuple 71]
-
-box.space.sophia:select{72}
--
-- [72, tuple 72]
-
-box.space.sophia:select{73}
--
-- [73, tuple 73]
-
-box.space.sophia:select{74}
--
-- [74, tuple 74]
-
-box.space.memtx:insert{75, "tuple 75"}
--
-None
-box.space.memtx:insert{76, "tuple 76"}
--
-None
-box.space.memtx:insert{77, "tuple 77"}
--
-None
-box.space.memtx:insert{78, "tuple 78"}
--
-None
-box.space.memtx:insert{79, "tuple 79"}
--
-None
-box.space.sophia:insert{75, "tuple 75"}
--
-None
-box.space.sophia:insert{76, "tuple 76"}
--
-None
-box.space.sophia:insert{77, "tuple 77"}
--
-None
-box.space.sophia:insert{78, "tuple 78"}
--
-None
-box.space.sophia:insert{79, "tuple 79"}
--
-None
-box.space.memtx:select{75}
--
-- [75, tuple 75]
-
-box.space.memtx:select{76}
--
-- [76, tuple 76]
-
-box.space.memtx:select{77}
--
-- [77, tuple 77]
-
-box.space.memtx:select{78}
--
-- [78, tuple 78]
-
-box.space.memtx:select{79}
--
-- [79, tuple 79]
-
-box.space.sophia:select{75}
--
-- [75, tuple 75]
-
-box.space.sophia:select{76}
--
-- [76, tuple 76]
-
-box.space.sophia:select{77}
--
-- [77, tuple 77]
-
-box.space.sophia:select{78}
--
-- [78, tuple 78]
-
-box.space.sophia:select{79}
--
-- [79, tuple 79]
-
-rollback servers configuration
-switch master to master
-box.cfg{replication_source=''}
----
-...
-switch replica to replica
-test 4 iteration
-box.space.memtx:insert{80, "tuple 80"}
--
-None
-box.space.memtx:insert{81, "tuple 81"}
--
-None
-box.space.memtx:insert{82, "tuple 82"}
--
-None
-box.space.memtx:insert{83, "tuple 83"}
--
-None
-box.space.memtx:insert{84, "tuple 84"}
--
-None
-box.space.sophia:insert{80, "tuple 80"}
--
-None
-box.space.sophia:insert{81, "tuple 81"}
--
-None
-box.space.sophia:insert{82, "tuple 82"}
--
-None
-box.space.sophia:insert{83, "tuple 83"}
--
-None
-box.space.sophia:insert{84, "tuple 84"}
--
-None
-box.space.memtx:select{80}
--
-- [80, tuple 80]
-
-box.space.memtx:select{81}
--
-- [81, tuple 81]
-
-box.space.memtx:select{82}
--
-- [82, tuple 82]
-
-box.space.memtx:select{83}
--
-- [83, tuple 83]
-
-box.space.memtx:select{84}
--
-- [84, tuple 84]
-
-box.space.sophia:select{80}
--
-- [80, tuple 80]
-
-box.space.sophia:select{81}
--
-- [81, tuple 81]
-
-box.space.sophia:select{82}
--
-- [82, tuple 82]
-
-box.space.sophia:select{83}
--
-- [83, tuple 83]
-
-box.space.sophia:select{84}
--
-- [84, tuple 84]
-
-box.space.memtx:insert{85, "tuple 85"}
--
-None
-box.space.memtx:insert{86, "tuple 86"}
--
-None
-box.space.memtx:insert{87, "tuple 87"}
--
-None
-box.space.memtx:insert{88, "tuple 88"}
--
-None
-box.space.memtx:insert{89, "tuple 89"}
--
-None
-box.space.sophia:insert{85, "tuple 85"}
--
-None
-box.space.sophia:insert{86, "tuple 86"}
--
-None
-box.space.sophia:insert{87, "tuple 87"}
--
-None
-box.space.sophia:insert{88, "tuple 88"}
--
-None
-box.space.sophia:insert{89, "tuple 89"}
--
-None
-box.space.memtx:select{85}
--
-- [85, tuple 85]
-
-box.space.memtx:select{86}
--
-- [86, tuple 86]
-
-box.space.memtx:select{87}
--
-- [87, tuple 87]
-
-box.space.memtx:select{88}
--
-- [88, tuple 88]
-
-box.space.memtx:select{89}
--
-- [89, tuple 89]
-
-box.space.sophia:select{85}
--
-- [85, tuple 85]
-
-box.space.sophia:select{86}
--
-- [86, tuple 86]
-
-box.space.sophia:select{87}
--
-- [87, tuple 87]
-
-box.space.sophia:select{88}
--
-- [88, tuple 88]
-
-box.space.sophia:select{89}
--
-- [89, tuple 89]
-
-swap servers
-switch replica to master
-box.cfg{replication_source=''}
----
-...
-switch master to replica
-box.space.memtx:insert{90, "tuple 90"}
--
-None
-box.space.memtx:insert{91, "tuple 91"}
--
-None
-box.space.memtx:insert{92, "tuple 92"}
--
-None
-box.space.memtx:insert{93, "tuple 93"}
--
-None
-box.space.memtx:insert{94, "tuple 94"}
--
-None
-box.space.sophia:insert{90, "tuple 90"}
--
-None
-box.space.sophia:insert{91, "tuple 91"}
--
-None
-box.space.sophia:insert{92, "tuple 92"}
--
-None
-box.space.sophia:insert{93, "tuple 93"}
--
-None
-box.space.sophia:insert{94, "tuple 94"}
--
-None
-box.space.memtx:select{90}
--
-- [90, tuple 90]
-
-box.space.memtx:select{91}
--
-- [91, tuple 91]
-
-box.space.memtx:select{92}
--
-- [92, tuple 92]
-
-box.space.memtx:select{93}
--
-- [93, tuple 93]
-
-box.space.memtx:select{94}
--
-- [94, tuple 94]
-
-box.space.sophia:select{90}
--
-- [90, tuple 90]
-
-box.space.sophia:select{91}
--
-- [91, tuple 91]
-
-box.space.sophia:select{92}
--
-- [92, tuple 92]
-
-box.space.sophia:select{93}
--
-- [93, tuple 93]
-
-box.space.sophia:select{94}
--
-- [94, tuple 94]
-
-box.space.memtx:insert{95, "tuple 95"}
--
-None
-box.space.memtx:insert{96, "tuple 96"}
--
-None
-box.space.memtx:insert{97, "tuple 97"}
--
-None
-box.space.memtx:insert{98, "tuple 98"}
--
-None
-box.space.memtx:insert{99, "tuple 99"}
--
-None
-box.space.sophia:insert{95, "tuple 95"}
--
-None
-box.space.sophia:insert{96, "tuple 96"}
--
-None
-box.space.sophia:insert{97, "tuple 97"}
--
-None
-box.space.sophia:insert{98, "tuple 98"}
--
-None
-box.space.sophia:insert{99, "tuple 99"}
--
-None
-box.space.memtx:select{95}
--
-- [95, tuple 95]
-
-box.space.memtx:select{96}
--
-- [96, tuple 96]
-
-box.space.memtx:select{97}
--
-- [97, tuple 97]
-
-box.space.memtx:select{98}
--
-- [98, tuple 98]
-
-box.space.memtx:select{99}
--
-- [99, tuple 99]
-
-box.space.sophia:select{95}
--
-- [95, tuple 95]
-
-box.space.sophia:select{96}
--
-- [96, tuple 96]
-
-box.space.sophia:select{97}
--
-- [97, tuple 97]
-
-box.space.sophia:select{98}
--
-- [98, tuple 98]
-
-box.space.sophia:select{99}
--
-- [99, tuple 99]
-
-rollback servers configuration
-switch master to master
-box.cfg{replication_source=''}
----
-...
-switch replica to replica
-test 5 iteration
-box.space.memtx:insert{100, "tuple 100"}
--
-None
-box.space.memtx:insert{101, "tuple 101"}
--
-None
-box.space.memtx:insert{102, "tuple 102"}
--
-None
-box.space.memtx:insert{103, "tuple 103"}
--
-None
-box.space.memtx:insert{104, "tuple 104"}
--
-None
-box.space.sophia:insert{100, "tuple 100"}
--
-None
-box.space.sophia:insert{101, "tuple 101"}
--
-None
-box.space.sophia:insert{102, "tuple 102"}
--
-None
-box.space.sophia:insert{103, "tuple 103"}
--
-None
-box.space.sophia:insert{104, "tuple 104"}
--
-None
-box.space.memtx:select{100}
--
-- [100, tuple 100]
-
-box.space.memtx:select{101}
--
-- [101, tuple 101]
-
-box.space.memtx:select{102}
--
-- [102, tuple 102]
-
-box.space.memtx:select{103}
--
-- [103, tuple 103]
-
-box.space.memtx:select{104}
--
-- [104, tuple 104]
-
-box.space.sophia:select{100}
--
-- [100, tuple 100]
-
-box.space.sophia:select{101}
--
-- [101, tuple 101]
-
-box.space.sophia:select{102}
--
-- [102, tuple 102]
-
-box.space.sophia:select{103}
--
-- [103, tuple 103]
-
-box.space.sophia:select{104}
--
-- [104, tuple 104]
-
-box.space.memtx:insert{105, "tuple 105"}
--
-None
-box.space.memtx:insert{106, "tuple 106"}
--
-None
-box.space.memtx:insert{107, "tuple 107"}
--
-None
-box.space.memtx:insert{108, "tuple 108"}
--
-None
-box.space.memtx:insert{109, "tuple 109"}
--
-None
-box.space.sophia:insert{105, "tuple 105"}
--
-None
-box.space.sophia:insert{106, "tuple 106"}
--
-None
-box.space.sophia:insert{107, "tuple 107"}
--
-None
-box.space.sophia:insert{108, "tuple 108"}
--
-None
-box.space.sophia:insert{109, "tuple 109"}
--
-None
-box.space.memtx:select{105}
--
-- [105, tuple 105]
-
-box.space.memtx:select{106}
--
-- [106, tuple 106]
-
-box.space.memtx:select{107}
--
-- [107, tuple 107]
-
-box.space.memtx:select{108}
--
-- [108, tuple 108]
-
-box.space.memtx:select{109}
--
-- [109, tuple 109]
-
-box.space.sophia:select{105}
--
-- [105, tuple 105]
-
-box.space.sophia:select{106}
--
-- [106, tuple 106]
-
-box.space.sophia:select{107}
--
-- [107, tuple 107]
-
-box.space.sophia:select{108}
--
-- [108, tuple 108]
-
-box.space.sophia:select{109}
--
-- [109, tuple 109]
-
-swap servers
-switch replica to master
-box.cfg{replication_source=''}
----
-...
-switch master to replica
-box.space.memtx:insert{110, "tuple 110"}
--
-None
-box.space.memtx:insert{111, "tuple 111"}
--
-None
-box.space.memtx:insert{112, "tuple 112"}
--
-None
-box.space.memtx:insert{113, "tuple 113"}
--
-None
-box.space.memtx:insert{114, "tuple 114"}
--
-None
-box.space.sophia:insert{110, "tuple 110"}
--
-None
-box.space.sophia:insert{111, "tuple 111"}
--
-None
-box.space.sophia:insert{112, "tuple 112"}
--
-None
-box.space.sophia:insert{113, "tuple 113"}
--
-None
-box.space.sophia:insert{114, "tuple 114"}
--
-None
-box.space.memtx:select{110}
--
-- [110, tuple 110]
-
-box.space.memtx:select{111}
--
-- [111, tuple 111]
-
-box.space.memtx:select{112}
--
-- [112, tuple 112]
-
-box.space.memtx:select{113}
--
-- [113, tuple 113]
-
-box.space.memtx:select{114}
--
-- [114, tuple 114]
-
-box.space.sophia:select{110}
--
-- [110, tuple 110]
-
-box.space.sophia:select{111}
--
-- [111, tuple 111]
-
-box.space.sophia:select{112}
--
-- [112, tuple 112]
-
-box.space.sophia:select{113}
--
-- [113, tuple 113]
-
-box.space.sophia:select{114}
--
-- [114, tuple 114]
-
-box.space.memtx:insert{115, "tuple 115"}
--
-None
-box.space.memtx:insert{116, "tuple 116"}
--
-None
-box.space.memtx:insert{117, "tuple 117"}
--
-None
-box.space.memtx:insert{118, "tuple 118"}
--
-None
-box.space.memtx:insert{119, "tuple 119"}
--
-None
-box.space.sophia:insert{115, "tuple 115"}
--
-None
-box.space.sophia:insert{116, "tuple 116"}
--
-None
-box.space.sophia:insert{117, "tuple 117"}
--
-None
-box.space.sophia:insert{118, "tuple 118"}
--
-None
-box.space.sophia:insert{119, "tuple 119"}
--
-None
-box.space.memtx:select{115}
--
-- [115, tuple 115]
-
-box.space.memtx:select{116}
--
-- [116, tuple 116]
-
-box.space.memtx:select{117}
--
-- [117, tuple 117]
-
-box.space.memtx:select{118}
--
-- [118, tuple 118]
-
-box.space.memtx:select{119}
--
-- [119, tuple 119]
-
-box.space.sophia:select{115}
--
-- [115, tuple 115]
-
-box.space.sophia:select{116}
--
-- [116, tuple 116]
-
-box.space.sophia:select{117}
--
-- [117, tuple 117]
-
-box.space.sophia:select{118}
--
-- [118, tuple 118]
-
-box.space.sophia:select{119}
--
-- [119, tuple 119]
-
-rollback servers configuration
-switch master to master
-box.cfg{replication_source=''}
----
-...
-switch replica to replica
-test 6 iteration
-box.space.memtx:insert{120, "tuple 120"}
--
-None
-box.space.memtx:insert{121, "tuple 121"}
--
-None
-box.space.memtx:insert{122, "tuple 122"}
--
-None
-box.space.memtx:insert{123, "tuple 123"}
--
-None
-box.space.memtx:insert{124, "tuple 124"}
--
-None
-box.space.sophia:insert{120, "tuple 120"}
--
-None
-box.space.sophia:insert{121, "tuple 121"}
--
-None
-box.space.sophia:insert{122, "tuple 122"}
--
-None
-box.space.sophia:insert{123, "tuple 123"}
--
-None
-box.space.sophia:insert{124, "tuple 124"}
--
-None
-box.space.memtx:select{120}
--
-- [120, tuple 120]
-
-box.space.memtx:select{121}
--
-- [121, tuple 121]
-
-box.space.memtx:select{122}
--
-- [122, tuple 122]
-
-box.space.memtx:select{123}
--
-- [123, tuple 123]
-
-box.space.memtx:select{124}
--
-- [124, tuple 124]
-
-box.space.sophia:select{120}
--
-- [120, tuple 120]
-
-box.space.sophia:select{121}
--
-- [121, tuple 121]
-
-box.space.sophia:select{122}
--
-- [122, tuple 122]
-
-box.space.sophia:select{123}
--
-- [123, tuple 123]
-
-box.space.sophia:select{124}
--
-- [124, tuple 124]
-
-box.space.memtx:insert{125, "tuple 125"}
--
-None
-box.space.memtx:insert{126, "tuple 126"}
--
-None
-box.space.memtx:insert{127, "tuple 127"}
--
-None
-box.space.memtx:insert{128, "tuple 128"}
--
-None
-box.space.memtx:insert{129, "tuple 129"}
--
-None
-box.space.sophia:insert{125, "tuple 125"}
--
-None
-box.space.sophia:insert{126, "tuple 126"}
--
-None
-box.space.sophia:insert{127, "tuple 127"}
--
-None
-box.space.sophia:insert{128, "tuple 128"}
--
-None
-box.space.sophia:insert{129, "tuple 129"}
--
-None
-box.space.memtx:select{125}
--
-- [125, tuple 125]
-
-box.space.memtx:select{126}
--
-- [126, tuple 126]
-
-box.space.memtx:select{127}
--
-- [127, tuple 127]
-
-box.space.memtx:select{128}
--
-- [128, tuple 128]
-
-box.space.memtx:select{129}
--
-- [129, tuple 129]
-
-box.space.sophia:select{125}
--
-- [125, tuple 125]
-
-box.space.sophia:select{126}
--
-- [126, tuple 126]
-
-box.space.sophia:select{127}
--
-- [127, tuple 127]
-
-box.space.sophia:select{128}
--
-- [128, tuple 128]
-
-box.space.sophia:select{129}
--
-- [129, tuple 129]
-
-swap servers
-switch replica to master
-box.cfg{replication_source=''}
----
-...
-switch master to replica
-box.space.memtx:insert{130, "tuple 130"}
--
-None
-box.space.memtx:insert{131, "tuple 131"}
--
-None
-box.space.memtx:insert{132, "tuple 132"}
--
-None
-box.space.memtx:insert{133, "tuple 133"}
--
-None
-box.space.memtx:insert{134, "tuple 134"}
--
-None
-box.space.sophia:insert{130, "tuple 130"}
--
-None
-box.space.sophia:insert{131, "tuple 131"}
--
-None
-box.space.sophia:insert{132, "tuple 132"}
--
-None
-box.space.sophia:insert{133, "tuple 133"}
--
-None
-box.space.sophia:insert{134, "tuple 134"}
--
-None
-box.space.memtx:select{130}
--
-- [130, tuple 130]
-
-box.space.memtx:select{131}
--
-- [131, tuple 131]
-
-box.space.memtx:select{132}
--
-- [132, tuple 132]
-
-box.space.memtx:select{133}
--
-- [133, tuple 133]
-
-box.space.memtx:select{134}
--
-- [134, tuple 134]
-
-box.space.sophia:select{130}
--
-- [130, tuple 130]
-
-box.space.sophia:select{131}
--
-- [131, tuple 131]
-
-box.space.sophia:select{132}
--
-- [132, tuple 132]
-
-box.space.sophia:select{133}
--
-- [133, tuple 133]
-
-box.space.sophia:select{134}
--
-- [134, tuple 134]
-
-box.space.memtx:insert{135, "tuple 135"}
--
-None
-box.space.memtx:insert{136, "tuple 136"}
--
-None
-box.space.memtx:insert{137, "tuple 137"}
--
-None
-box.space.memtx:insert{138, "tuple 138"}
--
-None
-box.space.memtx:insert{139, "tuple 139"}
--
-None
-box.space.sophia:insert{135, "tuple 135"}
--
-None
-box.space.sophia:insert{136, "tuple 136"}
--
-None
-box.space.sophia:insert{137, "tuple 137"}
--
-None
-box.space.sophia:insert{138, "tuple 138"}
--
-None
-box.space.sophia:insert{139, "tuple 139"}
--
-None
-box.space.memtx:select{135}
--
-- [135, tuple 135]
-
-box.space.memtx:select{136}
--
-- [136, tuple 136]
-
-box.space.memtx:select{137}
--
-- [137, tuple 137]
-
-box.space.memtx:select{138}
--
-- [138, tuple 138]
-
-box.space.memtx:select{139}
--
-- [139, tuple 139]
-
-box.space.sophia:select{135}
--
-- [135, tuple 135]
-
-box.space.sophia:select{136}
--
-- [136, tuple 136]
-
-box.space.sophia:select{137}
--
-- [137, tuple 137]
-
-box.space.sophia:select{138}
--
-- [138, tuple 138]
-
-box.space.sophia:select{139}
--
-- [139, tuple 139]
-
-rollback servers configuration
-switch master to master
-box.cfg{replication_source=''}
----
-...
-switch replica to replica
-test 7 iteration
-box.space.memtx:insert{140, "tuple 140"}
--
-None
-box.space.memtx:insert{141, "tuple 141"}
--
-None
-box.space.memtx:insert{142, "tuple 142"}
--
-None
-box.space.memtx:insert{143, "tuple 143"}
--
-None
-box.space.memtx:insert{144, "tuple 144"}
--
-None
-box.space.sophia:insert{140, "tuple 140"}
--
-None
-box.space.sophia:insert{141, "tuple 141"}
--
-None
-box.space.sophia:insert{142, "tuple 142"}
--
-None
-box.space.sophia:insert{143, "tuple 143"}
--
-None
-box.space.sophia:insert{144, "tuple 144"}
--
-None
-box.space.memtx:select{140}
--
-- [140, tuple 140]
-
-box.space.memtx:select{141}
--
-- [141, tuple 141]
-
-box.space.memtx:select{142}
--
-- [142, tuple 142]
-
-box.space.memtx:select{143}
--
-- [143, tuple 143]
-
-box.space.memtx:select{144}
--
-- [144, tuple 144]
-
-box.space.sophia:select{140}
--
-- [140, tuple 140]
-
-box.space.sophia:select{141}
--
-- [141, tuple 141]
-
-box.space.sophia:select{142}
--
-- [142, tuple 142]
-
-box.space.sophia:select{143}
--
-- [143, tuple 143]
-
-box.space.sophia:select{144}
--
-- [144, tuple 144]
-
-box.space.memtx:insert{145, "tuple 145"}
--
-None
-box.space.memtx:insert{146, "tuple 146"}
--
-None
-box.space.memtx:insert{147, "tuple 147"}
--
-None
-box.space.memtx:insert{148, "tuple 148"}
--
-None
-box.space.memtx:insert{149, "tuple 149"}
--
-None
-box.space.sophia:insert{145, "tuple 145"}
--
-None
-box.space.sophia:insert{146, "tuple 146"}
--
-None
-box.space.sophia:insert{147, "tuple 147"}
--
-None
-box.space.sophia:insert{148, "tuple 148"}
--
-None
-box.space.sophia:insert{149, "tuple 149"}
--
-None
-box.space.memtx:select{145}
--
-- [145, tuple 145]
-
-box.space.memtx:select{146}
--
-- [146, tuple 146]
-
-box.space.memtx:select{147}
--
-- [147, tuple 147]
-
-box.space.memtx:select{148}
--
-- [148, tuple 148]
-
-box.space.memtx:select{149}
--
-- [149, tuple 149]
-
-box.space.sophia:select{145}
--
-- [145, tuple 145]
-
-box.space.sophia:select{146}
--
-- [146, tuple 146]
-
-box.space.sophia:select{147}
--
-- [147, tuple 147]
-
-box.space.sophia:select{148}
--
-- [148, tuple 148]
-
-box.space.sophia:select{149}
--
-- [149, tuple 149]
-
-swap servers
-switch replica to master
-box.cfg{replication_source=''}
----
-...
-switch master to replica
-box.space.memtx:insert{150, "tuple 150"}
--
-None
-box.space.memtx:insert{151, "tuple 151"}
--
-None
-box.space.memtx:insert{152, "tuple 152"}
--
-None
-box.space.memtx:insert{153, "tuple 153"}
--
-None
-box.space.memtx:insert{154, "tuple 154"}
--
-None
-box.space.sophia:insert{150, "tuple 150"}
--
-None
-box.space.sophia:insert{151, "tuple 151"}
--
-None
-box.space.sophia:insert{152, "tuple 152"}
--
-None
-box.space.sophia:insert{153, "tuple 153"}
--
-None
-box.space.sophia:insert{154, "tuple 154"}
--
-None
-box.space.memtx:select{150}
--
-- [150, tuple 150]
-
-box.space.memtx:select{151}
--
-- [151, tuple 151]
-
-box.space.memtx:select{152}
--
-- [152, tuple 152]
-
-box.space.memtx:select{153}
--
-- [153, tuple 153]
-
-box.space.memtx:select{154}
--
-- [154, tuple 154]
-
-box.space.sophia:select{150}
--
-- [150, tuple 150]
-
-box.space.sophia:select{151}
--
-- [151, tuple 151]
-
-box.space.sophia:select{152}
--
-- [152, tuple 152]
-
-box.space.sophia:select{153}
--
-- [153, tuple 153]
-
-box.space.sophia:select{154}
--
-- [154, tuple 154]
-
-box.space.memtx:insert{155, "tuple 155"}
--
-None
-box.space.memtx:insert{156, "tuple 156"}
--
-None
-box.space.memtx:insert{157, "tuple 157"}
--
-None
-box.space.memtx:insert{158, "tuple 158"}
--
-None
-box.space.memtx:insert{159, "tuple 159"}
--
-None
-box.space.sophia:insert{155, "tuple 155"}
--
-None
-box.space.sophia:insert{156, "tuple 156"}
--
-None
-box.space.sophia:insert{157, "tuple 157"}
--
-None
-box.space.sophia:insert{158, "tuple 158"}
--
-None
-box.space.sophia:insert{159, "tuple 159"}
--
-None
-box.space.memtx:select{155}
--
-- [155, tuple 155]
-
-box.space.memtx:select{156}
--
-- [156, tuple 156]
-
-box.space.memtx:select{157}
--
-- [157, tuple 157]
-
-box.space.memtx:select{158}
--
-- [158, tuple 158]
-
-box.space.memtx:select{159}
--
-- [159, tuple 159]
-
-box.space.sophia:select{155}
--
-- [155, tuple 155]
-
-box.space.sophia:select{156}
--
-- [156, tuple 156]
-
-box.space.sophia:select{157}
--
-- [157, tuple 157]
-
-box.space.sophia:select{158}
--
-- [158, tuple 158]
-
-box.space.sophia:select{159}
--
-- [159, tuple 159]
-
-rollback servers configuration
-switch master to master
-box.cfg{replication_source=''}
----
-...
-switch replica to replica
-test 8 iteration
-box.space.memtx:insert{160, "tuple 160"}
--
-None
-box.space.memtx:insert{161, "tuple 161"}
--
-None
-box.space.memtx:insert{162, "tuple 162"}
--
-None
-box.space.memtx:insert{163, "tuple 163"}
--
-None
-box.space.memtx:insert{164, "tuple 164"}
--
-None
-box.space.sophia:insert{160, "tuple 160"}
--
-None
-box.space.sophia:insert{161, "tuple 161"}
--
-None
-box.space.sophia:insert{162, "tuple 162"}
--
-None
-box.space.sophia:insert{163, "tuple 163"}
--
-None
-box.space.sophia:insert{164, "tuple 164"}
--
-None
-box.space.memtx:select{160}
--
-- [160, tuple 160]
-
-box.space.memtx:select{161}
--
-- [161, tuple 161]
-
-box.space.memtx:select{162}
--
-- [162, tuple 162]
-
-box.space.memtx:select{163}
--
-- [163, tuple 163]
-
-box.space.memtx:select{164}
--
-- [164, tuple 164]
-
-box.space.sophia:select{160}
--
-- [160, tuple 160]
-
-box.space.sophia:select{161}
--
-- [161, tuple 161]
-
-box.space.sophia:select{162}
--
-- [162, tuple 162]
-
-box.space.sophia:select{163}
--
-- [163, tuple 163]
-
-box.space.sophia:select{164}
--
-- [164, tuple 164]
-
-box.space.memtx:insert{165, "tuple 165"}
--
-None
-box.space.memtx:insert{166, "tuple 166"}
--
-None
-box.space.memtx:insert{167, "tuple 167"}
--
-None
-box.space.memtx:insert{168, "tuple 168"}
--
-None
-box.space.memtx:insert{169, "tuple 169"}
--
-None
-box.space.sophia:insert{165, "tuple 165"}
--
-None
-box.space.sophia:insert{166, "tuple 166"}
--
-None
-box.space.sophia:insert{167, "tuple 167"}
--
-None
-box.space.sophia:insert{168, "tuple 168"}
--
-None
-box.space.sophia:insert{169, "tuple 169"}
--
-None
-box.space.memtx:select{165}
--
-- [165, tuple 165]
-
-box.space.memtx:select{166}
--
-- [166, tuple 166]
-
-box.space.memtx:select{167}
--
-- [167, tuple 167]
-
-box.space.memtx:select{168}
--
-- [168, tuple 168]
-
-box.space.memtx:select{169}
--
-- [169, tuple 169]
-
-box.space.sophia:select{165}
--
-- [165, tuple 165]
-
-box.space.sophia:select{166}
--
-- [166, tuple 166]
-
-box.space.sophia:select{167}
--
-- [167, tuple 167]
-
-box.space.sophia:select{168}
--
-- [168, tuple 168]
-
-box.space.sophia:select{169}
--
-- [169, tuple 169]
-
-swap servers
-switch replica to master
-box.cfg{replication_source=''}
----
-...
-switch master to replica
-box.space.memtx:insert{170, "tuple 170"}
--
-None
-box.space.memtx:insert{171, "tuple 171"}
--
-None
-box.space.memtx:insert{172, "tuple 172"}
--
-None
-box.space.memtx:insert{173, "tuple 173"}
--
-None
-box.space.memtx:insert{174, "tuple 174"}
--
-None
-box.space.sophia:insert{170, "tuple 170"}
--
-None
-box.space.sophia:insert{171, "tuple 171"}
--
-None
-box.space.sophia:insert{172, "tuple 172"}
--
-None
-box.space.sophia:insert{173, "tuple 173"}
--
-None
-box.space.sophia:insert{174, "tuple 174"}
--
-None
-box.space.memtx:select{170}
--
-- [170, tuple 170]
-
-box.space.memtx:select{171}
--
-- [171, tuple 171]
-
-box.space.memtx:select{172}
--
-- [172, tuple 172]
-
-box.space.memtx:select{173}
--
-- [173, tuple 173]
-
-box.space.memtx:select{174}
--
-- [174, tuple 174]
-
-box.space.sophia:select{170}
--
-- [170, tuple 170]
-
-box.space.sophia:select{171}
--
-- [171, tuple 171]
-
-box.space.sophia:select{172}
--
-- [172, tuple 172]
-
-box.space.sophia:select{173}
--
-- [173, tuple 173]
-
-box.space.sophia:select{174}
--
-- [174, tuple 174]
-
-box.space.memtx:insert{175, "tuple 175"}
--
-None
-box.space.memtx:insert{176, "tuple 176"}
--
-None
-box.space.memtx:insert{177, "tuple 177"}
--
-None
-box.space.memtx:insert{178, "tuple 178"}
--
-None
-box.space.memtx:insert{179, "tuple 179"}
--
-None
-box.space.sophia:insert{175, "tuple 175"}
--
-None
-box.space.sophia:insert{176, "tuple 176"}
--
-None
-box.space.sophia:insert{177, "tuple 177"}
--
-None
-box.space.sophia:insert{178, "tuple 178"}
--
-None
-box.space.sophia:insert{179, "tuple 179"}
--
-None
-box.space.memtx:select{175}
--
-- [175, tuple 175]
-
-box.space.memtx:select{176}
--
-- [176, tuple 176]
-
-box.space.memtx:select{177}
--
-- [177, tuple 177]
-
-box.space.memtx:select{178}
--
-- [178, tuple 178]
-
-box.space.memtx:select{179}
--
-- [179, tuple 179]
-
-box.space.sophia:select{175}
--
-- [175, tuple 175]
-
-box.space.sophia:select{176}
--
-- [176, tuple 176]
-
-box.space.sophia:select{177}
--
-- [177, tuple 177]
-
-box.space.sophia:select{178}
--
-- [178, tuple 178]
-
-box.space.sophia:select{179}
--
-- [179, tuple 179]
-
-rollback servers configuration
-switch master to master
-box.cfg{replication_source=''}
----
-...
-switch replica to replica
-test 9 iteration
-box.space.memtx:insert{180, "tuple 180"}
--
-None
-box.space.memtx:insert{181, "tuple 181"}
--
-None
-box.space.memtx:insert{182, "tuple 182"}
--
-None
-box.space.memtx:insert{183, "tuple 183"}
--
-None
-box.space.memtx:insert{184, "tuple 184"}
--
-None
-box.space.sophia:insert{180, "tuple 180"}
--
-None
-box.space.sophia:insert{181, "tuple 181"}
--
-None
-box.space.sophia:insert{182, "tuple 182"}
--
-None
-box.space.sophia:insert{183, "tuple 183"}
--
-None
-box.space.sophia:insert{184, "tuple 184"}
--
-None
-box.space.memtx:select{180}
--
-- [180, tuple 180]
-
-box.space.memtx:select{181}
--
-- [181, tuple 181]
-
-box.space.memtx:select{182}
--
-- [182, tuple 182]
-
-box.space.memtx:select{183}
--
-- [183, tuple 183]
-
-box.space.memtx:select{184}
--
-- [184, tuple 184]
-
-box.space.sophia:select{180}
--
-- [180, tuple 180]
-
-box.space.sophia:select{181}
--
-- [181, tuple 181]
-
-box.space.sophia:select{182}
--
-- [182, tuple 182]
-
-box.space.sophia:select{183}
--
-- [183, tuple 183]
-
-box.space.sophia:select{184}
--
-- [184, tuple 184]
-
-box.space.memtx:insert{185, "tuple 185"}
--
-None
-box.space.memtx:insert{186, "tuple 186"}
--
-None
-box.space.memtx:insert{187, "tuple 187"}
--
-None
-box.space.memtx:insert{188, "tuple 188"}
--
-None
-box.space.memtx:insert{189, "tuple 189"}
--
-None
-box.space.sophia:insert{185, "tuple 185"}
--
-None
-box.space.sophia:insert{186, "tuple 186"}
--
-None
-box.space.sophia:insert{187, "tuple 187"}
--
-None
-box.space.sophia:insert{188, "tuple 188"}
--
-None
-box.space.sophia:insert{189, "tuple 189"}
--
-None
-box.space.memtx:select{185}
--
-- [185, tuple 185]
-
-box.space.memtx:select{186}
--
-- [186, tuple 186]
-
-box.space.memtx:select{187}
--
-- [187, tuple 187]
-
-box.space.memtx:select{188}
--
-- [188, tuple 188]
-
-box.space.memtx:select{189}
--
-- [189, tuple 189]
-
-box.space.sophia:select{185}
--
-- [185, tuple 185]
-
-box.space.sophia:select{186}
--
-- [186, tuple 186]
-
-box.space.sophia:select{187}
--
-- [187, tuple 187]
-
-box.space.sophia:select{188}
--
-- [188, tuple 188]
-
-box.space.sophia:select{189}
--
-- [189, tuple 189]
-
-swap servers
-switch replica to master
-box.cfg{replication_source=''}
----
-...
-switch master to replica
-box.space.memtx:insert{190, "tuple 190"}
--
-None
-box.space.memtx:insert{191, "tuple 191"}
--
-None
-box.space.memtx:insert{192, "tuple 192"}
--
-None
-box.space.memtx:insert{193, "tuple 193"}
--
-None
-box.space.memtx:insert{194, "tuple 194"}
--
-None
-box.space.sophia:insert{190, "tuple 190"}
--
-None
-box.space.sophia:insert{191, "tuple 191"}
--
-None
-box.space.sophia:insert{192, "tuple 192"}
--
-None
-box.space.sophia:insert{193, "tuple 193"}
--
-None
-box.space.sophia:insert{194, "tuple 194"}
--
-None
-box.space.memtx:select{190}
--
-- [190, tuple 190]
-
-box.space.memtx:select{191}
--
-- [191, tuple 191]
-
-box.space.memtx:select{192}
--
-- [192, tuple 192]
-
-box.space.memtx:select{193}
--
-- [193, tuple 193]
-
-box.space.memtx:select{194}
--
-- [194, tuple 194]
-
-box.space.sophia:select{190}
--
-- [190, tuple 190]
-
-box.space.sophia:select{191}
--
-- [191, tuple 191]
-
-box.space.sophia:select{192}
--
-- [192, tuple 192]
-
-box.space.sophia:select{193}
--
-- [193, tuple 193]
-
-box.space.sophia:select{194}
--
-- [194, tuple 194]
-
-box.space.memtx:insert{195, "tuple 195"}
--
-None
-box.space.memtx:insert{196, "tuple 196"}
--
-None
-box.space.memtx:insert{197, "tuple 197"}
--
-None
-box.space.memtx:insert{198, "tuple 198"}
--
-None
-box.space.memtx:insert{199, "tuple 199"}
--
-None
-box.space.sophia:insert{195, "tuple 195"}
--
-None
-box.space.sophia:insert{196, "tuple 196"}
--
-None
-box.space.sophia:insert{197, "tuple 197"}
--
-None
-box.space.sophia:insert{198, "tuple 198"}
--
-None
-box.space.sophia:insert{199, "tuple 199"}
--
-None
-box.space.memtx:select{195}
--
-- [195, tuple 195]
-
-box.space.memtx:select{196}
--
-- [196, tuple 196]
-
-box.space.memtx:select{197}
--
-- [197, tuple 197]
-
-box.space.memtx:select{198}
--
-- [198, tuple 198]
-
-box.space.memtx:select{199}
--
-- [199, tuple 199]
-
-box.space.sophia:select{195}
--
-- [195, tuple 195]
-
-box.space.sophia:select{196}
--
-- [196, tuple 196]
-
-box.space.sophia:select{197}
--
-- [197, tuple 197]
-
-box.space.sophia:select{198}
--
-- [198, tuple 198]
-
-box.space.sophia:select{199}
--
-- [199, tuple 199]
-
-rollback servers configuration
-switch master to master
-box.cfg{replication_source=''}
----
-...
-switch replica to replica
-test 10 iteration
-box.space.memtx:insert{200, "tuple 200"}
--
-None
-box.space.memtx:insert{201, "tuple 201"}
--
-None
-box.space.memtx:insert{202, "tuple 202"}
--
-None
-box.space.memtx:insert{203, "tuple 203"}
--
-None
-box.space.memtx:insert{204, "tuple 204"}
--
-None
-box.space.sophia:insert{200, "tuple 200"}
--
-None
-box.space.sophia:insert{201, "tuple 201"}
--
-None
-box.space.sophia:insert{202, "tuple 202"}
--
-None
-box.space.sophia:insert{203, "tuple 203"}
--
-None
-box.space.sophia:insert{204, "tuple 204"}
--
-None
-box.space.memtx:select{200}
--
-- [200, tuple 200]
-
-box.space.memtx:select{201}
--
-- [201, tuple 201]
-
-box.space.memtx:select{202}
--
-- [202, tuple 202]
-
-box.space.memtx:select{203}
--
-- [203, tuple 203]
-
-box.space.memtx:select{204}
--
-- [204, tuple 204]
-
-box.space.sophia:select{200}
--
-- [200, tuple 200]
-
-box.space.sophia:select{201}
--
-- [201, tuple 201]
-
-box.space.sophia:select{202}
--
-- [202, tuple 202]
-
-box.space.sophia:select{203}
--
-- [203, tuple 203]
-
-box.space.sophia:select{204}
--
-- [204, tuple 204]
-
-box.space.memtx:insert{205, "tuple 205"}
--
-None
-box.space.memtx:insert{206, "tuple 206"}
--
-None
-box.space.memtx:insert{207, "tuple 207"}
--
-None
-box.space.memtx:insert{208, "tuple 208"}
--
-None
-box.space.memtx:insert{209, "tuple 209"}
--
-None
-box.space.sophia:insert{205, "tuple 205"}
--
-None
-box.space.sophia:insert{206, "tuple 206"}
--
-None
-box.space.sophia:insert{207, "tuple 207"}
--
-None
-box.space.sophia:insert{208, "tuple 208"}
--
-None
-box.space.sophia:insert{209, "tuple 209"}
--
-None
-box.space.memtx:select{205}
--
-- [205, tuple 205]
-
-box.space.memtx:select{206}
--
-- [206, tuple 206]
-
-box.space.memtx:select{207}
--
-- [207, tuple 207]
-
-box.space.memtx:select{208}
--
-- [208, tuple 208]
-
-box.space.memtx:select{209}
--
-- [209, tuple 209]
-
-box.space.sophia:select{205}
--
-- [205, tuple 205]
-
-box.space.sophia:select{206}
--
-- [206, tuple 206]
-
-box.space.sophia:select{207}
--
-- [207, tuple 207]
-
-box.space.sophia:select{208}
--
-- [208, tuple 208]
-
-box.space.sophia:select{209}
--
-- [209, tuple 209]
-
-swap servers
-switch replica to master
-box.cfg{replication_source=''}
----
-...
-switch master to replica
-box.space.memtx:insert{210, "tuple 210"}
--
-None
-box.space.memtx:insert{211, "tuple 211"}
--
-None
-box.space.memtx:insert{212, "tuple 212"}
--
-None
-box.space.memtx:insert{213, "tuple 213"}
--
-None
-box.space.memtx:insert{214, "tuple 214"}
--
-None
-box.space.sophia:insert{210, "tuple 210"}
--
-None
-box.space.sophia:insert{211, "tuple 211"}
--
-None
-box.space.sophia:insert{212, "tuple 212"}
--
-None
-box.space.sophia:insert{213, "tuple 213"}
--
-None
-box.space.sophia:insert{214, "tuple 214"}
--
-None
-box.space.memtx:select{210}
--
-- [210, tuple 210]
-
-box.space.memtx:select{211}
--
-- [211, tuple 211]
-
-box.space.memtx:select{212}
--
-- [212, tuple 212]
-
-box.space.memtx:select{213}
--
-- [213, tuple 213]
-
-box.space.memtx:select{214}
--
-- [214, tuple 214]
-
-box.space.sophia:select{210}
--
-- [210, tuple 210]
-
-box.space.sophia:select{211}
--
-- [211, tuple 211]
-
-box.space.sophia:select{212}
--
-- [212, tuple 212]
-
-box.space.sophia:select{213}
--
-- [213, tuple 213]
-
-box.space.sophia:select{214}
--
-- [214, tuple 214]
-
-box.space.memtx:insert{215, "tuple 215"}
--
-None
-box.space.memtx:insert{216, "tuple 216"}
--
-None
-box.space.memtx:insert{217, "tuple 217"}
--
-None
-box.space.memtx:insert{218, "tuple 218"}
--
-None
-box.space.memtx:insert{219, "tuple 219"}
--
-None
-box.space.sophia:insert{215, "tuple 215"}
--
-None
-box.space.sophia:insert{216, "tuple 216"}
--
-None
-box.space.sophia:insert{217, "tuple 217"}
--
-None
-box.space.sophia:insert{218, "tuple 218"}
--
-None
-box.space.sophia:insert{219, "tuple 219"}
--
-None
-box.space.memtx:select{215}
--
-- [215, tuple 215]
-
-box.space.memtx:select{216}
--
-- [216, tuple 216]
-
-box.space.memtx:select{217}
--
-- [217, tuple 217]
-
-box.space.memtx:select{218}
--
-- [218, tuple 218]
-
-box.space.memtx:select{219}
--
-- [219, tuple 219]
-
-box.space.sophia:select{215}
--
-- [215, tuple 215]
-
-box.space.sophia:select{216}
--
-- [216, tuple 216]
-
-box.space.sophia:select{217}
--
-- [217, tuple 217]
-
-box.space.sophia:select{218}
--
-- [218, tuple 218]
-
-box.space.sophia:select{219}
--
-- [219, tuple 219]
-
-rollback servers configuration
-switch master to master
-box.cfg{replication_source=''}
----
-...
-switch replica to replica
-test 11 iteration
-box.space.memtx:insert{220, "tuple 220"}
--
-None
-box.space.memtx:insert{221, "tuple 221"}
--
-None
-box.space.memtx:insert{222, "tuple 222"}
--
-None
-box.space.memtx:insert{223, "tuple 223"}
--
-None
-box.space.memtx:insert{224, "tuple 224"}
--
-None
-box.space.sophia:insert{220, "tuple 220"}
--
-None
-box.space.sophia:insert{221, "tuple 221"}
--
-None
-box.space.sophia:insert{222, "tuple 222"}
--
-None
-box.space.sophia:insert{223, "tuple 223"}
--
-None
-box.space.sophia:insert{224, "tuple 224"}
--
-None
-box.space.memtx:select{220}
--
-- [220, tuple 220]
-
-box.space.memtx:select{221}
--
-- [221, tuple 221]
-
-box.space.memtx:select{222}
--
-- [222, tuple 222]
-
-box.space.memtx:select{223}
--
-- [223, tuple 223]
-
-box.space.memtx:select{224}
--
-- [224, tuple 224]
-
-box.space.sophia:select{220}
--
-- [220, tuple 220]
-
-box.space.sophia:select{221}
--
-- [221, tuple 221]
-
-box.space.sophia:select{222}
--
-- [222, tuple 222]
-
-box.space.sophia:select{223}
--
-- [223, tuple 223]
-
-box.space.sophia:select{224}
--
-- [224, tuple 224]
-
-box.space.memtx:insert{225, "tuple 225"}
--
-None
-box.space.memtx:insert{226, "tuple 226"}
--
-None
-box.space.memtx:insert{227, "tuple 227"}
--
-None
-box.space.memtx:insert{228, "tuple 228"}
--
-None
-box.space.memtx:insert{229, "tuple 229"}
--
-None
-box.space.sophia:insert{225, "tuple 225"}
--
-None
-box.space.sophia:insert{226, "tuple 226"}
--
-None
-box.space.sophia:insert{227, "tuple 227"}
--
-None
-box.space.sophia:insert{228, "tuple 228"}
--
-None
-box.space.sophia:insert{229, "tuple 229"}
--
-None
-box.space.memtx:select{225}
--
-- [225, tuple 225]
-
-box.space.memtx:select{226}
--
-- [226, tuple 226]
-
-box.space.memtx:select{227}
--
-- [227, tuple 227]
-
-box.space.memtx:select{228}
--
-- [228, tuple 228]
-
-box.space.memtx:select{229}
--
-- [229, tuple 229]
-
-box.space.sophia:select{225}
--
-- [225, tuple 225]
-
-box.space.sophia:select{226}
--
-- [226, tuple 226]
-
-box.space.sophia:select{227}
--
-- [227, tuple 227]
-
-box.space.sophia:select{228}
--
-- [228, tuple 228]
-
-box.space.sophia:select{229}
--
-- [229, tuple 229]
-
-swap servers
-switch replica to master
-box.cfg{replication_source=''}
----
-...
-switch master to replica
-box.space.memtx:insert{230, "tuple 230"}
--
-None
-box.space.memtx:insert{231, "tuple 231"}
--
-None
-box.space.memtx:insert{232, "tuple 232"}
--
-None
-box.space.memtx:insert{233, "tuple 233"}
--
-None
-box.space.memtx:insert{234, "tuple 234"}
--
-None
-box.space.sophia:insert{230, "tuple 230"}
--
-None
-box.space.sophia:insert{231, "tuple 231"}
--
-None
-box.space.sophia:insert{232, "tuple 232"}
--
-None
-box.space.sophia:insert{233, "tuple 233"}
--
-None
-box.space.sophia:insert{234, "tuple 234"}
--
-None
-box.space.memtx:select{230}
--
-- [230, tuple 230]
-
-box.space.memtx:select{231}
--
-- [231, tuple 231]
-
-box.space.memtx:select{232}
--
-- [232, tuple 232]
-
-box.space.memtx:select{233}
--
-- [233, tuple 233]
-
-box.space.memtx:select{234}
--
-- [234, tuple 234]
-
-box.space.sophia:select{230}
--
-- [230, tuple 230]
-
-box.space.sophia:select{231}
--
-- [231, tuple 231]
-
-box.space.sophia:select{232}
--
-- [232, tuple 232]
-
-box.space.sophia:select{233}
--
-- [233, tuple 233]
-
-box.space.sophia:select{234}
--
-- [234, tuple 234]
-
-box.space.memtx:insert{235, "tuple 235"}
--
-None
-box.space.memtx:insert{236, "tuple 236"}
--
-None
-box.space.memtx:insert{237, "tuple 237"}
--
-None
-box.space.memtx:insert{238, "tuple 238"}
--
-None
-box.space.memtx:insert{239, "tuple 239"}
--
-None
-box.space.sophia:insert{235, "tuple 235"}
--
-None
-box.space.sophia:insert{236, "tuple 236"}
--
-None
-box.space.sophia:insert{237, "tuple 237"}
--
-None
-box.space.sophia:insert{238, "tuple 238"}
--
-None
-box.space.sophia:insert{239, "tuple 239"}
--
-None
-box.space.memtx:select{235}
--
-- [235, tuple 235]
-
-box.space.memtx:select{236}
--
-- [236, tuple 236]
-
-box.space.memtx:select{237}
--
-- [237, tuple 237]
-
-box.space.memtx:select{238}
--
-- [238, tuple 238]
-
-box.space.memtx:select{239}
--
-- [239, tuple 239]
-
-box.space.sophia:select{235}
--
-- [235, tuple 235]
-
-box.space.sophia:select{236}
--
-- [236, tuple 236]
-
-box.space.sophia:select{237}
--
-- [237, tuple 237]
-
-box.space.sophia:select{238}
--
-- [238, tuple 238]
-
-box.space.sophia:select{239}
--
-- [239, tuple 239]
-
-rollback servers configuration
-switch master to master
-box.cfg{replication_source=''}
----
-...
-switch replica to replica
-test 12 iteration
-box.space.memtx:insert{240, "tuple 240"}
--
-None
-box.space.memtx:insert{241, "tuple 241"}
--
-None
-box.space.memtx:insert{242, "tuple 242"}
--
-None
-box.space.memtx:insert{243, "tuple 243"}
--
-None
-box.space.memtx:insert{244, "tuple 244"}
--
-None
-box.space.sophia:insert{240, "tuple 240"}
--
-None
-box.space.sophia:insert{241, "tuple 241"}
--
-None
-box.space.sophia:insert{242, "tuple 242"}
--
-None
-box.space.sophia:insert{243, "tuple 243"}
--
-None
-box.space.sophia:insert{244, "tuple 244"}
--
-None
-box.space.memtx:select{240}
--
-- [240, tuple 240]
-
-box.space.memtx:select{241}
--
-- [241, tuple 241]
-
-box.space.memtx:select{242}
--
-- [242, tuple 242]
-
-box.space.memtx:select{243}
--
-- [243, tuple 243]
-
-box.space.memtx:select{244}
--
-- [244, tuple 244]
-
-box.space.sophia:select{240}
--
-- [240, tuple 240]
-
-box.space.sophia:select{241}
--
-- [241, tuple 241]
-
-box.space.sophia:select{242}
--
-- [242, tuple 242]
-
-box.space.sophia:select{243}
--
-- [243, tuple 243]
-
-box.space.sophia:select{244}
--
-- [244, tuple 244]
-
-box.space.memtx:insert{245, "tuple 245"}
--
-None
-box.space.memtx:insert{246, "tuple 246"}
--
-None
-box.space.memtx:insert{247, "tuple 247"}
--
-None
-box.space.memtx:insert{248, "tuple 248"}
--
-None
-box.space.memtx:insert{249, "tuple 249"}
--
-None
-box.space.sophia:insert{245, "tuple 245"}
--
-None
-box.space.sophia:insert{246, "tuple 246"}
--
-None
-box.space.sophia:insert{247, "tuple 247"}
--
-None
-box.space.sophia:insert{248, "tuple 248"}
--
-None
-box.space.sophia:insert{249, "tuple 249"}
--
-None
-box.space.memtx:select{245}
--
-- [245, tuple 245]
-
-box.space.memtx:select{246}
--
-- [246, tuple 246]
-
-box.space.memtx:select{247}
--
-- [247, tuple 247]
-
-box.space.memtx:select{248}
--
-- [248, tuple 248]
-
-box.space.memtx:select{249}
--
-- [249, tuple 249]
-
-box.space.sophia:select{245}
--
-- [245, tuple 245]
-
-box.space.sophia:select{246}
--
-- [246, tuple 246]
-
-box.space.sophia:select{247}
--
-- [247, tuple 247]
-
-box.space.sophia:select{248}
--
-- [248, tuple 248]
-
-box.space.sophia:select{249}
--
-- [249, tuple 249]
-
-swap servers
-switch replica to master
-box.cfg{replication_source=''}
----
-...
-switch master to replica
-box.space.memtx:insert{250, "tuple 250"}
--
-None
-box.space.memtx:insert{251, "tuple 251"}
--
-None
-box.space.memtx:insert{252, "tuple 252"}
--
-None
-box.space.memtx:insert{253, "tuple 253"}
--
-None
-box.space.memtx:insert{254, "tuple 254"}
--
-None
-box.space.sophia:insert{250, "tuple 250"}
--
-None
-box.space.sophia:insert{251, "tuple 251"}
--
-None
-box.space.sophia:insert{252, "tuple 252"}
--
-None
-box.space.sophia:insert{253, "tuple 253"}
--
-None
-box.space.sophia:insert{254, "tuple 254"}
--
-None
-box.space.memtx:select{250}
--
-- [250, tuple 250]
-
-box.space.memtx:select{251}
--
-- [251, tuple 251]
-
-box.space.memtx:select{252}
--
-- [252, tuple 252]
-
-box.space.memtx:select{253}
--
-- [253, tuple 253]
-
-box.space.memtx:select{254}
--
-- [254, tuple 254]
-
-box.space.sophia:select{250}
--
-- [250, tuple 250]
-
-box.space.sophia:select{251}
--
-- [251, tuple 251]
-
-box.space.sophia:select{252}
--
-- [252, tuple 252]
-
-box.space.sophia:select{253}
--
-- [253, tuple 253]
-
-box.space.sophia:select{254}
--
-- [254, tuple 254]
-
-box.space.memtx:insert{255, "tuple 255"}
--
-None
-box.space.memtx:insert{256, "tuple 256"}
--
-None
-box.space.memtx:insert{257, "tuple 257"}
--
-None
-box.space.memtx:insert{258, "tuple 258"}
--
-None
-box.space.memtx:insert{259, "tuple 259"}
--
-None
-box.space.sophia:insert{255, "tuple 255"}
--
-None
-box.space.sophia:insert{256, "tuple 256"}
--
-None
-box.space.sophia:insert{257, "tuple 257"}
--
-None
-box.space.sophia:insert{258, "tuple 258"}
--
-None
-box.space.sophia:insert{259, "tuple 259"}
--
-None
-box.space.memtx:select{255}
--
-- [255, tuple 255]
-
-box.space.memtx:select{256}
--
-- [256, tuple 256]
-
-box.space.memtx:select{257}
--
-- [257, tuple 257]
-
-box.space.memtx:select{258}
--
-- [258, tuple 258]
-
-box.space.memtx:select{259}
--
-- [259, tuple 259]
-
-box.space.sophia:select{255}
--
-- [255, tuple 255]
-
-box.space.sophia:select{256}
--
-- [256, tuple 256]
-
-box.space.sophia:select{257}
--
-- [257, tuple 257]
-
-box.space.sophia:select{258}
--
-- [258, tuple 258]
-
-box.space.sophia:select{259}
--
-- [259, tuple 259]
-
-rollback servers configuration
-switch master to master
-box.cfg{replication_source=''}
----
-...
-switch replica to replica
-test 13 iteration
-box.space.memtx:insert{260, "tuple 260"}
--
-None
-box.space.memtx:insert{261, "tuple 261"}
--
-None
-box.space.memtx:insert{262, "tuple 262"}
--
-None
-box.space.memtx:insert{263, "tuple 263"}
--
-None
-box.space.memtx:insert{264, "tuple 264"}
--
-None
-box.space.sophia:insert{260, "tuple 260"}
--
-None
-box.space.sophia:insert{261, "tuple 261"}
--
-None
-box.space.sophia:insert{262, "tuple 262"}
--
-None
-box.space.sophia:insert{263, "tuple 263"}
--
-None
-box.space.sophia:insert{264, "tuple 264"}
--
-None
-box.space.memtx:select{260}
--
-- [260, tuple 260]
-
-box.space.memtx:select{261}
--
-- [261, tuple 261]
-
-box.space.memtx:select{262}
--
-- [262, tuple 262]
-
-box.space.memtx:select{263}
--
-- [263, tuple 263]
-
-box.space.memtx:select{264}
--
-- [264, tuple 264]
-
-box.space.sophia:select{260}
--
-- [260, tuple 260]
-
-box.space.sophia:select{261}
--
-- [261, tuple 261]
-
-box.space.sophia:select{262}
--
-- [262, tuple 262]
-
-box.space.sophia:select{263}
--
-- [263, tuple 263]
-
-box.space.sophia:select{264}
--
-- [264, tuple 264]
-
-box.space.memtx:insert{265, "tuple 265"}
--
-None
-box.space.memtx:insert{266, "tuple 266"}
--
-None
-box.space.memtx:insert{267, "tuple 267"}
--
-None
-box.space.memtx:insert{268, "tuple 268"}
--
-None
-box.space.memtx:insert{269, "tuple 269"}
--
-None
-box.space.sophia:insert{265, "tuple 265"}
--
-None
-box.space.sophia:insert{266, "tuple 266"}
--
-None
-box.space.sophia:insert{267, "tuple 267"}
--
-None
-box.space.sophia:insert{268, "tuple 268"}
--
-None
-box.space.sophia:insert{269, "tuple 269"}
--
-None
-box.space.memtx:select{265}
--
-- [265, tuple 265]
-
-box.space.memtx:select{266}
--
-- [266, tuple 266]
-
-box.space.memtx:select{267}
--
-- [267, tuple 267]
-
-box.space.memtx:select{268}
--
-- [268, tuple 268]
-
-box.space.memtx:select{269}
--
-- [269, tuple 269]
-
-box.space.sophia:select{265}
--
-- [265, tuple 265]
-
-box.space.sophia:select{266}
--
-- [266, tuple 266]
-
-box.space.sophia:select{267}
--
-- [267, tuple 267]
-
-box.space.sophia:select{268}
--
-- [268, tuple 268]
-
-box.space.sophia:select{269}
--
-- [269, tuple 269]
-
-swap servers
-switch replica to master
-box.cfg{replication_source=''}
----
-...
-switch master to replica
-box.space.memtx:insert{270, "tuple 270"}
--
-None
-box.space.memtx:insert{271, "tuple 271"}
--
-None
-box.space.memtx:insert{272, "tuple 272"}
--
-None
-box.space.memtx:insert{273, "tuple 273"}
--
-None
-box.space.memtx:insert{274, "tuple 274"}
--
-None
-box.space.sophia:insert{270, "tuple 270"}
--
-None
-box.space.sophia:insert{271, "tuple 271"}
--
-None
-box.space.sophia:insert{272, "tuple 272"}
--
-None
-box.space.sophia:insert{273, "tuple 273"}
--
-None
-box.space.sophia:insert{274, "tuple 274"}
--
-None
-box.space.memtx:select{270}
--
-- [270, tuple 270]
-
-box.space.memtx:select{271}
--
-- [271, tuple 271]
-
-box.space.memtx:select{272}
--
-- [272, tuple 272]
-
-box.space.memtx:select{273}
--
-- [273, tuple 273]
-
-box.space.memtx:select{274}
--
-- [274, tuple 274]
-
-box.space.sophia:select{270}
--
-- [270, tuple 270]
-
-box.space.sophia:select{271}
--
-- [271, tuple 271]
-
-box.space.sophia:select{272}
--
-- [272, tuple 272]
-
-box.space.sophia:select{273}
--
-- [273, tuple 273]
-
-box.space.sophia:select{274}
--
-- [274, tuple 274]
-
-box.space.memtx:insert{275, "tuple 275"}
--
-None
-box.space.memtx:insert{276, "tuple 276"}
--
-None
-box.space.memtx:insert{277, "tuple 277"}
--
-None
-box.space.memtx:insert{278, "tuple 278"}
--
-None
-box.space.memtx:insert{279, "tuple 279"}
--
-None
-box.space.sophia:insert{275, "tuple 275"}
--
-None
-box.space.sophia:insert{276, "tuple 276"}
--
-None
-box.space.sophia:insert{277, "tuple 277"}
--
-None
-box.space.sophia:insert{278, "tuple 278"}
--
-None
-box.space.sophia:insert{279, "tuple 279"}
--
-None
-box.space.memtx:select{275}
--
-- [275, tuple 275]
-
-box.space.memtx:select{276}
--
-- [276, tuple 276]
-
-box.space.memtx:select{277}
--
-- [277, tuple 277]
-
-box.space.memtx:select{278}
--
-- [278, tuple 278]
-
-box.space.memtx:select{279}
--
-- [279, tuple 279]
-
-box.space.sophia:select{275}
--
-- [275, tuple 275]
-
-box.space.sophia:select{276}
--
-- [276, tuple 276]
-
-box.space.sophia:select{277}
--
-- [277, tuple 277]
-
-box.space.sophia:select{278}
--
-- [278, tuple 278]
-
-box.space.sophia:select{279}
--
-- [279, tuple 279]
-
-rollback servers configuration
-switch master to master
-box.cfg{replication_source=''}
----
-...
-switch replica to replica
-test 14 iteration
-box.space.memtx:insert{280, "tuple 280"}
--
-None
-box.space.memtx:insert{281, "tuple 281"}
--
-None
-box.space.memtx:insert{282, "tuple 282"}
--
-None
-box.space.memtx:insert{283, "tuple 283"}
--
-None
-box.space.memtx:insert{284, "tuple 284"}
--
-None
-box.space.sophia:insert{280, "tuple 280"}
--
-None
-box.space.sophia:insert{281, "tuple 281"}
--
-None
-box.space.sophia:insert{282, "tuple 282"}
--
-None
-box.space.sophia:insert{283, "tuple 283"}
--
-None
-box.space.sophia:insert{284, "tuple 284"}
--
-None
-box.space.memtx:select{280}
--
-- [280, tuple 280]
-
-box.space.memtx:select{281}
--
-- [281, tuple 281]
-
-box.space.memtx:select{282}
--
-- [282, tuple 282]
-
-box.space.memtx:select{283}
--
-- [283, tuple 283]
-
-box.space.memtx:select{284}
--
-- [284, tuple 284]
-
-box.space.sophia:select{280}
--
-- [280, tuple 280]
-
-box.space.sophia:select{281}
--
-- [281, tuple 281]
-
-box.space.sophia:select{282}
--
-- [282, tuple 282]
-
-box.space.sophia:select{283}
--
-- [283, tuple 283]
-
-box.space.sophia:select{284}
--
-- [284, tuple 284]
-
-box.space.memtx:insert{285, "tuple 285"}
--
-None
-box.space.memtx:insert{286, "tuple 286"}
--
-None
-box.space.memtx:insert{287, "tuple 287"}
--
-None
-box.space.memtx:insert{288, "tuple 288"}
--
-None
-box.space.memtx:insert{289, "tuple 289"}
--
-None
-box.space.sophia:insert{285, "tuple 285"}
--
-None
-box.space.sophia:insert{286, "tuple 286"}
--
-None
-box.space.sophia:insert{287, "tuple 287"}
--
-None
-box.space.sophia:insert{288, "tuple 288"}
--
-None
-box.space.sophia:insert{289, "tuple 289"}
--
-None
-box.space.memtx:select{285}
--
-- [285, tuple 285]
-
-box.space.memtx:select{286}
--
-- [286, tuple 286]
-
-box.space.memtx:select{287}
--
-- [287, tuple 287]
-
-box.space.memtx:select{288}
--
-- [288, tuple 288]
-
-box.space.memtx:select{289}
--
-- [289, tuple 289]
-
-box.space.sophia:select{285}
--
-- [285, tuple 285]
-
-box.space.sophia:select{286}
--
-- [286, tuple 286]
-
-box.space.sophia:select{287}
--
-- [287, tuple 287]
-
-box.space.sophia:select{288}
--
-- [288, tuple 288]
-
-box.space.sophia:select{289}
--
-- [289, tuple 289]
-
-swap servers
-switch replica to master
-box.cfg{replication_source=''}
----
-...
-switch master to replica
-box.space.memtx:insert{290, "tuple 290"}
--
-None
-box.space.memtx:insert{291, "tuple 291"}
--
-None
-box.space.memtx:insert{292, "tuple 292"}
--
-None
-box.space.memtx:insert{293, "tuple 293"}
--
-None
-box.space.memtx:insert{294, "tuple 294"}
--
-None
-box.space.sophia:insert{290, "tuple 290"}
--
-None
-box.space.sophia:insert{291, "tuple 291"}
--
-None
-box.space.sophia:insert{292, "tuple 292"}
--
-None
-box.space.sophia:insert{293, "tuple 293"}
--
-None
-box.space.sophia:insert{294, "tuple 294"}
--
-None
-box.space.memtx:select{290}
--
-- [290, tuple 290]
-
-box.space.memtx:select{291}
--
-- [291, tuple 291]
-
-box.space.memtx:select{292}
--
-- [292, tuple 292]
-
-box.space.memtx:select{293}
--
-- [293, tuple 293]
-
-box.space.memtx:select{294}
--
-- [294, tuple 294]
-
-box.space.sophia:select{290}
--
-- [290, tuple 290]
-
-box.space.sophia:select{291}
--
-- [291, tuple 291]
-
-box.space.sophia:select{292}
--
-- [292, tuple 292]
-
-box.space.sophia:select{293}
--
-- [293, tuple 293]
-
-box.space.sophia:select{294}
--
-- [294, tuple 294]
-
-box.space.memtx:insert{295, "tuple 295"}
--
-None
-box.space.memtx:insert{296, "tuple 296"}
--
-None
-box.space.memtx:insert{297, "tuple 297"}
--
-None
-box.space.memtx:insert{298, "tuple 298"}
--
-None
-box.space.memtx:insert{299, "tuple 299"}
--
-None
-box.space.sophia:insert{295, "tuple 295"}
--
-None
-box.space.sophia:insert{296, "tuple 296"}
--
-None
-box.space.sophia:insert{297, "tuple 297"}
--
-None
-box.space.sophia:insert{298, "tuple 298"}
--
-None
-box.space.sophia:insert{299, "tuple 299"}
--
-None
-box.space.memtx:select{295}
--
-- [295, tuple 295]
-
-box.space.memtx:select{296}
--
-- [296, tuple 296]
-
-box.space.memtx:select{297}
--
-- [297, tuple 297]
-
-box.space.memtx:select{298}
--
-- [298, tuple 298]
-
-box.space.memtx:select{299}
--
-- [299, tuple 299]
-
-box.space.sophia:select{295}
--
-- [295, tuple 295]
-
-box.space.sophia:select{296}
--
-- [296, tuple 296]
-
-box.space.sophia:select{297}
--
-- [297, tuple 297]
-
-box.space.sophia:select{298}
--
-- [298, tuple 298]
-
-box.space.sophia:select{299}
--
-- [299, tuple 299]
-
-rollback servers configuration
-switch master to master
-box.cfg{replication_source=''}
----
-...
-switch replica to replica
-test 15 iteration
-box.space.memtx:insert{300, "tuple 300"}
--
-None
-box.space.memtx:insert{301, "tuple 301"}
--
-None
-box.space.memtx:insert{302, "tuple 302"}
--
-None
-box.space.memtx:insert{303, "tuple 303"}
--
-None
-box.space.memtx:insert{304, "tuple 304"}
--
-None
-box.space.sophia:insert{300, "tuple 300"}
--
-None
-box.space.sophia:insert{301, "tuple 301"}
--
-None
-box.space.sophia:insert{302, "tuple 302"}
--
-None
-box.space.sophia:insert{303, "tuple 303"}
--
-None
-box.space.sophia:insert{304, "tuple 304"}
--
-None
-box.space.memtx:select{300}
--
-- [300, tuple 300]
-
-box.space.memtx:select{301}
--
-- [301, tuple 301]
-
-box.space.memtx:select{302}
--
-- [302, tuple 302]
-
-box.space.memtx:select{303}
--
-- [303, tuple 303]
-
-box.space.memtx:select{304}
--
-- [304, tuple 304]
-
-box.space.sophia:select{300}
--
-- [300, tuple 300]
-
-box.space.sophia:select{301}
--
-- [301, tuple 301]
-
-box.space.sophia:select{302}
--
-- [302, tuple 302]
-
-box.space.sophia:select{303}
--
-- [303, tuple 303]
-
-box.space.sophia:select{304}
--
-- [304, tuple 304]
-
-box.space.memtx:insert{305, "tuple 305"}
--
-None
-box.space.memtx:insert{306, "tuple 306"}
--
-None
-box.space.memtx:insert{307, "tuple 307"}
--
-None
-box.space.memtx:insert{308, "tuple 308"}
--
-None
-box.space.memtx:insert{309, "tuple 309"}
--
-None
-box.space.sophia:insert{305, "tuple 305"}
--
-None
-box.space.sophia:insert{306, "tuple 306"}
--
-None
-box.space.sophia:insert{307, "tuple 307"}
--
-None
-box.space.sophia:insert{308, "tuple 308"}
--
-None
-box.space.sophia:insert{309, "tuple 309"}
--
-None
-box.space.memtx:select{305}
--
-- [305, tuple 305]
-
-box.space.memtx:select{306}
--
-- [306, tuple 306]
-
-box.space.memtx:select{307}
--
-- [307, tuple 307]
-
-box.space.memtx:select{308}
--
-- [308, tuple 308]
-
-box.space.memtx:select{309}
--
-- [309, tuple 309]
-
-box.space.sophia:select{305}
--
-- [305, tuple 305]
-
-box.space.sophia:select{306}
--
-- [306, tuple 306]
-
-box.space.sophia:select{307}
--
-- [307, tuple 307]
-
-box.space.sophia:select{308}
--
-- [308, tuple 308]
-
-box.space.sophia:select{309}
--
-- [309, tuple 309]
-
-swap servers
-switch replica to master
-box.cfg{replication_source=''}
----
-...
-switch master to replica
-box.space.memtx:insert{310, "tuple 310"}
--
-None
-box.space.memtx:insert{311, "tuple 311"}
--
-None
-box.space.memtx:insert{312, "tuple 312"}
--
-None
-box.space.memtx:insert{313, "tuple 313"}
--
-None
-box.space.memtx:insert{314, "tuple 314"}
--
-None
-box.space.sophia:insert{310, "tuple 310"}
--
-None
-box.space.sophia:insert{311, "tuple 311"}
--
-None
-box.space.sophia:insert{312, "tuple 312"}
--
-None
-box.space.sophia:insert{313, "tuple 313"}
--
-None
-box.space.sophia:insert{314, "tuple 314"}
--
-None
-box.space.memtx:select{310}
--
-- [310, tuple 310]
-
-box.space.memtx:select{311}
--
-- [311, tuple 311]
-
-box.space.memtx:select{312}
--
-- [312, tuple 312]
-
-box.space.memtx:select{313}
--
-- [313, tuple 313]
-
-box.space.memtx:select{314}
--
-- [314, tuple 314]
-
-box.space.sophia:select{310}
--
-- [310, tuple 310]
-
-box.space.sophia:select{311}
--
-- [311, tuple 311]
-
-box.space.sophia:select{312}
--
-- [312, tuple 312]
-
-box.space.sophia:select{313}
--
-- [313, tuple 313]
-
-box.space.sophia:select{314}
--
-- [314, tuple 314]
-
-box.space.memtx:insert{315, "tuple 315"}
--
-None
-box.space.memtx:insert{316, "tuple 316"}
--
-None
-box.space.memtx:insert{317, "tuple 317"}
--
-None
-box.space.memtx:insert{318, "tuple 318"}
--
-None
-box.space.memtx:insert{319, "tuple 319"}
--
-None
-box.space.sophia:insert{315, "tuple 315"}
--
-None
-box.space.sophia:insert{316, "tuple 316"}
--
-None
-box.space.sophia:insert{317, "tuple 317"}
--
-None
-box.space.sophia:insert{318, "tuple 318"}
--
-None
-box.space.sophia:insert{319, "tuple 319"}
--
-None
-box.space.memtx:select{315}
--
-- [315, tuple 315]
-
-box.space.memtx:select{316}
--
-- [316, tuple 316]
-
-box.space.memtx:select{317}
--
-- [317, tuple 317]
-
-box.space.memtx:select{318}
--
-- [318, tuple 318]
-
-box.space.memtx:select{319}
--
-- [319, tuple 319]
-
-box.space.sophia:select{315}
--
-- [315, tuple 315]
-
-box.space.sophia:select{316}
--
-- [316, tuple 316]
-
-box.space.sophia:select{317}
--
-- [317, tuple 317]
-
-box.space.sophia:select{318}
--
-- [318, tuple 318]
-
-box.space.sophia:select{319}
--
-- [319, tuple 319]
-
-rollback servers configuration
-switch master to master
-box.cfg{replication_source=''}
----
-...
-switch replica to replica
-test 16 iteration
-box.space.memtx:insert{320, "tuple 320"}
--
-None
-box.space.memtx:insert{321, "tuple 321"}
--
-None
-box.space.memtx:insert{322, "tuple 322"}
--
-None
-box.space.memtx:insert{323, "tuple 323"}
--
-None
-box.space.memtx:insert{324, "tuple 324"}
--
-None
-box.space.sophia:insert{320, "tuple 320"}
--
-None
-box.space.sophia:insert{321, "tuple 321"}
--
-None
-box.space.sophia:insert{322, "tuple 322"}
--
-None
-box.space.sophia:insert{323, "tuple 323"}
--
-None
-box.space.sophia:insert{324, "tuple 324"}
--
-None
-box.space.memtx:select{320}
--
-- [320, tuple 320]
-
-box.space.memtx:select{321}
--
-- [321, tuple 321]
-
-box.space.memtx:select{322}
--
-- [322, tuple 322]
-
-box.space.memtx:select{323}
--
-- [323, tuple 323]
-
-box.space.memtx:select{324}
--
-- [324, tuple 324]
-
-box.space.sophia:select{320}
--
-- [320, tuple 320]
-
-box.space.sophia:select{321}
--
-- [321, tuple 321]
-
-box.space.sophia:select{322}
--
-- [322, tuple 322]
-
-box.space.sophia:select{323}
--
-- [323, tuple 323]
-
-box.space.sophia:select{324}
--
-- [324, tuple 324]
-
-box.space.memtx:insert{325, "tuple 325"}
--
-None
-box.space.memtx:insert{326, "tuple 326"}
--
-None
-box.space.memtx:insert{327, "tuple 327"}
--
-None
-box.space.memtx:insert{328, "tuple 328"}
--
-None
-box.space.memtx:insert{329, "tuple 329"}
--
-None
-box.space.sophia:insert{325, "tuple 325"}
--
-None
-box.space.sophia:insert{326, "tuple 326"}
--
-None
-box.space.sophia:insert{327, "tuple 327"}
--
-None
-box.space.sophia:insert{328, "tuple 328"}
--
-None
-box.space.sophia:insert{329, "tuple 329"}
--
-None
-box.space.memtx:select{325}
--
-- [325, tuple 325]
-
-box.space.memtx:select{326}
--
-- [326, tuple 326]
-
-box.space.memtx:select{327}
--
-- [327, tuple 327]
-
-box.space.memtx:select{328}
--
-- [328, tuple 328]
-
-box.space.memtx:select{329}
--
-- [329, tuple 329]
-
-box.space.sophia:select{325}
--
-- [325, tuple 325]
-
-box.space.sophia:select{326}
--
-- [326, tuple 326]
-
-box.space.sophia:select{327}
--
-- [327, tuple 327]
-
-box.space.sophia:select{328}
--
-- [328, tuple 328]
-
-box.space.sophia:select{329}
--
-- [329, tuple 329]
-
-swap servers
-switch replica to master
-box.cfg{replication_source=''}
----
-...
-switch master to replica
-box.space.memtx:insert{330, "tuple 330"}
--
-None
-box.space.memtx:insert{331, "tuple 331"}
--
-None
-box.space.memtx:insert{332, "tuple 332"}
--
-None
-box.space.memtx:insert{333, "tuple 333"}
--
-None
-box.space.memtx:insert{334, "tuple 334"}
--
-None
-box.space.sophia:insert{330, "tuple 330"}
--
-None
-box.space.sophia:insert{331, "tuple 331"}
--
-None
-box.space.sophia:insert{332, "tuple 332"}
--
-None
-box.space.sophia:insert{333, "tuple 333"}
--
-None
-box.space.sophia:insert{334, "tuple 334"}
--
-None
-box.space.memtx:select{330}
--
-- [330, tuple 330]
-
-box.space.memtx:select{331}
--
-- [331, tuple 331]
-
-box.space.memtx:select{332}
--
-- [332, tuple 332]
-
-box.space.memtx:select{333}
--
-- [333, tuple 333]
-
-box.space.memtx:select{334}
--
-- [334, tuple 334]
-
-box.space.sophia:select{330}
--
-- [330, tuple 330]
-
-box.space.sophia:select{331}
--
-- [331, tuple 331]
-
-box.space.sophia:select{332}
--
-- [332, tuple 332]
-
-box.space.sophia:select{333}
--
-- [333, tuple 333]
-
-box.space.sophia:select{334}
--
-- [334, tuple 334]
-
-box.space.memtx:insert{335, "tuple 335"}
--
-None
-box.space.memtx:insert{336, "tuple 336"}
--
-None
-box.space.memtx:insert{337, "tuple 337"}
--
-None
-box.space.memtx:insert{338, "tuple 338"}
--
-None
-box.space.memtx:insert{339, "tuple 339"}
--
-None
-box.space.sophia:insert{335, "tuple 335"}
--
-None
-box.space.sophia:insert{336, "tuple 336"}
--
-None
-box.space.sophia:insert{337, "tuple 337"}
--
-None
-box.space.sophia:insert{338, "tuple 338"}
--
-None
-box.space.sophia:insert{339, "tuple 339"}
--
-None
-box.space.memtx:select{335}
--
-- [335, tuple 335]
-
-box.space.memtx:select{336}
--
-- [336, tuple 336]
-
-box.space.memtx:select{337}
--
-- [337, tuple 337]
-
-box.space.memtx:select{338}
--
-- [338, tuple 338]
-
-box.space.memtx:select{339}
--
-- [339, tuple 339]
-
-box.space.sophia:select{335}
--
-- [335, tuple 335]
-
-box.space.sophia:select{336}
--
-- [336, tuple 336]
-
-box.space.sophia:select{337}
--
-- [337, tuple 337]
-
-box.space.sophia:select{338}
--
-- [338, tuple 338]
-
-box.space.sophia:select{339}
--
-- [339, tuple 339]
-
-rollback servers configuration
-switch master to master
-box.cfg{replication_source=''}
----
-...
-switch replica to replica
-test 17 iteration
-box.space.memtx:insert{340, "tuple 340"}
--
-None
-box.space.memtx:insert{341, "tuple 341"}
--
-None
-box.space.memtx:insert{342, "tuple 342"}
--
-None
-box.space.memtx:insert{343, "tuple 343"}
--
-None
-box.space.memtx:insert{344, "tuple 344"}
--
-None
-box.space.sophia:insert{340, "tuple 340"}
--
-None
-box.space.sophia:insert{341, "tuple 341"}
--
-None
-box.space.sophia:insert{342, "tuple 342"}
--
-None
-box.space.sophia:insert{343, "tuple 343"}
--
-None
-box.space.sophia:insert{344, "tuple 344"}
--
-None
-box.space.memtx:select{340}
--
-- [340, tuple 340]
-
-box.space.memtx:select{341}
--
-- [341, tuple 341]
-
-box.space.memtx:select{342}
--
-- [342, tuple 342]
-
-box.space.memtx:select{343}
--
-- [343, tuple 343]
-
-box.space.memtx:select{344}
--
-- [344, tuple 344]
-
-box.space.sophia:select{340}
--
-- [340, tuple 340]
-
-box.space.sophia:select{341}
--
-- [341, tuple 341]
-
-box.space.sophia:select{342}
--
-- [342, tuple 342]
-
-box.space.sophia:select{343}
--
-- [343, tuple 343]
-
-box.space.sophia:select{344}
--
-- [344, tuple 344]
-
-box.space.memtx:insert{345, "tuple 345"}
--
-None
-box.space.memtx:insert{346, "tuple 346"}
--
-None
-box.space.memtx:insert{347, "tuple 347"}
--
-None
-box.space.memtx:insert{348, "tuple 348"}
--
-None
-box.space.memtx:insert{349, "tuple 349"}
--
-None
-box.space.sophia:insert{345, "tuple 345"}
--
-None
-box.space.sophia:insert{346, "tuple 346"}
--
-None
-box.space.sophia:insert{347, "tuple 347"}
--
-None
-box.space.sophia:insert{348, "tuple 348"}
--
-None
-box.space.sophia:insert{349, "tuple 349"}
--
-None
-box.space.memtx:select{345}
--
-- [345, tuple 345]
-
-box.space.memtx:select{346}
--
-- [346, tuple 346]
-
-box.space.memtx:select{347}
--
-- [347, tuple 347]
-
-box.space.memtx:select{348}
--
-- [348, tuple 348]
-
-box.space.memtx:select{349}
--
-- [349, tuple 349]
-
-box.space.sophia:select{345}
--
-- [345, tuple 345]
-
-box.space.sophia:select{346}
--
-- [346, tuple 346]
-
-box.space.sophia:select{347}
--
-- [347, tuple 347]
-
-box.space.sophia:select{348}
--
-- [348, tuple 348]
-
-box.space.sophia:select{349}
--
-- [349, tuple 349]
-
-swap servers
-switch replica to master
-box.cfg{replication_source=''}
----
-...
-switch master to replica
-box.space.memtx:insert{350, "tuple 350"}
--
-None
-box.space.memtx:insert{351, "tuple 351"}
--
-None
-box.space.memtx:insert{352, "tuple 352"}
--
-None
-box.space.memtx:insert{353, "tuple 353"}
--
-None
-box.space.memtx:insert{354, "tuple 354"}
--
-None
-box.space.sophia:insert{350, "tuple 350"}
--
-None
-box.space.sophia:insert{351, "tuple 351"}
--
-None
-box.space.sophia:insert{352, "tuple 352"}
--
-None
-box.space.sophia:insert{353, "tuple 353"}
--
-None
-box.space.sophia:insert{354, "tuple 354"}
--
-None
-box.space.memtx:select{350}
--
-- [350, tuple 350]
-
-box.space.memtx:select{351}
--
-- [351, tuple 351]
-
-box.space.memtx:select{352}
--
-- [352, tuple 352]
-
-box.space.memtx:select{353}
--
-- [353, tuple 353]
-
-box.space.memtx:select{354}
--
-- [354, tuple 354]
-
-box.space.sophia:select{350}
--
-- [350, tuple 350]
-
-box.space.sophia:select{351}
--
-- [351, tuple 351]
-
-box.space.sophia:select{352}
--
-- [352, tuple 352]
-
-box.space.sophia:select{353}
--
-- [353, tuple 353]
-
-box.space.sophia:select{354}
--
-- [354, tuple 354]
-
-box.space.memtx:insert{355, "tuple 355"}
--
-None
-box.space.memtx:insert{356, "tuple 356"}
--
-None
-box.space.memtx:insert{357, "tuple 357"}
--
-None
-box.space.memtx:insert{358, "tuple 358"}
--
-None
-box.space.memtx:insert{359, "tuple 359"}
--
-None
-box.space.sophia:insert{355, "tuple 355"}
--
-None
-box.space.sophia:insert{356, "tuple 356"}
--
-None
-box.space.sophia:insert{357, "tuple 357"}
--
-None
-box.space.sophia:insert{358, "tuple 358"}
--
-None
-box.space.sophia:insert{359, "tuple 359"}
--
-None
-box.space.memtx:select{355}
--
-- [355, tuple 355]
-
-box.space.memtx:select{356}
--
-- [356, tuple 356]
-
-box.space.memtx:select{357}
--
-- [357, tuple 357]
-
-box.space.memtx:select{358}
--
-- [358, tuple 358]
-
-box.space.memtx:select{359}
--
-- [359, tuple 359]
-
-box.space.sophia:select{355}
--
-- [355, tuple 355]
-
-box.space.sophia:select{356}
--
-- [356, tuple 356]
-
-box.space.sophia:select{357}
--
-- [357, tuple 357]
-
-box.space.sophia:select{358}
--
-- [358, tuple 358]
-
-box.space.sophia:select{359}
--
-- [359, tuple 359]
-
-rollback servers configuration
-switch master to master
-box.cfg{replication_source=''}
----
-...
-switch replica to replica
-test 18 iteration
-box.space.memtx:insert{360, "tuple 360"}
--
-None
-box.space.memtx:insert{361, "tuple 361"}
--
-None
-box.space.memtx:insert{362, "tuple 362"}
--
-None
-box.space.memtx:insert{363, "tuple 363"}
--
-None
-box.space.memtx:insert{364, "tuple 364"}
--
-None
-box.space.sophia:insert{360, "tuple 360"}
--
-None
-box.space.sophia:insert{361, "tuple 361"}
--
-None
-box.space.sophia:insert{362, "tuple 362"}
--
-None
-box.space.sophia:insert{363, "tuple 363"}
--
-None
-box.space.sophia:insert{364, "tuple 364"}
--
-None
-box.space.memtx:select{360}
--
-- [360, tuple 360]
-
-box.space.memtx:select{361}
--
-- [361, tuple 361]
-
-box.space.memtx:select{362}
--
-- [362, tuple 362]
-
-box.space.memtx:select{363}
--
-- [363, tuple 363]
-
-box.space.memtx:select{364}
--
-- [364, tuple 364]
-
-box.space.sophia:select{360}
--
-- [360, tuple 360]
-
-box.space.sophia:select{361}
--
-- [361, tuple 361]
-
-box.space.sophia:select{362}
--
-- [362, tuple 362]
-
-box.space.sophia:select{363}
--
-- [363, tuple 363]
-
-box.space.sophia:select{364}
--
-- [364, tuple 364]
-
-box.space.memtx:insert{365, "tuple 365"}
--
-None
-box.space.memtx:insert{366, "tuple 366"}
--
-None
-box.space.memtx:insert{367, "tuple 367"}
--
-None
-box.space.memtx:insert{368, "tuple 368"}
--
-None
-box.space.memtx:insert{369, "tuple 369"}
--
-None
-box.space.sophia:insert{365, "tuple 365"}
--
-None
-box.space.sophia:insert{366, "tuple 366"}
--
-None
-box.space.sophia:insert{367, "tuple 367"}
--
-None
-box.space.sophia:insert{368, "tuple 368"}
--
-None
-box.space.sophia:insert{369, "tuple 369"}
--
-None
-box.space.memtx:select{365}
--
-- [365, tuple 365]
-
-box.space.memtx:select{366}
--
-- [366, tuple 366]
-
-box.space.memtx:select{367}
--
-- [367, tuple 367]
-
-box.space.memtx:select{368}
--
-- [368, tuple 368]
-
-box.space.memtx:select{369}
--
-- [369, tuple 369]
-
-box.space.sophia:select{365}
--
-- [365, tuple 365]
-
-box.space.sophia:select{366}
--
-- [366, tuple 366]
-
-box.space.sophia:select{367}
--
-- [367, tuple 367]
-
-box.space.sophia:select{368}
--
-- [368, tuple 368]
-
-box.space.sophia:select{369}
--
-- [369, tuple 369]
-
-swap servers
-switch replica to master
-box.cfg{replication_source=''}
----
-...
-switch master to replica
-box.space.memtx:insert{370, "tuple 370"}
--
-None
-box.space.memtx:insert{371, "tuple 371"}
--
-None
-box.space.memtx:insert{372, "tuple 372"}
--
-None
-box.space.memtx:insert{373, "tuple 373"}
--
-None
-box.space.memtx:insert{374, "tuple 374"}
--
-None
-box.space.sophia:insert{370, "tuple 370"}
--
-None
-box.space.sophia:insert{371, "tuple 371"}
--
-None
-box.space.sophia:insert{372, "tuple 372"}
--
-None
-box.space.sophia:insert{373, "tuple 373"}
--
-None
-box.space.sophia:insert{374, "tuple 374"}
--
-None
-box.space.memtx:select{370}
--
-- [370, tuple 370]
-
-box.space.memtx:select{371}
--
-- [371, tuple 371]
-
-box.space.memtx:select{372}
--
-- [372, tuple 372]
-
-box.space.memtx:select{373}
--
-- [373, tuple 373]
-
-box.space.memtx:select{374}
--
-- [374, tuple 374]
-
-box.space.sophia:select{370}
--
-- [370, tuple 370]
-
-box.space.sophia:select{371}
--
-- [371, tuple 371]
-
-box.space.sophia:select{372}
--
-- [372, tuple 372]
-
-box.space.sophia:select{373}
--
-- [373, tuple 373]
-
-box.space.sophia:select{374}
--
-- [374, tuple 374]
-
-box.space.memtx:insert{375, "tuple 375"}
--
-None
-box.space.memtx:insert{376, "tuple 376"}
--
-None
-box.space.memtx:insert{377, "tuple 377"}
--
-None
-box.space.memtx:insert{378, "tuple 378"}
--
-None
-box.space.memtx:insert{379, "tuple 379"}
--
-None
-box.space.sophia:insert{375, "tuple 375"}
--
-None
-box.space.sophia:insert{376, "tuple 376"}
--
-None
-box.space.sophia:insert{377, "tuple 377"}
--
-None
-box.space.sophia:insert{378, "tuple 378"}
--
-None
-box.space.sophia:insert{379, "tuple 379"}
--
-None
-box.space.memtx:select{375}
--
-- [375, tuple 375]
-
-box.space.memtx:select{376}
--
-- [376, tuple 376]
-
-box.space.memtx:select{377}
--
-- [377, tuple 377]
-
-box.space.memtx:select{378}
--
-- [378, tuple 378]
-
-box.space.memtx:select{379}
--
-- [379, tuple 379]
-
-box.space.sophia:select{375}
--
-- [375, tuple 375]
-
-box.space.sophia:select{376}
--
-- [376, tuple 376]
-
-box.space.sophia:select{377}
--
-- [377, tuple 377]
-
-box.space.sophia:select{378}
--
-- [378, tuple 378]
-
-box.space.sophia:select{379}
--
-- [379, tuple 379]
-
-rollback servers configuration
-switch master to master
-box.cfg{replication_source=''}
----
-...
-switch replica to replica
-test 19 iteration
-box.space.memtx:insert{380, "tuple 380"}
--
-None
-box.space.memtx:insert{381, "tuple 381"}
--
-None
-box.space.memtx:insert{382, "tuple 382"}
--
-None
-box.space.memtx:insert{383, "tuple 383"}
--
-None
-box.space.memtx:insert{384, "tuple 384"}
--
-None
-box.space.sophia:insert{380, "tuple 380"}
--
-None
-box.space.sophia:insert{381, "tuple 381"}
--
-None
-box.space.sophia:insert{382, "tuple 382"}
--
-None
-box.space.sophia:insert{383, "tuple 383"}
--
-None
-box.space.sophia:insert{384, "tuple 384"}
--
-None
-box.space.memtx:select{380}
--
-- [380, tuple 380]
-
-box.space.memtx:select{381}
--
-- [381, tuple 381]
-
-box.space.memtx:select{382}
--
-- [382, tuple 382]
-
-box.space.memtx:select{383}
--
-- [383, tuple 383]
-
-box.space.memtx:select{384}
--
-- [384, tuple 384]
-
-box.space.sophia:select{380}
--
-- [380, tuple 380]
-
-box.space.sophia:select{381}
--
-- [381, tuple 381]
-
-box.space.sophia:select{382}
--
-- [382, tuple 382]
-
-box.space.sophia:select{383}
--
-- [383, tuple 383]
-
-box.space.sophia:select{384}
--
-- [384, tuple 384]
-
-box.space.memtx:insert{385, "tuple 385"}
--
-None
-box.space.memtx:insert{386, "tuple 386"}
--
-None
-box.space.memtx:insert{387, "tuple 387"}
--
-None
-box.space.memtx:insert{388, "tuple 388"}
--
-None
-box.space.memtx:insert{389, "tuple 389"}
--
-None
-box.space.sophia:insert{385, "tuple 385"}
--
-None
-box.space.sophia:insert{386, "tuple 386"}
--
-None
-box.space.sophia:insert{387, "tuple 387"}
--
-None
-box.space.sophia:insert{388, "tuple 388"}
--
-None
-box.space.sophia:insert{389, "tuple 389"}
--
-None
-box.space.memtx:select{385}
--
-- [385, tuple 385]
-
-box.space.memtx:select{386}
--
-- [386, tuple 386]
-
-box.space.memtx:select{387}
--
-- [387, tuple 387]
-
-box.space.memtx:select{388}
--
-- [388, tuple 388]
-
-box.space.memtx:select{389}
--
-- [389, tuple 389]
-
-box.space.sophia:select{385}
--
-- [385, tuple 385]
-
-box.space.sophia:select{386}
--
-- [386, tuple 386]
-
-box.space.sophia:select{387}
--
-- [387, tuple 387]
-
-box.space.sophia:select{388}
--
-- [388, tuple 388]
-
-box.space.sophia:select{389}
--
-- [389, tuple 389]
-
-swap servers
-switch replica to master
-box.cfg{replication_source=''}
----
-...
-switch master to replica
-box.space.memtx:insert{390, "tuple 390"}
--
-None
-box.space.memtx:insert{391, "tuple 391"}
--
-None
-box.space.memtx:insert{392, "tuple 392"}
--
-None
-box.space.memtx:insert{393, "tuple 393"}
--
-None
-box.space.memtx:insert{394, "tuple 394"}
--
-None
-box.space.sophia:insert{390, "tuple 390"}
--
-None
-box.space.sophia:insert{391, "tuple 391"}
--
-None
-box.space.sophia:insert{392, "tuple 392"}
--
-None
-box.space.sophia:insert{393, "tuple 393"}
--
-None
-box.space.sophia:insert{394, "tuple 394"}
--
-None
-box.space.memtx:select{390}
--
-- [390, tuple 390]
-
-box.space.memtx:select{391}
--
-- [391, tuple 391]
-
-box.space.memtx:select{392}
--
-- [392, tuple 392]
-
-box.space.memtx:select{393}
--
-- [393, tuple 393]
-
-box.space.memtx:select{394}
--
-- [394, tuple 394]
-
-box.space.sophia:select{390}
--
-- [390, tuple 390]
-
-box.space.sophia:select{391}
--
-- [391, tuple 391]
-
-box.space.sophia:select{392}
--
-- [392, tuple 392]
-
-box.space.sophia:select{393}
--
-- [393, tuple 393]
-
-box.space.sophia:select{394}
--
-- [394, tuple 394]
-
-box.space.memtx:insert{395, "tuple 395"}
--
-None
-box.space.memtx:insert{396, "tuple 396"}
--
-None
-box.space.memtx:insert{397, "tuple 397"}
--
-None
-box.space.memtx:insert{398, "tuple 398"}
--
-None
-box.space.memtx:insert{399, "tuple 399"}
--
-None
-box.space.sophia:insert{395, "tuple 395"}
--
-None
-box.space.sophia:insert{396, "tuple 396"}
--
-None
-box.space.sophia:insert{397, "tuple 397"}
--
-None
-box.space.sophia:insert{398, "tuple 398"}
--
-None
-box.space.sophia:insert{399, "tuple 399"}
--
-None
-box.space.memtx:select{395}
--
-- [395, tuple 395]
-
-box.space.memtx:select{396}
--
-- [396, tuple 396]
-
-box.space.memtx:select{397}
--
-- [397, tuple 397]
-
-box.space.memtx:select{398}
--
-- [398, tuple 398]
-
-box.space.memtx:select{399}
--
-- [399, tuple 399]
-
-box.space.sophia:select{395}
--
-- [395, tuple 395]
-
-box.space.sophia:select{396}
--
-- [396, tuple 396]
-
-box.space.sophia:select{397}
--
-- [397, tuple 397]
-
-box.space.sophia:select{398}
--
-- [398, tuple 398]
-
-box.space.sophia:select{399}
--
-- [399, tuple 399]
-
-rollback servers configuration
-switch master to master
-box.cfg{replication_source=''}
----
-...
-switch replica to replica
blob - 3153e36ee178b8fb956e1339a0d32832e7a72f7f (mode 644)
blob + /dev/null
--- test/replication/swap.test.py
+++ /dev/null
-import os
-import tarantool
-from lib.tarantool_server import TarantoolServer
-import re
-import yaml
-
-REPEAT = 20
-ID_BEGIN = 0
-ID_STEP = 5
-LOGIN = 'test'
-PASSWORD = 'pass123456'
-
-engines = ['memtx', 'sophia']
-
-def insert_tuples(_server, begin, end, msg = "tuple"):
- for engine in engines:
- for i in range(begin, end):
- print 'box.space.%s:insert{%d, "%s %d"}' % (engine, i, msg, i)
- print '-'
- space = _server.iproto.py_con.space(engine)
- print space.insert((i, '%s %d' % (msg, i)))
-
-def select_tuples(_server, begin, end):
- for engine in engines:
- for i in range(begin, end):
- print 'box.space.%s:select{%d}' % (engine, i)
- print '-'
- space = _server.iproto.py_con.space(engine)
- print space.select(i)
-
-# master server
-master = server
-# Re-deploy server to cleanup Sophia data
-master.stop()
-master.cleanup()
-master.deploy()
-master.admin("box.schema.user.create('%s', { password = '%s'})" % (LOGIN, PASSWORD))
-master.admin("box.schema.user.grant('%s', 'read,write,execute', 'universe')" % LOGIN)
-master.iproto.py_con.authenticate(LOGIN, PASSWORD)
-master.uri = '%s:%s@%s' % (LOGIN, PASSWORD, master.iproto.uri)
-os.putenv('MASTER', master.uri)
-
-# replica server
-replica = TarantoolServer()
-replica.script = "replication/replica.lua"
-replica.vardir = server.vardir #os.path.join(server.vardir, 'replica')
-replica.deploy()
-replica.admin("while box.info.server.id == 0 do require('fiber').sleep(0.01) end")
-replica.uri = '%s:%s@%s' % (LOGIN, PASSWORD, replica.iproto.uri)
-replica.admin("while box.space['_priv']:len() < 1 do require('fiber').sleep(0.01) end")
-replica.iproto.py_con.authenticate(LOGIN, PASSWORD)
-
-for engine in engines:
- master.admin("s = box.schema.space.create('%s', { engine = '%s'})" % (engine, engine))
- master.admin("index = s:create_index('primary', {type = 'tree'})")
-
-### gh-343: replica.cc must not add login and password to proc title
-#status = replica.get_param("status")
-#host_port = "%s:%s" % master.iproto.uri
-#m = re.search(r'replica/(.*)/.*', status)
-#if not m or m.group(1) != host_port:
-# print 'invalid box.info.status', status, 'expected host:port', host_port
-
-master_id = master.get_param('server')['id']
-replica_id = replica.get_param('server')['id']
-
-id = ID_BEGIN
-for i in range(REPEAT):
- print "test %d iteration" % i
-
- # insert to master
- insert_tuples(master, id, id + ID_STEP)
- # select from replica
- replica.wait_lsn(master_id, master.get_lsn(master_id))
- select_tuples(replica, id, id + ID_STEP)
- id += ID_STEP
-
- # insert to master
- insert_tuples(master, id, id + ID_STEP)
- # select from replica
- replica.wait_lsn(master_id, master.get_lsn(master_id))
- select_tuples(replica, id, id + ID_STEP)
- id += ID_STEP
-
- print "swap servers"
- # reconfigure replica to master
- replica.rpl_master = None
- print("switch replica to master")
- replica.admin("box.cfg{replication_source=''}")
- # reconfigure master to replica
- master.rpl_master = replica
- print("switch master to replica")
- master.admin("box.cfg{replication_source='%s'}" % replica.uri, silent=True)
-
- # insert to replica
- insert_tuples(replica, id, id + ID_STEP)
- # select from master
- master.wait_lsn(replica_id, replica.get_lsn(replica_id))
- select_tuples(master, id, id + ID_STEP)
- id += ID_STEP
-
- # insert to replica
- insert_tuples(replica, id, id + ID_STEP)
- # select from master
- master.wait_lsn(replica_id, replica.get_lsn(replica_id))
- select_tuples(master, id, id + ID_STEP)
- id += ID_STEP
-
- print "rollback servers configuration"
- # reconfigure replica to master
- master.rpl_master = None
- print("switch master to master")
- master.admin("box.cfg{replication_source=''}")
- # reconfigure master to replica
- replica.rpl_master = master
- print("switch replica to replica")
- replica.admin("box.cfg{replication_source='%s'}" % master.uri, silent=True)
-
-
-# Cleanup.
-replica.stop()
-replica.cleanup(True)
-server.stop()
-server.deploy()
blob - /dev/null
blob + 1259b1b4d9dd7fbc1dd122f7e78deb89fb47b5b2 (mode 644)
--- /dev/null
+++ test/long_run-py/box.lua
+#!/usr/bin/env tarantool
+
+require('suite')
+
+os.execute("rm -rf sophia_test")
+os.execute("mkdir -p sophia_test")
+
+local sophia = {
+ threads = 5
+}
+
+box.cfg {
+ listen = os.getenv("LISTEN"),
+ slab_alloc_arena = 0.1,
+ pid_file = "tarantool.pid",
+ rows_per_wal = 500000,
+ sophia_dir = "./sophia_test",
+ sophia = sophia,
+}
+
+require('console').listen(os.getenv('ADMIN'))
blob - /dev/null
blob + fa4c2f0c0368def7ea4f67a9947e3dd955e5c62f (mode 644)
--- /dev/null
+++ test/long_run-py/finalizers.result
+Expected error: <type 'exceptions.OSError'>
blob - /dev/null
blob + c471892f1770175dc9510225936e84021e865c1a (mode 644)
--- /dev/null
+++ test/long_run-py/finalizers.test.py
+import os
+import sys
+import re
+import yaml
+from lib.tarantool_server import TarantoolServer
+
+server = TarantoolServer(server.ini)
+server.script = 'long_run/lua/finalizers.lua'
+server.vardir = os.path.join(server.vardir, 'finalizers')
+try:
+ server.deploy()
+except:
+ print "Expected error:", sys.exc_info()[0]
+else:
+ print "Error! exception did not occur"
+
+
blob - /dev/null
blob + 122e1cd79d4c9495138805b64101865d5b6ed4db (mode 644)
--- /dev/null
+++ test/long_run-py/suite.ini
+[default]
+core = tarantool
+description = long running tests
+script = box.lua
+long_run = finalizers.test.py
+valgrind_disabled =
+release_disabled =
+lua_libs = suite.lua
+use_unix_sockets = True
blob - /dev/null
blob + 0b33dec7d766907ce938ca73f881be49ab77b97e (mode 644)
--- /dev/null
+++ test/long_run-py/suite.lua
+
+function string_function()
+ local random_number
+ local random_string
+ random_string = ""
+ for x = 1,20,1 do
+ random_number = math.random(65, 90)
+ random_string = random_string .. string.char(random_number)
+ end
+ return random_string
+end
+
+function delete_replace_update(engine_name)
+ local string_value
+ if (box.space._space.index.name:select{'tester'}[1] ~= nil) then
+ box.space.tester:drop()
+ end
+ box.schema.space.create('tester', {engine=engine_name})
+ box.space.tester:create_index('primary',{type = 'tree', parts = {1, 'STR'}})
+
+ local random_number
+ local string_value_2
+ local string_value_3
+ local counter = 1
+ while counter < 100000 do
+ local string_value = string_function()
+
+ local string_table = box.space.tester.index.primary:select({string_value}, {iterator = 'GE', limit = 1})
+ if string_table[1] == nil then
+ box.space.tester:insert{string_value, counter}
+ string_value_2 = string_value
+ else
+ string_value_2 = string_table[1][1]
+ end
+
+ if string_value_2 == nil then
+ box.space.tester:insert{string_value, counter}
+ string_value_2 = string_value
+ end
+
+ random_number = math.random(1,6)
+
+ string_value_3 = string_function()
+-- print('<'..counter..'> [' .. random_number .. '] value_2: ' .. string_value_2 .. ' value_3: ' .. string_value_3)
+ if random_number == 1 then
+ box.space.tester:delete{string_value_2}
+ end
+ if random_number == 2 then
+ box.space.tester:replace{string_value_2, counter, string_value_3}
+ end
+ if random_number == 3 then
+ box.space.tester:delete{string_value_2}
+ box.space.tester:insert{string_value_2, counter}
+ end
+ if random_number == 4 then
+ if counter < 1000000 then
+ box.space.tester:delete{string_value_3}
+ box.space.tester:insert{string_value_3, counter, string_value_2}
+ end
+ end
+ if random_number == 5 then
+ box.space.tester:update({string_value_2}, {{'=', 2, string_value_3}})
+ end
+ if random_number == 6 then
+ box.space.tester:update({string_value_2}, {{'=', 2, string_value_3}})
+ end
+ counter = counter + 1
+ end
+
+ box.space.tester:drop()
+ return {counter, random_number, string_value_2, string_value_3}
+end
+
+function delete_insert(engine_name)
+ local string_value
+ if (box.space._space.index.name:select{'tester'}[1] ~= nil) then
+ box.space.tester:drop()
+ end
+ box.schema.space.create('tester', {engine=engine_name})
+ box.space.tester:create_index('primary',{type = 'tree', parts = {1, 'STR'}})
+ local string_value_2
+ local counter = 1
+ while counter < 100000 do
+ local string_value = string_function()
+ local string_table = box.space.tester.index.primary:select({string_value}, {iterator = 'GE', limit = 1})
+
+ if string_table[1] == nil then
+ -- print (1, ' insert', counter, string_value)
+ box.space.tester:insert{string_value, counter}
+ string_value_2 = string_value
+ else
+ string_value_2 = string_table[1][1]
+ end
+
+ if string_value_2 == nil then
+ -- print (2, ' insert', counter, string_value)
+ box.space.tester:insert{string_value, counter}
+ string_value_2 = string_value
+ end
+
+ -- print (3, ' delete', counter, string_value_2)
+ box.space.tester:delete{string_value_2}
+
+ -- print (4, ' insert', counter, string_value_2)
+ box.space.tester:insert{string_value_2, counter}
+
+ counter = counter + 1
+ end
+ box.space.tester:drop()
+ return {counter, string_value_2}
+end
blob - /dev/null
blob + acb0026bc1d19263f1df7c8849955e2e70dd04be (mode 644)
--- /dev/null
+++ test/replication-py/cluster.result
+ok - cluster uuid
+-------------------------------------------------------------
+ gh-696: Check global READ permissions for replication
+-------------------------------------------------------------
+ok - join without read permissions to universe
+ok - subscribe without read permissions to universe
+box.schema.user.grant('guest', 'read', 'universe')
+---
+...
+ok - join without write permissions to _cluster
+box.schema.user.grant('guest', 'write', 'space', '_cluster')
+---
+...
+ok - join with granted permissions
+box.schema.user.revoke('guest', 'read', 'universe')
+---
+...
+box.schema.user.revoke('guest', 'write', 'space', '_cluster')
+---
+...
+box.schema.user.grant('guest', 'replication')
+---
+...
+ok - join with granted role
+-------------------------------------------------------------
+gh-707: Master crashes on JOIN if it does not have snapshot files
+gh-480: If socket is closed while JOIN, replica wont reconnect
+-------------------------------------------------------------
+ok - join without snapshots
+ok - _cluster does not changed after unsuccessful JOIN
+box.schema.user.revoke('guest', 'replication')
+---
+...
+box.snapshot()
+---
+- ok
+...
+-------------------------------------------------------------
+gh-434: Assertion if replace _cluster tuple for local server
+-------------------------------------------------------------
+box.space._cluster:replace{1, '8c7ff474-65f9-4abe-81a4-a3e1019bb1ae'}
+---
+- [1, '8c7ff474-65f9-4abe-81a4-a3e1019bb1ae']
+...
+box.info.server.uuid
+---
+- 8c7ff474-65f9-4abe-81a4-a3e1019bb1ae
+...
+check log line for 'server UUID changed to 8c7ff474-65f9-4abe-81a4-a3e1019bb1ae'
+
+'server UUID changed to 8c7ff474-65f9-4abe-81a4-a3e1019bb1ae' exists in server log
+
+box.info.server.uuid
+---
+- 8c7ff474-65f9-4abe-81a4-a3e1019bb1ae
+...
+box.snapshot()
+---
+- ok
+...
+box.info.server.uuid
+---
+- 8c7ff474-65f9-4abe-81a4-a3e1019bb1ae
+...
+box.space._cluster:replace{1, require('uuid').NULL:str()}
+---
+- error: 'Invalid UUID: 00000000-0000-0000-0000-000000000000'
+...
+-------------------------------------------------------------
+gh-1140: Assertion if replace _cluster tuple for remote server
+-------------------------------------------------------------
+box.space._cluster:replace{5, '0d5bd431-7f3e-4695-a5c2-82de0a9cbc95'}
+---
+- [5, '0d5bd431-7f3e-4695-a5c2-82de0a9cbc95']
+...
+box.info.vclock[5] == 0
+---
+- true
+...
+box.space._cluster:replace{5, '0d5bd431-7f3e-4695-a5c2-82de0a9cbc95'}
+---
+- [5, '0d5bd431-7f3e-4695-a5c2-82de0a9cbc95']
+...
+box.space._cluster:replace{5, 'a48a19a3-26c0-4f8c-a5b5-77377bab389b'}
+---
+- [5, 'a48a19a3-26c0-4f8c-a5b5-77377bab389b']
+...
+box.space._cluster:delete(5)
+---
+- [5, 'a48a19a3-26c0-4f8c-a5b5-77377bab389b']
+...
+box.info.vclock[5] == nil
+---
+- true
+...
+-------------------------------------------------------------
+gh-527: update vclock on delete from box.space._cluster
+-------------------------------------------------------------
+box.schema.user.grant('guest', 'replication')
+---
+...
+box.space._schema:insert{"test", 48}
+---
+- ['test', 48]
+...
+box.info.server.id
+---
+- 2
+...
+box.info.server.ro
+---
+- false
+...
+box.info.server.lsn
+---
+- 1
+...
+box.info.vclock[2]
+---
+- 1
+...
+box.space._cluster:delete{2}
+---
+- [2, '<replica uuid>']
+...
+box.info.server.id
+---
+- 0
+...
+box.info.server.ro
+---
+- true
+...
+box.info.server.lsn
+---
+- -1
+...
+box.info.vclock[2]
+---
+- null
+...
+box.space._schema:replace{"test", 48}
+---
+- error: Can't modify data because this server is in read-only mode.
+...
+box.space._cluster:insert{10, "<replica uuid>"}
+---
+- [10, '<replica uuid>']
+...
+box.info.server.id
+---
+- 10
+...
+box.info.server.ro
+---
+- false
+...
+box.info.server.lsn
+---
+- 0
+...
+box.info.vclock[2]
+---
+- null
+...
+box.info.vclock[10]
+---
+- 0
+...
+box.space._cluster:update(10, {{'=', 1, 11}})
+---
+- error: Attempt to modify a tuple field which is part of index 'primary' in space
+ '_cluster'
+...
+box.info.server.id
+---
+- 10
+...
+box.info.server.ro
+---
+- false
+...
+box.info.server.lsn
+---
+- 0
+...
+box.info.vclock[2]
+---
+- null
+...
+box.info.vclock[10]
+---
+- 0
+...
+box.info.vclock[11]
+---
+- null
+...
+box.schema.user.revoke('guest', 'replication')
+---
+...
blob - /dev/null
blob + 4d3ac78ec5826ca01e430791484bfda3b6c4d152 (mode 644)
--- /dev/null
+++ test/replication-py/cluster.test.py
+import os
+import sys
+import re
+import yaml
+import uuid
+import glob
+from lib.tarantool_server import TarantoolServer
+
+## Get cluster uuid
+cluster_uuid = ''
+try:
+ cluster_uuid = yaml.load(server.admin("box.space._schema:get('cluster')",
+ silent = True))[0][1]
+ uuid.UUID('{' + cluster_uuid + '}')
+ print 'ok - cluster uuid'
+except Exception as e:
+ print 'not ok - invalid cluster uuid', e
+
+print '-------------------------------------------------------------'
+print ' gh-696: Check global READ permissions for replication'
+print '-------------------------------------------------------------'
+
+# Generate replica cluster UUID
+replica_uuid = str(uuid.uuid4())
+
+## Universal read permission is required to perform JOIN/SUBSCRIBE
+rows = list(server.iproto.py_con.join(replica_uuid))
+print len(rows) == 1 and rows[0].return_message.find('Read access') >= 0 and \
+ 'ok' or 'not ok', '-', 'join without read permissions to universe'
+rows = list(server.iproto.py_con.subscribe(cluster_uuid, replica_uuid))
+print len(rows) == 1 and rows[0].return_message.find('Read access') >= 0 and \
+ 'ok' or 'not ok', '-', 'subscribe without read permissions to universe'
+
+## Write permission to space `_cluster` is required to perform JOIN
+server.admin("box.schema.user.grant('guest', 'read', 'universe')")
+server.iproto.py_con.close() # re-connect with new permissions
+rows = list(server.iproto.py_con.join(replica_uuid))
+print len(rows) == 1 and rows[0].return_message.find('Write access') >= 0 and \
+ 'ok' or 'not ok', '-', 'join without write permissions to _cluster'
+
+def check_join(msg):
+ ok = True
+ for resp in server.iproto.py_con.join(replica_uuid):
+ if resp.completion_status != 0:
+ print 'not ok', '-', msg, resp.return_message
+ ok = False
+
+ server.iproto.py_con.close() # JOIN brokes protocol
+ if not ok:
+ return
+ tuples = server.iproto.py_con.space('_cluster').select(replica_uuid, index = 1)
+ if len(tuples) == 0:
+ print 'not ok', '-', msg, 'missing entry in _cluster'
+ return
+ server_id = tuples[0][0]
+ print 'ok', '-', msg
+ return server_id
+
+## JOIN with permissions
+server.admin("box.schema.user.grant('guest', 'write', 'space', '_cluster')")
+server.iproto.py_con.close() # re-connect with new permissions
+server_id = check_join('join with granted permissions')
+server.iproto.py_con.space('_cluster').delete(server_id)
+
+# JOIN with granted role
+server.admin("box.schema.user.revoke('guest', 'read', 'universe')")
+server.admin("box.schema.user.revoke('guest', 'write', 'space', '_cluster')")
+server.admin("box.schema.user.grant('guest', 'replication')")
+server.iproto.py_con.close() # re-connect with new permissions
+server_id = check_join('join with granted role')
+server.iproto.py_con.space('_cluster').delete(server_id)
+
+print '-------------------------------------------------------------'
+print 'gh-707: Master crashes on JOIN if it does not have snapshot files'
+print 'gh-480: If socket is closed while JOIN, replica wont reconnect'
+print '-------------------------------------------------------------'
+
+data_dir = os.path.join(server.vardir, server.name)
+for k in glob.glob(os.path.join(data_dir, '*.snap')):
+ os.unlink(k)
+
+# remember the number of servers in _cluster table
+server_count = len(server.iproto.py_con.space('_cluster').select(()))
+
+rows = list(server.iproto.py_con.join(replica_uuid))
+print len(rows) == 1 and rows[0].return_message.find('snapshot') >= 0 and \
+ 'ok' or 'not ok', '-', 'join without snapshots'
+
+print server_count == len(server.iproto.py_con.space('_cluster').select(())) and\
+ 'ok' or 'not ok', '-', '_cluster does not changed after unsuccessful JOIN'
+
+server.admin("box.schema.user.revoke('guest', 'replication')")
+server.admin('box.snapshot()')
+
+print '-------------------------------------------------------------'
+print 'gh-434: Assertion if replace _cluster tuple for local server'
+print '-------------------------------------------------------------'
+server.stop()
+script = server.script
+server.script = "replication/panic.lua"
+server.deploy()
+
+new_uuid = '8c7ff474-65f9-4abe-81a4-a3e1019bb1ae'
+
+# Check log message
+# Requires panic_on_wal_error = false
+server.admin("box.space._cluster:replace{{1, '{0}'}}".format(new_uuid))
+server.admin("box.info.server.uuid")
+
+line = "server UUID changed to " + new_uuid
+print "check log line for '%s'" % line
+print
+if server.logfile_pos.seek_once(line) >= 0:
+ print "'%s' exists in server log" % line
+print
+server.admin("box.info.server.uuid")
+
+# Check that new UUID has been saved in snapshot
+server.admin("box.snapshot()")
+server.restart()
+
+server.admin("box.info.server.uuid")
+
+# Invalid UUID
+server.admin("box.space._cluster:replace{1, require('uuid').NULL:str()}")
+
+print '-------------------------------------------------------------'
+print 'gh-1140: Assertion if replace _cluster tuple for remote server'
+print '-------------------------------------------------------------'
+
+# Test that insert is OK
+new_uuid = '0d5bd431-7f3e-4695-a5c2-82de0a9cbc95'
+server.admin("box.space._cluster:replace{{5, '{0}'}}".format(new_uuid))
+server.admin("box.info.vclock[5] == 0")
+
+# Replace with the same UUID is OK
+server.admin("box.space._cluster:replace{{5, '{0}'}}".format(new_uuid))
+# Replace with a new UUID is OK
+new_uuid = 'a48a19a3-26c0-4f8c-a5b5-77377bab389b'
+server.admin("box.space._cluster:replace{{5, '{0}'}}".format(new_uuid))
+# Delete is OK
+server.admin("box.space._cluster:delete(5)")
+server.admin("box.info.vclock[5] == nil")
+
+# Cleanup
+server.stop()
+server.script = script
+server.deploy()
+
+print '-------------------------------------------------------------'
+print 'gh-527: update vclock on delete from box.space._cluster'
+print '-------------------------------------------------------------'
+
+# master server
+master = server
+master_id = master.get_param('server')['id']
+
+master.admin("box.schema.user.grant('guest', 'replication')")
+
+replica = TarantoolServer(server.ini)
+replica.script = 'replication/replica.lua'
+replica.vardir = server.vardir
+replica.rpl_master = master
+replica.deploy()
+replica.wait_lsn(master_id, master.get_lsn(master_id))
+replica_id = replica.get_param('server')['id']
+replica_uuid = replica.get_param('server')['uuid']
+sys.stdout.push_filter(replica_uuid, '<replica uuid>')
+replica.admin('box.space._schema:insert{"test", 48}')
+
+replica.admin('box.info.server.id')
+replica.admin('box.info.server.ro')
+replica.admin('box.info.server.lsn') # 1
+replica.admin('box.info.vclock[%d]' % replica_id)
+
+master.admin('box.space._cluster:delete{%d}' % replica_id)
+replica.wait_lsn(master_id, master.get_lsn(master_id))
+replica.admin('box.info.server.id')
+replica.admin('box.info.server.ro')
+replica.admin('box.info.server.lsn') # -1
+replica.admin('box.info.vclock[%d]' % replica_id)
+# replica is read-only
+replica.admin('box.space._schema:replace{"test", 48}')
+
+replica_id2 = 10
+master.admin('box.space._cluster:insert{%d, "%s"}' %
+ (replica_id2, replica_uuid))
+replica.wait_lsn(master_id, master.get_lsn(master_id))
+replica.admin('box.info.server.id')
+replica.admin('box.info.server.ro')
+replica.admin('box.info.server.lsn') # 0
+replica.admin('box.info.vclock[%d]' % replica_id)
+replica.admin('box.info.vclock[%d]' % replica_id2)
+
+replica_id3 = 11
+# Tuple is read-only
+server.admin("box.space._cluster:update(%d, {{'=', 1, %d}})" %
+ (replica_id2, replica_id3))
+replica.wait_lsn(master_id, master.get_lsn(master_id))
+replica.admin('box.info.server.id')
+replica.admin('box.info.server.ro')
+replica.admin('box.info.server.lsn') # 0
+replica.admin('box.info.vclock[%d]' % replica_id)
+replica.admin('box.info.vclock[%d]' % replica_id2)
+replica.admin('box.info.vclock[%d]' % replica_id3)
+replica.stop()
+replica.cleanup(True)
+
+# Cleanup
+sys.stdout.pop_filter()
+
+master.admin("box.schema.user.revoke('guest', 'replication')")
blob - /dev/null
blob + 7bc5dceb093750395e51f200ec3cf2a43e8546ca (mode 644)
--- /dev/null
+++ test/replication-py/conflict.result
+box.schema.user.grant('guest', 'replication')
+---
+...
+reset master-master replication
+parallel send: box.space.test:update(1, {{'#', 2, 1}})
+parallel send: box.space.test:update(1, {{'#', 2, 1}})
+replication state is correct
+box.space.test:select{1}
+---
+- - [1]
+...
+box.space.test:select{1}
+---
+- - [1]
+...
+reset master-master replication
+parallel send: box.space.test:insert{20, 1}
+parallel send: box.space.test:insert{20, 2}
+replication state is correct
+reset master-master replication
+parallel send: box.space.test:update(2, {{'=', 2, 1}})
+parallel send: box.space.test:update(2, {{'=', 2, 2}})
+replication state is correct
+reset master-master replication
+parallel send: box.space.test:update(1, {{'+', 2, 1}})
+parallel send: box.space.test:update(1, {{'+', 2, 2}})
+replication state is correct
+box.space.test:select{1}
+---
+- - [1, 4]
+...
+box.space.test:select{1}
+---
+- - [1, 4]
+...
+reset master-master replication
+parallel send: box.space.test:delete(999)
+parallel send: box.space.test:delete(999)
+replication state is correct
+box.space.test:select{}
+---
+- - [1, 1]
+ - [2, 4]
+ - [3, 9]
+ - [4, 16]
+ - [5, 25]
+ - [6, 36]
+ - [7, 49]
+ - [8, 64]
+ - [9, 81]
+...
+box.space.test:select{}
+---
+- - [1, 1]
+ - [2, 4]
+ - [3, 9]
+ - [4, 16]
+ - [5, 25]
+ - [6, 36]
+ - [7, 49]
+ - [8, 64]
+ - [9, 81]
+...
blob - /dev/null
blob + 8d6e9347f1eed8ac6d1f43e4cd90c0e66332db32 (mode 644)
--- /dev/null
+++ test/replication-py/conflict.test.py
+from lib.tarantool_server import TarantoolServer
+from time import sleep
+import yaml
+
+def check_replication(nodes, select_args=''):
+ for node in nodes:
+ node.admin('box.space.test:select{%s}' % select_args)
+
+master = server
+master.admin("box.schema.user.grant('guest', 'replication')")
+
+replica = TarantoolServer(server.ini)
+replica.script = 'replication/replica.lua'
+replica.vardir = server.vardir
+replica.rpl_master = master
+replica.deploy()
+
+def parallel_run(cmd1, cmd2, compare):
+ print 'parallel send: %s' % cmd1
+ print 'parallel send: %s' % cmd2
+ master.admin.socket.sendall('%s\n' % cmd1)
+ replica.admin.socket.sendall('%s\n' % cmd2)
+
+ master.admin.socket.recv(2048)
+ replica.admin.socket.recv(2048)
+
+ # wait for status changing in tarantool
+ master_status = yaml.load(master.admin(
+ 'box.info().replication.status', silent=True
+ ))[0]
+ replica_status = yaml.load(replica.admin(
+ 'box.info().replication.status', silent=True
+ ))[0]
+
+ # wait for status
+ results = [f(master_status, replica_status) for f in compare]
+ while True:
+ sleep(0.01)
+ if any(results):
+ print 'replication state is correct'
+ break
+
+def prepare_cluster():
+ print 'reset master-master replication'
+ master.stop()
+ master.cleanup(True)
+ master.start()
+ master.admin("box.schema.user.grant('guest', 'replication')", silent=True)
+
+ replica.stop()
+ replica.cleanup(True)
+ replica.start()
+
+ master.admin("box.cfg{replication_source='%s'}" % replica.iproto.uri, silent=True)
+ r1_id = replica.get_param('server')['id']
+ r2_id = master.get_param('server')['id']
+
+ master.admin("space = box.schema.space.create('test')", silent=True)
+ master.admin("index = space:create_index('primary', { type = 'tree'})", silent=True)
+ master.admin('for k = 1, 9 do space:insert{k, k*k} end', silent=True)
+
+ # wait lsn
+ replica.wait_lsn(r2_id, master.get_lsn(r2_id))
+ master.wait_lsn(r1_id, replica.get_lsn(r1_id))
+
+# test1: double update in master and replica
+prepare_cluster()
+parallel_run(
+ "box.space.test:update(1, {{'#', 2, 1}})",
+ "box.space.test:update(1, {{'#', 2, 1}})",
+ [
+ lambda x,y: x == 'stopped' or y == 'stopped',
+ lambda x,y: x == 'follow' and y == 'follow',
+ ]
+)
+check_replication([master, replica], '1')
+
+# test2: insert different values with single id
+prepare_cluster()
+parallel_run(
+ 'box.space.test:insert{20, 1}',
+ 'box.space.test:insert{20, 2}',
+ [
+ lambda x,y: x == 'stopped' or y == 'stopped',
+ lambda x,y: x == 'follow' and y == 'follow',
+ ]
+)
+
+# test3: update different values
+prepare_cluster()
+parallel_run(
+ "box.space.test:update(2, {{'=', 2, 1}})",
+ "box.space.test:update(2, {{'=', 2, 2}})",
+ [lambda x,y: x == 'follow' and y == 'follow',]
+)
+
+# test4: CRDT increment with update
+prepare_cluster()
+parallel_run(
+ "box.space.test:update(1, {{'+', 2, 1}})",
+ "box.space.test:update(1, {{'+', 2, 2}})",
+ [lambda x,y: x == 'follow' and y == 'follow',]
+)
+check_replication([master, replica], '1')
+
+# test5: delete not existing key
+prepare_cluster()
+parallel_run(
+ "box.space.test:delete(999)",
+ "box.space.test:delete(999)",
+ [lambda x,y: x == 'follow' and y == 'follow',]
+)
+check_replication([master, replica])
+
+# cleanup
+replica.stop()
+replica.cleanup(True)
+server.stop()
+server.cleanup(True)
+server.deploy()
blob - /dev/null
blob + 0e27d903be5e858bc77505b35060cde17bb9f502 (mode 644)
--- /dev/null
+++ test/replication-py/init_storage.result
+box.schema.user.grant('guest', 'replication')
+---
+...
+space = box.schema.space.create('test', {id = 42})
+---
+...
+index = space:create_index('primary', { type = 'tree'})
+---
+...
+for k = 1, 9 do space:insert{k, k*k} end
+---
+...
+-------------------------------------------------------------
+replica test 1 (no such space)
+-------------------------------------------------------------
+box.space.test
+---
+- null
+...
+-------------------------------------------------------------
+replica JOIN
+-------------------------------------------------------------
+box.snapshot()
+---
+- ok
+...
+box.space.test:select()
+---
+- - [1, 1]
+ - [2, 4]
+ - [3, 9]
+ - [4, 16]
+ - [5, 25]
+ - [6, 36]
+ - [7, 49]
+ - [8, 64]
+ - [9, 81]
+...
+box.space.test:select()
+---
+- - [1, 1]
+ - [2, 4]
+ - [3, 9]
+ - [4, 16]
+ - [5, 25]
+ - [6, 36]
+ - [7, 49]
+ - [8, 64]
+ - [9, 81]
+...
+-------------------------------------------------------------
+replica test 2 (must be ok)
+-------------------------------------------------------------
+for k = 10, 19 do box.space[42]:insert{k, k*k*k} end
+---
+...
+for k = 20, 29 do box.space[42]:upsert({k}, {}) end
+---
+...
+space = box.space.test
+---
+...
+space:get{1}
+---
+- [1, 1]
+...
+space:get{2}
+---
+- [2, 4]
+...
+space:get{3}
+---
+- [3, 9]
+...
+space:get{4}
+---
+- [4, 16]
+...
+space:get{5}
+---
+- [5, 25]
+...
+space:get{6}
+---
+- [6, 36]
+...
+space:get{7}
+---
+- [7, 49]
+...
+space:get{8}
+---
+- [8, 64]
+...
+space:get{9}
+---
+- [9, 81]
+...
+space:get{10}
+---
+- [10, 1000]
+...
+space:get{11}
+---
+- [11, 1331]
+...
+space:get{12}
+---
+- [12, 1728]
+...
+space:get{13}
+---
+- [13, 2197]
+...
+space:get{14}
+---
+- [14, 2744]
+...
+space:get{15}
+---
+- [15, 3375]
+...
+space:get{16}
+---
+- [16, 4096]
+...
+space:get{17}
+---
+- [17, 4913]
+...
+space:get{18}
+---
+- [18, 5832]
+...
+space:get{19}
+---
+- [19, 6859]
+...
+-------------------------------------------------------------
+reconnect on JOIN/SUBSCRIBE
+-------------------------------------------------------------
+waiting reconnect on JOIN...
+ok
+waiting reconnect on SUBSCRIBE...
+ok
blob - /dev/null
blob + e59ff14c9c5f6d79cdd13b06742351c30902b1e4 (mode 644)
--- /dev/null
+++ test/replication-py/init_storage.test.py
+import os
+import glob
+from lib.tarantool_server import TarantoolServer
+
+# master server
+master = server
+master_id = master.get_param('server')['id']
+
+master.admin("box.schema.user.grant('guest', 'replication')")
+master.admin("space = box.schema.space.create('test', {id = 42})")
+master.admin("index = space:create_index('primary', { type = 'tree'})")
+
+master.admin('for k = 1, 9 do space:insert{k, k*k} end')
+data_dir = os.path.join(master.vardir, master.name)
+for k in glob.glob(os.path.join(data_dir, '*.xlog')):
+ os.unlink(k)
+
+print '-------------------------------------------------------------'
+print 'replica test 1 (no such space)'
+print '-------------------------------------------------------------'
+
+replica = TarantoolServer(server.ini)
+replica.script = 'replication/replica.lua'
+replica.vardir = server.vardir #os.path.join(server.vardir, 'replica')
+replica.rpl_master = master
+replica.deploy()
+
+replica.admin('box.space.test')
+
+replica.stop()
+replica.cleanup(True)
+
+print '-------------------------------------------------------------'
+print 'replica JOIN'
+print '-------------------------------------------------------------'
+
+master.admin('box.snapshot()')
+master.restart()
+
+replica.deploy()
+replica.wait_lsn(master_id, master.get_lsn(master_id))
+replica.admin('box.space.test:select()')
+
+#
+# gh-484: JOIN doesn't save data to snapshot with TREE index
+#
+
+replica.restart()
+
+replica.admin('box.space.test:select()')
+replica.stop()
+replica.cleanup(True)
+
+print '-------------------------------------------------------------'
+print 'replica test 2 (must be ok)'
+print '-------------------------------------------------------------'
+
+master.restart()
+master.admin('for k = 10, 19 do box.space[42]:insert{k, k*k*k} end')
+master.admin("for k = 20, 29 do box.space[42]:upsert({k}, {}) end")
+lsn = master.get_lsn(master_id)
+
+replica = TarantoolServer(server.ini)
+replica.script = 'replication/replica.lua'
+replica.vardir = server.vardir #os.path.join(server.vardir, 'replica')
+replica.rpl_master = master
+replica.deploy()
+
+replica.admin('space = box.space.test');
+replica.wait_lsn(master_id, lsn)
+for i in range(1, 20):
+ replica.admin('space:get{%d}' % i)
+
+replica.stop()
+replica.cleanup(True)
+
+print '-------------------------------------------------------------'
+print 'reconnect on JOIN/SUBSCRIBE'
+print '-------------------------------------------------------------'
+
+server.stop()
+replica = TarantoolServer(server.ini)
+replica.script = 'replication/replica.lua'
+replica.vardir = server.vardir #os.path.join(server.vardir, 'replica')
+replica.rpl_master = master
+replica.deploy(wait=False)
+
+print 'waiting reconnect on JOIN...'
+server.start()
+replica.wait_until_started()
+print 'ok'
+
+replica.stop()
+server.stop()
+
+print 'waiting reconnect on SUBSCRIBE...'
+replica.start(wait=False)
+server.start()
+replica.wait_until_started()
+print 'ok'
+
+replica.stop()
+replica.cleanup(True)
+
+server.stop()
+server.deploy()
blob - /dev/null
blob + 814ff8206e9c2303fb2c126c5074f3faf1b941fa (mode 644)
--- /dev/null
+++ test/replication-py/master.lua
+#!/usr/bin/env tarantool
+os = require('os')
+box.cfg({
+ listen = os.getenv("LISTEN"),
+ slab_alloc_arena = 0.1,
+})
+
+require('console').listen(os.getenv('ADMIN'))
blob - /dev/null
blob + 6b392325d21d8bb7fb45986d0ee853342c4be5ac (mode 644)
--- /dev/null
+++ test/replication-py/multi.result
+fiber = require('fiber')
+---
+...
+box.schema.user.grant('guest', 'replication')
+---
+...
+box.schema.user.grant('guest', 'execute', 'universe')
+---
+...
+----------------------------------------------------------------------
+Bootstrap replicas
+----------------------------------------------------------------------
+done
+----------------------------------------------------------------------
+Make a full mesh
+----------------------------------------------------------------------
+server 1 connected
+server 1 connected
+server 1 connected
+box.info.vclock
+---
+- - 4
+ - 0
+ - 0
+...
+server 2 connected
+server 2 connected
+server 2 connected
+box.info.vclock
+---
+- - 4
+ - 0
+ - 0
+...
+server 3 connected
+server 3 connected
+server 3 connected
+box.info.vclock
+---
+- - 4
+ - 0
+ - 0
+...
+done
+----------------------------------------------------------------------
+Test inserts
+----------------------------------------------------------------------
+Create a test space
+_ = box.schema.space.create('test')
+---
+...
+_ = box.space.test:create_index('primary')
+---
+...
+server 1 is ok
+server 2 is ok
+server 3 is ok
+
+Insert records
+inserted 60 records
+
+Synchronize
+server 3 done
+server 3 done
+server 3 done
+done
+
+Check data
+server 1 is ok
+server 2 is ok
+server 3 is ok
+Done
+
+
+----------------------------------------------------------------------
+Cleanup
+----------------------------------------------------------------------
+server 1 done
+server 2 done
+server 3 done
+
blob - /dev/null
blob + 6a564d9967b626d95feb8445f68a426b99568c97 (mode 644)
--- /dev/null
+++ test/replication-py/multi.test.py
+import sys
+import os
+from lib.tarantool_server import TarantoolServer
+import yaml
+
+REPLICA_N = 3
+ROW_N = REPLICA_N * 20
+
+##
+
+# master server
+master = server
+master.admin("fiber = require('fiber')")
+master.admin("box.schema.user.grant('guest', 'replication')")
+master.admin("box.schema.user.grant('guest', 'execute', 'universe')")
+
+print '----------------------------------------------------------------------'
+print 'Bootstrap replicas'
+print '----------------------------------------------------------------------'
+
+# Start replicas
+master.id = master.get_param('server')['id']
+master_lsn = master.get_lsn(master.id)
+cluster = [ master ]
+for i in range(REPLICA_N - 1):
+ server = TarantoolServer(server.ini)
+ server.script = 'replication/replica.lua'
+ server.vardir = os.path.join(server.vardir, 'replica', str(master.id + i))
+ server.rpl_master = master
+ server.deploy()
+ # Wait replica to fully bootstrap.
+ # Otherwise can get ACCESS_DENIED error.
+ server.wait_lsn(master.id, master_lsn)
+ cluster.append(server)
+
+# Make a list of servers
+sources = []
+for server in cluster:
+ sources.append(yaml.load(server.admin('box.cfg.listen', silent = True))[0])
+ server.id = server.get_param('server')['id']
+
+print 'done'
+
+print '----------------------------------------------------------------------'
+print 'Make a full mesh'
+print '----------------------------------------------------------------------'
+
+# Connect each server to each other to make full mesh
+for server in cluster:
+ server.iproto.py_con.eval("box.cfg { replication_source = ... }", [sources])
+
+# Wait connections to establish
+for server in cluster:
+ for server2 in cluster:
+ server.iproto.py_con.eval("""
+ while #box.info.vclock[...] ~= nil do
+ fiber.sleep(0.01)
+ end;""", server2.id)
+ print 'server', server.id, "connected"
+ server.admin("box.info.vclock")
+
+print 'done'
+
+print '----------------------------------------------------------------------'
+print 'Test inserts'
+print '----------------------------------------------------------------------'
+
+print 'Create a test space'
+master.admin("_ = box.schema.space.create('test')")
+master.admin("_ = box.space.test:create_index('primary')")
+master_lsn = master.get_lsn(master.id)
+# Wait changes to propagate to replicas
+for server in cluster:
+ server.wait_lsn(master.id, master_lsn)
+ print 'server', server.id, 'is ok'
+print
+
+print 'Insert records'
+for i in range(ROW_N):
+ server = cluster[i % REPLICA_N]
+ server.admin("box.space.test:insert{%d, %s}" % (i, server.id), silent = True)
+print 'inserted %d records' % ROW_N
+print
+
+print 'Synchronize'
+for server1 in cluster:
+ for server2 in cluster:
+ server1.wait_lsn(server2.id, server2.get_lsn(server2.id))
+ print 'server', server.id, 'done'
+print 'done'
+print
+
+print 'Check data'
+for server in cluster:
+ cnt = yaml.load(server.admin("box.space.test:len()", silent = True))[0]
+ print 'server', server.id, 'is', cnt == ROW_N and 'ok' or 'not ok'
+print 'Done'
+print
+
+print
+print '----------------------------------------------------------------------'
+print 'Cleanup'
+print '----------------------------------------------------------------------'
+
+for server in cluster:
+ server.stop()
+ print 'server', server.id, 'done'
+print
+
+master.cleanup()
+master.deploy()
blob - /dev/null
blob + a7848717d0a7bcc1fcea98adc0807cef4fa23889 (mode 644)
--- /dev/null
+++ test/replication-py/readonly.result
+box.schema.user.grant('guest', 'replication')
+---
+...
+box.info.server.id
+---
+- 2
+...
+box.info.server.ro
+---
+- false
+...
+box.info.server.lsn
+---
+- 0
+...
+-------------------------------------------------------------
+replica is read-only until receive self server_id in _cluster
+-------------------------------------------------------------
+box.cfg{replication_source = ""}
+---
+...
+box.info.server.id
+---
+- 0
+...
+box.info.server.ro
+---
+- true
+...
+box.info.server.lsn
+---
+- -1
+...
+space = box.schema.space.create("ro")
+---
+- error: Can't modify data because this server is in read-only mode.
+...
+box.info.vclock[2]
+---
+- null
+...
blob - /dev/null
blob + 438a81862675ecaac859fd967c7aed89eff2eb01 (mode 644)
--- /dev/null
+++ test/replication-py/readonly.test.py
+import os
+from glob import iglob as glob
+from lib.tarantool_server import TarantoolServer
+
+# master server
+master = server
+master_id = master.get_param('server')['id']
+
+master.admin("box.schema.user.grant('guest', 'replication')")
+
+replica = TarantoolServer(server.ini)
+replica.script = 'replication/replica.lua'
+replica.vardir = server.vardir #os.path.join(server.vardir, 'replica')
+replica.rpl_master = master
+replica.deploy()
+replica.wait_lsn(master_id, master.get_lsn(master_id))
+replica_id = replica.get_param('server')['id']
+replica.admin('box.info.server.id')
+replica.admin('box.info.server.ro')
+replica.admin('box.info.server.lsn')
+replica.stop()
+
+print '-------------------------------------------------------------'
+print 'replica is read-only until receive self server_id in _cluster'
+print '-------------------------------------------------------------'
+
+# Remove xlog retrived by SUBSCRIBE
+filename = str(0).zfill(20) + ".xlog"
+wal = os.path.join(os.path.join(replica.vardir, replica.name), filename)
+os.remove(wal)
+
+# Start replica without master
+server.stop()
+replica.start()
+replica.admin('box.cfg{replication_source = ""}')
+
+# Check that replica in read-only mode
+replica.admin('box.info.server.id')
+replica.admin('box.info.server.ro')
+replica.admin('box.info.server.lsn')
+replica.admin('space = box.schema.space.create("ro")')
+replica.admin('box.info.vclock[%d]' % replica_id)
+
+replica.stop()
+replica.cleanup(True)
+server.deploy()
blob - /dev/null
blob + 3a08208e065f353d7999aebea94592b85e5133c5 (mode 644)
--- /dev/null
+++ test/replication-py/replica.lua
+#!/usr/bin/env tarantool
+
+box.cfg({
+ listen = os.getenv("LISTEN"),
+ replication_source = os.getenv("MASTER"),
+ slab_alloc_arena = 0.1,
+})
+
+require('console').listen(os.getenv('ADMIN'))
blob - /dev/null
blob + 792ebe9c8090f1d94405481d532cc288c0e989f5 (mode 644)
--- /dev/null
+++ test/replication-py/suite.ini
+[default]
+core = tarantool
+script = master.lua
+description = tarantool/box, replication
blob - /dev/null
blob + 84bacc69969560584eeb4a3efbe6768cf58f429c (mode 644)
--- /dev/null
+++ test/replication-py/swap.result
+box.schema.user.create('test', { password = 'pass123456'})
+---
+...
+box.schema.user.grant('test', 'read,write,execute', 'universe')
+---
+...
+while box.info.server.id == 0 do require('fiber').sleep(0.01) end
+---
+...
+while box.space['_priv']:len() < 1 do require('fiber').sleep(0.01) end
+---
+...
+s = box.schema.space.create('memtx', { engine = 'memtx'})
+---
+...
+index = s:create_index('primary', {type = 'tree'})
+---
+...
+s = box.schema.space.create('sophia', { engine = 'sophia'})
+---
+...
+index = s:create_index('primary', {type = 'tree'})
+---
+...
+test 0 iteration
+box.space.memtx:insert{0, "tuple 0"}
+-
+None
+box.space.memtx:insert{1, "tuple 1"}
+-
+None
+box.space.memtx:insert{2, "tuple 2"}
+-
+None
+box.space.memtx:insert{3, "tuple 3"}
+-
+None
+box.space.memtx:insert{4, "tuple 4"}
+-
+None
+box.space.sophia:insert{0, "tuple 0"}
+-
+None
+box.space.sophia:insert{1, "tuple 1"}
+-
+None
+box.space.sophia:insert{2, "tuple 2"}
+-
+None
+box.space.sophia:insert{3, "tuple 3"}
+-
+None
+box.space.sophia:insert{4, "tuple 4"}
+-
+None
+box.space.memtx:select{0}
+-
+- [0, tuple 0]
+
+box.space.memtx:select{1}
+-
+- [1, tuple 1]
+
+box.space.memtx:select{2}
+-
+- [2, tuple 2]
+
+box.space.memtx:select{3}
+-
+- [3, tuple 3]
+
+box.space.memtx:select{4}
+-
+- [4, tuple 4]
+
+box.space.sophia:select{0}
+-
+- [0, tuple 0]
+
+box.space.sophia:select{1}
+-
+- [1, tuple 1]
+
+box.space.sophia:select{2}
+-
+- [2, tuple 2]
+
+box.space.sophia:select{3}
+-
+- [3, tuple 3]
+
+box.space.sophia:select{4}
+-
+- [4, tuple 4]
+
+box.space.memtx:insert{5, "tuple 5"}
+-
+None
+box.space.memtx:insert{6, "tuple 6"}
+-
+None
+box.space.memtx:insert{7, "tuple 7"}
+-
+None
+box.space.memtx:insert{8, "tuple 8"}
+-
+None
+box.space.memtx:insert{9, "tuple 9"}
+-
+None
+box.space.sophia:insert{5, "tuple 5"}
+-
+None
+box.space.sophia:insert{6, "tuple 6"}
+-
+None
+box.space.sophia:insert{7, "tuple 7"}
+-
+None
+box.space.sophia:insert{8, "tuple 8"}
+-
+None
+box.space.sophia:insert{9, "tuple 9"}
+-
+None
+box.space.memtx:select{5}
+-
+- [5, tuple 5]
+
+box.space.memtx:select{6}
+-
+- [6, tuple 6]
+
+box.space.memtx:select{7}
+-
+- [7, tuple 7]
+
+box.space.memtx:select{8}
+-
+- [8, tuple 8]
+
+box.space.memtx:select{9}
+-
+- [9, tuple 9]
+
+box.space.sophia:select{5}
+-
+- [5, tuple 5]
+
+box.space.sophia:select{6}
+-
+- [6, tuple 6]
+
+box.space.sophia:select{7}
+-
+- [7, tuple 7]
+
+box.space.sophia:select{8}
+-
+- [8, tuple 8]
+
+box.space.sophia:select{9}
+-
+- [9, tuple 9]
+
+swap servers
+switch replica to master
+box.cfg{replication_source=''}
+---
+...
+switch master to replica
+box.space.memtx:insert{10, "tuple 10"}
+-
+None
+box.space.memtx:insert{11, "tuple 11"}
+-
+None
+box.space.memtx:insert{12, "tuple 12"}
+-
+None
+box.space.memtx:insert{13, "tuple 13"}
+-
+None
+box.space.memtx:insert{14, "tuple 14"}
+-
+None
+box.space.sophia:insert{10, "tuple 10"}
+-
+None
+box.space.sophia:insert{11, "tuple 11"}
+-
+None
+box.space.sophia:insert{12, "tuple 12"}
+-
+None
+box.space.sophia:insert{13, "tuple 13"}
+-
+None
+box.space.sophia:insert{14, "tuple 14"}
+-
+None
+box.space.memtx:select{10}
+-
+- [10, tuple 10]
+
+box.space.memtx:select{11}
+-
+- [11, tuple 11]
+
+box.space.memtx:select{12}
+-
+- [12, tuple 12]
+
+box.space.memtx:select{13}
+-
+- [13, tuple 13]
+
+box.space.memtx:select{14}
+-
+- [14, tuple 14]
+
+box.space.sophia:select{10}
+-
+- [10, tuple 10]
+
+box.space.sophia:select{11}
+-
+- [11, tuple 11]
+
+box.space.sophia:select{12}
+-
+- [12, tuple 12]
+
+box.space.sophia:select{13}
+-
+- [13, tuple 13]
+
+box.space.sophia:select{14}
+-
+- [14, tuple 14]
+
+box.space.memtx:insert{15, "tuple 15"}
+-
+None
+box.space.memtx:insert{16, "tuple 16"}
+-
+None
+box.space.memtx:insert{17, "tuple 17"}
+-
+None
+box.space.memtx:insert{18, "tuple 18"}
+-
+None
+box.space.memtx:insert{19, "tuple 19"}
+-
+None
+box.space.sophia:insert{15, "tuple 15"}
+-
+None
+box.space.sophia:insert{16, "tuple 16"}
+-
+None
+box.space.sophia:insert{17, "tuple 17"}
+-
+None
+box.space.sophia:insert{18, "tuple 18"}
+-
+None
+box.space.sophia:insert{19, "tuple 19"}
+-
+None
+box.space.memtx:select{15}
+-
+- [15, tuple 15]
+
+box.space.memtx:select{16}
+-
+- [16, tuple 16]
+
+box.space.memtx:select{17}
+-
+- [17, tuple 17]
+
+box.space.memtx:select{18}
+-
+- [18, tuple 18]
+
+box.space.memtx:select{19}
+-
+- [19, tuple 19]
+
+box.space.sophia:select{15}
+-
+- [15, tuple 15]
+
+box.space.sophia:select{16}
+-
+- [16, tuple 16]
+
+box.space.sophia:select{17}
+-
+- [17, tuple 17]
+
+box.space.sophia:select{18}
+-
+- [18, tuple 18]
+
+box.space.sophia:select{19}
+-
+- [19, tuple 19]
+
+rollback servers configuration
+switch master to master
+box.cfg{replication_source=''}
+---
+...
+switch replica to replica
+test 1 iteration
+box.space.memtx:insert{20, "tuple 20"}
+-
+None
+box.space.memtx:insert{21, "tuple 21"}
+-
+None
+box.space.memtx:insert{22, "tuple 22"}
+-
+None
+box.space.memtx:insert{23, "tuple 23"}
+-
+None
+box.space.memtx:insert{24, "tuple 24"}
+-
+None
+box.space.sophia:insert{20, "tuple 20"}
+-
+None
+box.space.sophia:insert{21, "tuple 21"}
+-
+None
+box.space.sophia:insert{22, "tuple 22"}
+-
+None
+box.space.sophia:insert{23, "tuple 23"}
+-
+None
+box.space.sophia:insert{24, "tuple 24"}
+-
+None
+box.space.memtx:select{20}
+-
+- [20, tuple 20]
+
+box.space.memtx:select{21}
+-
+- [21, tuple 21]
+
+box.space.memtx:select{22}
+-
+- [22, tuple 22]
+
+box.space.memtx:select{23}
+-
+- [23, tuple 23]
+
+box.space.memtx:select{24}
+-
+- [24, tuple 24]
+
+box.space.sophia:select{20}
+-
+- [20, tuple 20]
+
+box.space.sophia:select{21}
+-
+- [21, tuple 21]
+
+box.space.sophia:select{22}
+-
+- [22, tuple 22]
+
+box.space.sophia:select{23}
+-
+- [23, tuple 23]
+
+box.space.sophia:select{24}
+-
+- [24, tuple 24]
+
+box.space.memtx:insert{25, "tuple 25"}
+-
+None
+box.space.memtx:insert{26, "tuple 26"}
+-
+None
+box.space.memtx:insert{27, "tuple 27"}
+-
+None
+box.space.memtx:insert{28, "tuple 28"}
+-
+None
+box.space.memtx:insert{29, "tuple 29"}
+-
+None
+box.space.sophia:insert{25, "tuple 25"}
+-
+None
+box.space.sophia:insert{26, "tuple 26"}
+-
+None
+box.space.sophia:insert{27, "tuple 27"}
+-
+None
+box.space.sophia:insert{28, "tuple 28"}
+-
+None
+box.space.sophia:insert{29, "tuple 29"}
+-
+None
+box.space.memtx:select{25}
+-
+- [25, tuple 25]
+
+box.space.memtx:select{26}
+-
+- [26, tuple 26]
+
+box.space.memtx:select{27}
+-
+- [27, tuple 27]
+
+box.space.memtx:select{28}
+-
+- [28, tuple 28]
+
+box.space.memtx:select{29}
+-
+- [29, tuple 29]
+
+box.space.sophia:select{25}
+-
+- [25, tuple 25]
+
+box.space.sophia:select{26}
+-
+- [26, tuple 26]
+
+box.space.sophia:select{27}
+-
+- [27, tuple 27]
+
+box.space.sophia:select{28}
+-
+- [28, tuple 28]
+
+box.space.sophia:select{29}
+-
+- [29, tuple 29]
+
+swap servers
+switch replica to master
+box.cfg{replication_source=''}
+---
+...
+switch master to replica
+box.space.memtx:insert{30, "tuple 30"}
+-
+None
+box.space.memtx:insert{31, "tuple 31"}
+-
+None
+box.space.memtx:insert{32, "tuple 32"}
+-
+None
+box.space.memtx:insert{33, "tuple 33"}
+-
+None
+box.space.memtx:insert{34, "tuple 34"}
+-
+None
+box.space.sophia:insert{30, "tuple 30"}
+-
+None
+box.space.sophia:insert{31, "tuple 31"}
+-
+None
+box.space.sophia:insert{32, "tuple 32"}
+-
+None
+box.space.sophia:insert{33, "tuple 33"}
+-
+None
+box.space.sophia:insert{34, "tuple 34"}
+-
+None
+box.space.memtx:select{30}
+-
+- [30, tuple 30]
+
+box.space.memtx:select{31}
+-
+- [31, tuple 31]
+
+box.space.memtx:select{32}
+-
+- [32, tuple 32]
+
+box.space.memtx:select{33}
+-
+- [33, tuple 33]
+
+box.space.memtx:select{34}
+-
+- [34, tuple 34]
+
+box.space.sophia:select{30}
+-
+- [30, tuple 30]
+
+box.space.sophia:select{31}
+-
+- [31, tuple 31]
+
+box.space.sophia:select{32}
+-
+- [32, tuple 32]
+
+box.space.sophia:select{33}
+-
+- [33, tuple 33]
+
+box.space.sophia:select{34}
+-
+- [34, tuple 34]
+
+box.space.memtx:insert{35, "tuple 35"}
+-
+None
+box.space.memtx:insert{36, "tuple 36"}
+-
+None
+box.space.memtx:insert{37, "tuple 37"}
+-
+None
+box.space.memtx:insert{38, "tuple 38"}
+-
+None
+box.space.memtx:insert{39, "tuple 39"}
+-
+None
+box.space.sophia:insert{35, "tuple 35"}
+-
+None
+box.space.sophia:insert{36, "tuple 36"}
+-
+None
+box.space.sophia:insert{37, "tuple 37"}
+-
+None
+box.space.sophia:insert{38, "tuple 38"}
+-
+None
+box.space.sophia:insert{39, "tuple 39"}
+-
+None
+box.space.memtx:select{35}
+-
+- [35, tuple 35]
+
+box.space.memtx:select{36}
+-
+- [36, tuple 36]
+
+box.space.memtx:select{37}
+-
+- [37, tuple 37]
+
+box.space.memtx:select{38}
+-
+- [38, tuple 38]
+
+box.space.memtx:select{39}
+-
+- [39, tuple 39]
+
+box.space.sophia:select{35}
+-
+- [35, tuple 35]
+
+box.space.sophia:select{36}
+-
+- [36, tuple 36]
+
+box.space.sophia:select{37}
+-
+- [37, tuple 37]
+
+box.space.sophia:select{38}
+-
+- [38, tuple 38]
+
+box.space.sophia:select{39}
+-
+- [39, tuple 39]
+
+rollback servers configuration
+switch master to master
+box.cfg{replication_source=''}
+---
+...
+switch replica to replica
+test 2 iteration
+box.space.memtx:insert{40, "tuple 40"}
+-
+None
+box.space.memtx:insert{41, "tuple 41"}
+-
+None
+box.space.memtx:insert{42, "tuple 42"}
+-
+None
+box.space.memtx:insert{43, "tuple 43"}
+-
+None
+box.space.memtx:insert{44, "tuple 44"}
+-
+None
+box.space.sophia:insert{40, "tuple 40"}
+-
+None
+box.space.sophia:insert{41, "tuple 41"}
+-
+None
+box.space.sophia:insert{42, "tuple 42"}
+-
+None
+box.space.sophia:insert{43, "tuple 43"}
+-
+None
+box.space.sophia:insert{44, "tuple 44"}
+-
+None
+box.space.memtx:select{40}
+-
+- [40, tuple 40]
+
+box.space.memtx:select{41}
+-
+- [41, tuple 41]
+
+box.space.memtx:select{42}
+-
+- [42, tuple 42]
+
+box.space.memtx:select{43}
+-
+- [43, tuple 43]
+
+box.space.memtx:select{44}
+-
+- [44, tuple 44]
+
+box.space.sophia:select{40}
+-
+- [40, tuple 40]
+
+box.space.sophia:select{41}
+-
+- [41, tuple 41]
+
+box.space.sophia:select{42}
+-
+- [42, tuple 42]
+
+box.space.sophia:select{43}
+-
+- [43, tuple 43]
+
+box.space.sophia:select{44}
+-
+- [44, tuple 44]
+
+box.space.memtx:insert{45, "tuple 45"}
+-
+None
+box.space.memtx:insert{46, "tuple 46"}
+-
+None
+box.space.memtx:insert{47, "tuple 47"}
+-
+None
+box.space.memtx:insert{48, "tuple 48"}
+-
+None
+box.space.memtx:insert{49, "tuple 49"}
+-
+None
+box.space.sophia:insert{45, "tuple 45"}
+-
+None
+box.space.sophia:insert{46, "tuple 46"}
+-
+None
+box.space.sophia:insert{47, "tuple 47"}
+-
+None
+box.space.sophia:insert{48, "tuple 48"}
+-
+None
+box.space.sophia:insert{49, "tuple 49"}
+-
+None
+box.space.memtx:select{45}
+-
+- [45, tuple 45]
+
+box.space.memtx:select{46}
+-
+- [46, tuple 46]
+
+box.space.memtx:select{47}
+-
+- [47, tuple 47]
+
+box.space.memtx:select{48}
+-
+- [48, tuple 48]
+
+box.space.memtx:select{49}
+-
+- [49, tuple 49]
+
+box.space.sophia:select{45}
+-
+- [45, tuple 45]
+
+box.space.sophia:select{46}
+-
+- [46, tuple 46]
+
+box.space.sophia:select{47}
+-
+- [47, tuple 47]
+
+box.space.sophia:select{48}
+-
+- [48, tuple 48]
+
+box.space.sophia:select{49}
+-
+- [49, tuple 49]
+
+swap servers
+switch replica to master
+box.cfg{replication_source=''}
+---
+...
+switch master to replica
+box.space.memtx:insert{50, "tuple 50"}
+-
+None
+box.space.memtx:insert{51, "tuple 51"}
+-
+None
+box.space.memtx:insert{52, "tuple 52"}
+-
+None
+box.space.memtx:insert{53, "tuple 53"}
+-
+None
+box.space.memtx:insert{54, "tuple 54"}
+-
+None
+box.space.sophia:insert{50, "tuple 50"}
+-
+None
+box.space.sophia:insert{51, "tuple 51"}
+-
+None
+box.space.sophia:insert{52, "tuple 52"}
+-
+None
+box.space.sophia:insert{53, "tuple 53"}
+-
+None
+box.space.sophia:insert{54, "tuple 54"}
+-
+None
+box.space.memtx:select{50}
+-
+- [50, tuple 50]
+
+box.space.memtx:select{51}
+-
+- [51, tuple 51]
+
+box.space.memtx:select{52}
+-
+- [52, tuple 52]
+
+box.space.memtx:select{53}
+-
+- [53, tuple 53]
+
+box.space.memtx:select{54}
+-
+- [54, tuple 54]
+
+box.space.sophia:select{50}
+-
+- [50, tuple 50]
+
+box.space.sophia:select{51}
+-
+- [51, tuple 51]
+
+box.space.sophia:select{52}
+-
+- [52, tuple 52]
+
+box.space.sophia:select{53}
+-
+- [53, tuple 53]
+
+box.space.sophia:select{54}
+-
+- [54, tuple 54]
+
+box.space.memtx:insert{55, "tuple 55"}
+-
+None
+box.space.memtx:insert{56, "tuple 56"}
+-
+None
+box.space.memtx:insert{57, "tuple 57"}
+-
+None
+box.space.memtx:insert{58, "tuple 58"}
+-
+None
+box.space.memtx:insert{59, "tuple 59"}
+-
+None
+box.space.sophia:insert{55, "tuple 55"}
+-
+None
+box.space.sophia:insert{56, "tuple 56"}
+-
+None
+box.space.sophia:insert{57, "tuple 57"}
+-
+None
+box.space.sophia:insert{58, "tuple 58"}
+-
+None
+box.space.sophia:insert{59, "tuple 59"}
+-
+None
+box.space.memtx:select{55}
+-
+- [55, tuple 55]
+
+box.space.memtx:select{56}
+-
+- [56, tuple 56]
+
+box.space.memtx:select{57}
+-
+- [57, tuple 57]
+
+box.space.memtx:select{58}
+-
+- [58, tuple 58]
+
+box.space.memtx:select{59}
+-
+- [59, tuple 59]
+
+box.space.sophia:select{55}
+-
+- [55, tuple 55]
+
+box.space.sophia:select{56}
+-
+- [56, tuple 56]
+
+box.space.sophia:select{57}
+-
+- [57, tuple 57]
+
+box.space.sophia:select{58}
+-
+- [58, tuple 58]
+
+box.space.sophia:select{59}
+-
+- [59, tuple 59]
+
+rollback servers configuration
+switch master to master
+box.cfg{replication_source=''}
+---
+...
+switch replica to replica
+test 3 iteration
+box.space.memtx:insert{60, "tuple 60"}
+-
+None
+box.space.memtx:insert{61, "tuple 61"}
+-
+None
+box.space.memtx:insert{62, "tuple 62"}
+-
+None
+box.space.memtx:insert{63, "tuple 63"}
+-
+None
+box.space.memtx:insert{64, "tuple 64"}
+-
+None
+box.space.sophia:insert{60, "tuple 60"}
+-
+None
+box.space.sophia:insert{61, "tuple 61"}
+-
+None
+box.space.sophia:insert{62, "tuple 62"}
+-
+None
+box.space.sophia:insert{63, "tuple 63"}
+-
+None
+box.space.sophia:insert{64, "tuple 64"}
+-
+None
+box.space.memtx:select{60}
+-
+- [60, tuple 60]
+
+box.space.memtx:select{61}
+-
+- [61, tuple 61]
+
+box.space.memtx:select{62}
+-
+- [62, tuple 62]
+
+box.space.memtx:select{63}
+-
+- [63, tuple 63]
+
+box.space.memtx:select{64}
+-
+- [64, tuple 64]
+
+box.space.sophia:select{60}
+-
+- [60, tuple 60]
+
+box.space.sophia:select{61}
+-
+- [61, tuple 61]
+
+box.space.sophia:select{62}
+-
+- [62, tuple 62]
+
+box.space.sophia:select{63}
+-
+- [63, tuple 63]
+
+box.space.sophia:select{64}
+-
+- [64, tuple 64]
+
+box.space.memtx:insert{65, "tuple 65"}
+-
+None
+box.space.memtx:insert{66, "tuple 66"}
+-
+None
+box.space.memtx:insert{67, "tuple 67"}
+-
+None
+box.space.memtx:insert{68, "tuple 68"}
+-
+None
+box.space.memtx:insert{69, "tuple 69"}
+-
+None
+box.space.sophia:insert{65, "tuple 65"}
+-
+None
+box.space.sophia:insert{66, "tuple 66"}
+-
+None
+box.space.sophia:insert{67, "tuple 67"}
+-
+None
+box.space.sophia:insert{68, "tuple 68"}
+-
+None
+box.space.sophia:insert{69, "tuple 69"}
+-
+None
+box.space.memtx:select{65}
+-
+- [65, tuple 65]
+
+box.space.memtx:select{66}
+-
+- [66, tuple 66]
+
+box.space.memtx:select{67}
+-
+- [67, tuple 67]
+
+box.space.memtx:select{68}
+-
+- [68, tuple 68]
+
+box.space.memtx:select{69}
+-
+- [69, tuple 69]
+
+box.space.sophia:select{65}
+-
+- [65, tuple 65]
+
+box.space.sophia:select{66}
+-
+- [66, tuple 66]
+
+box.space.sophia:select{67}
+-
+- [67, tuple 67]
+
+box.space.sophia:select{68}
+-
+- [68, tuple 68]
+
+box.space.sophia:select{69}
+-
+- [69, tuple 69]
+
+swap servers
+switch replica to master
+box.cfg{replication_source=''}
+---
+...
+switch master to replica
+box.space.memtx:insert{70, "tuple 70"}
+-
+None
+box.space.memtx:insert{71, "tuple 71"}
+-
+None
+box.space.memtx:insert{72, "tuple 72"}
+-
+None
+box.space.memtx:insert{73, "tuple 73"}
+-
+None
+box.space.memtx:insert{74, "tuple 74"}
+-
+None
+box.space.sophia:insert{70, "tuple 70"}
+-
+None
+box.space.sophia:insert{71, "tuple 71"}
+-
+None
+box.space.sophia:insert{72, "tuple 72"}
+-
+None
+box.space.sophia:insert{73, "tuple 73"}
+-
+None
+box.space.sophia:insert{74, "tuple 74"}
+-
+None
+box.space.memtx:select{70}
+-
+- [70, tuple 70]
+
+box.space.memtx:select{71}
+-
+- [71, tuple 71]
+
+box.space.memtx:select{72}
+-
+- [72, tuple 72]
+
+box.space.memtx:select{73}
+-
+- [73, tuple 73]
+
+box.space.memtx:select{74}
+-
+- [74, tuple 74]
+
+box.space.sophia:select{70}
+-
+- [70, tuple 70]
+
+box.space.sophia:select{71}
+-
+- [71, tuple 71]
+
+box.space.sophia:select{72}
+-
+- [72, tuple 72]
+
+box.space.sophia:select{73}
+-
+- [73, tuple 73]
+
+box.space.sophia:select{74}
+-
+- [74, tuple 74]
+
+box.space.memtx:insert{75, "tuple 75"}
+-
+None
+box.space.memtx:insert{76, "tuple 76"}
+-
+None
+box.space.memtx:insert{77, "tuple 77"}
+-
+None
+box.space.memtx:insert{78, "tuple 78"}
+-
+None
+box.space.memtx:insert{79, "tuple 79"}
+-
+None
+box.space.sophia:insert{75, "tuple 75"}
+-
+None
+box.space.sophia:insert{76, "tuple 76"}
+-
+None
+box.space.sophia:insert{77, "tuple 77"}
+-
+None
+box.space.sophia:insert{78, "tuple 78"}
+-
+None
+box.space.sophia:insert{79, "tuple 79"}
+-
+None
+box.space.memtx:select{75}
+-
+- [75, tuple 75]
+
+box.space.memtx:select{76}
+-
+- [76, tuple 76]
+
+box.space.memtx:select{77}
+-
+- [77, tuple 77]
+
+box.space.memtx:select{78}
+-
+- [78, tuple 78]
+
+box.space.memtx:select{79}
+-
+- [79, tuple 79]
+
+box.space.sophia:select{75}
+-
+- [75, tuple 75]
+
+box.space.sophia:select{76}
+-
+- [76, tuple 76]
+
+box.space.sophia:select{77}
+-
+- [77, tuple 77]
+
+box.space.sophia:select{78}
+-
+- [78, tuple 78]
+
+box.space.sophia:select{79}
+-
+- [79, tuple 79]
+
+rollback servers configuration
+switch master to master
+box.cfg{replication_source=''}
+---
+...
+switch replica to replica
+test 4 iteration
+box.space.memtx:insert{80, "tuple 80"}
+-
+None
+box.space.memtx:insert{81, "tuple 81"}
+-
+None
+box.space.memtx:insert{82, "tuple 82"}
+-
+None
+box.space.memtx:insert{83, "tuple 83"}
+-
+None
+box.space.memtx:insert{84, "tuple 84"}
+-
+None
+box.space.sophia:insert{80, "tuple 80"}
+-
+None
+box.space.sophia:insert{81, "tuple 81"}
+-
+None
+box.space.sophia:insert{82, "tuple 82"}
+-
+None
+box.space.sophia:insert{83, "tuple 83"}
+-
+None
+box.space.sophia:insert{84, "tuple 84"}
+-
+None
+box.space.memtx:select{80}
+-
+- [80, tuple 80]
+
+box.space.memtx:select{81}
+-
+- [81, tuple 81]
+
+box.space.memtx:select{82}
+-
+- [82, tuple 82]
+
+box.space.memtx:select{83}
+-
+- [83, tuple 83]
+
+box.space.memtx:select{84}
+-
+- [84, tuple 84]
+
+box.space.sophia:select{80}
+-
+- [80, tuple 80]
+
+box.space.sophia:select{81}
+-
+- [81, tuple 81]
+
+box.space.sophia:select{82}
+-
+- [82, tuple 82]
+
+box.space.sophia:select{83}
+-
+- [83, tuple 83]
+
+box.space.sophia:select{84}
+-
+- [84, tuple 84]
+
+box.space.memtx:insert{85, "tuple 85"}
+-
+None
+box.space.memtx:insert{86, "tuple 86"}
+-
+None
+box.space.memtx:insert{87, "tuple 87"}
+-
+None
+box.space.memtx:insert{88, "tuple 88"}
+-
+None
+box.space.memtx:insert{89, "tuple 89"}
+-
+None
+box.space.sophia:insert{85, "tuple 85"}
+-
+None
+box.space.sophia:insert{86, "tuple 86"}
+-
+None
+box.space.sophia:insert{87, "tuple 87"}
+-
+None
+box.space.sophia:insert{88, "tuple 88"}
+-
+None
+box.space.sophia:insert{89, "tuple 89"}
+-
+None
+box.space.memtx:select{85}
+-
+- [85, tuple 85]
+
+box.space.memtx:select{86}
+-
+- [86, tuple 86]
+
+box.space.memtx:select{87}
+-
+- [87, tuple 87]
+
+box.space.memtx:select{88}
+-
+- [88, tuple 88]
+
+box.space.memtx:select{89}
+-
+- [89, tuple 89]
+
+box.space.sophia:select{85}
+-
+- [85, tuple 85]
+
+box.space.sophia:select{86}
+-
+- [86, tuple 86]
+
+box.space.sophia:select{87}
+-
+- [87, tuple 87]
+
+box.space.sophia:select{88}
+-
+- [88, tuple 88]
+
+box.space.sophia:select{89}
+-
+- [89, tuple 89]
+
+swap servers
+switch replica to master
+box.cfg{replication_source=''}
+---
+...
+switch master to replica
+box.space.memtx:insert{90, "tuple 90"}
+-
+None
+box.space.memtx:insert{91, "tuple 91"}
+-
+None
+box.space.memtx:insert{92, "tuple 92"}
+-
+None
+box.space.memtx:insert{93, "tuple 93"}
+-
+None
+box.space.memtx:insert{94, "tuple 94"}
+-
+None
+box.space.sophia:insert{90, "tuple 90"}
+-
+None
+box.space.sophia:insert{91, "tuple 91"}
+-
+None
+box.space.sophia:insert{92, "tuple 92"}
+-
+None
+box.space.sophia:insert{93, "tuple 93"}
+-
+None
+box.space.sophia:insert{94, "tuple 94"}
+-
+None
+box.space.memtx:select{90}
+-
+- [90, tuple 90]
+
+box.space.memtx:select{91}
+-
+- [91, tuple 91]
+
+box.space.memtx:select{92}
+-
+- [92, tuple 92]
+
+box.space.memtx:select{93}
+-
+- [93, tuple 93]
+
+box.space.memtx:select{94}
+-
+- [94, tuple 94]
+
+box.space.sophia:select{90}
+-
+- [90, tuple 90]
+
+box.space.sophia:select{91}
+-
+- [91, tuple 91]
+
+box.space.sophia:select{92}
+-
+- [92, tuple 92]
+
+box.space.sophia:select{93}
+-
+- [93, tuple 93]
+
+box.space.sophia:select{94}
+-
+- [94, tuple 94]
+
+box.space.memtx:insert{95, "tuple 95"}
+-
+None
+box.space.memtx:insert{96, "tuple 96"}
+-
+None
+box.space.memtx:insert{97, "tuple 97"}
+-
+None
+box.space.memtx:insert{98, "tuple 98"}
+-
+None
+box.space.memtx:insert{99, "tuple 99"}
+-
+None
+box.space.sophia:insert{95, "tuple 95"}
+-
+None
+box.space.sophia:insert{96, "tuple 96"}
+-
+None
+box.space.sophia:insert{97, "tuple 97"}
+-
+None
+box.space.sophia:insert{98, "tuple 98"}
+-
+None
+box.space.sophia:insert{99, "tuple 99"}
+-
+None
+box.space.memtx:select{95}
+-
+- [95, tuple 95]
+
+box.space.memtx:select{96}
+-
+- [96, tuple 96]
+
+box.space.memtx:select{97}
+-
+- [97, tuple 97]
+
+box.space.memtx:select{98}
+-
+- [98, tuple 98]
+
+box.space.memtx:select{99}
+-
+- [99, tuple 99]
+
+box.space.sophia:select{95}
+-
+- [95, tuple 95]
+
+box.space.sophia:select{96}
+-
+- [96, tuple 96]
+
+box.space.sophia:select{97}
+-
+- [97, tuple 97]
+
+box.space.sophia:select{98}
+-
+- [98, tuple 98]
+
+box.space.sophia:select{99}
+-
+- [99, tuple 99]
+
+rollback servers configuration
+switch master to master
+box.cfg{replication_source=''}
+---
+...
+switch replica to replica
+test 5 iteration
+box.space.memtx:insert{100, "tuple 100"}
+-
+None
+box.space.memtx:insert{101, "tuple 101"}
+-
+None
+box.space.memtx:insert{102, "tuple 102"}
+-
+None
+box.space.memtx:insert{103, "tuple 103"}
+-
+None
+box.space.memtx:insert{104, "tuple 104"}
+-
+None
+box.space.sophia:insert{100, "tuple 100"}
+-
+None
+box.space.sophia:insert{101, "tuple 101"}
+-
+None
+box.space.sophia:insert{102, "tuple 102"}
+-
+None
+box.space.sophia:insert{103, "tuple 103"}
+-
+None
+box.space.sophia:insert{104, "tuple 104"}
+-
+None
+box.space.memtx:select{100}
+-
+- [100, tuple 100]
+
+box.space.memtx:select{101}
+-
+- [101, tuple 101]
+
+box.space.memtx:select{102}
+-
+- [102, tuple 102]
+
+box.space.memtx:select{103}
+-
+- [103, tuple 103]
+
+box.space.memtx:select{104}
+-
+- [104, tuple 104]
+
+box.space.sophia:select{100}
+-
+- [100, tuple 100]
+
+box.space.sophia:select{101}
+-
+- [101, tuple 101]
+
+box.space.sophia:select{102}
+-
+- [102, tuple 102]
+
+box.space.sophia:select{103}
+-
+- [103, tuple 103]
+
+box.space.sophia:select{104}
+-
+- [104, tuple 104]
+
+box.space.memtx:insert{105, "tuple 105"}
+-
+None
+box.space.memtx:insert{106, "tuple 106"}
+-
+None
+box.space.memtx:insert{107, "tuple 107"}
+-
+None
+box.space.memtx:insert{108, "tuple 108"}
+-
+None
+box.space.memtx:insert{109, "tuple 109"}
+-
+None
+box.space.sophia:insert{105, "tuple 105"}
+-
+None
+box.space.sophia:insert{106, "tuple 106"}
+-
+None
+box.space.sophia:insert{107, "tuple 107"}
+-
+None
+box.space.sophia:insert{108, "tuple 108"}
+-
+None
+box.space.sophia:insert{109, "tuple 109"}
+-
+None
+box.space.memtx:select{105}
+-
+- [105, tuple 105]
+
+box.space.memtx:select{106}
+-
+- [106, tuple 106]
+
+box.space.memtx:select{107}
+-
+- [107, tuple 107]
+
+box.space.memtx:select{108}
+-
+- [108, tuple 108]
+
+box.space.memtx:select{109}
+-
+- [109, tuple 109]
+
+box.space.sophia:select{105}
+-
+- [105, tuple 105]
+
+box.space.sophia:select{106}
+-
+- [106, tuple 106]
+
+box.space.sophia:select{107}
+-
+- [107, tuple 107]
+
+box.space.sophia:select{108}
+-
+- [108, tuple 108]
+
+box.space.sophia:select{109}
+-
+- [109, tuple 109]
+
+swap servers
+switch replica to master
+box.cfg{replication_source=''}
+---
+...
+switch master to replica
+box.space.memtx:insert{110, "tuple 110"}
+-
+None
+box.space.memtx:insert{111, "tuple 111"}
+-
+None
+box.space.memtx:insert{112, "tuple 112"}
+-
+None
+box.space.memtx:insert{113, "tuple 113"}
+-
+None
+box.space.memtx:insert{114, "tuple 114"}
+-
+None
+box.space.sophia:insert{110, "tuple 110"}
+-
+None
+box.space.sophia:insert{111, "tuple 111"}
+-
+None
+box.space.sophia:insert{112, "tuple 112"}
+-
+None
+box.space.sophia:insert{113, "tuple 113"}
+-
+None
+box.space.sophia:insert{114, "tuple 114"}
+-
+None
+box.space.memtx:select{110}
+-
+- [110, tuple 110]
+
+box.space.memtx:select{111}
+-
+- [111, tuple 111]
+
+box.space.memtx:select{112}
+-
+- [112, tuple 112]
+
+box.space.memtx:select{113}
+-
+- [113, tuple 113]
+
+box.space.memtx:select{114}
+-
+- [114, tuple 114]
+
+box.space.sophia:select{110}
+-
+- [110, tuple 110]
+
+box.space.sophia:select{111}
+-
+- [111, tuple 111]
+
+box.space.sophia:select{112}
+-
+- [112, tuple 112]
+
+box.space.sophia:select{113}
+-
+- [113, tuple 113]
+
+box.space.sophia:select{114}
+-
+- [114, tuple 114]
+
+box.space.memtx:insert{115, "tuple 115"}
+-
+None
+box.space.memtx:insert{116, "tuple 116"}
+-
+None
+box.space.memtx:insert{117, "tuple 117"}
+-
+None
+box.space.memtx:insert{118, "tuple 118"}
+-
+None
+box.space.memtx:insert{119, "tuple 119"}
+-
+None
+box.space.sophia:insert{115, "tuple 115"}
+-
+None
+box.space.sophia:insert{116, "tuple 116"}
+-
+None
+box.space.sophia:insert{117, "tuple 117"}
+-
+None
+box.space.sophia:insert{118, "tuple 118"}
+-
+None
+box.space.sophia:insert{119, "tuple 119"}
+-
+None
+box.space.memtx:select{115}
+-
+- [115, tuple 115]
+
+box.space.memtx:select{116}
+-
+- [116, tuple 116]
+
+box.space.memtx:select{117}
+-
+- [117, tuple 117]
+
+box.space.memtx:select{118}
+-
+- [118, tuple 118]
+
+box.space.memtx:select{119}
+-
+- [119, tuple 119]
+
+box.space.sophia:select{115}
+-
+- [115, tuple 115]
+
+box.space.sophia:select{116}
+-
+- [116, tuple 116]
+
+box.space.sophia:select{117}
+-
+- [117, tuple 117]
+
+box.space.sophia:select{118}
+-
+- [118, tuple 118]
+
+box.space.sophia:select{119}
+-
+- [119, tuple 119]
+
+rollback servers configuration
+switch master to master
+box.cfg{replication_source=''}
+---
+...
+switch replica to replica
+test 6 iteration
+box.space.memtx:insert{120, "tuple 120"}
+-
+None
+box.space.memtx:insert{121, "tuple 121"}
+-
+None
+box.space.memtx:insert{122, "tuple 122"}
+-
+None
+box.space.memtx:insert{123, "tuple 123"}
+-
+None
+box.space.memtx:insert{124, "tuple 124"}
+-
+None
+box.space.sophia:insert{120, "tuple 120"}
+-
+None
+box.space.sophia:insert{121, "tuple 121"}
+-
+None
+box.space.sophia:insert{122, "tuple 122"}
+-
+None
+box.space.sophia:insert{123, "tuple 123"}
+-
+None
+box.space.sophia:insert{124, "tuple 124"}
+-
+None
+box.space.memtx:select{120}
+-
+- [120, tuple 120]
+
+box.space.memtx:select{121}
+-
+- [121, tuple 121]
+
+box.space.memtx:select{122}
+-
+- [122, tuple 122]
+
+box.space.memtx:select{123}
+-
+- [123, tuple 123]
+
+box.space.memtx:select{124}
+-
+- [124, tuple 124]
+
+box.space.sophia:select{120}
+-
+- [120, tuple 120]
+
+box.space.sophia:select{121}
+-
+- [121, tuple 121]
+
+box.space.sophia:select{122}
+-
+- [122, tuple 122]
+
+box.space.sophia:select{123}
+-
+- [123, tuple 123]
+
+box.space.sophia:select{124}
+-
+- [124, tuple 124]
+
+box.space.memtx:insert{125, "tuple 125"}
+-
+None
+box.space.memtx:insert{126, "tuple 126"}
+-
+None
+box.space.memtx:insert{127, "tuple 127"}
+-
+None
+box.space.memtx:insert{128, "tuple 128"}
+-
+None
+box.space.memtx:insert{129, "tuple 129"}
+-
+None
+box.space.sophia:insert{125, "tuple 125"}
+-
+None
+box.space.sophia:insert{126, "tuple 126"}
+-
+None
+box.space.sophia:insert{127, "tuple 127"}
+-
+None
+box.space.sophia:insert{128, "tuple 128"}
+-
+None
+box.space.sophia:insert{129, "tuple 129"}
+-
+None
+box.space.memtx:select{125}
+-
+- [125, tuple 125]
+
+box.space.memtx:select{126}
+-
+- [126, tuple 126]
+
+box.space.memtx:select{127}
+-
+- [127, tuple 127]
+
+box.space.memtx:select{128}
+-
+- [128, tuple 128]
+
+box.space.memtx:select{129}
+-
+- [129, tuple 129]
+
+box.space.sophia:select{125}
+-
+- [125, tuple 125]
+
+box.space.sophia:select{126}
+-
+- [126, tuple 126]
+
+box.space.sophia:select{127}
+-
+- [127, tuple 127]
+
+box.space.sophia:select{128}
+-
+- [128, tuple 128]
+
+box.space.sophia:select{129}
+-
+- [129, tuple 129]
+
+swap servers
+switch replica to master
+box.cfg{replication_source=''}
+---
+...
+switch master to replica
+box.space.memtx:insert{130, "tuple 130"}
+-
+None
+box.space.memtx:insert{131, "tuple 131"}
+-
+None
+box.space.memtx:insert{132, "tuple 132"}
+-
+None
+box.space.memtx:insert{133, "tuple 133"}
+-
+None
+box.space.memtx:insert{134, "tuple 134"}
+-
+None
+box.space.sophia:insert{130, "tuple 130"}
+-
+None
+box.space.sophia:insert{131, "tuple 131"}
+-
+None
+box.space.sophia:insert{132, "tuple 132"}
+-
+None
+box.space.sophia:insert{133, "tuple 133"}
+-
+None
+box.space.sophia:insert{134, "tuple 134"}
+-
+None
+box.space.memtx:select{130}
+-
+- [130, tuple 130]
+
+box.space.memtx:select{131}
+-
+- [131, tuple 131]
+
+box.space.memtx:select{132}
+-
+- [132, tuple 132]
+
+box.space.memtx:select{133}
+-
+- [133, tuple 133]
+
+box.space.memtx:select{134}
+-
+- [134, tuple 134]
+
+box.space.sophia:select{130}
+-
+- [130, tuple 130]
+
+box.space.sophia:select{131}
+-
+- [131, tuple 131]
+
+box.space.sophia:select{132}
+-
+- [132, tuple 132]
+
+box.space.sophia:select{133}
+-
+- [133, tuple 133]
+
+box.space.sophia:select{134}
+-
+- [134, tuple 134]
+
+box.space.memtx:insert{135, "tuple 135"}
+-
+None
+box.space.memtx:insert{136, "tuple 136"}
+-
+None
+box.space.memtx:insert{137, "tuple 137"}
+-
+None
+box.space.memtx:insert{138, "tuple 138"}
+-
+None
+box.space.memtx:insert{139, "tuple 139"}
+-
+None
+box.space.sophia:insert{135, "tuple 135"}
+-
+None
+box.space.sophia:insert{136, "tuple 136"}
+-
+None
+box.space.sophia:insert{137, "tuple 137"}
+-
+None
+box.space.sophia:insert{138, "tuple 138"}
+-
+None
+box.space.sophia:insert{139, "tuple 139"}
+-
+None
+box.space.memtx:select{135}
+-
+- [135, tuple 135]
+
+box.space.memtx:select{136}
+-
+- [136, tuple 136]
+
+box.space.memtx:select{137}
+-
+- [137, tuple 137]
+
+box.space.memtx:select{138}
+-
+- [138, tuple 138]
+
+box.space.memtx:select{139}
+-
+- [139, tuple 139]
+
+box.space.sophia:select{135}
+-
+- [135, tuple 135]
+
+box.space.sophia:select{136}
+-
+- [136, tuple 136]
+
+box.space.sophia:select{137}
+-
+- [137, tuple 137]
+
+box.space.sophia:select{138}
+-
+- [138, tuple 138]
+
+box.space.sophia:select{139}
+-
+- [139, tuple 139]
+
+rollback servers configuration
+switch master to master
+box.cfg{replication_source=''}
+---
+...
+switch replica to replica
+test 7 iteration
+box.space.memtx:insert{140, "tuple 140"}
+-
+None
+box.space.memtx:insert{141, "tuple 141"}
+-
+None
+box.space.memtx:insert{142, "tuple 142"}
+-
+None
+box.space.memtx:insert{143, "tuple 143"}
+-
+None
+box.space.memtx:insert{144, "tuple 144"}
+-
+None
+box.space.sophia:insert{140, "tuple 140"}
+-
+None
+box.space.sophia:insert{141, "tuple 141"}
+-
+None
+box.space.sophia:insert{142, "tuple 142"}
+-
+None
+box.space.sophia:insert{143, "tuple 143"}
+-
+None
+box.space.sophia:insert{144, "tuple 144"}
+-
+None
+box.space.memtx:select{140}
+-
+- [140, tuple 140]
+
+box.space.memtx:select{141}
+-
+- [141, tuple 141]
+
+box.space.memtx:select{142}
+-
+- [142, tuple 142]
+
+box.space.memtx:select{143}
+-
+- [143, tuple 143]
+
+box.space.memtx:select{144}
+-
+- [144, tuple 144]
+
+box.space.sophia:select{140}
+-
+- [140, tuple 140]
+
+box.space.sophia:select{141}
+-
+- [141, tuple 141]
+
+box.space.sophia:select{142}
+-
+- [142, tuple 142]
+
+box.space.sophia:select{143}
+-
+- [143, tuple 143]
+
+box.space.sophia:select{144}
+-
+- [144, tuple 144]
+
+box.space.memtx:insert{145, "tuple 145"}
+-
+None
+box.space.memtx:insert{146, "tuple 146"}
+-
+None
+box.space.memtx:insert{147, "tuple 147"}
+-
+None
+box.space.memtx:insert{148, "tuple 148"}
+-
+None
+box.space.memtx:insert{149, "tuple 149"}
+-
+None
+box.space.sophia:insert{145, "tuple 145"}
+-
+None
+box.space.sophia:insert{146, "tuple 146"}
+-
+None
+box.space.sophia:insert{147, "tuple 147"}
+-
+None
+box.space.sophia:insert{148, "tuple 148"}
+-
+None
+box.space.sophia:insert{149, "tuple 149"}
+-
+None
+box.space.memtx:select{145}
+-
+- [145, tuple 145]
+
+box.space.memtx:select{146}
+-
+- [146, tuple 146]
+
+box.space.memtx:select{147}
+-
+- [147, tuple 147]
+
+box.space.memtx:select{148}
+-
+- [148, tuple 148]
+
+box.space.memtx:select{149}
+-
+- [149, tuple 149]
+
+box.space.sophia:select{145}
+-
+- [145, tuple 145]
+
+box.space.sophia:select{146}
+-
+- [146, tuple 146]
+
+box.space.sophia:select{147}
+-
+- [147, tuple 147]
+
+box.space.sophia:select{148}
+-
+- [148, tuple 148]
+
+box.space.sophia:select{149}
+-
+- [149, tuple 149]
+
+swap servers
+switch replica to master
+box.cfg{replication_source=''}
+---
+...
+switch master to replica
+box.space.memtx:insert{150, "tuple 150"}
+-
+None
+box.space.memtx:insert{151, "tuple 151"}
+-
+None
+box.space.memtx:insert{152, "tuple 152"}
+-
+None
+box.space.memtx:insert{153, "tuple 153"}
+-
+None
+box.space.memtx:insert{154, "tuple 154"}
+-
+None
+box.space.sophia:insert{150, "tuple 150"}
+-
+None
+box.space.sophia:insert{151, "tuple 151"}
+-
+None
+box.space.sophia:insert{152, "tuple 152"}
+-
+None
+box.space.sophia:insert{153, "tuple 153"}
+-
+None
+box.space.sophia:insert{154, "tuple 154"}
+-
+None
+box.space.memtx:select{150}
+-
+- [150, tuple 150]
+
+box.space.memtx:select{151}
+-
+- [151, tuple 151]
+
+box.space.memtx:select{152}
+-
+- [152, tuple 152]
+
+box.space.memtx:select{153}
+-
+- [153, tuple 153]
+
+box.space.memtx:select{154}
+-
+- [154, tuple 154]
+
+box.space.sophia:select{150}
+-
+- [150, tuple 150]
+
+box.space.sophia:select{151}
+-
+- [151, tuple 151]
+
+box.space.sophia:select{152}
+-
+- [152, tuple 152]
+
+box.space.sophia:select{153}
+-
+- [153, tuple 153]
+
+box.space.sophia:select{154}
+-
+- [154, tuple 154]
+
+box.space.memtx:insert{155, "tuple 155"}
+-
+None
+box.space.memtx:insert{156, "tuple 156"}
+-
+None
+box.space.memtx:insert{157, "tuple 157"}
+-
+None
+box.space.memtx:insert{158, "tuple 158"}
+-
+None
+box.space.memtx:insert{159, "tuple 159"}
+-
+None
+box.space.sophia:insert{155, "tuple 155"}
+-
+None
+box.space.sophia:insert{156, "tuple 156"}
+-
+None
+box.space.sophia:insert{157, "tuple 157"}
+-
+None
+box.space.sophia:insert{158, "tuple 158"}
+-
+None
+box.space.sophia:insert{159, "tuple 159"}
+-
+None
+box.space.memtx:select{155}
+-
+- [155, tuple 155]
+
+box.space.memtx:select{156}
+-
+- [156, tuple 156]
+
+box.space.memtx:select{157}
+-
+- [157, tuple 157]
+
+box.space.memtx:select{158}
+-
+- [158, tuple 158]
+
+box.space.memtx:select{159}
+-
+- [159, tuple 159]
+
+box.space.sophia:select{155}
+-
+- [155, tuple 155]
+
+box.space.sophia:select{156}
+-
+- [156, tuple 156]
+
+box.space.sophia:select{157}
+-
+- [157, tuple 157]
+
+box.space.sophia:select{158}
+-
+- [158, tuple 158]
+
+box.space.sophia:select{159}
+-
+- [159, tuple 159]
+
+rollback servers configuration
+switch master to master
+box.cfg{replication_source=''}
+---
+...
+switch replica to replica
+test 8 iteration
+box.space.memtx:insert{160, "tuple 160"}
+-
+None
+box.space.memtx:insert{161, "tuple 161"}
+-
+None
+box.space.memtx:insert{162, "tuple 162"}
+-
+None
+box.space.memtx:insert{163, "tuple 163"}
+-
+None
+box.space.memtx:insert{164, "tuple 164"}
+-
+None
+box.space.sophia:insert{160, "tuple 160"}
+-
+None
+box.space.sophia:insert{161, "tuple 161"}
+-
+None
+box.space.sophia:insert{162, "tuple 162"}
+-
+None
+box.space.sophia:insert{163, "tuple 163"}
+-
+None
+box.space.sophia:insert{164, "tuple 164"}
+-
+None
+box.space.memtx:select{160}
+-
+- [160, tuple 160]
+
+box.space.memtx:select{161}
+-
+- [161, tuple 161]
+
+box.space.memtx:select{162}
+-
+- [162, tuple 162]
+
+box.space.memtx:select{163}
+-
+- [163, tuple 163]
+
+box.space.memtx:select{164}
+-
+- [164, tuple 164]
+
+box.space.sophia:select{160}
+-
+- [160, tuple 160]
+
+box.space.sophia:select{161}
+-
+- [161, tuple 161]
+
+box.space.sophia:select{162}
+-
+- [162, tuple 162]
+
+box.space.sophia:select{163}
+-
+- [163, tuple 163]
+
+box.space.sophia:select{164}
+-
+- [164, tuple 164]
+
+box.space.memtx:insert{165, "tuple 165"}
+-
+None
+box.space.memtx:insert{166, "tuple 166"}
+-
+None
+box.space.memtx:insert{167, "tuple 167"}
+-
+None
+box.space.memtx:insert{168, "tuple 168"}
+-
+None
+box.space.memtx:insert{169, "tuple 169"}
+-
+None
+box.space.sophia:insert{165, "tuple 165"}
+-
+None
+box.space.sophia:insert{166, "tuple 166"}
+-
+None
+box.space.sophia:insert{167, "tuple 167"}
+-
+None
+box.space.sophia:insert{168, "tuple 168"}
+-
+None
+box.space.sophia:insert{169, "tuple 169"}
+-
+None
+box.space.memtx:select{165}
+-
+- [165, tuple 165]
+
+box.space.memtx:select{166}
+-
+- [166, tuple 166]
+
+box.space.memtx:select{167}
+-
+- [167, tuple 167]
+
+box.space.memtx:select{168}
+-
+- [168, tuple 168]
+
+box.space.memtx:select{169}
+-
+- [169, tuple 169]
+
+box.space.sophia:select{165}
+-
+- [165, tuple 165]
+
+box.space.sophia:select{166}
+-
+- [166, tuple 166]
+
+box.space.sophia:select{167}
+-
+- [167, tuple 167]
+
+box.space.sophia:select{168}
+-
+- [168, tuple 168]
+
+box.space.sophia:select{169}
+-
+- [169, tuple 169]
+
+swap servers
+switch replica to master
+box.cfg{replication_source=''}
+---
+...
+switch master to replica
+box.space.memtx:insert{170, "tuple 170"}
+-
+None
+box.space.memtx:insert{171, "tuple 171"}
+-
+None
+box.space.memtx:insert{172, "tuple 172"}
+-
+None
+box.space.memtx:insert{173, "tuple 173"}
+-
+None
+box.space.memtx:insert{174, "tuple 174"}
+-
+None
+box.space.sophia:insert{170, "tuple 170"}
+-
+None
+box.space.sophia:insert{171, "tuple 171"}
+-
+None
+box.space.sophia:insert{172, "tuple 172"}
+-
+None
+box.space.sophia:insert{173, "tuple 173"}
+-
+None
+box.space.sophia:insert{174, "tuple 174"}
+-
+None
+box.space.memtx:select{170}
+-
+- [170, tuple 170]
+
+box.space.memtx:select{171}
+-
+- [171, tuple 171]
+
+box.space.memtx:select{172}
+-
+- [172, tuple 172]
+
+box.space.memtx:select{173}
+-
+- [173, tuple 173]
+
+box.space.memtx:select{174}
+-
+- [174, tuple 174]
+
+box.space.sophia:select{170}
+-
+- [170, tuple 170]
+
+box.space.sophia:select{171}
+-
+- [171, tuple 171]
+
+box.space.sophia:select{172}
+-
+- [172, tuple 172]
+
+box.space.sophia:select{173}
+-
+- [173, tuple 173]
+
+box.space.sophia:select{174}
+-
+- [174, tuple 174]
+
+box.space.memtx:insert{175, "tuple 175"}
+-
+None
+box.space.memtx:insert{176, "tuple 176"}
+-
+None
+box.space.memtx:insert{177, "tuple 177"}
+-
+None
+box.space.memtx:insert{178, "tuple 178"}
+-
+None
+box.space.memtx:insert{179, "tuple 179"}
+-
+None
+box.space.sophia:insert{175, "tuple 175"}
+-
+None
+box.space.sophia:insert{176, "tuple 176"}
+-
+None
+box.space.sophia:insert{177, "tuple 177"}
+-
+None
+box.space.sophia:insert{178, "tuple 178"}
+-
+None
+box.space.sophia:insert{179, "tuple 179"}
+-
+None
+box.space.memtx:select{175}
+-
+- [175, tuple 175]
+
+box.space.memtx:select{176}
+-
+- [176, tuple 176]
+
+box.space.memtx:select{177}
+-
+- [177, tuple 177]
+
+box.space.memtx:select{178}
+-
+- [178, tuple 178]
+
+box.space.memtx:select{179}
+-
+- [179, tuple 179]
+
+box.space.sophia:select{175}
+-
+- [175, tuple 175]
+
+box.space.sophia:select{176}
+-
+- [176, tuple 176]
+
+box.space.sophia:select{177}
+-
+- [177, tuple 177]
+
+box.space.sophia:select{178}
+-
+- [178, tuple 178]
+
+box.space.sophia:select{179}
+-
+- [179, tuple 179]
+
+rollback servers configuration
+switch master to master
+box.cfg{replication_source=''}
+---
+...
+switch replica to replica
+test 9 iteration
+box.space.memtx:insert{180, "tuple 180"}
+-
+None
+box.space.memtx:insert{181, "tuple 181"}
+-
+None
+box.space.memtx:insert{182, "tuple 182"}
+-
+None
+box.space.memtx:insert{183, "tuple 183"}
+-
+None
+box.space.memtx:insert{184, "tuple 184"}
+-
+None
+box.space.sophia:insert{180, "tuple 180"}
+-
+None
+box.space.sophia:insert{181, "tuple 181"}
+-
+None
+box.space.sophia:insert{182, "tuple 182"}
+-
+None
+box.space.sophia:insert{183, "tuple 183"}
+-
+None
+box.space.sophia:insert{184, "tuple 184"}
+-
+None
+box.space.memtx:select{180}
+-
+- [180, tuple 180]
+
+box.space.memtx:select{181}
+-
+- [181, tuple 181]
+
+box.space.memtx:select{182}
+-
+- [182, tuple 182]
+
+box.space.memtx:select{183}
+-
+- [183, tuple 183]
+
+box.space.memtx:select{184}
+-
+- [184, tuple 184]
+
+box.space.sophia:select{180}
+-
+- [180, tuple 180]
+
+box.space.sophia:select{181}
+-
+- [181, tuple 181]
+
+box.space.sophia:select{182}
+-
+- [182, tuple 182]
+
+box.space.sophia:select{183}
+-
+- [183, tuple 183]
+
+box.space.sophia:select{184}
+-
+- [184, tuple 184]
+
+box.space.memtx:insert{185, "tuple 185"}
+-
+None
+box.space.memtx:insert{186, "tuple 186"}
+-
+None
+box.space.memtx:insert{187, "tuple 187"}
+-
+None
+box.space.memtx:insert{188, "tuple 188"}
+-
+None
+box.space.memtx:insert{189, "tuple 189"}
+-
+None
+box.space.sophia:insert{185, "tuple 185"}
+-
+None
+box.space.sophia:insert{186, "tuple 186"}
+-
+None
+box.space.sophia:insert{187, "tuple 187"}
+-
+None
+box.space.sophia:insert{188, "tuple 188"}
+-
+None
+box.space.sophia:insert{189, "tuple 189"}
+-
+None
+box.space.memtx:select{185}
+-
+- [185, tuple 185]
+
+box.space.memtx:select{186}
+-
+- [186, tuple 186]
+
+box.space.memtx:select{187}
+-
+- [187, tuple 187]
+
+box.space.memtx:select{188}
+-
+- [188, tuple 188]
+
+box.space.memtx:select{189}
+-
+- [189, tuple 189]
+
+box.space.sophia:select{185}
+-
+- [185, tuple 185]
+
+box.space.sophia:select{186}
+-
+- [186, tuple 186]
+
+box.space.sophia:select{187}
+-
+- [187, tuple 187]
+
+box.space.sophia:select{188}
+-
+- [188, tuple 188]
+
+box.space.sophia:select{189}
+-
+- [189, tuple 189]
+
+swap servers
+switch replica to master
+box.cfg{replication_source=''}
+---
+...
+switch master to replica
+box.space.memtx:insert{190, "tuple 190"}
+-
+None
+box.space.memtx:insert{191, "tuple 191"}
+-
+None
+box.space.memtx:insert{192, "tuple 192"}
+-
+None
+box.space.memtx:insert{193, "tuple 193"}
+-
+None
+box.space.memtx:insert{194, "tuple 194"}
+-
+None
+box.space.sophia:insert{190, "tuple 190"}
+-
+None
+box.space.sophia:insert{191, "tuple 191"}
+-
+None
+box.space.sophia:insert{192, "tuple 192"}
+-
+None
+box.space.sophia:insert{193, "tuple 193"}
+-
+None
+box.space.sophia:insert{194, "tuple 194"}
+-
+None
+box.space.memtx:select{190}
+-
+- [190, tuple 190]
+
+box.space.memtx:select{191}
+-
+- [191, tuple 191]
+
+box.space.memtx:select{192}
+-
+- [192, tuple 192]
+
+box.space.memtx:select{193}
+-
+- [193, tuple 193]
+
+box.space.memtx:select{194}
+-
+- [194, tuple 194]
+
+box.space.sophia:select{190}
+-
+- [190, tuple 190]
+
+box.space.sophia:select{191}
+-
+- [191, tuple 191]
+
+box.space.sophia:select{192}
+-
+- [192, tuple 192]
+
+box.space.sophia:select{193}
+-
+- [193, tuple 193]
+
+box.space.sophia:select{194}
+-
+- [194, tuple 194]
+
+box.space.memtx:insert{195, "tuple 195"}
+-
+None
+box.space.memtx:insert{196, "tuple 196"}
+-
+None
+box.space.memtx:insert{197, "tuple 197"}
+-
+None
+box.space.memtx:insert{198, "tuple 198"}
+-
+None
+box.space.memtx:insert{199, "tuple 199"}
+-
+None
+box.space.sophia:insert{195, "tuple 195"}
+-
+None
+box.space.sophia:insert{196, "tuple 196"}
+-
+None
+box.space.sophia:insert{197, "tuple 197"}
+-
+None
+box.space.sophia:insert{198, "tuple 198"}
+-
+None
+box.space.sophia:insert{199, "tuple 199"}
+-
+None
+box.space.memtx:select{195}
+-
+- [195, tuple 195]
+
+box.space.memtx:select{196}
+-
+- [196, tuple 196]
+
+box.space.memtx:select{197}
+-
+- [197, tuple 197]
+
+box.space.memtx:select{198}
+-
+- [198, tuple 198]
+
+box.space.memtx:select{199}
+-
+- [199, tuple 199]
+
+box.space.sophia:select{195}
+-
+- [195, tuple 195]
+
+box.space.sophia:select{196}
+-
+- [196, tuple 196]
+
+box.space.sophia:select{197}
+-
+- [197, tuple 197]
+
+box.space.sophia:select{198}
+-
+- [198, tuple 198]
+
+box.space.sophia:select{199}
+-
+- [199, tuple 199]
+
+rollback servers configuration
+switch master to master
+box.cfg{replication_source=''}
+---
+...
+switch replica to replica
+test 10 iteration
+box.space.memtx:insert{200, "tuple 200"}
+-
+None
+box.space.memtx:insert{201, "tuple 201"}
+-
+None
+box.space.memtx:insert{202, "tuple 202"}
+-
+None
+box.space.memtx:insert{203, "tuple 203"}
+-
+None
+box.space.memtx:insert{204, "tuple 204"}
+-
+None
+box.space.sophia:insert{200, "tuple 200"}
+-
+None
+box.space.sophia:insert{201, "tuple 201"}
+-
+None
+box.space.sophia:insert{202, "tuple 202"}
+-
+None
+box.space.sophia:insert{203, "tuple 203"}
+-
+None
+box.space.sophia:insert{204, "tuple 204"}
+-
+None
+box.space.memtx:select{200}
+-
+- [200, tuple 200]
+
+box.space.memtx:select{201}
+-
+- [201, tuple 201]
+
+box.space.memtx:select{202}
+-
+- [202, tuple 202]
+
+box.space.memtx:select{203}
+-
+- [203, tuple 203]
+
+box.space.memtx:select{204}
+-
+- [204, tuple 204]
+
+box.space.sophia:select{200}
+-
+- [200, tuple 200]
+
+box.space.sophia:select{201}
+-
+- [201, tuple 201]
+
+box.space.sophia:select{202}
+-
+- [202, tuple 202]
+
+box.space.sophia:select{203}
+-
+- [203, tuple 203]
+
+box.space.sophia:select{204}
+-
+- [204, tuple 204]
+
+box.space.memtx:insert{205, "tuple 205"}
+-
+None
+box.space.memtx:insert{206, "tuple 206"}
+-
+None
+box.space.memtx:insert{207, "tuple 207"}
+-
+None
+box.space.memtx:insert{208, "tuple 208"}
+-
+None
+box.space.memtx:insert{209, "tuple 209"}
+-
+None
+box.space.sophia:insert{205, "tuple 205"}
+-
+None
+box.space.sophia:insert{206, "tuple 206"}
+-
+None
+box.space.sophia:insert{207, "tuple 207"}
+-
+None
+box.space.sophia:insert{208, "tuple 208"}
+-
+None
+box.space.sophia:insert{209, "tuple 209"}
+-
+None
+box.space.memtx:select{205}
+-
+- [205, tuple 205]
+
+box.space.memtx:select{206}
+-
+- [206, tuple 206]
+
+box.space.memtx:select{207}
+-
+- [207, tuple 207]
+
+box.space.memtx:select{208}
+-
+- [208, tuple 208]
+
+box.space.memtx:select{209}
+-
+- [209, tuple 209]
+
+box.space.sophia:select{205}
+-
+- [205, tuple 205]
+
+box.space.sophia:select{206}
+-
+- [206, tuple 206]
+
+box.space.sophia:select{207}
+-
+- [207, tuple 207]
+
+box.space.sophia:select{208}
+-
+- [208, tuple 208]
+
+box.space.sophia:select{209}
+-
+- [209, tuple 209]
+
+swap servers
+switch replica to master
+box.cfg{replication_source=''}
+---
+...
+switch master to replica
+box.space.memtx:insert{210, "tuple 210"}
+-
+None
+box.space.memtx:insert{211, "tuple 211"}
+-
+None
+box.space.memtx:insert{212, "tuple 212"}
+-
+None
+box.space.memtx:insert{213, "tuple 213"}
+-
+None
+box.space.memtx:insert{214, "tuple 214"}
+-
+None
+box.space.sophia:insert{210, "tuple 210"}
+-
+None
+box.space.sophia:insert{211, "tuple 211"}
+-
+None
+box.space.sophia:insert{212, "tuple 212"}
+-
+None
+box.space.sophia:insert{213, "tuple 213"}
+-
+None
+box.space.sophia:insert{214, "tuple 214"}
+-
+None
+box.space.memtx:select{210}
+-
+- [210, tuple 210]
+
+box.space.memtx:select{211}
+-
+- [211, tuple 211]
+
+box.space.memtx:select{212}
+-
+- [212, tuple 212]
+
+box.space.memtx:select{213}
+-
+- [213, tuple 213]
+
+box.space.memtx:select{214}
+-
+- [214, tuple 214]
+
+box.space.sophia:select{210}
+-
+- [210, tuple 210]
+
+box.space.sophia:select{211}
+-
+- [211, tuple 211]
+
+box.space.sophia:select{212}
+-
+- [212, tuple 212]
+
+box.space.sophia:select{213}
+-
+- [213, tuple 213]
+
+box.space.sophia:select{214}
+-
+- [214, tuple 214]
+
+box.space.memtx:insert{215, "tuple 215"}
+-
+None
+box.space.memtx:insert{216, "tuple 216"}
+-
+None
+box.space.memtx:insert{217, "tuple 217"}
+-
+None
+box.space.memtx:insert{218, "tuple 218"}
+-
+None
+box.space.memtx:insert{219, "tuple 219"}
+-
+None
+box.space.sophia:insert{215, "tuple 215"}
+-
+None
+box.space.sophia:insert{216, "tuple 216"}
+-
+None
+box.space.sophia:insert{217, "tuple 217"}
+-
+None
+box.space.sophia:insert{218, "tuple 218"}
+-
+None
+box.space.sophia:insert{219, "tuple 219"}
+-
+None
+box.space.memtx:select{215}
+-
+- [215, tuple 215]
+
+box.space.memtx:select{216}
+-
+- [216, tuple 216]
+
+box.space.memtx:select{217}
+-
+- [217, tuple 217]
+
+box.space.memtx:select{218}
+-
+- [218, tuple 218]
+
+box.space.memtx:select{219}
+-
+- [219, tuple 219]
+
+box.space.sophia:select{215}
+-
+- [215, tuple 215]
+
+box.space.sophia:select{216}
+-
+- [216, tuple 216]
+
+box.space.sophia:select{217}
+-
+- [217, tuple 217]
+
+box.space.sophia:select{218}
+-
+- [218, tuple 218]
+
+box.space.sophia:select{219}
+-
+- [219, tuple 219]
+
+rollback servers configuration
+switch master to master
+box.cfg{replication_source=''}
+---
+...
+switch replica to replica
+test 11 iteration
+box.space.memtx:insert{220, "tuple 220"}
+-
+None
+box.space.memtx:insert{221, "tuple 221"}
+-
+None
+box.space.memtx:insert{222, "tuple 222"}
+-
+None
+box.space.memtx:insert{223, "tuple 223"}
+-
+None
+box.space.memtx:insert{224, "tuple 224"}
+-
+None
+box.space.sophia:insert{220, "tuple 220"}
+-
+None
+box.space.sophia:insert{221, "tuple 221"}
+-
+None
+box.space.sophia:insert{222, "tuple 222"}
+-
+None
+box.space.sophia:insert{223, "tuple 223"}
+-
+None
+box.space.sophia:insert{224, "tuple 224"}
+-
+None
+box.space.memtx:select{220}
+-
+- [220, tuple 220]
+
+box.space.memtx:select{221}
+-
+- [221, tuple 221]
+
+box.space.memtx:select{222}
+-
+- [222, tuple 222]
+
+box.space.memtx:select{223}
+-
+- [223, tuple 223]
+
+box.space.memtx:select{224}
+-
+- [224, tuple 224]
+
+box.space.sophia:select{220}
+-
+- [220, tuple 220]
+
+box.space.sophia:select{221}
+-
+- [221, tuple 221]
+
+box.space.sophia:select{222}
+-
+- [222, tuple 222]
+
+box.space.sophia:select{223}
+-
+- [223, tuple 223]
+
+box.space.sophia:select{224}
+-
+- [224, tuple 224]
+
+box.space.memtx:insert{225, "tuple 225"}
+-
+None
+box.space.memtx:insert{226, "tuple 226"}
+-
+None
+box.space.memtx:insert{227, "tuple 227"}
+-
+None
+box.space.memtx:insert{228, "tuple 228"}
+-
+None
+box.space.memtx:insert{229, "tuple 229"}
+-
+None
+box.space.sophia:insert{225, "tuple 225"}
+-
+None
+box.space.sophia:insert{226, "tuple 226"}
+-
+None
+box.space.sophia:insert{227, "tuple 227"}
+-
+None
+box.space.sophia:insert{228, "tuple 228"}
+-
+None
+box.space.sophia:insert{229, "tuple 229"}
+-
+None
+box.space.memtx:select{225}
+-
+- [225, tuple 225]
+
+box.space.memtx:select{226}
+-
+- [226, tuple 226]
+
+box.space.memtx:select{227}
+-
+- [227, tuple 227]
+
+box.space.memtx:select{228}
+-
+- [228, tuple 228]
+
+box.space.memtx:select{229}
+-
+- [229, tuple 229]
+
+box.space.sophia:select{225}
+-
+- [225, tuple 225]
+
+box.space.sophia:select{226}
+-
+- [226, tuple 226]
+
+box.space.sophia:select{227}
+-
+- [227, tuple 227]
+
+box.space.sophia:select{228}
+-
+- [228, tuple 228]
+
+box.space.sophia:select{229}
+-
+- [229, tuple 229]
+
+swap servers
+switch replica to master
+box.cfg{replication_source=''}
+---
+...
+switch master to replica
+box.space.memtx:insert{230, "tuple 230"}
+-
+None
+box.space.memtx:insert{231, "tuple 231"}
+-
+None
+box.space.memtx:insert{232, "tuple 232"}
+-
+None
+box.space.memtx:insert{233, "tuple 233"}
+-
+None
+box.space.memtx:insert{234, "tuple 234"}
+-
+None
+box.space.sophia:insert{230, "tuple 230"}
+-
+None
+box.space.sophia:insert{231, "tuple 231"}
+-
+None
+box.space.sophia:insert{232, "tuple 232"}
+-
+None
+box.space.sophia:insert{233, "tuple 233"}
+-
+None
+box.space.sophia:insert{234, "tuple 234"}
+-
+None
+box.space.memtx:select{230}
+-
+- [230, tuple 230]
+
+box.space.memtx:select{231}
+-
+- [231, tuple 231]
+
+box.space.memtx:select{232}
+-
+- [232, tuple 232]
+
+box.space.memtx:select{233}
+-
+- [233, tuple 233]
+
+box.space.memtx:select{234}
+-
+- [234, tuple 234]
+
+box.space.sophia:select{230}
+-
+- [230, tuple 230]
+
+box.space.sophia:select{231}
+-
+- [231, tuple 231]
+
+box.space.sophia:select{232}
+-
+- [232, tuple 232]
+
+box.space.sophia:select{233}
+-
+- [233, tuple 233]
+
+box.space.sophia:select{234}
+-
+- [234, tuple 234]
+
+box.space.memtx:insert{235, "tuple 235"}
+-
+None
+box.space.memtx:insert{236, "tuple 236"}
+-
+None
+box.space.memtx:insert{237, "tuple 237"}
+-
+None
+box.space.memtx:insert{238, "tuple 238"}
+-
+None
+box.space.memtx:insert{239, "tuple 239"}
+-
+None
+box.space.sophia:insert{235, "tuple 235"}
+-
+None
+box.space.sophia:insert{236, "tuple 236"}
+-
+None
+box.space.sophia:insert{237, "tuple 237"}
+-
+None
+box.space.sophia:insert{238, "tuple 238"}
+-
+None
+box.space.sophia:insert{239, "tuple 239"}
+-
+None
+box.space.memtx:select{235}
+-
+- [235, tuple 235]
+
+box.space.memtx:select{236}
+-
+- [236, tuple 236]
+
+box.space.memtx:select{237}
+-
+- [237, tuple 237]
+
+box.space.memtx:select{238}
+-
+- [238, tuple 238]
+
+box.space.memtx:select{239}
+-
+- [239, tuple 239]
+
+box.space.sophia:select{235}
+-
+- [235, tuple 235]
+
+box.space.sophia:select{236}
+-
+- [236, tuple 236]
+
+box.space.sophia:select{237}
+-
+- [237, tuple 237]
+
+box.space.sophia:select{238}
+-
+- [238, tuple 238]
+
+box.space.sophia:select{239}
+-
+- [239, tuple 239]
+
+rollback servers configuration
+switch master to master
+box.cfg{replication_source=''}
+---
+...
+switch replica to replica
+test 12 iteration
+box.space.memtx:insert{240, "tuple 240"}
+-
+None
+box.space.memtx:insert{241, "tuple 241"}
+-
+None
+box.space.memtx:insert{242, "tuple 242"}
+-
+None
+box.space.memtx:insert{243, "tuple 243"}
+-
+None
+box.space.memtx:insert{244, "tuple 244"}
+-
+None
+box.space.sophia:insert{240, "tuple 240"}
+-
+None
+box.space.sophia:insert{241, "tuple 241"}
+-
+None
+box.space.sophia:insert{242, "tuple 242"}
+-
+None
+box.space.sophia:insert{243, "tuple 243"}
+-
+None
+box.space.sophia:insert{244, "tuple 244"}
+-
+None
+box.space.memtx:select{240}
+-
+- [240, tuple 240]
+
+box.space.memtx:select{241}
+-
+- [241, tuple 241]
+
+box.space.memtx:select{242}
+-
+- [242, tuple 242]
+
+box.space.memtx:select{243}
+-
+- [243, tuple 243]
+
+box.space.memtx:select{244}
+-
+- [244, tuple 244]
+
+box.space.sophia:select{240}
+-
+- [240, tuple 240]
+
+box.space.sophia:select{241}
+-
+- [241, tuple 241]
+
+box.space.sophia:select{242}
+-
+- [242, tuple 242]
+
+box.space.sophia:select{243}
+-
+- [243, tuple 243]
+
+box.space.sophia:select{244}
+-
+- [244, tuple 244]
+
+box.space.memtx:insert{245, "tuple 245"}
+-
+None
+box.space.memtx:insert{246, "tuple 246"}
+-
+None
+box.space.memtx:insert{247, "tuple 247"}
+-
+None
+box.space.memtx:insert{248, "tuple 248"}
+-
+None
+box.space.memtx:insert{249, "tuple 249"}
+-
+None
+box.space.sophia:insert{245, "tuple 245"}
+-
+None
+box.space.sophia:insert{246, "tuple 246"}
+-
+None
+box.space.sophia:insert{247, "tuple 247"}
+-
+None
+box.space.sophia:insert{248, "tuple 248"}
+-
+None
+box.space.sophia:insert{249, "tuple 249"}
+-
+None
+box.space.memtx:select{245}
+-
+- [245, tuple 245]
+
+box.space.memtx:select{246}
+-
+- [246, tuple 246]
+
+box.space.memtx:select{247}
+-
+- [247, tuple 247]
+
+box.space.memtx:select{248}
+-
+- [248, tuple 248]
+
+box.space.memtx:select{249}
+-
+- [249, tuple 249]
+
+box.space.sophia:select{245}
+-
+- [245, tuple 245]
+
+box.space.sophia:select{246}
+-
+- [246, tuple 246]
+
+box.space.sophia:select{247}
+-
+- [247, tuple 247]
+
+box.space.sophia:select{248}
+-
+- [248, tuple 248]
+
+box.space.sophia:select{249}
+-
+- [249, tuple 249]
+
+swap servers
+switch replica to master
+box.cfg{replication_source=''}
+---
+...
+switch master to replica
+box.space.memtx:insert{250, "tuple 250"}
+-
+None
+box.space.memtx:insert{251, "tuple 251"}
+-
+None
+box.space.memtx:insert{252, "tuple 252"}
+-
+None
+box.space.memtx:insert{253, "tuple 253"}
+-
+None
+box.space.memtx:insert{254, "tuple 254"}
+-
+None
+box.space.sophia:insert{250, "tuple 250"}
+-
+None
+box.space.sophia:insert{251, "tuple 251"}
+-
+None
+box.space.sophia:insert{252, "tuple 252"}
+-
+None
+box.space.sophia:insert{253, "tuple 253"}
+-
+None
+box.space.sophia:insert{254, "tuple 254"}
+-
+None
+box.space.memtx:select{250}
+-
+- [250, tuple 250]
+
+box.space.memtx:select{251}
+-
+- [251, tuple 251]
+
+box.space.memtx:select{252}
+-
+- [252, tuple 252]
+
+box.space.memtx:select{253}
+-
+- [253, tuple 253]
+
+box.space.memtx:select{254}
+-
+- [254, tuple 254]
+
+box.space.sophia:select{250}
+-
+- [250, tuple 250]
+
+box.space.sophia:select{251}
+-
+- [251, tuple 251]
+
+box.space.sophia:select{252}
+-
+- [252, tuple 252]
+
+box.space.sophia:select{253}
+-
+- [253, tuple 253]
+
+box.space.sophia:select{254}
+-
+- [254, tuple 254]
+
+box.space.memtx:insert{255, "tuple 255"}
+-
+None
+box.space.memtx:insert{256, "tuple 256"}
+-
+None
+box.space.memtx:insert{257, "tuple 257"}
+-
+None
+box.space.memtx:insert{258, "tuple 258"}
+-
+None
+box.space.memtx:insert{259, "tuple 259"}
+-
+None
+box.space.sophia:insert{255, "tuple 255"}
+-
+None
+box.space.sophia:insert{256, "tuple 256"}
+-
+None
+box.space.sophia:insert{257, "tuple 257"}
+-
+None
+box.space.sophia:insert{258, "tuple 258"}
+-
+None
+box.space.sophia:insert{259, "tuple 259"}
+-
+None
+box.space.memtx:select{255}
+-
+- [255, tuple 255]
+
+box.space.memtx:select{256}
+-
+- [256, tuple 256]
+
+box.space.memtx:select{257}
+-
+- [257, tuple 257]
+
+box.space.memtx:select{258}
+-
+- [258, tuple 258]
+
+box.space.memtx:select{259}
+-
+- [259, tuple 259]
+
+box.space.sophia:select{255}
+-
+- [255, tuple 255]
+
+box.space.sophia:select{256}
+-
+- [256, tuple 256]
+
+box.space.sophia:select{257}
+-
+- [257, tuple 257]
+
+box.space.sophia:select{258}
+-
+- [258, tuple 258]
+
+box.space.sophia:select{259}
+-
+- [259, tuple 259]
+
+rollback servers configuration
+switch master to master
+box.cfg{replication_source=''}
+---
+...
+switch replica to replica
+test 13 iteration
+box.space.memtx:insert{260, "tuple 260"}
+-
+None
+box.space.memtx:insert{261, "tuple 261"}
+-
+None
+box.space.memtx:insert{262, "tuple 262"}
+-
+None
+box.space.memtx:insert{263, "tuple 263"}
+-
+None
+box.space.memtx:insert{264, "tuple 264"}
+-
+None
+box.space.sophia:insert{260, "tuple 260"}
+-
+None
+box.space.sophia:insert{261, "tuple 261"}
+-
+None
+box.space.sophia:insert{262, "tuple 262"}
+-
+None
+box.space.sophia:insert{263, "tuple 263"}
+-
+None
+box.space.sophia:insert{264, "tuple 264"}
+-
+None
+box.space.memtx:select{260}
+-
+- [260, tuple 260]
+
+box.space.memtx:select{261}
+-
+- [261, tuple 261]
+
+box.space.memtx:select{262}
+-
+- [262, tuple 262]
+
+box.space.memtx:select{263}
+-
+- [263, tuple 263]
+
+box.space.memtx:select{264}
+-
+- [264, tuple 264]
+
+box.space.sophia:select{260}
+-
+- [260, tuple 260]
+
+box.space.sophia:select{261}
+-
+- [261, tuple 261]
+
+box.space.sophia:select{262}
+-
+- [262, tuple 262]
+
+box.space.sophia:select{263}
+-
+- [263, tuple 263]
+
+box.space.sophia:select{264}
+-
+- [264, tuple 264]
+
+box.space.memtx:insert{265, "tuple 265"}
+-
+None
+box.space.memtx:insert{266, "tuple 266"}
+-
+None
+box.space.memtx:insert{267, "tuple 267"}
+-
+None
+box.space.memtx:insert{268, "tuple 268"}
+-
+None
+box.space.memtx:insert{269, "tuple 269"}
+-
+None
+box.space.sophia:insert{265, "tuple 265"}
+-
+None
+box.space.sophia:insert{266, "tuple 266"}
+-
+None
+box.space.sophia:insert{267, "tuple 267"}
+-
+None
+box.space.sophia:insert{268, "tuple 268"}
+-
+None
+box.space.sophia:insert{269, "tuple 269"}
+-
+None
+box.space.memtx:select{265}
+-
+- [265, tuple 265]
+
+box.space.memtx:select{266}
+-
+- [266, tuple 266]
+
+box.space.memtx:select{267}
+-
+- [267, tuple 267]
+
+box.space.memtx:select{268}
+-
+- [268, tuple 268]
+
+box.space.memtx:select{269}
+-
+- [269, tuple 269]
+
+box.space.sophia:select{265}
+-
+- [265, tuple 265]
+
+box.space.sophia:select{266}
+-
+- [266, tuple 266]
+
+box.space.sophia:select{267}
+-
+- [267, tuple 267]
+
+box.space.sophia:select{268}
+-
+- [268, tuple 268]
+
+box.space.sophia:select{269}
+-
+- [269, tuple 269]
+
+swap servers
+switch replica to master
+box.cfg{replication_source=''}
+---
+...
+switch master to replica
+box.space.memtx:insert{270, "tuple 270"}
+-
+None
+box.space.memtx:insert{271, "tuple 271"}
+-
+None
+box.space.memtx:insert{272, "tuple 272"}
+-
+None
+box.space.memtx:insert{273, "tuple 273"}
+-
+None
+box.space.memtx:insert{274, "tuple 274"}
+-
+None
+box.space.sophia:insert{270, "tuple 270"}
+-
+None
+box.space.sophia:insert{271, "tuple 271"}
+-
+None
+box.space.sophia:insert{272, "tuple 272"}
+-
+None
+box.space.sophia:insert{273, "tuple 273"}
+-
+None
+box.space.sophia:insert{274, "tuple 274"}
+-
+None
+box.space.memtx:select{270}
+-
+- [270, tuple 270]
+
+box.space.memtx:select{271}
+-
+- [271, tuple 271]
+
+box.space.memtx:select{272}
+-
+- [272, tuple 272]
+
+box.space.memtx:select{273}
+-
+- [273, tuple 273]
+
+box.space.memtx:select{274}
+-
+- [274, tuple 274]
+
+box.space.sophia:select{270}
+-
+- [270, tuple 270]
+
+box.space.sophia:select{271}
+-
+- [271, tuple 271]
+
+box.space.sophia:select{272}
+-
+- [272, tuple 272]
+
+box.space.sophia:select{273}
+-
+- [273, tuple 273]
+
+box.space.sophia:select{274}
+-
+- [274, tuple 274]
+
+box.space.memtx:insert{275, "tuple 275"}
+-
+None
+box.space.memtx:insert{276, "tuple 276"}
+-
+None
+box.space.memtx:insert{277, "tuple 277"}
+-
+None
+box.space.memtx:insert{278, "tuple 278"}
+-
+None
+box.space.memtx:insert{279, "tuple 279"}
+-
+None
+box.space.sophia:insert{275, "tuple 275"}
+-
+None
+box.space.sophia:insert{276, "tuple 276"}
+-
+None
+box.space.sophia:insert{277, "tuple 277"}
+-
+None
+box.space.sophia:insert{278, "tuple 278"}
+-
+None
+box.space.sophia:insert{279, "tuple 279"}
+-
+None
+box.space.memtx:select{275}
+-
+- [275, tuple 275]
+
+box.space.memtx:select{276}
+-
+- [276, tuple 276]
+
+box.space.memtx:select{277}
+-
+- [277, tuple 277]
+
+box.space.memtx:select{278}
+-
+- [278, tuple 278]
+
+box.space.memtx:select{279}
+-
+- [279, tuple 279]
+
+box.space.sophia:select{275}
+-
+- [275, tuple 275]
+
+box.space.sophia:select{276}
+-
+- [276, tuple 276]
+
+box.space.sophia:select{277}
+-
+- [277, tuple 277]
+
+box.space.sophia:select{278}
+-
+- [278, tuple 278]
+
+box.space.sophia:select{279}
+-
+- [279, tuple 279]
+
+rollback servers configuration
+switch master to master
+box.cfg{replication_source=''}
+---
+...
+switch replica to replica
+test 14 iteration
+box.space.memtx:insert{280, "tuple 280"}
+-
+None
+box.space.memtx:insert{281, "tuple 281"}
+-
+None
+box.space.memtx:insert{282, "tuple 282"}
+-
+None
+box.space.memtx:insert{283, "tuple 283"}
+-
+None
+box.space.memtx:insert{284, "tuple 284"}
+-
+None
+box.space.sophia:insert{280, "tuple 280"}
+-
+None
+box.space.sophia:insert{281, "tuple 281"}
+-
+None
+box.space.sophia:insert{282, "tuple 282"}
+-
+None
+box.space.sophia:insert{283, "tuple 283"}
+-
+None
+box.space.sophia:insert{284, "tuple 284"}
+-
+None
+box.space.memtx:select{280}
+-
+- [280, tuple 280]
+
+box.space.memtx:select{281}
+-
+- [281, tuple 281]
+
+box.space.memtx:select{282}
+-
+- [282, tuple 282]
+
+box.space.memtx:select{283}
+-
+- [283, tuple 283]
+
+box.space.memtx:select{284}
+-
+- [284, tuple 284]
+
+box.space.sophia:select{280}
+-
+- [280, tuple 280]
+
+box.space.sophia:select{281}
+-
+- [281, tuple 281]
+
+box.space.sophia:select{282}
+-
+- [282, tuple 282]
+
+box.space.sophia:select{283}
+-
+- [283, tuple 283]
+
+box.space.sophia:select{284}
+-
+- [284, tuple 284]
+
+box.space.memtx:insert{285, "tuple 285"}
+-
+None
+box.space.memtx:insert{286, "tuple 286"}
+-
+None
+box.space.memtx:insert{287, "tuple 287"}
+-
+None
+box.space.memtx:insert{288, "tuple 288"}
+-
+None
+box.space.memtx:insert{289, "tuple 289"}
+-
+None
+box.space.sophia:insert{285, "tuple 285"}
+-
+None
+box.space.sophia:insert{286, "tuple 286"}
+-
+None
+box.space.sophia:insert{287, "tuple 287"}
+-
+None
+box.space.sophia:insert{288, "tuple 288"}
+-
+None
+box.space.sophia:insert{289, "tuple 289"}
+-
+None
+box.space.memtx:select{285}
+-
+- [285, tuple 285]
+
+box.space.memtx:select{286}
+-
+- [286, tuple 286]
+
+box.space.memtx:select{287}
+-
+- [287, tuple 287]
+
+box.space.memtx:select{288}
+-
+- [288, tuple 288]
+
+box.space.memtx:select{289}
+-
+- [289, tuple 289]
+
+box.space.sophia:select{285}
+-
+- [285, tuple 285]
+
+box.space.sophia:select{286}
+-
+- [286, tuple 286]
+
+box.space.sophia:select{287}
+-
+- [287, tuple 287]
+
+box.space.sophia:select{288}
+-
+- [288, tuple 288]
+
+box.space.sophia:select{289}
+-
+- [289, tuple 289]
+
+swap servers
+switch replica to master
+box.cfg{replication_source=''}
+---
+...
+switch master to replica
+box.space.memtx:insert{290, "tuple 290"}
+-
+None
+box.space.memtx:insert{291, "tuple 291"}
+-
+None
+box.space.memtx:insert{292, "tuple 292"}
+-
+None
+box.space.memtx:insert{293, "tuple 293"}
+-
+None
+box.space.memtx:insert{294, "tuple 294"}
+-
+None
+box.space.sophia:insert{290, "tuple 290"}
+-
+None
+box.space.sophia:insert{291, "tuple 291"}
+-
+None
+box.space.sophia:insert{292, "tuple 292"}
+-
+None
+box.space.sophia:insert{293, "tuple 293"}
+-
+None
+box.space.sophia:insert{294, "tuple 294"}
+-
+None
+box.space.memtx:select{290}
+-
+- [290, tuple 290]
+
+box.space.memtx:select{291}
+-
+- [291, tuple 291]
+
+box.space.memtx:select{292}
+-
+- [292, tuple 292]
+
+box.space.memtx:select{293}
+-
+- [293, tuple 293]
+
+box.space.memtx:select{294}
+-
+- [294, tuple 294]
+
+box.space.sophia:select{290}
+-
+- [290, tuple 290]
+
+box.space.sophia:select{291}
+-
+- [291, tuple 291]
+
+box.space.sophia:select{292}
+-
+- [292, tuple 292]
+
+box.space.sophia:select{293}
+-
+- [293, tuple 293]
+
+box.space.sophia:select{294}
+-
+- [294, tuple 294]
+
+box.space.memtx:insert{295, "tuple 295"}
+-
+None
+box.space.memtx:insert{296, "tuple 296"}
+-
+None
+box.space.memtx:insert{297, "tuple 297"}
+-
+None
+box.space.memtx:insert{298, "tuple 298"}
+-
+None
+box.space.memtx:insert{299, "tuple 299"}
+-
+None
+box.space.sophia:insert{295, "tuple 295"}
+-
+None
+box.space.sophia:insert{296, "tuple 296"}
+-
+None
+box.space.sophia:insert{297, "tuple 297"}
+-
+None
+box.space.sophia:insert{298, "tuple 298"}
+-
+None
+box.space.sophia:insert{299, "tuple 299"}
+-
+None
+box.space.memtx:select{295}
+-
+- [295, tuple 295]
+
+box.space.memtx:select{296}
+-
+- [296, tuple 296]
+
+box.space.memtx:select{297}
+-
+- [297, tuple 297]
+
+box.space.memtx:select{298}
+-
+- [298, tuple 298]
+
+box.space.memtx:select{299}
+-
+- [299, tuple 299]
+
+box.space.sophia:select{295}
+-
+- [295, tuple 295]
+
+box.space.sophia:select{296}
+-
+- [296, tuple 296]
+
+box.space.sophia:select{297}
+-
+- [297, tuple 297]
+
+box.space.sophia:select{298}
+-
+- [298, tuple 298]
+
+box.space.sophia:select{299}
+-
+- [299, tuple 299]
+
+rollback servers configuration
+switch master to master
+box.cfg{replication_source=''}
+---
+...
+switch replica to replica
+test 15 iteration
+box.space.memtx:insert{300, "tuple 300"}
+-
+None
+box.space.memtx:insert{301, "tuple 301"}
+-
+None
+box.space.memtx:insert{302, "tuple 302"}
+-
+None
+box.space.memtx:insert{303, "tuple 303"}
+-
+None
+box.space.memtx:insert{304, "tuple 304"}
+-
+None
+box.space.sophia:insert{300, "tuple 300"}
+-
+None
+box.space.sophia:insert{301, "tuple 301"}
+-
+None
+box.space.sophia:insert{302, "tuple 302"}
+-
+None
+box.space.sophia:insert{303, "tuple 303"}
+-
+None
+box.space.sophia:insert{304, "tuple 304"}
+-
+None
+box.space.memtx:select{300}
+-
+- [300, tuple 300]
+
+box.space.memtx:select{301}
+-
+- [301, tuple 301]
+
+box.space.memtx:select{302}
+-
+- [302, tuple 302]
+
+box.space.memtx:select{303}
+-
+- [303, tuple 303]
+
+box.space.memtx:select{304}
+-
+- [304, tuple 304]
+
+box.space.sophia:select{300}
+-
+- [300, tuple 300]
+
+box.space.sophia:select{301}
+-
+- [301, tuple 301]
+
+box.space.sophia:select{302}
+-
+- [302, tuple 302]
+
+box.space.sophia:select{303}
+-
+- [303, tuple 303]
+
+box.space.sophia:select{304}
+-
+- [304, tuple 304]
+
+box.space.memtx:insert{305, "tuple 305"}
+-
+None
+box.space.memtx:insert{306, "tuple 306"}
+-
+None
+box.space.memtx:insert{307, "tuple 307"}
+-
+None
+box.space.memtx:insert{308, "tuple 308"}
+-
+None
+box.space.memtx:insert{309, "tuple 309"}
+-
+None
+box.space.sophia:insert{305, "tuple 305"}
+-
+None
+box.space.sophia:insert{306, "tuple 306"}
+-
+None
+box.space.sophia:insert{307, "tuple 307"}
+-
+None
+box.space.sophia:insert{308, "tuple 308"}
+-
+None
+box.space.sophia:insert{309, "tuple 309"}
+-
+None
+box.space.memtx:select{305}
+-
+- [305, tuple 305]
+
+box.space.memtx:select{306}
+-
+- [306, tuple 306]
+
+box.space.memtx:select{307}
+-
+- [307, tuple 307]
+
+box.space.memtx:select{308}
+-
+- [308, tuple 308]
+
+box.space.memtx:select{309}
+-
+- [309, tuple 309]
+
+box.space.sophia:select{305}
+-
+- [305, tuple 305]
+
+box.space.sophia:select{306}
+-
+- [306, tuple 306]
+
+box.space.sophia:select{307}
+-
+- [307, tuple 307]
+
+box.space.sophia:select{308}
+-
+- [308, tuple 308]
+
+box.space.sophia:select{309}
+-
+- [309, tuple 309]
+
+swap servers
+switch replica to master
+box.cfg{replication_source=''}
+---
+...
+switch master to replica
+box.space.memtx:insert{310, "tuple 310"}
+-
+None
+box.space.memtx:insert{311, "tuple 311"}
+-
+None
+box.space.memtx:insert{312, "tuple 312"}
+-
+None
+box.space.memtx:insert{313, "tuple 313"}
+-
+None
+box.space.memtx:insert{314, "tuple 314"}
+-
+None
+box.space.sophia:insert{310, "tuple 310"}
+-
+None
+box.space.sophia:insert{311, "tuple 311"}
+-
+None
+box.space.sophia:insert{312, "tuple 312"}
+-
+None
+box.space.sophia:insert{313, "tuple 313"}
+-
+None
+box.space.sophia:insert{314, "tuple 314"}
+-
+None
+box.space.memtx:select{310}
+-
+- [310, tuple 310]
+
+box.space.memtx:select{311}
+-
+- [311, tuple 311]
+
+box.space.memtx:select{312}
+-
+- [312, tuple 312]
+
+box.space.memtx:select{313}
+-
+- [313, tuple 313]
+
+box.space.memtx:select{314}
+-
+- [314, tuple 314]
+
+box.space.sophia:select{310}
+-
+- [310, tuple 310]
+
+box.space.sophia:select{311}
+-
+- [311, tuple 311]
+
+box.space.sophia:select{312}
+-
+- [312, tuple 312]
+
+box.space.sophia:select{313}
+-
+- [313, tuple 313]
+
+box.space.sophia:select{314}
+-
+- [314, tuple 314]
+
+box.space.memtx:insert{315, "tuple 315"}
+-
+None
+box.space.memtx:insert{316, "tuple 316"}
+-
+None
+box.space.memtx:insert{317, "tuple 317"}
+-
+None
+box.space.memtx:insert{318, "tuple 318"}
+-
+None
+box.space.memtx:insert{319, "tuple 319"}
+-
+None
+box.space.sophia:insert{315, "tuple 315"}
+-
+None
+box.space.sophia:insert{316, "tuple 316"}
+-
+None
+box.space.sophia:insert{317, "tuple 317"}
+-
+None
+box.space.sophia:insert{318, "tuple 318"}
+-
+None
+box.space.sophia:insert{319, "tuple 319"}
+-
+None
+box.space.memtx:select{315}
+-
+- [315, tuple 315]
+
+box.space.memtx:select{316}
+-
+- [316, tuple 316]
+
+box.space.memtx:select{317}
+-
+- [317, tuple 317]
+
+box.space.memtx:select{318}
+-
+- [318, tuple 318]
+
+box.space.memtx:select{319}
+-
+- [319, tuple 319]
+
+box.space.sophia:select{315}
+-
+- [315, tuple 315]
+
+box.space.sophia:select{316}
+-
+- [316, tuple 316]
+
+box.space.sophia:select{317}
+-
+- [317, tuple 317]
+
+box.space.sophia:select{318}
+-
+- [318, tuple 318]
+
+box.space.sophia:select{319}
+-
+- [319, tuple 319]
+
+rollback servers configuration
+switch master to master
+box.cfg{replication_source=''}
+---
+...
+switch replica to replica
+test 16 iteration
+box.space.memtx:insert{320, "tuple 320"}
+-
+None
+box.space.memtx:insert{321, "tuple 321"}
+-
+None
+box.space.memtx:insert{322, "tuple 322"}
+-
+None
+box.space.memtx:insert{323, "tuple 323"}
+-
+None
+box.space.memtx:insert{324, "tuple 324"}
+-
+None
+box.space.sophia:insert{320, "tuple 320"}
+-
+None
+box.space.sophia:insert{321, "tuple 321"}
+-
+None
+box.space.sophia:insert{322, "tuple 322"}
+-
+None
+box.space.sophia:insert{323, "tuple 323"}
+-
+None
+box.space.sophia:insert{324, "tuple 324"}
+-
+None
+box.space.memtx:select{320}
+-
+- [320, tuple 320]
+
+box.space.memtx:select{321}
+-
+- [321, tuple 321]
+
+box.space.memtx:select{322}
+-
+- [322, tuple 322]
+
+box.space.memtx:select{323}
+-
+- [323, tuple 323]
+
+box.space.memtx:select{324}
+-
+- [324, tuple 324]
+
+box.space.sophia:select{320}
+-
+- [320, tuple 320]
+
+box.space.sophia:select{321}
+-
+- [321, tuple 321]
+
+box.space.sophia:select{322}
+-
+- [322, tuple 322]
+
+box.space.sophia:select{323}
+-
+- [323, tuple 323]
+
+box.space.sophia:select{324}
+-
+- [324, tuple 324]
+
+box.space.memtx:insert{325, "tuple 325"}
+-
+None
+box.space.memtx:insert{326, "tuple 326"}
+-
+None
+box.space.memtx:insert{327, "tuple 327"}
+-
+None
+box.space.memtx:insert{328, "tuple 328"}
+-
+None
+box.space.memtx:insert{329, "tuple 329"}
+-
+None
+box.space.sophia:insert{325, "tuple 325"}
+-
+None
+box.space.sophia:insert{326, "tuple 326"}
+-
+None
+box.space.sophia:insert{327, "tuple 327"}
+-
+None
+box.space.sophia:insert{328, "tuple 328"}
+-
+None
+box.space.sophia:insert{329, "tuple 329"}
+-
+None
+box.space.memtx:select{325}
+-
+- [325, tuple 325]
+
+box.space.memtx:select{326}
+-
+- [326, tuple 326]
+
+box.space.memtx:select{327}
+-
+- [327, tuple 327]
+
+box.space.memtx:select{328}
+-
+- [328, tuple 328]
+
+box.space.memtx:select{329}
+-
+- [329, tuple 329]
+
+box.space.sophia:select{325}
+-
+- [325, tuple 325]
+
+box.space.sophia:select{326}
+-
+- [326, tuple 326]
+
+box.space.sophia:select{327}
+-
+- [327, tuple 327]
+
+box.space.sophia:select{328}
+-
+- [328, tuple 328]
+
+box.space.sophia:select{329}
+-
+- [329, tuple 329]
+
+swap servers
+switch replica to master
+box.cfg{replication_source=''}
+---
+...
+switch master to replica
+box.space.memtx:insert{330, "tuple 330"}
+-
+None
+box.space.memtx:insert{331, "tuple 331"}
+-
+None
+box.space.memtx:insert{332, "tuple 332"}
+-
+None
+box.space.memtx:insert{333, "tuple 333"}
+-
+None
+box.space.memtx:insert{334, "tuple 334"}
+-
+None
+box.space.sophia:insert{330, "tuple 330"}
+-
+None
+box.space.sophia:insert{331, "tuple 331"}
+-
+None
+box.space.sophia:insert{332, "tuple 332"}
+-
+None
+box.space.sophia:insert{333, "tuple 333"}
+-
+None
+box.space.sophia:insert{334, "tuple 334"}
+-
+None
+box.space.memtx:select{330}
+-
+- [330, tuple 330]
+
+box.space.memtx:select{331}
+-
+- [331, tuple 331]
+
+box.space.memtx:select{332}
+-
+- [332, tuple 332]
+
+box.space.memtx:select{333}
+-
+- [333, tuple 333]
+
+box.space.memtx:select{334}
+-
+- [334, tuple 334]
+
+box.space.sophia:select{330}
+-
+- [330, tuple 330]
+
+box.space.sophia:select{331}
+-
+- [331, tuple 331]
+
+box.space.sophia:select{332}
+-
+- [332, tuple 332]
+
+box.space.sophia:select{333}
+-
+- [333, tuple 333]
+
+box.space.sophia:select{334}
+-
+- [334, tuple 334]
+
+box.space.memtx:insert{335, "tuple 335"}
+-
+None
+box.space.memtx:insert{336, "tuple 336"}
+-
+None
+box.space.memtx:insert{337, "tuple 337"}
+-
+None
+box.space.memtx:insert{338, "tuple 338"}
+-
+None
+box.space.memtx:insert{339, "tuple 339"}
+-
+None
+box.space.sophia:insert{335, "tuple 335"}
+-
+None
+box.space.sophia:insert{336, "tuple 336"}
+-
+None
+box.space.sophia:insert{337, "tuple 337"}
+-
+None
+box.space.sophia:insert{338, "tuple 338"}
+-
+None
+box.space.sophia:insert{339, "tuple 339"}
+-
+None
+box.space.memtx:select{335}
+-
+- [335, tuple 335]
+
+box.space.memtx:select{336}
+-
+- [336, tuple 336]
+
+box.space.memtx:select{337}
+-
+- [337, tuple 337]
+
+box.space.memtx:select{338}
+-
+- [338, tuple 338]
+
+box.space.memtx:select{339}
+-
+- [339, tuple 339]
+
+box.space.sophia:select{335}
+-
+- [335, tuple 335]
+
+box.space.sophia:select{336}
+-
+- [336, tuple 336]
+
+box.space.sophia:select{337}
+-
+- [337, tuple 337]
+
+box.space.sophia:select{338}
+-
+- [338, tuple 338]
+
+box.space.sophia:select{339}
+-
+- [339, tuple 339]
+
+rollback servers configuration
+switch master to master
+box.cfg{replication_source=''}
+---
+...
+switch replica to replica
+test 17 iteration
+box.space.memtx:insert{340, "tuple 340"}
+-
+None
+box.space.memtx:insert{341, "tuple 341"}
+-
+None
+box.space.memtx:insert{342, "tuple 342"}
+-
+None
+box.space.memtx:insert{343, "tuple 343"}
+-
+None
+box.space.memtx:insert{344, "tuple 344"}
+-
+None
+box.space.sophia:insert{340, "tuple 340"}
+-
+None
+box.space.sophia:insert{341, "tuple 341"}
+-
+None
+box.space.sophia:insert{342, "tuple 342"}
+-
+None
+box.space.sophia:insert{343, "tuple 343"}
+-
+None
+box.space.sophia:insert{344, "tuple 344"}
+-
+None
+box.space.memtx:select{340}
+-
+- [340, tuple 340]
+
+box.space.memtx:select{341}
+-
+- [341, tuple 341]
+
+box.space.memtx:select{342}
+-
+- [342, tuple 342]
+
+box.space.memtx:select{343}
+-
+- [343, tuple 343]
+
+box.space.memtx:select{344}
+-
+- [344, tuple 344]
+
+box.space.sophia:select{340}
+-
+- [340, tuple 340]
+
+box.space.sophia:select{341}
+-
+- [341, tuple 341]
+
+box.space.sophia:select{342}
+-
+- [342, tuple 342]
+
+box.space.sophia:select{343}
+-
+- [343, tuple 343]
+
+box.space.sophia:select{344}
+-
+- [344, tuple 344]
+
+box.space.memtx:insert{345, "tuple 345"}
+-
+None
+box.space.memtx:insert{346, "tuple 346"}
+-
+None
+box.space.memtx:insert{347, "tuple 347"}
+-
+None
+box.space.memtx:insert{348, "tuple 348"}
+-
+None
+box.space.memtx:insert{349, "tuple 349"}
+-
+None
+box.space.sophia:insert{345, "tuple 345"}
+-
+None
+box.space.sophia:insert{346, "tuple 346"}
+-
+None
+box.space.sophia:insert{347, "tuple 347"}
+-
+None
+box.space.sophia:insert{348, "tuple 348"}
+-
+None
+box.space.sophia:insert{349, "tuple 349"}
+-
+None
+box.space.memtx:select{345}
+-
+- [345, tuple 345]
+
+box.space.memtx:select{346}
+-
+- [346, tuple 346]
+
+box.space.memtx:select{347}
+-
+- [347, tuple 347]
+
+box.space.memtx:select{348}
+-
+- [348, tuple 348]
+
+box.space.memtx:select{349}
+-
+- [349, tuple 349]
+
+box.space.sophia:select{345}
+-
+- [345, tuple 345]
+
+box.space.sophia:select{346}
+-
+- [346, tuple 346]
+
+box.space.sophia:select{347}
+-
+- [347, tuple 347]
+
+box.space.sophia:select{348}
+-
+- [348, tuple 348]
+
+box.space.sophia:select{349}
+-
+- [349, tuple 349]
+
+swap servers
+switch replica to master
+box.cfg{replication_source=''}
+---
+...
+switch master to replica
+box.space.memtx:insert{350, "tuple 350"}
+-
+None
+box.space.memtx:insert{351, "tuple 351"}
+-
+None
+box.space.memtx:insert{352, "tuple 352"}
+-
+None
+box.space.memtx:insert{353, "tuple 353"}
+-
+None
+box.space.memtx:insert{354, "tuple 354"}
+-
+None
+box.space.sophia:insert{350, "tuple 350"}
+-
+None
+box.space.sophia:insert{351, "tuple 351"}
+-
+None
+box.space.sophia:insert{352, "tuple 352"}
+-
+None
+box.space.sophia:insert{353, "tuple 353"}
+-
+None
+box.space.sophia:insert{354, "tuple 354"}
+-
+None
+box.space.memtx:select{350}
+-
+- [350, tuple 350]
+
+box.space.memtx:select{351}
+-
+- [351, tuple 351]
+
+box.space.memtx:select{352}
+-
+- [352, tuple 352]
+
+box.space.memtx:select{353}
+-
+- [353, tuple 353]
+
+box.space.memtx:select{354}
+-
+- [354, tuple 354]
+
+box.space.sophia:select{350}
+-
+- [350, tuple 350]
+
+box.space.sophia:select{351}
+-
+- [351, tuple 351]
+
+box.space.sophia:select{352}
+-
+- [352, tuple 352]
+
+box.space.sophia:select{353}
+-
+- [353, tuple 353]
+
+box.space.sophia:select{354}
+-
+- [354, tuple 354]
+
+box.space.memtx:insert{355, "tuple 355"}
+-
+None
+box.space.memtx:insert{356, "tuple 356"}
+-
+None
+box.space.memtx:insert{357, "tuple 357"}
+-
+None
+box.space.memtx:insert{358, "tuple 358"}
+-
+None
+box.space.memtx:insert{359, "tuple 359"}
+-
+None
+box.space.sophia:insert{355, "tuple 355"}
+-
+None
+box.space.sophia:insert{356, "tuple 356"}
+-
+None
+box.space.sophia:insert{357, "tuple 357"}
+-
+None
+box.space.sophia:insert{358, "tuple 358"}
+-
+None
+box.space.sophia:insert{359, "tuple 359"}
+-
+None
+box.space.memtx:select{355}
+-
+- [355, tuple 355]
+
+box.space.memtx:select{356}
+-
+- [356, tuple 356]
+
+box.space.memtx:select{357}
+-
+- [357, tuple 357]
+
+box.space.memtx:select{358}
+-
+- [358, tuple 358]
+
+box.space.memtx:select{359}
+-
+- [359, tuple 359]
+
+box.space.sophia:select{355}
+-
+- [355, tuple 355]
+
+box.space.sophia:select{356}
+-
+- [356, tuple 356]
+
+box.space.sophia:select{357}
+-
+- [357, tuple 357]
+
+box.space.sophia:select{358}
+-
+- [358, tuple 358]
+
+box.space.sophia:select{359}
+-
+- [359, tuple 359]
+
+rollback servers configuration
+switch master to master
+box.cfg{replication_source=''}
+---
+...
+switch replica to replica
+test 18 iteration
+box.space.memtx:insert{360, "tuple 360"}
+-
+None
+box.space.memtx:insert{361, "tuple 361"}
+-
+None
+box.space.memtx:insert{362, "tuple 362"}
+-
+None
+box.space.memtx:insert{363, "tuple 363"}
+-
+None
+box.space.memtx:insert{364, "tuple 364"}
+-
+None
+box.space.sophia:insert{360, "tuple 360"}
+-
+None
+box.space.sophia:insert{361, "tuple 361"}
+-
+None
+box.space.sophia:insert{362, "tuple 362"}
+-
+None
+box.space.sophia:insert{363, "tuple 363"}
+-
+None
+box.space.sophia:insert{364, "tuple 364"}
+-
+None
+box.space.memtx:select{360}
+-
+- [360, tuple 360]
+
+box.space.memtx:select{361}
+-
+- [361, tuple 361]
+
+box.space.memtx:select{362}
+-
+- [362, tuple 362]
+
+box.space.memtx:select{363}
+-
+- [363, tuple 363]
+
+box.space.memtx:select{364}
+-
+- [364, tuple 364]
+
+box.space.sophia:select{360}
+-
+- [360, tuple 360]
+
+box.space.sophia:select{361}
+-
+- [361, tuple 361]
+
+box.space.sophia:select{362}
+-
+- [362, tuple 362]
+
+box.space.sophia:select{363}
+-
+- [363, tuple 363]
+
+box.space.sophia:select{364}
+-
+- [364, tuple 364]
+
+box.space.memtx:insert{365, "tuple 365"}
+-
+None
+box.space.memtx:insert{366, "tuple 366"}
+-
+None
+box.space.memtx:insert{367, "tuple 367"}
+-
+None
+box.space.memtx:insert{368, "tuple 368"}
+-
+None
+box.space.memtx:insert{369, "tuple 369"}
+-
+None
+box.space.sophia:insert{365, "tuple 365"}
+-
+None
+box.space.sophia:insert{366, "tuple 366"}
+-
+None
+box.space.sophia:insert{367, "tuple 367"}
+-
+None
+box.space.sophia:insert{368, "tuple 368"}
+-
+None
+box.space.sophia:insert{369, "tuple 369"}
+-
+None
+box.space.memtx:select{365}
+-
+- [365, tuple 365]
+
+box.space.memtx:select{366}
+-
+- [366, tuple 366]
+
+box.space.memtx:select{367}
+-
+- [367, tuple 367]
+
+box.space.memtx:select{368}
+-
+- [368, tuple 368]
+
+box.space.memtx:select{369}
+-
+- [369, tuple 369]
+
+box.space.sophia:select{365}
+-
+- [365, tuple 365]
+
+box.space.sophia:select{366}
+-
+- [366, tuple 366]
+
+box.space.sophia:select{367}
+-
+- [367, tuple 367]
+
+box.space.sophia:select{368}
+-
+- [368, tuple 368]
+
+box.space.sophia:select{369}
+-
+- [369, tuple 369]
+
+swap servers
+switch replica to master
+box.cfg{replication_source=''}
+---
+...
+switch master to replica
+box.space.memtx:insert{370, "tuple 370"}
+-
+None
+box.space.memtx:insert{371, "tuple 371"}
+-
+None
+box.space.memtx:insert{372, "tuple 372"}
+-
+None
+box.space.memtx:insert{373, "tuple 373"}
+-
+None
+box.space.memtx:insert{374, "tuple 374"}
+-
+None
+box.space.sophia:insert{370, "tuple 370"}
+-
+None
+box.space.sophia:insert{371, "tuple 371"}
+-
+None
+box.space.sophia:insert{372, "tuple 372"}
+-
+None
+box.space.sophia:insert{373, "tuple 373"}
+-
+None
+box.space.sophia:insert{374, "tuple 374"}
+-
+None
+box.space.memtx:select{370}
+-
+- [370, tuple 370]
+
+box.space.memtx:select{371}
+-
+- [371, tuple 371]
+
+box.space.memtx:select{372}
+-
+- [372, tuple 372]
+
+box.space.memtx:select{373}
+-
+- [373, tuple 373]
+
+box.space.memtx:select{374}
+-
+- [374, tuple 374]
+
+box.space.sophia:select{370}
+-
+- [370, tuple 370]
+
+box.space.sophia:select{371}
+-
+- [371, tuple 371]
+
+box.space.sophia:select{372}
+-
+- [372, tuple 372]
+
+box.space.sophia:select{373}
+-
+- [373, tuple 373]
+
+box.space.sophia:select{374}
+-
+- [374, tuple 374]
+
+box.space.memtx:insert{375, "tuple 375"}
+-
+None
+box.space.memtx:insert{376, "tuple 376"}
+-
+None
+box.space.memtx:insert{377, "tuple 377"}
+-
+None
+box.space.memtx:insert{378, "tuple 378"}
+-
+None
+box.space.memtx:insert{379, "tuple 379"}
+-
+None
+box.space.sophia:insert{375, "tuple 375"}
+-
+None
+box.space.sophia:insert{376, "tuple 376"}
+-
+None
+box.space.sophia:insert{377, "tuple 377"}
+-
+None
+box.space.sophia:insert{378, "tuple 378"}
+-
+None
+box.space.sophia:insert{379, "tuple 379"}
+-
+None
+box.space.memtx:select{375}
+-
+- [375, tuple 375]
+
+box.space.memtx:select{376}
+-
+- [376, tuple 376]
+
+box.space.memtx:select{377}
+-
+- [377, tuple 377]
+
+box.space.memtx:select{378}
+-
+- [378, tuple 378]
+
+box.space.memtx:select{379}
+-
+- [379, tuple 379]
+
+box.space.sophia:select{375}
+-
+- [375, tuple 375]
+
+box.space.sophia:select{376}
+-
+- [376, tuple 376]
+
+box.space.sophia:select{377}
+-
+- [377, tuple 377]
+
+box.space.sophia:select{378}
+-
+- [378, tuple 378]
+
+box.space.sophia:select{379}
+-
+- [379, tuple 379]
+
+rollback servers configuration
+switch master to master
+box.cfg{replication_source=''}
+---
+...
+switch replica to replica
+test 19 iteration
+box.space.memtx:insert{380, "tuple 380"}
+-
+None
+box.space.memtx:insert{381, "tuple 381"}
+-
+None
+box.space.memtx:insert{382, "tuple 382"}
+-
+None
+box.space.memtx:insert{383, "tuple 383"}
+-
+None
+box.space.memtx:insert{384, "tuple 384"}
+-
+None
+box.space.sophia:insert{380, "tuple 380"}
+-
+None
+box.space.sophia:insert{381, "tuple 381"}
+-
+None
+box.space.sophia:insert{382, "tuple 382"}
+-
+None
+box.space.sophia:insert{383, "tuple 383"}
+-
+None
+box.space.sophia:insert{384, "tuple 384"}
+-
+None
+box.space.memtx:select{380}
+-
+- [380, tuple 380]
+
+box.space.memtx:select{381}
+-
+- [381, tuple 381]
+
+box.space.memtx:select{382}
+-
+- [382, tuple 382]
+
+box.space.memtx:select{383}
+-
+- [383, tuple 383]
+
+box.space.memtx:select{384}
+-
+- [384, tuple 384]
+
+box.space.sophia:select{380}
+-
+- [380, tuple 380]
+
+box.space.sophia:select{381}
+-
+- [381, tuple 381]
+
+box.space.sophia:select{382}
+-
+- [382, tuple 382]
+
+box.space.sophia:select{383}
+-
+- [383, tuple 383]
+
+box.space.sophia:select{384}
+-
+- [384, tuple 384]
+
+box.space.memtx:insert{385, "tuple 385"}
+-
+None
+box.space.memtx:insert{386, "tuple 386"}
+-
+None
+box.space.memtx:insert{387, "tuple 387"}
+-
+None
+box.space.memtx:insert{388, "tuple 388"}
+-
+None
+box.space.memtx:insert{389, "tuple 389"}
+-
+None
+box.space.sophia:insert{385, "tuple 385"}
+-
+None
+box.space.sophia:insert{386, "tuple 386"}
+-
+None
+box.space.sophia:insert{387, "tuple 387"}
+-
+None
+box.space.sophia:insert{388, "tuple 388"}
+-
+None
+box.space.sophia:insert{389, "tuple 389"}
+-
+None
+box.space.memtx:select{385}
+-
+- [385, tuple 385]
+
+box.space.memtx:select{386}
+-
+- [386, tuple 386]
+
+box.space.memtx:select{387}
+-
+- [387, tuple 387]
+
+box.space.memtx:select{388}
+-
+- [388, tuple 388]
+
+box.space.memtx:select{389}
+-
+- [389, tuple 389]
+
+box.space.sophia:select{385}
+-
+- [385, tuple 385]
+
+box.space.sophia:select{386}
+-
+- [386, tuple 386]
+
+box.space.sophia:select{387}
+-
+- [387, tuple 387]
+
+box.space.sophia:select{388}
+-
+- [388, tuple 388]
+
+box.space.sophia:select{389}
+-
+- [389, tuple 389]
+
+swap servers
+switch replica to master
+box.cfg{replication_source=''}
+---
+...
+switch master to replica
+box.space.memtx:insert{390, "tuple 390"}
+-
+None
+box.space.memtx:insert{391, "tuple 391"}
+-
+None
+box.space.memtx:insert{392, "tuple 392"}
+-
+None
+box.space.memtx:insert{393, "tuple 393"}
+-
+None
+box.space.memtx:insert{394, "tuple 394"}
+-
+None
+box.space.sophia:insert{390, "tuple 390"}
+-
+None
+box.space.sophia:insert{391, "tuple 391"}
+-
+None
+box.space.sophia:insert{392, "tuple 392"}
+-
+None
+box.space.sophia:insert{393, "tuple 393"}
+-
+None
+box.space.sophia:insert{394, "tuple 394"}
+-
+None
+box.space.memtx:select{390}
+-
+- [390, tuple 390]
+
+box.space.memtx:select{391}
+-
+- [391, tuple 391]
+
+box.space.memtx:select{392}
+-
+- [392, tuple 392]
+
+box.space.memtx:select{393}
+-
+- [393, tuple 393]
+
+box.space.memtx:select{394}
+-
+- [394, tuple 394]
+
+box.space.sophia:select{390}
+-
+- [390, tuple 390]
+
+box.space.sophia:select{391}
+-
+- [391, tuple 391]
+
+box.space.sophia:select{392}
+-
+- [392, tuple 392]
+
+box.space.sophia:select{393}
+-
+- [393, tuple 393]
+
+box.space.sophia:select{394}
+-
+- [394, tuple 394]
+
+box.space.memtx:insert{395, "tuple 395"}
+-
+None
+box.space.memtx:insert{396, "tuple 396"}
+-
+None
+box.space.memtx:insert{397, "tuple 397"}
+-
+None
+box.space.memtx:insert{398, "tuple 398"}
+-
+None
+box.space.memtx:insert{399, "tuple 399"}
+-
+None
+box.space.sophia:insert{395, "tuple 395"}
+-
+None
+box.space.sophia:insert{396, "tuple 396"}
+-
+None
+box.space.sophia:insert{397, "tuple 397"}
+-
+None
+box.space.sophia:insert{398, "tuple 398"}
+-
+None
+box.space.sophia:insert{399, "tuple 399"}
+-
+None
+box.space.memtx:select{395}
+-
+- [395, tuple 395]
+
+box.space.memtx:select{396}
+-
+- [396, tuple 396]
+
+box.space.memtx:select{397}
+-
+- [397, tuple 397]
+
+box.space.memtx:select{398}
+-
+- [398, tuple 398]
+
+box.space.memtx:select{399}
+-
+- [399, tuple 399]
+
+box.space.sophia:select{395}
+-
+- [395, tuple 395]
+
+box.space.sophia:select{396}
+-
+- [396, tuple 396]
+
+box.space.sophia:select{397}
+-
+- [397, tuple 397]
+
+box.space.sophia:select{398}
+-
+- [398, tuple 398]
+
+box.space.sophia:select{399}
+-
+- [399, tuple 399]
+
+rollback servers configuration
+switch master to master
+box.cfg{replication_source=''}
+---
+...
+switch replica to replica
blob - /dev/null
blob + 3153e36ee178b8fb956e1339a0d32832e7a72f7f (mode 644)
--- /dev/null
+++ test/replication-py/swap.test.py
+import os
+import tarantool
+from lib.tarantool_server import TarantoolServer
+import re
+import yaml
+
+REPEAT = 20
+ID_BEGIN = 0
+ID_STEP = 5
+LOGIN = 'test'
+PASSWORD = 'pass123456'
+
+engines = ['memtx', 'sophia']
+
+def insert_tuples(_server, begin, end, msg = "tuple"):
+ for engine in engines:
+ for i in range(begin, end):
+ print 'box.space.%s:insert{%d, "%s %d"}' % (engine, i, msg, i)
+ print '-'
+ space = _server.iproto.py_con.space(engine)
+ print space.insert((i, '%s %d' % (msg, i)))
+
+def select_tuples(_server, begin, end):
+ for engine in engines:
+ for i in range(begin, end):
+ print 'box.space.%s:select{%d}' % (engine, i)
+ print '-'
+ space = _server.iproto.py_con.space(engine)
+ print space.select(i)
+
+# master server
+master = server
+# Re-deploy server to cleanup Sophia data
+master.stop()
+master.cleanup()
+master.deploy()
+master.admin("box.schema.user.create('%s', { password = '%s'})" % (LOGIN, PASSWORD))
+master.admin("box.schema.user.grant('%s', 'read,write,execute', 'universe')" % LOGIN)
+master.iproto.py_con.authenticate(LOGIN, PASSWORD)
+master.uri = '%s:%s@%s' % (LOGIN, PASSWORD, master.iproto.uri)
+os.putenv('MASTER', master.uri)
+
+# replica server
+replica = TarantoolServer()
+replica.script = "replication/replica.lua"
+replica.vardir = server.vardir #os.path.join(server.vardir, 'replica')
+replica.deploy()
+replica.admin("while box.info.server.id == 0 do require('fiber').sleep(0.01) end")
+replica.uri = '%s:%s@%s' % (LOGIN, PASSWORD, replica.iproto.uri)
+replica.admin("while box.space['_priv']:len() < 1 do require('fiber').sleep(0.01) end")
+replica.iproto.py_con.authenticate(LOGIN, PASSWORD)
+
+for engine in engines:
+ master.admin("s = box.schema.space.create('%s', { engine = '%s'})" % (engine, engine))
+ master.admin("index = s:create_index('primary', {type = 'tree'})")
+
+### gh-343: replica.cc must not add login and password to proc title
+#status = replica.get_param("status")
+#host_port = "%s:%s" % master.iproto.uri
+#m = re.search(r'replica/(.*)/.*', status)
+#if not m or m.group(1) != host_port:
+# print 'invalid box.info.status', status, 'expected host:port', host_port
+
+master_id = master.get_param('server')['id']
+replica_id = replica.get_param('server')['id']
+
+id = ID_BEGIN
+for i in range(REPEAT):
+ print "test %d iteration" % i
+
+ # insert to master
+ insert_tuples(master, id, id + ID_STEP)
+ # select from replica
+ replica.wait_lsn(master_id, master.get_lsn(master_id))
+ select_tuples(replica, id, id + ID_STEP)
+ id += ID_STEP
+
+ # insert to master
+ insert_tuples(master, id, id + ID_STEP)
+ # select from replica
+ replica.wait_lsn(master_id, master.get_lsn(master_id))
+ select_tuples(replica, id, id + ID_STEP)
+ id += ID_STEP
+
+ print "swap servers"
+ # reconfigure replica to master
+ replica.rpl_master = None
+ print("switch replica to master")
+ replica.admin("box.cfg{replication_source=''}")
+ # reconfigure master to replica
+ master.rpl_master = replica
+ print("switch master to replica")
+ master.admin("box.cfg{replication_source='%s'}" % replica.uri, silent=True)
+
+ # insert to replica
+ insert_tuples(replica, id, id + ID_STEP)
+ # select from master
+ master.wait_lsn(replica_id, replica.get_lsn(replica_id))
+ select_tuples(master, id, id + ID_STEP)
+ id += ID_STEP
+
+ # insert to replica
+ insert_tuples(replica, id, id + ID_STEP)
+ # select from master
+ master.wait_lsn(replica_id, replica.get_lsn(replica_id))
+ select_tuples(master, id, id + ID_STEP)
+ id += ID_STEP
+
+ print "rollback servers configuration"
+ # reconfigure replica to master
+ master.rpl_master = None
+ print("switch master to master")
+ master.admin("box.cfg{replication_source=''}")
+ # reconfigure master to replica
+ replica.rpl_master = master
+ print("switch replica to replica")
+ replica.admin("box.cfg{replication_source='%s'}" % master.uri, silent=True)
+
+
+# Cleanup.
+replica.stop()
+replica.cleanup(True)
+server.stop()
+server.deploy()
blob - 53ae732283903afc0a2c0bcf9c8ba0ef645bc89a (mode 644)
blob + /dev/null
--- test/xlog/dup_key.result
+++ /dev/null
-space = box.schema.space.create('test')
----
-...
-index = box.space.test:create_index('primary')
----
-...
-box.space.test:insert{1, 'first tuple'}
----
-- [1, 'first tuple']
-...
-box.space.test:insert{2, 'second tuple'}
----
-- [2, 'second tuple']
-...
-.xlog exists
-space = box.schema.space.create('test')
----
-...
-index = box.space.test:create_index('primary')
----
-...
-box.space.test:insert{1, 'first tuple'}
----
-- [1, 'first tuple']
-...
-box.space.test:delete{1}
----
-- [1, 'first tuple']
-...
-box.space.test:insert{1, 'third tuple'}
----
-- [1, 'third tuple']
-...
-box.space.test:insert{2, 'fourth tuple'}
----
-- [2, 'fourth tuple']
-...
-.xlog exists
-check log line for 'Duplicate key'
-
-'Duplicate key' exists in server log
-
-box.space.test:get{1}
----
-- [1, 'first tuple']
-...
-box.space.test:get{2}
----
-- [2, 'second tuple']
-...
-box.space.test:len()
----
-- 2
-...
blob - c727f074daa0fd589e35f987de6cb665196a86ba (mode 644)
blob + /dev/null
--- test/xlog/dup_key.test.py
+++ /dev/null
-import os
-import yaml
-
-#print """
-#A test case for https://bugs.launchpad.net/tarantool/+bug/1052018
-#panic_on_wal_error doesn't work for duplicate key errors
-#"""
-
-server.stop()
-server.deploy()
-lsn = int(yaml.load(server.admin("box.info.server.lsn", silent=True))[0])
-filename = str(lsn).zfill(20) + ".xlog"
-vardir = os.path.join(server.vardir, server.name)
-wal_old = os.path.join(vardir, "old_" + filename)
-wal = os.path.join(vardir, filename)
-
-# Create wal#1
-server.admin("space = box.schema.space.create('test')")
-server.admin("index = box.space.test:create_index('primary')")
-server.admin("box.space.test:insert{1, 'first tuple'}")
-server.admin("box.space.test:insert{2, 'second tuple'}")
-server.stop()
-
-# Save wal #1
-if os.access(wal, os.F_OK):
- print ".xlog exists"
- os.rename(wal, wal_old)
-
-lsn += 4
-
-# Create another wal#1
-server.start()
-server.admin("space = box.schema.space.create('test')")
-server.admin("index = box.space.test:create_index('primary')")
-server.admin("box.space.test:insert{1, 'first tuple'}")
-server.admin("box.space.test:delete{1}")
-server.stop()
-
-# Create wal#2
-server.start()
-server.admin("box.space.test:insert{1, 'third tuple'}")
-server.admin("box.space.test:insert{2, 'fourth tuple'}")
-server.stop()
-
-if os.access(wal, os.F_OK):
- print ".xlog exists"
- # Replace wal#1 with saved copy
- os.unlink(wal)
- os.rename(wal_old, wal)
-
-
-server.start()
-line = 'Duplicate key'
-print "check log line for '%s'" % line
-print
-if server.logfile_pos.seek_once(line) >= 0:
- print "'%s' exists in server log" % line
-print
-
-server.admin("box.space.test:get{1}")
-server.admin("box.space.test:get{2}")
-server.admin("box.space.test:len()")
-
blob - 7aaa405c4d62ad005e058cd85f28ea72a509e7b3 (mode 644)
blob + /dev/null
--- test/xlog/empty.result
+++ /dev/null
-.xlog exists
-_ = box.schema.space.create('test')
----
-- error: Failed to write to disk
-...
-_ = box.schema.space.create('test')
----
-...
blob - f3bf8416425e7dc17214f8d833d0c069634d1d74 (mode 644)
blob + /dev/null
--- test/xlog/empty.test.py
+++ /dev/null
-import os
-import yaml
-from os.path import abspath
-
-#
-# This test used to pass:
-#
-# Empty xlog.inprogress must be deleted during recovery
-#
-# it doesn't pass any more since an xlog with missing header
-# can't be parsed by xdir_scan, thus we do nothing about it.
-#
-server.stop()
-server.deploy()
-lsn = str(yaml.load(server.admin("box.info.server.lsn", silent=True))[0])
-path = os.path.join(server.vardir, server.name)
-filename = os.path.join(path, lsn.zfill(20) + ".xlog")
-f = open(filename, "w+")
-f.close()
-server.start()
-server.stop()
-if os.access(filename, os.F_OK):
- print ".xlog exists"
-# the server has started but is crippled since it
-# can't override an existing file
-server.start()
-server.admin("_ = box.schema.space.create('test')")
-os.unlink(filename)
-server.admin("_ = box.schema.space.create('test')")
blob - 685fc1efa85aa2d0b44b3f778daf06eca18d799c (mode 644)
blob + /dev/null
--- test/xlog/lsn_gap.result
+++ /dev/null
-space = box.schema.space.create('test')
----
-...
-index = box.space.test:create_index('primary')
----
-...
-box.space.test:insert{1, 'first tuple'}
----
-- [1, 'first tuple']
-...
-box.space.test:insert{2, 'second tuple'}
----
-- [2, 'second tuple']
-...
-box.space.test:insert{3, 'third tuple'}
----
-- [3, 'third tuple']
-...
-box.space.test:insert{4, 'fourth tuple'}
----
-- [4, 'fourth tuple']
-...
-check log line for 'ignoring a gap in LSN'
-
-'ignoring a gap in LSN' exists in server log
-
-box.space.test:select{}
----
-- - [1, 'first tuple']
- - [2, 'second tuple']
- - [4, 'fourth tuple']
-...
blob - c4281d89d9dd71f1b9916262518cda86850010c1 (mode 644)
blob + /dev/null
--- test/xlog/lsn_gap.test.py
+++ /dev/null
-import os
-import yaml
-#
-# gh-167: Replica can't find next xlog file if there is a gap in LSN
-#
-
-server.stop()
-server.deploy()
-
-# Create wal#1
-server.admin("space = box.schema.space.create('test')")
-server.admin("index = box.space.test:create_index('primary')")
-server.admin("box.space.test:insert{1, 'first tuple'}")
-server.admin("box.space.test:insert{2, 'second tuple'}")
-lsn = int(yaml.load(server.admin("box.info.server.lsn", silent=True))[0])
-path = os.path.join(server.vardir, server.name)
-wal = os.path.join(path, str(lsn).zfill(20) + ".xlog")
-server.stop()
-server.start()
-server.admin("box.space.test:insert{3, 'third tuple'}")
-server.stop()
-server.start()
-server.admin("box.space.test:insert{4, 'fourth tuple'}")
-server.stop()
-
-# Remove xlog with {3, 'third tuple'}
-os.unlink(wal)
-
-server.start()
-line="ignoring a gap in LSN"
-print "check log line for '%s'" % line
-print
-if server.logfile_pos.seek_once(line) >= 0:
- print "'%s' exists in server log" % line
-print
-
-# missing tuple from removed xlog
-server.admin("box.space.test:select{}")
-
blob - d9452019bae099af646d270bfb889b2f12a2d6f8 (mode 644)
blob + /dev/null
--- test/xlog/misc.result
+++ /dev/null
-
-# xlog file must exist after inserts.
-
-space = box.schema.space.create('tweedledum', { id = 0 })
----
-...
-.xlog exists
-index = space:create_index('primary', { type = 'hash' })
----
-...
-
-# a new xlog must be opened after regular termination.
-
-box.space[0]:insert{3, 'third tuple'}
----
-- [3, 'third tuple']
-...
-a new .xlog exists
-.xlog stays around after sutdown
-
-# An xlog file with one record during recovery.
-
-box.space[0]:insert{4, 'fourth tuple'}
----
-- [4, 'fourth tuple']
-...
-box.space[0]:insert{5, 'Unfinished record'}
----
-- [5, 'Unfinished record']
-...
-.xlog exists after kill -9
-corrupt .xlog exists after start
-box.snapshot()
----
-- ok
-...
-box.space._schema:insert({'test', 'test'})
----
-- ['test', 'test']
-...
-box.snapshot()
----
-- ok
-...
-.snap.inprogress is ignored
blob - a182354b99a0f7484d9c9d199c2c354155c76e97 (mode 644)
blob + /dev/null
--- test/xlog/misc.test.py
+++ /dev/null
-import os
-import yaml
-
-from os.path import abspath
-
-# cleanup server.vardir
-server.stop()
-server.deploy()
-lsn = int(yaml.load(server.admin("box.info.server.lsn", silent=True))[0])
-server.stop()
-
-data_path = os.path.join(server.vardir, server.name)
-
-print """
-# xlog file must exist after inserts.
-"""
-filename = str(lsn).zfill(20) + ".xlog"
-wal = os.path.join(data_path, filename)
-
-server.start()
-
-server.admin("space = box.schema.space.create('tweedledum', { id = 0 })")
-if os.access(wal, os.F_OK):
- print ".xlog exists"
-
-server.admin("index = space:create_index('primary', { type = 'hash' })")
-
-server.stop()
-lsn += 2
-
-print """
-# a new xlog must be opened after regular termination.
-"""
-filename = str(lsn).zfill(20) + ".xlog"
-server.start()
-
-wal = os.path.join(data_path, filename)
-
-server.admin("box.space[0]:insert{3, 'third tuple'}")
-
-if os.access(wal, os.F_OK):
- print "a new .xlog exists"
-
-server.stop()
-
-if os.access(wal, os.F_OK):
- print ".xlog stays around after sutdown"
-lsn += 1
-
-print """
-# An xlog file with one record during recovery.
-"""
-
-server.start()
-filename = str(lsn).zfill(20) + ".xlog"
-wal = os.path.join(data_path, filename)
-server.admin("box.space[0]:insert{4, 'fourth tuple'}")
-server.admin("box.space[0]:insert{5, 'Unfinished record'}")
-pid = int(yaml.load(server.admin("require('tarantool').pid()", silent=True))[0])
-from signal import SIGKILL
-if pid > 0:
- os.kill(pid, SIGKILL)
-server.stop()
-
-if os.access(wal, os.F_OK):
- print ".xlog exists after kill -9"
- # Remove last byte from xlog
- f = open(wal, "a")
- size = f.tell()
- f.truncate(size - 1)
- f.close()
-
-server.start()
-
-if os.access(wal, os.F_OK):
- print "corrupt .xlog exists after start"
-server.stop()
-lsn += 1
-
-server.start()
-orig_lsn = int(yaml.load(admin("box.info.server.lsn", silent=True))[0])
-
-# create .snap.inprogress
-admin("box.snapshot()")
-admin("box.space._schema:insert({'test', 'test'})")
-admin("box.snapshot()")
-lsn = int(yaml.load(admin("box.info.server.lsn", silent=True))[0])
-snapshot = str(lsn).zfill(20) + ".snap"
-snapshot = os.path.join(data_path, snapshot)
-server.stop()
-os.rename(snapshot, snapshot + ".inprogress")
-# remove .xlogs
-for f in os.listdir(data_path):
- if f.endswith(".xlog"):
- os.remove(os.path.join(data_path, f))
-
-# check that .snap.inprogress is ignored during scan
-server.start()
-lsn = int(yaml.load(admin("box.info.server.lsn", silent=True))[0])
-if lsn == orig_lsn:
- print ".snap.inprogress is ignored"
blob - c52f75c68d739c0643757f1ff535464777c33eda (mode 644)
blob + /dev/null
--- test/xlog/missing.result
+++ /dev/null
-space = box.schema.space.create('test')
----
-...
-index = box.space.test:create_index('primary')
----
-...
-box.space.test:insert{1, 'first tuple'}
----
-- [1, 'first tuple']
-...
-box.space.test:insert{2, 'second tuple'}
----
-- [2, 'second tuple']
-...
-box.space.test:insert{3, 'third tuple'}
----
-- [3, 'third tuple']
-...
-box.space.test:delete{1}
----
-- [1, 'first tuple']
-...
-box.space.test:delete{2}
----
-- [2, 'second tuple']
-...
-box.space.test:delete{3}
----
-- [3, 'third tuple']
-...
-check log line for 'ignoring a gap in LSN'
-
-'ignoring a gap in LSN' exists in server log
-
-box.space.test:select{}
----
-- []
-...
-box.space.test:drop()
----
-...
blob - 2f55bcc05f2039a92f2dea62f367ae1c6e5bc9cd (mode 644)
blob + /dev/null
--- test/xlog/missing.test.py
+++ /dev/null
-import yaml
-import os
-#
-# gh-716: infinite loop at start if missing xlog
-#
-
-server.stop()
-server.deploy()
-
-# Create wal#1
-server.admin("space = box.schema.space.create('test')")
-server.admin("index = box.space.test:create_index('primary')")
-server.stop()
-server.start()
-# these inserts will be in their own xlog, which then will
-# get "lost"
-lsn = int(yaml.load(server.admin("box.info.server.lsn", silent=True))[0])
-data_path = os.path.join(server.vardir, server.name)
-wal = os.path.join(data_path, str(lsn).zfill(20) + ".xlog")
-server.admin("box.space.test:insert{1, 'first tuple'}")
-server.admin("box.space.test:insert{2, 'second tuple'}")
-server.admin("box.space.test:insert{3, 'third tuple'}")
-server.stop()
-server.start()
-# put deletes in their own xlog
-server.admin("box.space.test:delete{1}")
-server.admin("box.space.test:delete{2}")
-server.admin("box.space.test:delete{3}")
-server.stop()
-
-# Remove xlog with inserts
-os.unlink(wal)
-# tarantool doesn't issue an LSN for deletes which delete nothing
-# this may lead to infinite recursion at start
-server.start()
-line="ignoring a gap in LSN"
-print "check log line for '%s'" % line
-print
-if server.logfile_pos.seek_once(line) >= 0:
- print "'%s' exists in server log" % line
-print
-
-# missing tuples from removed xlog
-server.admin("box.space.test:select{}")
-server.admin("box.space.test:drop()")
blob - /dev/null
blob + 3bd8968c20ce6457143be36e51d0231302846692 (mode 644)
--- /dev/null
+++ test/xlog-py/box.lua
+#!/usr/bin/env tarantool
+os = require('os')
+
+box.cfg{
+ listen = os.getenv("LISTEN"),
+ slab_alloc_arena = 0.1,
+ pid_file = "tarantool.pid",
+ panic_on_wal_error = false,
+ rows_per_wal = 10
+}
+
+require('console').listen(os.getenv('ADMIN'))
blob - /dev/null
blob + 53ae732283903afc0a2c0bcf9c8ba0ef645bc89a (mode 644)
--- /dev/null
+++ test/xlog-py/dup_key.result
+space = box.schema.space.create('test')
+---
+...
+index = box.space.test:create_index('primary')
+---
+...
+box.space.test:insert{1, 'first tuple'}
+---
+- [1, 'first tuple']
+...
+box.space.test:insert{2, 'second tuple'}
+---
+- [2, 'second tuple']
+...
+.xlog exists
+space = box.schema.space.create('test')
+---
+...
+index = box.space.test:create_index('primary')
+---
+...
+box.space.test:insert{1, 'first tuple'}
+---
+- [1, 'first tuple']
+...
+box.space.test:delete{1}
+---
+- [1, 'first tuple']
+...
+box.space.test:insert{1, 'third tuple'}
+---
+- [1, 'third tuple']
+...
+box.space.test:insert{2, 'fourth tuple'}
+---
+- [2, 'fourth tuple']
+...
+.xlog exists
+check log line for 'Duplicate key'
+
+'Duplicate key' exists in server log
+
+box.space.test:get{1}
+---
+- [1, 'first tuple']
+...
+box.space.test:get{2}
+---
+- [2, 'second tuple']
+...
+box.space.test:len()
+---
+- 2
+...
blob - /dev/null
blob + c727f074daa0fd589e35f987de6cb665196a86ba (mode 644)
--- /dev/null
+++ test/xlog-py/dup_key.test.py
+import os
+import yaml
+
+#print """
+#A test case for https://bugs.launchpad.net/tarantool/+bug/1052018
+#panic_on_wal_error doesn't work for duplicate key errors
+#"""
+
+server.stop()
+server.deploy()
+lsn = int(yaml.load(server.admin("box.info.server.lsn", silent=True))[0])
+filename = str(lsn).zfill(20) + ".xlog"
+vardir = os.path.join(server.vardir, server.name)
+wal_old = os.path.join(vardir, "old_" + filename)
+wal = os.path.join(vardir, filename)
+
+# Create wal#1
+server.admin("space = box.schema.space.create('test')")
+server.admin("index = box.space.test:create_index('primary')")
+server.admin("box.space.test:insert{1, 'first tuple'}")
+server.admin("box.space.test:insert{2, 'second tuple'}")
+server.stop()
+
+# Save wal #1
+if os.access(wal, os.F_OK):
+ print ".xlog exists"
+ os.rename(wal, wal_old)
+
+lsn += 4
+
+# Create another wal#1
+server.start()
+server.admin("space = box.schema.space.create('test')")
+server.admin("index = box.space.test:create_index('primary')")
+server.admin("box.space.test:insert{1, 'first tuple'}")
+server.admin("box.space.test:delete{1}")
+server.stop()
+
+# Create wal#2
+server.start()
+server.admin("box.space.test:insert{1, 'third tuple'}")
+server.admin("box.space.test:insert{2, 'fourth tuple'}")
+server.stop()
+
+if os.access(wal, os.F_OK):
+ print ".xlog exists"
+ # Replace wal#1 with saved copy
+ os.unlink(wal)
+ os.rename(wal_old, wal)
+
+
+server.start()
+line = 'Duplicate key'
+print "check log line for '%s'" % line
+print
+if server.logfile_pos.seek_once(line) >= 0:
+ print "'%s' exists in server log" % line
+print
+
+server.admin("box.space.test:get{1}")
+server.admin("box.space.test:get{2}")
+server.admin("box.space.test:len()")
+
blob - /dev/null
blob + 68ac8ab17503c24c2ed91747f241348de761709b (mode 644)
--- /dev/null
+++ test/xlog-py/empty.result
+.xlog exists
+_ = box.schema.space.create('test')
+---
+- error: Failed to write to disk
+...
+_ = box.schema.space.create('test')
+---
+...
+box.space.test:drop()
+---
+...
blob - /dev/null
blob + 1e810eede71736fdc9b23ed424d993b547d4da2d (mode 644)
--- /dev/null
+++ test/xlog-py/empty.test.py
+import os
+import yaml
+from os.path import abspath
+
+#
+# This test used to pass:
+#
+# Empty xlog.inprogress must be deleted during recovery
+#
+# it doesn't pass any more since an xlog with missing header
+# can't be parsed by xdir_scan, thus we do nothing about it.
+#
+server.stop()
+server.deploy()
+lsn = str(yaml.load(server.admin("box.info.server.lsn", silent=True))[0])
+path = os.path.join(server.vardir, server.name)
+filename = os.path.join(path, lsn.zfill(20) + ".xlog")
+f = open(filename, "w+")
+f.close()
+server.start()
+server.stop()
+if os.access(filename, os.F_OK):
+ print ".xlog exists"
+# the server has started but is crippled since it
+# can't override an existing file
+server.start()
+server.admin("_ = box.schema.space.create('test')")
+os.unlink(filename)
+server.admin("_ = box.schema.space.create('test')")
+server.admin("box.space.test:drop()")
blob - /dev/null
blob + 685fc1efa85aa2d0b44b3f778daf06eca18d799c (mode 644)
--- /dev/null
+++ test/xlog-py/lsn_gap.result
+space = box.schema.space.create('test')
+---
+...
+index = box.space.test:create_index('primary')
+---
+...
+box.space.test:insert{1, 'first tuple'}
+---
+- [1, 'first tuple']
+...
+box.space.test:insert{2, 'second tuple'}
+---
+- [2, 'second tuple']
+...
+box.space.test:insert{3, 'third tuple'}
+---
+- [3, 'third tuple']
+...
+box.space.test:insert{4, 'fourth tuple'}
+---
+- [4, 'fourth tuple']
+...
+check log line for 'ignoring a gap in LSN'
+
+'ignoring a gap in LSN' exists in server log
+
+box.space.test:select{}
+---
+- - [1, 'first tuple']
+ - [2, 'second tuple']
+ - [4, 'fourth tuple']
+...
blob - /dev/null
blob + c4281d89d9dd71f1b9916262518cda86850010c1 (mode 644)
--- /dev/null
+++ test/xlog-py/lsn_gap.test.py
+import os
+import yaml
+#
+# gh-167: Replica can't find next xlog file if there is a gap in LSN
+#
+
+server.stop()
+server.deploy()
+
+# Create wal#1
+server.admin("space = box.schema.space.create('test')")
+server.admin("index = box.space.test:create_index('primary')")
+server.admin("box.space.test:insert{1, 'first tuple'}")
+server.admin("box.space.test:insert{2, 'second tuple'}")
+lsn = int(yaml.load(server.admin("box.info.server.lsn", silent=True))[0])
+path = os.path.join(server.vardir, server.name)
+wal = os.path.join(path, str(lsn).zfill(20) + ".xlog")
+server.stop()
+server.start()
+server.admin("box.space.test:insert{3, 'third tuple'}")
+server.stop()
+server.start()
+server.admin("box.space.test:insert{4, 'fourth tuple'}")
+server.stop()
+
+# Remove xlog with {3, 'third tuple'}
+os.unlink(wal)
+
+server.start()
+line="ignoring a gap in LSN"
+print "check log line for '%s'" % line
+print
+if server.logfile_pos.seek_once(line) >= 0:
+ print "'%s' exists in server log" % line
+print
+
+# missing tuple from removed xlog
+server.admin("box.space.test:select{}")
+
blob - /dev/null
blob + d9452019bae099af646d270bfb889b2f12a2d6f8 (mode 644)
--- /dev/null
+++ test/xlog-py/misc.result
+
+# xlog file must exist after inserts.
+
+space = box.schema.space.create('tweedledum', { id = 0 })
+---
+...
+.xlog exists
+index = space:create_index('primary', { type = 'hash' })
+---
+...
+
+# a new xlog must be opened after regular termination.
+
+box.space[0]:insert{3, 'third tuple'}
+---
+- [3, 'third tuple']
+...
+a new .xlog exists
+.xlog stays around after sutdown
+
+# An xlog file with one record during recovery.
+
+box.space[0]:insert{4, 'fourth tuple'}
+---
+- [4, 'fourth tuple']
+...
+box.space[0]:insert{5, 'Unfinished record'}
+---
+- [5, 'Unfinished record']
+...
+.xlog exists after kill -9
+corrupt .xlog exists after start
+box.snapshot()
+---
+- ok
+...
+box.space._schema:insert({'test', 'test'})
+---
+- ['test', 'test']
+...
+box.snapshot()
+---
+- ok
+...
+.snap.inprogress is ignored
blob - /dev/null
blob + a182354b99a0f7484d9c9d199c2c354155c76e97 (mode 644)
--- /dev/null
+++ test/xlog-py/misc.test.py
+import os
+import yaml
+
+from os.path import abspath
+
+# cleanup server.vardir
+server.stop()
+server.deploy()
+lsn = int(yaml.load(server.admin("box.info.server.lsn", silent=True))[0])
+server.stop()
+
+data_path = os.path.join(server.vardir, server.name)
+
+print """
+# xlog file must exist after inserts.
+"""
+filename = str(lsn).zfill(20) + ".xlog"
+wal = os.path.join(data_path, filename)
+
+server.start()
+
+server.admin("space = box.schema.space.create('tweedledum', { id = 0 })")
+if os.access(wal, os.F_OK):
+ print ".xlog exists"
+
+server.admin("index = space:create_index('primary', { type = 'hash' })")
+
+server.stop()
+lsn += 2
+
+print """
+# a new xlog must be opened after regular termination.
+"""
+filename = str(lsn).zfill(20) + ".xlog"
+server.start()
+
+wal = os.path.join(data_path, filename)
+
+server.admin("box.space[0]:insert{3, 'third tuple'}")
+
+if os.access(wal, os.F_OK):
+ print "a new .xlog exists"
+
+server.stop()
+
+if os.access(wal, os.F_OK):
+ print ".xlog stays around after sutdown"
+lsn += 1
+
+print """
+# An xlog file with one record during recovery.
+"""
+
+server.start()
+filename = str(lsn).zfill(20) + ".xlog"
+wal = os.path.join(data_path, filename)
+server.admin("box.space[0]:insert{4, 'fourth tuple'}")
+server.admin("box.space[0]:insert{5, 'Unfinished record'}")
+pid = int(yaml.load(server.admin("require('tarantool').pid()", silent=True))[0])
+from signal import SIGKILL
+if pid > 0:
+ os.kill(pid, SIGKILL)
+server.stop()
+
+if os.access(wal, os.F_OK):
+ print ".xlog exists after kill -9"
+ # Remove last byte from xlog
+ f = open(wal, "a")
+ size = f.tell()
+ f.truncate(size - 1)
+ f.close()
+
+server.start()
+
+if os.access(wal, os.F_OK):
+ print "corrupt .xlog exists after start"
+server.stop()
+lsn += 1
+
+server.start()
+orig_lsn = int(yaml.load(admin("box.info.server.lsn", silent=True))[0])
+
+# create .snap.inprogress
+admin("box.snapshot()")
+admin("box.space._schema:insert({'test', 'test'})")
+admin("box.snapshot()")
+lsn = int(yaml.load(admin("box.info.server.lsn", silent=True))[0])
+snapshot = str(lsn).zfill(20) + ".snap"
+snapshot = os.path.join(data_path, snapshot)
+server.stop()
+os.rename(snapshot, snapshot + ".inprogress")
+# remove .xlogs
+for f in os.listdir(data_path):
+ if f.endswith(".xlog"):
+ os.remove(os.path.join(data_path, f))
+
+# check that .snap.inprogress is ignored during scan
+server.start()
+lsn = int(yaml.load(admin("box.info.server.lsn", silent=True))[0])
+if lsn == orig_lsn:
+ print ".snap.inprogress is ignored"
blob - /dev/null
blob + c52f75c68d739c0643757f1ff535464777c33eda (mode 644)
--- /dev/null
+++ test/xlog-py/missing.result
+space = box.schema.space.create('test')
+---
+...
+index = box.space.test:create_index('primary')
+---
+...
+box.space.test:insert{1, 'first tuple'}
+---
+- [1, 'first tuple']
+...
+box.space.test:insert{2, 'second tuple'}
+---
+- [2, 'second tuple']
+...
+box.space.test:insert{3, 'third tuple'}
+---
+- [3, 'third tuple']
+...
+box.space.test:delete{1}
+---
+- [1, 'first tuple']
+...
+box.space.test:delete{2}
+---
+- [2, 'second tuple']
+...
+box.space.test:delete{3}
+---
+- [3, 'third tuple']
+...
+check log line for 'ignoring a gap in LSN'
+
+'ignoring a gap in LSN' exists in server log
+
+box.space.test:select{}
+---
+- []
+...
+box.space.test:drop()
+---
+...
blob - /dev/null
blob + 2f55bcc05f2039a92f2dea62f367ae1c6e5bc9cd (mode 644)
--- /dev/null
+++ test/xlog-py/missing.test.py
+import yaml
+import os
+#
+# gh-716: infinite loop at start if missing xlog
+#
+
+server.stop()
+server.deploy()
+
+# Create wal#1
+server.admin("space = box.schema.space.create('test')")
+server.admin("index = box.space.test:create_index('primary')")
+server.stop()
+server.start()
+# these inserts will be in their own xlog, which then will
+# get "lost"
+lsn = int(yaml.load(server.admin("box.info.server.lsn", silent=True))[0])
+data_path = os.path.join(server.vardir, server.name)
+wal = os.path.join(data_path, str(lsn).zfill(20) + ".xlog")
+server.admin("box.space.test:insert{1, 'first tuple'}")
+server.admin("box.space.test:insert{2, 'second tuple'}")
+server.admin("box.space.test:insert{3, 'third tuple'}")
+server.stop()
+server.start()
+# put deletes in their own xlog
+server.admin("box.space.test:delete{1}")
+server.admin("box.space.test:delete{2}")
+server.admin("box.space.test:delete{3}")
+server.stop()
+
+# Remove xlog with inserts
+os.unlink(wal)
+# tarantool doesn't issue an LSN for deletes which delete nothing
+# this may lead to infinite recursion at start
+server.start()
+line="ignoring a gap in LSN"
+print "check log line for '%s'" % line
+print
+if server.logfile_pos.seek_once(line) >= 0:
+ print "'%s' exists in server log" % line
+print
+
+# missing tuples from removed xlog
+server.admin("box.space.test:select{}")
+server.admin("box.space.test:drop()")
blob - /dev/null
blob + 830cc8fcc5d81fb47745a50678d6c433a2ec43b3 (mode 644)
--- /dev/null
+++ test/xlog-py/suite.ini
+[default]
+core = tarantool
+description = legacy python tests
+script = box.lua
+lua_libs = lua/fiber.lua lua/fifo.lua
+use_unix_sockets = True