[Tarantool-patches] [PATCH v3 3/4] errinj: add ERRINJ_FIBER_MADVISE and ERRINJ_FIBER_MPROTECT

Cyrill Gorcunov gorcunov at gmail.com
Tue Feb 4 17:31:46 MSK 2020


We will need them to test fiber's stack memory manipulations.

Co-developed-by: Alexander Turenko <alexander.turenko at tarantool.org>
Signed-off-by: Cyrill Gorcunov <gorcunov at gmail.com>
---
 src/lib/core/errinj.h  |    2 +
 src/lib/core/fiber.c   |   20 +-
 test/box/errinj.result | 2616 +++++++++++++++++++++-------------------
 3 files changed, 1380 insertions(+), 1258 deletions(-)

diff --git a/src/lib/core/errinj.h b/src/lib/core/errinj.h
index 672da2119..ed0cba903 100644
--- a/src/lib/core/errinj.h
+++ b/src/lib/core/errinj.h
@@ -135,6 +135,8 @@ struct errinj {
 	_(ERRINJ_COIO_SENDFILE_CHUNK, ERRINJ_INT, {.iparam = -1}) \
 	_(ERRINJ_SWIM_FD_ONLY, ERRINJ_BOOL, {.bparam = false}) \
 	_(ERRINJ_DYN_MODULE_COUNT, ERRINJ_INT, {.iparam = 0}) \
+	_(ERRINJ_FIBER_MADVISE, ERRINJ_BOOL, {.bparam = false}) \
+	_(ERRINJ_FIBER_MPROTECT, ERRINJ_INT, {.iparam = -1})
 
 ENUM0(errinj_id, ERRINJ_LIST);
 extern struct errinj errinjs[];
diff --git a/src/lib/core/fiber.c b/src/lib/core/fiber.c
index d6ff481a5..36f1b1209 100644
--- a/src/lib/core/fiber.c
+++ b/src/lib/core/fiber.c
@@ -41,6 +41,7 @@
 #include "assoc.h"
 #include "memory.h"
 #include "trigger.h"
+#include "errinj.h"
 
 #if ENABLE_FIBER_TOP
 #include <x86intrin.h> /* __rdtscp() */
@@ -176,7 +177,14 @@ static int (*fiber_invoke)(fiber_func f, va_list ap);
 static inline int
 fiber_madvise(void *addr, size_t len, int advice)
 {
-	if (madvise(addr, len, advice) != 0) {
+	int rc = 0;
+
+	ERROR_INJECT(ERRINJ_FIBER_MADVISE, {
+		errno = ENOMEM;
+		rc = -1;
+	});
+
+	if (rc != 0 || madvise(addr, len, advice) != 0) {
 		diag_set(SystemError, "fiber madvise %p:%zu:%d failed",
 			 addr, len, advice);
 		return -1;
@@ -187,7 +195,15 @@ fiber_madvise(void *addr, size_t len, int advice)
 static inline int
 fiber_mprotect(void *addr, size_t len, int prot)
 {
-	if (mprotect(addr, len, prot) != 0) {
+	int rc = 0;
+
+	struct errinj *inj = errinj(ERRINJ_FIBER_MPROTECT, ERRINJ_INT);
+	if (inj != NULL && inj->iparam == prot) {
+		errno = ENOMEM;
+		rc = -1;
+	}
+
+	if (rc != 0 || mprotect(addr, len, prot) != 0) {
 		diag_set(SystemError, "fiber mprotect %p:%zu:%d failed",
 			 addr, len, prot);
 		return -1;
diff --git a/test/box/errinj.result b/test/box/errinj.result
index babe36b1b..c58e1d2e8 100644
--- a/test/box/errinj.result
+++ b/test/box/errinj.result
@@ -1,1783 +1,1887 @@
+-- test-run result file version 2
 -- Test that recovery had been completed without errors
 test_run = require('test_run').new()
----
-...
+ | ---
+ | ...
 test_run:cmd("restart server default")
+ | 
 box.error.last() == nil
----
-- true
-...
+ | ---
+ | - true
+ | ...
+
 errinj = box.error.injection
----
-...
+ | ---
+ | ...
 net_box = require('net.box')
----
-...
+ | ---
+ | ...
+
 space = box.schema.space.create('tweedledum')
----
-...
+ | ---
+ | ...
 index = space:create_index('primary', { type = 'hash' })
----
-...
+ | ---
+ | ...
+
 errinj.info()
----
-- ERRINJ_VY_RUN_WRITE_STMT_TIMEOUT:
-    state: 0
-  ERRINJ_WAL_WRITE:
-    state: false
-  ERRINJ_RELAY_BREAK_LSN:
-    state: -1
-  ERRINJ_HTTPC_EXECUTE:
-    state: false
-  ERRINJ_VYRUN_DATA_READ:
-    state: false
-  ERRINJ_SWIM_FD_ONLY:
-    state: false
-  ERRINJ_SQL_NAME_NORMALIZATION:
-    state: false
-  ERRINJ_VY_SCHED_TIMEOUT:
-    state: 0
-  ERRINJ_COIO_SENDFILE_CHUNK:
-    state: -1
-  ERRINJ_HTTP_RESPONSE_ADD_WAIT:
-    state: false
-  ERRINJ_WAL_WRITE_PARTIAL:
-    state: -1
-  ERRINJ_VY_GC:
-    state: false
-  ERRINJ_WAL_DELAY:
-    state: false
-  ERRINJ_INDEX_ALLOC:
-    state: false
-  ERRINJ_WAL_WRITE_EOF:
-    state: false
-  ERRINJ_WAL_SYNC:
-    state: false
-  ERRINJ_BUILD_INDEX:
-    state: -1
-  ERRINJ_BUILD_INDEX_DELAY:
-    state: false
-  ERRINJ_VY_RUN_FILE_RENAME:
-    state: false
-  ERRINJ_VY_COMPACTION_DELAY:
-    state: false
-  ERRINJ_VY_DUMP_DELAY:
-    state: false
-  ERRINJ_VY_DELAY_PK_LOOKUP:
-    state: false
-  ERRINJ_VY_TASK_COMPLETE:
-    state: false
-  ERRINJ_PORT_DUMP:
-    state: false
-  ERRINJ_WAL_BREAK_LSN:
-    state: -1
-  ERRINJ_WAL_IO:
-    state: false
-  ERRINJ_WAL_FALLOCATE:
-    state: 0
-  ERRINJ_DYN_MODULE_COUNT:
-    state: 0
-  ERRINJ_VY_INDEX_FILE_RENAME:
-    state: false
-  ERRINJ_TUPLE_FORMAT_COUNT:
-    state: -1
-  ERRINJ_TUPLE_ALLOC:
-    state: false
-  ERRINJ_VY_RUN_WRITE_DELAY:
-    state: false
-  ERRINJ_VY_READ_PAGE:
-    state: false
-  ERRINJ_RELAY_REPORT_INTERVAL:
-    state: 0
-  ERRINJ_VY_LOG_FILE_RENAME:
-    state: false
-  ERRINJ_VY_READ_PAGE_TIMEOUT:
-    state: 0
-  ERRINJ_XLOG_META:
-    state: false
-  ERRINJ_SIO_READ_MAX:
-    state: -1
-  ERRINJ_SNAP_COMMIT_DELAY:
-    state: false
-  ERRINJ_WAL_WRITE_DISK:
-    state: false
-  ERRINJ_SNAP_WRITE_DELAY:
-    state: false
-  ERRINJ_LOG_ROTATE:
-    state: false
-  ERRINJ_VY_RUN_WRITE:
-    state: false
-  ERRINJ_CHECK_FORMAT_DELAY:
-    state: false
-  ERRINJ_VY_LOG_FLUSH_DELAY:
-    state: false
-  ERRINJ_RELAY_FINAL_JOIN:
-    state: false
-  ERRINJ_REPLICA_JOIN_DELAY:
-    state: false
-  ERRINJ_RELAY_FINAL_SLEEP:
-    state: false
-  ERRINJ_VY_RUN_DISCARD:
-    state: false
-  ERRINJ_WAL_ROTATE:
-    state: false
-  ERRINJ_RELAY_EXIT_DELAY:
-    state: 0
-  ERRINJ_VY_POINT_ITER_WAIT:
-    state: false
-  ERRINJ_MEMTX_DELAY_GC:
-    state: false
-  ERRINJ_IPROTO_TX_DELAY:
-    state: false
-  ERRINJ_XLOG_READ:
-    state: -1
-  ERRINJ_TUPLE_FIELD:
-    state: false
-  ERRINJ_XLOG_GARBAGE:
-    state: false
-  ERRINJ_VY_INDEX_DUMP:
-    state: -1
-  ERRINJ_VY_READ_PAGE_DELAY:
-    state: false
-  ERRINJ_TESTING:
-    state: false
-  ERRINJ_RELAY_SEND_DELAY:
-    state: false
-  ERRINJ_VY_SQUASH_TIMEOUT:
-    state: 0
-  ERRINJ_VY_LOG_FLUSH:
-    state: false
-  ERRINJ_RELAY_TIMEOUT:
-    state: 0
-...
+ | ---
+ | - ERRINJ_VY_RUN_WRITE_STMT_TIMEOUT:
+ |     state: 0
+ |   ERRINJ_WAL_BREAK_LSN:
+ |     state: -1
+ |   ERRINJ_VYRUN_DATA_READ:
+ |     state: false
+ |   ERRINJ_VY_SCHED_TIMEOUT:
+ |     state: 0
+ |   ERRINJ_HTTP_RESPONSE_ADD_WAIT:
+ |     state: false
+ |   ERRINJ_WAL_WRITE_EOF:
+ |     state: false
+ |   ERRINJ_BUILD_INDEX_DELAY:
+ |     state: false
+ |   ERRINJ_VY_DELAY_PK_LOOKUP:
+ |     state: false
+ |   ERRINJ_VY_POINT_ITER_WAIT:
+ |     state: false
+ |   ERRINJ_WAL_IO:
+ |     state: false
+ |   ERRINJ_VY_INDEX_FILE_RENAME:
+ |     state: false
+ |   ERRINJ_TUPLE_FORMAT_COUNT:
+ |     state: -1
+ |   ERRINJ_TUPLE_ALLOC:
+ |     state: false
+ |   ERRINJ_VY_RUN_FILE_RENAME:
+ |     state: false
+ |   ERRINJ_VY_READ_PAGE:
+ |     state: false
+ |   ERRINJ_RELAY_REPORT_INTERVAL:
+ |     state: 0
+ |   ERRINJ_RELAY_BREAK_LSN:
+ |     state: -1
+ |   ERRINJ_XLOG_META:
+ |     state: false
+ |   ERRINJ_SNAP_COMMIT_DELAY:
+ |     state: false
+ |   ERRINJ_VY_RUN_WRITE:
+ |     state: false
+ |   ERRINJ_BUILD_INDEX:
+ |     state: -1
+ |   ERRINJ_RELAY_FINAL_JOIN:
+ |     state: false
+ |   ERRINJ_REPLICA_JOIN_DELAY:
+ |     state: false
+ |   ERRINJ_LOG_ROTATE:
+ |     state: false
+ |   ERRINJ_MEMTX_DELAY_GC:
+ |     state: false
+ |   ERRINJ_XLOG_GARBAGE:
+ |     state: false
+ |   ERRINJ_VY_READ_PAGE_DELAY:
+ |     state: false
+ |   ERRINJ_SWIM_FD_ONLY:
+ |     state: false
+ |   ERRINJ_WAL_WRITE:
+ |     state: false
+ |   ERRINJ_HTTPC_EXECUTE:
+ |     state: false
+ |   ERRINJ_SQL_NAME_NORMALIZATION:
+ |     state: false
+ |   ERRINJ_WAL_WRITE_PARTIAL:
+ |     state: -1
+ |   ERRINJ_VY_GC:
+ |     state: false
+ |   ERRINJ_WAL_DELAY:
+ |     state: false
+ |   ERRINJ_XLOG_READ:
+ |     state: -1
+ |   ERRINJ_WAL_SYNC:
+ |     state: false
+ |   ERRINJ_VY_TASK_COMPLETE:
+ |     state: false
+ |   ERRINJ_PORT_DUMP:
+ |     state: false
+ |   ERRINJ_COIO_SENDFILE_CHUNK:
+ |     state: -1
+ |   ERRINJ_DYN_MODULE_COUNT:
+ |     state: 0
+ |   ERRINJ_SIO_READ_MAX:
+ |     state: -1
+ |   ERRINJ_FIBER_MPROTECT:
+ |     state: -1
+ |   ERRINJ_FIBER_MADVISE:
+ |     state: false
+ |   ERRINJ_RELAY_TIMEOUT:
+ |     state: 0
+ |   ERRINJ_VY_DUMP_DELAY:
+ |     state: false
+ |   ERRINJ_VY_SQUASH_TIMEOUT:
+ |     state: 0
+ |   ERRINJ_VY_LOG_FLUSH_DELAY:
+ |     state: false
+ |   ERRINJ_RELAY_SEND_DELAY:
+ |     state: false
+ |   ERRINJ_VY_COMPACTION_DELAY:
+ |     state: false
+ |   ERRINJ_VY_LOG_FILE_RENAME:
+ |     state: false
+ |   ERRINJ_VY_RUN_DISCARD:
+ |     state: false
+ |   ERRINJ_WAL_ROTATE:
+ |     state: false
+ |   ERRINJ_VY_READ_PAGE_TIMEOUT:
+ |     state: 0
+ |   ERRINJ_VY_INDEX_DUMP:
+ |     state: -1
+ |   ERRINJ_TUPLE_FIELD:
+ |     state: false
+ |   ERRINJ_SNAP_WRITE_DELAY:
+ |     state: false
+ |   ERRINJ_IPROTO_TX_DELAY:
+ |     state: false
+ |   ERRINJ_RELAY_EXIT_DELAY:
+ |     state: 0
+ |   ERRINJ_RELAY_FINAL_SLEEP:
+ |     state: false
+ |   ERRINJ_WAL_WRITE_DISK:
+ |     state: false
+ |   ERRINJ_CHECK_FORMAT_DELAY:
+ |     state: false
+ |   ERRINJ_TESTING:
+ |     state: false
+ |   ERRINJ_VY_RUN_WRITE_DELAY:
+ |     state: false
+ |   ERRINJ_WAL_FALLOCATE:
+ |     state: 0
+ |   ERRINJ_VY_LOG_FLUSH:
+ |     state: false
+ |   ERRINJ_INDEX_ALLOC:
+ |     state: false
+ | ...
 errinj.set("some-injection", true)
----
-- 'error: can''t find error injection ''some-injection'''
-...
+ | ---
+ | - 'error: can''t find error injection ''some-injection'''
+ | ...
 errinj.set("some-injection") -- check error
----
-- 'error: can''t find error injection ''some-injection'''
-...
+ | ---
+ | - 'error: can''t find error injection ''some-injection'''
+ | ...
 space:select{222444}
----
-- []
-...
+ | ---
+ | - []
+ | ...
 errinj.set("ERRINJ_TESTING", true)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 space:select{222444}
----
-- error: Error injection 'ERRINJ_TESTING'
-...
+ | ---
+ | - error: Error injection 'ERRINJ_TESTING'
+ | ...
 errinj.set("ERRINJ_TESTING", false)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
+
 -- Check how well we handle a failed log write
 errinj.set("ERRINJ_WAL_IO", true)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 space:insert{1}
----
-- error: Failed to write to disk
-...
+ | ---
+ | - error: Failed to write to disk
+ | ...
 space:get{1}
----
-...
+ | ---
+ | ...
 errinj.set("ERRINJ_WAL_IO", false)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 space:insert{1}
----
-- [1]
-...
+ | ---
+ | - [1]
+ | ...
 errinj.set("ERRINJ_WAL_IO", true)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 space:update(1, {{'=', 2, 2}})
----
-- error: Failed to write to disk
-...
+ | ---
+ | - error: Failed to write to disk
+ | ...
 space:get{1}
----
-- [1]
-...
+ | ---
+ | - [1]
+ | ...
 space:get{2}
----
-...
+ | ---
+ | ...
 errinj.set("ERRINJ_WAL_IO", false)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 space:update(1, {{'=', 2, 2}})
----
-- [1, 2]
-...
+ | ---
+ | - [1, 2]
+ | ...
 space:truncate()
----
-...
+ | ---
+ | ...
+
 -- Check that WAL vclock isn't promoted on failed write.
 lsn1 = box.info.vclock[box.info.id]
----
-...
+ | ---
+ | ...
 errinj.set("ERRINJ_WAL_WRITE_PARTIAL", 0)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 space:insert{1}
----
-- error: Failed to write to disk
-...
+ | ---
+ | - error: Failed to write to disk
+ | ...
 errinj.set("ERRINJ_WAL_WRITE_PARTIAL", -1)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 space:insert{1}
----
-- [1]
-...
+ | ---
+ | - [1]
+ | ...
 -- Check vclock was promoted only one time
 box.info.vclock[box.info.id] == lsn1 + 1
----
-- true
-...
+ | ---
+ | - true
+ | ...
 errinj.set("ERRINJ_WAL_WRITE_PARTIAL", 0)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 space:update(1, {{'=', 2, 2}})
----
-- error: Failed to write to disk
-...
+ | ---
+ | - error: Failed to write to disk
+ | ...
 space:get{1}
----
-- [1]
-...
+ | ---
+ | - [1]
+ | ...
 errinj.set("ERRINJ_WAL_WRITE_PARTIAL", -1)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 space:update(1, {{'=', 2, 2}})
----
-- [1, 2]
-...
+ | ---
+ | - [1, 2]
+ | ...
 -- Check vclock was promoted only two times
 box.info.vclock[box.info.id] == lsn1 + 2
----
-- true
-...
+ | ---
+ | - true
+ | ...
 space:truncate()
----
-...
+ | ---
+ | ...
+
 -- Check a failed log rotation
 errinj.set("ERRINJ_WAL_ROTATE", true)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 space:insert{1}
----
-- error: Failed to write to disk
-...
+ | ---
+ | - error: Failed to write to disk
+ | ...
 space:get{1}
----
-...
+ | ---
+ | ...
 errinj.set("ERRINJ_WAL_ROTATE", false)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 space:insert{1}
----
-- [1]
-...
+ | ---
+ | - [1]
+ | ...
 errinj.set("ERRINJ_WAL_ROTATE", true)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 space:update(1, {{'=', 2, 2}})
----
-- error: Failed to write to disk
-...
+ | ---
+ | - error: Failed to write to disk
+ | ...
 space:get{1}
----
-- [1]
-...
+ | ---
+ | - [1]
+ | ...
 space:get{2}
----
-...
+ | ---
+ | ...
 errinj.set("ERRINJ_WAL_ROTATE", false)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 space:update(1, {{'=', 2, 2}})
----
-- [1, 2]
-...
+ | ---
+ | - [1, 2]
+ | ...
 space:get{1}
----
-- [1, 2]
-...
+ | ---
+ | - [1, 2]
+ | ...
 space:get{2}
----
-...
+ | ---
+ | ...
 space:truncate()
----
-...
+ | ---
+ | ...
+
 space:drop()
----
-...
+ | ---
+ | ...
+
 -- Check how well we handle a failed log write in DDL
 s_disabled = box.schema.space.create('disabled')
----
-...
+ | ---
+ | ...
 s_withindex = box.schema.space.create('withindex')
----
-...
+ | ---
+ | ...
 index1 = s_withindex:create_index('primary', { type = 'hash' })
----
-...
+ | ---
+ | ...
 s_withdata = box.schema.space.create('withdata')
----
-...
+ | ---
+ | ...
 index2 = s_withdata:create_index('primary', { type = 'tree' })
----
-...
+ | ---
+ | ...
 s_withdata:insert{1, 2, 3, 4, 5}
----
-- [1, 2, 3, 4, 5]
-...
+ | ---
+ | - [1, 2, 3, 4, 5]
+ | ...
 s_withdata:insert{4, 5, 6, 7, 8}
----
-- [4, 5, 6, 7, 8]
-...
+ | ---
+ | - [4, 5, 6, 7, 8]
+ | ...
 index3 = s_withdata:create_index('secondary', { type = 'hash', parts = {2, 'unsigned', 3, 'unsigned' }})
----
-...
+ | ---
+ | ...
 errinj.set("ERRINJ_WAL_IO", true)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 test = box.schema.space.create('test')
----
-- error: Failed to write to disk
-...
+ | ---
+ | - error: Failed to write to disk
+ | ...
 s_disabled:create_index('primary', { type = 'hash' })
----
-- error: Failed to write to disk
-...
+ | ---
+ | - error: Failed to write to disk
+ | ...
 s_disabled.enabled
----
-- false
-...
+ | ---
+ | - false
+ | ...
 s_disabled:insert{0}
----
-- error: 'No index #0 is defined in space ''disabled'''
-...
+ | ---
+ | - error: 'No index #0 is defined in space ''disabled'''
+ | ...
 s_withindex:create_index('secondary', { type = 'tree', parts = { 2, 'unsigned'} })
----
-- error: Failed to write to disk
-...
+ | ---
+ | - error: Failed to write to disk
+ | ...
 s_withindex.index.secondary
----
-- null
-...
+ | ---
+ | - null
+ | ...
 s_withdata.index.secondary:drop()
----
-- error: Failed to write to disk
-...
+ | ---
+ | - error: Failed to write to disk
+ | ...
 s_withdata.index.secondary.unique
----
-- true
-...
+ | ---
+ | - true
+ | ...
 s_withdata:drop()
----
-- error: Failed to write to disk
-...
+ | ---
+ | - error: Failed to write to disk
+ | ...
 box.space['withdata'].enabled
----
-- true
-...
+ | ---
+ | - true
+ | ...
 index4 = s_withdata:create_index('another', { type = 'tree', parts = { 5, 'unsigned' }, unique = false})
----
-- error: Failed to write to disk
-...
+ | ---
+ | - error: Failed to write to disk
+ | ...
 s_withdata.index.another
----
-- null
-...
+ | ---
+ | - null
+ | ...
 errinj.set("ERRINJ_WAL_IO", false)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 test = box.schema.space.create('test')
----
-...
+ | ---
+ | ...
 index5 = s_disabled:create_index('primary', { type = 'hash' })
----
-...
+ | ---
+ | ...
 s_disabled.enabled
----
-- true
-...
+ | ---
+ | - true
+ | ...
 s_disabled:insert{0}
----
-- [0]
-...
+ | ---
+ | - [0]
+ | ...
 index6 = s_withindex:create_index('secondary', { type = 'tree', parts = { 2, 'unsigned'} })
----
-...
+ | ---
+ | ...
 s_withindex.index.secondary.unique
----
-- true
-...
+ | ---
+ | - true
+ | ...
 s_withdata.index.secondary:drop()
----
-...
+ | ---
+ | ...
 s_withdata.index.secondary
----
-- null
-...
+ | ---
+ | - null
+ | ...
 s_withdata:drop()
----
-...
+ | ---
+ | ...
 box.space['withdata']
----
-- null
-...
+ | ---
+ | - null
+ | ...
 index7 = s_withdata:create_index('another', { type = 'tree', parts = { 5, 'unsigned' }, unique = false})
----
-- error: Space 'withdata' does not exist
-...
+ | ---
+ | - error: Space 'withdata' does not exist
+ | ...
 s_withdata.index.another
----
-- null
-...
+ | ---
+ | - null
+ | ...
 test:drop()
----
-...
+ | ---
+ | ...
 s_disabled:drop()
----
-...
+ | ---
+ | ...
 s_withindex:drop()
----
-...
+ | ---
+ | ...
+
 -- Check transaction rollback when out of memory
 env = require('test_run')
----
-...
+ | ---
+ | ...
 test_run = env.new()
----
-...
+ | ---
+ | ...
+
 s = box.schema.space.create('s')
----
-...
+ | ---
+ | ...
 _ = s:create_index('pk')
----
-...
+ | ---
+ | ...
 errinj.set("ERRINJ_TUPLE_ALLOC", true)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 s:auto_increment{}
----
-- error: Failed to allocate 16 bytes in slab allocator for memtx_tuple
-...
+ | ---
+ | - error: Failed to allocate 16 bytes in slab allocator for memtx_tuple
+ | ...
 s:select{}
----
-- []
-...
+ | ---
+ | - []
+ | ...
 s:auto_increment{}
----
-- error: Failed to allocate 16 bytes in slab allocator for memtx_tuple
-...
+ | ---
+ | - error: Failed to allocate 16 bytes in slab allocator for memtx_tuple
+ | ...
 s:select{}
----
-- []
-...
+ | ---
+ | - []
+ | ...
 s:auto_increment{}
----
-- error: Failed to allocate 16 bytes in slab allocator for memtx_tuple
-...
+ | ---
+ | - error: Failed to allocate 16 bytes in slab allocator for memtx_tuple
+ | ...
 s:select{}
----
-- []
-...
+ | ---
+ | - []
+ | ...
 test_run:cmd("setopt delimiter ';'")
----
-- true
-...
+ | ---
+ | - true
+ | ...
 box.begin()
     s:insert{1}
 box.commit();
----
-- error: Failed to allocate 16 bytes in slab allocator for memtx_tuple
-...
+ | ---
+ | - error: Failed to allocate 16 bytes in slab allocator for memtx_tuple
+ | ...
 box.rollback();
----
-...
+ | ---
+ | ...
 s:select{};
----
-- []
-...
+ | ---
+ | - []
+ | ...
 box.begin()
     s:insert{1}
     s:insert{2}
 box.commit();
----
-- error: Failed to allocate 16 bytes in slab allocator for memtx_tuple
-...
+ | ---
+ | - error: Failed to allocate 16 bytes in slab allocator for memtx_tuple
+ | ...
 s:select{};
----
-- []
-...
+ | ---
+ | - []
+ | ...
 box.rollback();
----
-...
+ | ---
+ | ...
 box.begin()
     pcall(s.insert, s, {1})
     s:insert{2}
 box.commit();
----
-- error: Failed to allocate 16 bytes in slab allocator for memtx_tuple
-...
+ | ---
+ | - error: Failed to allocate 16 bytes in slab allocator for memtx_tuple
+ | ...
 s:select{};
----
-- []
-...
+ | ---
+ | - []
+ | ...
 box.rollback();
----
-...
+ | ---
+ | ...
 errinj.set("ERRINJ_TUPLE_ALLOC", false);
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 box.begin()
     s:insert{1}
     errinj.set("ERRINJ_TUPLE_ALLOC", true)
     s:insert{2}
 box.commit();
----
-- error: Failed to allocate 16 bytes in slab allocator for memtx_tuple
-...
+ | ---
+ | - error: Failed to allocate 16 bytes in slab allocator for memtx_tuple
+ | ...
 errinj.set("ERRINJ_TUPLE_ALLOC", false);
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 box.rollback();
----
-...
+ | ---
+ | ...
 s:select{};
----
-- []
-...
+ | ---
+ | - []
+ | ...
 box.begin()
     s:insert{1}
     errinj.set("ERRINJ_TUPLE_ALLOC", true)
     pcall(s.insert, s, {2})
 box.commit();
----
-...
+ | ---
+ | ...
 s:select{};
----
-- - [1]
-...
+ | ---
+ | - - [1]
+ | ...
 box.rollback();
----
-...
+ | ---
+ | ...
+
 test_run:cmd("setopt delimiter ''");
----
-- true
-...
+ | ---
+ | - true
+ | ...
 errinj.set("ERRINJ_TUPLE_ALLOC", false)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
+
 s:drop()
----
-...
+ | ---
+ | ...
 s = box.schema.space.create('test')
----
-...
+ | ---
+ | ...
 _ = s:create_index('test', {parts = {1, 'unsigned', 3, 'unsigned', 5, 'unsigned'}})
----
-...
+ | ---
+ | ...
 s:insert{1, 2, 3, 4, 5, 6}
----
-- [1, 2, 3, 4, 5, 6]
-...
+ | ---
+ | - [1, 2, 3, 4, 5, 6]
+ | ...
 t = s:select{}[1]
----
-...
+ | ---
+ | ...
 errinj.set("ERRINJ_TUPLE_FIELD", true)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 tostring(t[1]) .. tostring(t[2]) ..tostring(t[3]) .. tostring(t[4]) .. tostring(t[5]) .. tostring(t[6])
----
-- 1nil3nil5nil
-...
+ | ---
+ | - 1nil3nil5nil
+ | ...
 errinj.set("ERRINJ_TUPLE_FIELD", false)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 tostring(t[1]) .. tostring(t[2]) ..tostring(t[3]) .. tostring(t[4]) .. tostring(t[5]) .. tostring(t[6])
----
-- '123456'
-...
+ | ---
+ | - '123456'
+ | ...
+
 s:drop()
----
-...
+ | ---
+ | ...
 s = box.schema.space.create('test')
----
-...
+ | ---
+ | ...
 _ = s:create_index('test', {parts = {2, 'unsigned', 4, 'unsigned', 6, 'unsigned'}})
----
-...
+ | ---
+ | ...
 s:insert{1, 2, 3, 4, 5, 6}
----
-- [1, 2, 3, 4, 5, 6]
-...
+ | ---
+ | - [1, 2, 3, 4, 5, 6]
+ | ...
 t = s:select{}[1]
----
-...
+ | ---
+ | ...
 errinj.set("ERRINJ_TUPLE_FIELD", true)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 tostring(t[1]) .. tostring(t[2]) ..tostring(t[3]) .. tostring(t[4]) .. tostring(t[5]) .. tostring(t[6])
----
-- 12nil4nil6
-...
+ | ---
+ | - 12nil4nil6
+ | ...
 errinj.set("ERRINJ_TUPLE_FIELD", false)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 tostring(t[1]) .. tostring(t[2]) ..tostring(t[3]) .. tostring(t[4]) .. tostring(t[5]) .. tostring(t[6])
----
-- '123456'
-...
+ | ---
+ | - '123456'
+ | ...
+
 -- Cleanup
 s:drop()
----
-...
+ | ---
+ | ...
+
 --
 -- gh-2046: don't store offsets for sequential multi-parts keys
 --
 s = box.schema.space.create('test')
----
-...
+ | ---
+ | ...
 _ = s:create_index('seq2', { parts = { 1, 'unsigned', 2, 'unsigned' }})
----
-...
+ | ---
+ | ...
 _ = s:create_index('seq3', { parts = { 1, 'unsigned', 2, 'unsigned', 3, 'unsigned' }})
----
-...
+ | ---
+ | ...
 _ = s:create_index('seq5', { parts = { 1, 'unsigned', 2, 'unsigned', 3, 'unsigned', 4, 'scalar', 5, 'number' }})
----
-...
+ | ---
+ | ...
 _ = s:create_index('rnd1', { parts = { 3, 'unsigned' }})
----
-...
+ | ---
+ | ...
+
 errinj.set("ERRINJ_TUPLE_FIELD", true)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 tuple = s:insert({1, 2, 3, 4, 5, 6, 7, 8, 9, 10})
----
-...
+ | ---
+ | ...
 tuple
----
-- [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
-...
+ | ---
+ | - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+ | ...
 tuple[1] -- not-null, always accessible
----
-- 1
-...
+ | ---
+ | - 1
+ | ...
 tuple[2] -- null, doesn't have offset
----
-- null
-...
+ | ---
+ | - null
+ | ...
 tuple[3] -- not null, has offset
----
-- 3
-...
+ | ---
+ | - 3
+ | ...
 tuple[4] -- null, doesn't have offset
----
-- null
-...
+ | ---
+ | - null
+ | ...
 tuple[5] -- null, doesn't have offset
----
-- null
-...
+ | ---
+ | - null
+ | ...
 s.index.seq2:select({1})
----
-- - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
-...
+ | ---
+ | - - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+ | ...
 s.index.seq2:select({1, 2})
----
-- - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
-...
+ | ---
+ | - - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+ | ...
 s.index.seq3:select({1})
----
-- - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
-...
+ | ---
+ | - - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+ | ...
 s.index.seq3:select({1, 2, 3})
----
-- - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
-...
+ | ---
+ | - - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+ | ...
 s.index.seq5:select({1})
----
-- - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
-...
+ | ---
+ | - - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+ | ...
 s.index.seq5:select({1, 2, 3, 4, 5})
----
-- - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
-...
+ | ---
+ | - - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+ | ...
 s.index.rnd1:select({3})
----
-- - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
-...
+ | ---
+ | - - [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
+ | ...
 errinj.set("ERRINJ_TUPLE_FIELD", false)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 s:drop()
----
-...
+ | ---
+ | ...
+
 space = box.schema.space.create('test')
----
-...
+ | ---
+ | ...
 _ = space:create_index('pk')
----
-...
+ | ---
+ | ...
 errinj.set("ERRINJ_WAL_WRITE", true)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 space:insert{1}
----
-- error: Failed to write to disk
-...
+ | ---
+ | - error: Failed to write to disk
+ | ...
 errinj.set("ERRINJ_WAL_WRITE", false)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
+
 errinj.set("ERRINJ_WAL_WRITE_DISK", true)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 _ = space:insert{1, require'digest'.urandom(192 * 1024)}
----
-- error: Failed to write to disk
-...
+ | ---
+ | - error: Failed to write to disk
+ | ...
 errinj.set("ERRINJ_WAL_WRITE_DISK", false)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
+
 _ = space:insert{1}
----
-...
+ | ---
+ | ...
 errinj.set("ERRINJ_WAL_WRITE", true)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 box.snapshot()
----
-- error: Error injection 'xlog write injection'
-...
+ | ---
+ | - error: Error injection 'xlog write injection'
+ | ...
 errinj.set("ERRINJ_WAL_WRITE", false)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 space:drop()
----
-...
+ | ---
+ | ...
+
 --test space:bsize() in case of memory error
 utils = dofile('utils.lua')
----
-...
+ | ---
+ | ...
 s = box.schema.space.create('space_bsize')
----
-...
+ | ---
+ | ...
 idx = s:create_index('primary')
----
-...
+ | ---
+ | ...
+
 for i = 1, 13 do s:insert{ i, string.rep('x', i) } end
----
-...
+ | ---
+ | ...
+
 s:bsize()
----
-- 130
-...
+ | ---
+ | - 130
+ | ...
 utils.space_bsize(s)
----
-- 130
-...
+ | ---
+ | - 130
+ | ...
+
 errinj.set("ERRINJ_TUPLE_ALLOC", true)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
+
 s:replace{1, "test"}
----
-- error: Failed to allocate 21 bytes in slab allocator for memtx_tuple
-...
+ | ---
+ | - error: Failed to allocate 21 bytes in slab allocator for memtx_tuple
+ | ...
 s:bsize()
----
-- 130
-...
+ | ---
+ | - 130
+ | ...
 utils.space_bsize(s)
----
-- 130
-...
+ | ---
+ | - 130
+ | ...
+
 s:update({1}, {{'=', 3, '!'}})
----
-- error: Failed to allocate 20 bytes in slab allocator for memtx_tuple
-...
+ | ---
+ | - error: Failed to allocate 20 bytes in slab allocator for memtx_tuple
+ | ...
 s:bsize()
----
-- 130
-...
+ | ---
+ | - 130
+ | ...
 utils.space_bsize(s)
----
-- 130
-...
+ | ---
+ | - 130
+ | ...
+
 errinj.set("ERRINJ_TUPLE_ALLOC", false)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
+
 s:drop()
----
-...
+ | ---
+ | ...
+
 space = box.schema.space.create('test')
----
-...
+ | ---
+ | ...
 index1 = space:create_index('primary')
----
-...
+ | ---
+ | ...
 fiber = require'fiber'
----
-...
+ | ---
+ | ...
 ch = fiber.channel(1)
----
-...
+ | ---
+ | ...
+
 test_run:cmd('setopt delimiter ";"')
----
-- true
-...
+ | ---
+ | - true
+ | ...
 function test()
   errinj.set('ERRINJ_WAL_WRITE_DISK', true)
   pcall(box.space.test.replace, box.space.test, {1, 1})
   errinj.set('ERRINJ_WAL_WRITE_DISK', false)
   ch:put(true)
 end ;
----
-...
+ | ---
+ | ...
+
 function run()
   fiber.create(test)
   box.snapshot()
 end ;
----
-...
+ | ---
+ | ...
+
 test_run:cmd('setopt delimiter ""');
----
-- true
-...
+ | ---
+ | - true
+ | ...
+
 -- Port_dump can fail.
+
 box.schema.user.grant('guest', 'read', 'space', '_space')
----
-...
+ | ---
+ | ...
+
 cn = net_box.connect(box.cfg.listen)
----
-...
+ | ---
+ | ...
 cn:ping()
----
-- true
-...
+ | ---
+ | - true
+ | ...
 errinj.set('ERRINJ_PORT_DUMP', true)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 ok, ret = pcall(cn.space._space.select, cn.space._space)
----
-...
+ | ---
+ | ...
 assert(not ok)
----
-- true
-...
+ | ---
+ | - true
+ | ...
 assert(string.match(tostring(ret), 'Failed to allocate'))
----
-- Failed to allocate
-...
+ | ---
+ | - Failed to allocate
+ | ...
 errinj.set('ERRINJ_PORT_DUMP', false)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 cn:close()
----
-...
+ | ---
+ | ...
 box.schema.user.revoke('guest', 'read', 'space', '_space')
----
-...
+ | ---
+ | ...
+
 run()
----
-- error: Can't start a checkpoint while in cascading rollback
-...
+ | ---
+ | - error: Can't start a checkpoint while in cascading rollback
+ | ...
 ch:get()
----
-- true
-...
+ | ---
+ | - true
+ | ...
+
 box.space.test:select()
----
-- []
-...
+ | ---
+ | - []
+ | ...
 test_run:cmd('restart server default')
+ | 
 box.space.test:select()
----
-- []
-...
+ | ---
+ | - []
+ | ...
 box.space.test:drop()
----
-...
+ | ---
+ | ...
+
 errinj = box.error.injection
----
-...
+ | ---
+ | ...
 net_box = require('net.box')
----
-...
+ | ---
+ | ...
 fiber = require'fiber'
----
-...
+ | ---
+ | ...
+
 s = box.schema.space.create('test')
----
-...
+ | ---
+ | ...
 _ = s:create_index('pk')
----
-...
+ | ---
+ | ...
+
 ch = fiber.channel(2)
----
-...
+ | ---
+ | ...
+
 test_run:cmd("setopt delimiter ';'")
----
-- true
-...
+ | ---
+ | - true
+ | ...
 function test(tuple)
    ch:put({pcall(s.replace, s, tuple)})
 end;
----
-...
+ | ---
+ | ...
 test_run:cmd("setopt delimiter ''");
----
-- true
-...
+ | ---
+ | - true
+ | ...
+
 errinj.set("ERRINJ_WAL_WRITE", true)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 _ = {fiber.create(test, {1, 2, 3}), fiber.create(test, {3, 4, 5})}
----
-...
+ | ---
+ | ...
+
 {ch:get(), ch:get()}
----
-- - - false
-    - Failed to write to disk
-  - - false
-    - Failed to write to disk
-...
+ | ---
+ | - - - false
+ |     - Failed to write to disk
+ |   - - false
+ |     - Failed to write to disk
+ | ...
 errinj.set("ERRINJ_WAL_WRITE", false)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 s:drop()
----
-...
+ | ---
+ | ...
+
 -- rebuild some secondary indexes if the primary was changed
 s = box.schema.space.create('test')
----
-...
+ | ---
+ | ...
 i1 = s:create_index('i1', {parts = {1, 'unsigned'}})
----
-...
+ | ---
+ | ...
 --i2 = s:create_index('i2', {parts = {5, 'unsigned'}, unique = false})
 --i3 = s:create_index('i3', {parts = {6, 'unsigned'}, unique = false})
 i2 = i1 i3 = i1
----
-...
+ | ---
+ | ...
+
 _ = s:insert{1, 4, 3, 4, 10, 10}
----
-...
+ | ---
+ | ...
 _ = s:insert{2, 3, 1, 2, 10, 10}
----
-...
+ | ---
+ | ...
 _ = s:insert{3, 2, 2, 1, 10, 10}
----
-...
+ | ---
+ | ...
 _ = s:insert{4, 1, 4, 3, 10, 10}
----
-...
+ | ---
+ | ...
+
 i1:select{}
----
-- - [1, 4, 3, 4, 10, 10]
-  - [2, 3, 1, 2, 10, 10]
-  - [3, 2, 2, 1, 10, 10]
-  - [4, 1, 4, 3, 10, 10]
-...
+ | ---
+ | - - [1, 4, 3, 4, 10, 10]
+ |   - [2, 3, 1, 2, 10, 10]
+ |   - [3, 2, 2, 1, 10, 10]
+ |   - [4, 1, 4, 3, 10, 10]
+ | ...
 i2:select{}
----
-- - [1, 4, 3, 4, 10, 10]
-  - [2, 3, 1, 2, 10, 10]
-  - [3, 2, 2, 1, 10, 10]
-  - [4, 1, 4, 3, 10, 10]
-...
+ | ---
+ | - - [1, 4, 3, 4, 10, 10]
+ |   - [2, 3, 1, 2, 10, 10]
+ |   - [3, 2, 2, 1, 10, 10]
+ |   - [4, 1, 4, 3, 10, 10]
+ | ...
 i3:select{}
----
-- - [1, 4, 3, 4, 10, 10]
-  - [2, 3, 1, 2, 10, 10]
-  - [3, 2, 2, 1, 10, 10]
-  - [4, 1, 4, 3, 10, 10]
-...
+ | ---
+ | - - [1, 4, 3, 4, 10, 10]
+ |   - [2, 3, 1, 2, 10, 10]
+ |   - [3, 2, 2, 1, 10, 10]
+ |   - [4, 1, 4, 3, 10, 10]
+ | ...
+
 i1:alter({parts={2, 'unsigned'}})
----
-...
+ | ---
+ | ...
+
 _ = collectgarbage('collect')
----
-...
+ | ---
+ | ...
 i1:select{}
----
-- - [4, 1, 4, 3, 10, 10]
-  - [3, 2, 2, 1, 10, 10]
-  - [2, 3, 1, 2, 10, 10]
-  - [1, 4, 3, 4, 10, 10]
-...
+ | ---
+ | - - [4, 1, 4, 3, 10, 10]
+ |   - [3, 2, 2, 1, 10, 10]
+ |   - [2, 3, 1, 2, 10, 10]
+ |   - [1, 4, 3, 4, 10, 10]
+ | ...
 i2:select{}
----
-- - [4, 1, 4, 3, 10, 10]
-  - [3, 2, 2, 1, 10, 10]
-  - [2, 3, 1, 2, 10, 10]
-  - [1, 4, 3, 4, 10, 10]
-...
+ | ---
+ | - - [4, 1, 4, 3, 10, 10]
+ |   - [3, 2, 2, 1, 10, 10]
+ |   - [2, 3, 1, 2, 10, 10]
+ |   - [1, 4, 3, 4, 10, 10]
+ | ...
 i3:select{}
----
-- - [4, 1, 4, 3, 10, 10]
-  - [3, 2, 2, 1, 10, 10]
-  - [2, 3, 1, 2, 10, 10]
-  - [1, 4, 3, 4, 10, 10]
-...
+ | ---
+ | - - [4, 1, 4, 3, 10, 10]
+ |   - [3, 2, 2, 1, 10, 10]
+ |   - [2, 3, 1, 2, 10, 10]
+ |   - [1, 4, 3, 4, 10, 10]
+ | ...
+
 box.error.injection.set('ERRINJ_BUILD_INDEX', i2.id)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
+
 i1:alter{parts = {3, "unsigned"}}
----
-- error: Error injection 'build index'
-...
+ | ---
+ | - error: Error injection 'build index'
+ | ...
+
 _ = collectgarbage('collect')
----
-...
+ | ---
+ | ...
 i1:select{}
----
-- - [4, 1, 4, 3, 10, 10]
-  - [3, 2, 2, 1, 10, 10]
-  - [2, 3, 1, 2, 10, 10]
-  - [1, 4, 3, 4, 10, 10]
-...
+ | ---
+ | - - [4, 1, 4, 3, 10, 10]
+ |   - [3, 2, 2, 1, 10, 10]
+ |   - [2, 3, 1, 2, 10, 10]
+ |   - [1, 4, 3, 4, 10, 10]
+ | ...
 i2:select{}
----
-- - [4, 1, 4, 3, 10, 10]
-  - [3, 2, 2, 1, 10, 10]
-  - [2, 3, 1, 2, 10, 10]
-  - [1, 4, 3, 4, 10, 10]
-...
+ | ---
+ | - - [4, 1, 4, 3, 10, 10]
+ |   - [3, 2, 2, 1, 10, 10]
+ |   - [2, 3, 1, 2, 10, 10]
+ |   - [1, 4, 3, 4, 10, 10]
+ | ...
 i3:select{}
----
-- - [4, 1, 4, 3, 10, 10]
-  - [3, 2, 2, 1, 10, 10]
-  - [2, 3, 1, 2, 10, 10]
-  - [1, 4, 3, 4, 10, 10]
-...
+ | ---
+ | - - [4, 1, 4, 3, 10, 10]
+ |   - [3, 2, 2, 1, 10, 10]
+ |   - [2, 3, 1, 2, 10, 10]
+ |   - [1, 4, 3, 4, 10, 10]
+ | ...
+
 box.error.injection.set('ERRINJ_BUILD_INDEX', i3.id)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
+
 i1:alter{parts = {4, "unsigned"}}
----
-- error: Error injection 'build index'
-...
+ | ---
+ | - error: Error injection 'build index'
+ | ...
+
 _ = collectgarbage('collect')
----
-...
+ | ---
+ | ...
 i1:select{}
----
-- - [4, 1, 4, 3, 10, 10]
-  - [3, 2, 2, 1, 10, 10]
-  - [2, 3, 1, 2, 10, 10]
-  - [1, 4, 3, 4, 10, 10]
-...
+ | ---
+ | - - [4, 1, 4, 3, 10, 10]
+ |   - [3, 2, 2, 1, 10, 10]
+ |   - [2, 3, 1, 2, 10, 10]
+ |   - [1, 4, 3, 4, 10, 10]
+ | ...
 i2:select{}
----
-- - [4, 1, 4, 3, 10, 10]
-  - [3, 2, 2, 1, 10, 10]
-  - [2, 3, 1, 2, 10, 10]
-  - [1, 4, 3, 4, 10, 10]
-...
+ | ---
+ | - - [4, 1, 4, 3, 10, 10]
+ |   - [3, 2, 2, 1, 10, 10]
+ |   - [2, 3, 1, 2, 10, 10]
+ |   - [1, 4, 3, 4, 10, 10]
+ | ...
 i3:select{}
----
-- - [4, 1, 4, 3, 10, 10]
-  - [3, 2, 2, 1, 10, 10]
-  - [2, 3, 1, 2, 10, 10]
-  - [1, 4, 3, 4, 10, 10]
-...
+ | ---
+ | - - [4, 1, 4, 3, 10, 10]
+ |   - [3, 2, 2, 1, 10, 10]
+ |   - [2, 3, 1, 2, 10, 10]
+ |   - [1, 4, 3, 4, 10, 10]
+ | ...
+
 box.error.injection.set('ERRINJ_BUILD_INDEX', -1)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
+
 s:drop()
----
-...
+ | ---
+ | ...
+
 --
 -- Do not rebuild index if the only change is a key part type
 -- compatible change.
 --
 s = box.schema.space.create('test')
----
-...
+ | ---
+ | ...
 pk = s:create_index('pk')
----
-...
+ | ---
+ | ...
 sk = s:create_index('sk', {parts = {2, 'unsigned'}})
----
-...
+ | ---
+ | ...
 s:replace{1, 1}
----
-- [1, 1]
-...
+ | ---
+ | - [1, 1]
+ | ...
 box.error.injection.set('ERRINJ_BUILD_INDEX', sk.id)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 sk:alter({parts = {2, 'number'}})
----
-...
+ | ---
+ | ...
 box.error.injection.set('ERRINJ_BUILD_INDEX', -1)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 s:drop()
----
-...
+ | ---
+ | ...
+
 --
 -- gh-3255: iproto can crash and discard responses, if a network
 -- is saturated, and DML yields too long on commit.
 --
+
 s = box.schema.space.create('test')
----
-...
+ | ---
+ | ...
 _ = s:create_index('pk')
----
-...
+ | ---
+ | ...
 box.schema.user.grant('guest', 'read,write,alter', 'space', 'test')
----
-...
+ | ---
+ | ...
 c = net_box.connect(box.cfg.listen)
----
-...
+ | ---
+ | ...
+
 ch = fiber.channel(200)
----
-...
+ | ---
+ | ...
 errinj.set("ERRINJ_IPROTO_TX_DELAY", true)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 for i = 1, 100 do fiber.create(function() for j = 1, 10 do c.space.test:replace{1} end ch:put(true) end) end
----
-...
+ | ---
+ | ...
 for i = 1, 100 do fiber.create(function() for j = 1, 10 do c.space.test:select() end ch:put(true) end) end
----
-...
+ | ---
+ | ...
 for i = 1, 200 do ch:get() end
----
-...
+ | ---
+ | ...
 errinj.set("ERRINJ_IPROTO_TX_DELAY", false)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
+
 s:drop()
----
-...
+ | ---
+ | ...
+
 --
 -- gh-3325: do not cancel already sent requests, when a schema
 -- change is detected.
 --
+
 box.schema.user.grant('guest', 'execute', 'universe')
----
-...
+ | ---
+ | ...
+
 s = box.schema.create_space('test')
----
-...
+ | ---
+ | ...
 pk = s:create_index('pk')
----
-...
+ | ---
+ | ...
+
 box.schema.user.grant('guest', 'read,write,alter', 'space', 'test')
----
-...
+ | ---
+ | ...
 box.schema.user.grant('guest', 'create', 'space')
----
-...
+ | ---
+ | ...
 box.schema.user.grant('guest', 'write', 'space', '_index')
----
-...
+ | ---
+ | ...
 s:replace{1, 1}
----
-- [1, 1]
-...
+ | ---
+ | - [1, 1]
+ | ...
 cn = net_box.connect(box.cfg.listen)
----
-...
+ | ---
+ | ...
 errinj.set("ERRINJ_WAL_DELAY", true)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 ok = nil
----
-...
+ | ---
+ | ...
 err = nil
----
-...
+ | ---
+ | ...
 test_run:cmd('setopt delimiter ";"')
----
-- true
-...
+ | ---
+ | - true
+ | ...
 f = fiber.create(function()
   local str = 'box.space.test:create_index("sk", {parts = {{2, "integer"}}})'
   ok, err = pcall(cn.eval, cn, str)
 end)
 test_run:cmd('setopt delimiter ""');
----
-...
+ | ---
+ | ...
 cn.space.test:get{1}
----
-- [1, 1]
-...
+ | ---
+ | - [1, 1]
+ | ...
 errinj.set("ERRINJ_WAL_DELAY", false)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 while ok == nil do fiber.sleep(0.01) end
----
-...
+ | ---
+ | ...
 ok, err
----
-- true
-- null
-...
+ | ---
+ | - true
+ | - null
+ | ...
 cn:close()
----
-...
+ | ---
+ | ...
 s:drop()
----
-...
+ | ---
+ | ...
 box.schema.user.revoke('guest', 'execute', 'universe')
----
-...
+ | ---
+ | ...
 box.schema.user.revoke('guest', 'create', 'space')
----
-...
+ | ---
+ | ...
 box.schema.user.revoke('guest', 'write', 'space', '_index')
----
-...
+ | ---
+ | ...
 --
 -- If message memory pool is used up, stop the connection, until
 -- the pool has free memory.
 --
 started = 0
----
-...
+ | ---
+ | ...
 finished = 0
----
-...
+ | ---
+ | ...
 continue = false
----
-...
+ | ---
+ | ...
 test_run:cmd('setopt delimiter ";"')
----
-- true
-...
+ | ---
+ | - true
+ | ...
 function long_poll_f()
     started = started + 1
     f = fiber.self()
     while not continue do fiber.sleep(0.01) end
     finished = finished + 1
 end;
----
-...
+ | ---
+ | ...
+
 box.schema.func.create('long_poll_f');
----
-...
+ | ---
+ | ...
 box.schema.user.grant('guest', 'execute', 'function', 'long_poll_f');
----
-...
+ | ---
+ | ...
+
 test_run:cmd('setopt delimiter ""');
----
-- true
-...
+ | ---
+ | - true
+ | ...
 cn = net_box.connect(box.cfg.listen)
----
-...
+ | ---
+ | ...
 function long_poll() cn:call('long_poll_f') end
----
-...
+ | ---
+ | ...
 _ = fiber.create(long_poll)
----
-...
+ | ---
+ | ...
 while started ~= 1 do fiber.sleep(0.01) end
----
-...
+ | ---
+ | ...
 -- Simulate OOM for new requests.
 errinj.set("ERRINJ_TESTING", true)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 -- This request tries to allocate memory for request data and
 -- fails. This stops the connection until an existing
 -- request is finished.
 log = require('log')
----
-...
+ | ---
+ | ...
 -- Fill the log with garbage to not accidentally read log messages
 -- produced by a previous test.
 log.info(string.rep('a', 1000))
----
-...
+ | ---
+ | ...
 _ = fiber.create(long_poll)
----
-...
+ | ---
+ | ...
 while not test_run:grep_log('default', 'can not allocate memory for a new message', 1000) do fiber.sleep(0.01) end
----
-...
+ | ---
+ | ...
 test_run:grep_log('default', 'stopping input on connection', 1000) ~= nil
----
-- true
-...
+ | ---
+ | - true
+ | ...
 started == 1
----
-- true
-...
+ | ---
+ | - true
+ | ...
 continue = true
----
-...
+ | ---
+ | ...
 errinj.set("ERRINJ_TESTING", false)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 -- Ensure that when memory is available again, the pending
 -- request is executed.
 while finished ~= 2 do fiber.sleep(0.01) end
----
-...
+ | ---
+ | ...
 cn:close()
----
-...
+ | ---
+ | ...
+
 box.schema.user.revoke('guest', 'execute', 'function', 'long_poll_f')
----
-...
+ | ---
+ | ...
 box.schema.func.drop('long_poll_f')
----
-...
+ | ---
+ | ...
 --
 -- gh-3289: drop/truncate leaves the space in inconsistent
 -- state if WAL write fails.
 --
 s = box.schema.space.create('test')
----
-...
+ | ---
+ | ...
 _ = s:create_index('pk')
----
-...
+ | ---
+ | ...
 for i = 1, 10 do s:replace{i} end
----
-...
+ | ---
+ | ...
 errinj.set('ERRINJ_WAL_IO', true)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 s:drop()
----
-- error: Failed to write to disk
-...
+ | ---
+ | - error: Failed to write to disk
+ | ...
 s:truncate()
----
-- error: Failed to write to disk
-...
+ | ---
+ | - error: Failed to write to disk
+ | ...
 s:drop()
----
-- error: Failed to write to disk
-...
+ | ---
+ | - error: Failed to write to disk
+ | ...
 s:truncate()
----
-- error: Failed to write to disk
-...
+ | ---
+ | - error: Failed to write to disk
+ | ...
 errinj.set('ERRINJ_WAL_IO', false)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 for i = 1, 10 do s:replace{i + 10} end
----
-...
+ | ---
+ | ...
 s:select()
----
-- - [1]
-  - [2]
-  - [3]
-  - [4]
-  - [5]
-  - [6]
-  - [7]
-  - [8]
-  - [9]
-  - [10]
-  - [11]
-  - [12]
-  - [13]
-  - [14]
-  - [15]
-  - [16]
-  - [17]
-  - [18]
-  - [19]
-  - [20]
-...
+ | ---
+ | - - [1]
+ |   - [2]
+ |   - [3]
+ |   - [4]
+ |   - [5]
+ |   - [6]
+ |   - [7]
+ |   - [8]
+ |   - [9]
+ |   - [10]
+ |   - [11]
+ |   - [12]
+ |   - [13]
+ |   - [14]
+ |   - [15]
+ |   - [16]
+ |   - [17]
+ |   - [18]
+ |   - [19]
+ |   - [20]
+ | ...
 s:drop()
----
-...
+ | ---
+ | ...
+
 --
 -- gh-3432: check that deletion of temporary tuples is not delayed
 -- if snapshot is in progress.
 --
 test_run:cmd("create server test with script='box/lua/cfg_memory.lua'")
----
-- true
-...
+ | ---
+ | - true
+ | ...
 test_run:cmd(string.format("start server test with args='%d'", 100 * 1024 * 1024))
----
-- true
-...
+ | ---
+ | - true
+ | ...
 test_run:cmd("switch test")
----
-- true
-...
+ | ---
+ | - true
+ | ...
+
 fiber = require('fiber')
----
-...
+ | ---
+ | ...
+
 -- Create a persistent space.
 _ = box.schema.space.create('test')
----
-...
+ | ---
+ | ...
 _ = box.space.test:create_index('pk')
----
-...
+ | ---
+ | ...
 for i = 1, 100 do box.space.test:insert{i} end
----
-...
+ | ---
+ | ...
+
 -- Create a temporary space.
 count = 500
----
-...
+ | ---
+ | ...
 pad = string.rep('x', 100 * 1024)
----
-...
+ | ---
+ | ...
 _ = box.schema.space.create('tmp', {temporary = true})
----
-...
+ | ---
+ | ...
 _ = box.space.tmp:create_index('pk')
----
-...
+ | ---
+ | ...
 for i = 1, count do box.space.tmp:insert{i, pad} end
----
-...
+ | ---
+ | ...
+
 -- Start background snapshot.
 c = fiber.channel(1)
----
-...
+ | ---
+ | ...
 box.error.injection.set('ERRINJ_SNAP_WRITE_DELAY', true)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 _ = fiber.create(function() box.snapshot() c:put(true) end)
----
-...
+ | ---
+ | ...
+
 -- Overwrite data stored in the temporary space while snapshot
 -- is in progress to make sure that tuples stored in it are freed
 -- immediately.
 for i = 1, count do box.space.tmp:delete{i} end
----
-...
+ | ---
+ | ...
 _ = collectgarbage('collect')
----
-...
+ | ---
+ | ...
 for i = 1, count do box.space.tmp:insert{i, pad} end
----
-...
+ | ---
+ | ...
+
 box.error.injection.set('ERRINJ_SNAP_WRITE_DELAY', false)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 c:get()
----
-- true
-...
+ | ---
+ | - true
+ | ...
+
 box.space.tmp:drop()
----
-...
+ | ---
+ | ...
 box.space.test:drop()
----
-...
+ | ---
+ | ...
+
 test_run:cmd("switch default")
----
-- true
-...
+ | ---
+ | - true
+ | ...
 test_run:cmd("stop server test")
----
-- true
-...
+ | ---
+ | - true
+ | ...
 test_run:cmd("cleanup server test")
----
-- true
-...
+ | ---
+ | - true
+ | ...
+
 --
 -- gh-3406: check that incomplete files got cleaned up after restart.
 --
 fio = require('fio')
----
-...
+ | ---
+ | ...
 fiber = require('fiber')
----
-...
+ | ---
+ | ...
+
 -- Check that snap.inprogress files are removed.
 _ = box.schema.space.create('test')
----
-...
+ | ---
+ | ...
 _ = box.space.test:create_index('primary')
----
-...
+ | ---
+ | ...
 for i = 1, 10 do box.space.test:insert{i} end
----
-...
+ | ---
+ | ...
+
 errinj.set('ERRINJ_SNAP_WRITE_DELAY', true)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 _ = fiber.create(function() box.snapshot() end)
----
-...
+ | ---
+ | ...
 path = fio.pathjoin(box.cfg.memtx_dir, '*.snap.inprogress')
----
-...
+ | ---
+ | ...
 while #fio.glob(path) == 0 do fiber.sleep(0.001) end
----
-...
+ | ---
+ | ...
 #fio.glob(path) > 0
----
-- true
-...
+ | ---
+ | - true
+ | ...
+
 test_run:cmd('restart server default')
+ | 
+
 fio = require('fio')
----
-...
+ | ---
+ | ...
 fiber = require('fiber')
----
-...
+ | ---
+ | ...
 errinj = box.error.injection
----
-...
+ | ---
+ | ...
+
 #fio.glob(fio.pathjoin(box.cfg.memtx_dir, "*.snap.inprogress")) == 0
----
-- true
-...
+ | ---
+ | - true
+ | ...
 box.space.test:drop()
----
-...
+ | ---
+ | ...
+
 -- Check that run.inprogress, index.inprogress, and vylog.inprogress
 -- files are removed.
 _ = box.schema.space.create('test', {engine = 'vinyl'})
----
-...
+ | ---
+ | ...
 _ = box.space.test:create_index('primary')
----
-...
+ | ---
+ | ...
+
 errinj.set('ERRINJ_VY_LOG_FILE_RENAME', true)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 box.snapshot()
----
-- error: Error injection 'vinyl log file rename'
-...
+ | ---
+ | - error: Error injection 'vinyl log file rename'
+ | ...
 errinj.set('ERRINJ_VY_LOG_FILE_RENAME', false)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
+
 errinj.set('ERRINJ_VY_GC', true)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 errinj.set('ERRINJ_VY_SCHED_TIMEOUT', 0.001)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
+
 errinj.set('ERRINJ_VY_RUN_FILE_RENAME', true)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 box.space.test:insert{1}
----
-- [1]
-...
+ | ---
+ | - [1]
+ | ...
 box.snapshot() -- error
----
-- error: Error injection 'vinyl run file rename'
-...
+ | ---
+ | - error: Error injection 'vinyl run file rename'
+ | ...
 errinj.set('ERRINJ_VY_RUN_FILE_RENAME', false)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
+
 -- Wait for the scheduler to unthrottle.
 repeat fiber.sleep(0.001) until pcall(box.snapshot)
----
-...
+ | ---
+ | ...
+
 errinj.set('ERRINJ_VY_INDEX_FILE_RENAME', true)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 box.space.test:insert{2}
----
-- [2]
-...
+ | ---
+ | - [2]
+ | ...
 box.snapshot() -- error
----
-- error: Error injection 'vinyl index file rename'
-...
+ | ---
+ | - error: Error injection 'vinyl index file rename'
+ | ...
 errinj.set('ERRINJ_VY_INDEX_FILE_RENAME', false)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
+
 errinj.set('ERRINJ_VY_SCHED_TIMEOUT', 0)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 errinj.set('ERRINJ_VY_GC', false)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
+
 test_run:cmd('restart server default')
+ | 
+
 fio = require('fio')
----
-...
+ | ---
+ | ...
 #fio.glob(fio.pathjoin(box.cfg.vinyl_dir, '*.vylog.inprogress')) == 0
----
-- true
-...
+ | ---
+ | - true
+ | ...
 #fio.glob(fio.pathjoin(box.cfg.vinyl_dir, box.space.test.id, 0, '*.run.inprogress')) == 0
----
-- true
-...
+ | ---
+ | - true
+ | ...
 #fio.glob(fio.pathjoin(box.cfg.vinyl_dir, box.space.test.id, 0, '*.index.inprogress')) == 0
----
-- true
-...
+ | ---
+ | - true
+ | ...
+
 box.space.test:drop()
----
-...
+ | ---
+ | ...
+
 -- gh-4276 - check grant privilege rollback
 _ = box.schema.user.create('testg')
----
-...
+ | ---
+ | ...
 _ = box.schema.space.create('testg'):create_index('pk')
----
-...
+ | ---
+ | ...
+
 box.error.injection.set('ERRINJ_WAL_IO', true)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 -- the grant operation above fails and test hasn't any space test permissions
 box.schema.user.grant('testg', 'read,write', 'space', 'testg')
----
-- error: Failed to write to disk
-...
+ | ---
+ | - error: Failed to write to disk
+ | ...
 -- switch user and check they couldn't select
 box.session.su('testg')
----
-...
+ | ---
+ | ...
 box.space.testg:select()
----
-- error: Read access to space 'testg' is denied for user 'testg'
-...
+ | ---
+ | - error: Read access to space 'testg' is denied for user 'testg'
+ | ...
 box.session.su('admin')
----
-...
+ | ---
+ | ...
 box.error.injection.set('ERRINJ_WAL_IO', false)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 box.schema.user.drop('testg')
----
-...
+ | ---
+ | ...
 box.space.testg:drop()
----
-...
+ | ---
+ | ...
+
 --
 -- Errinj:get().
 --
 box.error.injection.get('bad name')
----
-- 'error: can''t find error injection ''bad name'''
-...
+ | ---
+ | - 'error: can''t find error injection ''bad name'''
+ | ...
 box.error.injection.set('ERRINJ_WAL_IO', true)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 box.error.injection.get('ERRINJ_WAL_IO')
----
-- true
-...
+ | ---
+ | - true
+ | ...
 box.error.injection.set('ERRINJ_WAL_IO', false)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 box.error.injection.get('ERRINJ_WAL_IO')
----
-- false
-...
+ | ---
+ | - false
+ | ...
 box.error.injection.set('ERRINJ_TUPLE_FORMAT_COUNT', 20)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 box.error.injection.get('ERRINJ_TUPLE_FORMAT_COUNT')
----
-- 20
-...
+ | ---
+ | - 20
+ | ...
 box.error.injection.set('ERRINJ_TUPLE_FORMAT_COUNT', -1)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 box.error.injection.get('ERRINJ_TUPLE_FORMAT_COUNT')
----
-- -1
-...
+ | ---
+ | - -1
+ | ...
 box.error.injection.set('ERRINJ_RELAY_TIMEOUT', 0.5)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 box.error.injection.get('ERRINJ_RELAY_TIMEOUT')
----
-- 0.5
-...
+ | ---
+ | - 0.5
+ | ...
 box.error.injection.set('ERRINJ_RELAY_TIMEOUT', 0)
----
-- ok
-...
+ | ---
+ | - ok
+ | ...
 box.error.injection.get('ERRINJ_RELAY_TIMEOUT')
----
-- 0
-...
+ | ---
+ | - 0
+ | ...
-- 
2.20.1



More information about the Tarantool-patches mailing list