Commit Diff


commit - 2c71fd7fbb7b483ce8739c90161010523b5347da
commit + af929c2339f3d0da3ef896322d9909157237c4b1
blob - b79c47df76797803d9d027a7d5e02929140da049
blob + 72ded82383c28c0e72e86006e564e884324edaa6
--- .gitignore
+++ .gitignore
@@ -49,7 +49,7 @@ src/box/bootstrap.h
 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
@@ -8,6 +8,11 @@ compiler:
   - clang
   - gcc
 
+matrix:
+  exclude:
+    - os: osx
+      compiler: gcc
+
 addons:
   postgresql: "9.1"
 
blob - 2faa825ca61e4c77f1384f80f5c05633239e6ca9
blob + 8437eaedf5cf19b28fb123414c824eb8213e7f23
--- Doxyfile.API.in
+++ Doxyfile.API.in
@@ -1,5 +1,5 @@
 @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
@@ -7,7 +7,7 @@ include/tarantool/lua.hpp
 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
@@ -1,6 +1,6 @@
 # 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)
@@ -20,7 +20,7 @@ function(rebuild_module_api)
         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}
@@ -28,15 +28,15 @@ function(rebuild_module_api)
             -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
@@ -2,5 +2,5 @@
                             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
@@ -227,7 +227,7 @@ chkconfig --del tarantool
 "%{_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
@@ -3,8 +3,6 @@
 #
 enable_tnt_compile_flags()
 
-add_subdirectory(trivia)
-
 include_directories(${LIBEV_INCLUDE_DIR})
 include_directories(${LIBEIO_INCLUDE_DIR})
 include_directories(${LIBCORO_INCLUDE_DIR})
@@ -117,6 +115,26 @@ set (server_sources
      ${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
@@ -45,6 +45,7 @@
 #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
@@ -1939,10 +1940,13 @@ on_commit_dd_cluster(struct trigger *trigger, void *ev
 		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);
 }
 
 /**
@@ -1977,6 +1981,8 @@ on_replace_dd_cluster(struct trigger *trigger, void *e
 		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
@@ -463,8 +463,8 @@ boxk(enum iproto_type type, uint32_t space_id, const c
 	}
 	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);
 }
 
@@ -657,9 +657,6 @@ box_on_cluster_join(const tt_uuid *server_uuid)
 	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));
 }
@@ -704,17 +701,24 @@ box_process_subscribe(int fd, struct xrow_header *head
 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
@@ -72,25 +72,16 @@ cluster_clock()
 }
 
 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);
@@ -107,9 +98,28 @@ cluster_set_server(const tt_uuid *server_uuid, uint32_
 }
 
 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
@@ -111,9 +111,15 @@ cserver_id_is_reserved(uint32_t id)
  * 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
@@ -43,6 +43,7 @@ extern "C" {
 #include "box/schema.h"
 #include "box/tuple.h"
 #include "box/txn.h"
+#include "box/vclock.h" /* VCLOCK_MAX */
 
 /**
  * Trigger function for all spaces
@@ -332,5 +333,7 @@ box_lua_space_init(struct lua_State *L)
 	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
@@ -152,6 +152,7 @@ vclock_sum(const struct vclock *vclock)
 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
@@ -0,0 +1,5 @@
+#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
@@ -0,0 +1,27 @@
+#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
@@ -1,19 +0,0 @@
-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
@@ -1,5 +0,0 @@
-#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
@@ -1,27 +0,0 @@
-#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
@@ -1,6 +1,5 @@
 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
@@ -333,14 +333,12 @@ local function test_ucdata(test, s)
 
     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
@@ -1,5 +1,5 @@
 #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
@@ -1,51 +0,0 @@
-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
@@ -1,25 +0,0 @@
-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
@@ -1,23 +0,0 @@
-
- #
- # 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
@@ -1,46 +0,0 @@
-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
@@ -1,142 +0,0 @@
-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
@@ -1,34 +0,0 @@
-
-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
@@ -1,766 +0,0 @@
-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
@@ -1,192 +0,0 @@
-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
@@ -1,5 +1,5 @@
 #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
@@ -1,131 +0,0 @@
-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
@@ -1,213 +0,0 @@
-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
@@ -663,7 +663,7 @@ i2:delete{8}
 ---
 - [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
@@ -191,7 +191,7 @@ s:insert{1, 2, 3}
 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
@@ -1,25 +0,0 @@
-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
@@ -1,34 +0,0 @@
-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
@@ -1,57 +0,0 @@
-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
@@ -1,72 +0,0 @@
-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
@@ -1,29 +0,0 @@
-#
-# 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
@@ -1,46 +0,0 @@
-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
@@ -1,4 +1,10 @@
 --UPSERT https://github.com/tarantool/tarantool/issues/905
+env = require('test_run')
+---
+...
+test_run = env.new()
+---
+...
 s = box.schema.create_space('tweedledum')
 ---
 ...
@@ -147,7 +153,10 @@ s:drop()
 ---
 ...
 --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'
@@ -226,7 +235,10 @@ function test(key_tuple, ops, expect)
 end;
 ---
 ...
---# setopt delimiter ''
+test_run:cmd("setopt delimiter ''");
+---
+- true
+...
 engine = 'memtx'
 ---
 ...
@@ -480,9 +492,11 @@ test(t, {{':', 3, 3, 3, ''}, {'|', 3, 4}}, {{1, '1', 4
 ---
 - 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'
@@ -512,7 +526,10 @@ function anything_to_string(tab)
 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
@@ -1,4 +1,6 @@
 --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')
 
@@ -43,7 +45,7 @@ s:select{0}
 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'
@@ -117,7 +119,7 @@ function test(key_tuple, ops, expect)
             ') 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})
@@ -200,10 +202,9 @@ t[1] = 3
 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'
@@ -231,7 +232,7 @@ function anything_to_string(tab)
     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
@@ -1 +0,0 @@
-Expected error: <type 'exceptions.OSError'>
blob - c471892f1770175dc9510225936e84021e865c1a (mode 644)
blob + /dev/null
--- test/long_run/finalizers.test.py
+++ /dev/null
@@ -1,17 +0,0 @@
-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
@@ -1,6 +1,8 @@
 #!/usr/bin/env tarantool
+env = require('test_run')
+test_run = env.new()
 
---# setopt delimiter ';'
+test_run:cmd("setopt delimiter ';'")
 
 function on_gc(t)
 end;
@@ -16,7 +18,7 @@ function test_finalizers()
     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
@@ -0,0 +1,51 @@
+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
@@ -0,0 +1,25 @@
+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
@@ -0,0 +1,23 @@
+
+ #
+ # 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
@@ -0,0 +1,46 @@
+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
@@ -0,0 +1,142 @@
+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
@@ -0,0 +1,34 @@
+
+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
@@ -0,0 +1,12 @@
+#!/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
@@ -0,0 +1,766 @@
+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
@@ -0,0 +1,192 @@
+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
@@ -0,0 +1,131 @@
+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
@@ -0,0 +1,213 @@
+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
@@ -0,0 +1,25 @@
+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
@@ -0,0 +1,34 @@
+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
@@ -0,0 +1,9 @@
+#!/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
@@ -0,0 +1,57 @@
+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
@@ -0,0 +1,72 @@
+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
@@ -0,0 +1,29 @@
+#
+# 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
@@ -0,0 +1,46 @@
+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
@@ -0,0 +1,6 @@
+[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
@@ -1,195 +0,0 @@
-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
@@ -1,216 +0,0 @@
-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
@@ -1,63 +0,0 @@
-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
@@ -1,120 +0,0 @@
-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
@@ -0,0 +1,29 @@
+
+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
@@ -1,145 +0,0 @@
-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
@@ -1,106 +0,0 @@
-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
@@ -0,0 +1,128 @@
+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
@@ -0,0 +1,58 @@
+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
@@ -1,81 +0,0 @@
-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
@@ -1,111 +0,0 @@
-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
@@ -1,41 +0,0 @@
-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
@@ -1,46 +0,0 @@
-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
@@ -185,3 +185,6 @@ box.snapshot()
 ---
 - ok
 ...
+box.schema.user.revoke('guest', 'replication')
+---
+...
blob - 4a35739b9b1706942db018a200a953de28ebf1c1
blob + 0d5d40aa6ab171bfe2745e031e12016c78791e06
--- test/replication/s_join.test.lua
+++ test/replication/s_join.test.lua
@@ -20,3 +20,4 @@ test_run:cmd("stop server replica")
 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
@@ -1,152 +0,0 @@
-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
@@ -1,34 +0,0 @@
-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
@@ -1,10 +1,28 @@
---# 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
 ---
 ...
@@ -27,12 +45,18 @@ box.space._schema:insert({'dup'})
 ---
 - ['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
 ---
 ...
@@ -55,7 +79,10 @@ box.info.replication.status == "off"
 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()
@@ -70,7 +97,10 @@ slowpoke_loop = function(s, peer)
 end;
 ---
 ...
---# setopt delimiter ''
+test_run:cmd("setopt delimiter ''");
+---
+- true
+...
 slowpoke = require('socket').tcp_server('127.0.0.1', 0, slowpoke_loop)
 ---
 ...
@@ -172,9 +202,18 @@ r.idle < 1
 ---
 - 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
@@ -1,8 +1,10 @@
---# 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
@@ -11,9 +13,9 @@ r.lag < 1
 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
@@ -23,7 +25,7 @@ box.info.replication.status == "off"
 
 -- 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()
@@ -36,7 +38,7 @@ slowpoke_loop = function(s, peer)
     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()
@@ -78,7 +80,7 @@ box.cfg { replication_source = source }
 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
@@ -4,3 +4,4 @@ script =  master.lua
 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
@@ -1,5884 +0,0 @@
-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
@@ -1,124 +0,0 @@
-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
@@ -0,0 +1,21 @@
+#!/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
@@ -0,0 +1 @@
+Expected error: <type 'exceptions.OSError'>
blob - /dev/null
blob + c471892f1770175dc9510225936e84021e865c1a (mode 644)
--- /dev/null
+++ test/long_run-py/finalizers.test.py
@@ -0,0 +1,17 @@
+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
@@ -0,0 +1,9 @@
+[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
@@ -0,0 +1,111 @@
+
+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
@@ -0,0 +1,201 @@
+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
@@ -0,0 +1,212 @@
+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
@@ -0,0 +1,63 @@
+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
@@ -0,0 +1,120 @@
+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
@@ -0,0 +1,145 @@
+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
@@ -0,0 +1,106 @@
+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
@@ -0,0 +1,8 @@
+#!/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
@@ -0,0 +1,81 @@
+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
@@ -0,0 +1,111 @@
+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
@@ -0,0 +1,41 @@
+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
@@ -0,0 +1,46 @@
+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
@@ -0,0 +1,9 @@
+#!/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
@@ -0,0 +1,4 @@
+[default]
+core = tarantool
+script =  master.lua
+description = tarantool/box, replication
blob - /dev/null
blob + 84bacc69969560584eeb4a3efbe6768cf58f429c (mode 644)
--- /dev/null
+++ test/replication-py/swap.result
@@ -0,0 +1,5884 @@
+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
@@ -0,0 +1,124 @@
+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
@@ -1,54 +0,0 @@
-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
@@ -1,63 +0,0 @@
-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
@@ -1,8 +0,0 @@
-.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
@@ -1,29 +0,0 @@
-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
@@ -1,32 +0,0 @@
-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
@@ -1,39 +0,0 @@
-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
@@ -1,45 +0,0 @@
-
-# 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
@@ -1,101 +0,0 @@
-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
@@ -1,41 +0,0 @@
-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
@@ -1,45 +0,0 @@
-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
@@ -0,0 +1,12 @@
+#!/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
@@ -0,0 +1,54 @@
+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
@@ -0,0 +1,63 @@
+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
@@ -0,0 +1,11 @@
+.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
@@ -0,0 +1,30 @@
+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
@@ -0,0 +1,32 @@
+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
@@ -0,0 +1,39 @@
+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
@@ -0,0 +1,45 @@
+
+# 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
@@ -0,0 +1,101 @@
+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
@@ -0,0 +1,41 @@
+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
@@ -0,0 +1,45 @@
+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
@@ -0,0 +1,6 @@
+[default]
+core = tarantool
+description = legacy python tests
+script = box.lua
+lua_libs = lua/fiber.lua lua/fifo.lua
+use_unix_sockets = True