From 120bf1da30bd4ec2e8135ce28a91b1883554dcc3 Mon Sep 17 00:00:00 2001 From: Carl Csaposs Date: Fri, 24 Feb 2023 16:08:18 +0000 Subject: [PATCH] Cache charmcraft pack container, skip unstable tests except on schedule (#109) Ported from https://github.com/canonical/mysql-k8s-operator/pull/146 --- .github/workflows/ci.yaml | 92 +++++++++++++++++++++++-- .github/workflows/integration.yaml | 77 --------------------- .github/workflows/lint.yaml | 16 ----- .github/workflows/unit.yaml | 16 ----- CONTRIBUTING.md | 10 +-- pyproject.toml | 1 + tests/integration/__init__.py | 2 + tests/integration/conftest.py | 28 ++++++++ tests/integration/ha_tests/__init__.py | 2 + tests/integration/ha_tests/helpers.py | 8 +-- tests/integration/ha_tests/test_ha.py | 4 +- tests/integration/test_charm.py | 11 +-- tests/integration/tls_tests/__init__.py | 2 + tests/integration/tls_tests/helpers.py | 2 +- tests/integration/tls_tests/test_tls.py | 7 +- tests/unit/test_charm.py | 5 +- tests/unit/test_mongodb_lib.py | 49 +++++++------ tests/unit/test_mongodb_provider.py | 3 +- tox.ini | 59 +++++++++------- 19 files changed, 200 insertions(+), 194 deletions(-) delete mode 100644 .github/workflows/integration.yaml delete mode 100644 .github/workflows/lint.yaml delete mode 100644 .github/workflows/unit.yaml create mode 100644 tests/integration/__init__.py create mode 100644 tests/integration/conftest.py create mode 100644 tests/integration/ha_tests/__init__.py create mode 100644 tests/integration/tls_tests/__init__.py diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 06f43f94a..f2d676409 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,12 +1,90 @@ -name: Charmed Operator Tests +# Copyright 2022 Canonical Ltd. +# See LICENSE file for licensing details. +name: Tests + on: - workflow_call: pull_request: + schedule: + - cron: '53 0 * * *' # Daily at 00:53 UTC + # Triggered on push to branch "main" by .github/workflows/release.yaml + workflow_call: jobs: lint: - uses: ./.github/workflows/lint.yaml - unit: - uses: ./.github/workflows/unit.yaml - integration: - uses: ./.github/workflows/integration.yaml + name: Lint + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Install tox + # TODO: Consider replacing with custom image on self-hosted runner OR pinning version + run: python3 -m pip install tox + - name: Run linters + run: tox run -e lint + + unit-test: + name: Unit tests + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Install tox + # TODO: Consider replacing with custom image on self-hosted runner OR pinning version + run: python3 -m pip install tox + - name: Run tests + run: tox run -e unit + + build: + name: Build charms + uses: canonical/data-platform-workflows/.github/workflows/build_charms_with_cache.yaml@v1 + + integration-test: + strategy: + fail-fast: false + matrix: + tox-environments: + - integration + - ha-integration + - tls-integration + name: ${{ matrix.tox-environments }} + needs: + - lint + - unit-test + - build + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Setup operator environment + # TODO: Replace with custom image on self-hosted runner + uses: charmed-kubernetes/actions-operator@main + with: + provider: microk8s + # This is needed until https://bugs.launchpad.net/juju/+bug/1977582 is fixed + bootstrap-options: "--agent-version 2.9.29" + - name: Download packed charm(s) + uses: actions/download-artifact@v3 + with: + name: ${{ needs.build.outputs.artifact-name }} + - name: Select tests + id: select-tests + run: | + if [ "${{ github.event_name }}" == "schedule" ] + then + echo Running unstable and stable tests + echo "mark_expression=" >> $GITHUB_OUTPUT + else + echo Skipping unstable tests + echo "mark_expression=not unstable" >> $GITHUB_OUTPUT + fi + - name: Run integration tests + # set a predictable model name so it can be consumed by charm-logdump-action + run: sg microk8s -c "tox run -e ${{ matrix.tox-environments }} -- --model testing -m '${{ steps.select-tests.outputs.mark_expression }}'" + env: + CI_PACKED_CHARMS: ${{ needs.build.outputs.charms }} + - name: Dump logs + uses: canonical/charm-logdump-action@main + if: failure() + with: + app: mongodb-k8s + model: testing diff --git a/.github/workflows/integration.yaml b/.github/workflows/integration.yaml deleted file mode 100644 index f0252a4bf..000000000 --- a/.github/workflows/integration.yaml +++ /dev/null @@ -1,77 +0,0 @@ -name: Integration Tests -on: - workflow_call: - workflow_dispatch: - -jobs: - integration-test-microk8s: - name: Integration tests (microk8s) - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - - name: Setup operator environment - uses: charmed-kubernetes/actions-operator@main - with: - provider: microk8s - # This is needed until https://bugs.launchpad.net/juju/+bug/1977582 is fixed - bootstrap-options: "--agent-version 2.9.29" - - name: Install tox - run: python3 -m pip install tox - - name: Run integration tests - # set a predictable model name so it can be consumed by charm-logdump-action - run: sg microk8s -c "tox -e integration -- --model testing" - - name: Dump logs - uses: canonical/charm-logdump-action@main - if: failure() - with: - app: mongodb-k8s - model: testing - ha-integration-test-microk8s: - name: HA Integration tests (microk8s) - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - - name: Setup operator environment - uses: charmed-kubernetes/actions-operator@main - with: - provider: microk8s - # This is needed until https://bugs.launchpad.net/juju/+bug/1977582 is fixed - bootstrap-options: "--agent-version 2.9.29" - - name: Install Helm - run: /usr/bin/sudo snap install helm3 - - name: Install tox - run: python3 -m pip install tox - - name: Run HA integration tests - # set a predictable model name so it can be consumed by charm-logdump-action - run: sg microk8s -c "tox -e ha-integration -- --model testing" - - name: Dump logs - uses: canonical/charm-logdump-action@main - if: failure() - with: - app: mongodb-k8s - model: testing - tls-integration-test-microk8s: - name: TLS Integration tests (microk8s) - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - - name: Setup operator environment - uses: charmed-kubernetes/actions-operator@main - with: - provider: microk8s - # This is needed until https://bugs.launchpad.net/juju/+bug/1977582 is fixed - bootstrap-options: "--agent-version 2.9.29" - - name: Install tox - run: python3 -m pip install tox - - name: Run tls integration tests - # set a predictable model name so it can be consumed by charm-logdump-action - run: sg microk8s -c "tox -e tls-integration -- --model testing" - - name: Dump logs - uses: canonical/charm-logdump-action@main - if: failure() - with: - app: mongodb-k8s - model: testing \ No newline at end of file diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml deleted file mode 100644 index fb707ee82..000000000 --- a/.github/workflows/lint.yaml +++ /dev/null @@ -1,16 +0,0 @@ -name: Unit Tests -on: - workflow_call: - workflow_dispatch: - -jobs: - lint: - name: Lint - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - - name: Install tox - run: python3 -m pip install tox - - name: Run linters - run: tox -e lint \ No newline at end of file diff --git a/.github/workflows/unit.yaml b/.github/workflows/unit.yaml deleted file mode 100644 index 47ac5d761..000000000 --- a/.github/workflows/unit.yaml +++ /dev/null @@ -1,16 +0,0 @@ -name: Unit Tests -on: - workflow_call: - workflow_dispatch: - -jobs: - unit-test: - name: Unit tests - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - - name: Install tox - run: python3 -m pip install tox - - name: Run tests - run: tox -e unit \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0972222a1..e11fa67bd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -47,11 +47,11 @@ export PATH=$PATH:$HOME/.local/bin ### Testing ```shell -tox -e fmt # update your code according to linting rules -tox -e lint # code style -tox -e unit # unit tests -tox -e integration # integration tests -tox # runs 'fmt', 'lint' and 'unit' environments +tox run -e fmt # update your code according to linting rules +tox run -e lint # code style +tox run -e unit # unit tests +tox run -e integration # integration tests +tox # runs 'fmt', 'lint' and 'unit' environments ``` ## Build charm diff --git a/pyproject.toml b/pyproject.toml index a8e49383a..332bf6991 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -58,6 +58,7 @@ show_missing = true [tool.pytest.ini_options] minversion = "6.0" log_cli_level = "INFO" +markers = ["unstable"] # Formatting tools configuration [tool.black] diff --git a/tests/integration/__init__.py b/tests/integration/__init__.py new file mode 100644 index 000000000..db3bfe1a6 --- /dev/null +++ b/tests/integration/__init__.py @@ -0,0 +1,2 @@ +# Copyright 2023 Canonical Ltd. +# See LICENSE file for licensing details. diff --git a/tests/integration/conftest.py b/tests/integration/conftest.py new file mode 100644 index 000000000..da132958d --- /dev/null +++ b/tests/integration/conftest.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python3 +# Copyright 2022 Canonical Ltd. +# See LICENSE file for licensing details. + +import json +import os +from pathlib import Path + +import pytest +from pytest_operator.plugin import OpsTest + + +@pytest.fixture(scope="module") +def ops_test(ops_test: OpsTest) -> OpsTest: + if os.environ.get("CI") == "true": + # Running in GitHub Actions; skip build step + # (GitHub Actions uses a separate, cached build step. See .github/workflows/ci.yaml) + packed_charms = json.loads(os.environ["CI_PACKED_CHARMS"]) + + async def build_charm(charm_path, bases_index: int = None) -> Path: + for charm in packed_charms: + if Path(charm_path) == Path(charm["directory_path"]): + if bases_index is None or bases_index == charm["bases_index"]: + return charm["file_path"] + raise ValueError(f"Unable to find .charm file for {bases_index=} at {charm_path=}") + + ops_test.build_charm = build_charm + return ops_test diff --git a/tests/integration/ha_tests/__init__.py b/tests/integration/ha_tests/__init__.py new file mode 100644 index 000000000..db3bfe1a6 --- /dev/null +++ b/tests/integration/ha_tests/__init__.py @@ -0,0 +1,2 @@ +# Copyright 2023 Canonical Ltd. +# See LICENSE file for licensing details. diff --git a/tests/integration/ha_tests/helpers.py b/tests/integration/ha_tests/helpers.py index 087b2873f..e9f3be4f0 100644 --- a/tests/integration/ha_tests/helpers.py +++ b/tests/integration/ha_tests/helpers.py @@ -24,13 +24,7 @@ wait_fixed, ) -from tests.integration.helpers import ( - APP_NAME, - get_mongo_cmd, - get_password, - mongodb_uri, - primary_host, -) +from ..helpers import APP_NAME, get_mongo_cmd, get_password, mongodb_uri, primary_host METADATA = yaml.safe_load(Path("./metadata.yaml").read_text()) MONGODB_CONTAINER_NAME = "mongod" diff --git a/tests/integration/ha_tests/test_ha.py b/tests/integration/ha_tests/test_ha.py index 9ee7b995b..fbc2539e9 100644 --- a/tests/integration/ha_tests/test_ha.py +++ b/tests/integration/ha_tests/test_ha.py @@ -9,7 +9,8 @@ import pytest_asyncio from pytest_operator.plugin import OpsTest -from tests.integration.ha_tests.helpers import ( +from ..helpers import APP_NAME +from .helpers import ( ANOTHER_DATABASE_APP_NAME, MONGOD_PROCESS_NAME, MONGODB_CONTAINER_NAME, @@ -43,7 +44,6 @@ verify_writes, wait_until_unit_in_status, ) -from tests.integration.helpers import APP_NAME MEDIAN_REELECTION_TIME = 12 diff --git a/tests/integration/test_charm.py b/tests/integration/test_charm.py index 13bc36ec1..d001015a2 100644 --- a/tests/integration/test_charm.py +++ b/tests/integration/test_charm.py @@ -6,7 +6,12 @@ import time import pytest -from helpers import ( +from lightkube import AsyncClient +from lightkube.resources.core_v1 import Pod +from pymongo import MongoClient +from pytest_operator.plugin import OpsTest + +from .helpers import ( APP_NAME, METADATA, TEST_DOCUMENTS, @@ -19,10 +24,6 @@ run_mongo_op, secondary_mongo_uris_with_sync_delay, ) -from lightkube import AsyncClient -from lightkube.resources.core_v1 import Pod -from pymongo import MongoClient -from pytest_operator.plugin import OpsTest logger = logging.getLogger(__name__) diff --git a/tests/integration/tls_tests/__init__.py b/tests/integration/tls_tests/__init__.py new file mode 100644 index 000000000..db3bfe1a6 --- /dev/null +++ b/tests/integration/tls_tests/__init__.py @@ -0,0 +1,2 @@ +# Copyright 2023 Canonical Ltd. +# See LICENSE file for licensing details. diff --git a/tests/integration/tls_tests/helpers.py b/tests/integration/tls_tests/helpers.py index f224f9cde..24ab4a4ec 100644 --- a/tests/integration/tls_tests/helpers.py +++ b/tests/integration/tls_tests/helpers.py @@ -10,7 +10,7 @@ from pytest_operator.plugin import OpsTest from tenacity import RetryError, Retrying, stop_after_attempt, wait_exponential -from tests.integration.helpers import get_mongo_cmd, get_password +from ..helpers import get_mongo_cmd, get_password logger = logging.getLogger(__name__) diff --git a/tests/integration/tls_tests/test_tls.py b/tests/integration/tls_tests/test_tls.py index 3e6abab53..43a204d1b 100644 --- a/tests/integration/tls_tests/test_tls.py +++ b/tests/integration/tls_tests/test_tls.py @@ -6,12 +6,7 @@ import pytest from pytest_operator.plugin import OpsTest -from tests.integration.tls_tests.helpers import ( - METADATA, - check_tls, - time_file_created, - time_process_started, -) +from .helpers import METADATA, check_tls, time_file_created, time_process_started TLS_CERTIFICATES_APP_NAME = "tls-certificates-operator" DATABASE_APP_NAME = "mongodb-k8s" diff --git a/tests/unit/test_charm.py b/tests/unit/test_charm.py index 24633b8b4..d6851974b 100644 --- a/tests/unit/test_charm.py +++ b/tests/unit/test_charm.py @@ -16,7 +16,8 @@ ) from charm import MongoDBCharm, NotReadyError -from tests.unit.helpers import patch_network_get + +from .helpers import patch_network_get PYMONGO_EXCEPTIONS = [ (ConnectionFailure("error message"), ConnectionFailure), @@ -447,7 +448,7 @@ def test_reconfigure_not_already_initialised(self, connection, defer): @patch("ops.framework.EventBase.defer") @patch("charm.MongoDBConnection") - @patch("lib.charms.mongodb.v0.mongodb.MongoClient") + @patch("charms.mongodb.v0.mongodb.MongoClient") def test_reconfigure_get_members_failure(self, client, connection, defer): """Tests reconfigure does not execute when unable to get the replica set members. diff --git a/tests/unit/test_mongodb_lib.py b/tests/unit/test_mongodb_lib.py index 5d3872095..a5b691c38 100644 --- a/tests/unit/test_mongodb_lib.py +++ b/tests/unit/test_mongodb_lib.py @@ -4,10 +4,9 @@ import unittest from unittest.mock import call, patch +from charms.mongodb.v0.mongodb import MongoDBConnection, NotReadyError from pymongo.errors import ConfigurationError, ConnectionFailure, OperationFailure -from lib.charms.mongodb.v0.mongodb import MongoDBConnection, NotReadyError - MONGO_CONFIG = { "replset": "mongo-k8s", "database": "admin", @@ -24,8 +23,8 @@ class TestMongoServer(unittest.TestCase): - @patch("lib.charms.mongodb.v0.mongodb.MongoClient") - @patch("lib.charms.mongodb.v0.mongodb.MongoDBConfiguration") + @patch("charms.mongodb.v0.mongodb.MongoClient") + @patch("charms.mongodb.v0.mongodb.MongoDBConfiguration") def test_is_ready_error_handling(self, config, mock_client): """Test failure to check ready of replica returns False. @@ -42,8 +41,8 @@ def test_is_ready_error_handling(self, config, mock_client): # verify we close connection (mock_client.return_value.close).assert_called() - @patch("lib.charms.mongodb.v0.mongodb.MongoClient") - @patch("lib.charms.mongodb.v0.mongodb.MongoDBConfiguration") + @patch("charms.mongodb.v0.mongodb.MongoClient") + @patch("charms.mongodb.v0.mongodb.MongoDBConfiguration") def test_init_replset_error_handling(self, config, mock_client): """Test failure to initialise replica set raises an error. @@ -58,8 +57,8 @@ def test_init_replset_error_handling(self, config, mock_client): # verify we close connection (mock_client.return_value.close).assert_called() - @patch("lib.charms.mongodb.v0.mongodb.MongoClient") - @patch("lib.charms.mongodb.v0.mongodb.MongoDBConfiguration") + @patch("charms.mongodb.v0.mongodb.MongoClient") + @patch("charms.mongodb.v0.mongodb.MongoDBConfiguration") def test_get_replset_members_error_handling(self, config, mock_client): """Test failure to get replica set members raises an error. @@ -74,8 +73,8 @@ def test_get_replset_members_error_handling(self, config, mock_client): # verify we close connection (mock_client.return_value.close).assert_called() - @patch("lib.charms.mongodb.v0.mongodb.MongoClient") - @patch("lib.charms.mongodb.v0.mongodb.MongoDBConfiguration") + @patch("charms.mongodb.v0.mongodb.MongoClient") + @patch("charms.mongodb.v0.mongodb.MongoDBConfiguration") def test_add_replset_members_pymongo_error_handling(self, config, mock_client): """Test failures related to PyMongo properly get handled in add_replset_member. @@ -91,9 +90,9 @@ def test_add_replset_members_pymongo_error_handling(self, config, mock_client): # verify we close connection (mock_client.return_value.close).assert_called() - @patch("lib.charms.mongodb.v0.mongodb.MongoDBConnection._is_any_sync") - @patch("lib.charms.mongodb.v0.mongodb.MongoClient") - @patch("lib.charms.mongodb.v0.mongodb.MongoDBConfiguration") + @patch("charms.mongodb.v0.mongodb.MongoDBConnection._is_any_sync") + @patch("charms.mongodb.v0.mongodb.MongoClient") + @patch("charms.mongodb.v0.mongodb.MongoDBConfiguration") def test_add_replset_member_wait_to_sync(self, config, mock_client, any_sync): """Tests that adding replica set members raises NotReadyError if another member is syncing. @@ -112,8 +111,8 @@ def test_add_replset_member_wait_to_sync(self, config, mock_client, any_sync): no_reconfig = call("replSetReconfig") not in actual_calls self.assertEqual(no_reconfig, True) - @patch("lib.charms.mongodb.v0.mongodb.MongoClient") - @patch("lib.charms.mongodb.v0.mongodb.MongoDBConfiguration") + @patch("charms.mongodb.v0.mongodb.MongoClient") + @patch("charms.mongodb.v0.mongodb.MongoDBConfiguration") def test_remove_replset_members_pymongo_error_handling(self, config, mock_client): """Test failures related to PyMongo properly get handled in remove_replset_member. @@ -129,9 +128,9 @@ def test_remove_replset_members_pymongo_error_handling(self, config, mock_client # verify we close connection (mock_client.return_value.close).assert_called() - @patch("lib.charms.mongodb.v0.mongodb.MongoDBConnection._is_any_removing") - @patch("lib.charms.mongodb.v0.mongodb.MongoClient") - @patch("lib.charms.mongodb.v0.mongodb.MongoDBConfiguration") + @patch("charms.mongodb.v0.mongodb.MongoDBConnection._is_any_removing") + @patch("charms.mongodb.v0.mongodb.MongoClient") + @patch("charms.mongodb.v0.mongodb.MongoDBConfiguration") def test_remove_replset_member_wait_to_remove(self, config, mock_client, any_remove): """Tests removing replica set members raises NotReadyError if another member is removing. @@ -150,9 +149,9 @@ def test_remove_replset_member_wait_to_remove(self, config, mock_client, any_rem no_reconfig = call("replSetReconfig") not in actual_calls self.assertEqual(no_reconfig, True) - @patch("lib.charms.mongodb.v0.mongodb.MongoDBConnection._is_any_removing") - @patch("lib.charms.mongodb.v0.mongodb.MongoClient") - @patch("lib.charms.mongodb.v0.mongodb.MongoDBConfiguration") + @patch("charms.mongodb.v0.mongodb.MongoDBConnection._is_any_removing") + @patch("charms.mongodb.v0.mongodb.MongoClient") + @patch("charms.mongodb.v0.mongodb.MongoDBConfiguration") def test_create_user_error_handling(self, config, mock_client, any_remove): """Test failures related to PyMongo properly get handled when creating a user. @@ -167,8 +166,8 @@ def test_create_user_error_handling(self, config, mock_client, any_remove): # verify we close connection (mock_client.return_value.close).assert_called() - @patch("lib.charms.mongodb.v0.mongodb.MongoClient") - @patch("lib.charms.mongodb.v0.mongodb.MongoDBConfiguration") + @patch("charms.mongodb.v0.mongodb.MongoClient") + @patch("charms.mongodb.v0.mongodb.MongoDBConfiguration") def test_update_user_error_handling(self, config, mock_client): """Test failures related to PyMongo properly get handled when updating a user. @@ -183,8 +182,8 @@ def test_update_user_error_handling(self, config, mock_client): # verify we close connection (mock_client.return_value.close).assert_called() - @patch("lib.charms.mongodb.v0.mongodb.MongoClient") - @patch("lib.charms.mongodb.v0.mongodb.MongoDBConfiguration") + @patch("charms.mongodb.v0.mongodb.MongoClient") + @patch("charms.mongodb.v0.mongodb.MongoDBConfiguration") def test_drop_user_error_handling(self, config, mock_client): """Test failures related to PyMongo properly get handled when dropping a user. diff --git a/tests/unit/test_mongodb_provider.py b/tests/unit/test_mongodb_provider.py index d0ceebdbd..30186b0f9 100644 --- a/tests/unit/test_mongodb_provider.py +++ b/tests/unit/test_mongodb_provider.py @@ -10,7 +10,8 @@ from pymongo.errors import ConfigurationError, ConnectionFailure, OperationFailure from charm import MongoDBCharm -from tests.unit.helpers import patch_network_get + +from .helpers import patch_network_get PYMONGO_EXCEPTIONS = [ (ConnectionFailure("error message"), ConnectionFailure), diff --git a/tox.ini b/tox.ini index b4800b601..b5837c957 100644 --- a/tox.ini +++ b/tox.ini @@ -2,31 +2,30 @@ # See LICENSE file for licensing details. [tox] -skipsdist=True -isolated_build = True +no_package = True skip_missing_interpreters = True -envlist = fmt, lint, unit +env_list = format, lint, unit [vars] -src_path = {toxinidir}/src/ -tst_path = {toxinidir}/tests/ -lib_path = {toxinidir}/lib/charms/mongodb -all_path = {[vars]src_path} {[vars]tst_path} {[vars]lib_path} +src_path = {tox_root}/src +tests_path = {tox_root}/tests +lib_path = {tox_root}/lib/charms/mongodb +all_path = {[vars]src_path} {[vars]tests_path} {[vars]lib_path} [testenv] -whitelist_externals = poetry -setenv = - PYTHONPATH = {toxinidir}:{toxinidir}/lib:{[vars]src_path} - PYTHONBREAKPOINT=ipdb.set_trace - PY_COLORS=1 -passenv = - PYTHONPATH - CHARM_BUILD_DIR - MODEL_SETTINGS +allowlist_externals = poetry +set_env = + PYTHONPATH = {tox_root}/lib:{[vars]src_path} + PYTHONBREAKPOINT=ipdb.set_trace + PY_COLORS=1 +pass_env = + PYTHONPATH + CHARM_BUILD_DIR + MODEL_SETTINGS deps = poetry -[testenv:fmt] +[testenv:format] description = Apply coding style standards to code commands = poetry install --only fmt @@ -38,9 +37,9 @@ description = Check code against coding style standards commands = poetry install --only fmt,lint poetry run codespell {[vars]lib_path} - poetry run codespell {toxinidir} --skip {toxinidir}/.git --skip {toxinidir}/.tox \ - --skip {toxinidir}/build --skip {toxinidir}/lib --skip {toxinidir}/venv \ - --skip {toxinidir}/.mypy_cache --skip {toxinidir}/icon.svg + poetry run codespell {tox_root} --skip {tox_root}/.git --skip {tox_root}/.tox \ + --skip {tox_root}/build --skip {tox_root}/lib --skip {tox_root}/venv \ + --skip {tox_root}/.mypy_cache --skip {tox_root}/icon.svg # pflake8 wrapper supports config from pyproject.toml poetry run pflake8 {[vars]all_path} poetry run isort --check-only --diff {[vars]all_path} @@ -52,26 +51,38 @@ commands = poetry install --with unit poetry export -f requirements.txt -o requirements.txt poetry run coverage run --source={[vars]src_path} \ - -m pytest --ignore={[vars]tst_path}integration -v --tb native -s {posargs} + -m pytest -v --tb native -s {posargs} {[vars]tests_path}/unit poetry run coverage report [testenv:integration] description = Run integration tests +pass_env = + {[testenv]pass_env} + CI + CI_PACKED_CHARMS commands = poetry install --with integration poetry export -f requirements.txt -o requirements.txt - poetry run pytest -v --tb native {[vars]tst_path}integration/test_charm.py --log-cli-level=INFO -s {posargs} + poetry run pytest -v --tb native --log-cli-level=INFO -s {posargs} {[vars]tests_path}/integration/test_charm.py [testenv:ha-integration] description = Run HA integration tests +pass_env = + {[testenv]pass_env} + CI + CI_PACKED_CHARMS commands = poetry install --with integration poetry export -f requirements.txt -o requirements.txt - poetry run pytest -v --tb native {[vars]tst_path}integration/ha_tests --log-cli-level=INFO -s {posargs} --durations=0 + poetry run pytest -v --tb native --log-cli-level=INFO -s --durations=0 {posargs} {[vars]tests_path}/integration/ha_tests/test_ha.py [testenv:tls-integration] description = Run tls integration tests +pass_env = + {[testenv]pass_env} + CI + CI_PACKED_CHARMS commands = poetry install --with integration poetry export -f requirements.txt -o requirements.txt - poetry run pytest -v --tb native {[vars]tst_path}integration/tls_tests --log-cli-level=INFO -s {posargs} --durations=0 + poetry run pytest -v --tb native --log-cli-level=INFO -s --durations=0 {posargs} {[vars]tests_path}/integration/tls_tests/test_tls.py