From d4f4440d7fcf54e9e7d501e21926809ba0dcf524 Mon Sep 17 00:00:00 2001 From: Erik Olof Gunnar Andersson Date: Sat, 1 May 2021 17:43:15 -0700 Subject: [PATCH 1/3] Improved Travis CI - Added scripts to run tests locally with RabbitMQ running in a Docker container. - SSL certs generated on the fly inside the container. --- .travis.yml | 17 +++-- amqpstorm/connection.py | 2 +- amqpstorm/tests/__init__.py | 51 ++++++++++--- .../tests/functional/ssl/reliability_tests.py | 72 ++++++++++++++++--- .../tests/resources/{cacert.pem => ca.pem} | 0 amqpstorm/tests/resources/ssl/.empty | 0 amqpstorm/uri_connection.py | 2 +- docker/Dockerfile | 13 ++++ docker/generate-certs | 26 +++++++ docker/openssl.cnf | 54 ++++++++++++++ docker/rabbitmq.conf | 22 ++++++ docker/wait-for-rabbitmq | 3 + examples/ssl_with_context.py | 2 +- run_ci_locally.sh | 26 +++++++ 14 files changed, 260 insertions(+), 30 deletions(-) rename amqpstorm/tests/resources/{cacert.pem => ca.pem} (100%) create mode 100644 amqpstorm/tests/resources/ssl/.empty create mode 100644 docker/Dockerfile create mode 100755 docker/generate-certs create mode 100644 docker/openssl.cnf create mode 100644 docker/rabbitmq.conf create mode 100755 docker/wait-for-rabbitmq create mode 100755 run_ci_locally.sh diff --git a/.travis.yml b/.travis.yml index 60658348..96e3230f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,12 +11,17 @@ python: - 3.8 - 3.9 before_install: - - docker pull eandersson86/amqpstorm-rabbitmq-ci:latest - - docker run -d --hostname rmq.eandersson.net --name travis-rmq -p 5671:5671 -p 5672:5672 -p 15672:15672 eandersson86/amqpstorm-rabbitmq-ci:latest - - sleep 15s - - nc -zv localhost 5671 - - nc -zv localhost 5672 - - nc -zv localhost 15672 + - docker build -t rabbitmqdev ./docker/ + - docker run -d --hostname rmq.eandersson.net --name rabbitmqdev -p 5671:5671 -p 5672:5672 -p 15671:15671 -p 15672:15672 rabbitmqdev + - docker cp rabbitmqdev:/etc/rabbitmq/ssl/ ./amqpstorm/tests/resources/ + - docker exec rabbitmqdev wait-for-rabbitmq + - docker exec rabbitmqdev rabbitmqctl add_user 'eandersson' '2a55f70a841f18b' + - docker exec rabbitmqdev rabbitmqctl -p / set_permissions 'eandersson' '.*' '.*' '.*' + - docker exec rabbitmqdev rabbitmqctl set_user_tags eandersson administrator + - nc -zv rmq.eandersson.net 5671 || exit 1 + - nc -zv rmq.eandersson.net 5672 || exit 1 + - nc -zv rmq.eandersson.net 15671 || exit 1 + - nc -zv rmq.eandersson.net 15672 || exit 1 install: - pip install -r requirements.txt - pip install -r test-requirements.txt diff --git a/amqpstorm/connection.py b/amqpstorm/connection.py index a1cad599..2e60f056 100644 --- a/amqpstorm/connection.py +++ b/amqpstorm/connection.py @@ -42,7 +42,7 @@ class Connection(Stateful): import ssl import amqpstorm ssl_options = { - 'context': ssl.create_default_context(cafile='cacert.pem'), + 'context': ssl.create_default_context(cafile='ca_certificate.pem'), 'server_hostname': 'rmq.eandersson.net', 'check_hostname': True, # New 2.8.0, default is False 'verify_mode': 'required', # New 2.8.0, default is 'none' diff --git a/amqpstorm/tests/__init__.py b/amqpstorm/tests/__init__.py index c1325434..00ac15fc 100644 --- a/amqpstorm/tests/__init__.py +++ b/amqpstorm/tests/__init__.py @@ -2,14 +2,43 @@ CURRENT_DIR = os.path.dirname(os.path.realpath(__file__)) -HOST = os.environ.get('AMQP_HOST', '127.0.0.1') -USERNAME = os.environ.get('AMQP_USERNAME', 'guest') -PASSWORD = os.environ.get('AMQP_PASSWORD', 'guest') -URI = os.environ.get('AMQP_URI', 'amqp://guest:guest@127.0.0.1:5672/%2F') -HTTP_URL = os.environ.get('AMQP_HTTP_URL', 'http://127.0.0.1:15672') - -SSL_URI = os.environ.get('AMQP_SSL_URI', - 'amqps://guest:guest@rmq.eandersson.net:5671/%2F') -SSL_HOST = os.environ.get('AMQP_SSL_HOST', 'rmq.eandersson.net') -CAFILE = os.environ.get('AMQP_CAFILE', - '{0}/resources/cacert.pem'.format(CURRENT_DIR)) +HOST = os.environ.get( + 'AMQP_HOST', + 'rmq.eandersson.net' +) +USERNAME = os.environ.get( + 'AMQP_USERNAME', + 'eandersson' +) +PASSWORD = os.environ.get( + 'AMQP_PASSWORD', + '2a55f70a841f18b' +) +URI = os.environ.get( + 'AMQP_URI', + 'amqp://eandersson:2a55f70a841f18b@rmq.eandersson.net:5672/%2F' +) +HTTP_URL = os.environ.get( + 'AMQP_HTTP_URL', + 'http://rmq.eandersson.net:15672' +) +SSL_URI = os.environ.get( + 'AMQP_SSL_URI', + 'amqps://eandersson:2a55f70a841f18b@rmq.eandersson.net:5671/%2F' +) +SSL_HOST = os.environ.get( + 'AMQP_SSL_HOST', + 'rmq.eandersson.net' +) +CAFILE = os.environ.get( + 'AMQP_CAFILE', + '{0}/resources/ssl/ca_certificate.pem'.format(CURRENT_DIR) +) +CERTFILE = os.environ.get( + 'AMQP_CERTFILE', + '{0}/resources/ssl/client/client_certificate.pem'.format(CURRENT_DIR) +) +KEYFILE = os.environ.get( + 'AMQP_KEYFILE', + '{0}/resources/ssl/client/private_key.pem'.format(CURRENT_DIR) +) diff --git a/amqpstorm/tests/functional/ssl/reliability_tests.py b/amqpstorm/tests/functional/ssl/reliability_tests.py index 552808e6..cb1e651c 100644 --- a/amqpstorm/tests/functional/ssl/reliability_tests.py +++ b/amqpstorm/tests/functional/ssl/reliability_tests.py @@ -5,6 +5,8 @@ from amqpstorm import Connection from amqpstorm import UriConnection from amqpstorm.tests import CAFILE +from amqpstorm.tests import CERTFILE +from amqpstorm.tests import KEYFILE from amqpstorm.tests import PASSWORD from amqpstorm.tests import SSL_HOST from amqpstorm.tests import SSL_URI @@ -16,8 +18,13 @@ class SSLReliabilityFunctionalTests(TestFunctionalFramework): @setup(new_connection=False, queue=True) def test_functional_ssl_open_new_connection_loop(self): + context = ssl.create_default_context(cafile=CAFILE) + context.load_cert_chain( + certfile=CERTFILE, + keyfile=KEYFILE, + ) ssl_options = { - 'context': ssl.create_default_context(cafile=CAFILE), + 'context': context, 'server_hostname': SSL_HOST } @@ -49,8 +56,13 @@ def test_functional_ssl_open_new_connection_loop(self): @setup(new_connection=False, queue=True) def test_functional_ssl_open_close_connection_loop(self): + context = ssl.create_default_context(cafile=CAFILE) + context.load_cert_chain( + certfile=CERTFILE, + keyfile=KEYFILE, + ) ssl_options = { - 'context': ssl.create_default_context(cafile=CAFILE), + 'context': context, 'server_hostname': SSL_HOST } self.connection = self.connection = Connection( @@ -84,11 +96,16 @@ def test_functional_ssl_open_close_connection_loop(self): @setup(new_connection=False, queue=False) def test_functional_ssl_open_close_channel_loop(self): + context = ssl.create_default_context(cafile=CAFILE) + context.load_cert_chain( + certfile=CERTFILE, + keyfile=KEYFILE, + ) ssl_options = { - 'context': ssl.create_default_context(cafile=CAFILE), + 'context': context, 'server_hostname': SSL_HOST } - self.connection = self.connection = Connection( + self.connection = Connection( SSL_HOST, USERNAME, PASSWORD, port=5671, ssl=True, ssl_options=ssl_options) @@ -110,8 +127,13 @@ def test_functional_ssl_open_close_channel_loop(self): @setup(new_connection=False, queue=True) def test_functional_ssl_open_multiple_channels(self): + context = ssl.create_default_context(cafile=CAFILE) + context.load_cert_chain( + certfile=CERTFILE, + keyfile=KEYFILE, + ) ssl_options = { - 'context': ssl.create_default_context(cafile=CAFILE), + 'context': context, 'server_hostname': SSL_HOST } self.connection = self.connection = Connection( @@ -137,8 +159,13 @@ def test_functional_ssl_close_performance(self): :return: """ for _ in range(10): + context = ssl.create_default_context(cafile=CAFILE) + context.load_cert_chain( + certfile=CERTFILE, + keyfile=KEYFILE, + ) ssl_options = { - 'context': ssl.create_default_context(cafile=CAFILE), + 'context': context, 'server_hostname': SSL_HOST } self.connection = self.connection = Connection( @@ -151,14 +178,29 @@ def test_functional_ssl_close_performance(self): @setup(new_connection=False) def test_functional_ssl_uri_connection(self): - self.connection = UriConnection(SSL_URI) + context = ssl.create_default_context(cafile=CAFILE) + context.load_cert_chain( + certfile=CERTFILE, + keyfile=KEYFILE, + ) + ssl_options = { + 'context': context, + 'server_hostname': SSL_HOST + } + + self.connection = UriConnection(SSL_URI, ssl_options=ssl_options) self.channel = self.connection.channel() self.assertTrue(self.connection.is_open) @setup(new_connection=False) def test_functional_ssl_uri_connection_with_context(self): + context = ssl.create_default_context(cafile=CAFILE) + context.load_cert_chain( + certfile=CERTFILE, + keyfile=KEYFILE, + ) ssl_options = { - 'context': ssl.create_default_context(cafile=CAFILE), + 'context': context, 'server_hostname': SSL_HOST } @@ -197,8 +239,13 @@ def increment_message_count(self): @setup(new_connection=False, queue=False) def test_functional_publish_1k_with_ssl(self): + context = ssl.create_default_context(cafile=CAFILE) + context.load_cert_chain( + certfile=CERTFILE, + keyfile=KEYFILE, + ) ssl_options = { - 'context': ssl.create_default_context(cafile=CAFILE), + 'context': context, 'server_hostname': SSL_HOST } self.connection = self.connection = Connection( @@ -244,8 +291,13 @@ def publish_messages(self): @setup(new_connection=False, queue=True) def test_functional_consume_with_ssl_until_empty(self): + context = ssl.create_default_context(cafile=CAFILE) + context.load_cert_chain( + certfile=CERTFILE, + keyfile=KEYFILE, + ) ssl_options = { - 'context': ssl.create_default_context(cafile=CAFILE), + 'context': context, 'server_hostname': SSL_HOST } self.connection = self.connection = Connection( diff --git a/amqpstorm/tests/resources/cacert.pem b/amqpstorm/tests/resources/ca.pem similarity index 100% rename from amqpstorm/tests/resources/cacert.pem rename to amqpstorm/tests/resources/ca.pem diff --git a/amqpstorm/tests/resources/ssl/.empty b/amqpstorm/tests/resources/ssl/.empty new file mode 100644 index 00000000..e69de29b diff --git a/amqpstorm/uri_connection.py b/amqpstorm/uri_connection.py index 39bfdd75..10ca836e 100644 --- a/amqpstorm/uri_connection.py +++ b/amqpstorm/uri_connection.py @@ -31,7 +31,7 @@ class UriConnection(Connection): import ssl import amqpstorm ssl_options = { - 'context': ssl.create_default_context(cafile='cacert.pem'), + 'context': ssl.create_default_context(cafile='ca_certificate.pem'), 'server_hostname': 'rmq.eandersson.net' } connection = amqpstorm.UriConnection( diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 00000000..881a5410 --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,13 @@ +FROM rabbitmq:management-alpine +RUN apk --update add openssl + +env RABBITMQ_USE_LONGNAME=true +RUN mkdir -p /etc/rabbitmq/ssl/ + +COPY rabbitmq.conf /etc/rabbitmq/rabbitmq.conf +COPY wait-for-rabbitmq /bin/wait-for-rabbitmq +COPY generate-certs /etc/rabbitmq/ssl/generate-certs +COPY openssl.cnf /etc/rabbitmq/ssl/openssl.cnf + +RUN /etc/rabbitmq/ssl/generate-certs && \ + chown -R rabbitmq.rabbitmq /etc/rabbitmq/ssl/* diff --git a/docker/generate-certs b/docker/generate-certs new file mode 100755 index 00000000..a059b0e3 --- /dev/null +++ b/docker/generate-certs @@ -0,0 +1,26 @@ +#!/bin/bash +mkdir -p /etc/rabbitmq/ssl/certs +mkdir -p /etc/rabbitmq/ssl/client +mkdir -p /etc/rabbitmq/ssl/private +mkdir -p /etc/rabbitmq/ssl/server + +echo 01 > /etc/rabbitmq/ssl/serial +touch /etc/rabbitmq/ssl/index.txt + +cd /etc/rabbitmq/ssl/ +openssl req -x509 -config openssl.cnf -newkey rsa:4096 -days 365 -out ca_certificate.pem -outform PEM -subj /CN=rmq.eandersson.net/ -nodes +openssl x509 -in ca_certificate.pem -out ca_certificate.cer -outform DER + +cd /etc/rabbitmq/ssl/server +openssl genrsa -out private_key.pem 4096 +openssl req -new -key private_key.pem -out req.pem -outform PEM -subj /CN=rmq.eandersson.net/O=server/ -nodes + +cd /etc/rabbitmq/ssl/ +openssl ca -config openssl.cnf -in server/req.pem -out server/server_certificate.pem -notext -batch -extensions server_ca_extensions + +cd /etc/rabbitmq/ssl/client +openssl genrsa -out private_key.pem 4096 +openssl req -new -key private_key.pem -out req.pem -outform PEM -subj /CN=rmq.eandersson.net/O=client/ -nodes + +cd /etc/rabbitmq/ssl/ +openssl ca -config openssl.cnf -in client/req.pem -out client/client_certificate.pem -notext -batch -extensions client_ca_extensions diff --git a/docker/openssl.cnf b/docker/openssl.cnf new file mode 100644 index 00000000..88e0c86e --- /dev/null +++ b/docker/openssl.cnf @@ -0,0 +1,54 @@ +[ ca ] +default_ca = testca + +[ testca ] +dir = /etc/rabbitmq/ssl +certificate = $dir/ca_certificate.pem +database = $dir/index.txt +new_certs_dir = $dir/certs +private_key = $dir/private/ca_private_key.pem +serial = $dir/serial + +default_crl_days = 7 +default_days = 365 +default_md = sha512 + +policy = testca_policy +x509_extensions = certificate_extensions + +[ testca_policy ] +commonName = supplied +stateOrProvinceName = optional +countryName = optional +emailAddress = optional +organizationName = optional +organizationalUnitName = optional +domainComponent = optional + +[ certificate_extensions ] +basicConstraints = CA:false + +[ req ] +default_bits = 4096 +default_keyfile = ./private/ca_private_key.pem +default_md = sha512 +prompt = yes +distinguished_name = root_ca_distinguished_name +x509_extensions = root_ca_extensions + +[ root_ca_distinguished_name ] +commonName = hostname + +[ root_ca_extensions ] +basicConstraints = CA:true +keyUsage = keyCertSign, cRLSign + +[ client_ca_extensions ] +basicConstraints = CA:false +keyUsage = digitalSignature,keyEncipherment +extendedKeyUsage = 1.3.6.1.5.5.7.3.2 + +[ server_ca_extensions ] +basicConstraints = CA:false +keyUsage = digitalSignature,keyEncipherment +extendedKeyUsage = 1.3.6.1.5.5.7.3.1 diff --git a/docker/rabbitmq.conf b/docker/rabbitmq.conf new file mode 100644 index 00000000..3593f71a --- /dev/null +++ b/docker/rabbitmq.conf @@ -0,0 +1,22 @@ +log.console = true +log.console.level = debug +log.connection.level = debug + +listeners.ssl.default = 5671 +listeners.tcp.default = 5672 + +ssl_options.cacertfile = /etc/rabbitmq/ssl/ca_certificate.pem +ssl_options.certfile = /etc/rabbitmq/ssl/server/server_certificate.pem +ssl_options.keyfile = /etc/rabbitmq/ssl/server/private_key.pem +ssl_options.verify = verify_peer +ssl_options.fail_if_no_peer_cert = true + +ssl_options.versions.1 = tlsv1.3 + +management.tcp.port = 15672 +management.ssl.port = 15671 +management.ssl.cacertfile = /etc/rabbitmq/ssl/ca_certificate.pem +management.ssl.certfile = /etc/rabbitmq/ssl/server/server_certificate.pem +management.ssl.keyfile = /etc/rabbitmq/ssl/server/private_key.pem + +management.ssl.versions.1 = tlsv1.3 diff --git a/docker/wait-for-rabbitmq b/docker/wait-for-rabbitmq new file mode 100755 index 00000000..50d985c6 --- /dev/null +++ b/docker/wait-for-rabbitmq @@ -0,0 +1,3 @@ +#!/bin/bash +while [ ! -f /var/lib/rabbitmq/mnesia/rabbit@rmq.eandersson.net.pid ]; do sleep 1; done +rabbitmqctl --timeout 16 wait /var/lib/rabbitmq/mnesia/rabbit@rmq.eandersson.net.pid --longnames \ No newline at end of file diff --git a/examples/ssl_with_context.py b/examples/ssl_with_context.py index a3820b88..b67b64b9 100644 --- a/examples/ssl_with_context.py +++ b/examples/ssl_with_context.py @@ -28,7 +28,7 @@ def on_message(message): SSL_OPTIONS = { - 'context': ssl.create_default_context(cafile='cacert.pem'), + 'context': ssl.create_default_context(cafile='ca_certificate.pem'), 'server_hostname': 'rmq.eandersson.net' } diff --git a/run_ci_locally.sh b/run_ci_locally.sh new file mode 100755 index 00000000..d8c6183f --- /dev/null +++ b/run_ci_locally.sh @@ -0,0 +1,26 @@ +#!/bin/bash +set -o pipefail +set -e + +# Build RabbitMQ container and start it. +docker rm rabbitmqdev -f || true +docker build -t rabbitmqdev ./docker/ +docker run -d --hostname rmq.eandersson.net --name rabbitmqdev -p 5671:5671 -p 5672:5672 -p 15671:15671 -p 15672:15672 rabbitmqdev +docker cp rabbitmqdev:/etc/rabbitmq/ssl/ ./amqpstorm/tests/resources/ + +# Wait for RabbitMQ to startup properly. +docker exec rabbitmqdev wait-for-rabbitmq + +# Add user. +docker exec rabbitmqdev rabbitmqctl add_user 'eandersson' '2a55f70a841f18b' +docker exec rabbitmqdev rabbitmqctl -p / set_permissions 'eandersson' '.*' '.*' '.*' +docker exec rabbitmqdev rabbitmqctl set_user_tags eandersson administrator + +# Confirm all ports are reachable. +nc -zv rmq.eandersson.net 5671 || exit 1 +nc -zv rmq.eandersson.net 5672 || exit 1 +nc -zv rmq.eandersson.net 15671 || exit 1 +nc -zv rmq.eandersson.net 15672 || exit 1 + +# Run tests. +nosetests -v -l DEBUG --logging-level=DEBUG --with-coverage --cover-package=amqpstorm --with-timer --timer-top-n 10 From b4279e28f5907beffe83a8e5c49e87ee80ac422b Mon Sep 17 00:00:00 2001 From: Erik Olof Gunnar Andersson Date: Tue, 4 May 2021 22:11:08 -0700 Subject: [PATCH 2/3] Further CI tuning - Cleaned up Dockerfiles. - Skip SSL tests if SSL cert not configured. - Fixed old W605 PEP8 warnings. --- .travis.yml | 16 ++++++++-------- MANIFEST.in | 4 +++- .../tests/functional/ssl/reliability_tests.py | 5 +++++ .../tests/unit/basic/basic_exception_tests.py | 6 +++--- amqpstorm/tests/unit/basic/basic_tests.py | 2 +- .../unit/channel/channel_exception_tests.py | 4 ++-- .../tests/unit/channel/channel_frame_tests.py | 4 ++-- .../tests/unit/channel0/channel0_frame_tests.py | 2 +- amqpstorm/tests/unit/rpc_tests.py | 6 +++--- docker/Dockerfile | 8 ++++---- docker/{ => files}/generate-certs | 0 docker/{ => files}/openssl.cnf | 0 docker/{ => files}/rabbitmq.conf | 0 docker/{ => files}/wait-for-rabbitmq | 0 run_ci_locally.sh | 17 +++++++++-------- 15 files changed, 41 insertions(+), 33 deletions(-) rename docker/{ => files}/generate-certs (100%) rename docker/{ => files}/openssl.cnf (100%) rename docker/{ => files}/rabbitmq.conf (100%) rename docker/{ => files}/wait-for-rabbitmq (100%) diff --git a/.travis.yml b/.travis.yml index 96e3230f..64903358 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,13 +11,13 @@ python: - 3.8 - 3.9 before_install: - - docker build -t rabbitmqdev ./docker/ - - docker run -d --hostname rmq.eandersson.net --name rabbitmqdev -p 5671:5671 -p 5672:5672 -p 15671:15671 -p 15672:15672 rabbitmqdev - - docker cp rabbitmqdev:/etc/rabbitmq/ssl/ ./amqpstorm/tests/resources/ - - docker exec rabbitmqdev wait-for-rabbitmq - - docker exec rabbitmqdev rabbitmqctl add_user 'eandersson' '2a55f70a841f18b' - - docker exec rabbitmqdev rabbitmqctl -p / set_permissions 'eandersson' '.*' '.*' '.*' - - docker exec rabbitmqdev rabbitmqctl set_user_tags eandersson administrator + - docker build -t amqpstormdev ./docker/ + - docker run -d --hostname rmq.eandersson.net --name amqpstormdev -p 5671:5671 -p 5672:5672 -p 15671:15671 -p 15672:15672 amqpstormdev + - docker cp amqpstormdev:/etc/rabbitmq/ssl/ ./amqpstorm/tests/resources/ + - docker exec amqpstormdev wait-for-rabbitmq + - docker exec amqpstormdev rabbitmqctl add_user 'eandersson' '2a55f70a841f18b' + - docker exec amqpstormdev rabbitmqctl -p / set_permissions 'eandersson' '.*' '.*' '.*' + - docker exec amqpstormdev rabbitmqctl set_user_tags eandersson administrator - nc -zv rmq.eandersson.net 5671 || exit 1 - nc -zv rmq.eandersson.net 5672 || exit 1 - nc -zv rmq.eandersson.net 15671 || exit 1 @@ -27,7 +27,7 @@ install: - pip install -r test-requirements.txt script: - nosetests -v -l DEBUG --logging-level=DEBUG --with-coverage --cover-package=amqpstorm --with-timer --timer-top-n 10 - - flake8 --ignore=F821,W605 . + - flake8 --ignore=F821 . after_success: - bash <(curl -s https://codecov.io/bash) services: diff --git a/MANIFEST.in b/MANIFEST.in index b7f36481..999d50dd 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1 +1,3 @@ -include *.rst LICENSE \ No newline at end of file +include *.rst LICENSE +prune examples* +prune resources* \ No newline at end of file diff --git a/amqpstorm/tests/functional/ssl/reliability_tests.py b/amqpstorm/tests/functional/ssl/reliability_tests.py index cb1e651c..3423ebf1 100644 --- a/amqpstorm/tests/functional/ssl/reliability_tests.py +++ b/amqpstorm/tests/functional/ssl/reliability_tests.py @@ -1,6 +1,8 @@ +import os.path import ssl import threading import time +import unittest from amqpstorm import Connection from amqpstorm import UriConnection @@ -15,6 +17,7 @@ from amqpstorm.tests.functional.utility import setup +@unittest.skipIf(os.path.exists(CAFILE), 'SSL tests not configured') class SSLReliabilityFunctionalTests(TestFunctionalFramework): @setup(new_connection=False, queue=True) def test_functional_ssl_open_new_connection_loop(self): @@ -209,6 +212,7 @@ def test_functional_ssl_uri_connection_with_context(self): self.assertTrue(self.connection.is_open) +@unittest.skipIf(os.path.exists(CAFILE), 'SSL tests not configured') class PublishAndConsume1kWithSSLTest(TestFunctionalFramework): messages_to_send = 1000 messages_consumed = 0 @@ -278,6 +282,7 @@ def test_functional_publish_1k_with_ssl(self): 'test took too long') +@unittest.skipIf(os.path.exists(CAFILE), 'SSL tests not configured') class Consume1kWithSSLUntilEmpty(TestFunctionalFramework): messages_to_send = 1000 diff --git a/amqpstorm/tests/unit/basic/basic_exception_tests.py b/amqpstorm/tests/unit/basic/basic_exception_tests.py index a0453572..63348e55 100644 --- a/amqpstorm/tests/unit/basic/basic_exception_tests.py +++ b/amqpstorm/tests/unit/basic/basic_exception_tests.py @@ -246,7 +246,7 @@ def test_basic_get_content_body_timeout_error(self): self.assertRaisesRegexp( exception.AMQPChannelError, - 'rpc requests .* \(.*\) took too long', + r'rpc requests .* \(.*\) took too long', basic._get_content_body, uuid, len(self.message) ) @@ -259,7 +259,7 @@ def test_basic_publish_confirms_raises_on_timeout(self): self.assertRaisesRegexp( exception.AMQPChannelError, - 'rpc requests .* \(.*\) took too long', + r'rpc requests .* \(.*\) took too long', basic.publish, body=self.message, routing_key='travis-ci' ) @@ -276,7 +276,7 @@ def on_publish_return_invalid_frame(*_): self.assertRaisesRegexp( exception.AMQPChannelError, - 'rpc requests .* \(.*\) took too long', + r'rpc requests .* \(.*\) took too long', basic.publish, body=self.message, routing_key='travis-ci' ) diff --git a/amqpstorm/tests/unit/basic/basic_tests.py b/amqpstorm/tests/unit/basic/basic_tests.py index 32acbe68..8b38051a 100644 --- a/amqpstorm/tests/unit/basic/basic_tests.py +++ b/amqpstorm/tests/unit/basic/basic_tests.py @@ -96,7 +96,7 @@ def on_get_frame(*_): self.assertRaisesRegexp( AMQPChannelError, - 'rpc requests .* \(.*\) took too long', + r'rpc requests .* \(.*\) took too long', basic.get, 'travis-ci' ) diff --git a/amqpstorm/tests/unit/channel/channel_exception_tests.py b/amqpstorm/tests/unit/channel/channel_exception_tests.py index 6463e1d9..6a6d8409 100644 --- a/amqpstorm/tests/unit/channel/channel_exception_tests.py +++ b/amqpstorm/tests/unit/channel/channel_exception_tests.py @@ -175,8 +175,8 @@ def test_channel_raises_with_return_reply_code_500(self): self.assertRaisesRegexp( AMQPMessageError, - "Message not delivered: Error \(500\) to queue " - "'' from exchange ''", + r"Message not delivered: Error \(500\) to queue " + r"'' from exchange ''", channel.check_for_errors ) diff --git a/amqpstorm/tests/unit/channel/channel_frame_tests.py b/amqpstorm/tests/unit/channel/channel_frame_tests.py index 0291b039..adac0fa0 100644 --- a/amqpstorm/tests/unit/channel/channel_frame_tests.py +++ b/amqpstorm/tests/unit/channel/channel_frame_tests.py @@ -80,8 +80,8 @@ def test_channel_basic_return_frame(self): self.assertRaisesRegexp( AMQPMessageError, - "Message not delivered: travis-ci \(500\) to queue " - "'routing_key' from exchange 'exchange'", + r"Message not delivered: travis-ci \(500\) to queue " + r"'routing_key' from exchange 'exchange'", channel.check_for_errors ) diff --git a/amqpstorm/tests/unit/channel0/channel0_frame_tests.py b/amqpstorm/tests/unit/channel0/channel0_frame_tests.py index 701b96ca..2a0d07e4 100644 --- a/amqpstorm/tests/unit/channel0/channel0_frame_tests.py +++ b/amqpstorm/tests/unit/channel0/channel0_frame_tests.py @@ -102,7 +102,7 @@ def test_channel0_start_invalid_auth_frame(self): self.assertRaisesRegexp( AMQPConnectionError, - 'Unsupported Security Mechanism\(s\): invalid', + r'Unsupported Security Mechanism\(s\): invalid', connection.check_for_errors ) diff --git a/amqpstorm/tests/unit/rpc_tests.py b/amqpstorm/tests/unit/rpc_tests.py index ed2c98b9..acf10480 100644 --- a/amqpstorm/tests/unit/rpc_tests.py +++ b/amqpstorm/tests/unit/rpc_tests.py @@ -54,7 +54,7 @@ def test_rpc_get_request_timeout(self): uuid = rpc.register_request(['travis-ci']) self.assertRaisesRegexp( AMQPChannelError, - 'rpc requests %s \(travis-ci\) took too long' + r'rpc requests %s \(travis-ci\) took too long' % uuid, rpc.get_request, uuid=uuid, raw=False ) @@ -64,7 +64,7 @@ def test_rpc_get_request_timeout_raw(self): uuid = rpc.register_request(['travis-ci']) self.assertRaisesRegexp( AMQPChannelError, - 'rpc requests %s \(travis-ci\) took too long' + r'rpc requests %s \(travis-ci\) took too long' % uuid, rpc.get_request, uuid=uuid, raw=False ) @@ -166,7 +166,7 @@ def test_rpc_raises_on_timeout(self): time.sleep(0.1) self.assertRaisesRegexp( AMQPChannelError, - 'rpc requests %s \(travis-ci-2\) took too long' % uuid, + r'rpc requests %s \(travis-ci-2\) took too long' % uuid, rpc.get_request, uuid ) diff --git a/docker/Dockerfile b/docker/Dockerfile index 881a5410..a23c4a53 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -4,10 +4,10 @@ RUN apk --update add openssl env RABBITMQ_USE_LONGNAME=true RUN mkdir -p /etc/rabbitmq/ssl/ -COPY rabbitmq.conf /etc/rabbitmq/rabbitmq.conf -COPY wait-for-rabbitmq /bin/wait-for-rabbitmq -COPY generate-certs /etc/rabbitmq/ssl/generate-certs -COPY openssl.cnf /etc/rabbitmq/ssl/openssl.cnf +COPY ./files/rabbitmq.conf /etc/rabbitmq/rabbitmq.conf +COPY ./files/wait-for-rabbitmq /bin/wait-for-rabbitmq +COPY ./files/generate-certs /etc/rabbitmq/ssl/generate-certs +COPY ./files/openssl.cnf /etc/rabbitmq/ssl/openssl.cnf RUN /etc/rabbitmq/ssl/generate-certs && \ chown -R rabbitmq.rabbitmq /etc/rabbitmq/ssl/* diff --git a/docker/generate-certs b/docker/files/generate-certs similarity index 100% rename from docker/generate-certs rename to docker/files/generate-certs diff --git a/docker/openssl.cnf b/docker/files/openssl.cnf similarity index 100% rename from docker/openssl.cnf rename to docker/files/openssl.cnf diff --git a/docker/rabbitmq.conf b/docker/files/rabbitmq.conf similarity index 100% rename from docker/rabbitmq.conf rename to docker/files/rabbitmq.conf diff --git a/docker/wait-for-rabbitmq b/docker/files/wait-for-rabbitmq similarity index 100% rename from docker/wait-for-rabbitmq rename to docker/files/wait-for-rabbitmq diff --git a/run_ci_locally.sh b/run_ci_locally.sh index d8c6183f..36913495 100755 --- a/run_ci_locally.sh +++ b/run_ci_locally.sh @@ -3,18 +3,18 @@ set -o pipefail set -e # Build RabbitMQ container and start it. -docker rm rabbitmqdev -f || true -docker build -t rabbitmqdev ./docker/ -docker run -d --hostname rmq.eandersson.net --name rabbitmqdev -p 5671:5671 -p 5672:5672 -p 15671:15671 -p 15672:15672 rabbitmqdev -docker cp rabbitmqdev:/etc/rabbitmq/ssl/ ./amqpstorm/tests/resources/ +docker rm amqpstormdev -f || true +docker build -t amqpstormdev ./docker/ +docker run -d --hostname rmq.eandersson.net --name amqpstormdev -p 5671:5671 -p 5672:5672 -p 15671:15671 -p 15672:15672 amqpstormdev +docker cp amqpstormdev:/etc/rabbitmq/ssl/ ./amqpstorm/tests/resources/ # Wait for RabbitMQ to startup properly. -docker exec rabbitmqdev wait-for-rabbitmq +docker exec amqpstormdev wait-for-rabbitmq # Add user. -docker exec rabbitmqdev rabbitmqctl add_user 'eandersson' '2a55f70a841f18b' -docker exec rabbitmqdev rabbitmqctl -p / set_permissions 'eandersson' '.*' '.*' '.*' -docker exec rabbitmqdev rabbitmqctl set_user_tags eandersson administrator +docker exec amqpstormdev rabbitmqctl add_user 'eandersson' '2a55f70a841f18b' +docker exec amqpstormdev rabbitmqctl -p / set_permissions 'eandersson' '.*' '.*' '.*' +docker exec amqpstormdev rabbitmqctl set_user_tags eandersson administrator # Confirm all ports are reachable. nc -zv rmq.eandersson.net 5671 || exit 1 @@ -24,3 +24,4 @@ nc -zv rmq.eandersson.net 15672 || exit 1 # Run tests. nosetests -v -l DEBUG --logging-level=DEBUG --with-coverage --cover-package=amqpstorm --with-timer --timer-top-n 10 +flake8 --ignore=F821 amqpstorm/ From 46484821ee9c0bee0f343598db401c4873fc671c Mon Sep 17 00:00:00 2001 From: Erik Olof Gunnar Andersson Date: Tue, 4 May 2021 22:22:15 -0700 Subject: [PATCH 3/3] Fixed typo in ssl testing --- amqpstorm/tests/functional/ssl/reliability_tests.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/amqpstorm/tests/functional/ssl/reliability_tests.py b/amqpstorm/tests/functional/ssl/reliability_tests.py index 3423ebf1..71cfb9c0 100644 --- a/amqpstorm/tests/functional/ssl/reliability_tests.py +++ b/amqpstorm/tests/functional/ssl/reliability_tests.py @@ -17,7 +17,7 @@ from amqpstorm.tests.functional.utility import setup -@unittest.skipIf(os.path.exists(CAFILE), 'SSL tests not configured') +@unittest.skipIf(not os.path.exists(CAFILE), 'SSL tests not configured') class SSLReliabilityFunctionalTests(TestFunctionalFramework): @setup(new_connection=False, queue=True) def test_functional_ssl_open_new_connection_loop(self): @@ -212,7 +212,7 @@ def test_functional_ssl_uri_connection_with_context(self): self.assertTrue(self.connection.is_open) -@unittest.skipIf(os.path.exists(CAFILE), 'SSL tests not configured') +@unittest.skipIf(not os.path.exists(CAFILE), 'SSL tests not configured') class PublishAndConsume1kWithSSLTest(TestFunctionalFramework): messages_to_send = 1000 messages_consumed = 0 @@ -282,7 +282,7 @@ def test_functional_publish_1k_with_ssl(self): 'test took too long') -@unittest.skipIf(os.path.exists(CAFILE), 'SSL tests not configured') +@unittest.skipIf(not os.path.exists(CAFILE), 'SSL tests not configured') class Consume1kWithSSLUntilEmpty(TestFunctionalFramework): messages_to_send = 1000