Skip to content
Snippets Groups Projects
Commit a49f6711 authored by Alexandr Lyapunov's avatar Alexandr Lyapunov Committed by Konstantin Osipov
Browse files

vinyl: add err injection tests for vy_prepare

parent a0d27684
No related branches found
No related tags found
No related merge requests found
......@@ -237,6 +237,7 @@ txn_commit(struct txn *txn)
if (txn->n_rows > 0)
signature = txn_write_to_wal(txn);
ERROR_INJECT(ERRINJ_WAL_SHORT_DELAY, fiber_sleep(0.01););
/*
* The transaction is in the binary log. No action below
* may throw. In case an error has happened, there is
......
......@@ -934,6 +934,16 @@ xlog_tx_write_plain(struct xlog *log)
diag_set(ClientError, ER_INJECTION, "xlog write injection");
return -1;
});
ERROR_INJECT_U64(ERRINJ_WAL_WRITE_COUNTDOWN,
errinj_getu64(ERRINJ_WAL_WRITE_COUNTDOWN) != UINT64_MAX,
{
uint64_t countdown = errinj_getu64(ERRINJ_WAL_WRITE_COUNTDOWN);
if (countdown == 0) {
diag_set(ClientError, ER_INJECTION, "xlog write injection");
return -1;
}
errinj_setu64(ERRINJ_WAL_WRITE_COUNTDOWN, countdown - 1);
});
ssize_t written = fio_writevn(log->fd, log->obuf.iov, log->obuf.pos + 1);
if (written < 0) {
......@@ -1023,6 +1033,16 @@ xlog_tx_write_zstd(struct xlog *log)
obuf_reset(&log->zbuf);
goto error;
});
ERROR_INJECT_U64(ERRINJ_WAL_WRITE_COUNTDOWN,
errinj_getu64(ERRINJ_WAL_WRITE_COUNTDOWN) != UINT64_MAX,
{
uint64_t countdown = errinj_getu64(ERRINJ_WAL_WRITE_COUNTDOWN);
if (countdown == 0) {
diag_set(ClientError, ER_INJECTION, "xlog write injection");
return -1;
}
errinj_setu64(ERRINJ_WAL_WRITE_COUNTDOWN, countdown - 1);
});
ssize_t written;
written = fio_writevn(log->fd, log->zbuf.iov,
......
......@@ -60,7 +60,9 @@ struct errinj {
_(ERRINJ_WAL_WRITE, ERRINJ_BOOL, {.bparam = false}) \
_(ERRINJ_WAL_WRITE_PARTIAL, ERRINJ_U64, {.u64param = UINT64_MAX}) \
_(ERRINJ_WAL_WRITE_DISK, ERRINJ_BOOL, {.bparam = false}) \
_(ERRINJ_WAL_WRITE_COUNTDOWN, ERRINJ_U64, {.u64param = UINT64_MAX}) \
_(ERRINJ_WAL_DELAY, ERRINJ_BOOL, {.bparam = false}) \
_(ERRINJ_WAL_SHORT_DELAY, ERRINJ_BOOL, {.bparam = false}) \
_(ERRINJ_INDEX_ALLOC, ERRINJ_BOOL, {.bparam = false}) \
_(ERRINJ_TUPLE_ALLOC, ERRINJ_BOOL, {.bparam = false}) \
_(ERRINJ_TUPLE_FIELD, ERRINJ_BOOL, {.bparam = false}) \
......
......@@ -16,11 +16,13 @@ errinj.info()
state: false
ERRINJ_WAL_WRITE:
state: false
ERRINJ_WAL_SHORT_DELAY:
state: false
ERRINJ_VY_READ_PAGE_TIMEOUT:
state: false
ERRINJ_WAL_WRITE_DISK:
state: false
ERRINJ_WAL_WRITE_PARTIAL:
ERRINJ_WAL_WRITE_COUNTDOWN:
state: 18446744073709551615
ERRINJ_VY_GC:
state: false
......@@ -40,14 +42,16 @@ errinj.info()
state: false
ERRINJ_VINYL_SCHED_TIMEOUT:
state: 0
ERRINJ_WAL_IO:
state: false
ERRINJ_RELAY:
state: false
ERRINJ_TESTING:
ERRINJ_WAL_IO:
state: false
ERRINJ_VY_SQUASH_TIMEOUT:
state: 0
ERRINJ_TESTING:
state: false
ERRINJ_WAL_WRITE_PARTIAL:
state: 18446744073709551615
ERRINJ_TUPLE_FIELD:
state: false
ERRINJ_TUPLE_ALLOC:
......
......@@ -384,3 +384,303 @@ errinj.set("ERRINJ_VY_SQUASH_TIMEOUT", 0)
---
- ok
...
--https://github.com/tarantool/tarantool/issues/1842
--test error injection
s = box.schema.space.create('test', {engine='vinyl'})
---
...
_ = s:create_index('pk')
---
...
s:replace{0, 0}
---
- [0, 0]
...
errinj.set("ERRINJ_WAL_WRITE_COUNTDOWN", 2)
---
- ok
...
s:replace{1, 0}
---
- [1, 0]
...
s:replace{2, 0}
---
- [2, 0]
...
s:replace{3, 0}
---
- error: Failed to write to disk
...
s:replace{4, 0}
---
- error: Failed to write to disk
...
s:replace{5, 0}
---
- error: Failed to write to disk
...
s:replace{6, 0}
---
- error: Failed to write to disk
...
errinj.set("ERRINJ_WAL_WRITE_COUNTDOWN", 0xFFFFFFFFFFFFFFFF)
---
- ok
...
s:replace{7, 0}
---
- [7, 0]
...
s:replace{8, 0}
---
- [8, 0]
...
s:select{}
---
- - [0, 0]
- [1, 0]
- [2, 0]
- [7, 0]
- [8, 0]
...
s:drop()
---
...
--iterator test
test_run:cmd("setopt delimiter ';'")
---
- true
...
function create_iterator(obj, key, opts)
local iter, key, state = obj:pairs(key, opts)
local res = {}
res['iter'] = iter
res['key'] = key
res['state'] = state
return res
end;
---
...
function iterator_next(iter_obj)
local st, tp = iter_obj.iter.gen(iter_obj.key, iter_obj.state)
return tp
end;
---
...
function iterate_over(iter_obj)
local tp = nil
local ret = {}
local i = 0
tp = iterator_next(iter_obj)
while tp do
ret[i] = tp
i = i + 1
tp = iterator_next(iter_obj)
end
return ret
end;
---
...
fiber_status = 0
function fiber_func()
box.begin()
s:replace{5, 5}
fiber_status = 1
local res = {pcall(box.commit) }
fiber_status = 2
return unpack(res)
end;
---
...
test_run:cmd("setopt delimiter ''");
---
- true
...
s = box.schema.space.create('test', {engine='vinyl'})
---
...
_ = s:create_index('pk')
---
...
fiber = require('fiber')
---
...
_ = s:replace{0, 0}
---
...
_ = s:replace{10, 0}
---
...
_ = s:replace{20, 0}
---
...
test_run:cmd("setopt delimiter ';'");
---
- true
...
faced_trash = false
for i = 1,100 do
errinj.set("ERRINJ_WAL_WRITE_COUNTDOWN", 0)
local f = fiber.create(fiber_func)
local itr = create_iterator(s, {0}, {iterator='GE'})
local first = iterator_next(itr)
local second = iterator_next(itr)
if (second[1] ~= 5 and second[1] ~= 10) then faced_trash = true end
while fiber_status <= 1 do fiber.sleep(0.001) end
local _,next = pcall(iterator_next, itr)
_,next = pcall(iterator_next, itr)
_,next = pcall(iterator_next, itr)
errinj.set("ERRINJ_WAL_WRITE_COUNTDOWN", 0xFFFFFFFFFFFFFFFF)
s:delete{5}
end;
---
...
test_run:cmd("setopt delimiter ''");
---
- true
...
faced_trash
---
- false
...
s:drop()
---
...
-- TX in prepared but not committed state
s = box.schema.space.create('test', {engine='vinyl'})
---
...
_ = s:create_index('pk')
---
...
fiber = require('fiber')
---
...
txn_proxy = require('txn_proxy')
---
...
s:replace{1, "original"}
---
- [1, 'original']
...
s:replace{2, "original"}
---
- [2, 'original']
...
s:replace{3, "original"}
---
- [3, 'original']
...
c0 = txn_proxy.new()
---
...
c0:begin()
---
-
...
c1 = txn_proxy.new()
---
...
c1:begin()
---
-
...
c2 = txn_proxy.new()
---
...
c2:begin()
---
-
...
c3 = txn_proxy.new()
---
...
c3:begin()
---
-
...
errinj.set("ERRINJ_WAL_SHORT_DELAY", true)
---
- ok
...
c0('s:replace{1, "c0"}')
---
- - [1, 'c0']
...
c0('s:replace{2, "c0"}')
---
- - [2, 'c0']
...
c0('s:replace{3, "c0"}')
---
- - [3, 'c0']
...
_ = fiber.create(c0.commit, c0)
---
...
c1('s:replace{1, "c1"}')
---
- - [1, 'c1']
...
c1('s:replace{2, "c1"}')
---
- - [2, 'c1']
...
_ = fiber.create(c1.commit, c1)
---
...
c3('s:select{1}') -- c1 is visible
---
- - [[1, 'c1']]
...
c2('s:replace{1, "c2"}')
---
- - [1, 'c2']
...
c2('s:replace{3, "c2"}')
---
- - [3, 'c2']
...
_ = fiber.create(c2.commit, c2)
---
...
c3('s:select{1}') -- c1 is visible, c2 is not
---
- - [[1, 'c1']]
...
c3('s:select{2}') -- c1 is visible
---
- - [[2, 'c1']]
...
c3('s:select{3}') -- c2 is not visible
---
- - [[3, 'c0']]
...
fiber.sleep(0.1)
---
...
c3('s:select{1}') -- c1 is visible, c2 is not
---
- - [[1, 'c1']]
...
c3('s:select{2}') -- c1 is visible
---
- - [[2, 'c1']]
...
c3('s:select{3}') -- c2 is not visible
---
- - [[3, 'c0']]
...
c3:commit()
---
-
...
errinj.set("ERRINJ_WAL_SHORT_DELAY", false)
---
- ok
...
s:drop()
---
...
......@@ -130,3 +130,143 @@ for i=1,256 do s:upsert({0, 0}, {{'+', 2, 1}}) end
s:drop() -- index is gone
fiber.sleep(0.05)
errinj.set("ERRINJ_VY_SQUASH_TIMEOUT", 0)
--https://github.com/tarantool/tarantool/issues/1842
--test error injection
s = box.schema.space.create('test', {engine='vinyl'})
_ = s:create_index('pk')
s:replace{0, 0}
errinj.set("ERRINJ_WAL_WRITE_COUNTDOWN", 2)
s:replace{1, 0}
s:replace{2, 0}
s:replace{3, 0}
s:replace{4, 0}
s:replace{5, 0}
s:replace{6, 0}
errinj.set("ERRINJ_WAL_WRITE_COUNTDOWN", 0xFFFFFFFFFFFFFFFF)
s:replace{7, 0}
s:replace{8, 0}
s:select{}
s:drop()
--iterator test
test_run:cmd("setopt delimiter ';'")
function create_iterator(obj, key, opts)
local iter, key, state = obj:pairs(key, opts)
local res = {}
res['iter'] = iter
res['key'] = key
res['state'] = state
return res
end;
function iterator_next(iter_obj)
local st, tp = iter_obj.iter.gen(iter_obj.key, iter_obj.state)
return tp
end;
function iterate_over(iter_obj)
local tp = nil
local ret = {}
local i = 0
tp = iterator_next(iter_obj)
while tp do
ret[i] = tp
i = i + 1
tp = iterator_next(iter_obj)
end
return ret
end;
fiber_status = 0
function fiber_func()
box.begin()
s:replace{5, 5}
fiber_status = 1
local res = {pcall(box.commit) }
fiber_status = 2
return unpack(res)
end;
test_run:cmd("setopt delimiter ''");
s = box.schema.space.create('test', {engine='vinyl'})
_ = s:create_index('pk')
fiber = require('fiber')
_ = s:replace{0, 0}
_ = s:replace{10, 0}
_ = s:replace{20, 0}
test_run:cmd("setopt delimiter ';'");
faced_trash = false
for i = 1,100 do
errinj.set("ERRINJ_WAL_WRITE_COUNTDOWN", 0)
local f = fiber.create(fiber_func)
local itr = create_iterator(s, {0}, {iterator='GE'})
local first = iterator_next(itr)
local second = iterator_next(itr)
if (second[1] ~= 5 and second[1] ~= 10) then faced_trash = true end
while fiber_status <= 1 do fiber.sleep(0.001) end
local _,next = pcall(iterator_next, itr)
_,next = pcall(iterator_next, itr)
_,next = pcall(iterator_next, itr)
errinj.set("ERRINJ_WAL_WRITE_COUNTDOWN", 0xFFFFFFFFFFFFFFFF)
s:delete{5}
end;
test_run:cmd("setopt delimiter ''");
faced_trash
s:drop()
-- TX in prepared but not committed state
s = box.schema.space.create('test', {engine='vinyl'})
_ = s:create_index('pk')
fiber = require('fiber')
txn_proxy = require('txn_proxy')
s:replace{1, "original"}
s:replace{2, "original"}
s:replace{3, "original"}
c0 = txn_proxy.new()
c0:begin()
c1 = txn_proxy.new()
c1:begin()
c2 = txn_proxy.new()
c2:begin()
c3 = txn_proxy.new()
c3:begin()
errinj.set("ERRINJ_WAL_SHORT_DELAY", true)
c0('s:replace{1, "c0"}')
c0('s:replace{2, "c0"}')
c0('s:replace{3, "c0"}')
_ = fiber.create(c0.commit, c0)
c1('s:replace{1, "c1"}')
c1('s:replace{2, "c1"}')
_ = fiber.create(c1.commit, c1)
c3('s:select{1}') -- c1 is visible
c2('s:replace{1, "c2"}')
c2('s:replace{3, "c2"}')
_ = fiber.create(c2.commit, c2)
c3('s:select{1}') -- c1 is visible, c2 is not
c3('s:select{2}') -- c1 is visible
c3('s:select{3}') -- c2 is not visible
fiber.sleep(0.1)
c3('s:select{1}') -- c1 is visible, c2 is not
c3('s:select{2}') -- c1 is visible
c3('s:select{3}') -- c2 is not visible
c3:commit()
errinj.set("ERRINJ_WAL_SHORT_DELAY", false)
s:drop()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment