-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Integration tests for commands, delete operations, expiry
Add test for bloom command arity, behavior and basic error Set up a base case for valkey bloom filter module Signed-off-by: Vanessa Tang <[email protected]> Set info of expansion to Null for NONSCALING mode Signed-off-by: Vanessa Tang <[email protected]> Add test for basic valkey command Signed-off-by: Vanessa Tang <[email protected]>
- Loading branch information
1 parent
f299216
commit 2b3aacc
Showing
6 changed files
with
225 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
import pytest | ||
from valkey_bloom_test_case import ValkeyBloomTestCaseBase | ||
from valkeytests.conftest import resource_port_tracker | ||
|
||
class TestBloomCommand(ValkeyBloomTestCaseBase): | ||
|
||
def verify_command_arity(self, command, expected_arity): | ||
command_info = self.client.execute_command('COMMAND', 'INFO', command) | ||
actual_arity = command_info.get(command).get('arity') | ||
assert actual_arity == expected_arity, f"Arity mismatch for command '{command}'" | ||
|
||
def test_bloom_command_arity(self): | ||
self.verify_command_arity('BF.EXISTS', -1) | ||
self.verify_command_arity('BF.ADD', -1) | ||
self.verify_command_arity('BF.MEXISTS', -1) | ||
self.verify_command_arity('BF.MADD', -1) | ||
self.verify_command_arity('BF.CARD', -1) | ||
self.verify_command_arity('BF.RESERVE', -1) | ||
self.verify_command_arity('BF.INFO', -1) | ||
self.verify_command_arity('BF.INSERT', -1) | ||
|
||
def test_bloom_command_error(self): | ||
basic_error_test_cases = [ | ||
# not found | ||
('BF.INFO TEST404', 'not found'), | ||
# incorrect syntax and argument usage | ||
('BF.ADDX TEST KEY', 'unknown command \'BF.ADDX\', with args beginning with: \'TEST\' \'KEY\' '), | ||
('BF.EXIST KEY', 'unknown command \'BF.EXIST\', with args beginning with: \'KEY\' '), | ||
('bf.reserv', 'unknown command \'bf.reserv\', with args beginning with: '), | ||
('bf.info key item', 'Invalid information value'), | ||
('bf.insert key CAPACITY 10000 ERROR 0.01 EXPANSION 0.99 NOCREATE NONSCALING ITEMS test1 test2 test3', 'Bad expansion'), | ||
('BF.INSERT KEY HELLO WORLD', 'wrong number of arguments for \'BF.INSERT\' command'), | ||
('BF.RESERVE KEY SSS SSS', 'bad error rate'), | ||
('BF.RESERVE KEY 0.01 SSS', 'bad capacity'), | ||
('BF.RESERVE KEY 0.01 0.01', 'bad capacity'), | ||
('BF.RESERVE KEY 0.01 -1', 'bad capacity'), | ||
('BF.RESERVE TT 0.01 1 NONSCALING EXPANSION 1', 'wrong number of arguments for \'BF.RESERVE\' command'), | ||
('BF.RESERVE bf 0.01 1000', 'item exists'), | ||
('BF.ADD bf_non 2', 'non scaling filter is full'), | ||
('BF.RESERVE TEST_CAP 0.50 0', '(capacity should be larger than 0)'), | ||
('BF.INSERT KEY error 2 ITEMS test1', '(0 < error rate range < 1)'), | ||
|
||
# wrong number of arguments | ||
('BF.ADD TEST', 'wrong number of arguments for \'BF.ADD\' command'), | ||
('BF.ADD', 'wrong number of arguments for \'BF.ADD\' command'), | ||
('BF.ADD HELLO TEST WORLD', 'wrong number of arguments for \'BF.ADD\' command'), | ||
('BF.CARD KEY ITEM', 'wrong number of arguments for \'BF.CARD\' command'), | ||
('bf.card', 'wrong number of arguments for \'BF.CARD\' command'), | ||
('BF.EXISTS', 'wrong number of arguments for \'BF.EXISTS\' command'), | ||
('bf.exists item', 'wrong number of arguments for \'BF.EXISTS\' command'), | ||
('bf.exists key item hello', 'wrong number of arguments for \'BF.EXISTS\' command'), | ||
('BF.INFO', 'wrong number of arguments for \'BF.INFO\' command'), | ||
('bf.info key capacity size', 'wrong number of arguments for \'BF.INFO\' command'), | ||
('BF.INSERT', 'wrong number of arguments for \'BF.INSERT\' command'), | ||
('BF.INSERT KEY', 'wrong number of arguments for \'BF.INSERT\' command'), | ||
('BF.INSERT KEY HELLO', 'wrong number of arguments for \'BF.INSERT\' command'), | ||
('BF.MADD', 'wrong number of arguments for \'BF.MADD\' command'), | ||
('BF.MADD KEY', 'wrong number of arguments for \'BF.MADD\' command'), | ||
('BF.MEXISTS', 'wrong number of arguments for \'BF.MEXISTS\' command'), | ||
('BF.MEXISTS INFO', 'wrong number of arguments for \'BF.MEXISTS\' command'), | ||
('BF.RESERVE', 'wrong number of arguments for \'BF.RESERVE\' command'), | ||
('BF.RESERVE KEY', 'wrong number of arguments for \'BF.RESERVE\' command'), | ||
('BF.RESERVE KEY SSS', 'wrong number of arguments for \'BF.RESERVE\' command'), | ||
('BF.RESERVE TT1 0.01 1 NONSCALING test1 test2 test3', 'wrong number of arguments for \'BF.RESERVE\' command'), | ||
] | ||
|
||
assert self.client.execute_command('FLUSHALL') | ||
assert self.client.info_obj().num_keys() == 0 | ||
assert self.client.execute_command('BF.ADD key item') == 1 | ||
assert self.client.execute_command('BF.RESERVE bf 0.01 1000') == b'OK' | ||
|
||
# non scaling filter | ||
assert self.client.execute_command('BF.RESERVE bf_non 0.01 2 NONSCALING') == b'OK' | ||
assert self.client.execute_command('BF.ADD bf_non 0') == 1 | ||
assert self.client.execute_command('BF.ADD bf_non 1') == 1 | ||
|
||
for test_case in basic_error_test_cases: | ||
cmd = test_case[0] | ||
expected_err_reply = test_case[1] | ||
self.verify_error_response(self.client, cmd, expected_err_reply) | ||
|
||
def test_bloom_command_behavior(self): | ||
basic_behavior_test_case = [ | ||
('BF.ADD key item', 1), | ||
('BF.ADD key item', 0), | ||
('BF.ADD key item1', 1), | ||
('BF.EXISTS key item', 1), | ||
('BF.EXISTS key item2', 0), | ||
('BF.MADD key item item2', [0, 1]), | ||
('BF.EXISTS key item', 1), | ||
('BF.EXISTS key item2', 1), | ||
('BF.EXISTS key item3', 0), | ||
('BF.MADD hello world1 world2 world3', [1, 1, 1]), | ||
('BF.MADD hello world1 world2 world3 world4', [0, 0, 0, 1]), | ||
('BF.MEXISTS hello world5', [0]), | ||
('BF.MADD hello world5', [1]), | ||
('BF.MEXISTS hello world5 world6 world7', [1, 0, 0]), | ||
('BF.INSERT TEST ITEMS ITEMS', [1]), | ||
('BF.INSERT TEST CAPACITY 1000 ITEMS ITEMS', [0]), | ||
('BF.INSERT TEST CAPACITY 200 error 0.99 ITEMS ITEMS ITEMS1 ITEMS2', [0, 1, 1]), | ||
('BF.INSERT TEST CAPACITY 300 ERROR 0.90 EXPANSION 1 ITEMS ITEMS FOO', [0, 1]), | ||
('BF.INSERT TEST ERROR 0.80 EXPANSION 3 NOCREATE items BOO', [1]), | ||
('BF.INSERT TEST ERROR 0.80 EXPANSION 1 NOCREATE NONSCALING items BOO', [0]), | ||
('BF.INFO TEST Capacity', 100), | ||
('BF.INFO TEST ITEMS', 5), | ||
('bf.info TEST expansion', 2), | ||
('BF.CARD key', 3), | ||
('BF.CARD hello', 5), | ||
('BF.CARD TEST', 5), | ||
('bf.card HELLO', 0), | ||
('BF.RESERVE bf 0.01 1000', b'OK'), | ||
('BF.RESERVE bf_exp 0.01 1000 EXPANSION 2', b'OK'), | ||
('BF.RESERVE bf_non 0.01 1000 NONSCALING', b'OK'), | ||
('bf.info bf_exp expansion', 2), | ||
('BF.INFO bf_non expansion', None), | ||
] | ||
|
||
assert self.client.execute_command('FLUSHALL') | ||
assert self.client.info_obj().num_keys() == 0 | ||
|
||
for test_case in basic_behavior_test_case: | ||
cmd = test_case[0] | ||
expected_result = test_case[1] | ||
self.verify_command_behavior_as_expected(self.client, cmd, expected_result) | ||
|
||
# test bf.info | ||
assert self.client.execute_command('BF.RESERVE BF_INFO 0.50 2000 NONSCALING') == b'OK' | ||
bf_info = self.client.execute_command('BF.INFO BF_INFO') | ||
capacity_index = bf_info.index(b'Capacity') + 1 | ||
filter_index = bf_info.index(b'Number of filters') + 1 | ||
item_index = bf_info.index(b'Number of items inserted') + 1 | ||
expansion_index = bf_info.index(b'Expansion rate') + 1 | ||
assert bf_info[capacity_index] == self.client.execute_command('BF.INFO BF_INFO CAPACITY') == 2000 | ||
assert bf_info[filter_index] == self.client.execute_command('BF.INFO BF_INFO FILTERS') == 1 | ||
assert bf_info[item_index] == self.client.execute_command('BF.INFO BF_INFO ITEMS') == 0 | ||
assert bf_info[expansion_index] == self.client.execute_command('BF.INFO BF_INFO EXPANSION') == None |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import os | ||
import pytest | ||
from valkeytests.valkey_test_case import ValkeyTestCase | ||
from valkey import ResponseError | ||
|
||
class ValkeyBloomTestCaseBase(ValkeyTestCase): | ||
|
||
def get_custom_args(self): | ||
self.set_server_version(os.environ['SERVER_VERSION']) | ||
return { | ||
'loadmodule': os.getenv('MODULE_PATH'), | ||
} | ||
|
||
def verify_error_response(self, client, cmd, expected_err_reply): | ||
try: | ||
client.execute_command(cmd) | ||
assert False | ||
except ResponseError as e: | ||
assert_error_msg = f"Actual error message: '{str(e)}' is different from expected error message '{expected_err_reply}'" | ||
assert str(e) == expected_err_reply, assert_error_msg | ||
|
||
def verify_command_behavior_as_expected(self, client, cmd, expected_result): | ||
try: | ||
cmd_actual_result = client.execute_command(cmd) | ||
assert_error_msg = f"Actual command response '{cmd_actual_result}' is different from expected response '{expected_result}'" | ||
assert cmd_actual_result == expected_result, assert_error_msg | ||
except: | ||
print("Something went wrong in command behavior verification") |