Tarantool development patches archive
 help / color / mirror / Atom feed
* [Tarantool-patches] [PATCH v2] Split box/hash.test.lua to a set of small independent tests
@ 2020-03-19 10:24 Sergey Bronnikov
  2020-03-19 11:09 ` Oleg Piskunov
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Sergey Bronnikov @ 2020-03-19 10:24 UTC (permalink / raw)
  To: tarantool-patches; +Cc: Oleg Piskunov

Splitted single hash.test.lua to a set of small independent tests.

GitHub branch: https://github.com/tarantool/tarantool/tree/ligurio/hash_test_split

---
 test/box/hash.result                  | 873 --------------------------
 test/box/hash.test.lua                | 364 -----------
 test/box/hash_32bit_delete.result     |  70 +++
 test/box/hash_32bit_delete.test.lua   |  29 +
 test/box/hash_32bit_insert.result     |  38 ++
 test/box/hash_32bit_insert.test.lua   |  16 +
 test/box/hash_32bit_replace.result    |  56 ++
 test/box/hash_32bit_replace.test.lua  |  25 +
 test/box/hash_32bit_select.result     |  70 +++
 test/box/hash_32bit_select.test.lua   |  29 +
 test/box/hash_64bit_delete.result     | 111 ++++
 test/box/hash_64bit_delete.test.lua   |  42 ++
 test/box/hash_64bit_insert.result     |  54 ++
 test/box/hash_64bit_insert.test.lua   |  20 +
 test/box/hash_64bit_replace.result    |  68 ++
 test/box/hash_64bit_replace.test.lua  |  28 +
 test/box/hash_64bit_select.result     |  94 +++
 test/box/hash_64bit_select.test.lua   |  37 ++
 test/box/hash_collation.result        |  62 ++
 test/box/hash_collation.test.lua      |  22 +
 test/box/hash_gh-1467.result          |  17 +
 test/box/hash_gh-1467.test.lua        |   6 +
 test/box/hash_gh-3907.result          |  48 ++
 test/box/hash_gh-3907.test.lua        |  15 +
 test/box/hash_gh-616.result           |  17 +
 test/box/hash_gh-616.test.lua         |   7 +
 test/box/hash_iterate.result          |  21 +
 test/box/hash_iterate.test.lua        |   6 +
 test/box/hash_multipart.result        |   7 -
 test/box/hash_multipart.test.lua      |   2 -
 test/box/hash_not_a_multikey.result   |  17 +
 test/box/hash_not_a_multikey.test.lua |   6 +
 test/box/hash_replace.result          | 256 ++++++++
 test/box/hash_replace.test.lua        |  88 +++
 test/box/hash_string_delete.result    |  62 ++
 test/box/hash_string_delete.test.lua  |  24 +
 test/box/hash_string_insert.result    |  32 +
 test/box/hash_string_insert.test.lua  |  13 +
 test/box/hash_string_replace.result   |  47 ++
 test/box/hash_string_replace.test.lua |  19 +
 test/box/hash_string_select.result    |  63 ++
 test/box/hash_string_select.test.lua  |  25 +
 test/box/hash_with_function.result    |  26 +
 test/box/hash_with_function.test.lua  |   9 +
 44 files changed, 1695 insertions(+), 1246 deletions(-)
 delete mode 100644 test/box/hash.result
 delete mode 100644 test/box/hash.test.lua
 create mode 100644 test/box/hash_32bit_delete.result
 create mode 100644 test/box/hash_32bit_delete.test.lua
 create mode 100644 test/box/hash_32bit_insert.result
 create mode 100644 test/box/hash_32bit_insert.test.lua
 create mode 100644 test/box/hash_32bit_replace.result
 create mode 100644 test/box/hash_32bit_replace.test.lua
 create mode 100644 test/box/hash_32bit_select.result
 create mode 100644 test/box/hash_32bit_select.test.lua
 create mode 100644 test/box/hash_64bit_delete.result
 create mode 100644 test/box/hash_64bit_delete.test.lua
 create mode 100644 test/box/hash_64bit_insert.result
 create mode 100644 test/box/hash_64bit_insert.test.lua
 create mode 100644 test/box/hash_64bit_replace.result
 create mode 100644 test/box/hash_64bit_replace.test.lua
 create mode 100644 test/box/hash_64bit_select.result
 create mode 100644 test/box/hash_64bit_select.test.lua
 create mode 100644 test/box/hash_collation.result
 create mode 100644 test/box/hash_collation.test.lua
 create mode 100644 test/box/hash_gh-1467.result
 create mode 100644 test/box/hash_gh-1467.test.lua
 create mode 100644 test/box/hash_gh-3907.result
 create mode 100644 test/box/hash_gh-3907.test.lua
 create mode 100644 test/box/hash_gh-616.result
 create mode 100644 test/box/hash_gh-616.test.lua
 create mode 100644 test/box/hash_iterate.result
 create mode 100644 test/box/hash_iterate.test.lua
 create mode 100644 test/box/hash_not_a_multikey.result
 create mode 100644 test/box/hash_not_a_multikey.test.lua
 create mode 100644 test/box/hash_replace.result
 create mode 100644 test/box/hash_replace.test.lua
 create mode 100644 test/box/hash_string_delete.result
 create mode 100644 test/box/hash_string_delete.test.lua
 create mode 100644 test/box/hash_string_insert.result
 create mode 100644 test/box/hash_string_insert.test.lua
 create mode 100644 test/box/hash_string_replace.result
 create mode 100644 test/box/hash_string_replace.test.lua
 create mode 100644 test/box/hash_string_select.result
 create mode 100644 test/box/hash_string_select.test.lua
 create mode 100644 test/box/hash_with_function.result
 create mode 100644 test/box/hash_with_function.test.lua

diff --git a/test/box/hash.result b/test/box/hash.result
deleted file mode 100644
index 5e1441ecc..000000000
--- a/test/box/hash.result
+++ /dev/null
@@ -1,873 +0,0 @@
---=============================================================================
--- 32-bit hash tests
---=============================================================================
--------------------------------------------------------------------------------
--- 32-bit hash insert fields tests
--------------------------------------------------------------------------------
-hash = box.schema.space.create('tweedledum')
----
-...
-tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true })
----
-...
-bsize = tmp:bsize()
----
-...
--- Insert valid fields
-hash:insert{0, 'value1 v1.0', 'value2 v1.0'}
----
-- [0, 'value1 v1.0', 'value2 v1.0']
-...
-hash:insert{1, 'value1 v1.0', 'value2 v1.0'}
----
-- [1, 'value1 v1.0', 'value2 v1.0']
-...
-hash:insert{2, 'value1 v1.0', 'value2 v1.0'}
----
-- [2, 'value1 v1.0', 'value2 v1.0']
-...
-hash:insert{3, 'value1 v1.0', 'value2 v1.0'}
----
-- [3, 'value1 v1.0', 'value2 v1.0']
-...
-tmp:bsize() > bsize
----
-- true
-...
--- Insert invalid fields
-hash:insert{'invalid key', 'value1 v1.0', 'value2 v1.0'}
----
-- error: 'Tuple field 1 type does not match one required by operation: expected unsigned'
-...
--------------------------------------------------------------------------------
--- 32-bit hash replace fields tests
--------------------------------------------------------------------------------
--- Replace valid fields
-hash:replace{3, 'value1 v1.31', 'value2 1.12'}
----
-- [3, 'value1 v1.31', 'value2 1.12']
-...
-hash:replace{1, 'value1 v1.32', 'value2 1.72'}
----
-- [1, 'value1 v1.32', 'value2 1.72']
-...
-hash:replace{2, 'value1 v1.43', 'value2 1.92'}
----
-- [2, 'value1 v1.43', 'value2 1.92']
-...
--- Replace invalid fields
-hash:replace{'invalid key', 'value1 v1.0', 'value2 v1.0'}
----
-- error: 'Tuple field 1 type does not match one required by operation: expected unsigned'
-...
--------------------------------------------------------------------------------
--- 32-bit hash select fields test
--------------------------------------------------------------------------------
--- select by valid keys
-hash.index['primary']:get{0}
----
-- [0, 'value1 v1.0', 'value2 v1.0']
-...
-hash.index['primary']:get{1}
----
-- [1, 'value1 v1.32', 'value2 1.72']
-...
-hash.index['primary']:get{2}
----
-- [2, 'value1 v1.43', 'value2 1.92']
-...
-hash.index['primary']:get{3}
----
-- [3, 'value1 v1.31', 'value2 1.12']
-...
-hash.index['primary']:get{4}
----
-...
-hash.index['primary']:get{5}
----
-...
--- select by invalid keys
-hash.index['primary']:get{'invalid key'}
----
-- error: 'Supplied key type of part 0 does not match index part type: expected unsigned'
-...
-hash.index['primary']:get{1, 2}
----
-- error: Invalid key part count in an exact match (expected 1, got 2)
-...
--------------------------------------------------------------------------------
--- 32-bit hash delete fields test
--------------------------------------------------------------------------------
--- delete by valid keys
-hash:delete{0}
----
-- [0, 'value1 v1.0', 'value2 v1.0']
-...
-hash:delete{1}
----
-- [1, 'value1 v1.32', 'value2 1.72']
-...
-hash:delete{2}
----
-- [2, 'value1 v1.43', 'value2 1.92']
-...
-hash:delete{3}
----
-- [3, 'value1 v1.31', 'value2 1.12']
-...
-hash:delete{4}
----
-...
-hash:delete{5}
----
-...
--- delete by invalid keys
-hash:delete{'invalid key'}
----
-- error: 'Supplied key type of part 0 does not match index part type: expected unsigned'
-...
-hash:delete{1, 2}
----
-- error: Invalid key part count in an exact match (expected 1, got 2)
-...
-hash:truncate()
----
-...
---=============================================================================
--- 64-bit hash tests
---=============================================================================
--------------------------------------------------------------------------------
--- 64-bit hash inset fields tests
--------------------------------------------------------------------------------
--- Insert valid fields
-hash:insert{0ULL, 'value1 v1.0', 'value2 v1.0'}
----
-- [0, 'value1 v1.0', 'value2 v1.0']
-...
-hash:insert{1ULL, 'value1 v1.0', 'value2 v1.0'}
----
-- [1, 'value1 v1.0', 'value2 v1.0']
-...
-hash:insert{2ULL, 'value1 v1.0', 'value2 v1.0'}
----
-- [2, 'value1 v1.0', 'value2 v1.0']
-...
-hash:insert{3ULL, 'value1 v1.0', 'value2 v1.0'}
----
-- [3, 'value1 v1.0', 'value2 v1.0']
-...
--- Insert invalid fields
-hash:insert{100, 'value1 v1.0', 'value2 v1.0'}
----
-- [100, 'value1 v1.0', 'value2 v1.0']
-...
-hash:insert{101, 'value1 v1.0', 'value2 v1.0'}
----
-- [101, 'value1 v1.0', 'value2 v1.0']
-...
-hash:insert{102, 'value1 v1.0', 'value2 v1.0'}
----
-- [102, 'value1 v1.0', 'value2 v1.0']
-...
-hash:insert{103, 'value1 v1.0', 'value2 v1.0'}
----
-- [103, 'value1 v1.0', 'value2 v1.0']
-...
-hash:insert{'invalid key', 'value1 v1.0', 'value2 v1.0'}
----
-- error: 'Tuple field 1 type does not match one required by operation: expected unsigned'
-...
--------------------------------------------------------------------------------
--- 64-bit hash replace fields tests
--------------------------------------------------------------------------------
--- Replace valid fields
-hash:replace{3ULL, 'value1 v1.31', 'value2 1.12'}
----
-- [3, 'value1 v1.31', 'value2 1.12']
-...
-hash:replace{1ULL, 'value1 v1.32', 'value2 1.72'}
----
-- [1, 'value1 v1.32', 'value2 1.72']
-...
-hash:replace{2ULL, 'value1 v1.43', 'value2 1.92'}
----
-- [2, 'value1 v1.43', 'value2 1.92']
-...
--- Replace invalid fields
-hash:replace{3, 'value1 v1.31', 'value2 1.12'}
----
-- [3, 'value1 v1.31', 'value2 1.12']
-...
-hash:replace{1, 'value1 v1.32', 'value2 1.72'}
----
-- [1, 'value1 v1.32', 'value2 1.72']
-...
-hash:replace{2, 'value1 v1.43', 'value2 1.92'}
----
-- [2, 'value1 v1.43', 'value2 1.92']
-...
-hash:replace{'invalid key', 'value1 v1.0', 'value2 v1.0'}
----
-- error: 'Tuple field 1 type does not match one required by operation: expected unsigned'
-...
--------------------------------------------------------------------------------
--- 64-bit hash select fields test
--------------------------------------------------------------------------------
--- select by valid keys
-hash.index['primary']:get{0ULL}
----
-- [0, 'value1 v1.0', 'value2 v1.0']
-...
-hash.index['primary']:get{1ULL}
----
-- [1, 'value1 v1.32', 'value2 1.72']
-...
-hash.index['primary']:get{2ULL}
----
-- [2, 'value1 v1.43', 'value2 1.92']
-...
-hash.index['primary']:get{3ULL}
----
-- [3, 'value1 v1.31', 'value2 1.12']
-...
-hash.index['primary']:get{4ULL}
----
-...
-hash.index['primary']:get{5ULL}
----
-...
--- select by valid NUM keys
-hash.index['primary']:get{0}
----
-- [0, 'value1 v1.0', 'value2 v1.0']
-...
-hash.index['primary']:get{1}
----
-- [1, 'value1 v1.32', 'value2 1.72']
-...
-hash.index['primary']:get{2}
----
-- [2, 'value1 v1.43', 'value2 1.92']
-...
-hash.index['primary']:get{3}
----
-- [3, 'value1 v1.31', 'value2 1.12']
-...
-hash.index['primary']:get{4}
----
-...
-hash.index['primary']:get{5}
----
-...
--- select by invalid keys
-hash.index['primary']:get{'invalid key'}
----
-- error: 'Supplied key type of part 0 does not match index part type: expected unsigned'
-...
-hash.index['primary']:get{'00000001', '00000002'}
----
-- error: Invalid key part count in an exact match (expected 1, got 2)
-...
--------------------------------------------------------------------------------
--- 64-bit hash delete fields test
--------------------------------------------------------------------------------
--- delete by valid keys
-hash:delete{0ULL}
----
-- [0, 'value1 v1.0', 'value2 v1.0']
-...
-hash:delete{1ULL}
----
-- [1, 'value1 v1.32', 'value2 1.72']
-...
-hash:delete{2ULL}
----
-- [2, 'value1 v1.43', 'value2 1.92']
-...
-hash:delete{3ULL}
----
-- [3, 'value1 v1.31', 'value2 1.12']
-...
-hash:delete{4ULL}
----
-...
-hash:delete{5ULL}
----
-...
-hash:insert{0ULL, 'value1 v1.0', 'value2 v1.0'}
----
-- [0, 'value1 v1.0', 'value2 v1.0']
-...
-hash:insert{1ULL, 'value1 v1.0', 'value2 v1.0'}
----
-- [1, 'value1 v1.0', 'value2 v1.0']
-...
-hash:insert{2ULL, 'value1 v1.0', 'value2 v1.0'}
----
-- [2, 'value1 v1.0', 'value2 v1.0']
-...
-hash:insert{3ULL, 'value1 v1.0', 'value2 v1.0'}
----
-- [3, 'value1 v1.0', 'value2 v1.0']
-...
--- delete by valid NUM keys
-hash:delete{0}
----
-- [0, 'value1 v1.0', 'value2 v1.0']
-...
-hash:delete{1}
----
-- [1, 'value1 v1.0', 'value2 v1.0']
-...
-hash:delete{2}
----
-- [2, 'value1 v1.0', 'value2 v1.0']
-...
-hash:delete{3}
----
-- [3, 'value1 v1.0', 'value2 v1.0']
-...
-hash:delete{4}
----
-...
-hash:delete{5}
----
-...
--- delete by invalid keys
-hash:delete{'invalid key'}
----
-- error: 'Supplied key type of part 0 does not match index part type: expected unsigned'
-...
-hash:delete{'00000001', '00000002'}
----
-- error: Invalid key part count in an exact match (expected 1, got 2)
-...
-hash:truncate()
----
-...
---=============================================================================
--- String hash tests
---=============================================================================
--------------------------------------------------------------------------------
--- String hash inset fields tests
--------------------------------------------------------------------------------
-hash.index['primary']:drop()
----
-...
-tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'string'}, unique = true })
----
-...
--- Insert valid fields
-hash:insert{'key 0', 'value1 v1.0', 'value2 v1.0'}
----
-- ['key 0', 'value1 v1.0', 'value2 v1.0']
-...
-hash:insert{'key 1', 'value1 v1.0', 'value2 v1.0'}
----
-- ['key 1', 'value1 v1.0', 'value2 v1.0']
-...
-hash:insert{'key 2', 'value1 v1.0', 'value2 v1.0'}
----
-- ['key 2', 'value1 v1.0', 'value2 v1.0']
-...
-hash:insert{'key 3', 'value1 v1.0', 'value2 v1.0'}
----
-- ['key 3', 'value1 v1.0', 'value2 v1.0']
-...
--------------------------------------------------------------------------------
--- String hash replace fields tests
--------------------------------------------------------------------------------
--- Replace valid fields
-hash:replace{'key 3', 'value1 v1.31', 'value2 1.12'}
----
-- ['key 3', 'value1 v1.31', 'value2 1.12']
-...
-hash:replace{'key 1', 'value1 v1.32', 'value2 1.72'}
----
-- ['key 1', 'value1 v1.32', 'value2 1.72']
-...
-hash:replace{'key 2', 'value1 v1.43', 'value2 1.92'}
----
-- ['key 2', 'value1 v1.43', 'value2 1.92']
-...
--------------------------------------------------------------------------------
--- String hash select fields test
--------------------------------------------------------------------------------
--- select by valid keys
-hash.index['primary']:get{'key 0'}
----
-- ['key 0', 'value1 v1.0', 'value2 v1.0']
-...
-hash.index['primary']:get{'key 1'}
----
-- ['key 1', 'value1 v1.32', 'value2 1.72']
-...
-hash.index['primary']:get{'key 2'}
----
-- ['key 2', 'value1 v1.43', 'value2 1.92']
-...
-hash.index['primary']:get{'key 3'}
----
-- ['key 3', 'value1 v1.31', 'value2 1.12']
-...
-hash.index['primary']:get{'key 4'}
----
-...
-hash.index['primary']:get{'key 5'}
----
-...
--- select by invalid keys
-hash.index['primary']:get{'key 1', 'key 2'}
----
-- error: Invalid key part count in an exact match (expected 1, got 2)
-...
--------------------------------------------------------------------------------
--- String hash delete fields test
--------------------------------------------------------------------------------
--- delete by valid keys
-hash:delete{'key 0'}
----
-- ['key 0', 'value1 v1.0', 'value2 v1.0']
-...
-hash:delete{'key 1'}
----
-- ['key 1', 'value1 v1.32', 'value2 1.72']
-...
-hash:delete{'key 2'}
----
-- ['key 2', 'value1 v1.43', 'value2 1.92']
-...
-hash:delete{'key 3'}
----
-- ['key 3', 'value1 v1.31', 'value2 1.12']
-...
-hash:delete{'key 4'}
----
-...
-hash:delete{'key 5'}
----
-...
--- delete by invalid keys
-hash:delete{'key 1', 'key 2'}
----
-- error: Invalid key part count in an exact match (expected 1, got 2)
-...
-hash:truncate()
----
-...
--------------------------------------------------------------------------------
--- Collation test
--------------------------------------------------------------------------------
-hash.index['primary']:drop()
----
-...
-tmp = hash:create_index('primary', { type = 'hash', parts = {{1, 'string', collation = 'unicode_ci'}}, unique = true})
----
-...
-tmp = hash:create_index('secondary', { type = 'hash', parts = {{2, 'scalar', collation = 'unicode_ci'}}, unique = true})
----
-...
-hash:insert{'Ёж', 'Hedgehog'}
----
-- ['Ёж', 'Hedgehog']
-...
-hash:insert{'Ёлка', 'Spruce'}
----
-- ['Ёлка', 'Spruce']
-...
-hash:insert{'Jogurt', 'Йогурт'}
----
-- ['Jogurt', 'Йогурт']
-...
-hash:insert{'Один', 1}
----
-- ['Один', 1]
-...
-hash.index.primary:get('ёж')
----
-- ['Ёж', 'Hedgehog']
-...
-hash.index.primary:get('елка')
----
-- ['Ёлка', 'Spruce']
-...
-hash.index.secondary:get('spruce')
----
-- ['Ёлка', 'Spruce']
-...
-hash.index.secondary:get('йогурт')
----
-- ['Jogurt', 'Йогурт']
-...
-hash.index.secondary:get(1)
----
-- ['Один', 1]
-...
-hash.index.secondary:get('иогурт')
----
-...
-hash.index.secondary:get(2)
----
-...
-------------------------
--- hash::replace tests
-------------------------
-hash.index['secondary']:drop()
----
-...
-hash.index['primary']:drop()
----
-...
-tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true })
----
-...
-tmp = hash:create_index('field1', { type = 'hash', parts = {2, 'unsigned'}, unique = true })
----
-...
-tmp = hash:create_index('field2', { type = 'hash', parts = {3, 'unsigned'}, unique = true })
----
-...
-tmp = hash:create_index('field3', { type = 'hash', parts = {4, 'unsigned'}, unique = true })
----
-...
-hash:insert{0, 0, 0, 0}
----
-- [0, 0, 0, 0]
-...
-hash:insert{1, 1, 1, 1}
----
-- [1, 1, 1, 1]
-...
-hash:insert{2, 2, 2, 2}
----
-- [2, 2, 2, 2]
-...
--- OK
-hash:replace{1, 1, 1, 1}
----
-- [1, 1, 1, 1]
-...
-hash.index['primary']:get{10}
----
-...
-hash.index['field1']:get{10}
----
-...
-hash.index['field2']:get{10}
----
-...
-hash.index['field3']:get{10}
----
-...
-hash.index['primary']:get{1}
----
-- [1, 1, 1, 1]
-...
-hash.index['field1']:get{1}
----
-- [1, 1, 1, 1]
-...
-hash.index['field2']:get{1}
----
-- [1, 1, 1, 1]
-...
-hash.index['field3']:get{1}
----
-- [1, 1, 1, 1]
-...
--- OK
-hash:insert{10, 10, 10, 10}
----
-- [10, 10, 10, 10]
-...
-hash:delete{10}
----
-- [10, 10, 10, 10]
-...
-hash.index['primary']:get{10}
----
-...
-hash.index['field1']:get{10}
----
-...
-hash.index['field2']:get{10}
----
-...
-hash.index['field3']:get{10}
----
-...
--- TupleFound (primary key)
-hash:insert{1, 10, 10, 10}
----
-- error: Duplicate key exists in unique index 'primary' in space 'tweedledum'
-...
-hash.index['primary']:get{10}
----
-...
-hash.index['field1']:get{10}
----
-...
-hash.index['field2']:get{10}
----
-...
-hash.index['field3']:get{10}
----
-...
-hash.index['primary']:get{1}
----
-- [1, 1, 1, 1]
-...
--- TupleNotFound (primary key)
-hash:replace{10, 10, 10, 10}
----
-- [10, 10, 10, 10]
-...
-hash.index['primary']:get{10}
----
-- [10, 10, 10, 10]
-...
-hash.index['field1']:get{10}
----
-- [10, 10, 10, 10]
-...
-hash.index['field2']:get{10}
----
-- [10, 10, 10, 10]
-...
-hash.index['field3']:get{10}
----
-- [10, 10, 10, 10]
-...
--- TupleFound (key --1)
-hash:insert{10, 0, 10, 10}
----
-- error: Duplicate key exists in unique index 'primary' in space 'tweedledum'
-...
-hash.index['primary']:get{10}
----
-- [10, 10, 10, 10]
-...
-hash.index['field1']:get{10}
----
-- [10, 10, 10, 10]
-...
-hash.index['field2']:get{10}
----
-- [10, 10, 10, 10]
-...
-hash.index['field3']:get{10}
----
-- [10, 10, 10, 10]
-...
-hash.index['field1']:get{0}
----
-- [0, 0, 0, 0]
-...
--- TupleFound (key --1)
--- hash:replace_if_exists(2, 0, 10, 10)
-hash.index['primary']:get{10}
----
-- [10, 10, 10, 10]
-...
-hash.index['field1']:get{10}
----
-- [10, 10, 10, 10]
-...
-hash.index['field2']:get{10}
----
-- [10, 10, 10, 10]
-...
-hash.index['field3']:get{10}
----
-- [10, 10, 10, 10]
-...
-hash.index['field1']:get{0}
----
-- [0, 0, 0, 0]
-...
--- TupleFound (key --3)
-hash:insert{10, 10, 10, 0}
----
-- error: Duplicate key exists in unique index 'primary' in space 'tweedledum'
-...
-hash.index['primary']:get{10}
----
-- [10, 10, 10, 10]
-...
-hash.index['field1']:get{10}
----
-- [10, 10, 10, 10]
-...
-hash.index['field2']:get{10}
----
-- [10, 10, 10, 10]
-...
-hash.index['field3']:get{10}
----
-- [10, 10, 10, 10]
-...
-hash.index['field3']:get{0}
----
-- [0, 0, 0, 0]
-...
--- TupleFound (key --3)
--- hash:replace_if_exists(2, 10, 10, 0)
-hash.index['primary']:get{10}
----
-- [10, 10, 10, 10]
-...
-hash.index['field1']:get{10}
----
-- [10, 10, 10, 10]
-...
-hash.index['field2']:get{10}
----
-- [10, 10, 10, 10]
-...
-hash.index['field3']:get{10}
----
-- [10, 10, 10, 10]
-...
-hash.index['field3']:get{0}
----
-- [0, 0, 0, 0]
-...
-hash:drop()
----
-...
-hash = box.schema.space.create('tweedledum')
----
-...
-hi = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true })
----
-...
-hash:insert{0}
----
-- [0]
-...
-hash:insert{16}
----
-- [16]
-...
-for _, tuple in hi:pairs(nil, {iterator = box.index.ALL}) do hash:delete{tuple[1]} end
----
-...
-hash:drop()
----
-...
--- 
--- gh-616 "1-based indexing and 0-based error message
---
-_ = box.schema.create_space('test')
----
-...
-_ = box.space.test:create_index('i',{parts={1,'string'}})
----
-...
-box.space.test:insert{1}
----
-- error: 'Tuple field 1 type does not match one required by operation: expected string'
-...
-box.space.test:drop()
----
-...
--- gh-1467: invalid iterator type
-space = box.schema.space.create('test')
----
-...
-index = space:create_index('primary', { type = 'hash' })
----
-...
-space:select({1}, {iterator = 'BITS_ALL_SET' } )
----
-- error: Index 'primary' (HASH) of space 'test' (memtx) does not support requested
-    iterator type
-...
-space:drop()
----
-...
--- gh-3907: check that integer numbers stored as MP_FLOAT/MP_DOUBLE
--- are hashed as MP_INT/MP_UINT.
-ffi = require('ffi')
----
-...
-s = box.schema.space.create('test')
----
-...
-_ = s:create_index('primary', {type = 'hash', parts = {1, 'number'}})
----
-...
-s:insert{ffi.new('double', 0)}
----
-- [0]
-...
-s:insert{ffi.new('double', -1)}
----
-- [-1]
-...
-s:insert{ffi.new('double', 9007199254740992)}
----
-- [9007199254740992]
-...
-s:insert{ffi.new('double', -9007199254740994)}
----
-- [-9007199254740994]
-...
-s:get(0LL)
----
-- [0]
-...
-s:get(-1LL)
----
-- [-1]
-...
-s:get(9007199254740992LL)
----
-- [9007199254740992]
-...
-s:get(-9007199254740994LL)
----
-- [-9007199254740994]
-...
-s:drop()
----
-...
--- Hash index cannot be multikey.
-s = box.schema.space.create('test')
----
-...
-_ = s:create_index('primary')
----
-...
-_ = s:create_index('hash', {type = 'hash', parts = {{'[2][*]', 'unsigned'}}})
----
-- error: 'Can''t create or modify index ''hash'' in space ''test'': HASH index cannot
-    be multikey'
-...
-s:drop()
----
-...
--- Hash index can not use function.
-s = box.schema.space.create('withdata')
----
-...
-lua_code = [[function(tuple) return tuple[1] + tuple[2] end]]
----
-...
-box.schema.func.create('s', {body = lua_code, is_deterministic = true, is_sandboxed = true})
----
-...
-_ = s:create_index('pk')
----
-...
-_ = s:create_index('idx', {type = 'hash', func = box.func.s.id, parts = {{1, 'unsigned'}}})
----
-- error: 'Can''t create or modify index ''idx'' in space ''withdata'': HASH index
-    can not use a function'
-...
-s:drop()
----
-...
-box.schema.func.drop('s')
----
-...
diff --git a/test/box/hash.test.lua b/test/box/hash.test.lua
deleted file mode 100644
index 78c831f77..000000000
--- a/test/box/hash.test.lua
+++ /dev/null
@@ -1,364 +0,0 @@
---=============================================================================
--- 32-bit hash tests
---=============================================================================
--------------------------------------------------------------------------------
--- 32-bit hash insert fields tests
--------------------------------------------------------------------------------
-hash = box.schema.space.create('tweedledum')
-tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true })
-
-bsize = tmp:bsize()
-
--- Insert valid fields
-hash:insert{0, 'value1 v1.0', 'value2 v1.0'}
-hash:insert{1, 'value1 v1.0', 'value2 v1.0'}
-hash:insert{2, 'value1 v1.0', 'value2 v1.0'}
-hash:insert{3, 'value1 v1.0', 'value2 v1.0'}
-
-tmp:bsize() > bsize
-
--- Insert invalid fields
-hash:insert{'invalid key', 'value1 v1.0', 'value2 v1.0'}
-
--------------------------------------------------------------------------------
--- 32-bit hash replace fields tests
--------------------------------------------------------------------------------
-
--- Replace valid fields
-hash:replace{3, 'value1 v1.31', 'value2 1.12'}
-hash:replace{1, 'value1 v1.32', 'value2 1.72'}
-hash:replace{2, 'value1 v1.43', 'value2 1.92'}
-
--- Replace invalid fields
-hash:replace{'invalid key', 'value1 v1.0', 'value2 v1.0'}
-
--------------------------------------------------------------------------------
--- 32-bit hash select fields test
--------------------------------------------------------------------------------
-
--- select by valid keys
-hash.index['primary']:get{0}
-hash.index['primary']:get{1}
-hash.index['primary']:get{2}
-hash.index['primary']:get{3}
-hash.index['primary']:get{4}
-hash.index['primary']:get{5}
-
--- select by invalid keys
-hash.index['primary']:get{'invalid key'}
-hash.index['primary']:get{1, 2}
-
--------------------------------------------------------------------------------
--- 32-bit hash delete fields test
--------------------------------------------------------------------------------
-
--- delete by valid keys
-hash:delete{0}
-hash:delete{1}
-hash:delete{2}
-hash:delete{3}
-hash:delete{4}
-hash:delete{5}
-
--- delete by invalid keys
-hash:delete{'invalid key'}
-hash:delete{1, 2}
-
-hash:truncate()
-
---=============================================================================
--- 64-bit hash tests
---=============================================================================
--------------------------------------------------------------------------------
--- 64-bit hash inset fields tests
--------------------------------------------------------------------------------
-
--- Insert valid fields
-hash:insert{0ULL, 'value1 v1.0', 'value2 v1.0'}
-hash:insert{1ULL, 'value1 v1.0', 'value2 v1.0'}
-hash:insert{2ULL, 'value1 v1.0', 'value2 v1.0'}
-hash:insert{3ULL, 'value1 v1.0', 'value2 v1.0'}
-
--- Insert invalid fields
-hash:insert{100, 'value1 v1.0', 'value2 v1.0'}
-hash:insert{101, 'value1 v1.0', 'value2 v1.0'}
-hash:insert{102, 'value1 v1.0', 'value2 v1.0'}
-hash:insert{103, 'value1 v1.0', 'value2 v1.0'}
-hash:insert{'invalid key', 'value1 v1.0', 'value2 v1.0'}
-
--------------------------------------------------------------------------------
--- 64-bit hash replace fields tests
--------------------------------------------------------------------------------
-
--- Replace valid fields
-hash:replace{3ULL, 'value1 v1.31', 'value2 1.12'}
-hash:replace{1ULL, 'value1 v1.32', 'value2 1.72'}
-hash:replace{2ULL, 'value1 v1.43', 'value2 1.92'}
-
--- Replace invalid fields
-hash:replace{3, 'value1 v1.31', 'value2 1.12'}
-hash:replace{1, 'value1 v1.32', 'value2 1.72'}
-hash:replace{2, 'value1 v1.43', 'value2 1.92'}
-hash:replace{'invalid key', 'value1 v1.0', 'value2 v1.0'}
-
--------------------------------------------------------------------------------
--- 64-bit hash select fields test
--------------------------------------------------------------------------------
-
--- select by valid keys
-hash.index['primary']:get{0ULL}
-hash.index['primary']:get{1ULL}
-hash.index['primary']:get{2ULL}
-hash.index['primary']:get{3ULL}
-hash.index['primary']:get{4ULL}
-hash.index['primary']:get{5ULL}
-
--- select by valid NUM keys
-hash.index['primary']:get{0}
-hash.index['primary']:get{1}
-hash.index['primary']:get{2}
-hash.index['primary']:get{3}
-hash.index['primary']:get{4}
-hash.index['primary']:get{5}
-
--- select by invalid keys
-hash.index['primary']:get{'invalid key'}
-hash.index['primary']:get{'00000001', '00000002'}
-
--------------------------------------------------------------------------------
--- 64-bit hash delete fields test
--------------------------------------------------------------------------------
-
--- delete by valid keys
-hash:delete{0ULL}
-hash:delete{1ULL}
-hash:delete{2ULL}
-hash:delete{3ULL}
-hash:delete{4ULL}
-hash:delete{5ULL}
-
-hash:insert{0ULL, 'value1 v1.0', 'value2 v1.0'}
-hash:insert{1ULL, 'value1 v1.0', 'value2 v1.0'}
-hash:insert{2ULL, 'value1 v1.0', 'value2 v1.0'}
-hash:insert{3ULL, 'value1 v1.0', 'value2 v1.0'}
-
--- delete by valid NUM keys
-hash:delete{0}
-hash:delete{1}
-hash:delete{2}
-hash:delete{3}
-hash:delete{4}
-hash:delete{5}
-
--- delete by invalid keys
-hash:delete{'invalid key'}
-hash:delete{'00000001', '00000002'}
-hash:truncate()
-
---=============================================================================
--- String hash tests
---=============================================================================
--------------------------------------------------------------------------------
--- String hash inset fields tests
--------------------------------------------------------------------------------
-hash.index['primary']:drop()
-tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'string'}, unique = true })
-
--- Insert valid fields
-hash:insert{'key 0', 'value1 v1.0', 'value2 v1.0'}
-hash:insert{'key 1', 'value1 v1.0', 'value2 v1.0'}
-hash:insert{'key 2', 'value1 v1.0', 'value2 v1.0'}
-hash:insert{'key 3', 'value1 v1.0', 'value2 v1.0'}
-
--------------------------------------------------------------------------------
--- String hash replace fields tests
--------------------------------------------------------------------------------
-
--- Replace valid fields
-hash:replace{'key 3', 'value1 v1.31', 'value2 1.12'}
-hash:replace{'key 1', 'value1 v1.32', 'value2 1.72'}
-hash:replace{'key 2', 'value1 v1.43', 'value2 1.92'}
-
--------------------------------------------------------------------------------
--- String hash select fields test
--------------------------------------------------------------------------------
-
--- select by valid keys
-hash.index['primary']:get{'key 0'}
-hash.index['primary']:get{'key 1'}
-hash.index['primary']:get{'key 2'}
-hash.index['primary']:get{'key 3'}
-hash.index['primary']:get{'key 4'}
-hash.index['primary']:get{'key 5'}
-
--- select by invalid keys
-hash.index['primary']:get{'key 1', 'key 2'}
-
--------------------------------------------------------------------------------
--- String hash delete fields test
--------------------------------------------------------------------------------
-
--- delete by valid keys
-hash:delete{'key 0'}
-hash:delete{'key 1'}
-hash:delete{'key 2'}
-hash:delete{'key 3'}
-hash:delete{'key 4'}
-hash:delete{'key 5'}
-
--- delete by invalid keys
-hash:delete{'key 1', 'key 2'}
-hash:truncate()
-
--------------------------------------------------------------------------------
--- Collation test
--------------------------------------------------------------------------------
-hash.index['primary']:drop()
-tmp = hash:create_index('primary', { type = 'hash', parts = {{1, 'string', collation = 'unicode_ci'}}, unique = true})
-tmp = hash:create_index('secondary', { type = 'hash', parts = {{2, 'scalar', collation = 'unicode_ci'}}, unique = true})
-
-hash:insert{'Ёж', 'Hedgehog'}
-hash:insert{'Ёлка', 'Spruce'}
-hash:insert{'Jogurt', 'Йогурт'}
-hash:insert{'Один', 1}
-
-hash.index.primary:get('ёж')
-hash.index.primary:get('елка')
-hash.index.secondary:get('spruce')
-hash.index.secondary:get('йогурт')
-hash.index.secondary:get(1)
-hash.index.secondary:get('иогурт')
-hash.index.secondary:get(2)
-
-------------------------
--- hash::replace tests
-------------------------
-hash.index['secondary']:drop()
-hash.index['primary']:drop()
-tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true })
-tmp = hash:create_index('field1', { type = 'hash', parts = {2, 'unsigned'}, unique = true })
-tmp = hash:create_index('field2', { type = 'hash', parts = {3, 'unsigned'}, unique = true })
-tmp = hash:create_index('field3', { type = 'hash', parts = {4, 'unsigned'}, unique = true })
-
-hash:insert{0, 0, 0, 0}
-hash:insert{1, 1, 1, 1}
-hash:insert{2, 2, 2, 2}
-
--- OK
-hash:replace{1, 1, 1, 1}
-hash.index['primary']:get{10}
-hash.index['field1']:get{10}
-hash.index['field2']:get{10}
-hash.index['field3']:get{10}
-hash.index['primary']:get{1}
-hash.index['field1']:get{1}
-hash.index['field2']:get{1}
-hash.index['field3']:get{1}
-
--- OK
-hash:insert{10, 10, 10, 10}
-hash:delete{10}
-hash.index['primary']:get{10}
-hash.index['field1']:get{10}
-hash.index['field2']:get{10}
-hash.index['field3']:get{10}
-
--- TupleFound (primary key)
-hash:insert{1, 10, 10, 10}
-hash.index['primary']:get{10}
-hash.index['field1']:get{10}
-hash.index['field2']:get{10}
-hash.index['field3']:get{10}
-hash.index['primary']:get{1}
-
--- TupleNotFound (primary key)
-hash:replace{10, 10, 10, 10}
-hash.index['primary']:get{10}
-hash.index['field1']:get{10}
-hash.index['field2']:get{10}
-hash.index['field3']:get{10}
-
--- TupleFound (key --1)
-hash:insert{10, 0, 10, 10}
-hash.index['primary']:get{10}
-hash.index['field1']:get{10}
-hash.index['field2']:get{10}
-hash.index['field3']:get{10}
-hash.index['field1']:get{0}
-
--- TupleFound (key --1)
--- hash:replace_if_exists(2, 0, 10, 10)
-hash.index['primary']:get{10}
-hash.index['field1']:get{10}
-hash.index['field2']:get{10}
-hash.index['field3']:get{10}
-hash.index['field1']:get{0}
-
--- TupleFound (key --3)
-hash:insert{10, 10, 10, 0}
-hash.index['primary']:get{10}
-hash.index['field1']:get{10}
-hash.index['field2']:get{10}
-hash.index['field3']:get{10}
-hash.index['field3']:get{0}
-
--- TupleFound (key --3)
--- hash:replace_if_exists(2, 10, 10, 0)
-hash.index['primary']:get{10}
-hash.index['field1']:get{10}
-hash.index['field2']:get{10}
-hash.index['field3']:get{10}
-hash.index['field3']:get{0}
-
-hash:drop()
-
-hash = box.schema.space.create('tweedledum')
-hi = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true })
-hash:insert{0}
-hash:insert{16}
-for _, tuple in hi:pairs(nil, {iterator = box.index.ALL}) do hash:delete{tuple[1]} end
-hash:drop()
-
--- 
--- gh-616 "1-based indexing and 0-based error message
---
-_ = box.schema.create_space('test')
-_ = box.space.test:create_index('i',{parts={1,'string'}})
-box.space.test:insert{1}
-box.space.test:drop()
-
--- gh-1467: invalid iterator type
-space = box.schema.space.create('test')
-index = space:create_index('primary', { type = 'hash' })
-space:select({1}, {iterator = 'BITS_ALL_SET' } )
-space:drop()
-
--- gh-3907: check that integer numbers stored as MP_FLOAT/MP_DOUBLE
--- are hashed as MP_INT/MP_UINT.
-ffi = require('ffi')
-s = box.schema.space.create('test')
-_ = s:create_index('primary', {type = 'hash', parts = {1, 'number'}})
-s:insert{ffi.new('double', 0)}
-s:insert{ffi.new('double', -1)}
-s:insert{ffi.new('double', 9007199254740992)}
-s:insert{ffi.new('double', -9007199254740994)}
-s:get(0LL)
-s:get(-1LL)
-s:get(9007199254740992LL)
-s:get(-9007199254740994LL)
-s:drop()
-
--- Hash index cannot be multikey.
-s = box.schema.space.create('test')
-_ = s:create_index('primary')
-_ = s:create_index('hash', {type = 'hash', parts = {{'[2][*]', 'unsigned'}}})
-s:drop()
-
--- Hash index can not use function.
-s = box.schema.space.create('withdata')
-lua_code = [[function(tuple) return tuple[1] + tuple[2] end]]
-box.schema.func.create('s', {body = lua_code, is_deterministic = true, is_sandboxed = true})
-_ = s:create_index('pk')
-_ = s:create_index('idx', {type = 'hash', func = box.func.s.id, parts = {{1, 'unsigned'}}})
-s:drop()
-box.schema.func.drop('s')
diff --git a/test/box/hash_32bit_delete.result b/test/box/hash_32bit_delete.result
new file mode 100644
index 000000000..b35143b10
--- /dev/null
+++ b/test/box/hash_32bit_delete.result
@@ -0,0 +1,70 @@
+-- test-run result file version 2
+-------------------------------------------------------------------------------
+-- 32-bit hash insert fields tests
+-------------------------------------------------------------------------------
+hash = box.schema.space.create('tweedledum')
+ | ---
+ | ...
+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true })
+ | ---
+ | ...
+
+-- Insert valid fields
+hash:insert{0, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [0, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{1, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [1, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{2, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [2, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{3, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [3, 'value1 v1.0', 'value2 v1.0']
+ | ...
+
+-------------------------------------------------------------------------------
+-- 32-bit hash delete fields test
+-------------------------------------------------------------------------------
+
+-- delete by valid keys
+hash:delete{0}
+ | ---
+ | - [0, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:delete{1}
+ | ---
+ | - [1, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:delete{2}
+ | ---
+ | - [2, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:delete{3}
+ | ---
+ | - [3, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:delete{4}
+ | ---
+ | ...
+hash:delete{5}
+ | ---
+ | ...
+
+-- delete by invalid keys
+hash:delete{'invalid key'}
+ | ---
+ | - error: 'Supplied key type of part 0 does not match index part type: expected unsigned'
+ | ...
+hash:delete{1, 2}
+ | ---
+ | - error: Invalid key part count in an exact match (expected 1, got 2)
+ | ...
+
+hash:drop()
+ | ---
+ | ...
diff --git a/test/box/hash_32bit_delete.test.lua b/test/box/hash_32bit_delete.test.lua
new file mode 100644
index 000000000..682e0bc96
--- /dev/null
+++ b/test/box/hash_32bit_delete.test.lua
@@ -0,0 +1,29 @@
+-------------------------------------------------------------------------------
+-- 32-bit hash insert fields tests
+-------------------------------------------------------------------------------
+hash = box.schema.space.create('tweedledum')
+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true })
+
+-- Insert valid fields
+hash:insert{0, 'value1 v1.0', 'value2 v1.0'}
+hash:insert{1, 'value1 v1.0', 'value2 v1.0'}
+hash:insert{2, 'value1 v1.0', 'value2 v1.0'}
+hash:insert{3, 'value1 v1.0', 'value2 v1.0'}
+
+-------------------------------------------------------------------------------
+-- 32-bit hash delete fields test
+-------------------------------------------------------------------------------
+
+-- delete by valid keys
+hash:delete{0}
+hash:delete{1}
+hash:delete{2}
+hash:delete{3}
+hash:delete{4}
+hash:delete{5}
+
+-- delete by invalid keys
+hash:delete{'invalid key'}
+hash:delete{1, 2}
+
+hash:drop()
diff --git a/test/box/hash_32bit_insert.result b/test/box/hash_32bit_insert.result
new file mode 100644
index 000000000..72c7c4842
--- /dev/null
+++ b/test/box/hash_32bit_insert.result
@@ -0,0 +1,38 @@
+-- test-run result file version 2
+-------------------------------------------------------------------------------
+-- 32-bit hash insert fields tests
+-------------------------------------------------------------------------------
+hash = box.schema.space.create('tweedledum')
+ | ---
+ | ...
+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true })
+ | ---
+ | ...
+
+-- Insert valid fields
+hash:insert{0, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [0, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{1, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [1, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{2, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [2, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{3, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [3, 'value1 v1.0', 'value2 v1.0']
+ | ...
+
+-- Insert invalid fields
+hash:insert{'invalid key', 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - error: 'Tuple field 1 type does not match one required by operation: expected unsigned'
+ | ...
+
+hash:drop()
+ | ---
+ | ...
diff --git a/test/box/hash_32bit_insert.test.lua b/test/box/hash_32bit_insert.test.lua
new file mode 100644
index 000000000..308b27d3e
--- /dev/null
+++ b/test/box/hash_32bit_insert.test.lua
@@ -0,0 +1,16 @@
+-------------------------------------------------------------------------------
+-- 32-bit hash insert fields tests
+-------------------------------------------------------------------------------
+hash = box.schema.space.create('tweedledum')
+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true })
+
+-- Insert valid fields
+hash:insert{0, 'value1 v1.0', 'value2 v1.0'}
+hash:insert{1, 'value1 v1.0', 'value2 v1.0'}
+hash:insert{2, 'value1 v1.0', 'value2 v1.0'}
+hash:insert{3, 'value1 v1.0', 'value2 v1.0'}
+
+-- Insert invalid fields
+hash:insert{'invalid key', 'value1 v1.0', 'value2 v1.0'}
+
+hash:drop()
diff --git a/test/box/hash_32bit_replace.result b/test/box/hash_32bit_replace.result
new file mode 100644
index 000000000..a1feba851
--- /dev/null
+++ b/test/box/hash_32bit_replace.result
@@ -0,0 +1,56 @@
+-- test-run result file version 2
+-------------------------------------------------------------------------------
+-- 32-bit hash insert fields tests
+-------------------------------------------------------------------------------
+hash = box.schema.space.create('tweedledum')
+ | ---
+ | ...
+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true })
+ | ---
+ | ...
+
+-- Insert valid fields
+hash:insert{0, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [0, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{1, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [1, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{2, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [2, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{3, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [3, 'value1 v1.0', 'value2 v1.0']
+ | ...
+
+-------------------------------------------------------------------------------
+-- 32-bit hash replace fields tests
+-------------------------------------------------------------------------------
+
+-- Replace valid fields
+hash:replace{3, 'value1 v1.31', 'value2 1.12'}
+ | ---
+ | - [3, 'value1 v1.31', 'value2 1.12']
+ | ...
+hash:replace{1, 'value1 v1.32', 'value2 1.72'}
+ | ---
+ | - [1, 'value1 v1.32', 'value2 1.72']
+ | ...
+hash:replace{2, 'value1 v1.43', 'value2 1.92'}
+ | ---
+ | - [2, 'value1 v1.43', 'value2 1.92']
+ | ...
+
+-- Replace invalid fields
+hash:replace{'invalid key', 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - error: 'Tuple field 1 type does not match one required by operation: expected unsigned'
+ | ...
+
+hash:drop()
+ | ---
+ | ...
diff --git a/test/box/hash_32bit_replace.test.lua b/test/box/hash_32bit_replace.test.lua
new file mode 100644
index 000000000..a00b02185
--- /dev/null
+++ b/test/box/hash_32bit_replace.test.lua
@@ -0,0 +1,25 @@
+-------------------------------------------------------------------------------
+-- 32-bit hash insert fields tests
+-------------------------------------------------------------------------------
+hash = box.schema.space.create('tweedledum')
+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true })
+
+-- Insert valid fields
+hash:insert{0, 'value1 v1.0', 'value2 v1.0'}
+hash:insert{1, 'value1 v1.0', 'value2 v1.0'}
+hash:insert{2, 'value1 v1.0', 'value2 v1.0'}
+hash:insert{3, 'value1 v1.0', 'value2 v1.0'}
+
+-------------------------------------------------------------------------------
+-- 32-bit hash replace fields tests
+-------------------------------------------------------------------------------
+
+-- Replace valid fields
+hash:replace{3, 'value1 v1.31', 'value2 1.12'}
+hash:replace{1, 'value1 v1.32', 'value2 1.72'}
+hash:replace{2, 'value1 v1.43', 'value2 1.92'}
+
+-- Replace invalid fields
+hash:replace{'invalid key', 'value1 v1.0', 'value2 v1.0'}
+
+hash:drop()
diff --git a/test/box/hash_32bit_select.result b/test/box/hash_32bit_select.result
new file mode 100644
index 000000000..f80df9bbd
--- /dev/null
+++ b/test/box/hash_32bit_select.result
@@ -0,0 +1,70 @@
+-- test-run result file version 2
+-------------------------------------------------------------------------------
+-- 32-bit hash insert fields tests
+-------------------------------------------------------------------------------
+hash = box.schema.space.create('tweedledum')
+ | ---
+ | ...
+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true })
+ | ---
+ | ...
+
+-- Insert valid fields
+hash:insert{0, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [0, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{1, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [1, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{2, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [2, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{3, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [3, 'value1 v1.0', 'value2 v1.0']
+ | ...
+
+-------------------------------------------------------------------------------
+-- 32-bit hash select fields test
+-------------------------------------------------------------------------------
+
+-- select by valid keys
+hash.index['primary']:get{0}
+ | ---
+ | - [0, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash.index['primary']:get{1}
+ | ---
+ | - [1, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash.index['primary']:get{2}
+ | ---
+ | - [2, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash.index['primary']:get{3}
+ | ---
+ | - [3, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash.index['primary']:get{4}
+ | ---
+ | ...
+hash.index['primary']:get{5}
+ | ---
+ | ...
+
+-- select by invalid keys
+hash.index['primary']:get{'invalid key'}
+ | ---
+ | - error: 'Supplied key type of part 0 does not match index part type: expected unsigned'
+ | ...
+hash.index['primary']:get{1, 2}
+ | ---
+ | - error: Invalid key part count in an exact match (expected 1, got 2)
+ | ...
+
+hash:drop()
+ | ---
+ | ...
diff --git a/test/box/hash_32bit_select.test.lua b/test/box/hash_32bit_select.test.lua
new file mode 100644
index 000000000..e077cc48d
--- /dev/null
+++ b/test/box/hash_32bit_select.test.lua
@@ -0,0 +1,29 @@
+-------------------------------------------------------------------------------
+-- 32-bit hash insert fields tests
+-------------------------------------------------------------------------------
+hash = box.schema.space.create('tweedledum')
+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true })
+
+-- Insert valid fields
+hash:insert{0, 'value1 v1.0', 'value2 v1.0'}
+hash:insert{1, 'value1 v1.0', 'value2 v1.0'}
+hash:insert{2, 'value1 v1.0', 'value2 v1.0'}
+hash:insert{3, 'value1 v1.0', 'value2 v1.0'}
+
+-------------------------------------------------------------------------------
+-- 32-bit hash select fields test
+-------------------------------------------------------------------------------
+
+-- select by valid keys
+hash.index['primary']:get{0}
+hash.index['primary']:get{1}
+hash.index['primary']:get{2}
+hash.index['primary']:get{3}
+hash.index['primary']:get{4}
+hash.index['primary']:get{5}
+
+-- select by invalid keys
+hash.index['primary']:get{'invalid key'}
+hash.index['primary']:get{1, 2}
+
+hash:drop()
diff --git a/test/box/hash_64bit_delete.result b/test/box/hash_64bit_delete.result
new file mode 100644
index 000000000..88079e6f2
--- /dev/null
+++ b/test/box/hash_64bit_delete.result
@@ -0,0 +1,111 @@
+-- test-run result file version 2
+-------------------------------------------------------------------------------
+-- 64-bit hash insert fields tests
+-------------------------------------------------------------------------------
+hash = box.schema.space.create('tweedledum')
+ | ---
+ | ...
+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true })
+ | ---
+ | ...
+
+-- Insert valid fields
+hash:insert{0ULL, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [0, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{1ULL, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [1, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{2ULL, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [2, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{3ULL, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [3, 'value1 v1.0', 'value2 v1.0']
+ | ...
+
+-------------------------------------------------------------------------------
+-- 64-bit hash delete fields test
+-------------------------------------------------------------------------------
+
+-- delete by valid keys
+hash:delete{0ULL}
+ | ---
+ | - [0, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:delete{1ULL}
+ | ---
+ | - [1, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:delete{2ULL}
+ | ---
+ | - [2, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:delete{3ULL}
+ | ---
+ | - [3, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:delete{4ULL}
+ | ---
+ | ...
+hash:delete{5ULL}
+ | ---
+ | ...
+
+hash:insert{0ULL, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [0, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{1ULL, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [1, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{2ULL, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [2, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{3ULL, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [3, 'value1 v1.0', 'value2 v1.0']
+ | ...
+
+-- delete by valid NUM keys
+hash:delete{0}
+ | ---
+ | - [0, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:delete{1}
+ | ---
+ | - [1, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:delete{2}
+ | ---
+ | - [2, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:delete{3}
+ | ---
+ | - [3, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:delete{4}
+ | ---
+ | ...
+hash:delete{5}
+ | ---
+ | ...
+
+-- delete by invalid keys
+hash:delete{'invalid key'}
+ | ---
+ | - error: 'Supplied key type of part 0 does not match index part type: expected unsigned'
+ | ...
+hash:delete{'00000001', '00000002'}
+ | ---
+ | - error: Invalid key part count in an exact match (expected 1, got 2)
+ | ...
+
+hash:drop()
+ | ---
+ | ...
diff --git a/test/box/hash_64bit_delete.test.lua b/test/box/hash_64bit_delete.test.lua
new file mode 100644
index 000000000..75675381f
--- /dev/null
+++ b/test/box/hash_64bit_delete.test.lua
@@ -0,0 +1,42 @@
+-------------------------------------------------------------------------------
+-- 64-bit hash insert fields tests
+-------------------------------------------------------------------------------
+hash = box.schema.space.create('tweedledum')
+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true })
+
+-- Insert valid fields
+hash:insert{0ULL, 'value1 v1.0', 'value2 v1.0'}
+hash:insert{1ULL, 'value1 v1.0', 'value2 v1.0'}
+hash:insert{2ULL, 'value1 v1.0', 'value2 v1.0'}
+hash:insert{3ULL, 'value1 v1.0', 'value2 v1.0'}
+
+-------------------------------------------------------------------------------
+-- 64-bit hash delete fields test
+-------------------------------------------------------------------------------
+
+-- delete by valid keys
+hash:delete{0ULL}
+hash:delete{1ULL}
+hash:delete{2ULL}
+hash:delete{3ULL}
+hash:delete{4ULL}
+hash:delete{5ULL}
+
+hash:insert{0ULL, 'value1 v1.0', 'value2 v1.0'}
+hash:insert{1ULL, 'value1 v1.0', 'value2 v1.0'}
+hash:insert{2ULL, 'value1 v1.0', 'value2 v1.0'}
+hash:insert{3ULL, 'value1 v1.0', 'value2 v1.0'}
+
+-- delete by valid NUM keys
+hash:delete{0}
+hash:delete{1}
+hash:delete{2}
+hash:delete{3}
+hash:delete{4}
+hash:delete{5}
+
+-- delete by invalid keys
+hash:delete{'invalid key'}
+hash:delete{'00000001', '00000002'}
+
+hash:drop()
diff --git a/test/box/hash_64bit_insert.result b/test/box/hash_64bit_insert.result
new file mode 100644
index 000000000..3f1275576
--- /dev/null
+++ b/test/box/hash_64bit_insert.result
@@ -0,0 +1,54 @@
+-- test-run result file version 2
+-------------------------------------------------------------------------------
+-- 64-bit hash insert fields tests
+-------------------------------------------------------------------------------
+hash = box.schema.space.create('tweedledum')
+ | ---
+ | ...
+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true })
+ | ---
+ | ...
+
+-- Insert valid fields
+hash:insert{0ULL, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [0, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{1ULL, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [1, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{2ULL, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [2, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{3ULL, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [3, 'value1 v1.0', 'value2 v1.0']
+ | ...
+
+-- Insert invalid fields
+hash:insert{100, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [100, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{101, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [101, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{102, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [102, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{103, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [103, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{'invalid key', 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - error: 'Tuple field 1 type does not match one required by operation: expected unsigned'
+ | ...
+
+hash:drop()
+ | ---
+ | ...
diff --git a/test/box/hash_64bit_insert.test.lua b/test/box/hash_64bit_insert.test.lua
new file mode 100644
index 000000000..c69214b4e
--- /dev/null
+++ b/test/box/hash_64bit_insert.test.lua
@@ -0,0 +1,20 @@
+-------------------------------------------------------------------------------
+-- 64-bit hash insert fields tests
+-------------------------------------------------------------------------------
+hash = box.schema.space.create('tweedledum')
+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true })
+
+-- Insert valid fields
+hash:insert{0ULL, 'value1 v1.0', 'value2 v1.0'}
+hash:insert{1ULL, 'value1 v1.0', 'value2 v1.0'}
+hash:insert{2ULL, 'value1 v1.0', 'value2 v1.0'}
+hash:insert{3ULL, 'value1 v1.0', 'value2 v1.0'}
+
+-- Insert invalid fields
+hash:insert{100, 'value1 v1.0', 'value2 v1.0'}
+hash:insert{101, 'value1 v1.0', 'value2 v1.0'}
+hash:insert{102, 'value1 v1.0', 'value2 v1.0'}
+hash:insert{103, 'value1 v1.0', 'value2 v1.0'}
+hash:insert{'invalid key', 'value1 v1.0', 'value2 v1.0'}
+
+hash:drop()
diff --git a/test/box/hash_64bit_replace.result b/test/box/hash_64bit_replace.result
new file mode 100644
index 000000000..0bf900818
--- /dev/null
+++ b/test/box/hash_64bit_replace.result
@@ -0,0 +1,68 @@
+-- test-run result file version 2
+-------------------------------------------------------------------------------
+-- 64-bit hash insert fields tests
+-------------------------------------------------------------------------------
+hash = box.schema.space.create('tweedledum')
+ | ---
+ | ...
+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true })
+ | ---
+ | ...
+
+-- Insert valid fields
+hash:insert{0ULL, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [0, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{1ULL, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [1, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{2ULL, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [2, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{3ULL, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [3, 'value1 v1.0', 'value2 v1.0']
+ | ...
+
+-------------------------------------------------------------------------------
+-- 64-bit hash replace fields tests
+-------------------------------------------------------------------------------
+
+-- Replace valid fields
+hash:replace{3ULL, 'value1 v1.31', 'value2 1.12'}
+ | ---
+ | - [3, 'value1 v1.31', 'value2 1.12']
+ | ...
+hash:replace{1ULL, 'value1 v1.32', 'value2 1.72'}
+ | ---
+ | - [1, 'value1 v1.32', 'value2 1.72']
+ | ...
+hash:replace{2ULL, 'value1 v1.43', 'value2 1.92'}
+ | ---
+ | - [2, 'value1 v1.43', 'value2 1.92']
+ | ...
+
+-- Replace invalid fields
+hash:replace{3, 'value1 v1.31', 'value2 1.12'}
+ | ---
+ | - [3, 'value1 v1.31', 'value2 1.12']
+ | ...
+hash:replace{1, 'value1 v1.32', 'value2 1.72'}
+ | ---
+ | - [1, 'value1 v1.32', 'value2 1.72']
+ | ...
+hash:replace{2, 'value1 v1.43', 'value2 1.92'}
+ | ---
+ | - [2, 'value1 v1.43', 'value2 1.92']
+ | ...
+hash:replace{'invalid key', 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - error: 'Tuple field 1 type does not match one required by operation: expected unsigned'
+ | ...
+
+hash:drop()
+ | ---
+ | ...
diff --git a/test/box/hash_64bit_replace.test.lua b/test/box/hash_64bit_replace.test.lua
new file mode 100644
index 000000000..4213110bc
--- /dev/null
+++ b/test/box/hash_64bit_replace.test.lua
@@ -0,0 +1,28 @@
+-------------------------------------------------------------------------------
+-- 64-bit hash insert fields tests
+-------------------------------------------------------------------------------
+hash = box.schema.space.create('tweedledum')
+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true })
+
+-- Insert valid fields
+hash:insert{0ULL, 'value1 v1.0', 'value2 v1.0'}
+hash:insert{1ULL, 'value1 v1.0', 'value2 v1.0'}
+hash:insert{2ULL, 'value1 v1.0', 'value2 v1.0'}
+hash:insert{3ULL, 'value1 v1.0', 'value2 v1.0'}
+
+-------------------------------------------------------------------------------
+-- 64-bit hash replace fields tests
+-------------------------------------------------------------------------------
+
+-- Replace valid fields
+hash:replace{3ULL, 'value1 v1.31', 'value2 1.12'}
+hash:replace{1ULL, 'value1 v1.32', 'value2 1.72'}
+hash:replace{2ULL, 'value1 v1.43', 'value2 1.92'}
+
+-- Replace invalid fields
+hash:replace{3, 'value1 v1.31', 'value2 1.12'}
+hash:replace{1, 'value1 v1.32', 'value2 1.72'}
+hash:replace{2, 'value1 v1.43', 'value2 1.92'}
+hash:replace{'invalid key', 'value1 v1.0', 'value2 v1.0'}
+
+hash:drop()
diff --git a/test/box/hash_64bit_select.result b/test/box/hash_64bit_select.result
new file mode 100644
index 000000000..74dd56727
--- /dev/null
+++ b/test/box/hash_64bit_select.result
@@ -0,0 +1,94 @@
+-- test-run result file version 2
+-------------------------------------------------------------------------------
+-- 64-bit hash insert fields tests
+-------------------------------------------------------------------------------
+hash = box.schema.space.create('tweedledum')
+ | ---
+ | ...
+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true })
+ | ---
+ | ...
+
+-- Insert valid fields
+hash:insert{0ULL, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [0, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{1ULL, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [1, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{2ULL, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [2, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{3ULL, 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - [3, 'value1 v1.0', 'value2 v1.0']
+ | ...
+
+-------------------------------------------------------------------------------
+-- 64-bit hash select fields test
+-------------------------------------------------------------------------------
+
+-- select by valid keys
+hash.index['primary']:get{0ULL}
+ | ---
+ | - [0, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash.index['primary']:get{1ULL}
+ | ---
+ | - [1, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash.index['primary']:get{2ULL}
+ | ---
+ | - [2, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash.index['primary']:get{3ULL}
+ | ---
+ | - [3, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash.index['primary']:get{4ULL}
+ | ---
+ | ...
+hash.index['primary']:get{5ULL}
+ | ---
+ | ...
+
+-- select by valid NUM keys
+hash.index['primary']:get{0}
+ | ---
+ | - [0, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash.index['primary']:get{1}
+ | ---
+ | - [1, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash.index['primary']:get{2}
+ | ---
+ | - [2, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash.index['primary']:get{3}
+ | ---
+ | - [3, 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash.index['primary']:get{4}
+ | ---
+ | ...
+hash.index['primary']:get{5}
+ | ---
+ | ...
+
+-- select by invalid keys
+hash.index['primary']:get{'invalid key'}
+ | ---
+ | - error: 'Supplied key type of part 0 does not match index part type: expected unsigned'
+ | ...
+hash.index['primary']:get{'00000001', '00000002'}
+ | ---
+ | - error: Invalid key part count in an exact match (expected 1, got 2)
+ | ...
+
+hash:drop()
+ | ---
+ | ...
diff --git a/test/box/hash_64bit_select.test.lua b/test/box/hash_64bit_select.test.lua
new file mode 100644
index 000000000..724fb24be
--- /dev/null
+++ b/test/box/hash_64bit_select.test.lua
@@ -0,0 +1,37 @@
+-------------------------------------------------------------------------------
+-- 64-bit hash insert fields tests
+-------------------------------------------------------------------------------
+hash = box.schema.space.create('tweedledum')
+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true })
+
+-- Insert valid fields
+hash:insert{0ULL, 'value1 v1.0', 'value2 v1.0'}
+hash:insert{1ULL, 'value1 v1.0', 'value2 v1.0'}
+hash:insert{2ULL, 'value1 v1.0', 'value2 v1.0'}
+hash:insert{3ULL, 'value1 v1.0', 'value2 v1.0'}
+
+-------------------------------------------------------------------------------
+-- 64-bit hash select fields test
+-------------------------------------------------------------------------------
+
+-- select by valid keys
+hash.index['primary']:get{0ULL}
+hash.index['primary']:get{1ULL}
+hash.index['primary']:get{2ULL}
+hash.index['primary']:get{3ULL}
+hash.index['primary']:get{4ULL}
+hash.index['primary']:get{5ULL}
+
+-- select by valid NUM keys
+hash.index['primary']:get{0}
+hash.index['primary']:get{1}
+hash.index['primary']:get{2}
+hash.index['primary']:get{3}
+hash.index['primary']:get{4}
+hash.index['primary']:get{5}
+
+-- select by invalid keys
+hash.index['primary']:get{'invalid key'}
+hash.index['primary']:get{'00000001', '00000002'}
+
+hash:drop()
diff --git a/test/box/hash_collation.result b/test/box/hash_collation.result
new file mode 100644
index 000000000..ea80b577d
--- /dev/null
+++ b/test/box/hash_collation.result
@@ -0,0 +1,62 @@
+-- test-run result file version 2
+-------------------------------------------------------------------------------
+-- Collation test
+-------------------------------------------------------------------------------
+
+hash = box.schema.space.create('tweedledum')
+ | ---
+ | ...
+tmp = hash:create_index('primary', { type = 'hash', parts = {{1, 'string', collation = 'unicode_ci'}}, unique = true})
+ | ---
+ | ...
+tmp = hash:create_index('secondary', { type = 'hash', parts = {{2, 'scalar', collation = 'unicode_ci'}}, unique = true})
+ | ---
+ | ...
+
+hash:insert{'Ёж', 'Hedgehog'}
+ | ---
+ | - ['Ёж', 'Hedgehog']
+ | ...
+hash:insert{'Ёлка', 'Spruce'}
+ | ---
+ | - ['Ёлка', 'Spruce']
+ | ...
+hash:insert{'Jogurt', 'Йогурт'}
+ | ---
+ | - ['Jogurt', 'Йогурт']
+ | ...
+hash:insert{'Один', 1}
+ | ---
+ | - ['Один', 1]
+ | ...
+
+hash.index.primary:get('ёж')
+ | ---
+ | - ['Ёж', 'Hedgehog']
+ | ...
+hash.index.primary:get('елка')
+ | ---
+ | - ['Ёлка', 'Spruce']
+ | ...
+hash.index.secondary:get('spruce')
+ | ---
+ | - ['Ёлка', 'Spruce']
+ | ...
+hash.index.secondary:get('йогурт')
+ | ---
+ | - ['Jogurt', 'Йогурт']
+ | ...
+hash.index.secondary:get(1)
+ | ---
+ | - ['Один', 1]
+ | ...
+hash.index.secondary:get('иогурт')
+ | ---
+ | ...
+hash.index.secondary:get(2)
+ | ---
+ | ...
+
+hash:drop()
+ | ---
+ | ...
diff --git a/test/box/hash_collation.test.lua b/test/box/hash_collation.test.lua
new file mode 100644
index 000000000..f9bca79f6
--- /dev/null
+++ b/test/box/hash_collation.test.lua
@@ -0,0 +1,22 @@
+-------------------------------------------------------------------------------
+-- Collation test
+-------------------------------------------------------------------------------
+
+hash = box.schema.space.create('tweedledum')
+tmp = hash:create_index('primary', { type = 'hash', parts = {{1, 'string', collation = 'unicode_ci'}}, unique = true})
+tmp = hash:create_index('secondary', { type = 'hash', parts = {{2, 'scalar', collation = 'unicode_ci'}}, unique = true})
+
+hash:insert{'Ёж', 'Hedgehog'}
+hash:insert{'Ёлка', 'Spruce'}
+hash:insert{'Jogurt', 'Йогурт'}
+hash:insert{'Один', 1}
+
+hash.index.primary:get('ёж')
+hash.index.primary:get('елка')
+hash.index.secondary:get('spruce')
+hash.index.secondary:get('йогурт')
+hash.index.secondary:get(1)
+hash.index.secondary:get('иогурт')
+hash.index.secondary:get(2)
+
+hash:drop()
diff --git a/test/box/hash_gh-1467.result b/test/box/hash_gh-1467.result
new file mode 100644
index 000000000..a2c736a11
--- /dev/null
+++ b/test/box/hash_gh-1467.result
@@ -0,0 +1,17 @@
+-- test-run result file version 2
+-- gh-1467: invalid iterator type
+
+space = box.schema.space.create('test')
+ | ---
+ | ...
+index = space:create_index('primary', { type = 'hash' })
+ | ---
+ | ...
+space:select({1}, {iterator = 'BITS_ALL_SET' } )
+ | ---
+ | - error: Index 'primary' (HASH) of space 'test' (memtx) does not support requested
+ |     iterator type
+ | ...
+space:drop()
+ | ---
+ | ...
diff --git a/test/box/hash_gh-1467.test.lua b/test/box/hash_gh-1467.test.lua
new file mode 100644
index 000000000..d98c31734
--- /dev/null
+++ b/test/box/hash_gh-1467.test.lua
@@ -0,0 +1,6 @@
+-- gh-1467: invalid iterator type
+
+space = box.schema.space.create('test')
+index = space:create_index('primary', { type = 'hash' })
+space:select({1}, {iterator = 'BITS_ALL_SET' } )
+space:drop()
diff --git a/test/box/hash_gh-3907.result b/test/box/hash_gh-3907.result
new file mode 100644
index 000000000..4ce7e40f4
--- /dev/null
+++ b/test/box/hash_gh-3907.result
@@ -0,0 +1,48 @@
+-- test-run result file version 2
+-- gh-3907: check that integer numbers stored as MP_FLOAT/MP_DOUBLE
+-- are hashed as MP_INT/MP_UINT.
+
+ffi = require('ffi')
+ | ---
+ | ...
+s = box.schema.space.create('test')
+ | ---
+ | ...
+_ = s:create_index('primary', {type = 'hash', parts = {1, 'number'}})
+ | ---
+ | ...
+s:insert{ffi.new('double', 0)}
+ | ---
+ | - [0]
+ | ...
+s:insert{ffi.new('double', -1)}
+ | ---
+ | - [-1]
+ | ...
+s:insert{ffi.new('double', 9007199254740992)}
+ | ---
+ | - [9007199254740992]
+ | ...
+s:insert{ffi.new('double', -9007199254740994)}
+ | ---
+ | - [-9007199254740994]
+ | ...
+s:get(0LL)
+ | ---
+ | - [0]
+ | ...
+s:get(-1LL)
+ | ---
+ | - [-1]
+ | ...
+s:get(9007199254740992LL)
+ | ---
+ | - [9007199254740992]
+ | ...
+s:get(-9007199254740994LL)
+ | ---
+ | - [-9007199254740994]
+ | ...
+s:drop()
+ | ---
+ | ...
diff --git a/test/box/hash_gh-3907.test.lua b/test/box/hash_gh-3907.test.lua
new file mode 100644
index 000000000..2bef03b0d
--- /dev/null
+++ b/test/box/hash_gh-3907.test.lua
@@ -0,0 +1,15 @@
+-- gh-3907: check that integer numbers stored as MP_FLOAT/MP_DOUBLE
+-- are hashed as MP_INT/MP_UINT.
+
+ffi = require('ffi')
+s = box.schema.space.create('test')
+_ = s:create_index('primary', {type = 'hash', parts = {1, 'number'}})
+s:insert{ffi.new('double', 0)}
+s:insert{ffi.new('double', -1)}
+s:insert{ffi.new('double', 9007199254740992)}
+s:insert{ffi.new('double', -9007199254740994)}
+s:get(0LL)
+s:get(-1LL)
+s:get(9007199254740992LL)
+s:get(-9007199254740994LL)
+s:drop()
diff --git a/test/box/hash_gh-616.result b/test/box/hash_gh-616.result
new file mode 100644
index 000000000..d5ee1eed9
--- /dev/null
+++ b/test/box/hash_gh-616.result
@@ -0,0 +1,17 @@
+-- test-run result file version 2
+-- 
+-- gh-616 "1-based indexing and 0-based error message
+--
+_ = box.schema.create_space('test')
+ | ---
+ | ...
+_ = box.space.test:create_index('i',{parts={1,'string'}})
+ | ---
+ | ...
+box.space.test:insert{1}
+ | ---
+ | - error: 'Tuple field 1 type does not match one required by operation: expected string'
+ | ...
+box.space.test:drop()
+ | ---
+ | ...
diff --git a/test/box/hash_gh-616.test.lua b/test/box/hash_gh-616.test.lua
new file mode 100644
index 000000000..8ea5f725a
--- /dev/null
+++ b/test/box/hash_gh-616.test.lua
@@ -0,0 +1,7 @@
+-- 
+-- gh-616 "1-based indexing and 0-based error message
+--
+_ = box.schema.create_space('test')
+_ = box.space.test:create_index('i',{parts={1,'string'}})
+box.space.test:insert{1}
+box.space.test:drop()
diff --git a/test/box/hash_iterate.result b/test/box/hash_iterate.result
new file mode 100644
index 000000000..64660ad6d
--- /dev/null
+++ b/test/box/hash_iterate.result
@@ -0,0 +1,21 @@
+-- test-run result file version 2
+hash = box.schema.space.create('tweedledum')
+ | ---
+ | ...
+hi = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true })
+ | ---
+ | ...
+hash:insert{0}
+ | ---
+ | - [0]
+ | ...
+hash:insert{16}
+ | ---
+ | - [16]
+ | ...
+for _, tuple in hi:pairs(nil, {iterator = box.index.ALL}) do hash:delete{tuple[1]} end
+ | ---
+ | ...
+hash:drop()
+ | ---
+ | ...
diff --git a/test/box/hash_iterate.test.lua b/test/box/hash_iterate.test.lua
new file mode 100644
index 000000000..1ee758a66
--- /dev/null
+++ b/test/box/hash_iterate.test.lua
@@ -0,0 +1,6 @@
+hash = box.schema.space.create('tweedledum')
+hi = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true })
+hash:insert{0}
+hash:insert{16}
+for _, tuple in hi:pairs(nil, {iterator = box.index.ALL}) do hash:delete{tuple[1]} end
+hash:drop()
diff --git a/test/box/hash_multipart.result b/test/box/hash_multipart.result
index 3de8ee3be..e94313b62 100644
--- a/test/box/hash_multipart.result
+++ b/test/box/hash_multipart.result
@@ -131,13 +131,6 @@ hash.index['unique']:select{1, 'baz'}
 - error: 'Supplied key type of part 1 does not match index part type: expected unsigned'
 ...
 -- cleanup
-hash:truncate()
----
-...
-hash:len()
----
-- 0
-...
 hash:drop()
 ---
 ...
diff --git a/test/box/hash_multipart.test.lua b/test/box/hash_multipart.test.lua
index 8b40504b1..c0a871bee 100644
--- a/test/box/hash_multipart.test.lua
+++ b/test/box/hash_multipart.test.lua
@@ -53,6 +53,4 @@ hash.index['unique']:get{1}
 hash.index['unique']:select{1, 'baz'}
 
 -- cleanup
-hash:truncate()
-hash:len()
 hash:drop()
diff --git a/test/box/hash_not_a_multikey.result b/test/box/hash_not_a_multikey.result
new file mode 100644
index 000000000..334aa676d
--- /dev/null
+++ b/test/box/hash_not_a_multikey.result
@@ -0,0 +1,17 @@
+-- test-run result file version 2
+-- Hash index cannot be multikey.
+
+s = box.schema.space.create('test')
+ | ---
+ | ...
+_ = s:create_index('primary')
+ | ---
+ | ...
+_ = s:create_index('hash', {type = 'hash', parts = {{'[2][*]', 'unsigned'}}})
+ | ---
+ | - error: 'Can''t create or modify index ''hash'' in space ''test'': HASH index cannot
+ |     be multikey'
+ | ...
+s:drop()
+ | ---
+ | ...
diff --git a/test/box/hash_not_a_multikey.test.lua b/test/box/hash_not_a_multikey.test.lua
new file mode 100644
index 000000000..bd82dfb83
--- /dev/null
+++ b/test/box/hash_not_a_multikey.test.lua
@@ -0,0 +1,6 @@
+-- Hash index cannot be multikey.
+
+s = box.schema.space.create('test')
+_ = s:create_index('primary')
+_ = s:create_index('hash', {type = 'hash', parts = {{'[2][*]', 'unsigned'}}})
+s:drop()
diff --git a/test/box/hash_replace.result b/test/box/hash_replace.result
new file mode 100644
index 000000000..1b45f7914
--- /dev/null
+++ b/test/box/hash_replace.result
@@ -0,0 +1,256 @@
+-- test-run result file version 2
+------------------------
+-- hash::replace tests
+------------------------
+
+hash = box.schema.space.create('tweedledum')
+ | ---
+ | ...
+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true })
+ | ---
+ | ...
+tmp = hash:create_index('field1', { type = 'hash', parts = {2, 'unsigned'}, unique = true })
+ | ---
+ | ...
+tmp = hash:create_index('field2', { type = 'hash', parts = {3, 'unsigned'}, unique = true })
+ | ---
+ | ...
+tmp = hash:create_index('field3', { type = 'hash', parts = {4, 'unsigned'}, unique = true })
+ | ---
+ | ...
+
+hash:insert{0, 0, 0, 0}
+ | ---
+ | - [0, 0, 0, 0]
+ | ...
+hash:insert{1, 1, 1, 1}
+ | ---
+ | - [1, 1, 1, 1]
+ | ...
+hash:insert{2, 2, 2, 2}
+ | ---
+ | - [2, 2, 2, 2]
+ | ...
+
+-- OK
+hash:replace{1, 1, 1, 1}
+ | ---
+ | - [1, 1, 1, 1]
+ | ...
+hash.index['primary']:get{10}
+ | ---
+ | ...
+hash.index['field1']:get{10}
+ | ---
+ | ...
+hash.index['field2']:get{10}
+ | ---
+ | ...
+hash.index['field3']:get{10}
+ | ---
+ | ...
+hash.index['primary']:get{1}
+ | ---
+ | - [1, 1, 1, 1]
+ | ...
+hash.index['field1']:get{1}
+ | ---
+ | - [1, 1, 1, 1]
+ | ...
+hash.index['field2']:get{1}
+ | ---
+ | - [1, 1, 1, 1]
+ | ...
+hash.index['field3']:get{1}
+ | ---
+ | - [1, 1, 1, 1]
+ | ...
+
+-- OK
+hash:insert{10, 10, 10, 10}
+ | ---
+ | - [10, 10, 10, 10]
+ | ...
+hash:delete{10}
+ | ---
+ | - [10, 10, 10, 10]
+ | ...
+hash.index['primary']:get{10}
+ | ---
+ | ...
+hash.index['field1']:get{10}
+ | ---
+ | ...
+hash.index['field2']:get{10}
+ | ---
+ | ...
+hash.index['field3']:get{10}
+ | ---
+ | ...
+
+-- TupleFound (primary key)
+hash:insert{1, 10, 10, 10}
+ | ---
+ | - error: Duplicate key exists in unique index 'primary' in space 'tweedledum'
+ | ...
+hash.index['primary']:get{10}
+ | ---
+ | ...
+hash.index['field1']:get{10}
+ | ---
+ | ...
+hash.index['field2']:get{10}
+ | ---
+ | ...
+hash.index['field3']:get{10}
+ | ---
+ | ...
+hash.index['primary']:get{1}
+ | ---
+ | - [1, 1, 1, 1]
+ | ...
+
+-- TupleNotFound (primary key)
+hash:replace{10, 10, 10, 10}
+ | ---
+ | - [10, 10, 10, 10]
+ | ...
+hash.index['primary']:get{10}
+ | ---
+ | - [10, 10, 10, 10]
+ | ...
+hash.index['field1']:get{10}
+ | ---
+ | - [10, 10, 10, 10]
+ | ...
+hash.index['field2']:get{10}
+ | ---
+ | - [10, 10, 10, 10]
+ | ...
+hash.index['field3']:get{10}
+ | ---
+ | - [10, 10, 10, 10]
+ | ...
+
+-- TupleFound (key --1)
+hash:insert{10, 0, 10, 10}
+ | ---
+ | - error: Duplicate key exists in unique index 'primary' in space 'tweedledum'
+ | ...
+hash.index['primary']:get{10}
+ | ---
+ | - [10, 10, 10, 10]
+ | ...
+hash.index['field1']:get{10}
+ | ---
+ | - [10, 10, 10, 10]
+ | ...
+hash.index['field2']:get{10}
+ | ---
+ | - [10, 10, 10, 10]
+ | ...
+hash.index['field3']:get{10}
+ | ---
+ | - [10, 10, 10, 10]
+ | ...
+hash.index['field1']:get{0}
+ | ---
+ | - [0, 0, 0, 0]
+ | ...
+
+-- TupleFound (key --1)
+-- hash:replace_if_exists(2, 0, 10, 10)
+hash.index['primary']:get{10}
+ | ---
+ | - [10, 10, 10, 10]
+ | ...
+hash.index['field1']:get{10}
+ | ---
+ | - [10, 10, 10, 10]
+ | ...
+hash.index['field2']:get{10}
+ | ---
+ | - [10, 10, 10, 10]
+ | ...
+hash.index['field3']:get{10}
+ | ---
+ | - [10, 10, 10, 10]
+ | ...
+hash.index['field1']:get{0}
+ | ---
+ | - [0, 0, 0, 0]
+ | ...
+
+-- TupleFound (key --3)
+hash:insert{10, 10, 10, 0}
+ | ---
+ | - error: Duplicate key exists in unique index 'primary' in space 'tweedledum'
+ | ...
+hash.index['primary']:get{10}
+ | ---
+ | - [10, 10, 10, 10]
+ | ...
+hash.index['field1']:get{10}
+ | ---
+ | - [10, 10, 10, 10]
+ | ...
+hash.index['field2']:get{10}
+ | ---
+ | - [10, 10, 10, 10]
+ | ...
+hash.index['field3']:get{10}
+ | ---
+ | - [10, 10, 10, 10]
+ | ...
+hash.index['field3']:get{0}
+ | ---
+ | - [0, 0, 0, 0]
+ | ...
+
+-- TupleFound (key --3)
+-- hash:replace_if_exists(2, 10, 10, 0)
+hash.index['primary']:get{10}
+ | ---
+ | - [10, 10, 10, 10]
+ | ...
+hash.index['field1']:get{10}
+ | ---
+ | - [10, 10, 10, 10]
+ | ...
+hash.index['field2']:get{10}
+ | ---
+ | - [10, 10, 10, 10]
+ | ...
+hash.index['field3']:get{10}
+ | ---
+ | - [10, 10, 10, 10]
+ | ...
+hash.index['field3']:get{0}
+ | ---
+ | - [0, 0, 0, 0]
+ | ...
+
+hash:drop()
+ | ---
+ | ...
+
+hash = box.schema.space.create('tweedledum')
+ | ---
+ | ...
+hi = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true })
+ | ---
+ | ...
+hash:insert{0}
+ | ---
+ | - [0]
+ | ...
+hash:insert{16}
+ | ---
+ | - [16]
+ | ...
+for _, tuple in hi:pairs(nil, {iterator = box.index.ALL}) do hash:delete{tuple[1]} end
+ | ---
+ | ...
+hash:drop()
+ | ---
+ | ...
diff --git a/test/box/hash_replace.test.lua b/test/box/hash_replace.test.lua
new file mode 100644
index 000000000..d876f1f12
--- /dev/null
+++ b/test/box/hash_replace.test.lua
@@ -0,0 +1,88 @@
+------------------------
+-- hash::replace tests
+------------------------
+
+hash = box.schema.space.create('tweedledum')
+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true })
+tmp = hash:create_index('field1', { type = 'hash', parts = {2, 'unsigned'}, unique = true })
+tmp = hash:create_index('field2', { type = 'hash', parts = {3, 'unsigned'}, unique = true })
+tmp = hash:create_index('field3', { type = 'hash', parts = {4, 'unsigned'}, unique = true })
+
+hash:insert{0, 0, 0, 0}
+hash:insert{1, 1, 1, 1}
+hash:insert{2, 2, 2, 2}
+
+-- OK
+hash:replace{1, 1, 1, 1}
+hash.index['primary']:get{10}
+hash.index['field1']:get{10}
+hash.index['field2']:get{10}
+hash.index['field3']:get{10}
+hash.index['primary']:get{1}
+hash.index['field1']:get{1}
+hash.index['field2']:get{1}
+hash.index['field3']:get{1}
+
+-- OK
+hash:insert{10, 10, 10, 10}
+hash:delete{10}
+hash.index['primary']:get{10}
+hash.index['field1']:get{10}
+hash.index['field2']:get{10}
+hash.index['field3']:get{10}
+
+-- TupleFound (primary key)
+hash:insert{1, 10, 10, 10}
+hash.index['primary']:get{10}
+hash.index['field1']:get{10}
+hash.index['field2']:get{10}
+hash.index['field3']:get{10}
+hash.index['primary']:get{1}
+
+-- TupleNotFound (primary key)
+hash:replace{10, 10, 10, 10}
+hash.index['primary']:get{10}
+hash.index['field1']:get{10}
+hash.index['field2']:get{10}
+hash.index['field3']:get{10}
+
+-- TupleFound (key --1)
+hash:insert{10, 0, 10, 10}
+hash.index['primary']:get{10}
+hash.index['field1']:get{10}
+hash.index['field2']:get{10}
+hash.index['field3']:get{10}
+hash.index['field1']:get{0}
+
+-- TupleFound (key --1)
+-- hash:replace_if_exists(2, 0, 10, 10)
+hash.index['primary']:get{10}
+hash.index['field1']:get{10}
+hash.index['field2']:get{10}
+hash.index['field3']:get{10}
+hash.index['field1']:get{0}
+
+-- TupleFound (key --3)
+hash:insert{10, 10, 10, 0}
+hash.index['primary']:get{10}
+hash.index['field1']:get{10}
+hash.index['field2']:get{10}
+hash.index['field3']:get{10}
+hash.index['field3']:get{0}
+
+-- TupleFound (key --3)
+-- hash:replace_if_exists(2, 10, 10, 0)
+hash.index['primary']:get{10}
+hash.index['field1']:get{10}
+hash.index['field2']:get{10}
+hash.index['field3']:get{10}
+hash.index['field3']:get{0}
+
+hash:drop()
+
+hash = box.schema.space.create('tweedledum')
+hi = hash:create_index('primary', { type = 'hash', parts = {1, 'unsigned'}, unique = true })
+hash:insert{0}
+hash:insert{16}
+for _, tuple in hi:pairs(nil, {iterator = box.index.ALL}) do hash:delete{tuple[1]} end
+hash:drop()
diff --git a/test/box/hash_string_delete.result b/test/box/hash_string_delete.result
new file mode 100644
index 000000000..3458f3c68
--- /dev/null
+++ b/test/box/hash_string_delete.result
@@ -0,0 +1,62 @@
+-- test-run result file version 2
+hash = box.schema.space.create('tweedledum')
+ | ---
+ | ...
+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'string'}, unique = true })
+ | ---
+ | ...
+
+-- Insert valid fields
+hash:insert{'key 0', 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - ['key 0', 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{'key 1', 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - ['key 1', 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{'key 2', 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - ['key 2', 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{'key 3', 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - ['key 3', 'value1 v1.0', 'value2 v1.0']
+ | ...
+
+-------------------------------------------------------------------------------
+-- String hash delete fields test
+-------------------------------------------------------------------------------
+
+-- delete by valid keys
+hash:delete{'key 0'}
+ | ---
+ | - ['key 0', 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:delete{'key 1'}
+ | ---
+ | - ['key 1', 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:delete{'key 2'}
+ | ---
+ | - ['key 2', 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:delete{'key 3'}
+ | ---
+ | - ['key 3', 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:delete{'key 4'}
+ | ---
+ | ...
+hash:delete{'key 5'}
+ | ---
+ | ...
+
+-- delete by invalid keys
+hash:delete{'key 1', 'key 2'}
+ | ---
+ | - error: Invalid key part count in an exact match (expected 1, got 2)
+ | ...
+hash:drop()
+ | ---
+ | ...
diff --git a/test/box/hash_string_delete.test.lua b/test/box/hash_string_delete.test.lua
new file mode 100644
index 000000000..612217ec9
--- /dev/null
+++ b/test/box/hash_string_delete.test.lua
@@ -0,0 +1,24 @@
+hash = box.schema.space.create('tweedledum')
+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'string'}, unique = true })
+
+-- Insert valid fields
+hash:insert{'key 0', 'value1 v1.0', 'value2 v1.0'}
+hash:insert{'key 1', 'value1 v1.0', 'value2 v1.0'}
+hash:insert{'key 2', 'value1 v1.0', 'value2 v1.0'}
+hash:insert{'key 3', 'value1 v1.0', 'value2 v1.0'}
+
+-------------------------------------------------------------------------------
+-- String hash delete fields test
+-------------------------------------------------------------------------------
+
+-- delete by valid keys
+hash:delete{'key 0'}
+hash:delete{'key 1'}
+hash:delete{'key 2'}
+hash:delete{'key 3'}
+hash:delete{'key 4'}
+hash:delete{'key 5'}
+
+-- delete by invalid keys
+hash:delete{'key 1', 'key 2'}
+hash:drop()
diff --git a/test/box/hash_string_insert.result b/test/box/hash_string_insert.result
new file mode 100644
index 000000000..50a52b6a8
--- /dev/null
+++ b/test/box/hash_string_insert.result
@@ -0,0 +1,32 @@
+-- test-run result file version 2
+-------------------------------------------------------------------------------
+-- String hash inset fields tests
+-------------------------------------------------------------------------------
+hash = box.schema.space.create('tweedledum')
+ | ---
+ | ...
+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'string'}, unique = true })
+ | ---
+ | ...
+
+-- Insert valid fields
+hash:insert{'key 0', 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - ['key 0', 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{'key 1', 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - ['key 1', 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{'key 2', 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - ['key 2', 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{'key 3', 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - ['key 3', 'value1 v1.0', 'value2 v1.0']
+ | ...
+
+hash:drop()
+ | ---
+ | ...
diff --git a/test/box/hash_string_insert.test.lua b/test/box/hash_string_insert.test.lua
new file mode 100644
index 000000000..9788abc0d
--- /dev/null
+++ b/test/box/hash_string_insert.test.lua
@@ -0,0 +1,13 @@
+-------------------------------------------------------------------------------
+-- String hash inset fields tests
+-------------------------------------------------------------------------------
+hash = box.schema.space.create('tweedledum')
+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'string'}, unique = true })
+
+-- Insert valid fields
+hash:insert{'key 0', 'value1 v1.0', 'value2 v1.0'}
+hash:insert{'key 1', 'value1 v1.0', 'value2 v1.0'}
+hash:insert{'key 2', 'value1 v1.0', 'value2 v1.0'}
+hash:insert{'key 3', 'value1 v1.0', 'value2 v1.0'}
+
+hash:drop()
diff --git a/test/box/hash_string_replace.result b/test/box/hash_string_replace.result
new file mode 100644
index 000000000..1fb525d71
--- /dev/null
+++ b/test/box/hash_string_replace.result
@@ -0,0 +1,47 @@
+-- test-run result file version 2
+hash = box.schema.space.create('tweedledum')
+ | ---
+ | ...
+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'string'}, unique = true })
+ | ---
+ | ...
+
+-- Insert valid fields
+hash:insert{'key 0', 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - ['key 0', 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{'key 1', 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - ['key 1', 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{'key 2', 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - ['key 2', 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{'key 3', 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - ['key 3', 'value1 v1.0', 'value2 v1.0']
+ | ...
+
+-------------------------------------------------------------------------------
+-- String hash replace fields tests
+-------------------------------------------------------------------------------
+
+-- Replace valid fields
+hash:replace{'key 3', 'value1 v1.31', 'value2 1.12'}
+ | ---
+ | - ['key 3', 'value1 v1.31', 'value2 1.12']
+ | ...
+hash:replace{'key 1', 'value1 v1.32', 'value2 1.72'}
+ | ---
+ | - ['key 1', 'value1 v1.32', 'value2 1.72']
+ | ...
+hash:replace{'key 2', 'value1 v1.43', 'value2 1.92'}
+ | ---
+ | - ['key 2', 'value1 v1.43', 'value2 1.92']
+ | ...
+
+hash:drop()
+ | ---
+ | ...
diff --git a/test/box/hash_string_replace.test.lua b/test/box/hash_string_replace.test.lua
new file mode 100644
index 000000000..db5cfa93e
--- /dev/null
+++ b/test/box/hash_string_replace.test.lua
@@ -0,0 +1,19 @@
+hash = box.schema.space.create('tweedledum')
+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'string'}, unique = true })
+
+-- Insert valid fields
+hash:insert{'key 0', 'value1 v1.0', 'value2 v1.0'}
+hash:insert{'key 1', 'value1 v1.0', 'value2 v1.0'}
+hash:insert{'key 2', 'value1 v1.0', 'value2 v1.0'}
+hash:insert{'key 3', 'value1 v1.0', 'value2 v1.0'}
+
+-------------------------------------------------------------------------------
+-- String hash replace fields tests
+-------------------------------------------------------------------------------
+
+-- Replace valid fields
+hash:replace{'key 3', 'value1 v1.31', 'value2 1.12'}
+hash:replace{'key 1', 'value1 v1.32', 'value2 1.72'}
+hash:replace{'key 2', 'value1 v1.43', 'value2 1.92'}
+
+hash:drop()
diff --git a/test/box/hash_string_select.result b/test/box/hash_string_select.result
new file mode 100644
index 000000000..16cb22d3c
--- /dev/null
+++ b/test/box/hash_string_select.result
@@ -0,0 +1,63 @@
+-- test-run result file version 2
+hash = box.schema.space.create('tweedledum')
+ | ---
+ | ...
+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'string'}, unique = true })
+ | ---
+ | ...
+
+-- Insert valid fields
+hash:insert{'key 0', 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - ['key 0', 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{'key 1', 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - ['key 1', 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{'key 2', 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - ['key 2', 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash:insert{'key 3', 'value1 v1.0', 'value2 v1.0'}
+ | ---
+ | - ['key 3', 'value1 v1.0', 'value2 v1.0']
+ | ...
+
+-------------------------------------------------------------------------------
+-- String hash select fields test
+-------------------------------------------------------------------------------
+
+-- select by valid keys
+hash.index['primary']:get{'key 0'}
+ | ---
+ | - ['key 0', 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash.index['primary']:get{'key 1'}
+ | ---
+ | - ['key 1', 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash.index['primary']:get{'key 2'}
+ | ---
+ | - ['key 2', 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash.index['primary']:get{'key 3'}
+ | ---
+ | - ['key 3', 'value1 v1.0', 'value2 v1.0']
+ | ...
+hash.index['primary']:get{'key 4'}
+ | ---
+ | ...
+hash.index['primary']:get{'key 5'}
+ | ---
+ | ...
+
+-- select by invalid keys
+hash.index['primary']:get{'key 1', 'key 2'}
+ | ---
+ | - error: Invalid key part count in an exact match (expected 1, got 2)
+ | ...
+
+hash:drop()
+ | ---
+ | ...
diff --git a/test/box/hash_string_select.test.lua b/test/box/hash_string_select.test.lua
new file mode 100644
index 000000000..ef3f10018
--- /dev/null
+++ b/test/box/hash_string_select.test.lua
@@ -0,0 +1,25 @@
+hash = box.schema.space.create('tweedledum')
+tmp = hash:create_index('primary', { type = 'hash', parts = {1, 'string'}, unique = true })
+
+-- Insert valid fields
+hash:insert{'key 0', 'value1 v1.0', 'value2 v1.0'}
+hash:insert{'key 1', 'value1 v1.0', 'value2 v1.0'}
+hash:insert{'key 2', 'value1 v1.0', 'value2 v1.0'}
+hash:insert{'key 3', 'value1 v1.0', 'value2 v1.0'}
+
+-------------------------------------------------------------------------------
+-- String hash select fields test
+-------------------------------------------------------------------------------
+
+-- select by valid keys
+hash.index['primary']:get{'key 0'}
+hash.index['primary']:get{'key 1'}
+hash.index['primary']:get{'key 2'}
+hash.index['primary']:get{'key 3'}
+hash.index['primary']:get{'key 4'}
+hash.index['primary']:get{'key 5'}
+
+-- select by invalid keys
+hash.index['primary']:get{'key 1', 'key 2'}
+
+hash:drop()
diff --git a/test/box/hash_with_function.result b/test/box/hash_with_function.result
new file mode 100644
index 000000000..cac268281
--- /dev/null
+++ b/test/box/hash_with_function.result
@@ -0,0 +1,26 @@
+-- test-run result file version 2
+-- Hash index can not use function.
+
+s = box.schema.space.create('withdata')
+ | ---
+ | ...
+lua_code = [[function(tuple) return tuple[1] + tuple[2] end]]
+ | ---
+ | ...
+box.schema.func.create('s', {body = lua_code, is_deterministic = true, is_sandboxed = true})
+ | ---
+ | ...
+_ = s:create_index('pk')
+ | ---
+ | ...
+_ = s:create_index('idx', {type = 'hash', func = box.func.s.id, parts = {{1, 'unsigned'}}})
+ | ---
+ | - error: 'Can''t create or modify index ''idx'' in space ''withdata'': HASH index
+ |     can not use a function'
+ | ...
+s:drop()
+ | ---
+ | ...
+box.schema.func.drop('s')
+ | ---
+ | ...
diff --git a/test/box/hash_with_function.test.lua b/test/box/hash_with_function.test.lua
new file mode 100644
index 000000000..9653de68e
--- /dev/null
+++ b/test/box/hash_with_function.test.lua
@@ -0,0 +1,9 @@
+-- Hash index can not use function.
+
+s = box.schema.space.create('withdata')
+lua_code = [[function(tuple) return tuple[1] + tuple[2] end]]
+box.schema.func.create('s', {body = lua_code, is_deterministic = true, is_sandboxed = true})
+_ = s:create_index('pk')
+_ = s:create_index('idx', {type = 'hash', func = box.func.s.id, parts = {{1, 'unsigned'}}})
+s:drop()
+box.schema.func.drop('s')
-- 
2.23.0


-- 
sergeyb@

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2020-03-25  9:13 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-03-19 10:24 [Tarantool-patches] [PATCH v2] Split box/hash.test.lua to a set of small independent tests Sergey Bronnikov
2020-03-19 11:09 ` Oleg Piskunov
2020-03-19 14:22 ` Alexander Tikhonov
2020-03-19 21:31 ` Konstantin Osipov
2020-03-20  7:09   ` Sergey Bronnikov
2020-03-20  9:20     ` Konstantin Osipov
2020-03-25  9:13 ` Kirill Yukhin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox