From 6a293e685d27894bc99ea4c0c7312c81f099ca45 Mon Sep 17 00:00:00 2001 From: Chayim Date: Thu, 11 Nov 2021 12:38:27 +0200 Subject: Fixes to allow --redis-url to pass through all tests (#1700) --- tests/conftest.py | 18 ++++++++++++++++ tests/test_commands.py | 50 ++++++++++++++++++++++++++++++++----------- tests/test_connection_pool.py | 12 ++++++++++- tests/test_monitor.py | 15 ++++++++++++- tests/test_pubsub.py | 7 +++++- tests/test_scripting.py | 11 +++++++++- 6 files changed, 97 insertions(+), 16 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 0adec91..bb682f7 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -31,6 +31,12 @@ def pytest_addoption(parser): def _get_info(redis_url): client = redis.Redis.from_url(redis_url) info = client.info() + try: + client.execute_command("CONFIG SET maxmemory 5555555") + client.execute_command("CONFIG SET maxmemory 0") + info["enterprise"] = False + except redis.exceptions.ResponseError: + info["enterprise"] = True client.connection_pool.disconnect() return info @@ -42,6 +48,7 @@ def pytest_sessionstart(session): arch_bits = info["arch_bits"] REDIS_INFO["version"] = version REDIS_INFO["arch_bits"] = arch_bits + REDIS_INFO["enterprise"] = info["enterprise"] # module info, if the second redis is running try: @@ -92,6 +99,17 @@ def skip_ifmodversion_lt(min_version: str, module_name: str): raise AttributeError("No redis module named {}".format(module_name)) +def skip_if_redis_enterprise(func): + check = REDIS_INFO["enterprise"] is True + return pytest.mark.skipif(check, reason="Redis enterprise" + ) + + +def skip_ifnot_redis_enterprise(func): + check = REDIS_INFO["enterprise"] is False + return pytest.mark.skipif(check, reason="Redis enterprise") + + def _get_client(cls, request, single_connection_client=True, flushdb=True, from_url=None, **kwargs): diff --git a/tests/test_commands.py b/tests/test_commands.py index 330ba28..df561d4 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -13,6 +13,7 @@ from .conftest import ( _get_client, skip_if_server_version_gte, skip_if_server_version_lt, + skip_if_redis_enterprise, skip_unless_arch_bits, ) @@ -80,6 +81,7 @@ class TestRedisCommands: assert 'get' in commands @skip_if_server_version_lt("6.0.0") + @skip_if_redis_enterprise def test_acl_deluser(self, r, request): username = 'redis-py-user' @@ -104,6 +106,7 @@ class TestRedisCommands: assert r.acl_getuser(users[4]) is None @skip_if_server_version_lt("6.0.0") + @skip_if_redis_enterprise def test_acl_genpass(self, r): password = r.acl_genpass() assert isinstance(password, str) @@ -117,6 +120,7 @@ class TestRedisCommands: assert isinstance(password, str) @skip_if_server_version_lt("6.0.0") + @skip_if_redis_enterprise def test_acl_getuser_setuser(self, r, request): username = 'redis-py-user' @@ -210,6 +214,7 @@ class TestRedisCommands: assert len(res) != 0 @skip_if_server_version_lt("6.0.0") + @skip_if_redis_enterprise def test_acl_list(self, r, request): username = 'redis-py-user' @@ -222,6 +227,7 @@ class TestRedisCommands: assert len(users) == 2 @skip_if_server_version_lt("6.0.0") + @skip_if_redis_enterprise def test_acl_log(self, r, request): username = 'redis-py-user' @@ -257,6 +263,7 @@ class TestRedisCommands: assert r.acl_log_reset() @skip_if_server_version_lt("6.0.0") + @skip_if_redis_enterprise def test_acl_setuser_categories_without_prefix_fails(self, r, request): username = 'redis-py-user' @@ -268,6 +275,7 @@ class TestRedisCommands: r.acl_setuser(username, categories=['list']) @skip_if_server_version_lt("6.0.0") + @skip_if_redis_enterprise def test_acl_setuser_commands_without_prefix_fails(self, r, request): username = 'redis-py-user' @@ -279,6 +287,7 @@ class TestRedisCommands: r.acl_setuser(username, commands=['get']) @skip_if_server_version_lt("6.0.0") + @skip_if_redis_enterprise def test_acl_setuser_add_passwords_and_nopass_fails(self, r, request): username = 'redis-py-user' @@ -312,13 +321,18 @@ class TestRedisCommands: assert 'addr' in info @skip_if_server_version_lt('5.0.0') - def test_client_list_type(self, r): + def test_client_list_types_not_replica(self, r): with pytest.raises(exceptions.RedisError): r.client_list(_type='not a client type') - for client_type in ['normal', 'master', 'replica', 'pubsub']: + for client_type in ['normal', 'master', 'pubsub']: clients = r.client_list(_type=client_type) assert isinstance(clients, list) + @skip_if_redis_enterprise + def test_client_list_replica(self, r): + clients = r.client_list(_type='replica') + assert isinstance(clients, list) + @skip_if_server_version_lt('6.2.0') def test_client_list_client_id(self, r, request): clients = r.client_list() @@ -454,6 +468,7 @@ class TestRedisCommands: assert r.client_kill_filter(laddr=client_2_addr) @skip_if_server_version_lt('6.0.0') + @skip_if_redis_enterprise def test_client_kill_filter_by_user(self, r, request): killuser = 'user_to_kill' r.acl_setuser(killuser, enabled=True, reset=True, @@ -467,6 +482,7 @@ class TestRedisCommands: r.acl_deluser(killuser) @skip_if_server_version_lt('2.9.50') + @skip_if_redis_enterprise def test_client_pause(self, r): assert r.client_pause(1) assert r.client_pause(timeout=1) @@ -474,6 +490,7 @@ class TestRedisCommands: r.client_pause(timeout='not an integer') @skip_if_server_version_lt('6.2.0') + @skip_if_redis_enterprise def test_client_unpause(self, r): assert r.client_unpause() == b'OK' @@ -491,15 +508,18 @@ class TestRedisCommands: assert r.get('foo') == b'bar' @skip_if_server_version_lt('6.0.0') + @skip_if_redis_enterprise def test_client_getredir(self, r): assert isinstance(r.client_getredir(), int) assert r.client_getredir() == -1 def test_config_get(self, r): data = r.config_get() - assert 'maxmemory' in data - assert data['maxmemory'].isdigit() + assert len(data.keys()) > 10 + # # assert 'maxmemory' in data + # assert data['maxmemory'].isdigit() + @skip_if_redis_enterprise def test_config_resetstat(self, r): r.ping() prior_commands_processed = int(r.info()['total_commands_processed']) @@ -508,14 +528,12 @@ class TestRedisCommands: reset_commands_processed = int(r.info()['total_commands_processed']) assert reset_commands_processed < prior_commands_processed + @skip_if_redis_enterprise def test_config_set(self, r): - data = r.config_get() - rdbname = data['dbfilename'] - try: - assert r.config_set('dbfilename', 'redis_py_test.rdb') - assert r.config_get()['dbfilename'] == 'redis_py_test.rdb' - finally: - assert r.config_set('dbfilename', rdbname) + r.config_set('timeout', 70) + assert r.config_get()['timeout'] == '70' + assert r.config_set('timeout', 0) + assert r.config_get()['timeout'] == '0' def test_dbsize(self, r): r['a'] = 'foo' @@ -530,8 +548,10 @@ class TestRedisCommands: r['b'] = 'bar' info = r.info() assert isinstance(info, dict) - assert info['db9']['keys'] == 2 + assert 'arch_bits' in info.keys() + assert 'redis_version' in info.keys() + @skip_if_redis_enterprise def test_lastsave(self, r): assert isinstance(r.lastsave(), datetime.datetime) @@ -625,6 +645,7 @@ class TestRedisCommands: assert isinstance(t[0], int) assert isinstance(t[1], int) + @skip_if_redis_enterprise def test_bgsave(self, r): assert r.bgsave() time.sleep(0.3) @@ -2433,6 +2454,7 @@ class TestRedisCommands: 'slaves', 'nodeid'), dict) @skip_if_server_version_lt('3.0.0') + @skip_if_redis_enterprise def test_readwrite(self, r): assert r.readwrite() @@ -3614,6 +3636,7 @@ class TestRedisCommands: assert isinstance(r.memory_usage('foo'), int) @skip_if_server_version_lt('4.0.0') + @skip_if_redis_enterprise def test_module_list(self, r): assert isinstance(r.module_list(), list) for x in r.module_list(): @@ -3626,6 +3649,7 @@ class TestRedisCommands: assert res >= 100 @skip_if_server_version_lt('4.0.0') + @skip_if_redis_enterprise def test_module(self, r): with pytest.raises(redis.exceptions.ModuleError) as excinfo: r.module_load('/some/fake/path') @@ -3680,6 +3704,7 @@ class TestRedisCommands: assert r.get(key) == b'blee!' @skip_if_server_version_lt('5.0.0') + @skip_if_redis_enterprise def test_replicaof(self, r): with pytest.raises(redis.ResponseError): assert r.replicaof("NO ONE") @@ -3756,6 +3781,7 @@ class TestBinarySave: assert '6' in parsed['allocation_stats'] assert '>=256' in parsed['allocation_stats'] + @skip_if_redis_enterprise def test_large_responses(self, r): "The PythonParser has some special cases for return values > 1MB" # load up 5MB of data into a key diff --git a/tests/test_connection_pool.py b/tests/test_connection_pool.py index 6fedec6..521f520 100644 --- a/tests/test_connection_pool.py +++ b/tests/test_connection_pool.py @@ -7,7 +7,11 @@ from unittest import mock from threading import Thread from redis.connection import ssl_available, to_bool -from .conftest import skip_if_server_version_lt, _get_client +from .conftest import ( + skip_if_server_version_lt, + skip_if_redis_enterprise, + _get_client +) from .test_pubsub import wait_for_message @@ -481,6 +485,7 @@ class TestConnection: assert not pool._available_connections[0]._sock @skip_if_server_version_lt('2.8.8') + @skip_if_redis_enterprise def test_busy_loading_disconnects_socket(self, r): """ If Redis raises a LOADING error, the connection should be @@ -491,6 +496,7 @@ class TestConnection: assert not r.connection._sock @skip_if_server_version_lt('2.8.8') + @skip_if_redis_enterprise def test_busy_loading_from_pipeline_immediate_command(self, r): """ BusyLoadingErrors should raise from Pipelines that execute a @@ -506,6 +512,7 @@ class TestConnection: assert not pool._available_connections[0]._sock @skip_if_server_version_lt('2.8.8') + @skip_if_redis_enterprise def test_busy_loading_from_pipeline(self, r): """ BusyLoadingErrors should be raised from a pipeline execution @@ -521,6 +528,7 @@ class TestConnection: assert not pool._available_connections[0]._sock @skip_if_server_version_lt('2.8.8') + @skip_if_redis_enterprise def test_read_only_error(self, r): "READONLY errors get turned in ReadOnlyError exceptions" with pytest.raises(redis.ReadOnlyError): @@ -546,6 +554,7 @@ class TestConnection: 'path=/path/to/socket,db=0', ) + @skip_if_redis_enterprise def test_connect_no_auth_supplied_when_required(self, r): """ AuthenticationError should be raised when the server requires a @@ -555,6 +564,7 @@ class TestConnection: r.execute_command('DEBUG', 'ERROR', 'ERR Client sent AUTH, but no password is set') + @skip_if_redis_enterprise def test_connect_invalid_password_supplied(self, r): "AuthenticationError should be raised when sending the wrong password" with pytest.raises(redis.AuthenticationError): diff --git a/tests/test_monitor.py b/tests/test_monitor.py index bbb7fb7..a8a535b 100644 --- a/tests/test_monitor.py +++ b/tests/test_monitor.py @@ -1,4 +1,8 @@ -from .conftest import wait_for_command +from .conftest import ( + skip_if_redis_enterprise, + skip_ifnot_redis_enterprise, + wait_for_command +) class TestMonitor: @@ -40,6 +44,7 @@ class TestMonitor: response = wait_for_command(r, m, 'GET foo\\\\x92') assert response['command'] == 'GET foo\\\\x92' + @skip_if_redis_enterprise def test_lua_script(self, r): with r.monitor() as m: script = 'return redis.call("GET", "foo")' @@ -49,3 +54,11 @@ class TestMonitor: assert response['client_type'] == 'lua' assert response['client_address'] == 'lua' assert response['client_port'] == '' + + @skip_ifnot_redis_enterprise + def test_lua_script_in_enterprise(self, r): + with r.monitor() as m: + script = 'return redis.call("GET", "foo")' + assert r.eval(script, 0) is None + response = wait_for_command(r, m, 'GET foo') + assert response is None diff --git a/tests/test_pubsub.py b/tests/test_pubsub.py index cfc6e5e..e242459 100644 --- a/tests/test_pubsub.py +++ b/tests/test_pubsub.py @@ -7,7 +7,11 @@ import pytest import redis from redis.exceptions import ConnectionError -from .conftest import _get_client, skip_if_server_version_lt +from .conftest import ( + _get_client, + skip_if_redis_enterprise, + skip_if_server_version_lt +) def wait_for_message(pubsub, timeout=0.1, ignore_subscribe_messages=False): @@ -528,6 +532,7 @@ class TestPubSubPings: class TestPubSubConnectionKilled: @skip_if_server_version_lt('3.0.0') + @skip_if_redis_enterprise def test_connection_error_raised_when_connection_dies(self, r): p = r.pubsub() p.subscribe('foo') diff --git a/tests/test_scripting.py b/tests/test_scripting.py index c3c2094..352f3ba 100644 --- a/tests/test_scripting.py +++ b/tests/test_scripting.py @@ -2,6 +2,8 @@ import pytest from redis import exceptions +from tests.conftest import skip_if_server_version_lt + multiply_script = """ local value = redis.call('GET', KEYS[1]) @@ -30,7 +32,8 @@ class TestScripting: # 2 * 3 == 6 assert r.eval(multiply_script, 1, 'a', 3) == 6 - def test_script_flush(self, r): + @skip_if_server_version_lt('6.2.0') + def test_script_flush_620(self, r): r.set('a', 2) r.script_load(multiply_script) r.script_flush('ASYNC') @@ -43,6 +46,12 @@ class TestScripting: r.script_load(multiply_script) r.script_flush() + with pytest.raises(exceptions.DataError): + r.set('a', 2) + r.script_load(multiply_script) + r.script_flush("NOTREAL") + + def test_script_flush(self, r): r.set('a', 2) r.script_load(multiply_script) r.script_flush(None) -- cgit v1.2.1