Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cache charmcraft pack container, skip unstable tests except on schedule #11

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 54 additions & 30 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -1,72 +1,96 @@
# Copyright 2022 Canonical Ltd.
# See LICENSE file for licensing details.
name: Tests

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

on:
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:
name: Lint
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Install tox
run: python3 -m pip install tox
- name: Install poetry
run: curl -sSL https://install.python-poetry.org | python3 -
- name: Run linters
run: tox -e lint
run: tox run -e lint

unit-test:
name: Unit tests
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Install tox
run: python3 -m pip install tox
- name: Install poetry
run: curl -sSL https://install.python-poetry.org | python3 -
- name: Run tests
run: tox -e unit

integration-test-lxd:
name: Integration tests for (lxd)
runs-on: ubuntu-22.04
needs:
- lint
- unit-test
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup operator environment
uses: charmed-kubernetes/actions-operator@main
with:
provider: lxd
bootstrap-options: "--agent-version 2.9.38"
- name: Install tox
run: python3 -m pip install tox
- name: Install poetry
run: curl -sSL https://install.python-poetry.org | python3 -
- name: Run integration tests
run: tox -e integration-lxd

integration-test-k8s:
name: Integration tests for (microk8s)
run: tox run -e unit

build:
name: Build charms
uses: canonical/data-platform-workflows/.github/workflows/build_charms_with_cache.yaml@v2

integration-test:
strategy:
fail-fast: false
matrix:
tox-environments:
- name: integration-lxd
provider: lxd
- name: integration-k8s
provider: microk8s
name: ${{ matrix.tox-environments.name }}
needs:
- lint
- unit-test
- build
runs-on: ubuntu-latest
timeout-minutes: 120
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
provider: ${{ matrix.tox-environments.provider }}
bootstrap-options: "--agent-version 2.9.38"
- name: Install tox
run: python3 -m pip install tox
- name: Install poetry
run: curl -sSL https://install.python-poetry.org | python3 -
- 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
run: tox -e integration-k8s
run: tox run -e ${{ matrix.tox-environments.name }} -- -m '${{ steps.select-tests.outputs.mark_expression }}'
env:
CI_PACKED_CHARMS: ${{ needs.build.outputs.charms }}
2 changes: 2 additions & 0 deletions .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ jobs:
lib-check:
name: Check libraries
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout
uses: actions/checkout@v3
Expand All @@ -33,6 +34,7 @@ jobs:
- lib-check
- ci-tests
runs-on: ubuntu-latest
timeout-minutes: 60
steps:
- name: Checkout
uses: actions/checkout@v3
Expand Down
16 changes: 8 additions & 8 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,21 +47,21 @@ juju deploy ./*.charm

## Developing

You can use the environments created by `tox` for development:
You can create an environment for development with `tox`:

```shell
tox --notest -e unit
source .tox/unit/bin/activate
tox devenv -e integration
source venv/bin/activate
```

### 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 'lint' and 'unit' environments
tox run -e format # 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 'lint' and 'unit' environments
```

## Canonical Contributor Agreement
Expand Down
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ show_missing = true
[tool.pytest.ini_options]
minversion = "6.0"
log_cli_level = "INFO"
asyncio_mode = "auto"
asyncio_mode = "auto"
markers = ["unstable"]

# Formatting tools configuration
[tool.black]
Expand Down
2 changes: 2 additions & 0 deletions tests/integration/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Copyright 2023 Canonical Ltd.
# See LICENSE file for licensing details.
25 changes: 24 additions & 1 deletion tests/integration/conftest.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,33 @@
# Copyright 2023 Canonical Ltd.
#!/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


@pytest.fixture(scope="module")
async def app_charm(ops_test: OpsTest):
"""Build the application charm."""
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

from juju.unit import Unit

from tests.integration.constants import DATABASE_NAME, POSTGRESQL
from .constants import DATABASE_NAME, POSTGRESQL

logger = logging.getLogger(__name__)

Expand Down
4 changes: 2 additions & 2 deletions tests/integration/test_charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import pytest
from pytest_operator.plugin import OpsTest

from tests.integration.constants import (
from .constants import (
APP,
DATA_INTEGRATOR,
DATABASE_NAME,
Expand All @@ -23,7 +23,7 @@
TOPIC_NAME,
ZOOKEEPER,
)
from tests.integration.helpers import (
from .helpers import (
check_logs,
fetch_action_database,
fetch_action_get_credentials,
Expand Down
2 changes: 2 additions & 0 deletions tests/unit/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Copyright 2023 Canonical Ltd.
# See LICENSE file for licensing details.
50 changes: 29 additions & 21 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -2,27 +2,27 @@
# See LICENSE file for licensing details.

[tox]
skipsdist=True
no_package = True
skip_missing_interpreters = True
envlist = fmt, lint, unit
env_list = lint, unit

[vars]
src_path = {toxinidir}/src/
tst_path = {toxinidir}/tests/
lib_path = {toxinidir}/lib/
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
all_path = {[vars]src_path} {[vars]tests_path} {[vars]lib_path}

[testenv]
setenv =
PYTHONPATH = {toxinidir}:{toxinidir}/lib:{[vars]src_path}
PYTHONBREAKPOINT=ipdb.set_trace
PY_COLORS=1
passenv =
PYTHONPATH
CHARM_BUILD_DIR
MODEL_SETTINGS
set_env =
PYTHONPATH = {tox_root}/lib:{[vars]src_path}
PYTHONBREAKPOINT=ipdb.set_trace
PY_COLORS=1
pass_env =
PYTHONPATH
CHARM_BUILD_DIR
MODEL_SETTINGS

[testenv:fmt]
[testenv:format]
allowlist_externals = poetry
description = Apply coding style standards to code
commands =
Expand All @@ -36,9 +36,9 @@ description = Check code against coding style standards
commands =
poetry install
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}
Expand All @@ -51,23 +51,31 @@ commands =
poetry install
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-lxd]
allowlist_externals = poetry
description = Run integration tests
pass_env =
{[testenv]pass_env}
CI
CI_PACKED_CHARMS
commands =
poetry install --with dev
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 --cloud=localhost {posargs}
poetry run pytest -v --tb native --log-cli-level=INFO -s --cloud=localhost {posargs} {[vars]tests_path}/integration/test_charm.py
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd make it more general to be consisnte with other repo


[testenv:integration-k8s]
allowlist_externals = poetry
description = Run integration tests
pass_env =
{[testenv]pass_env}
CI
CI_PACKED_CHARMS
commands =
poetry install --with dev
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 --cloud=microk8s {posargs}
poetry run pytest -v --tb native --log-cli-level=INFO -s --cloud=microk8s {posargs} {[vars]tests_path}/integration/test_charm.py
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd make it more general to be consisnte with other repo