def test_tuple(self, score_db, args, value_type, expected_value): test_tuple = tuple([1, 2, 3, self.ADDRESS]) ContainerUtil.put_to_db(score_db, 'test_tuple', test_tuple) assert ContainerUtil.get_from_db( score_db, 'test_tuple', args, value_type=value_type) == expected_value
def test_fail_container(self): testlist = [[]] ContainerUtil.put_to_db(self.db, 'test_list', testlist) self.assertEqual( ContainerUtil.get_from_db(self.db, 'test_list', 1, value_type=int), 0)
def test_var_db(self, context, key_value_db, old_value, new_value, value_type): context_db = ContextDatabase(key_value_db, is_shared=False) address = Address(AddressPrefix.CONTRACT, os.urandom(20)) score_db = IconScoreDatabase(address, context_db) self._init_context(context, address) self._set_revision(context, Revision.USE_RLP.value - 1) name = "var_db" var_db = VarDB(name, score_db, value_type) var_db.set(old_value) assert var_db.get() == old_value key = _get_final_key(address, ContainerTag.VAR, name.encode(), use_rlp=False) assert key_value_db.get(key) == ContainerUtil.encode_value(old_value) self._set_revision(context, Revision.USE_RLP.value) assert key_value_db.get(key) == ContainerUtil.encode_value(old_value) var_db.set(new_value) assert var_db.get() == new_value assert var_db.get() != old_value key = _get_final_key(address, ContainerTag.VAR, name.encode(), use_rlp=True) assert key_value_db.get(key) == ContainerUtil.encode_value(new_value) var_db.remove() assert var_db.get() == get_default_value(value_type) assert len(key_value_db) == 0
def test_default_val_db(self): test_dict = {1: 'a', 2: ['a', 'b', ['c', 'd']], 3: {'a': 1}} ContainerUtil.put_to_db(self.db, 'test_dict', test_dict) # dict_db self.assertEqual(ContainerUtil.get_from_db(self.db, 'test_dict', 3, 'b', value_type=int), 0) self.assertEqual(ContainerUtil.get_from_db(self.db, 'test_dict', 3, 'c', value_type=str), "") self.assertEqual(ContainerUtil.get_from_db(self.db, 'test_dict', 3, 'c', value_type=bytes), None) self.assertEqual(ContainerUtil.get_from_db(self.db, 'test_dict', 3, 'c', value_type=Address), None) # list_db self.assertEqual(ContainerUtil.get_from_db(self.db, 'test_dict', 2, 3, value_type=str), '') self.assertEqual(ContainerUtil.get_from_db(self.db, 'test_dict', 2, 3, value_type=int), 0) self.assertEqual(ContainerUtil.get_from_db(self.db, 'test_dict', 2, 3, value_type=bytes), None) self.assertEqual(ContainerUtil.get_from_db(self.db, 'test_dict', 2, 3, value_type=Address), None) # var_db test_var = VarDB('test_var', self.db, value_type=int) self.assertEqual(test_var.get(), 0) test_var2 = VarDB('test_var2', self.db, value_type=str) self.assertEqual(test_var2.get(), "") test_var3 = VarDB('test_var3', self.db, value_type=bytes) self.assertEqual(test_var3.get(), None) test_var4 = VarDB('test_var4', self.db, value_type=Address) self.assertEqual(test_var4.get(), None)
def test_container_util(self): prefix: bytes = ContainerUtil.create_db_prefix(ArrayDB, 'a') self.assertEqual(b'\x00|a', prefix) prefix: bytes = ContainerUtil.create_db_prefix(DictDB, 'dictdb') self.assertEqual(b'\x01|dictdb', prefix) with self.assertRaises(InvalidParamsException): prefix: bytes = ContainerUtil.create_db_prefix(VarDB, 'vardb')
def test_default_value_of_container_db(self, score_db, value_type, expected_value, collection, key_or_index): # TEST: Check the default value of collection object (dict, list) ContainerUtil.put_to_db(score_db, 'test_collection', collection) actual_value = ContainerUtil.get_from_db(score_db, 'test_collection', key_or_index, value_type=value_type) assert actual_value == expected_value
def test_nested_list(self, score_db, args, value_type, expected_value): test_list = [1, 2, 3, [4, 5, 6], [7, 8, 9, [10, 11, 12]], self.ADDRESS] ContainerUtil.put_to_db(score_db, 'test_list', test_list) if isinstance(args, tuple): assert ContainerUtil.get_from_db( score_db, 'test_list', *args, value_type=value_type) == expected_value else: assert ContainerUtil.get_from_db( score_db, 'test_list', args, value_type=value_type) == expected_value
def test_success_dict(self): addr1 = create_address(AddressPrefix.CONTRACT) test_dict = {1: 'a', 2: ['a', 'b', ['c', 'd']], 3: {'a': 1}, 4: addr1} ContainerUtil.put_to_db(self.db, 'test_dict', test_dict) self.assertEqual(ContainerUtil.get_from_db(self.db, 'test_dict', 1, value_type=str), 'a') self.assertEqual(ContainerUtil.get_from_db(self.db, 'test_dict', 2, 0, value_type=str), 'a') self.assertEqual(ContainerUtil.get_from_db(self.db, 'test_dict', 2, 1, value_type=str), 'b') self.assertEqual(ContainerUtil.get_from_db(self.db, 'test_dict', 2, 2, 0, value_type=str), 'c') self.assertEqual(ContainerUtil.get_from_db(self.db, 'test_dict', 2, 2, 1, value_type=str), 'd') self.assertEqual(ContainerUtil.get_from_db(self.db, 'test_dict', 3, 'a', value_type=int), 1) self.assertEqual(ContainerUtil.get_from_db(self.db, 'test_dict', 4, value_type=Address), addr1)
def test_score_db(self, context, key_value_db, prefixes, old_values, new_values): context_db = ContextDatabase(key_value_db, is_shared=False) score_address = Address(AddressPrefix.CONTRACT, os.urandom(20)) score_db = IconScoreDatabase(score_address, context_db) args = [score_address] self._init_context(context, score_address) self._set_revision(context, Revision.USE_RLP.value - 1) for prefix in prefixes: score_db = score_db.get_sub_db(prefix) args.append(prefix) for i, value in enumerate(old_values): key: bytes = f"key{i}".encode() encoded_value: bytes = ContainerUtil.encode_value(value) score_db.put(key, encoded_value) assert score_db.get(key) == encoded_value final_key: bytes = _get_final_key(*args, key, use_rlp=False) assert key_value_db.get(final_key) == encoded_value self._set_revision(context, Revision.USE_RLP.value) for i, value in enumerate(old_values): key: bytes = f"key{i}".encode() encoded_value: bytes = ContainerUtil.encode_value(value) assert score_db.get(key) == encoded_value final_key: bytes = _get_final_key(*args, key, use_rlp=False) assert key_value_db.get(final_key) == encoded_value for i, value in enumerate(new_values): key: bytes = f"key{i}".encode() encoded_value: bytes = ContainerUtil.encode_value(value) score_db.put(key, encoded_value) assert score_db.get(key) == encoded_value final_key: bytes = _get_final_key(*args, key, use_rlp=True) assert key_value_db.get(final_key) == encoded_value score_db.delete(key) assert score_db.get(key) is None assert key_value_db.get(final_key) is None
def test_nested_dict(self, score_db, args, value_type, expected_value): test_dict = { 1: 'a', 2: ['a', 'b', ['c', 'd']], 3: { 'a': 1 }, 4: self.ADDRESS } ContainerUtil.put_to_db(score_db, 'test_dict', test_dict) if isinstance(args, tuple): assert ContainerUtil.get_from_db( score_db, 'test_dict', *args, value_type=value_type) == expected_value else: assert ContainerUtil.get_from_db( score_db, 'test_dict', args, value_type=value_type) == expected_value
def test_success_dict_depth1(self): name = 'test_dict' test_dict = DictDB(name, self.db, value_type=int) prefix: bytes = ContainerUtil.create_db_prefix(DictDB, name) self.assertEqual(b'\x01|' + name.encode(), prefix) test_dict['a'] = 1 test_dict['b'] = 2 self.assertEqual(test_dict['a'], 1)
def test_success_dict_other_Key(self): name = 'test_dict' test_dict = DictDB(name, self.db, depth=2, value_type=int) prefix: bytes = ContainerUtil.create_db_prefix(DictDB, name) self.assertEqual(b'\x01|' + name.encode(), prefix) addr1 = create_address(1) addr2 = create_address(0) test_dict['a'][addr1] = 1 test_dict['a'][addr2] = 2 self.assertEqual(test_dict['a'][addr1], 1) self.assertEqual(test_dict['a'][addr2], 2)
def test_1_depth_dict_db(self, context, key_value_db, keys, old_values, new_values, value_type): context_db = ContextDatabase(key_value_db, is_shared=False) score_address = Address(AddressPrefix.CONTRACT, os.urandom(20)) score_db = IconScoreDatabase(score_address, context_db) self._init_context(context, score_address) self._set_revision(context, Revision.USE_RLP.value - 1) name = "dict_db_depth_1" dict_db = DictDB(name, score_db, depth=1, value_type=value_type) # Put two items to dict_db for i in range(2): k, v = keys[i], old_values[i] dict_db[k] = v assert dict_db[k] == v key = _get_final_key( score_address, ContainerTag.DICT, name.encode(), ContainerUtil.encode_key(k), use_rlp=False ) assert key_value_db.get(key) == ContainerUtil.encode_value(v) self._set_revision(context, Revision.USE_RLP.value) # Read old-formatted data on Revision.USE_RLP for i in range(2): k, v = keys[i], old_values[i] assert dict_db[k] == v key = _get_final_key( score_address, ContainerTag.DICT, name.encode(), ContainerUtil.encode_key(k), use_rlp=False ) assert key_value_db.get(key) == ContainerUtil.encode_value(v) # Put 4 items to dict_db for i, k in enumerate(keys): old_v = old_values[i] new_v = new_values[i] dict_db[k] = new_v assert dict_db[k] == new_v assert dict_db[k] != old_v key = _get_final_key( score_address, ContainerTag.DICT, name.encode(), ContainerUtil.encode_key(k), use_rlp=True ) assert key_value_db.get(key) == ContainerUtil.encode_value(new_v) # If there is no value for a given key, default value is returned for k in keys: del dict_db[k] assert dict_db[k] == get_default_value(value_type) assert len(key_value_db) == 0
def test_success_tuple(self): addr1 = create_address(AddressPrefix.CONTRACT) test_tuple = tuple([1, 2, 3, addr1]) ContainerUtil.put_to_db(self.db, 'test_tuple', test_tuple) self.assertEqual(ContainerUtil.get_from_db(self.db, 'test_tuple', 0, value_type=int), 1) self.assertEqual(ContainerUtil.get_from_db(self.db, 'test_tuple', 1, value_type=int), 2) self.assertEqual(ContainerUtil.get_from_db(self.db, 'test_tuple', 2, value_type=int), 3) self.assertEqual(ContainerUtil.get_from_db(self.db, 'test_tuple', 3, value_type=Address), addr1)
def test_array_db(self): name = "TEST" testarray = ArrayDB(name, self.db, value_type=int) self.assertNotEqual(testarray._db, self.db) self.assertEqual(testarray._db._prefix, ContainerUtil.create_db_prefix(ArrayDB, name)) testarray.put(1) testarray.put(3) testarray.put(5) testarray.put(7) self.assertEqual(4, len(testarray)) self.assertEqual(7, testarray.pop()) self.assertEqual(5, testarray.pop()) self.assertEqual(2, len(testarray))
def test_array_db(self, score_db): name = "TEST" testarray = ArrayDB(name, score_db, value_type=int) assert testarray._db != score_db assert testarray._db._prefix == ContainerUtil.create_db_prefix( ArrayDB, name) testarray.put(1) testarray.put(3) testarray.put(5) testarray.put(7) assert len(testarray) == 4 assert testarray.pop() == 7 assert testarray.pop() == 5 assert len(testarray) == 2
def test_array_db2(self): name = "TEST" testarray = ArrayDB(name, self.db, value_type=int) self.assertNotEqual(testarray._db, self.db) self.assertEqual( testarray._db._prefix, ContainerUtil.create_db_prefix(ArrayDB, name)) testarray.put(1) testarray.put(2) testarray.put(3) testarray.put(4) self.assertEqual(1, testarray[0]) self.assertEqual(2, testarray[1]) self.assertEqual(3, testarray[2]) self.assertEqual(4, testarray[3]) self.assertEqual(4, testarray[-1]) self.assertEqual(3, testarray[-2]) self.assertEqual(2, testarray[-3]) self.assertEqual(1, testarray[-4]) testarray[0] = 5 testarray[1] = 6 testarray[2] = 7 testarray[3] = 8 self.assertEqual(5, testarray[0]) self.assertEqual(6, testarray[1]) self.assertEqual(7, testarray[2]) self.assertEqual(8, testarray[3]) testarray[-1] = 4 testarray[-2] = 3 testarray[-3] = 2 testarray[-4] = 1 self.assertEqual(4, testarray[-1]) self.assertEqual(3, testarray[-2]) self.assertEqual(2, testarray[-3]) self.assertEqual(1, testarray[-4]) with self.assertRaises(ContainerDBException): testarray[5] = 1 a = testarray[5]
def test_array_db2(self, score_db): name = "TEST" testarray = ArrayDB(name, score_db, value_type=int) assert testarray._db != score_db assert testarray._db._prefix == ContainerUtil.create_db_prefix( ArrayDB, name) testarray.put(1) testarray.put(2) testarray.put(3) testarray.put(4) assert testarray[0] == 1 assert testarray[1] == 2 assert testarray[2] == 3 assert testarray[3] == 4 assert testarray[-1] == 4 assert testarray[-2] == 3 assert testarray[-3] == 2 assert testarray[-4] == 1 testarray[0] = 5 testarray[1] = 6 testarray[2] = 7 testarray[3] = 8 assert testarray[0] == 5 assert testarray[1] == 6 assert testarray[2] == 7 assert testarray[3] == 8 testarray[-1] = 4 testarray[-2] = 3 testarray[-3] = 2 testarray[-4] = 1 assert testarray[-1] == 4 assert testarray[-2] == 3 assert testarray[-3] == 2 assert testarray[-4] == 1 with pytest.raises(InvalidParamsException): testarray[5] = 1 a = testarray[5]
def test_array_db(self, context, key_value_db, values, value_type): context_db = ContextDatabase(key_value_db, is_shared=False) address = Address(AddressPrefix.CONTRACT, os.urandom(20)) score_db = IconScoreDatabase(address, context_db) self._init_context(context, score_db.address) self._set_revision(context, Revision.USE_RLP.value - 1) name = "array_db" array_db = ArrayDB(name, score_db, value_type) for i in range(2): array_db.put(values[i]) assert len(array_db) == 2 self._set_revision(context, Revision.USE_RLP.value) array_db.put(values[2]) array_db.put(values[3]) assert len(array_db) == 4 for i, value in enumerate(array_db): assert value == values[i] final_key: bytes = _get_final_key(address, ContainerTag.ARRAY, name.encode(), use_rlp=True) assert key_value_db.get(final_key) == int_to_bytes(len(array_db)) for i, use_rlp in enumerate((False, False, True, True)): key = _get_final_key( address.to_bytes(), ContainerTag.ARRAY.value, name.encode(), int_to_bytes(i), use_rlp=use_rlp, ) assert key_value_db.get(key) == ContainerUtil.encode_value(values[i]) for v in reversed(values): assert v == array_db.pop() assert len(array_db) == 0 # 2 values for array_db size still remain # even though all items in array_db have been popped. assert len(key_value_db) == 2
def test_success_list(self): addr1 = create_address(AddressPrefix.CONTRACT) test_list = [1, 2, 3, [4, 5, 6], [7, 8, 9, [10, 11, 12]], addr1] ContainerUtil.put_to_db(self.db, 'test_list', test_list) self.assertEqual( ContainerUtil.get_from_db(self.db, 'test_list', 0, value_type=int), 1) self.assertEqual( ContainerUtil.get_from_db(self.db, 'test_list', 1, value_type=int), 2) self.assertEqual( ContainerUtil.get_from_db(self.db, 'test_list', 2, value_type=int), 3) self.assertEqual( ContainerUtil.get_from_db(self.db, 'test_list', 3, 0, value_type=int), 4) self.assertEqual( ContainerUtil.get_from_db(self.db, 'test_list', 3, 1, value_type=int), 5) self.assertEqual( ContainerUtil.get_from_db(self.db, 'test_list', 3, 2, value_type=int), 6) self.assertEqual( ContainerUtil.get_from_db(self.db, 'test_list', 4, 0, value_type=int), 7) self.assertEqual( ContainerUtil.get_from_db(self.db, 'test_list', 4, 1, value_type=int), 8) self.assertEqual( ContainerUtil.get_from_db(self.db, 'test_list', 4, 2, value_type=int), 9) self.assertEqual( ContainerUtil.get_from_db(self.db, 'test_list', 4, 3, 0, value_type=int), 10) self.assertEqual( ContainerUtil.get_from_db(self.db, 'test_list', 4, 3, 1, value_type=int), 11) self.assertEqual( ContainerUtil.get_from_db(self.db, 'test_list', 4, 3, 2, value_type=int), 12) self.assertEqual( ContainerUtil.get_from_db(self.db, 'test_list', 5, value_type=Address), addr1)
def test_2_depth_dict_db(self, context, key_value_db, keys1, keys2, old_values, new_values, value_type): context_db = ContextDatabase(key_value_db, is_shared=False) score_address = Address(AddressPrefix.CONTRACT, os.urandom(20)) score_db = IconScoreDatabase(score_address, context_db) self._init_context(context, score_address) self._set_revision(context, Revision.USE_RLP.value - 1) name = "dict_db_depth_2" dict_db = DictDB(name, score_db, depth=2, value_type=value_type) # To assign a value to middle-layer dict_db is forbidden for k1, v in zip(keys1, old_values): with pytest.raises(InvalidContainerAccessException): dict_db[k1] = v # Assign values to dict_db on Revision.USE_RLP - 1 for k1 in keys1: for k2, v in zip(keys2, old_values): dict_db[k1][k2] = v assert len(key_value_db) == len(keys1) * len(keys2) for k1 in keys1: for k2, v in zip(keys2, old_values): assert dict_db[k1][k2] == v key: bytes = _get_final_key( score_address, ContainerTag.DICT, name.encode(), ContainerTag.DICT, ContainerUtil.encode_key(k1), ContainerUtil.encode_key(k2), use_rlp=False ) assert key_value_db.get(key) == ContainerUtil.encode_value(v) self._set_revision(context, Revision.USE_RLP.value) # Check if reading old-formatted key:value data works on Revision.USE_RLP for k1 in keys1: for k2, v in zip(keys2, old_values): assert dict_db[k1][k2] == v # Replace all old_values with new_values on Revision.USE_RLP for k1 in keys1: for k2, v in zip(keys2, new_values): dict_db[k1][k2] = v # old_values + new_values assert len(key_value_db) == len(keys1) * len(keys2) * 2 for k1 in keys1: for k2, v in zip(keys2, new_values): assert dict_db[k1][k2] == v key: bytes = _get_final_key( score_address, ContainerTag.DICT, name.encode(), ContainerUtil.encode_key(k1), ContainerUtil.encode_key(k2), use_rlp=True ) assert key_value_db.get(key) == ContainerUtil.encode_value(v) for k1 in keys1: for k2 in keys2: del dict_db[k1][k2] assert dict_db[k1][k2] == get_default_value(value_type) assert len(key_value_db) == 0
def test_container_util(self, prefix, score_db_cls, expected_prefix): actual_prefix: bytes = ContainerUtil.create_db_prefix( score_db_cls, prefix) assert actual_prefix == expected_prefix
def _check_the_db_prefix_format(name): prefix: bytes = ContainerUtil.create_db_prefix(DictDB, name) assert prefix == b'\x01|' + name.encode()
def test_when_create_var_db_prefix_using_container_util_should_raise_error( self): with pytest.raises(InvalidParamsException): ContainerUtil.create_db_prefix(VarDB, 'vardb')