diff --git a/debian/tarantool-common.logrotate b/debian/tarantool-common.logrotate
index 4fc10a52c0ddaa3f83751666ea5d07e32010e237..7d08ce3cf59ea1e7a7a255be0f3b802e2cef550d 100644
--- a/debian/tarantool-common.logrotate
+++ b/debian/tarantool-common.logrotate
@@ -7,7 +7,7 @@
     delaycompress
     create 0640 tarantool adm
     postrotate
-        /usr/bin/tarantool /usr/lib/tarantool/dist.lua logrotate `basename $1 .log`
+        /usr/bin/tarantool /usr/bin/tarantoolctl logrotate `basename $1 .log`
     endscript
 }
 
diff --git a/extra/dist/default/tarantool b/extra/dist/default/tarantool
index 81faf68920a1a7d6b61794b59c2ed71c736a532c..a861bdf5f135e95405a28eab718517f5992537d6 100644
--- a/extra/dist/default/tarantool
+++ b/extra/dist/default/tarantool
@@ -1,10 +1,11 @@
 -- Options for Tarantool
 default_cfg = {
-    pid_file    =   "/var/run/tarantool", -- will become pid_file .. instance .. '.pid'
-    wal_dir     =   "/var/lib/tarantool", -- will become wal_dir/instance/
-    snap_dir    =   "/var/lib/tarantool", -- snap_dir/instance/
-    logger      =   "/var/log/tarantool", -- logger/instance .. '.log'
-    username    =   "tarantool",
+    pid_file   = "/var/run/tarantool", -- will become pid_file .. instance .. '.pid'
+    wal_dir    = "/var/lib/tarantool", -- will become wal_dir/instance/
+    snap_dir   = "/var/lib/tarantool", -- snap_dir/instance/
+    sophia_dir = "/var/lib/tarantool", -- will become sophia_dir/sophia/instance/
+    logger     = "/var/log/tarantool", -- logger/instance .. '.log'
+    username   = "tarantool",
 }
 
 instance_dir = "/etc/tarantool/instances.enabled"
diff --git a/extra/dist/dist.lua b/extra/dist/dist.lua
index e103a2de90d153a73094e5e2eefbe2565c68b343..8a27a76e8cfd50aa0a39eb7451be975519699e7f 100755
--- a/extra/dist/dist.lua
+++ b/extra/dist/dist.lua
@@ -31,6 +31,9 @@ The file contains common default instances options:
         
         -- snap_dir/instance/
         snap_dir    =   "/var/lib/tarantool",
+
+        -- sophia_dir/instance/
+        sophia_dir  =   "/var/lib/tarantool/sophia",
         
         -- logger/instance .. '.log'
         logger      =   "/var/log/tarantool",
@@ -111,19 +114,21 @@ if instance_dir == nil then
     instance_dir = '/etc/tarantool/instances.enabled'
 end
 
-default_cfg.pid_file =  default_cfg.pid_file and default_cfg.pid_file or "/var/run/tarantool"
-default_cfg.wal_dir =  default_cfg.wal_dir and default_cfg.wal_dir or "/var/lib/tarantool"
-default_cfg.snap_dir =  default_cfg.snap_dir and default_cfg.snap_dir or "/var/lib/tarantool"
-default_cfg.logger =  default_cfg.logger and default_cfg.logger or "/var/log/tarantool"
-default_cfg.username =  default_cfg.username and default_cfg.username or "tarantool"
+default_cfg.pid_file   = default_cfg.pid_file and default_cfg.pid_file or "/var/run/tarantool"
+default_cfg.wal_dir    = default_cfg.wal_dir and default_cfg.wal_dir or "/var/lib/tarantool"
+default_cfg.snap_dir   = default_cfg.snap_dir and default_cfg.snap_dir or "/var/lib/tarantool"
+default_cfg.sophia_dir = default_cfg.sophia_dir and default_cfg.sophia_dir or "/var/lib/tarantool"
+default_cfg.logger     = default_cfg.logger and default_cfg.logger or "/var/log/tarantool"
+default_cfg.username   = default_cfg.username and default_cfg.username or "tarantool"
 
 -- create  a path to the control socket (admin console)
 local console_sock = fio.pathjoin(default_cfg.pid_file, instance .. '.control')
 
-default_cfg.pid_file = fio.pathjoin(default_cfg.pid_file, instance .. '.pid')
-default_cfg.wal_dir = fio.pathjoin(default_cfg.wal_dir, instance)
-default_cfg.snap_dir = fio.pathjoin(default_cfg.snap_dir, instance)
-default_cfg.logger = fio.pathjoin(default_cfg.logger, instance .. '.log')
+default_cfg.pid_file   = fio.pathjoin(default_cfg.pid_file, instance .. '.pid')
+default_cfg.wal_dir    = fio.pathjoin(default_cfg.wal_dir, instance)
+default_cfg.snap_dir   = fio.pathjoin(default_cfg.snap_dir, instance)
+default_cfg.sophia_dir = fio.pathjoin(default_cfg.sophia_dir, instance, 'sophia')
+default_cfg.logger     = fio.pathjoin(default_cfg.logger, instance .. '.log')
 
 local instance_lua = fio.pathjoin(instance_dir, instance .. '.lua')
 
@@ -146,16 +151,18 @@ function mk_default_dirs(cfg)
     if fio.stat(pid_dir) == nil then
         mkdir(pid_dir)
     end
-
     -- create wal_dir 
     if fio.stat(cfg.wal_dir) == nil then
         mkdir(cfg.wal_dir)
     end
-
     -- create snap_dir 
     if fio.stat(cfg.snap_dir) == nil then
         mkdir(cfg.snap_dir)
     end
+    -- create sophia_dir
+    if fio.stat(cfg.sophia_dir) == nil then
+        mkdir(cfg.sophia_dir)
+    end
     -- create log_dir
     log_dir = fio.dirname(cfg.logger)
     if log_dir:find('|') == nil and fio.stat(log_dir) == nil then
diff --git a/src/box/box.cc b/src/box/box.cc
index e1bc1271665f37780be61539d87a4c409a576eff..a4af9caa02bd1d899767e99a25a3db0a49dca52c 100644
--- a/src/box/box.cc
+++ b/src/box/box.cc
@@ -125,6 +125,7 @@ box_check_replication_source(const char *source)
 static void
 box_check_wal_mode(const char *mode_name)
 {
+	assert(mode_name != NULL); /* checked in Lua */
 	int mode = strindex(wal_mode_STRS, mode_name, WAL_MODE_MAX);
 	if (mode == WAL_MODE_MAX) {
 		tnt_raise(ClientError, ER_CFG,
diff --git a/src/box/lua/load_cfg.lua b/src/box/lua/load_cfg.lua
index 3b073880ea5dffe4eff97924ddbaf742256c45f2..47496a3e64d8c2c0834214b20cddab28acf7b028 100644
--- a/src/box/lua/load_cfg.lua
+++ b/src/box/lua/load_cfg.lua
@@ -59,7 +59,7 @@ local default_cfg = {
 
 -- types of available options
 -- could be comma separated lua types or 'any' if any type is allowed
-local template_cfg = {
+local template = {
     listen              = 'string, number',
     slab_alloc_arena    = 'number',
     slab_alloc_minimal  = 'number',
@@ -104,45 +104,9 @@ local dynamic_cfg = {
     snapshot_count          = box.internal.snap_daemon.set_snapshot_count,
 }
 
-local function reload_cfg(oldcfg, newcfg)
-    if newcfg == nil then
-        newcfg = {}
-    end
-    for key, val in pairs(newcfg) do
-        if dynamic_cfg[key] == nil then
-            box.error(box.error.RELOAD_CFG, key);
-        end
-        if val == "" then
-            val = nil
-        end
-        if wrapper_cfg[key] ~= nil then
-            val = wrapper_cfg[key](val)
-        end
-        dynamic_cfg[key](val)
-        rawset(oldcfg, key, val)
-    end
-    if type(box.on_reload_configuration) == 'function' then
-        box.on_reload_configuration()
-    end
-end
-
-local box = require('box')
--- Move all box members to box_saved
-local box_configured = {}
-for k, v in pairs(box) do
-    box_configured[k] = v
-    box[k] = nil
-end
-
-setmetatable(box, {
-    __index = function(table, index)
-        error("Please call box.cfg{} first")
-     end
-})
-
-local function check_param_table(table, template)
+local function prepare_cfg(table)
     if table == nil then
-        return
+        return {}
     end
     if type(table) ~= 'table' then
         error("Error: cfg should be a table")
@@ -151,9 +115,13 @@ local function check_param_table(table, template)
     if table.dont_check then
         return
     end
+    local newtable = {}
     for k,v in pairs(table) do
         if template[k] == nil then
             error("Error: cfg parameter '" .. k .. "' is unexpected")
+        elseif v == "" or v == nil then
+            -- "" and NULL = ffi.cast('void *', 0) set option to default value
+            v = default_cfg[k]
         elseif template[k] == 'any' then
             -- any type is ok
         elseif (string.find(template[k], ',') == nil) then
@@ -168,29 +136,48 @@ local function check_param_table(table, template)
                 error("Error: cfg parameter '" .. k .. "' should be one of types: " .. template[k])
             end
         end
+        if wrapper_cfg[k] ~= nil then
+            v = wrapper_cfg[k](v)
+        end
+        newtable[k] = v
     end
+    return newtable
 end
 
-
-local function update_param_table(table, defaults)
-    if table == nil then
-        table = {}
-    end
-    for k,v in pairs(defaults) do
-        if table[k] == nil then
-            table[k] = v
+local function reload_cfg(oldcfg, newcfg)
+    newcfg = prepare_cfg(newcfg)
+    for key, val in pairs(newcfg) do
+        if dynamic_cfg[key] == nil then
+            box.error(box.error.RELOAD_CFG, key);
         end
+        dynamic_cfg[key](val)
+        rawset(oldcfg, key, val)
+    end
+    if type(box.on_reload_configuration) == 'function' then
+        box.on_reload_configuration()
     end
-    return table
 end
 
-function box.cfg(cfg)
-    check_param_table(cfg, template_cfg)
-    cfg = update_param_table(cfg, default_cfg)
+local box = require('box')
+-- Move all box members to box_saved
+local box_configured = {}
+for k, v in pairs(box) do
+    box_configured[k] = v
+    box[k] = nil
+end
 
-    for k,v in pairs(wrapper_cfg) do
-        -- options that can be number or string
-        cfg[k] = wrapper_cfg[k](cfg[k])
+setmetatable(box, {
+    __index = function(table, index)
+        error("Please call box.cfg{} first")
+     end
+})
+
+function box.cfg(cfg)
+    cfg = prepare_cfg(cfg)
+    for k,v in pairs(default_cfg) do
+        if cfg[k] == nil then
+            cfg[k] = v
+        end
     end
     -- Restore box members from box_saved after initial configuration
     for k, v in pairs(box_configured) do
diff --git a/src/box/lua/schema.lua b/src/box/lua/schema.lua
index bb1e9a46f2f4a0d167c9a0b39baad5a224a7494b..e925bd17bb58505f887ae0bf0c64e2374083138e 100644
--- a/src/box/lua/schema.lua
+++ b/src/box/lua/schema.lua
@@ -188,7 +188,7 @@ box.schema.space.create = function(name, options)
         engine = 'string',
         id = 'number',
         field_count = 'number',
-        user = 'user',
+        user = 'string, number',
     }
     local options_defaults = {
         engine = 'memtx',
diff --git a/src/box/sophia_index.cc b/src/box/sophia_index.cc
index c82c9a717f548747970285de45d4ec1a69ee36df..b50bf1c2c128acfe6a54323428d6387a01ac8bc0 100644
--- a/src/box/sophia_index.cc
+++ b/src/box/sophia_index.cc
@@ -176,6 +176,31 @@ SophiaIndex::~SophiaIndex()
 	}
 }
 
+struct tuple *
+SophiaIndex::random(uint32_t rnd) const
+{
+	void *o = sp_object(db);
+	if (o == NULL)
+		tnt_raise(ClientError, ER_SOPHIA, sp_error(db));
+	sp_set(o, "key", &rnd, sizeof(rnd));
+	void *c = sp_cursor(db, "random", o);
+	if (c == NULL)
+		tnt_raise(ClientError, ER_SOPHIA, sp_error(db));
+	auto scoped_guard =
+		make_scoped_guard([=] { sp_destroy(c); });
+	o = sp_get(c);
+	if (o == NULL)
+		return NULL;
+	struct space *space = space_cache_find(key_def->space_id);
+	int valuesize;
+	void *value = sp_get(o, "value", &valuesize);
+	struct tuple *ret =
+		tuple_new(space->format, (char*)value,
+		          (char*)value + valuesize);
+	tuple_ref(ret, 1);
+	return ret;
+}
+
 void
 SophiaIndex::endBuild()
 {
@@ -184,9 +209,9 @@ SophiaIndex::endBuild()
 size_t
 SophiaIndex::size() const
 {
-	tnt_raise(ClientError, ER_UNSUPPORTED,
-	          "SophiaIndex", "size operation");
-	return 0;
+	void *profiler = sp_ctl(db, "profiler");
+	uint64_t count = *(uint64_t*)sp_get(profiler, "count", NULL);
+	return count;
 }
 
 size_t
diff --git a/src/box/sophia_index.h b/src/box/sophia_index.h
index 063961d790843fd5f5c17a6977327f5b0ffc14c6..322db9d97b17a5f763f12b9b9fbbfeab746c8878 100644
--- a/src/box/sophia_index.h
+++ b/src/box/sophia_index.h
@@ -38,12 +38,11 @@ class SophiaIndex: public Index {
 
 	virtual size_t size() const;
 	virtual void endBuild();
-
+	virtual struct tuple *random(uint32_t rnd) const;
 	virtual struct tuple *findByKey(const char *key, uint32_t part_count) const;
 	virtual struct tuple *replace(struct tuple *old_tuple,
 				      struct tuple *new_tuple,
 				      enum dup_replace_mode mode);
-
 	virtual struct iterator *allocIterator() const;
 	virtual void initIterator(struct iterator *iterator,
 				  enum iterator_type type,
diff --git a/src/lua/bsdsocket.cc b/src/lua/bsdsocket.cc
index 9e1e1693ad30c545036faeb8955df280d6bf9fe0..422571af9aef4323fe2188c44657682353a013c4 100644
--- a/src/lua/bsdsocket.cc
+++ b/src/lua/bsdsocket.cc
@@ -336,8 +336,8 @@ bsdsocket_local_resolve(const char *host, const char *port,
 	}
 
 	/* IPv6 */
-	char ipv6[16];
-	if (inet_pton(AF_INET6, host, ipv6) == 1) {
+	struct in6_addr ipv6;
+	if (inet_pton(AF_INET6, host, &ipv6) == 1) {
 		struct sockaddr_in6 *inaddr6 = (struct sockaddr_in6 *) addr;
 		if (*socklen < sizeof(*inaddr6)) {
 			errno = ENOBUFS;
@@ -345,8 +345,8 @@ bsdsocket_local_resolve(const char *host, const char *port,
 		}
 		memset(inaddr6, 0, sizeof(*inaddr6));
 		inaddr6->sin6_family = AF_INET6;
-		inaddr6->sin6_port = htonl(atol(port));
-		memcpy(inaddr6->sin6_addr.s6_addr, ipv6, 16);
+		inaddr6->sin6_port = htons(atoi(port));
+		memcpy(inaddr6->sin6_addr.s6_addr, &ipv6, sizeof(ipv6));
 		*socklen = sizeof(*inaddr6);
 		return 0;
 	}
@@ -804,6 +804,24 @@ lbox_bsdsocket_peername(struct lua_State *L)
 	return 1;
 }
 
+static int
+lbox_bsdsocket_accept(struct lua_State *L)
+{
+	int fh = lua_tointeger(L, 1);
+
+	struct sockaddr_storage fa;
+	socklen_t len = sizeof(fa);
+
+	int sc = accept(fh, (struct sockaddr*)&fa, &len);
+	if (sc < 0) {
+		lua_pushnil(L);
+		return 1;
+	}
+	lua_pushnumber(L, sc);
+	lbox_bsdsocket_push_addr(L, (struct sockaddr *)&fa, len);
+	return 2;
+}
+
 static int
 lbox_bsdsocket_recvfrom(struct lua_State *L)
 {
@@ -860,6 +878,7 @@ tarantool_lua_bsdsocket_init(struct lua_State *L)
 		{ "peer",		lbox_bsdsocket_peername		},
 		{ "recvfrom",		lbox_bsdsocket_recvfrom		},
 		{ "abort",		lbox_bsdsocket_abort		},
+		{ "accept",		lbox_bsdsocket_accept		},
 		{ NULL,			NULL				}
 	};
 
diff --git a/src/lua/bsdsocket.lua b/src/lua/bsdsocket.lua
index 871bdbd356a6fdf65f1d67199b3681c9b0a3dffc..e7aa926cda7ada49175a24c5132020c859babdab 100644
--- a/src/lua/bsdsocket.lua
+++ b/src/lua/bsdsocket.lua
@@ -504,12 +504,12 @@ socket_methods.accept = function(self)
     local fd = check_socket(self)
     self._errno = nil
 
-    local cfd = ffi.C.accept(fd, nil, nil)
-    if cfd < 1 then
+    local cfd, from = internal.accept(fd)
+    if cfd == nil then
         self._errno = box.errno()
         return nil
     end
-    return bless_socket(cfd)
+    return bless_socket(cfd), from
 end
 
 local function readchunk(self, size, timeout)
@@ -964,96 +964,80 @@ local function tcp_connect(host, port, timeout)
     return nil
 end
 
-local function tcp_server_remote(list, prepare, handler)
-    local slist = {}
-
-    -- bind/create sockets
-    for _, addr in pairs(list) do
-        local s = create_socket(addr.family, addr.type, addr.protocol)
-
-        local ok = false
-        if s ~= nil then
-            local backlog = prepare(s)
-            if s:bind(addr.host, addr.port) then
-                if s:listen(backlog) then
-                    ok = true
-                end
-            end
-        end
-
-        -- errors
-        if not ok then
-            if s ~= nil then
-                s:close()
-            end
-            local save_errno = boxerrno()
-            for _, s in pairs(slist) do
-                s:close()
-            end
-            boxerrno(save_errno)
-            return nil
-        end
-
-        table.insert(slist, s)
-    end
-    
-    local server = { s = slist }
+local function tcp_server_handler(server, sc, from)
+    fiber.name(sprintf("%s/client/%s:%s", server.name, from.host, from.port))
+    server.handler(sc, from)
+    sc:close()
+end
 
-    server.stop = function()
-        if #server.s == 0 then
-            return false
+local function tcp_server_loop(server, s, addr)
+    fiber.name(sprintf("%s/listen/%s:%s", server.name, addr.host, addr.port))
+    while s:readable() do
+        local sc, from = s:accept()
+        if sc == nil then
+            break
         end
-        for _, s in pairs(server.s) do
-            s:close()
-        end
-        server.s = {}
-        return true
+        fiber.create(tcp_server_handler, server, sc, from)
     end
-
-    for _, s in pairs(server.s) do
-        fiber.create(function(s)
-            fiber.name(sprintf("listen_fd=%d",s:fd()))
-
-            while s:readable() do
-                
-                local sc = s:accept()
-
-                if sc == nil then
-                    break
-                end
-
-                fiber.create(function(sc)
-                    pcall(handler, sc)
-                    sc:close()
-                end, sc)
-            end
-        end, s)
+    if addr.family == 'AF_UNIX' and addr.port then
+        os.remove(addr.port) -- remove unix socket
     end
-
-    return server
 end
 
-local function tcp_server(host, port, prepare, handler, timeout)
-    if handler == nil then
-        handler = prepare
-        prepare = function() end
-    end
+local function tcp_server_usage()
+    error('Usage: socket.tcp_server(host, port, handler | opts)')
+end
 
-    if type(prepare) ~= 'function' or type(handler) ~= 'function' then
-        error("Usage: socket.tcp_server(host, port[, prepare], handler)")
+local function tcp_server(host, port, opts, timeout)
+    local server = {}
+    if type(opts) == 'function' then
+        server.handler = opts
+    elseif type(opts) == 'table' then
+        if type(opts.handler) ~='function' or (opts.prepare ~= nil and
+            type(opts.prepare) ~= 'function') then
+            tcp_server_usage()
+        end
+        for k, v in pairs(opts) do
+            server[k] = v
+        end
+    else
+        tcp_server_usage()
     end
-
+    server.name = server.name or 'server'
+    timeout = timeout and tonumber(timeout) or TIMEOUT_INFINITY
+    local dns
     if host == 'unix/' then
-        return tcp_server_remote({{host = host, port = port, protocol = 0,
-            family = 'PF_UNIX', type = 'SOCK_STREAM' }}, prepare, handler)
+        dns = {{host = host, port = port, family = 'AF_UNIX', protocol = 0,
+            type = 'SOCK_STREAM' }}
+    else
+        dns = getaddrinfo(host, port, timeout, { type = 'SOCK_STREAM' })
+        if dns == nil then
+            return nil
+        end
     end
 
-    local dns = getaddrinfo(host, port, timeout, { type = 'SOCK_STREAM',
-        protocol = 'tcp' })
-    if dns == nil then
-        return nil
+    for _, addr in ipairs(dns) do
+        local s = create_socket(addr.family, addr.type, addr.protocol)
+        if s ~= nil then
+            local backlog
+            if server.prepare then
+                backlog = server.prepare(s)
+            else
+                s:setsockopt('SOL_SOCKET', 'SO_REUSEADDR', 1) -- ignore error
+            end
+            if not s:bind(addr.host, addr.port) or not s:listen(backlog) then
+                local save_errno = boxerrno()
+                s:close()
+                boxerrno(save_errno)
+                return nil
+            end
+            fiber.create(tcp_server_loop, server, s, addr)
+            return s, addr
+       end
     end
-    return tcp_server_remote(dns, prepare, handler)
+    -- DNS resolved successfully, but addresss family is not supported
+    boxerrno(boxerrno.EAFNOSUPPORT)
+    return nil
 end
 
 socket_mt   = {
diff --git a/src/lua/console.lua b/src/lua/console.lua
index 57d78d9f9093978fca5febda82ebba828ddd5405..fe04952f5b75c7ef940bb576a42e298be02df506 100644
--- a/src/lua/console.lua
+++ b/src/lua/console.lua
@@ -5,6 +5,7 @@ local fiber = require('fiber')
 local socket = require('socket')
 local log = require('log')
 local errno = require('errno')
+local urilib = require('uri')
 
 -- admin formatter must be able to encode any Lua variable
 local formatter = require('yaml').new()
@@ -221,13 +222,23 @@ end
 --
 -- Connect to remove server
 --
-local function connect(...)
+local function connect(uri)
     local self = fiber.self().storage.console
     if self == nil then
         error("console.connect() need existing console")
     end
+
+    local u
+    if uri then
+        u = urilib.parse(tostring(uri))
+    end
+    if u == nil or u.service == nil then
+        error('Usage: console.connect("[login:password@][host:]port")')
+    end
+
     -- connect to remote host
-    local remote = require('net.box'):new(...)
+    local remote = require('net.box'):new(u.host, u.service,
+        { user = u.login, password = u.password })
     -- check permissions
     remote:call('dostring', 'return true')
     -- override methods
@@ -237,22 +248,16 @@ local function connect(...)
     log.info("connected to %s:%s", self.remote.host, self.remote.port)
 end
 
-local function server_loop(server)
-    while server:readable() do
-        local client = server:accept()
-        if client then
-            local peer = client:peer()
-            log.info("console: client %s:%s connected", peer.host, peer.port)
-            local state = setmetatable({
-                running = true;
-                read = client_read;
-                print = client_print;
-                client = client;
-            }, repl_mt)
-            fiber.create(repl, state)
-        end
-    end
-    log.info("console: stopped")
+local function client_handler(client, peer)
+    log.info("console: client %s:%s connected", peer.host, peer.port)
+    local state = setmetatable({
+        running = true;
+        read = client_read;
+        print = client_print;
+        client = client;
+    }, repl_mt)
+    repl(state)
+    log.info("console: client %s:%s disconnected", peer.host, peer.port)
 end
 
 --
@@ -262,46 +267,23 @@ local function listen(uri)
     local host, port
     if uri == nil then
         host = 'unix/'
-    elseif type(uri) == 'number' or uri:match("^%d+$") then
-        port = tonumber(uri)
-    elseif uri:match("^/") then
-        host = 'unix/'
-        port = uri
+        port = '/tmp/tarantool-console.sock'
     else
-        host, port = uri:match("^(.*):(.*)$")
-        if not host then
-            port = uri
+        local u = urilib.parse(tostring(uri))
+        if u == nil or u.service == nil then
+            error('Usage: console.listen("[host:]port")')
         end
+        host = u.host
+        port = u.service or 3313
     end
-    local server
-    if host == 'unix/' then
-        port = port or '/tmp/tarantool-console.sock'
-        os.remove(port)
-        server = socket('AF_UNIX', 'SOCK_STREAM', 0)
-    else
-        host = host or '127.0.0.1'
-        port = port or 3313
-        server = socket('AF_INET', 'SOCK_STREAM', 'tcp')
-    end
-    if not server then
-	error(string.format('failed to create socket %s%s : %s',
-			    host, port, errno.strerror()))
-    end
-    server:setsockopt('SOL_SOCKET', 'SO_REUSEADDR', true)
-
-    if not server:bind(host, port) then
-        local msg = string.format('failed to bind: %s', server:error())
-        server:close()
-        error(msg)
-    end
-    if not server:listen() then
-        local msg = string.format('failed to listen: %s', server:error())
-        server:close()
-        error(msg)
+    local s, addr = socket.tcp_server(host, port, { handler = client_handler,
+        name = 'console'})
+    if not s then
+        error(string.format('failed to create server %s:%s: %s',
+            host, port, errno.strerror()))
     end
-    log.info("console: started on %s:%s", host, port)
-    fiber.create(server_loop, server)
-    return server
+    log.info("console: started on %s:%s", addr.host, addr.port)
+    return s
 end
 
 return {
diff --git a/test/app/cfg.result b/test/app/cfg.result
index 60f07692ade6cf0b4b14e0acd40124a0a2176809..38f4a9c0db8c3de4ad176a7e8d11d5b527ce1b80 100644
--- a/test/app/cfg.result
+++ b/test/app/cfg.result
@@ -1,2 +1,10 @@
-false	[string "-- load_cfg.lua - internal file..."]:139: Please call box.cfg{} first
-true	table
+TAP version 13
+1..8
+ok - exception on unconfigured box
+ok - configured box
+ok - cfg.wal_mode default value
+ok - cfg.wal_mode default value
+ok - cfg.wal_mode change
+ok - cfg.wal_mode default value
+ok - cfg.wal_mode change
+ok - cfg.wal_mode default value
diff --git a/test/app/cfg.test.lua b/test/app/cfg.test.lua
index bce98a2db290b603bec2a20e71572090c8a3ea2a..d768107c2cae79144649420f3a1ae68ca9b86e91 100755
--- a/test/app/cfg.test.lua
+++ b/test/app/cfg.test.lua
@@ -1,19 +1,48 @@
 #!/usr/bin/env tarantool
 
+local tap = require('tap')
+local test = tap.test('cfg')
+test:plan(8)
+
 --------------------------------------------------------------------------------
 -- All box members must raise an exception on access if box.cfg{} wasn't called
 --------------------------------------------------------------------------------
 
 local box = require('box')
-local function test()
+local function testfun()
     return type(box.space)
 end
 
-print(pcall(test))
+local status, result = pcall(testfun)
+
+test:ok(not status and result:match('Please call box.cfg{}'),
+    'exception on unconfigured box')
+
 box.cfg{
     logger="tarantool.log",
     slab_alloc_arena=0.1,
+    wal_mode = "", -- "" means default value
 }
-print(pcall(test))
 
+status, result = pcall(testfun)
+test:ok(status and result == 'table', 'configured box')
+
+--------------------------------------------------------------------------------
+-- gh-534: Segmentation fault after two bad wal_mode settings
+--------------------------------------------------------------------------------
+
+test:is(box.cfg.wal_mode, "write", "cfg.wal_mode default value")
+box.cfg{wal_mode = ""}
+test:is(box.cfg.wal_mode, "write", "cfg.wal_mode default value")
+box.cfg{wal_mode = "none"}
+test:is(box.cfg.wal_mode, "none", "cfg.wal_mode change")
+-- "" or NULL resets option to default value
+box.cfg{wal_mode = ""}
+test:is(box.cfg.wal_mode, "write", "cfg.wal_mode default value")
+box.cfg{wal_mode = "none"}
+test:is(box.cfg.wal_mode, "none", "cfg.wal_mode change")
+box.cfg{wal_mode = require('msgpack').NULL}
+test:is(box.cfg.wal_mode, "write", "cfg.wal_mode default value")
+
+test:check()
 os.exit(0)
diff --git a/test/app/console.result b/test/app/console.result
index e7f5b5ca465f82e795277c588e439b323a4cc9e4..c36eef7c724fd19eb6ed3b1f3a20fd4f865a97a3 100644
--- a/test/app/console.result
+++ b/test/app/console.result
@@ -1,5 +1,5 @@
 TAP version 13
-1..18
+1..25
 ok - console.listen started
 ok - connect to console
 ok - eval
@@ -11,6 +11,7 @@ ok - get delimiter is ';'
 ok - clear delimiter
 ok - remote network error
 ok - remote access denied
+ok - remote access denied
 ok - remote connect
 ok - remote eval
 ok - remote state.remote.host
@@ -18,3 +19,9 @@ ok - remote state.remote.port
 ok - remote state.prompt
 ok - remote disconnect
 ok - console.listen stopped
+ok - console.listen uri support
+ok - console.listen uri support
+ok - console.listen uri support
+ok - console.listen uri support
+ok - console.listen uri support
+ok - console.listen uri support
diff --git a/test/app/console.test.lua b/test/app/console.test.lua
index b569dce375b2fce8deca8ece69504ce2f68beee7..8ee97cbaf1dfe4bb67951b516a7ff692c324f803 100755
--- a/test/app/console.test.lua
+++ b/test/app/console.test.lua
@@ -22,7 +22,7 @@ local EOL = "\n%.%.%.\n"
 
 test = tap.test("console")
 
-test:plan(18)
+test:plan(25)
 
 -- Start console and connect to it
 local server = console.listen(CONSOLE_SOCKET)
@@ -55,22 +55,30 @@ client:write("require('console').delimiter('');\n")
 test:is(yaml.decode(client:read(EOL)), '', "clear delimiter")
 
 -- Connect to iproto console (CALL)
-client:write(string.format("require('console').connect('unix/', '/')\n"))
+client:write(string.format("require('console').connect('/')\n"))
 -- error: Connection is not established
 test:ok(yaml.decode(client:read(EOL))[1].error:find('not established'),
     'remote network error')
 
-client:write(string.format("require('console').connect('unix/', '%s')\n",
+client:write(string.format("require('console').connect('%s')\n",
     IPROTO_SOCKET))
 -- error: Execute access denied for user 'guest' to function 'dostring
 test:ok(yaml.decode(client:read(EOL))[1].error:find('access denied'),
     'remote access denied')
 
+-- create user
+box.schema.user.create('test', { password = 'pass' })
+client:write(string.format("require('console').connect('test:pass@%s')\n",
+    IPROTO_SOCKET))
+-- error: Execute access denied for user 'tester' to function 'dostring
+test:ok(yaml.decode(client:read(EOL))[1].error:find('access denied'),
+    'remote access denied')
+
 -- Add permissions to execute `dostring` for `guest`
 box.schema.func.create('dostring')
-box.schema.user.grant('guest', 'execute', 'function', 'dostring')
+box.schema.user.grant('test', 'execute', 'function', 'dostring')
 
-client:write(string.format("require('console').connect('unix/', '%s')\n",
+client:write(string.format("require('console').connect('test:pass@%s')\n",
     IPROTO_SOCKET))
 test:is(yaml.decode(client:read(EOL)), '', "remote connect")
 
@@ -102,11 +110,24 @@ server:close()
 -- Check that admon console has been stopped
 test:isnil(socket.tcp_connect("unix/", CONSOLE_SOCKET), "console.listen stopped")
 
-test:check()
-
 -- Stop iproto (not implemented yet)
 -- box.cfg{listen = nil}
-
-os.remove(CONSOLE_SOCKET)
 os.remove(IPROTO_SOCKET)
+
+local s = console.listen('127.0.0.1:0')
+addr = s:name()
+test:is(addr.family, 'AF_INET', 'console.listen uri support')
+test:is(addr.host, '127.0.0.1', 'console.listen uri support')
+test:isnt(addr.port, 0, 'console.listen uri support')
+s:close()
+
+local s = console.listen('console://unix/:'..CONSOLE_SOCKET)
+addr = s:name()
+test:is(addr.family, 'AF_UNIX', 'console.listen uri support')
+test:is(addr.host, 'unix/', 'console.listen uri support')
+test:is(addr.port, CONSOLE_SOCKET, 'console.listen uri support')
+s:close()
+
+test:check()
+
 os.exit(0)
diff --git a/test/box/access.result b/test/box/access.result
index eaf920e8f612ae728e6f467e72eba74730d87ed7..7ad11d39e9fed0a5ee2de6ac5226c74d2e5d3dc8 100644
--- a/test/box/access.result
+++ b/test/box/access.result
@@ -156,7 +156,14 @@ box.schema.user.drop('Петя_Иванов')
 ---
 ...
 -- gh-300: misleading error message if a function does not exist
-c = (require 'net.box'):new("127.0.0.1", box.cfg.listen)
+LISTEN = require('uri').parse(box.cfg.listen)
+---
+...
+LISTEN ~= nil
+---
+- true
+...
+c = (require 'net.box'):new(LISTEN.host, LISTEN.service)
 ---
 ...
 c:call('nosuchfunction')
diff --git a/test/box/access.test.lua b/test/box/access.test.lua
index cc7ff3a2b4c6202749f1cf5157c2fa783bcf3cb2..8569e0ec32e5093cffe4a40b75c1dc6541e17ccf 100644
--- a/test/box/access.test.lua
+++ b/test/box/access.test.lua
@@ -74,7 +74,9 @@ box.schema.user.create('Петя_Иванов')
 box.schema.user.drop('Петя_Иванов')
 
 -- gh-300: misleading error message if a function does not exist
-c = (require 'net.box'):new("127.0.0.1", box.cfg.listen)
+LISTEN = require('uri').parse(box.cfg.listen)
+LISTEN ~= nil
+c = (require 'net.box'):new(LISTEN.host, LISTEN.service)
 
 c:call('nosuchfunction')
 function nosuchfunction() end
diff --git a/test/box/access_bin.result b/test/box/access_bin.result
index 23aa5b2d6f54fc0b81d192f24bec291cd079f5c2..796a085ac0370c0f898497aeb16e9c2a94c35cc7 100644
--- a/test/box/access_bin.result
+++ b/test/box/access_bin.result
@@ -11,7 +11,14 @@ session = box.session
 net = { box = require('net.box') }
 ---
 ...
-c = net.box:new(0, box.cfg.listen)
+LISTEN = require('uri').parse(box.cfg.listen)
+---
+...
+LISTEN ~= nil
+---
+- true
+...
+c = net.box:new(LISTEN.host, LISTEN.service)
 ---
 ...
 c:call("dostring", "session.su('admin')")
@@ -45,7 +52,7 @@ box.schema.func.create('setuid_func')
 box.schema.user.grant('guest', 'execute', 'function', 'setuid_func')
 ---
 ...
-c = net.box:new(0, box.cfg.listen)
+c = net.box:new(LISTEN.host, LISTEN.service)
 ---
 ...
 c:call("setuid_func")
diff --git a/test/box/access_bin.test.lua b/test/box/access_bin.test.lua
index f9841d7ea50220baa1ddb83ccf11d29607c37b0c..18f3d167f28dac7446dbec4e7af1bd913a415274 100644
--- a/test/box/access_bin.test.lua
+++ b/test/box/access_bin.test.lua
@@ -5,7 +5,9 @@
 box.schema.user.grant('guest','read,write,execute','universe')
 session = box.session
 net = { box = require('net.box') }
-c = net.box:new(0, box.cfg.listen)
+LISTEN = require('uri').parse(box.cfg.listen)
+LISTEN ~= nil
+c = net.box:new(LISTEN.host, LISTEN.service)
 c:call("dostring", "session.su('admin')")
 c:call("dostring", "return session.user()")
 c:close()
@@ -18,7 +20,7 @@ setuid_space:create_index('primary')
 setuid_func = function() return box.space.setuid_space:auto_increment{} end
 box.schema.func.create('setuid_func')
 box.schema.user.grant('guest', 'execute', 'function', 'setuid_func')
-c = net.box:new(0, box.cfg.listen)
+c = net.box:new(LISTEN.host, LISTEN.service)
 c:call("setuid_func")
 session.su('guest')
 setuid_func()
diff --git a/test/box/bad_trigger.result b/test/box/bad_trigger.result
index f44644d9f8c100cd2fbf57b4bb3d56fcb4847eb2..5740f76833df897d234d482b85063b3b325d19f3 100644
--- a/test/box/bad_trigger.result
+++ b/test/box/bad_trigger.result
@@ -1,7 +1,7 @@
- 
+
  #
  # if on_connect() trigger raises an exception, the connection is dropped
- # 
+ #
  
 function f1() nosuchfunction() end
 ---
diff --git a/test/box/bad_trigger.test.py b/test/box/bad_trigger.test.py
index ebbed28bf956dc93ef8450aa8bb093c36b635036..b7337cdf61c6dade851eb05a9af917b45d9275e6 100644
--- a/test/box/bad_trigger.test.py
+++ b/test/box/bad_trigger.test.py
@@ -1,14 +1,15 @@
 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 """ 
+print """
  #
  # if on_connect() trigger raises an exception, the connection is dropped
- # 
+ #
  """
 
 server.admin("function f1() nosuchfunction() end")
@@ -16,8 +17,9 @@ server.admin("box.session.on_connect(f1)")
 
 unpacker = msgpack.Unpacker(use_list = False)
 
-s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-s.connect(('localhost', server.sql.port))
+conn = TarantoolConnection(server.sql.host, server.sql.port)
+conn.connect()
+s = conn.socket
 
 # Read greeting
 print 'greeting: ', len(s.recv(IPROTO_GREETING_SIZE)) == IPROTO_GREETING_SIZE
diff --git a/test/box/box.net.box.result b/test/box/box.net.box.result
index 9cb0f175bd202b0206a2d8ecd5a19285bf49b5e7..eff5cf47758c133d3d2552d1acfcc9a76cf90369 100644
--- a/test/box/box.net.box.result
+++ b/test/box/box.net.box.result
@@ -13,7 +13,7 @@ msgpack = require 'msgpack'
 box.schema.user.grant('guest', 'read,write,execute', 'universe')
 ---
 ...
-port = box.cfg.listen
+LISTEN = require('uri').parse(box.cfg.listen)
 ---
 ...
 space = box.schema.create_space('net_box_test_space')
@@ -26,7 +26,7 @@ space:create_index('primary', { type = 'tree' })
 log.info("create connection")
 ---
 ...
-cn = remote:new('127.0.0.1', port)
+cn = remote:new(LISTEN.host, LISTEN.service)
 ---
 ...
 cn:_wait_state({'active', 'error'}, 1)
@@ -301,7 +301,7 @@ cn:call('test_foo')
 - error: Connection is not established
 ...
 -- -- 2 reconnect
-cn = remote:new('127.0.0.1', port, { reconnect_after = .1 })
+cn = remote:new(LISTEN.host, LISTEN.service, { reconnect_after = .1 })
 ---
 ...
 cn:_wait_state({'active'}, 1)
@@ -362,7 +362,7 @@ cn:ping()
 - true
 ...
 -- -- dot-new-method
-cn1 = remote.new('127.0.0.1', port)
+cn1 = remote.new(LISTEN.host, LISTEN.service)
 ---
 ...
 cn1:_select(space.id, 0, {}, { iterator = 'ALL' })
@@ -439,7 +439,7 @@ cn.proto.b64decode('gJLoc!!!!!!!')
 ---
 - !!binary gJLo
 ...
-cn = remote:new('127.0.0.1', port, { user = 'netbox', password = '123', wait_connected = true })
+cn = remote:new(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123', wait_connected = true })
 ---
 ...
 cn:is_connected()
@@ -460,7 +460,7 @@ box.schema.user.create('netbox', { password  = 'test' })
 box.schema.user.grant('netbox', 'read, write, execute', 'universe');
 ---
 ...
-cn = remote:new('127.0.0.1', port, { user = 'netbox', password = 'test' })
+cn = remote:new(LISTEN.host, LISTEN.service, { user = 'netbox', password = 'test' })
 ---
 ...
 cn.state
@@ -495,11 +495,11 @@ cn:timeout(.01):call('ret_after', 1)
 ---
 - error: Timeout exceeded
 ...
-cn = remote:timeout(0.0000000001):new('127.0.0.1', port, { user = 'netbox', password = '123' })
+cn = remote:timeout(0.0000000001):new(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123' })
 ---
 - error: Timeout exceeded
 ...
-cn = remote:timeout(1):new('127.0.0.1', port, { user = 'netbox', password = '123' })
+cn = remote:timeout(1):new(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123' })
 ---
 ...
 remote.self:ping()
diff --git a/test/box/box.net.box.test.lua b/test/box/box.net.box.test.lua
index dfb82eb0460ecd264e2e2019490b13683b48de6e..6dc3448aaf4362294bdf8be04f5bb286e707ce05 100644
--- a/test/box/box.net.box.test.lua
+++ b/test/box/box.net.box.test.lua
@@ -4,13 +4,13 @@ log = require 'log'
 msgpack = require 'msgpack'
 
 box.schema.user.grant('guest', 'read,write,execute', 'universe')
-port = box.cfg.listen
+LISTEN = require('uri').parse(box.cfg.listen)
 space = box.schema.create_space('net_box_test_space')
 space:create_index('primary', { type = 'tree' })
 
 -- low level connection
 log.info("create connection")
-cn = remote:new('127.0.0.1', port)
+cn = remote:new(LISTEN.host, LISTEN.service)
 cn:_wait_state({'active', 'error'}, 1)
 log.info("state is %s", cn.state)
 
@@ -106,7 +106,7 @@ cn:ping()
 cn:call('test_foo')
 
 -- -- 2 reconnect
-cn = remote:new('127.0.0.1', port, { reconnect_after = .1 })
+cn = remote:new(LISTEN.host, LISTEN.service, { reconnect_after = .1 })
 cn:_wait_state({'active'}, 1)
 cn.space ~= nil
 
@@ -129,7 +129,7 @@ cn:ping()
 
 -- -- dot-new-method
 
-cn1 = remote.new('127.0.0.1', port)
+cn1 = remote.new(LISTEN.host, LISTEN.service)
 cn1:_select(space.id, 0, {}, { iterator = 'ALL' })
 
 -- -- error while waiting for response
@@ -159,7 +159,7 @@ res[1][2] == string.rep('a', 50000)
 cn.proto.b64decode('gJLocxbO32VmfO8x04xRVxKfgwzmNVM2t6a1ME8XsD0=')
 cn.proto.b64decode('gJLoc!!!!!!!')
 
-cn = remote:new('127.0.0.1', port, { user = 'netbox', password = '123', wait_connected = true })
+cn = remote:new(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123', wait_connected = true })
 cn:is_connected()
 cn.error
 cn.state
@@ -167,7 +167,7 @@ cn.state
 box.schema.user.create('netbox', { password  = 'test' })
 box.schema.user.grant('netbox', 'read, write, execute', 'universe');
 
-cn = remote:new('127.0.0.1', port, { user = 'netbox', password = 'test' })
+cn = remote:new(LISTEN.host, LISTEN.service, { user = 'netbox', password = 'test' })
 cn.state
 cn.error
 cn:ping()
@@ -180,8 +180,8 @@ cn:call('ret_after', .01)
 cn:timeout(1):call('ret_after', .01)
 cn:timeout(.01):call('ret_after', 1)
 
-cn = remote:timeout(0.0000000001):new('127.0.0.1', port, { user = 'netbox', password = '123' })
-cn = remote:timeout(1):new('127.0.0.1', port, { user = 'netbox', password = '123' })
+cn = remote:timeout(0.0000000001):new(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123' })
+cn = remote:timeout(1):new(LISTEN.host, LISTEN.service, { user = 'netbox', password = '123' })
 
 
 
diff --git a/test/box/bsdsocket.result b/test/box/bsdsocket.result
index ccc0973dea38030d9b48b65242cb2c55859ef2ea..043ac1e95ce91274c569ca22e00fb7a3f63a7a39 100644
--- a/test/box/bsdsocket.result
+++ b/test/box/bsdsocket.result
@@ -22,6 +22,9 @@ log = require 'log'
 errno = require 'errno'
 ---
 ...
+fio = require 'fio'
+---
+...
 type(socket)
 ---
 - table
@@ -59,18 +62,26 @@ for k in pairs(getmetatable(s).__index) do
 end;
 ---
 ...
---# setopt delimiter ''
-port = string.gsub(box.cfg.listen, '^.*:', '')
+s:close()
 ---
+- true
 ...
-s:nonblock(false)
+--# setopt delimiter ''
+s:close()
+
 ---
 - false
 ...
-s:sysconnect('127.0.0.1', port)
+LISTEN = require('uri').parse(box.cfg.listen)
+---
+...
+LISTEN ~= nil
 ---
 - true
 ...
+s = socket.tcp_connect(LISTEN.host, LISTEN.service)
+---
+...
 s:nonblock(true)
 ---
 - true
@@ -349,9 +360,20 @@ sc:write('Hello, world')
 ---
 - true
 ...
-sa = s:accept()
+sa, addr = s:accept()
+---
+...
+addr2 = sa:name()
 ---
 ...
+addr2.host == addr.host
+---
+- true
+...
+addr2.family == addr.family
+---
+- true
+...
 sa:nonblock(1)
 ---
 - true
@@ -1209,9 +1231,13 @@ os.remove(path)
 ---
 - true
 ...
-server = socket.tcp_server('unix/', path, function(s) s:write('Hello, world') end)
+server, addr = socket.tcp_server('unix/', path, function(s) s:write('Hello, world') end)
 ---
 ...
+type(addr)
+---
+- table
+...
 server ~= nil
 ---
 - true
@@ -1230,11 +1256,83 @@ client:read(123)
 ---
 - Hello, world
 ...
-server:stop()
+server:close()
 ---
 - true
 ...
-os.remove(path)
+-- unix socket automatically removed
+fio.stat(path) == nil
+---
+- true
+...
+--# setopt delimiter ';'
+server, addr = socket.tcp_server('localhost', 0, { handler = function(s)
+    s:read(2)
+    s:write('Hello, world')
+end, name = 'testserv'});
+---
+...
+--# setopt delimiter ''
+type(addr)
+---
+- table
+...
+server ~= nil
+---
+- true
+...
+addr2 = server:name()
+---
+...
+addr.host == addr2.host
+---
+- true
+...
+addr.family == addr2.family
+---
+- true
+...
+fiber.sleep(.5)
+---
+...
+client = socket.tcp_connect(addr2.host, addr2.port)
+---
+...
+client ~= nil
+---
+- true
+...
+-- Check that listen and client fibers have appropriate names
+cnt = 0
+---
+...
+--# setopt delimiter ';'
+for i=100,200 do
+    local f = fiber.find(i)
+    if f and f:name():match('^testserv/') then
+        cnt = cnt + 1
+    end
+end;
+---
+...
+--# setopt delimiter ''
+cnt
+---
+- 2
+...
+client:write('hi')
+---
+- true
+...
+client:read(123)
+---
+- Hello, world
+...
+client:close()
+---
+- true
+...
+server:close()
 ---
 - true
 ...
@@ -1275,11 +1373,7 @@ client:read{ line = { "\n\n", "\r\n\r\n" } }
 ---
 - "Hello\r\n\r\n"
 ...
-server:stop()
----
-- true
-...
-os.remove(path)
+server:close()
 ---
 - true
 ...
diff --git a/test/box/bsdsocket.test.lua b/test/box/bsdsocket.test.lua
index 7ead95599262bb1498d51354ba5cd88928b7ed1b..faf0346c4099676777570ff8f70f3c88caa69d16 100644
--- a/test/box/bsdsocket.test.lua
+++ b/test/box/bsdsocket.test.lua
@@ -6,6 +6,7 @@ fiber = require 'fiber'
 msgpack = require 'msgpack'
 log = require 'log'
 errno = require 'errno'
+fio = require 'fio'
 type(socket)
 
 socket('PF_INET', 'SOCK_STREAM', 'tcp121222');
@@ -23,12 +24,12 @@ for k in pairs(getmetatable(s).__index) do
         error("Arguments is not checked for "..k)
     end
 end;
+s:close()
 --# setopt delimiter ''
 
-port = string.gsub(box.cfg.listen, '^.*:', '')
-
-s:nonblock(false)
-s:sysconnect('127.0.0.1', port)
+LISTEN = require('uri').parse(box.cfg.listen)
+LISTEN ~= nil
+s = socket.tcp_connect(LISTEN.host, LISTEN.service)
 s:nonblock(true)
 s:nonblock()
 s:nonblock(false)
@@ -114,7 +115,10 @@ sc:writable(10)
 sc:write('Hello, world')
 
 
-sa = s:accept()
+sa, addr = s:accept()
+addr2 = sa:name()
+addr2.host == addr.host
+addr2.family == addr.family
 sa:nonblock(1)
 sa:read(8)
 sa:read(3)
@@ -404,37 +408,59 @@ s:close()
 os.remove(path)
 
 
-server = socket.tcp_server('unix/', path, function(s) s:write('Hello, world') end)
+server, addr = socket.tcp_server('unix/', path, function(s) s:write('Hello, world') end)
+type(addr)
 server ~= nil
 fiber.sleep(.5)
 client = socket.tcp_connect('unix/', path)
 client ~= nil
 client:read(123)
-server:stop()
-os.remove(path)
+server:close()
+-- unix socket automatically removed
+fio.stat(path) == nil
 
+--# setopt delimiter ';'
+server, addr = socket.tcp_server('localhost', 0, { handler = function(s)
+    s:read(2)
+    s:write('Hello, world')
+end, name = 'testserv'});
+--# setopt delimiter ''
+type(addr)
+server ~= nil
+addr2 = server:name()
+addr.host == addr2.host
+addr.family == addr2.family
+fiber.sleep(.5)
+client = socket.tcp_connect(addr2.host, addr2.port)
+client ~= nil
+-- Check that listen and client fibers have appropriate names
+cnt = 0
+--# setopt delimiter ';'
+for i=100,200 do
+    local f = fiber.find(i)
+    if f and f:name():match('^testserv/') then
+        cnt = cnt + 1
+    end
+end;
+--# setopt delimiter ''
+cnt
+client:write('hi')
+client:read(123)
+client:close()
+server:close()
 
 longstring = string.rep("abc", 65535)
 server = socket.tcp_server('unix/', path, function(s) s:write(longstring) end)
-
 client = socket.tcp_connect('unix/', path)
 client:read(#longstring) == longstring
-
 client = socket.tcp_connect('unix/', path)
 client:read(#longstring + 1) == longstring
-
 client = socket.tcp_connect('unix/', path)
 client:read(#longstring - 1) == string.sub(longstring, 1, #longstring - 1)
-
-
 longstring = "Hello\r\n\r\nworld\n\n"
-
 client = socket.tcp_connect('unix/', path)
 client:read{ line = { "\n\n", "\r\n\r\n" } }
-
-
-server:stop()
-os.remove(path)
+server:close()
 
 
 -- Test that socket is closed on GC
diff --git a/test/box/cfg.result b/test/box/cfg.result
index 86c19dbde9033cefeba93ac7d8585460cd4838cc..60f359c31f8e870efd19e77d2601ffbeea567c33 100644
--- a/test/box/cfg.result
+++ b/test/box/cfg.result
@@ -2,7 +2,7 @@
 --# push filter 'admin: .*' to 'admin: <uri>'
 box.cfg.nosuchoption = 1
 ---
-- error: '[string "-- load_cfg.lua - internal file..."]:204: Attempt to modify a read-only
+- error: '[string "-- load_cfg.lua - internal file..."]:191: Attempt to modify a read-only
     table'
 ...
 t = {} for k,v in pairs(box.cfg) do if type(v) ~= 'table' and type(v) ~= 'function' then table.insert(t, k..': '..tostring(v)) end end
@@ -63,4 +63,26 @@ t
   - 'snapshot_period: 0'
   - 'wal_dir_rescan_delay: 0.1'
 ...
+-- check that cfg with unexpected parameter fails.
+box.cfg{sherlock = 'holmes'}
+---
+- error: '[string "-- load_cfg.lua - internal file..."]:121: Error: cfg parameter
+    ''sherlock'' is unexpected'
+...
+-- check that cfg with unexpected type of parameter failes
+box.cfg{listen = {}}
+---
+- error: '[string "-- load_cfg.lua - internal file..."]:136: Error: cfg parameter
+    ''listen'' should be one of types: string, number'
+...
+box.cfg{wal_dir = 0}
+---
+- error: '[string "-- load_cfg.lua - internal file..."]:130: Error: cfg parameter
+    ''wal_dir'' should be of type string'
+...
+box.cfg{coredump = 'true'}
+---
+- error: '[string "-- load_cfg.lua - internal file..."]:130: Error: cfg parameter
+    ''coredump'' should be of type boolean'
+...
 --# clear filter
diff --git a/test/box/cfg.test.lua b/test/box/cfg.test.lua
index ee99deae794a6f606d6711abe6d65f4d19adb0d6..9d4e87075df1a961723c3e1a9badf8d65257f974 100644
--- a/test/box/cfg.test.lua
+++ b/test/box/cfg.test.lua
@@ -7,4 +7,13 @@ t
 box.cfg()
 t = {} for k,v in pairs(box.cfg) do if type(v) ~= 'table' and type(v) ~= 'function' then table.insert(t, k..': '..tostring(v)) end end
 t
+
+-- check that cfg with unexpected parameter fails.
+box.cfg{sherlock = 'holmes'}
+
+-- check that cfg with unexpected type of parameter failes
+box.cfg{listen = {}}
+box.cfg{wal_dir = 0}
+box.cfg{coredump = 'true'}
+
 --# clear filter
diff --git a/test/box/iproto.test.py b/test/box/iproto.test.py
index 031ae92ee3731de4a7ebceda1342dae17a07495a..d95af37e1e7f156fb18dfe925d637f7e29bb1c86 100644
--- a/test/box/iproto.test.py
+++ b/test/box/iproto.test.py
@@ -8,6 +8,7 @@ from tarantool import Connection
 from tarantool.request import RequestInsert
 from tarantool.request import RequestSelect
 from tarantool.response import Response
+from lib.tarantool_connection import TarantoolConnection
 
 print """
 #
@@ -16,8 +17,9 @@ print """
 """
 
 # opeing new connection to tarantool/box
-s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-s.connect(('localhost', server.sql.port))
+conn = TarantoolConnection(server.sql.host, server.sql.port)
+conn.connect()
+s = conn.socket
 
 print """
 # Test bug #899343 (server assertion failure on incorrect packet)
diff --git a/test/box/protocol.result b/test/box/protocol.result
index fbbe9a349d1bfb0d36868ed35a4e8568f23f3d3a..f1e99fccb70c88b6891e9fa4be66a9540d47fd2b 100644
--- a/test/box/protocol.result
+++ b/test/box/protocol.result
@@ -13,10 +13,14 @@ space:create_index('primary', { type = 'tree'})
 for i=1,5 do space:insert{i} end
 ---
 ...
-port = string.gsub(box.cfg.listen, '^.*:', '')
+LISTEN = require('uri').parse(box.cfg.listen)
 ---
 ...
-conn = (require 'net.box'):new('127.0.0.1', tonumber(port))
+LISTEN ~= nil
+---
+- true
+...
+conn = (require 'net.box'):new(LISTEN.host, LISTEN.service)
 ---
 ...
 conn.space[space.id]:select(3, { iterator = 'GE' })
diff --git a/test/box/protocol.test.lua b/test/box/protocol.test.lua
index 975fb20ffa50199fbf1bf2e2e16568e5ff6e01ad..fa75d8d8cd854e8020ccfb2ae59dc567fcd1f6f1 100644
--- a/test/box/protocol.test.lua
+++ b/test/box/protocol.test.lua
@@ -8,8 +8,9 @@ space = box.schema.create_space('tweedledum')
 space:create_index('primary', { type = 'tree'})
 for i=1,5 do space:insert{i} end
 
-port = string.gsub(box.cfg.listen, '^.*:', '')
-conn = (require 'net.box'):new('127.0.0.1', tonumber(port))
+LISTEN = require('uri').parse(box.cfg.listen)
+LISTEN ~= nil
+conn = (require 'net.box'):new(LISTEN.host, LISTEN.service)
 conn.space[space.id]:select(3, { iterator = 'GE' })
 conn.space[space.id]:select(3, { iterator = 'LE' })
 conn.space[space.id]:select(3, { iterator = 'GT' })
diff --git a/test/box/session.result b/test/box/session.result
index b0610ea741b85f00382872938bfcf11f28861874..96469ca9389aae39fe99580b2ec388a3bc57bc05 100644
--- a/test/box/session.result
+++ b/test/box/session.result
@@ -128,7 +128,10 @@ session.on_disconnect(dec)
 active_connections = 0
 ---
 ...
-c = net.box:new(0, box.cfg.listen)
+LISTEN = require('uri').parse(box.cfg.listen)
+---
+...
+c = net.box:new(LISTEN.host, LISTEN.service)
 ---
 ...
 while active_connections < 1 do fiber.sleep(0.001) end
@@ -138,7 +141,7 @@ active_connections
 ---
 - 1
 ...
-c1 = net.box:new(0, box.cfg.listen)
+c1 = net.box:new(LISTEN.host, LISTEN.service)
 ---
 ...
 while active_connections < 2 do fiber.sleep(0.001) end
@@ -183,7 +186,7 @@ session.on_disconnect(audit_disconnect)
 box.schema.user.grant('guest', 'read,write,execute', 'universe')
 ---
 ...
-a = net.box:new('127.0.0.1', box.cfg.listen)
+a = net.box:new(LISTEN.host, LISTEN.service)
 ---
 ...
 a:call('dostring', 'return space:get{session.id()}[1] == session.id()')[1][1]
diff --git a/test/box/session.test.lua b/test/box/session.test.lua
index 9be90f703391a53abcb661a3562237698bfbd292..95152624feb1015433c4c135a6500a97510228ed 100644
--- a/test/box/session.test.lua
+++ b/test/box/session.test.lua
@@ -51,10 +51,11 @@ net = { box = require('net.box') }
 session.on_connect(inc)
 session.on_disconnect(dec)
 active_connections = 0
-c = net.box:new(0, box.cfg.listen)
+LISTEN = require('uri').parse(box.cfg.listen)
+c = net.box:new(LISTEN.host, LISTEN.service)
 while active_connections < 1 do fiber.sleep(0.001) end
 active_connections
-c1 = net.box:new(0, box.cfg.listen)
+c1 = net.box:new(LISTEN.host, LISTEN.service)
 while active_connections < 2 do fiber.sleep(0.001) end
 active_connections
 c:close()
@@ -72,7 +73,7 @@ session.on_connect(audit_connect)
 session.on_disconnect(audit_disconnect)
 
 box.schema.user.grant('guest', 'read,write,execute', 'universe')
-a = net.box:new('127.0.0.1', box.cfg.listen)
+a = net.box:new(LISTEN.host, LISTEN.service)
 a:call('dostring', 'return space:get{session.id()}[1] == session.id()')[1][1]
 a:close()
 
diff --git a/test/lib/preprocessor.py b/test/lib/preprocessor.py
index 8f536568d0ea86a77069ac872f2a369539dbf712..f5f63678679fd15f8f0aaf3d9d257cce2b2960ff 100644
--- a/test/lib/preprocessor.py
+++ b/test/lib/preprocessor.py
@@ -30,8 +30,8 @@ class TestState(object):
         # curcon is an array since we may have many connections
         self.curcon = [self.connections['default']]
         nmsp = Namespace()
-        setattr(nmsp, 'admin', default_server.admin.port)
-        setattr(nmsp, 'listen', default_server.sql.port)
+        setattr(nmsp, 'admin', default_server.admin.uri)
+        setattr(nmsp, 'listen', default_server.sql.uri)
         setattr(self.environ, 'default', nmsp)
 
     def parse_preprocessor(self, string):
diff --git a/test/lib/server.py b/test/lib/server.py
index d7f8420abf5cce5f8a899a0e30abcb1086a64467..5aed7f27a4f043480c1dacd8d5794908b699efb7 100644
--- a/test/lib/server.py
+++ b/test/lib/server.py
@@ -15,8 +15,7 @@ import ConfigParser
 def check_port(port):
     """Check if the port we're connecting to is available"""
     try:
-        sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-        sock.connect(("localhost", port))
+        sock = socket.create_connection(("localhost", port))
     except socket.error as e:
         return
     raise RuntimeError("The server is already running on port {0}".format(port))
diff --git a/test/lib/tarantool-python b/test/lib/tarantool-python
index df94b88d87c249e41cdf45dd74b13a2949be24f0..b2bcd37691d3f4664bd34646078b02709fa102cd 160000
--- a/test/lib/tarantool-python
+++ b/test/lib/tarantool-python
@@ -1 +1 @@
-Subproject commit df94b88d87c249e41cdf45dd74b13a2949be24f0
+Subproject commit b2bcd37691d3f4664bd34646078b02709fa102cd
diff --git a/test/lib/tarantool_connection.py b/test/lib/tarantool_connection.py
index 873c1db09d874eb602abd2b82a73dbbc6e906b0e..5278809c10e72512cfb41ea95eb753da4633bbe6 100644
--- a/test/lib/tarantool_connection.py
+++ b/test/lib/tarantool_connection.py
@@ -27,6 +27,14 @@ import errno
 import re
 
 class TarantoolConnection(object):
+
+    @property
+    def uri(self):
+        if self.host == 'unix/' or re.search(r'^/', str(self.port)):
+            return self.port
+        else:
+            return self.host+':'+str(self.port)
+
     def __init__(self, host, port):
         self.host = host
         self.port = port
@@ -37,9 +45,8 @@ class TarantoolConnection(object):
             self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
             self.socket.connect(self.port)
         else:
-            self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+            self.socket = socket.create_connection((self.host, self.port))
             self.socket.setsockopt(socket.SOL_TCP, socket.TCP_NODELAY, 1)
-            self.socket.connect((self.host, self.port))
         self.is_connected = True
 
     def disconnect(self):
diff --git a/test/lib/tarantool_server.py b/test/lib/tarantool_server.py
index 332d37cbfd996000cb9c4c950c361d366d5ffe17..114f505fbaff71e0aa8b38c274c9c803fa4e4b26 100644
--- a/test/lib/tarantool_server.py
+++ b/test/lib/tarantool_server.py
@@ -36,8 +36,7 @@ color_stdout = Colorer()
 def check_port(port, rais=True):
     try:
         if isinstance(port, (int, long)):
-            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-            sock.connect(("localhost", port))
+            sock = socket.create_connection(("localhost", port))
         else:
             sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
             sock.connect(port)
@@ -464,10 +463,10 @@ class TarantoolServer(Server):
 
         check_port(self.admin.port)
 
-        os.putenv("LISTEN", str(self.sql.port))
-        os.putenv("ADMIN", str(self.admin.port))
+        os.putenv("LISTEN", self.sql.uri)
+        os.putenv("ADMIN", self.admin.uri)
         if self.rpl_master:
-            os.putenv("MASTER", "127.0.0.1:"+str(self.rpl_master.sql.port))
+            os.putenv("MASTER", self.rpl_master.sql.uri)
         args = self.prepare_args()
         self.logfile_pos = self.logfile
         self.process = subprocess.Popen(args,
diff --git a/test/replication/hot_standby.result b/test/replication/hot_standby.result
index 65676c970e8ca4bc47d827bf854fb6ac33a1e5fb..0f939412486f09b1b533d1173cc859b3281fafcb 100644
--- a/test/replication/hot_standby.result
+++ b/test/replication/hot_standby.result
@@ -64,7 +64,14 @@ end;
 --# set connection default
 -- set begin lsn on master, replica and hot_standby.
 --# set variable replica_port to 'replica.listen'
-a = (require 'net.box'):new('127.0.0.1', replica_port)
+REPLICA = require('uri').parse(tostring(replica_port))
+---
+...
+REPLICA ~= nil
+---
+- true
+...
+a = (require 'net.box'):new(REPLICA.host, REPLICA.service)
 ---
 ...
 a:call('_set_pri_lsn', box.info.server.id, box.info.server.lsn)
@@ -132,7 +139,14 @@ while box.info.status ~= 'running' do fiber.sleep(0.001) end
 -- hot_standby.listen is garbage, since hot_standby.lua
 -- uses MASTER environment variable for its listen
 --# set variable hot_standby_port to 'hot_standby.master'
-a = (require 'net.box'):new('127.0.0.1', hot_standby_port)
+HOT_STANDBY = require('uri').parse(tostring(hot_standby_port))
+---
+...
+HOT_STANDBY ~= nil
+---
+- true
+...
+a = (require 'net.box'):new(HOT_STANDBY.host, HOT_STANDBY.service)
 ---
 ...
 a:call('_set_pri_lsn', box.info.server.id, box.info.server.lsn)
diff --git a/test/replication/hot_standby.test.lua b/test/replication/hot_standby.test.lua
index e52f915b86fa06c02bfd5b890db023638db34a42..82c5165dfdd6a7e70fe23595a3e160e58cf77671 100644
--- a/test/replication/hot_standby.test.lua
+++ b/test/replication/hot_standby.test.lua
@@ -56,7 +56,9 @@ end;
 
 -- set begin lsn on master, replica and hot_standby.
 --# set variable replica_port to 'replica.listen'
-a = (require 'net.box'):new('127.0.0.1', replica_port)
+REPLICA = require('uri').parse(tostring(replica_port))
+REPLICA ~= nil
+a = (require 'net.box'):new(REPLICA.host, REPLICA.service)
 a:call('_set_pri_lsn', box.info.server.id, box.info.server.lsn)
 a:close()
 
@@ -78,7 +80,9 @@ while box.info.status ~= 'running' do fiber.sleep(0.001) end
 -- hot_standby.listen is garbage, since hot_standby.lua
 -- uses MASTER environment variable for its listen
 --# set variable hot_standby_port to 'hot_standby.master'
-a = (require 'net.box'):new('127.0.0.1', hot_standby_port)
+HOT_STANDBY = require('uri').parse(tostring(hot_standby_port))
+HOT_STANDBY ~= nil
+a = (require 'net.box'):new(HOT_STANDBY.host, HOT_STANDBY.service)
 a:call('_set_pri_lsn', box.info.server.id, box.info.server.lsn)
 a:close()
 
diff --git a/test/replication/swap.test.py b/test/replication/swap.test.py
index 49088df3f94ba61fb7a623c70903340463802149..eb3021ebdad958602e7d0454f9309e03a5765cbc 100644
--- a/test/replication/swap.test.py
+++ b/test/replication/swap.test.py
@@ -7,7 +7,6 @@ import yaml
 REPEAT = 20
 ID_BEGIN = 0
 ID_STEP = 5
-HOST = '127.0.0.1'
 LOGIN = 'test'
 PASSWORD = 'pass123456'
 
@@ -24,7 +23,7 @@ master = server
 master.admin("box.schema.user.create('%s', { password = '%s'})" % (LOGIN, PASSWORD))
 master.admin("box.schema.user.grant('%s', 'read,write,execute', 'universe')" % LOGIN)
 master.sql.py_con.authenticate(LOGIN, PASSWORD)
-master.uri = '%s:%s@%s:%s' % (LOGIN, PASSWORD, HOST, master.sql.port)
+master.uri = '%s:%s@%s' % (LOGIN, PASSWORD, master.sql.uri)
 os.putenv('MASTER', master.uri)
 
 # replica server
@@ -33,7 +32,7 @@ replica.script = "replication/replica.lua"
 replica.vardir = os.path.join(server.vardir, 'replica')
 replica.deploy()
 replica.admin("while box.info.server == nil do require('fiber').sleep(0.01) end")
-replica.uri = '%s:%s@%s:%s' % (LOGIN, PASSWORD, HOST, replica.sql.port)
+replica.uri = '%s:%s@%s' % (LOGIN, PASSWORD, replica.sql.uri)
 replica.admin("while box.space['_priv']:len() < 1 do require('fiber').sleep(0.01) end")
 replica.sql.py_con.authenticate(LOGIN, PASSWORD)
 
@@ -42,7 +41,7 @@ master.admin("s:create_index('primary', {type = 'hash'})")
 
 ### gh-343: replica.cc must not add login and password to proc title
 #status = replica.get_param("status")
-#host_port = "%s:%s" % (HOST, master.sql.port)
+#host_port = "%s:%s" % master.sql.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
diff --git a/test/sophia/crud.result b/test/sophia/crud.result
index 236262ca5bb91327cb6e2bb204c2fe03a5897cfc..52822918ea54bc3c82205c05c31912985589da3d 100644
--- a/test/sophia/crud.result
+++ b/test/sophia/crud.result
@@ -1161,9 +1161,18 @@ index:select(7,  {iterator = box.index.LT})
   - [2]
   - [1]
 ...
+-- random
+dofile('index_random_test.lua')
+---
+...
+index_random_test(space, 'primary')
+---
+- true
+...
 space:drop()
 ---
 ...
+--
 sophia_rmdir()
 ---
 ...
diff --git a/test/sophia/crud.test.lua b/test/sophia/crud.test.lua
index 204853e301b6fdf7f5d15bc3bd69842c2a32745b..191a58057830fb0de8478d8a21cbcf01e88b9e29 100644
--- a/test/sophia/crud.test.lua
+++ b/test/sophia/crud.test.lua
@@ -43,6 +43,13 @@ index:select(7,  {iterator = box.index.LE})
 index:select({}, {iterator = box.index.LT})
 index:select(7,  {iterator = box.index.LT})
 
+-- random
+
+dofile('index_random_test.lua')
+index_random_test(space, 'primary')
+
 space:drop()
 
+--
+
 sophia_rmdir()
diff --git a/test/sophia/dml.result b/test/sophia/dml.result
index 8276e134d01b32ee38e60b1cb41bbee6b9efe6b0..69b0f8746bf5b7d9d09d73126652466522b10167 100644
--- a/test/sophia/dml.result
+++ b/test/sophia/dml.result
@@ -20,7 +20,7 @@ sophia_printdir()
 space = box.schema.create_space('test', { id = 101, engine = 'sophia' })
 ---
 ...
-primary = space:create_index('primary')
+space:create_index('primary')
 ---
 ...
 sophia_printdir()
@@ -40,7 +40,7 @@ sophia_printdir()
 space = box.schema.create_space('test', { id = 102, engine = 'sophia' })
 ---
 ...
-primary = space:create_index('primary')
+space:create_index('primary')
 ---
 ...
 sophia_printdir()
@@ -67,7 +67,7 @@ space:drop()
 space = box.schema.create_space('test', { id = 103, engine = 'sophia' })
 ---
 ...
-primary = space:create_index('primary', {type = 'tree', parts = {1, 'STR'}})
+space:create_index('primary', {type = 'tree', parts = {1, 'STR'}})
 ---
 ...
 space:insert({'test'})
@@ -87,7 +87,7 @@ space:drop()
 space = box.schema.create_space('test', { id = 104, engine = 'sophia' })
 ---
 ...
-primary = space:create_index('primary', {type = 'tree', parts = {1, 'num'}})
+space:create_index('primary', {type = 'tree', parts = {1, 'num'}})
 ---
 ...
 space:insert({13})
@@ -107,7 +107,7 @@ space:drop()
 space = box.schema.create_space('test', { id = 105, engine = 'sophia' })
 ---
 ...
-primary = space:create_index('primary', {type = 'hash'})
+space:create_index('primary', {type = 'hash'})
 ---
 - error: Unsupported index type supplied for index 0 in space 105
 ...
@@ -133,6 +133,39 @@ sophia_printdir()
 ---
 - 
 ...
+-- index size
+space = box.schema.create_space('test', { id = 107, engine = 'sophia' })
+---
+...
+space:create_index('primary')
+---
+...
+primary = space.index[0]
+---
+...
+primary:len()
+---
+- 0
+...
+space:insert({13})
+---
+- [13]
+...
+space:insert({14})
+---
+- [14]
+...
+space:insert({15})
+---
+- [15]
+...
+primary:len()
+---
+- 3
+...
+space:drop()
+---
+...
 sophia_rmdir()
 ---
 ...
diff --git a/test/sophia/dml.test.lua b/test/sophia/dml.test.lua
index b26ba247b795eff9d047a9c4ca9bb9555603347f..56ca115287d3c6edca13fda99bc4e70c403e45c4 100644
--- a/test/sophia/dml.test.lua
+++ b/test/sophia/dml.test.lua
@@ -11,7 +11,7 @@ sophia_printdir()
 -- index create/drop
 
 space = box.schema.create_space('test', { id = 101, engine = 'sophia' })
-primary = space:create_index('primary')
+space:create_index('primary')
 sophia_printdir()
 space:drop()
 sophia_printdir()
@@ -19,7 +19,7 @@ sophia_printdir()
 -- index create/drop alter
 
 space = box.schema.create_space('test', { id = 102, engine = 'sophia' })
-primary = space:create_index('primary')
+space:create_index('primary')
 sophia_printdir()
 _index = box.space[box.schema.INDEX_ID]
 _index:delete{102, 0}
@@ -29,7 +29,7 @@ space:drop()
 -- index create/drop tree string
 
 space = box.schema.create_space('test', { id = 103, engine = 'sophia' })
-primary = space:create_index('primary', {type = 'tree', parts = {1, 'STR'}})
+space:create_index('primary', {type = 'tree', parts = {1, 'STR'}})
 space:insert({'test'})
 sophia_printdir()
 space:drop()
@@ -37,7 +37,7 @@ space:drop()
 -- index create/drop tree num
 
 space = box.schema.create_space('test', { id = 104, engine = 'sophia' })
-primary = space:create_index('primary', {type = 'tree', parts = {1, 'num'}})
+space:create_index('primary', {type = 'tree', parts = {1, 'num'}})
 space:insert({13})
 sophia_printdir()
 space:drop()
@@ -45,7 +45,7 @@ space:drop()
 -- index create hash 
 
 space = box.schema.create_space('test', { id = 105, engine = 'sophia' })
-primary = space:create_index('primary', {type = 'hash'})
+space:create_index('primary', {type = 'hash'})
 space:drop()
 
 -- secondary index create
@@ -56,4 +56,16 @@ space:create_index('secondary')
 space:drop()
 sophia_printdir()
 
+-- index size
+
+space = box.schema.create_space('test', { id = 107, engine = 'sophia' })
+space:create_index('primary')
+primary = space.index[0]
+primary:len()
+space:insert({13})
+space:insert({14})
+space:insert({15})
+primary:len()
+space:drop()
+
 sophia_rmdir()
diff --git a/test/sophia/gh.result b/test/sophia/gh.result
index 9b0340de6b4e16b98f109f45f9ff66abf9a2e336..7debe9511955e359d13fe24eb09354eca7aebd68 100644
--- a/test/sophia/gh.result
+++ b/test/sophia/gh.result
@@ -94,24 +94,6 @@ s:select{10000}
 s:drop()
 ---
 ...
--- gh-456: Sophia: index size() is unsupported
-s = box.schema.create_space('tester',{engine='sophia'})
----
-...
-s:create_index('sophia_index', {})
----
-...
-s.index[0]:len() -- exception
----
-- error: SophiaIndex does not support size operation
-...
-box.error()
----
-- error: SophiaIndex does not support size operation
-...
-s:drop()
----
-...
 -- gh-436: No error when creating temporary sophia space
 s = box.schema.create_space('tester',{engine='sophia', temporary=true})
 ---
diff --git a/test/sophia/gh.test.lua b/test/sophia/gh.test.lua
index 1cfc5e8101132fb959903d6e36eb896413532c08..790863b4d17aee01ae13a365d1f4ff4f0924de0f 100644
--- a/test/sophia/gh.test.lua
+++ b/test/sophia/gh.test.lua
@@ -39,14 +39,6 @@ box.rollback()
 s:select{10000}
 s:drop()
 
--- gh-456: Sophia: index size() is unsupported
-
-s = box.schema.create_space('tester',{engine='sophia'})
-s:create_index('sophia_index', {})
-s.index[0]:len() -- exception
-box.error()
-s:drop()
-
 -- gh-436: No error when creating temporary sophia space
 
 s = box.schema.create_space('tester',{engine='sophia', temporary=true})
diff --git a/test/sophia/index_random_test.lua b/test/sophia/index_random_test.lua
new file mode 100644
index 0000000000000000000000000000000000000000..5fb09f03c2b4c48723d45c62fd7181b1a5e0da73
--- /dev/null
+++ b/test/sophia/index_random_test.lua
@@ -0,0 +1,36 @@
+
+function index_random_test(space, index_no)
+	local COUNT = 1028
+	-- clear the space
+	space:truncate()
+	-- randomize
+	math.randomseed(os.time())
+	-- insert values into the index
+	for k=1,COUNT,1 do space:insert{k}  end
+	local rnd_start = math.random(4294967296)
+	-- try to get all values from the index using index.random
+	local tuples = {}
+	local found = 0
+	while found < COUNT do
+		local rnd = math.random(4294967296)
+		if rnd == rnd_start then
+			error('too many iterations')
+			return nil
+		end
+
+		local tuple = space.index[index_no]:random(rnd)
+		if tuple == nil then
+			error('nil returned')
+			return nil
+		end
+		print(tuple)
+
+		local k = tuple[1]
+		if tuples[k] == nil then
+			found = found + 1
+		end
+		tuples[k] = 1
+	end
+
+	return true
+end
diff --git a/test/sophia/suite.ini b/test/sophia/suite.ini
index 5139d0b87a1637c650a005a530dc72e9ef6f6986..ddf62d5dadc3cadb5233e84cb7d7eed7348221ba 100644
--- a/test/sophia/suite.ini
+++ b/test/sophia/suite.ini
@@ -5,5 +5,5 @@ script = box.lua
 disabled =
 valgrind_disabled =
 release_disabled =
-lua_libs =
+lua_libs = index_random_test.lua
 use_unix_sockets = True
diff --git a/test/unit/fiob.skipcond b/test/unit/fiob.skipcond
new file mode 100644
index 0000000000000000000000000000000000000000..d246d3b7c4bf083f7654bd631877fc1579adaedf
--- /dev/null
+++ b/test/unit/fiob.skipcond
@@ -0,0 +1,17 @@
+# vim: set ft=python :
+import re
+import os
+import os.path
+import tempfile
+
+dir = tempfile.mkdtemp()
+file = os.path.join(dir, 'test-o-direct')
+
+try:
+    fh = os.open(file, os.O_CREAT | os.O_DIRECT | os.O_TRUNC | os.O_RDWR)
+    os.unlink(file)
+    os.rmdir(dir)
+except:
+    self.skip = 1
+
+
diff --git a/third_party/sophia b/third_party/sophia
index 95a187853ad34e858897871e6b4047df82febf89..6c6c69d376d8452a7dfefd2086c4934065ab89cc 160000
--- a/third_party/sophia
+++ b/third_party/sophia
@@ -1 +1 @@
-Subproject commit 95a187853ad34e858897871e6b4047df82febf89
+Subproject commit 6c6c69d376d8452a7dfefd2086c4934065ab89cc