From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: From: Serge Petrenko Subject: [PATCH v3 2/2] test: move background index build test to engine suite from vinyl Date: Tue, 28 May 2019 18:33:25 +0300 Message-Id: <87a3ff76ed05d1f42d569e162ab5125cd51b781e.1559056498.git.sergepetrenko@tarantool.org> In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit To: vdavydov.dev@gmail.com Cc: tarantool-patches@freelists.org, kostja@tarantool.org, Serge Petrenko List-ID: Since we have implemented memtx background index build, the corresponding vinyl test cases are now also suitable for memtx, so move them to engine suite so that both engines are tested. Also add some tests to check that an ongoing index build is aborted in case a tuple violating unique constraing or format of the new index is inserted. Closes #3976 --- test/engine/ddl.result | 215 +++++++++++++++++++++++++++++++++++++++ test/engine/ddl.test.lua | 121 ++++++++++++++++++++++ test/vinyl/ddl.result | 118 --------------------- test/vinyl/ddl.test.lua | 70 ------------- 4 files changed, 336 insertions(+), 188 deletions(-) diff --git a/test/engine/ddl.result b/test/engine/ddl.result index c493bd4ac..2a82399d6 100644 --- a/test/engine/ddl.result +++ b/test/engine/ddl.result @@ -2222,3 +2222,218 @@ s.index.pk:drop(); s:drop(); --- ... +-- +-- Check that all modifications done to the space during index build +-- are reflected in the new index. +-- +math.randomseed(os.time()) + +s = box.schema.space.create('test', {engine = engine}) +_ = s:create_index('pk') + +inspector:cmd("setopt delimiter ';'") + +box.begin() +for i = 1, 1000 do + if (i % 100 == 0) then + box.commit() + box.begin() + end + if i % 300 == 0 then + box.snapshot() + end + box.space.test:replace{i, i, i} +end +box.commit(); +--- +... +last_val = 1000; +--- +... +function gen_load() + local s = box.space.test + for i = 1, 200 do + local op = math.random(4) + local key = math.random(1000) + local val1 = math.random(1000) + local val2 = last_val + 1 + last_val = val2 + if op == 1 then + pcall(s.insert, s, {key, val1, val2}) + elseif op == 2 then + pcall(s.replace, s, {key, val1, val2}) + elseif op == 3 then + pcall(s.delete, s, {key}) + elseif op == 4 then + pcall(s.upsert, s, {key, val1, val2}, {{'=', 2, val1}, {'=', 3, val2}}) + end + end +end; +--- +... +inspector:cmd("setopt delimiter ''"); +--- +- true +... +fiber = require('fiber') +--- +... +ch = fiber.channel(1) +--- +... +_ = fiber.create(function() gen_load() ch:put(true) end) +--- +... +_ = box.space.test:create_index('sk', {unique = false, parts = {2, 'unsigned'}}) +--- +... +ch:get() +--- +- true +... +_ = fiber.create(function() gen_load() ch:put(true) end) +--- +... +_ = box.space.test:create_index('tk', {unique = true, parts = {3, 'unsigned'}}) +--- +... +ch:get() +--- +- true +... +box.space.test.index.pk:count() == box.space.test.index.sk:count() +--- +- true +... +box.space.test.index.pk:count() == box.space.test.index.tk:count() +--- +- true +... +t = box.schema.space.create("space", {engine = engine}) +--- +... +_ = t:create_index("pk") +--- +... +for i = 1,1000 do t:insert{i, i} end +--- +... +-- check that index build is aborted in case conflicting tuple is inserted +-- error injection makes index build yield after 1 tuple is inserted into +-- new index, check that index build is aborted if unique constraint is +-- violated, as well as if tuple format doesn't match the new indexes one. +box.error.injection.set('ERRINJ_BUILD_INDEX_DELAY', 0.001) +--- +- ok +... +inspector:cmd("setopt delimiter ';'") +--- +- true +... +fiber.new(function() t:replace{1, 2} end) +t:create_index('sk', {parts = {2, 'unsigned', unique=true}}); +--- +- error: Duplicate key exists in unique index 'sk' in space 'space' +... +t:get{1}; +--- +- [1, 2] +... +t.index.sk; +--- +- null +... +t:replace{1, 1}; +--- +- [1, 1] +... +fiber.new(function() t:replace{2, 3} end) +t:create_index('sk', {parts = {2, 'unsigned', unique=true}}); +--- +- error: Duplicate key exists in unique index 'sk' in space 'space' +... +t:get{2}; +--- +- [2, 3] +... +t.index.sk == nil; +--- +- true +... +t:replace{2, 2}; +--- +- [2, 2] +... +fiber.new(function() t:replace{1, 'asdf'} end) +t:create_index('sk', {parts = {2, 'unsigned'}}); +--- +- error: 'Tuple field 2 type does not match one required by operation: expected unsigned' +... +t:get{1}; +--- +- [1, 'asdf'] +... +t.index.sk == nil; +--- +- true +... +t:replace{1, 1}; +--- +- [1, 1] +... +fiber.new(function() t:replace{2, 'asdf'} end) +t:create_index('sk', {parts = {2, 'unsigned'}}); +--- +- error: 'Tuple field 2 type does not match one required by operation: expected unsigned' +... +t:get{2}; +--- +- [2, 'asdf'] +... +t.index.sk == nil; +--- +- true +... +t:replace{2, 2}; +--- +- [2, 2] +... +inspector:cmd("setopt delimiter ''"); +--- +- true +... +box.error.injection.set('ERRINJ_BUILD_INDEX_DELAY', 0.0) +--- +- ok +... +inspector:cmd("restart server default") +box.space.space.index.sk == nil +--- +- true +... +box.space.test.index.pk:count() == box.space.test.index.sk:count() +--- +- true +... +box.space.test.index.pk:count() == box.space.test.index.tk:count() +--- +- true +... +box.snapshot() +--- +- ok +... +box.space.test.index.pk:count() == box.space.test.index.sk:count() +--- +- true +... +box.space.test.index.pk:count() == box.space.test.index.tk:count() +--- +- true +... +box.space.space:drop() +--- +... +box.space.test:drop() +--- +... diff --git a/test/engine/ddl.test.lua b/test/engine/ddl.test.lua index 636f6c3b9..c11530c20 100644 --- a/test/engine/ddl.test.lua +++ b/test/engine/ddl.test.lua @@ -830,3 +830,124 @@ box.commit(); -- index and space drop are not currently supported (because of truncate) s.index.pk:drop(); s:drop(); + +-- +-- Check that all modifications done to the space during index build +-- are reflected in the new index. +-- +math.randomseed(os.time()) + +s = box.schema.space.create('test', {engine = engine}) +_ = s:create_index('pk') + +inspector:cmd("setopt delimiter ';'") + +box.begin() +for i = 1, 1000 do + if (i % 100 == 0) then + box.commit() + box.begin() + end + if i % 300 == 0 then + box.snapshot() + end + box.space.test:replace{i, i, i} +end +box.commit(); + +last_val = 1000; + +function gen_load() + local s = box.space.test + for i = 1, 200 do + local op = math.random(4) + local key = math.random(1000) + local val1 = math.random(1000) + local val2 = last_val + 1 + last_val = val2 + if op == 1 then + pcall(s.insert, s, {key, val1, val2}) + elseif op == 2 then + pcall(s.replace, s, {key, val1, val2}) + elseif op == 3 then + pcall(s.delete, s, {key}) + elseif op == 4 then + pcall(s.upsert, s, {key, val1, val2}, {{'=', 2, val1}, {'=', 3, val2}}) + end + end +end; + +inspector:cmd("setopt delimiter ''"); + +fiber = require('fiber') +ch = fiber.channel(1) + +_ = fiber.create(function() gen_load() ch:put(true) end) +_ = box.space.test:create_index('sk', {unique = false, parts = {2, 'unsigned'}}) +ch:get() + +_ = fiber.create(function() gen_load() ch:put(true) end) +_ = box.space.test:create_index('tk', {unique = true, parts = {3, 'unsigned'}}) +ch:get() + +box.space.test.index.pk:count() == box.space.test.index.sk:count() +box.space.test.index.pk:count() == box.space.test.index.tk:count() + +t = box.schema.space.create("space", {engine = engine}) +_ = t:create_index("pk") +for i = 1,1000 do t:insert{i, i} end + +-- check that index build is aborted in case conflicting tuple is inserted +-- error injection makes index build yield after 1 tuple is inserted into +-- new index, check that index build is aborted if unique constraint is +-- violated, as well as if tuple format doesn't match the new indexes one. + +box.error.injection.set('ERRINJ_BUILD_INDEX_DELAY', 0.001) +inspector:cmd("setopt delimiter ';'") +fiber.new(function() t:replace{1, 2} end) +t:create_index('sk', {parts = {2, 'unsigned', unique=true}}); + +t:get{1}; +t.index.sk; + +t:replace{1, 1}; + +fiber.new(function() t:replace{2, 3} end) +t:create_index('sk', {parts = {2, 'unsigned', unique=true}}); + +t:get{2}; +t.index.sk == nil; + +t:replace{2, 2}; + +fiber.new(function() t:replace{1, 'asdf'} end) +t:create_index('sk', {parts = {2, 'unsigned'}}); + +t:get{1}; +t.index.sk == nil; + +t:replace{1, 1}; + +fiber.new(function() t:replace{2, 'asdf'} end) +t:create_index('sk', {parts = {2, 'unsigned'}}); + +t:get{2}; +t.index.sk == nil; + +t:replace{2, 2}; + +inspector:cmd("setopt delimiter ''"); +box.error.injection.set('ERRINJ_BUILD_INDEX_DELAY', 0.0) + +inspector:cmd("restart server default") + +box.space.space.index.sk == nil + +box.space.test.index.pk:count() == box.space.test.index.sk:count() +box.space.test.index.pk:count() == box.space.test.index.tk:count() +box.snapshot() +box.space.test.index.pk:count() == box.space.test.index.sk:count() +box.space.test.index.pk:count() == box.space.test.index.tk:count() + +box.space.space:drop() +box.space.test:drop() diff --git a/test/vinyl/ddl.result b/test/vinyl/ddl.result index 864050b3d..957dbb71d 100644 --- a/test/vinyl/ddl.result +++ b/test/vinyl/ddl.result @@ -655,124 +655,6 @@ s:drop() --- ... -- --- Check that all modifications done to the space during index build --- are reflected in the new index. --- -math.randomseed(os.time()) ---- -... -s = box.schema.space.create('test', {engine = 'vinyl'}) ---- -... -_ = s:create_index('pk') ---- -... -test_run:cmd("setopt delimiter ';'") ---- -- true -... -box.begin(); ---- -... -for i = 1, 1000 do - if (i % 100 == 0) then - box.commit() - box.begin() - end - if i % 300 == 0 then - box.snapshot() - end - box.space.test:replace{i, i, i} -end; ---- -... -box.commit(); ---- -... -last_val = 1000; ---- -... -function gen_load() - local s = box.space.test - for i = 1, 200 do - local op = math.random(4) - local key = math.random(1000) - local val1 = math.random(1000) - local val2 = last_val + 1 - last_val = val2 - if op == 1 then - pcall(s.insert, s, {key, val1, val2}) - elseif op == 2 then - pcall(s.replace, s, {key, val1, val2}) - elseif op == 3 then - pcall(s.delete, s, {key}) - elseif op == 4 then - pcall(s.upsert, s, {key, val1, val2}, {{'=', 2, val1}, {'=', 3, val2}}) - end - end -end; ---- -... -test_run:cmd("setopt delimiter ''"); ---- -- true -... -ch = fiber.channel(1) ---- -... -_ = fiber.create(function() gen_load() ch:put(true) end) ---- -... -_ = box.space.test:create_index('sk', {unique = false, parts = {2, 'unsigned'}}) ---- -... -ch:get() ---- -- true -... -_ = fiber.create(function() gen_load() ch:put(true) end) ---- -... -_ = box.space.test:create_index('tk', {unique = true, parts = {3, 'unsigned'}}) ---- -... -ch:get() ---- -- true -... -box.space.test.index.pk:count() == box.space.test.index.sk:count() ---- -- true -... -box.space.test.index.pk:count() == box.space.test.index.tk:count() ---- -- true -... -test_run:cmd("restart server default") -box.space.test.index.pk:count() == box.space.test.index.sk:count() ---- -- true -... -box.space.test.index.pk:count() == box.space.test.index.tk:count() ---- -- true -... -box.snapshot() ---- -- ok -... -box.space.test.index.pk:count() == box.space.test.index.sk:count() ---- -- true -... -box.space.test.index.pk:count() == box.space.test.index.tk:count() ---- -- true -... -box.space.test:drop() ---- -... --- -- Check that creation of a secondary index triggers dump -- if memory quota is exceeded. -- diff --git a/test/vinyl/ddl.test.lua b/test/vinyl/ddl.test.lua index 46189828b..010ec6d79 100644 --- a/test/vinyl/ddl.test.lua +++ b/test/vinyl/ddl.test.lua @@ -241,76 +241,6 @@ _ = s:create_index('secondary', {parts = {2, 'unsigned'}}) s:select() s:drop() --- --- Check that all modifications done to the space during index build --- are reflected in the new index. --- -math.randomseed(os.time()) - -s = box.schema.space.create('test', {engine = 'vinyl'}) -_ = s:create_index('pk') - -test_run:cmd("setopt delimiter ';'") - -box.begin(); -for i = 1, 1000 do - if (i % 100 == 0) then - box.commit() - box.begin() - end - if i % 300 == 0 then - box.snapshot() - end - box.space.test:replace{i, i, i} -end; -box.commit(); - -last_val = 1000; - -function gen_load() - local s = box.space.test - for i = 1, 200 do - local op = math.random(4) - local key = math.random(1000) - local val1 = math.random(1000) - local val2 = last_val + 1 - last_val = val2 - if op == 1 then - pcall(s.insert, s, {key, val1, val2}) - elseif op == 2 then - pcall(s.replace, s, {key, val1, val2}) - elseif op == 3 then - pcall(s.delete, s, {key}) - elseif op == 4 then - pcall(s.upsert, s, {key, val1, val2}, {{'=', 2, val1}, {'=', 3, val2}}) - end - end -end; - -test_run:cmd("setopt delimiter ''"); - -ch = fiber.channel(1) - -_ = fiber.create(function() gen_load() ch:put(true) end) -_ = box.space.test:create_index('sk', {unique = false, parts = {2, 'unsigned'}}) -ch:get() - -_ = fiber.create(function() gen_load() ch:put(true) end) -_ = box.space.test:create_index('tk', {unique = true, parts = {3, 'unsigned'}}) -ch:get() - -box.space.test.index.pk:count() == box.space.test.index.sk:count() -box.space.test.index.pk:count() == box.space.test.index.tk:count() - -test_run:cmd("restart server default") - -box.space.test.index.pk:count() == box.space.test.index.sk:count() -box.space.test.index.pk:count() == box.space.test.index.tk:count() -box.snapshot() -box.space.test.index.pk:count() == box.space.test.index.sk:count() -box.space.test.index.pk:count() == box.space.test.index.tk:count() -box.space.test:drop() - -- -- Check that creation of a secondary index triggers dump -- if memory quota is exceeded. -- 2.20.1 (Apple Git-117)