Skip to content

Commit 0934aba

Browse files
[DPE-4985] Create fixture for HA cluster set up + break HA tests into separate groups (#475)
* Create fixture for HA cluster set up + break HA tests into separate groups * Update outdated charm libs * Use dump plugin instead of nil to prime the scripts directory * Update outdated charm libs * Use standard way of priming directories in charm
1 parent 88d684e commit 0934aba

File tree

6 files changed

+77
-76
lines changed

6 files changed

+77
-76
lines changed

charmcraft.yaml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ bases:
1010
channel: "22.04"
1111
architectures: [arm64]
1212
parts:
13+
files:
14+
plugin: dump
15+
source: .
16+
prime:
17+
- scripts
1318
charm:
1419
override-pull: |
1520
craftctl default
@@ -25,5 +30,3 @@ parts:
2530
- pkg-config
2631
- rustc
2732
- cargo
28-
prime:
29-
- scripts

tests/integration/high_availability/conftest.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,11 @@
1212
from .. import juju_
1313
from .high_availability_helpers import (
1414
APPLICATION_DEFAULT_APP_NAME,
15+
deploy_and_scale_application,
16+
deploy_and_scale_mysql,
1517
deploy_chaos_mesh,
1618
destroy_chaos_mesh,
19+
relate_mysql_and_application,
1720
)
1821

1922
logger = logging.getLogger(__name__)
@@ -53,3 +56,22 @@ def built_charm(ops_test: OpsTest) -> pathlib.Path:
5356
charms_dst_dir = ops_test.tmp_path / "charms"
5457
packed_charm = list(charms_dst_dir.glob("*.charm"))
5558
return packed_charm[0].resolve(strict=True)
59+
60+
61+
@pytest.fixture()
62+
async def highly_available_cluster(ops_test: OpsTest) -> None:
63+
"""Run the set up for high availability tests.
64+
65+
Args:
66+
ops_test: The ops test framework
67+
"""
68+
logger.info("Deploying mysql-k8s and scaling to 3 units")
69+
mysql_application_name = await deploy_and_scale_mysql(ops_test)
70+
71+
logger.info("Deploying mysql-test-app")
72+
application_name = await deploy_and_scale_application(ops_test)
73+
74+
logger.info("Relating mysql-k8s with mysql-test-app")
75+
await relate_mysql_and_application(ops_test, mysql_application_name, application_name)
76+
77+
yield

tests/integration/high_availability/high_availability_helpers.py

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import subprocess
88
import tempfile
99
from pathlib import Path
10-
from typing import List, Optional, Tuple
10+
from typing import List, Optional
1111

1212
import kubernetes
1313
import lightkube
@@ -287,24 +287,6 @@ def destroy_chaos_mesh(namespace: str) -> None:
287287
)
288288

289289

290-
async def high_availability_test_setup(ops_test: OpsTest) -> Tuple[str, str]:
291-
"""Run the set up for high availability tests.
292-
293-
Args:
294-
ops_test: The ops test framework
295-
"""
296-
logger.info("Deploying mysql-k8s and scaling to 3 units")
297-
mysql_application_name = await deploy_and_scale_mysql(ops_test)
298-
299-
logger.info("Deploying mysql-test-app")
300-
application_name = await deploy_and_scale_application(ops_test)
301-
302-
logger.info("Relating mysql-k8s with mysql-test-app")
303-
await relate_mysql_and_application(ops_test, mysql_application_name, application_name)
304-
305-
return mysql_application_name, application_name
306-
307-
308290
async def send_signal_to_pod_container_process(
309291
model_name: str, unit_name: str, container_name: str, process: str, signal_code: str
310292
) -> None:

tests/integration/high_availability/test_node_drain.py

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@
1414
ensure_all_units_continuous_writes_incrementing,
1515
ensure_n_online_mysql_members,
1616
evict_pod,
17+
get_application_name,
1718
get_pod,
1819
get_pod_pvcs,
1920
get_pod_pvs,
20-
high_availability_test_setup,
2121
)
2222

2323
logger = logging.getLogger(__name__)
@@ -28,18 +28,12 @@
2828

2929

3030
@pytest.mark.group(1)
31-
@pytest.mark.skip_if_deployed
3231
@pytest.mark.abort_on_fail
33-
async def test_build_and_deploy(ops_test: OpsTest) -> None:
34-
"""Simple test to ensure that the mysql and application charms get deployed."""
35-
await high_availability_test_setup(ops_test)
36-
37-
38-
@pytest.mark.group(1)
39-
@pytest.mark.abort_on_fail
40-
async def test_pod_eviction_and_pvc_deletion(ops_test: OpsTest, continuous_writes) -> None:
32+
async def test_pod_eviction_and_pvc_deletion(
33+
ops_test: OpsTest, highly_available_cluster, continuous_writes
34+
) -> None:
4135
"""Test behavior when node drains - pod is evicted and pvs are rotated."""
42-
mysql_application_name, _ = await high_availability_test_setup(ops_test)
36+
mysql_application_name = get_application_name(ops_test, "mysql")
4337

4438
logger.info("Waiting until 3 mysql instances are online")
4539
# ensure all units in the cluster are online

tests/integration/high_availability/test_replication.py

Lines changed: 18 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
deploy_and_scale_mysql,
2424
ensure_all_units_continuous_writes_incrementing,
2525
ensure_n_online_mysql_members,
26-
high_availability_test_setup,
26+
get_application_name,
2727
insert_data_into_mysql_and_validate_replication,
2828
)
2929

@@ -32,17 +32,13 @@
3232
TIMEOUT = 15 * 60
3333

3434

35-
@pytest.mark.group(1)
36-
async def test_build_and_deploy(ops_test: OpsTest) -> None:
37-
"""Simple test to ensure that the mysql and application charms get deployed."""
38-
await high_availability_test_setup(ops_test)
39-
40-
4135
@pytest.mark.group(1)
4236
@pytest.mark.abort_on_fail
43-
async def test_check_consistency(ops_test: OpsTest, continuous_writes) -> None:
37+
async def test_check_consistency(
38+
ops_test: OpsTest, highly_available_cluster, continuous_writes
39+
) -> None:
4440
"""Test to write to primary, and read the same data back from replicas."""
45-
mysql_application_name, _ = await high_availability_test_setup(ops_test)
41+
mysql_application_name = get_application_name(ops_test, "mysql")
4642

4743
# assert that there are 3 units in the mysql cluster
4844
assert len(ops_test.model.applications[mysql_application_name].units) == 3
@@ -54,11 +50,13 @@ async def test_check_consistency(ops_test: OpsTest, continuous_writes) -> None:
5450
await ensure_all_units_continuous_writes_incrementing(ops_test)
5551

5652

57-
@pytest.mark.group(1)
53+
@pytest.mark.group(2)
5854
@pytest.mark.abort_on_fail
59-
async def test_no_replication_across_clusters(ops_test: OpsTest, continuous_writes) -> None:
55+
async def test_no_replication_across_clusters(
56+
ops_test: OpsTest, highly_available_cluster, continuous_writes
57+
) -> None:
6058
"""Test to ensure that writes to one cluster do not replicate to another cluster."""
61-
mysql_application_name, _ = await high_availability_test_setup(ops_test)
59+
mysql_application_name = get_application_name(ops_test, "mysql")
6260

6361
# assert that there are 3 units in the mysql cluster
6462
assert len(ops_test.model.applications[mysql_application_name].units) == 3
@@ -112,15 +110,15 @@ async def test_no_replication_across_clusters(ops_test: OpsTest, continuous_writ
112110
await clean_up_database_and_table(ops_test, database_name, table_name)
113111

114112

115-
@pytest.mark.group(1)
113+
@pytest.mark.group(3)
116114
@pytest.mark.abort_on_fail
117-
async def test_scaling_without_data_loss(ops_test: OpsTest) -> None:
115+
async def test_scaling_without_data_loss(ops_test: OpsTest, highly_available_cluster) -> None:
118116
"""Test to ensure that data is preserved when a unit is scaled up and then down.
119117
120118
Ensures that there are no running continuous writes as the extra data in the
121119
database makes scaling up slower.
122120
"""
123-
mysql_application_name, _ = await high_availability_test_setup(ops_test)
121+
mysql_application_name = get_application_name(ops_test, "mysql")
124122

125123
# assert that there are 3 units in the mysql cluster
126124
assert len(ops_test.model.applications[mysql_application_name].units) == 3
@@ -191,13 +189,13 @@ async def test_scaling_without_data_loss(ops_test: OpsTest) -> None:
191189
await clean_up_database_and_table(ops_test, database_name, table_name)
192190

193191

194-
# TODO: move test immediately after "test_build_and_deploy" once the following issue is resolved
195-
# https://github.com/canonical/mysql-k8s-operator/issues/102
196-
@pytest.mark.group(1)
192+
@pytest.mark.group(4)
197193
@pytest.mark.abort_on_fail
198-
async def test_kill_primary_check_reelection(ops_test: OpsTest, continuous_writes) -> None:
194+
async def test_kill_primary_check_reelection(
195+
ops_test: OpsTest, highly_available_cluster, continuous_writes
196+
) -> None:
199197
"""Test to kill the primary under load and ensure re-election of primary."""
200-
mysql_application_name, _ = await high_availability_test_setup(ops_test)
198+
mysql_application_name = get_application_name(ops_test, "mysql")
201199

202200
await ensure_all_units_continuous_writes_incrementing(ops_test)
203201

tests/integration/high_availability/test_self_healing.py

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424
ensure_all_units_continuous_writes_incrementing,
2525
ensure_n_online_mysql_members,
2626
ensure_process_not_running,
27+
get_application_name,
2728
get_process_stat,
28-
high_availability_test_setup,
2929
insert_data_into_mysql_and_validate_replication,
3030
isolate_instance_from_cluster,
3131
remove_instance_isolation,
@@ -40,17 +40,13 @@
4040
TIMEOUT = 40 * 60
4141

4242

43-
@pytest.mark.group(1)
44-
async def test_build_and_deploy(ops_test: OpsTest) -> None:
45-
"""Simple test to ensure that the mysql and application charms get deployed."""
46-
await high_availability_test_setup(ops_test)
47-
48-
4943
@pytest.mark.group(1)
5044
@pytest.mark.abort_on_fail
51-
async def test_kill_db_process(ops_test: OpsTest, continuous_writes) -> None:
45+
async def test_kill_db_process(
46+
ops_test: OpsTest, highly_available_cluster, continuous_writes
47+
) -> None:
5248
"""Test to send a SIGKILL to the primary db process and ensure that the cluster self heals."""
53-
mysql_application_name, _ = await high_availability_test_setup(ops_test)
49+
mysql_application_name = get_application_name(ops_test, "mysql")
5450

5551
logger.info("Waiting until 3 mysql instances are online")
5652
# ensure all units in the cluster are online
@@ -109,12 +105,14 @@ async def test_kill_db_process(ops_test: OpsTest, continuous_writes) -> None:
109105
await clean_up_database_and_table(ops_test, database_name, table_name)
110106

111107

112-
@pytest.mark.group(1)
108+
@pytest.mark.group(2)
113109
@pytest.mark.abort_on_fail
114110
@pytest.mark.unstable
115-
async def test_freeze_db_process(ops_test: OpsTest, continuous_writes) -> None:
111+
async def test_freeze_db_process(
112+
ops_test: OpsTest, highly_available_cluster, continuous_writes
113+
) -> None:
116114
"""Test to send a SIGSTOP to the primary db process and ensure that the cluster self heals."""
117-
mysql_application_name, _ = await high_availability_test_setup(ops_test)
115+
mysql_application_name = get_application_name(ops_test, "mysql")
118116

119117
# ensure all units in the cluster are online
120118
assert await ensure_n_online_mysql_members(
@@ -230,11 +228,13 @@ async def test_freeze_db_process(ops_test: OpsTest, continuous_writes) -> None:
230228
await ensure_all_units_continuous_writes_incrementing(ops_test)
231229

232230

233-
@pytest.mark.group(1)
231+
@pytest.mark.group(3)
234232
@pytest.mark.abort_on_fail
235-
async def test_graceful_crash_of_primary(ops_test: OpsTest, continuous_writes) -> None:
233+
async def test_graceful_crash_of_primary(
234+
ops_test: OpsTest, highly_available_cluster, continuous_writes
235+
) -> None:
236236
"""Test to send SIGTERM to primary instance and then verify recovery."""
237-
mysql_application_name, _ = await high_availability_test_setup(ops_test)
237+
mysql_application_name = get_application_name(ops_test, "mysql")
238238

239239
logger.info("Ensuring that there are 3 online mysql members")
240240
assert await ensure_n_online_mysql_members(
@@ -293,13 +293,13 @@ async def test_graceful_crash_of_primary(ops_test: OpsTest, continuous_writes) -
293293
await ensure_all_units_continuous_writes_incrementing(ops_test)
294294

295295

296-
@pytest.mark.group(1)
296+
@pytest.mark.group(4)
297297
@pytest.mark.abort_on_fail
298298
async def test_network_cut_affecting_an_instance(
299-
ops_test: OpsTest, continuous_writes, chaos_mesh
299+
ops_test: OpsTest, highly_available_cluster, continuous_writes, chaos_mesh
300300
) -> None:
301301
"""Test for a network cut affecting an instance."""
302-
mysql_application_name, _ = await high_availability_test_setup(ops_test)
302+
mysql_application_name = get_application_name(ops_test, "mysql")
303303

304304
logger.info("Ensuring that there are 3 online mysql members")
305305
assert await ensure_n_online_mysql_members(
@@ -377,12 +377,14 @@ async def test_network_cut_affecting_an_instance(
377377
await ensure_all_units_continuous_writes_incrementing(ops_test)
378378

379379

380-
@pytest.mark.group(1)
380+
@pytest.mark.group(5)
381381
@pytest.mark.abort_on_fail
382382
@pytest.mark.unstable
383-
async def test_graceful_full_cluster_crash_test(ops_test: OpsTest, continuous_writes) -> None:
383+
async def test_graceful_full_cluster_crash_test(
384+
ops_test: OpsTest, highly_available_cluster, continuous_writes
385+
) -> None:
384386
"""Test to send SIGTERM to all units and then ensure that the cluster recovers."""
385-
mysql_application_name, _ = await high_availability_test_setup(ops_test)
387+
mysql_application_name = get_application_name(ops_test, "mysql")
386388

387389
logger.info("Ensure there are 3 online mysql members")
388390
assert await ensure_n_online_mysql_members(
@@ -448,11 +450,11 @@ async def test_graceful_full_cluster_crash_test(ops_test: OpsTest, continuous_wr
448450
await ensure_all_units_continuous_writes_incrementing(ops_test)
449451

450452

451-
@pytest.mark.group(1)
453+
@pytest.mark.group(6)
452454
@pytest.mark.abort_on_fail
453-
async def test_single_unit_pod_delete(ops_test: OpsTest) -> None:
455+
async def test_single_unit_pod_delete(ops_test: OpsTest, highly_available_cluster) -> None:
454456
"""Delete the pod in a single unit deployment and write data to new pod."""
455-
mysql_application_name, _ = await high_availability_test_setup(ops_test)
457+
mysql_application_name = get_application_name(ops_test, "mysql")
456458

457459
logger.info("Scale mysql application to 1 unit that is active")
458460
async with ops_test.fast_forward("60s"):

0 commit comments

Comments
 (0)