[Tarantool-patches] [PATCH v4 12/12] txm: add a test
Aleksandr Lyapunov
alyapunov at tarantool.org
Tue Sep 8 13:22:12 MSK 2020
Part of #4897
---
test/box/suite.ini | 2 +-
test/box/tx_man.lua | 10 ++
test/box/tx_man.result | 406 +++++++++++++++++++++++++++++++++++++++++++++++
test/box/tx_man.test.lua | 122 ++++++++++++++
4 files changed, 539 insertions(+), 1 deletion(-)
create mode 100644 test/box/tx_man.lua
create mode 100644 test/box/tx_man.result
create mode 100644 test/box/tx_man.test.lua
diff --git a/test/box/suite.ini b/test/box/suite.ini
index a9ed671..952a726 100644
--- a/test/box/suite.ini
+++ b/test/box/suite.ini
@@ -6,7 +6,7 @@ disabled = rtree_errinj.test.lua tuple_bench.test.lua
long_run = huge_field_map_long.test.lua
config = engine.cfg
release_disabled = errinj.test.lua errinj_index.test.lua rtree_errinj.test.lua upsert_errinj.test.lua iproto_stress.test.lua gh-4648-func-load-unload.test.lua
-lua_libs = lua/fifo.lua lua/utils.lua lua/bitset.lua lua/index_random_test.lua lua/push.lua lua/identifier.lua
+lua_libs = lua/fifo.lua lua/utils.lua lua/bitset.lua lua/index_random_test.lua lua/push.lua lua/identifier.lua lua/txn_proxy.lua
use_unix_sockets = True
use_unix_sockets_iproto = True
is_parallel = True
diff --git a/test/box/tx_man.lua b/test/box/tx_man.lua
new file mode 100644
index 0000000..addcd11
--- /dev/null
+++ b/test/box/tx_man.lua
@@ -0,0 +1,10 @@
+#!/usr/bin/env tarantool
+
+box.cfg{
+ listen = os.getenv("LISTEN"),
+ memtx_memory = 107374182,
+ pid_file = "tarantool.pid",
+ memtx_use_mvcc_engine = true,
+}
+
+require('console').listen(os.getenv('ADMIN'))
diff --git a/test/box/tx_man.result b/test/box/tx_man.result
new file mode 100644
index 0000000..bd74ecf
--- /dev/null
+++ b/test/box/tx_man.result
@@ -0,0 +1,406 @@
+-- test-run result file version 2
+env = require('test_run')
+ | ---
+ | ...
+test_run = env.new()
+ | ---
+ | ...
+test_run:cmd("create server tx_man with script='box/tx_man.lua'")
+ | ---
+ | - true
+ | ...
+test_run:cmd("start server tx_man")
+ | ---
+ | - true
+ | ...
+test_run:cmd("switch tx_man")
+ | ---
+ | - true
+ | ...
+
+txn_proxy = require('txn_proxy')
+ | ---
+ | ...
+
+s = box.schema.space.create('test')
+ | ---
+ | ...
+i = s:create_index('pk', {parts={{1, 'uint'}}})
+ | ---
+ | ...
+i = s:create_index('sec', {parts={{2, 'uint'}}})
+ | ---
+ | ...
+
+tx1 = txn_proxy.new()
+ | ---
+ | ...
+tx2 = txn_proxy.new()
+ | ---
+ | ...
+
+-- Simple read/write conflicts.
+s:replace{1, 0}
+ | ---
+ | - [1, 0]
+ | ...
+tx1:begin()
+ | ---
+ | -
+ | ...
+tx2:begin()
+ | ---
+ | -
+ | ...
+tx1('s:select{1}')
+ | ---
+ | - - [[1, 0]]
+ | ...
+tx2('s:select{1}')
+ | ---
+ | - - [[1, 0]]
+ | ...
+tx1('s:replace{1, 1}')
+ | ---
+ | - - [1, 1]
+ | ...
+tx2('s:replace{1, 2}')
+ | ---
+ | - - [1, 2]
+ | ...
+tx1:commit()
+ | ---
+ | -
+ | ...
+tx2:commit()
+ | ---
+ | - - {'error': 'Transaction has been aborted by conflict'}
+ | ...
+s:select{}
+ | ---
+ | - - [1, 1]
+ | ...
+
+-- Simple read/write conflicts, different order.
+s:replace{1, 0}
+ | ---
+ | - [1, 0]
+ | ...
+tx1:begin()
+ | ---
+ | -
+ | ...
+tx2:begin()
+ | ---
+ | -
+ | ...
+tx1('s:select{1}')
+ | ---
+ | - - [[1, 0]]
+ | ...
+tx2('s:select{1}')
+ | ---
+ | - - [[1, 0]]
+ | ...
+tx1('s:replace{1, 1}')
+ | ---
+ | - - [1, 1]
+ | ...
+tx2('s:replace{1, 2}')
+ | ---
+ | - - [1, 2]
+ | ...
+tx2:commit() -- note that tx2 commits first.
+ | ---
+ | -
+ | ...
+tx1:commit()
+ | ---
+ | - - {'error': 'Transaction has been aborted by conflict'}
+ | ...
+s:select{}
+ | ---
+ | - - [1, 2]
+ | ...
+
+-- Implicit read/write conflicts.
+s:replace{1, 0}
+ | ---
+ | - [1, 0]
+ | ...
+tx1:begin()
+ | ---
+ | -
+ | ...
+tx2:begin()
+ | ---
+ | -
+ | ...
+tx1("s:update({1}, {{'+', 2, 3}})")
+ | ---
+ | - - [1, 3]
+ | ...
+tx2("s:update({1}, {{'+', 2, 5}})")
+ | ---
+ | - - [1, 5]
+ | ...
+tx1:commit()
+ | ---
+ | -
+ | ...
+tx2:commit()
+ | ---
+ | - - {'error': 'Transaction has been aborted by conflict'}
+ | ...
+s:select{}
+ | ---
+ | - - [1, 3]
+ | ...
+
+-- Implicit read/write conflicts, different order.
+s:replace{1, 0}
+ | ---
+ | - [1, 0]
+ | ...
+tx1:begin()
+ | ---
+ | -
+ | ...
+tx2:begin()
+ | ---
+ | -
+ | ...
+tx1("s:update({1}, {{'+', 2, 3}})")
+ | ---
+ | - - [1, 3]
+ | ...
+tx2("s:update({1}, {{'+', 2, 5}})")
+ | ---
+ | - - [1, 5]
+ | ...
+tx2:commit() -- note that tx2 commits first.
+ | ---
+ | -
+ | ...
+tx1:commit()
+ | ---
+ | - - {'error': 'Transaction has been aborted by conflict'}
+ | ...
+s:select{}
+ | ---
+ | - - [1, 5]
+ | ...
+s:delete{1}
+ | ---
+ | - [1, 5]
+ | ...
+
+-- Conflict in secondary index.
+tx1:begin()
+ | ---
+ | -
+ | ...
+tx2:begin()
+ | ---
+ | -
+ | ...
+tx1("s:replace{1, 1}")
+ | ---
+ | - - [1, 1]
+ | ...
+tx2("s:replace{2, 1}")
+ | ---
+ | - - [2, 1]
+ | ...
+tx1:commit()
+ | ---
+ | -
+ | ...
+tx2:commit()
+ | ---
+ | - - {'error': 'Transaction has been aborted by conflict'}
+ | ...
+s:select{}
+ | ---
+ | - - [1, 1]
+ | ...
+s:delete{1}
+ | ---
+ | - [1, 1]
+ | ...
+
+-- Conflict in secondary index, different order.
+tx1:begin()
+ | ---
+ | -
+ | ...
+tx2:begin()
+ | ---
+ | -
+ | ...
+tx1("s:replace{1, 2}")
+ | ---
+ | - - [1, 2]
+ | ...
+tx2("s:replace{2, 2}")
+ | ---
+ | - - [2, 2]
+ | ...
+tx2:commit() -- note that tx2 commits first.
+ | ---
+ | -
+ | ...
+tx1:commit()
+ | ---
+ | - - {'error': 'Transaction has been aborted by conflict'}
+ | ...
+s:select{}
+ | ---
+ | - - [2, 2]
+ | ...
+s:delete{2}
+ | ---
+ | - [2, 2]
+ | ...
+
+-- TXN is send to read view.
+s:replace{1, 1}
+ | ---
+ | - [1, 1]
+ | ...
+s:replace{2, 2}
+ | ---
+ | - [2, 2]
+ | ...
+s:replace{3, 3}
+ | ---
+ | - [3, 3]
+ | ...
+tx1:begin()
+ | ---
+ | -
+ | ...
+tx2:begin()
+ | ---
+ | -
+ | ...
+
+tx1("s:select{}")
+ | ---
+ | - - [[1, 1], [2, 2], [3, 3]]
+ | ...
+tx2("s:replace{1, 11}")
+ | ---
+ | - - [1, 11]
+ | ...
+tx2("s:replace{2, 12}")
+ | ---
+ | - - [2, 12]
+ | ...
+tx2:commit()
+ | ---
+ | -
+ | ...
+tx1("s:select{}")
+ | ---
+ | - - [[1, 1], [2, 2], [3, 3]]
+ | ...
+tx1:commit()
+ | ---
+ | -
+ | ...
+
+s:delete{1}
+ | ---
+ | - [1, 11]
+ | ...
+s:delete{2}
+ | ---
+ | - [2, 12]
+ | ...
+s:delete{3}
+ | ---
+ | - [3, 3]
+ | ...
+
+-- TXN is send to read view but tries to replace and becomes conflicted.
+s:replace{1, 1}
+ | ---
+ | - [1, 1]
+ | ...
+s:replace{2, 2}
+ | ---
+ | - [2, 2]
+ | ...
+s:replace{3, 3}
+ | ---
+ | - [3, 3]
+ | ...
+tx1:begin()
+ | ---
+ | -
+ | ...
+tx2:begin()
+ | ---
+ | -
+ | ...
+
+tx1("s:select{}")
+ | ---
+ | - - [[1, 1], [2, 2], [3, 3]]
+ | ...
+tx2("s:replace{1, 11}")
+ | ---
+ | - - [1, 11]
+ | ...
+tx2("s:replace{2, 12}")
+ | ---
+ | - - [2, 12]
+ | ...
+tx2:commit()
+ | ---
+ | -
+ | ...
+tx1("s:select{}")
+ | ---
+ | - - [[1, 1], [2, 2], [3, 3]]
+ | ...
+tx1("s:replace{3, 13}")
+ | ---
+ | - - [3, 13]
+ | ...
+tx1("s:select{}")
+ | ---
+ | - - [[1, 1], [2, 2], [3, 13]]
+ | ...
+tx1:commit()
+ | ---
+ | - - {'error': 'Transaction has been aborted by conflict'}
+ | ...
+
+s:delete{1}
+ | ---
+ | - [1, 11]
+ | ...
+s:delete{2}
+ | ---
+ | - [2, 12]
+ | ...
+s:delete{3}
+ | ---
+ | - [3, 3]
+ | ...
+
+test_run:cmd("switch default")
+ | ---
+ | - true
+ | ...
+test_run:cmd("stop server tx_man")
+ | ---
+ | - true
+ | ...
+test_run:cmd("cleanup server tx_man")
+ | ---
+ | - true
+ | ...
+
diff --git a/test/box/tx_man.test.lua b/test/box/tx_man.test.lua
new file mode 100644
index 0000000..de5a734
--- /dev/null
+++ b/test/box/tx_man.test.lua
@@ -0,0 +1,122 @@
+env = require('test_run')
+test_run = env.new()
+test_run:cmd("create server tx_man with script='box/tx_man.lua'")
+test_run:cmd("start server tx_man")
+test_run:cmd("switch tx_man")
+
+txn_proxy = require('txn_proxy')
+
+s = box.schema.space.create('test')
+i = s:create_index('pk', {parts={{1, 'uint'}}})
+i = s:create_index('sec', {parts={{2, 'uint'}}})
+
+tx1 = txn_proxy.new()
+tx2 = txn_proxy.new()
+
+-- Simple read/write conflicts.
+s:replace{1, 0}
+tx1:begin()
+tx2:begin()
+tx1('s:select{1}')
+tx2('s:select{1}')
+tx1('s:replace{1, 1}')
+tx2('s:replace{1, 2}')
+tx1:commit()
+tx2:commit()
+s:select{}
+
+-- Simple read/write conflicts, different order.
+s:replace{1, 0}
+tx1:begin()
+tx2:begin()
+tx1('s:select{1}')
+tx2('s:select{1}')
+tx1('s:replace{1, 1}')
+tx2('s:replace{1, 2}')
+tx2:commit() -- note that tx2 commits first.
+tx1:commit()
+s:select{}
+
+-- Implicit read/write conflicts.
+s:replace{1, 0}
+tx1:begin()
+tx2:begin()
+tx1("s:update({1}, {{'+', 2, 3}})")
+tx2("s:update({1}, {{'+', 2, 5}})")
+tx1:commit()
+tx2:commit()
+s:select{}
+
+-- Implicit read/write conflicts, different order.
+s:replace{1, 0}
+tx1:begin()
+tx2:begin()
+tx1("s:update({1}, {{'+', 2, 3}})")
+tx2("s:update({1}, {{'+', 2, 5}})")
+tx2:commit() -- note that tx2 commits first.
+tx1:commit()
+s:select{}
+s:delete{1}
+
+-- Conflict in secondary index.
+tx1:begin()
+tx2:begin()
+tx1("s:replace{1, 1}")
+tx2("s:replace{2, 1}")
+tx1:commit()
+tx2:commit()
+s:select{}
+s:delete{1}
+
+-- Conflict in secondary index, different order.
+tx1:begin()
+tx2:begin()
+tx1("s:replace{1, 2}")
+tx2("s:replace{2, 2}")
+tx2:commit() -- note that tx2 commits first.
+tx1:commit()
+s:select{}
+s:delete{2}
+
+-- TXN is send to read view.
+s:replace{1, 1}
+s:replace{2, 2}
+s:replace{3, 3}
+tx1:begin()
+tx2:begin()
+
+tx1("s:select{}")
+tx2("s:replace{1, 11}")
+tx2("s:replace{2, 12}")
+tx2:commit()
+tx1("s:select{}")
+tx1:commit()
+
+s:delete{1}
+s:delete{2}
+s:delete{3}
+
+-- TXN is send to read view but tries to replace and becomes conflicted.
+s:replace{1, 1}
+s:replace{2, 2}
+s:replace{3, 3}
+tx1:begin()
+tx2:begin()
+
+tx1("s:select{}")
+tx2("s:replace{1, 11}")
+tx2("s:replace{2, 12}")
+tx2:commit()
+tx1("s:select{}")
+tx1("s:replace{3, 13}")
+tx1("s:select{}")
+tx1:commit()
+
+s:delete{1}
+s:delete{2}
+s:delete{3}
+
+test_run:cmd("switch default")
+test_run:cmd("stop server tx_man")
+test_run:cmd("cleanup server tx_man")
+
--
2.7.4
More information about the Tarantool-patches
mailing list