diff options
Diffstat (limited to 'tests')
-rw-r--r-- | tests/conftest.py | 17 | ||||
-rw-r--r-- | tests/test_ssl.py | 61 |
2 files changed, 77 insertions, 1 deletions
diff --git a/tests/conftest.py b/tests/conftest.py index 4b5f6cb..0149166 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -14,8 +14,10 @@ from redis.retry import Retry REDIS_INFO = {} default_redis_url = "redis://localhost:6379/9" - default_redismod_url = "redis://localhost:36379" + +# default ssl client ignores verification for the purpose of testing +default_redis_ssl_url = "rediss://localhost:6666" default_cluster_nodes = 6 @@ -37,6 +39,13 @@ def pytest_addoption(parser): ) parser.addoption( + "--redis-ssl-url", + default=default_redis_ssl_url, + action="store", + help="Redis SSL connection string," " defaults to `%(default)s`", + ) + + parser.addoption( "--redis-cluster-nodes", default=default_cluster_nodes, action="store", @@ -248,6 +257,12 @@ def r2(request): yield client +@pytest.fixture() +def sslclient(request): + with _get_client(redis.Redis, request, ssl=True) as client: + yield client + + def _gen_cluster_mock_resp(r, response): connection = Mock() connection.retry = Retry(NoBackoff(), 0) diff --git a/tests/test_ssl.py b/tests/test_ssl.py new file mode 100644 index 0000000..70f9e58 --- /dev/null +++ b/tests/test_ssl.py @@ -0,0 +1,61 @@ +import os +from urllib.parse import urlparse + +import pytest + +import redis +from redis.exceptions import ConnectionError + + +@pytest.mark.ssl +class TestSSL: + """Tests for SSL connections + + This relies on the --redis-ssl-url purely for rebuilding the client + and connecting to the appropriate port. + """ + + ROOT = os.path.join(os.path.dirname(__file__), "..") + CERT_DIR = os.path.abspath(os.path.join(ROOT, "docker", "stunnel", "keys")) + if not os.path.isdir(CERT_DIR): # github actions package validation case + CERT_DIR = os.path.abspath( + os.path.join(ROOT, "..", "docker", "stunnel", "keys") + ) + if not os.path.isdir(CERT_DIR): + raise IOError(f"No SSL certificates found. They should be in {CERT_DIR}") + + def test_ssl_with_invalid_cert(self, request): + ssl_url = request.config.option.redis_ssl_url + sslclient = redis.from_url(ssl_url) + with pytest.raises(ConnectionError) as e: + sslclient.ping() + assert "SSL: CERTIFICATE_VERIFY_FAILED" in str(e) + + def test_ssl_connection(self, request): + ssl_url = request.config.option.redis_ssl_url + p = urlparse(ssl_url)[1].split(":") + r = redis.Redis(host=p[0], port=p[1], ssl=True, ssl_cert_reqs="none") + assert r.ping() + + def test_ssl_connection_without_ssl(self, request): + ssl_url = request.config.option.redis_ssl_url + p = urlparse(ssl_url)[1].split(":") + r = redis.Redis(host=p[0], port=p[1], ssl=False) + + with pytest.raises(ConnectionError) as e: + r.ping() + assert "Connection closed by server" in str(e) + + def test_validating_self_signed_certificate(self, request): + ssl_url = request.config.option.redis_ssl_url + p = urlparse(ssl_url)[1].split(":") + r = redis.Redis( + host=p[0], + port=p[1], + ssl=True, + ssl_certfile=os.path.join(self.CERT_DIR, "server-cert.pem"), + ssl_keyfile=os.path.join(self.CERT_DIR, "server-key.pem"), + ssl_cert_reqs="required", + ssl_ca_certs=os.path.join(self.CERT_DIR, "server-cert.pem"), + ) + assert r.ping() |