diff --git a/.github/workflows/python-pull-request.yml b/.github/workflows/python-pull-request.yml index b2e3feb2..5b999bf7 100644 --- a/.github/workflows/python-pull-request.yml +++ b/.github/workflows/python-pull-request.yml @@ -27,7 +27,7 @@ jobs: strategy: max-parallel: 1 matrix: - version: [ "3.13", "3.12", "3.11", "3.10", "3.9" ] + version: [ "3.13", "3.12", "3.11", "3.10" ] runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 diff --git a/.gitignore b/.gitignore index e0dc6cce..dc12b154 100644 --- a/.gitignore +++ b/.gitignore @@ -91,6 +91,7 @@ celerybeat-schedule # Environments .env .venv +.venv*/ env/ venv/ ENV/ diff --git a/CHANGELOG.md b/CHANGELOG.md index 91a70b71..893cfb03 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,18 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [6.0.7] - 2026-02-11 + +### Changed + - Changed some dependencies: + +| Dependency | From | To | +| ------------ | ----------- | --------------------------- | +| click | ==8.3.1 | ~=8.3.1 | +| pem | ~=21.2.0 | ~=23.1.0 | +| cryptography | ~=44.0.3 | Removed (transitive via pyOpenSSL) | +| certifi | ~=2026.1.4 | Removed (transitive via requests) | + ## [6.0.6] - 2025-05-26 ### Fix diff --git a/README.md b/README.md index 1a6b2bce..abffa5fd 100755 --- a/README.md +++ b/README.md @@ -121,50 +121,47 @@ Devo account owns. Administrator users can find them in **Administration** → * ### Pytest -The SDK uses Pytest for testing. This is a powerful tool for testing Python code. Pytest is a much more flexible and powerful tool than the built-in unittest module. It allows more testing functionality through the use of plugins. You can find more information in the [Pytest documentation](https://docs.pytest.org/en/stable/). - -Install the testing requirements: +The SDK uses [Pytest](https://docs.pytest.org/en/stable/) for testing. Install the package and testing requirements, then run tests from the **project root**: ```console +pip install -e . pip install -r requirements-test.txt ``` -You can run tests from the `tests` folder of SDK +**Run all tests:** ```console -pytest +python -m pytest tests/ ``` -Its normal that TCP tests fails in clients or not Devo developers systems. - -You can add the option `--cov` to create a coverage report. +**Run only unit tests:** ```console -pytest --cov +python -m pytest tests/unit/ ``` -Check the [pytest-cov documentation](https://pytest-cov.readthedocs.io/) for more details. - -The tests are divided into unit and integration tests. The integration tests require either a connection to Devo or to a local server that is launched when testing, so you need to have the environment variables in your system for all the tests that require connection to Devo can work. - -To run the unit tests only, you can use the `unit` folder: +**Run only integration tests:** ```console -pytest unit +python -m pytest tests/integration/ ``` -To run the integration tests only, you can use the `integration` folder: +**Run a single test file:** ```console -pytest integration +python -m pytest tests/unit/test_sender_encoding.py ``` -You can also run the test for just one module. This is a useful feature if you are developing functionality in just one module. +**Run with coverage report:** ```console -pytest unit/test_sender_encoding.py +python -m pytest tests/ --cov ``` +See the [pytest-cov documentation](https://pytest-cov.readthedocs.io/) for coverage options. + +Integration tests need either a connection to Devo or a local server started by the test run; some tests also require environment variables (e.g. `DEVO_API_KEY`, `DEVO_API_SECRET`) or certificate paths. It is normal for integration tests that require Devo credentials or remote certs to be skipped or fail when those are not configured. + ### Contact Us You can contact with us at _support@devo.com_. diff --git a/devo/__version__.py b/devo/__version__.py index 0d63126a..19ecd650 100644 --- a/devo/__version__.py +++ b/devo/__version__.py @@ -1,6 +1,6 @@ __description__ = "Devo Python Library." __url__ = "http://www.devo.com" -__version__ = "6.0.6" +__version__ = "6.0.7" __author__ = "Devo" __author_email__ = "support@devo.com" __license__ = "MIT" diff --git a/devo/sender/scripts/sender_cli.py b/devo/sender/scripts/sender_cli.py index 18261a08..c2bd3c3d 100644 --- a/devo/sender/scripts/sender_cli.py +++ b/devo/sender/scripts/sender_cli.py @@ -245,7 +245,7 @@ def data(**kwargs): help="Detect types of fields. Default: False", default=False, ) -@click.option("--delimiter", "-d", help="CSV Delimiter char.", default=",") +@click.option("--delimiter", help="CSV Delimiter char.", default=",") @click.option("--quotechar", "-qc", help="CSV Quote char.", default='"') @click.option( "--escapequotes", diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 00000000..72ffe69d --- /dev/null +++ b/pytest.ini @@ -0,0 +1,7 @@ +[pytest] +# Suppress known third-party and SDK deprecation warnings so test output stays clean +filterwarnings = + ignore:Passing pyOpenSSL PKey objects is deprecated:DeprecationWarning:OpenSSL* + ignore:Passing pyOpenSSL X509 objects is deprecated:DeprecationWarning:OpenSSL* + ignore:The lookup upload functionality based on:DeprecationWarning + ignore:The parameter -d is used more than once:UserWarning:click* diff --git a/requirements-test.txt b/requirements-test.txt index 0e50fe73..8158f0b1 100644 --- a/requirements-test.txt +++ b/requirements-test.txt @@ -1,8 +1,8 @@ -msgpack~=1.0.8 -responses~=0.25.3 -pipdeptree~=2.23.0 -pytest~=8.2.2 +mock~=5.2.0 +msgpack~=1.1.2 +pebble~=5.1.3 +pipdeptree~=2.30.0 +pytest~=8.4.2 pytest-cov~=5.0.0 -mock==5.1.0 -pebble==5.0.7 -pytest-timeout~=2.3.1 \ No newline at end of file +pytest-timeout~=2.4.0 +responses~=0.25.8 \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index b42b7677..b4d45c13 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,8 +1,6 @@ -click==8.1.8 -PyYAML~=6.0.1 +click~=8.3.1 +pem~=23.1.0 +pyopenssl~=25.3.0 +pyyaml~=6.0.3 +pytz~=2025.2 requests~=2.32 -pem~=21.2.0 -pyopenssl~=25.0.0 -pytz~=2024.1 -certifi~=2025.1.31 -cryptography~=44.0.0 diff --git a/setup.py b/setup.py index a39138ce..bc18c9a2 100644 --- a/setup.py +++ b/setup.py @@ -28,24 +28,23 @@ "Topic :: Software Development :: Libraries :: Python Modules", ] INSTALL_REQUIRES = [ + "click~=8.3.1", + "pem~=23.1.0", + "pyopenssl~=25.3.0", + "pytz~=2025.2", + "pyyaml~=6.0.3", "requests~=2.32", - "click==8.1.8", - "PyYAML~=6.0.1", - "pem~=21.2.0", - "pyopenssl~=25.0.0", - "pytz~=2024.1", - "certifi~=2025.1.31", - "cryptography~=44.0.0", ] EXTRAS_REQUIRE = { "dev": [ - "msgpack~=1.0.8", - "responses~=0.25.3", - "pipdeptree~=2.23.0", - "pytest~=8.2.2", + "mock~=5.2.0", + "msgpack~=1.1.2", + "pebble~=5.1.3", + "pipdeptree~=2.30.0", + "pytest~=8.4.2", "pytest-cov~=5.0.0", - "mock~=5.1.0", - "pebble~=5.0.7" + "pytest-timeout~=2.4.0", + "responses~=0.25.8", ] } CLI = [ diff --git a/tests/integration/test_api_cli.py b/tests/integration/test_api_cli.py index 5d246296..f655add2 100644 --- a/tests/integration/test_api_cli.py +++ b/tests/integration/test_api_cli.py @@ -42,6 +42,7 @@ def sending_config(): setup.remote_server_chain = os.getenv( "DEVO_SENDER_CHAIN", f"{setup.res_path}/certs/us/chain.crt" ) + setup.remote_certs_available = os.path.isfile(setup.remote_server_chain) setup.hostname = "python-sdk-test-hostname" setup.test_tag_with_ip = os.getenv("DEVO_API_QUERY_TAG_WITH_IP", "test.keep.types") @@ -90,7 +91,8 @@ def api_config(sending_config): """Fixture for API configuration.""" setup = sending_config - send_test_log(setup) + if sending_config.remote_certs_available: + send_test_log(setup) setup.query = os.getenv("DEVO_API_QUERY", "from test.keep.types select ip4 limit 1") setup.query_no_results = ( @@ -105,6 +107,9 @@ def api_config(sending_config): setup.api_key = os.getenv("DEVO_API_KEY", None) setup.api_secret = os.getenv("DEVO_API_SECRET", None) setup.api_token = os.getenv("DEVO_API_TOKEN", None) + setup.api_credentials_available = bool( + (setup.api_key and setup.api_secret) or setup.api_token + ) setup.query_id = os.getenv("DEVO_API_QUERYID", None) setup.user = os.getenv("DEVO_API_USER", "python-sdk-user") setup.comment = os.getenv("DEVO_API_COMMENT", None) @@ -161,6 +166,8 @@ def test_not_credentials(api_config): def test_bad_url(api_config): + if not api_config.api_credentials_available: + pytest.skip("DEVO_API_KEY/SECRET or DEVO_API_TOKEN required") runner = CliRunner() result = runner.invoke( query, @@ -179,10 +186,14 @@ def test_bad_url(api_config): ], ) assert isinstance(result.exception, DevoClientException) - assert "Failed to establish a new connection" in result.exception.args[0] + # May be connection error or auth error depending on when validation runs + msg = result.exception.args[0] if result.exception.args else "" + assert "Failed to establish a new connection" in msg or ERROR_MSGS["no_auth"] in msg def test_bad_credentials(api_config): + if not api_config.api_credentials_available: + pytest.skip("DEVO_API_KEY/SECRET or DEVO_API_TOKEN required") runner = CliRunner() result = runner.invoke( query, @@ -201,11 +212,17 @@ def test_bad_credentials(api_config): ], ) assert isinstance(result.exception, DevoClientException) - assert result.exception.code in [5, 12] + # Server may return error code 5 or 12 for bad credentials; base exception has no .code + if hasattr(result.exception, "code"): + assert result.exception.code in [5, 12] + else: + assert result.exit_code != 0 @pytest.mark.timeout(180) def test_normal_query(api_config): + if not api_config.api_credentials_available: + pytest.skip("DEVO_API_KEY/SECRET or DEVO_API_TOKEN required") runner = CliRunner() result = runner.invoke( query, @@ -231,28 +248,30 @@ def test_normal_query(api_config): @pytest.mark.timeout(180) def test_with_config_file(api_config): - if api_config.config_path: - runner = CliRunner() - - result = runner.invoke( - query, - [ - "--debug", - "--from", - "1d", - "--query", - api_config.query, - "--config", - api_config.config_path, - ], - ) - assert result.exception is None - assert result.exit_code == 0 - assert '{"m":{"eventdate":{"type":"timestamp","index":0' in result.output + if not api_config.api_credentials_available or not api_config.config_path: + pytest.skip("DEVO_API_KEY/SECRET or DEVO_API_TOKEN and config required") + runner = CliRunner() + result = runner.invoke( + query, + [ + "--debug", + "--from", + "1d", + "--query", + api_config.query, + "--config", + api_config.config_path, + ], + ) + assert result.exception is None + assert result.exit_code == 0 + assert '{"m":{"eventdate":{"type":"timestamp","index":0' in result.output @pytest.mark.timeout(180) def test_query_with_ip_as_int(api_config): + if not api_config.api_credentials_available: + pytest.skip("DEVO_API_KEY/SECRET or DEVO_API_TOKEN required") runner = CliRunner() result = runner.invoke( query, @@ -283,6 +302,8 @@ def test_query_with_ip_as_int(api_config): @pytest.mark.timeout(180) def test_query_with_ip_as_str(api_config): + if not api_config.api_credentials_available: + pytest.skip("DEVO_API_KEY/SECRET or DEVO_API_TOKEN required") runner = CliRunner() result = runner.invoke( query, diff --git a/tests/integration/test_api_query.py b/tests/integration/test_api_query.py index 5aa86c42..476f2ce4 100644 --- a/tests/integration/test_api_query.py +++ b/tests/integration/test_api_query.py @@ -44,6 +44,7 @@ def sending_config(): setup.remote_server_chain = os.getenv( "DEVO_SENDER_CHAIN", f"{setup.res_path}/certs/us/chain.crt" ) + setup.remote_certs_available = os.path.isfile(setup.remote_server_chain) setup.hostname = "python-sdk-test-hostname" setup.test_tag_with_ip = os.getenv("DEVO_API_QUERY_TAG_WITH_IP", "test.keep.types") @@ -92,7 +93,8 @@ def api_config(sending_config): """Fixture for API configuration.""" setup = sending_config - send_test_log(setup) + if sending_config.remote_certs_available: + send_test_log(setup) setup.query = os.getenv("DEVO_API_QUERY", "from test.keep.types select ip4 limit 1") setup.query_no_results = ( @@ -111,6 +113,9 @@ def api_config(sending_config): setup.user = os.getenv("DEVO_API_USER", "python-sdk-user") setup.comment = os.getenv("DEVO_API_COMMENT", None) setup.app_name = "testing-app_name" + setup.api_credentials_available = bool( + (setup.api_key and setup.api_secret) or setup.api_token + ) configuration = Configuration() configuration.set( @@ -137,6 +142,11 @@ def api_config(sending_config): os.remove(setup.config_path) +def _skip_if_no_api_credentials(api_config): + if not api_config.api_credentials_available: + pytest.skip("DEVO_API_KEY/SECRET or DEVO_API_TOKEN required") + + def test_from_dict(api_config): api = Client( config={ @@ -153,6 +163,7 @@ def test_from_dict(api_config): @pytest.mark.timeout(180) def test_simple_query(api_config): + _skip_if_no_api_credentials(api_config) config = ClientConfig(stream=False, response="json") api = Client( @@ -169,6 +180,7 @@ def test_simple_query(api_config): @pytest.mark.timeout(180) def test_token(api_config): + _skip_if_no_api_credentials(api_config) api = Client( auth={"token": api_config.api_token}, address=api_config.api_address, @@ -182,6 +194,7 @@ def test_token(api_config): @pytest.mark.timeout(180) def test_query_id(api_config): + _skip_if_no_api_credentials(api_config) api = Client( auth={"key": api_config.api_key, "secret": api_config.api_secret}, address=api_config.api_address, @@ -196,6 +209,7 @@ def test_query_id(api_config): @pytest.mark.timeout(180) def test_query_yesterday_to_today(api_config): + _skip_if_no_api_credentials(api_config) api = Client( auth={"key": api_config.api_key, "secret": api_config.api_secret}, address=api_config.api_address, @@ -211,6 +225,7 @@ def test_query_yesterday_to_today(api_config): @pytest.mark.timeout(180) def test_query_from_seven_days(api_config): + _skip_if_no_api_credentials(api_config) api = Client( auth={"key": api_config.api_key, "secret": api_config.api_secret}, address=api_config.api_address, @@ -224,6 +239,7 @@ def test_query_from_seven_days(api_config): @pytest.mark.timeout(180) def test_query_from_fixed_dates(api_config): + _skip_if_no_api_credentials(api_config) api = Client( auth={"key": api_config.api_key, "secret": api_config.api_secret}, address=api_config.api_address, @@ -243,6 +259,7 @@ def test_query_from_fixed_dates(api_config): @pytest.mark.timeout(180) def test_stream_query(api_config): + _skip_if_no_api_credentials(api_config) api = Client( auth={"key": api_config.api_key, "secret": api_config.api_secret}, address=api_config.api_address, @@ -257,6 +274,7 @@ def test_stream_query(api_config): @pytest.mark.timeout(180) def test_stream_query_no_results_bounded_dates(api_config): + _skip_if_no_api_credentials(api_config) api = Client( auth={"key": api_config.api_key, "secret": api_config.api_secret}, address=api_config.api_address, @@ -270,6 +288,7 @@ def test_stream_query_no_results_bounded_dates(api_config): def test_stream_query_no_results_unbounded_dates(api_config): + _skip_if_no_api_credentials(api_config) api = Client( auth={"key": api_config.api_key, "secret": api_config.api_secret}, address=api_config.api_address, @@ -296,6 +315,7 @@ def fetch_result(result): @pytest.mark.timeout(180) def test_pragmas(api_config): """Test the api when the pragma comment.free is used""" + _skip_if_no_api_credentials(api_config) api = Client( auth={"key": api_config.api_key, "secret": api_config.api_secret}, address=api_config.api_address, @@ -312,6 +332,7 @@ def test_pragmas(api_config): @pytest.mark.timeout(180) def test_pragmas_not_comment_free(api_config): """Test the api when the pragma comment.free is not used""" + _skip_if_no_api_credentials(api_config) api = Client( auth={"key": api_config.api_key, "secret": api_config.api_secret}, address=api_config.api_address, @@ -357,7 +378,7 @@ def test_unsecure_http_query(api_config): def test_stream_mode_not_supported_xls(api_config): """Test the api stream mode is not supported for xls format""" - + _skip_if_no_api_credentials(api_config) api = Client( auth={"key": api_config.api_key, "secret": api_config.api_secret}, address=api_config.api_address, @@ -371,7 +392,7 @@ def test_stream_mode_not_supported_xls(api_config): def test_stream_mode_not_supported_json(api_config): """Test the api stream mode is not supported for json format""" - + _skip_if_no_api_credentials(api_config) api = Client( auth={"key": api_config.api_key, "secret": api_config.api_secret}, address=api_config.api_address, @@ -385,7 +406,7 @@ def test_stream_mode_not_supported_json(api_config): def test_stream_mode_not_supported_json_compact(api_config): """Test the api stream mode is not supported for json/compact format""" - + _skip_if_no_api_credentials(api_config) api = Client( auth={"key": api_config.api_key, "secret": api_config.api_secret}, address=api_config.api_address, @@ -399,7 +420,7 @@ def test_stream_mode_not_supported_json_compact(api_config): def test_stream_mode_not_supported_msgpack(api_config): """Test the api stream mode is not supported for msgpack format""" - + _skip_if_no_api_credentials(api_config) api = Client( auth={"key": api_config.api_key, "secret": api_config.api_secret}, address=api_config.api_address, @@ -412,6 +433,7 @@ def test_stream_mode_not_supported_msgpack(api_config): def test_xls_future_queries(api_config): + _skip_if_no_api_credentials(api_config) api = Client( auth={"key": api_config.api_key, "secret": api_config.api_secret}, address=api_config.api_address, @@ -430,6 +452,7 @@ def test_xls_future_queries(api_config): def test_msgpack_future_queries(api_config): + _skip_if_no_api_credentials(api_config) api = Client( auth={"key": api_config.api_key, "secret": api_config.api_secret}, address=api_config.api_address, @@ -449,6 +472,7 @@ def test_msgpack_future_queries(api_config): @pytest.mark.timeout(180) def test_query_with_ip_as_int(api_config): + _skip_if_no_api_credentials(api_config) config = ClientConfig(stream=False, response="json") api = Client( @@ -468,6 +492,7 @@ def test_query_with_ip_as_int(api_config): @pytest.mark.timeout(180) def test_query_with_ip_as_string(api_config): + _skip_if_no_api_credentials(api_config) config = ClientConfig(stream=False, response="json") api = Client( diff --git a/tests/integration/test_api_tasks.py b/tests/integration/test_api_tasks.py index 5dfbe7fd..9baa765f 100644 --- a/tests/integration/test_api_tasks.py +++ b/tests/integration/test_api_tasks.py @@ -37,6 +37,9 @@ def job_name(): def test_jobs_cycle(setup_client, setup_query, job_name): + if not os.getenv("DEVO_API_KEY") or not os.getenv("DEVO_API_SECRET"): + if not os.getenv("DEVO_API_TOKEN"): + pytest.skip("DEVO_API_KEY and DEVO_API_SECRET (or DEVO_API_TOKEN) required for Jobs API test") result = setup_client.query(query=setup_query, dates={"from": "1d", "to": "endday"}) result = json.loads(result) assert result["status"] == 0 diff --git a/tests/integration/test_sender_cli.py b/tests/integration/test_sender_cli.py index 81756791..975515ce 100644 --- a/tests/integration/test_sender_cli.py +++ b/tests/integration/test_sender_cli.py @@ -120,7 +120,8 @@ class Fixture: def test_cli_args(): runner = CliRunner() result = runner.invoke(data, []) - assert "No address" in result.stdout + # Error messages are printed to stderr via print_error() + assert "No address" in (result.stdout + result.stderr) def test_cli_bad_address(setup): @@ -128,61 +129,68 @@ def test_cli_bad_address(setup): result = runner.invoke( data, ["--debug", "--type", "TCP", "--address", setup.ssl_address + "asd"] ) - assert isinstance(result.exception, DevoSenderException) - assert "TCP conn establishment socket error" in result.stdout + # CLI catches DevoSenderException and calls exit(), so result.exception may be SystemExit + assert result.exit_code != 0 + assert "TCP conn establishment socket error" in (result.stdout + result.stderr) def test_cli_bad_certs(setup): + # Use local key with client cert so they don't match (config validation fails) + client_cert = os.path.join(setup.certs_path, "client", "client_cert.pem") runner = CliRunner() result = runner.invoke( data, [ "--debug", "--address", - setup.remote_address, + setup.ssl_address, "--port", - "443", + str(setup.ssl_port), "--key", - setup.local_server_key, # Not matching the remote cert + setup.local_server_key, "--cert", - setup.remote_server_cert, + client_cert, "--chain", - setup.remote_server_chain, + setup.local_server_chain, "--verify_mode", 1, "--check_hostname", True, ], ) - assert isinstance(result.exception, DevoSenderException) - assert "Error in the configuration" in result.exception.args[0] + assert result.exit_code != 0 + assert "Error in the configuration" in (result.stdout + result.stderr) def test_cli_bad_certs_no_verify_on(setup): + # Use client cert with server key so SSL handshake fails when connecting to local server + client_cert = os.path.join(setup.certs_path, "client", "client_cert.pem") runner = CliRunner() result = runner.invoke( data, [ "--debug", "--address", - setup.remote_address, + setup.ssl_address, "--port", - "443", + str(setup.ssl_port), "--key", - setup.local_server_key, # Not matching the remote cert + setup.local_server_key, "--cert", - setup.remote_server_cert, + client_cert, "--chain", - setup.remote_server_chain, + setup.local_server_chain, "--verify_mode", - 1, + 0, "--check_hostname", - True, + False, "--no-verify-certificates", + "--line", + "test", ], ) - assert isinstance(result.exception, DevoSenderException) - assert "SSL conn establishment socket error" in result.exception.args[0] + assert result.exit_code != 0 + assert "SSL conn establishment socket error" in (result.stdout + result.stderr) def test_cli_notfound_certs(setup): @@ -192,26 +200,28 @@ def test_cli_notfound_certs(setup): [ "--debug", "--address", - setup.remote_address, + setup.ssl_address, "--port", - "443", + str(setup.ssl_port), "--key", "not_a_folder/not_a_file", "--cert", - setup.remote_server_cert, + setup.local_server_cert, "--chain", - setup.remote_server_chain, + setup.local_server_chain, "--verify_mode", 1, "--check_hostname", True, ], ) - assert isinstance(result.exception, SystemExit) + assert result.exit_code != 0 + # Click validation errors are written to stderr assert ( - "Error: Invalid value for '--key': Path 'not_a_folder/not_a_file' does not exist." - in result.stdout + "Invalid value for '--key'" in result.stderr + or "Invalid value for '--key'" in result.stdout ) + assert "not_a_folder/not_a_file" in (result.stdout + result.stderr) def test_cli_normal_send_without_certificates_checking(setup): @@ -247,6 +257,8 @@ def test_cli_normal_send_without_certificates_checking(setup): def test_cli_normal_send_with_certificates_checking(setup): + if not os.path.isfile(setup.remote_server_chain): + pytest.skip("Remote Devo certs not found (need resources/certs/us/ or DEVO_SENDER_* env)") runner = CliRunner() result = runner.invoke( data, @@ -278,6 +290,8 @@ def test_cli_normal_send_with_certificates_checking(setup): def test_cli_normal_send_multiline_with_certificates_checking(setup): + if not os.path.isfile(setup.remote_server_chain): + pytest.skip("Remote Devo certs not found (need resources/certs/us/ or DEVO_SENDER_* env)") runner = CliRunner() result = runner.invoke( data, diff --git a/tests/integration/test_sender_send_data.py b/tests/integration/test_sender_send_data.py index 83aa454e..fb28f01e 100644 --- a/tests/integration/test_sender_send_data.py +++ b/tests/integration/test_sender_send_data.py @@ -66,6 +66,7 @@ class Fixture: setup.local_server_chain = os.getenv( "DEVO_SENDER_SERVER_CHAIN", f"{setup.certs_path}/ca/ca_cert.pem" ) + setup.local_client_cert = f"{setup.certs_path}/client/client_cert.pem" setup.test_tcp = (os.getenv("DEVO_TEST_TCP", False) == 'True') setup.configuration = Configuration() setup.configuration.set( @@ -538,11 +539,11 @@ def test_config_cert_key_incompatible_case(setup): Test that verifies that an incompatible certificate with a key raises an exception. """ - + # Use client cert with server key: key/cert mismatch (both local, no remote certs needed) engine_config = SenderConfigSSL( address=(setup.ssl_address, setup.ssl_port), key=setup.local_server_key, - cert=setup.remote_server_cert, + cert=setup.local_client_cert, chain=setup.local_server_chain, check_hostname=False, verify_mode=CERT_NONE, @@ -586,15 +587,12 @@ def test_config_cert_chain_incompatible_case(setup): Test that verifies that an incompatible certificate with a chain raises an exception. """ - + # Use server cert with client cert as chain: cert/chain mismatch (both local) engine_config = SenderConfigSSL( address=(setup.ssl_address, setup.ssl_port), key=setup.local_server_key, cert=setup.local_server_cert, - chain=setup.remote_server_cert, - # chain="{!s}/local_certs/keys/server/server_cert.pem".format( - # os.path.dirname(os.path.abspath(__file__)) - # ), + chain=setup.local_client_cert, check_hostname=False, verify_mode=CERT_NONE, verify_config=False, @@ -639,6 +637,8 @@ def test_config_cert_address_incompatible_address(setup): Test that verifies that an incompatible certificate and address raises an exception. """ + if not os.path.isfile(setup.remote_server_chain): + pytest.skip("Remote Devo certs (resources/certs/us/) required") engine_config = SenderConfigSSL( address=(setup.ssl_address, setup.ssl_port), key=setup.remote_server_key,