Skip to content

Commit 587739c

Browse files
Cache charmcraft pack container, skip unstable tests except on schedule (#47)
Ported from canonical/mysql-k8s-operator#146
1 parent 569ffa0 commit 587739c

File tree

11 files changed

+151
-187
lines changed

11 files changed

+151
-187
lines changed

.github/workflows/ci.yaml

Lines changed: 47 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1+
# Copyright 2022 Canonical Ltd.
2+
# See LICENSE file for licensing details.
13
name: Tests
4+
25
on:
36
pull_request:
7+
schedule:
8+
- cron: '53 0 * * *' # Daily at 00:53 UTC
9+
# Triggered on push to branch "main" by .github/workflows/release.yaml
410
workflow_call:
511

612
jobs:
@@ -10,103 +16,70 @@ jobs:
1016
steps:
1117
- name: Checkout
1218
uses: actions/checkout@v3
13-
- name: Install dependencies
19+
- name: Install tox
20+
# TODO: Consider replacing with custom image on self-hosted runner OR pinning version
1421
run: python3 -m pip install tox
1522
- name: Run linters
16-
run: tox -e lint
23+
run: tox run -e lint
1724

1825
unit-test:
1926
name: Unit tests
2027
runs-on: ubuntu-22.04
2128
steps:
2229
- name: Checkout
2330
uses: actions/checkout@v3
24-
- name: Install dependencies
25-
run: python -m pip install tox
31+
- name: Install tox
32+
# TODO: Consider replacing with custom image on self-hosted runner OR pinning version
33+
run: python3 -m pip install tox
2634
- name: Run tests
27-
run: tox -e unit
28-
29-
integration-standalone:
30-
name: Integration tests for standalone charm
31-
needs:
32-
- lint
33-
- unit-test
34-
runs-on: ubuntu-22.04
35-
steps:
36-
- name: Checkout
37-
uses: actions/checkout@v3
38-
- name: Setup operator environment
39-
uses: charmed-kubernetes/actions-operator@main
40-
with:
41-
provider: lxd
42-
lxd-channel: 5.7/stable
43-
- name: Run integration tests
44-
run: tox -e standalone-integration
35+
run: tox run -e unit
4536

46-
integration-backend:
47-
name: Integration tests for backend relation
48-
needs:
49-
- lint
50-
- unit-test
51-
runs-on: ubuntu-22.04
52-
steps:
53-
- name: Checkout
54-
uses: actions/checkout@v3
55-
- name: Setup operator environment
56-
uses: charmed-kubernetes/actions-operator@main
57-
with:
58-
provider: lxd
59-
lxd-channel: 5.7/stable
60-
- name: Run integration tests
61-
run: tox -e backend-integration
37+
build:
38+
name: Build charms
39+
uses: canonical/data-platform-workflows/.github/workflows/build_charms_with_cache.yaml@v1
6240

63-
integration-client-relations:
64-
name: Integration tests for client relations
41+
integration-test:
42+
strategy:
43+
fail-fast: false
44+
matrix:
45+
tox-environments:
46+
- standalone-integration
47+
- backend-integration
48+
- client-relation-integration
49+
- legacy-client-relation-integration
50+
- legacy-client-relation-integration-admin
51+
- scaling-integration
52+
name: ${{ matrix.tox-environments }}
6553
needs:
6654
- lint
6755
- unit-test
56+
- build
6857
runs-on: ubuntu-22.04
6958
steps:
7059
- name: Checkout
7160
uses: actions/checkout@v3
7261
- name: Setup operator environment
62+
# TODO: Replace with custom image on self-hosted runner
7363
uses: charmed-kubernetes/actions-operator@main
7464
with:
7565
provider: lxd
7666
lxd-channel: 5.7/stable
77-
- name: Run integration tests
78-
run: tox -e client-relation-integration
79-
80-
integration-legacy-client-relations:
81-
name: Integration tests for legacy client relations
82-
needs:
83-
- lint
84-
- unit-test
85-
runs-on: ubuntu-latest
86-
steps:
87-
- name: Checkout
88-
uses: actions/checkout@v3
89-
- name: Setup operator environment
90-
uses: charmed-kubernetes/actions-operator@main
67+
- name: Download packed charm(s)
68+
uses: actions/download-artifact@v3
9169
with:
92-
provider: lxd
93-
lxd-channel: 5.7/stable
70+
name: ${{ needs.build.outputs.artifact-name }}
71+
- name: Select tests
72+
id: select-tests
73+
run: |
74+
if [ "${{ github.event_name }}" == "schedule" ]
75+
then
76+
echo Running unstable and stable tests
77+
echo "mark_expression=" >> $GITHUB_OUTPUT
78+
else
79+
echo Skipping unstable tests
80+
echo "mark_expression=not unstable" >> $GITHUB_OUTPUT
81+
fi
9482
- name: Run integration tests
95-
run: tox -e legacy-client-relation-integration
96-
97-
integration-scaling:
98-
name: Integration tests for scaling pgbouncer (microk8s)
99-
needs:
100-
- lint
101-
- unit-test
102-
runs-on: ubuntu-22.04
103-
steps:
104-
- name: Checkout
105-
uses: actions/checkout@v3
106-
- name: Setup operator environment
107-
uses: charmed-kubernetes/actions-operator@main
108-
with:
109-
provider: lxd
110-
lxd-channel: 5.7/stable
111-
- name: Run scaling integration tests
112-
run: tox -e scaling-integration
83+
run: tox run -e ${{ matrix.tox-environments }} -- -m '${{ steps.select-tests.outputs.mark_expression }}'
84+
env:
85+
CI_PACKED_CHARMS: ${{ needs.build.outputs.charms }}

CONTRIBUTING.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,21 @@ this operator.
2121

2222
## Developing
2323

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

2626
```shell
27-
tox --notest -e unit
28-
source .tox/unit/bin/activate
27+
tox devenv -e integration
28+
source venv/bin/activate
2929
```
3030

3131
### Testing
3232

3333
```shell
34-
tox -e fmt # update your code according to linting rules
35-
tox -e lint # code style
36-
tox -e unit # unit tests
37-
tox -e integration # integration tests
38-
tox # runs 'lint' and 'unit' environments
34+
tox run -e format # update your code according to linting rules
35+
tox run -e lint # code style
36+
tox run -e unit # unit tests
37+
tox run -e integration # integration tests
38+
tox # runs 'lint' and 'unit' environments
3939
```
4040

4141
## Build charm

pyproject.toml

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,7 @@ show_missing = true
1212
minversion = "6.0"
1313
log_cli_level = "INFO"
1414
asyncio_mode = "auto"
15-
markers = [
16-
"smoke: quick integration tests that can be run to quickly verify that the charm builds and deploys ok.",
17-
"dev: a quick development marker to run one test",
18-
"standalone: integration tests that relate to standalone charm function",
19-
"backend: integration tests that test backend relation to postgresql",
20-
"legacy_relation: integration tests that test legacy client relations",
21-
"client_relation: integration tests that test modern client relations",
22-
"scaling: integration tests for scaling pgbouncer",
23-
]
15+
markers = ["unstable"]
2416

2517
# Formatting tools configuration
2618
[tool.black]

tests/integration/conftest.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/usr/bin/env python3
2+
# Copyright 2022 Canonical Ltd.
3+
# See LICENSE file for licensing details.
4+
5+
import json
6+
import os
7+
from pathlib import Path
8+
9+
import pytest
10+
from pytest_operator.plugin import OpsTest
11+
12+
13+
@pytest.fixture(scope="module")
14+
def ops_test(ops_test: OpsTest) -> OpsTest:
15+
if os.environ.get("CI") == "true":
16+
# Running in GitHub Actions; skip build step
17+
# (GitHub Actions uses a separate, cached build step. See .github/workflows/ci.yaml)
18+
packed_charms = json.loads(os.environ["CI_PACKED_CHARMS"])
19+
20+
async def build_charm(charm_path, bases_index: int = None) -> Path:
21+
for charm in packed_charms:
22+
if Path(charm_path) == Path(charm["directory_path"]):
23+
if bases_index is None or bases_index == charm["bases_index"]:
24+
return charm["file_path"]
25+
raise ValueError(f"Unable to find .charm file for {bases_index=} at {charm_path=}")
26+
27+
ops_test.build_charm = build_charm
28+
return ops_test

tests/integration/relations/pgbouncer_provider/test_pgbouncer_provider.py

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@
4444

4545

4646
@pytest.mark.abort_on_fail
47-
@pytest.mark.client_relation
4847
async def test_database_relation_with_charm_libraries(
4948
ops_test: OpsTest, application_charm, pgb_charm
5049
):
@@ -81,7 +80,6 @@ async def test_database_relation_with_charm_libraries(
8180
await ops_test.model.wait_for_idle(status="active", raise_on_blocked=True)
8281

8382

84-
@pytest.mark.client_relation
8583
async def test_database_usage(ops_test: OpsTest):
8684
"""Check we can update and delete things."""
8785
update_query = (
@@ -100,7 +98,6 @@ async def test_database_usage(ops_test: OpsTest):
10098
assert "some data" in json.loads(run_update_query["results"])[0]
10199

102100

103-
@pytest.mark.client_relation
104101
async def test_database_version(ops_test: OpsTest):
105102
"""Check version is accurate."""
106103
version_query = "SELECT version();"
@@ -120,7 +117,6 @@ async def test_database_version(ops_test: OpsTest):
120117
assert version in json.loads(run_version_query["results"])[0][0]
121118

122119

123-
@pytest.mark.client_relation
124120
async def test_readonly_reads(ops_test: OpsTest):
125121
"""Check we can read things in readonly."""
126122
select_query = "SELECT data FROM test;"
@@ -136,7 +132,6 @@ async def test_readonly_reads(ops_test: OpsTest):
136132
assert "some data" in json.loads(run_select_query_readonly["results"])[0]
137133

138134

139-
@pytest.mark.client_relation
140135
async def test_cant_write_in_readonly(ops_test: OpsTest):
141136
"""Check we can't write in readonly."""
142137
drop_query = "DROP TABLE test;"
@@ -151,7 +146,6 @@ async def test_cant_write_in_readonly(ops_test: OpsTest):
151146
assert run_drop_query_readonly["Code"] == "1"
152147

153148

154-
@pytest.mark.client_relation
155149
async def test_database_admin_permissions(ops_test: OpsTest):
156150
"""Test admin permissions."""
157151
create_database_query = "CREATE DATABASE another_database;"
@@ -175,7 +169,6 @@ async def test_database_admin_permissions(ops_test: OpsTest):
175169
assert "no results to fetch" in json.loads(run_create_user_query["results"])
176170

177171

178-
@pytest.mark.client_relation
179172
async def test_no_read_only_endpoint_in_standalone_cluster(ops_test: OpsTest):
180173
"""Test that there is no read-only endpoint in a standalone cluster."""
181174
await scale_application(ops_test, PGB, 1)
@@ -193,7 +186,6 @@ async def test_no_read_only_endpoint_in_standalone_cluster(ops_test: OpsTest):
193186
), f"read-only-endpoints in pgb databag: {databag}"
194187

195188

196-
@pytest.mark.client_relation
197189
async def test_read_only_endpoint_in_scaled_up_cluster(ops_test: OpsTest):
198190
"""Test that there is read-only endpoint in a scaled up cluster."""
199191
await scale_application(ops_test, PGB, 2)
@@ -210,7 +202,6 @@ async def test_read_only_endpoint_in_scaled_up_cluster(ops_test: OpsTest):
210202
assert read_only_endpoints, f"read-only-endpoints not in pgb databag: {databag}"
211203

212204

213-
@pytest.mark.client_relation
214205
async def test_two_applications_dont_share_the_same_relation_data(
215206
ops_test: OpsTest, application_charm
216207
):
@@ -244,7 +235,6 @@ async def test_two_applications_dont_share_the_same_relation_data(
244235
assert application_connection_string != another_application_connection_string
245236

246237

247-
@pytest.mark.client_relation
248238
async def test_an_application_can_connect_to_multiple_database_clusters(
249239
ops_test: OpsTest, pgb_charm
250240
):
@@ -293,7 +283,6 @@ async def test_an_application_can_connect_to_multiple_database_clusters(
293283
assert application_connection_string != another_application_connection_string
294284

295285

296-
@pytest.mark.client_relation
297286
async def test_an_application_can_request_multiple_databases(ops_test: OpsTest, application_charm):
298287
"""Test that an application can request additional databases using the same interface.
299288
@@ -316,7 +305,6 @@ async def test_an_application_can_request_multiple_databases(ops_test: OpsTest,
316305
assert first_database_connection_string != second_database_connection_string
317306

318307

319-
@pytest.mark.client_relation
320308
async def test_with_legacy_relation(ops_test: OpsTest):
321309
"""Test that this relation and the legacy relation can be used simultaneously."""
322310
psql = "psql"
@@ -373,7 +361,6 @@ async def test_with_legacy_relation(ops_test: OpsTest):
373361
)
374362

375363

376-
@pytest.mark.client_relation
377364
async def test_scaling(ops_test: OpsTest):
378365
"""Check these relations all work when scaling pgbouncer."""
379366
await scale_application(ops_test, PGB, 1)
@@ -395,7 +382,6 @@ async def test_scaling(ops_test: OpsTest):
395382
)
396383

397384

398-
@pytest.mark.client_relation
399385
async def test_relation_broken(ops_test: OpsTest):
400386
"""Test that the user is removed when the relation is broken."""
401387
client_unit_name = ops_test.model.applications[CLIENT_APP_NAME].units[0].name
@@ -427,7 +413,6 @@ async def test_relation_broken(ops_test: OpsTest):
427413
assert "first-database_readonly" not in cfg["databases"].keys()
428414

429415

430-
@pytest.mark.client_relation
431416
async def test_relation_with_data_integrator(ops_test: OpsTest):
432417
"""Test that the charm can be related to the data integrator without extra user roles."""
433418
config = {"database-name": "test-database"}

tests/integration/relations/test_backend_database.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import logging
66
from pathlib import Path
77

8-
import pytest
98
import yaml
109
from pytest_operator.plugin import OpsTest
1110
from tenacity import RetryError, Retrying, stop_after_delay, wait_fixed
@@ -35,7 +34,6 @@
3534
RELATION = "backend-database"
3635

3736

38-
@pytest.mark.backend
3937
async def test_relate_pgbouncer_to_postgres(ops_test: OpsTest):
4038
"""Test that the pgbouncer and postgres charms can relate to one another."""
4139
# Build, deploy, and relate charms.
@@ -80,7 +78,6 @@ async def test_relate_pgbouncer_to_postgres(ops_test: OpsTest):
8078
logger.info(cfg.render())
8179

8280

83-
@pytest.mark.backend
8481
async def test_tls_encrypted_connection_to_postgres(ops_test: OpsTest):
8582
async with ops_test.fast_forward():
8683
# Relate PgBouncer to PostgreSQL.

0 commit comments

Comments
 (0)