Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
152 changes: 48 additions & 104 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
# Copyright 2022 Canonical Ltd.
# See LICENSE file for licensing details.
name: Tests

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:
Expand All @@ -10,136 +16,74 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Install dependencies
- 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 -e lint
run: tox run -e lint

unit-test:
name: Unit tests
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Install dependencies
run: python -m pip install tox
- 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 -e unit
run: tox run -e unit
- name: Upload Coverage to Codecov
uses: codecov/codecov-action@v3

integration-test-lxd-charm:
name: Integration tests for charm deployment (lxd)
needs:
- lint
- unit-test
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup operator environment
uses: charmed-kubernetes/actions-operator@main
with:
provider: lxd
- name: Run integration tests
run: tox -e charm-integration

integration-test-lxd-database-relation:
name: Integration tests for database relation (lxd)
needs:
- lint
- unit-test
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup operator environment
uses: charmed-kubernetes/actions-operator@main
with:
provider: lxd
# This is needed until https://bugs.launchpad.net/juju/+bug/1992833 is fixed.
bootstrap-options: "--agent-version 2.9.34"
- name: Run integration tests
run: tox -e database-relation-integration

integration-test-lxd-db-relation:
name: Integration tests for db relation (lxd)
needs:
- lint
- unit-test
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup operator environment
uses: charmed-kubernetes/actions-operator@main
with:
provider: lxd
- name: Run integration tests
run: tox -e db-relation-integration

integration-test-lxd-db-admin-relation:
name: Integration tests for db-admin relation (lxd)
needs:
- lint
- unit-test
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup operator environment
uses: charmed-kubernetes/actions-operator@main
with:
provider: lxd
- name: Run integration tests
run: tox -e db-admin-relation-integration
build:
name: Build charms
uses: canonical/data-platform-workflows/.github/workflows/build_charms_with_cache.yaml@v1

integration-test-ha-self-healing-rotation:
name: Integration tests for high availability self healing (lxd)
integration-test:
strategy:
fail-fast: false
matrix:
tox-environments:
- charm-integration
- database-relation-integration
- db-relation-integration
- db-admin-relation-integration
- ha-self-healing-integration
- password-rotation-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: lxd
# This is needed until https://bugs.launchpad.net/juju/+bug/1992833 is fixed.
bootstrap-options: "--agent-version 2.9.34"
- name: Run integration tests
run: tox -e ha-self-healing-integration

integration-test-lxd-password-rotation:
name: Integration tests for password rotation (lxd)
needs:
- lint
- unit-test
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup operator environment
uses: charmed-kubernetes/actions-operator@main
with:
provider: lxd
- name: Run integration tests
run: tox -e password-rotation-integration

integration-test-lxd-tls:
name: Integration tests for TLS (lxd)
needs:
- lint
- unit-test
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup operator environment
uses: charmed-kubernetes/actions-operator@main
- name: Download packed charm(s)
uses: actions/download-artifact@v3
with:
provider: lxd
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 tls-integration
run: tox run -e ${{ matrix.tox-environments }} -- -m '${{ steps.select-tests.outputs.mark_expression }}'
env:
CI_PACKED_CHARMS: ${{ needs.build.outputs.charms }}
17 changes: 9 additions & 8 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,24 @@ this operator.

## 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
```


## Build charm

Build the charm in this git repository using:
Expand Down
10 changes: 1 addition & 9 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,7 @@ exclude_lines = [
minversion = "6.0"
log_cli_level = "INFO"
asyncio_mode = "auto"
markers = [
"charm_tests",
"database_relation_tests",
"db_relation_tests",
"db_admin_relation_tests",
"ha_self_healing_tests",
"password_rotation_tests",
"tls_tests",
]
markers = ["unstable"]

# Formatting tools configuration
[tool.black]
Expand Down
25 changes: 24 additions & 1 deletion tests/integration/conftest.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,33 @@
#!/usr/bin/env python3
# Copyright 2022 Canonical Ltd.
# See LICENSE file for licensing details.
import pytest as pytest

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 charm(ops_test: OpsTest):
"""Build the charm-under-test."""
Expand Down
11 changes: 5 additions & 6 deletions tests/integration/ha_tests/test_self_healing.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@


@pytest.mark.abort_on_fail
@pytest.mark.ha_self_healing_tests
async def test_build_and_deploy(ops_test: OpsTest) -> None:
"""Build and deploy three unit of PostgreSQL."""
# It is possible for users to provide their own cluster for HA testing. Hence, check if there
Expand All @@ -56,7 +55,7 @@ async def test_build_and_deploy(ops_test: OpsTest) -> None:
await ops_test.model.wait_for_idle(status="active", timeout=1000)


@pytest.mark.ha_self_healing_tests
@pytest.mark.unstable
@pytest.mark.parametrize("process", DB_PROCESSES)
async def test_kill_db_process(
ops_test: OpsTest, process: str, continuous_writes, master_start_timeout
Expand Down Expand Up @@ -116,7 +115,7 @@ async def test_kill_db_process(
), "secondary not up to date with the cluster after restarting."


@pytest.mark.ha_self_healing_tests
@pytest.mark.unstable
@pytest.mark.parametrize("process", DB_PROCESSES)
async def test_freeze_db_process(
ops_test: OpsTest, process: str, continuous_writes, master_start_timeout
Expand Down Expand Up @@ -182,7 +181,7 @@ async def test_freeze_db_process(
), "secondary not up to date with the cluster after restarting."


@pytest.mark.ha_self_healing_tests
@pytest.mark.unstable
@pytest.mark.parametrize("process", DB_PROCESSES)
async def test_restart_db_process(
ops_test: OpsTest, process: str, continuous_writes, master_start_timeout
Expand Down Expand Up @@ -235,7 +234,7 @@ async def test_restart_db_process(
), "secondary not up to date with the cluster after restarting."


@pytest.mark.ha_self_healing_tests
@pytest.mark.unstable
@pytest.mark.parametrize("process", [PATRONI_PROCESS])
@pytest.mark.parametrize("signal", ["SIGTERM", "SIGKILL"])
async def test_full_cluster_restart(
Expand Down Expand Up @@ -293,7 +292,7 @@ async def test_full_cluster_restart(
assert total_expected_writes == actual_writes, "writes to the db were missed."


@pytest.mark.ha_self_healing_tests
@pytest.mark.unstable
async def test_forceful_restart_without_data_and_transaction_logs(
ops_test: OpsTest,
continuous_writes,
Expand Down
Loading