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

DPE-4613 Test for multi-relation scale in/out #489

Merged
merged 12 commits into from
Sep 12, 2024
Merged
10 changes: 6 additions & 4 deletions src/relations/mysql_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,11 +222,13 @@ def _configure_endpoints(self, _) -> None:

relation_data = self.database.fetch_relation_data()
for relation in relations:
# only update endpoints if on_database_requested has executed
if relation.id not in relation_data:
continue
# only update endpoints if on_database_requested on any
# relation
if relation.id in relation_data:
break
return

self.charm._mysql.update_endpoints()
self.charm._mysql.update_endpoints()

def _on_update_status(self, _) -> None:
"""Handle the update status event.
Expand Down
99 changes: 99 additions & 0 deletions tests/integration/test_multi_relations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
#!/usr/bin/env python3
# Copyright 2024 Canonical Ltd.
# See LICENSE file for licensing details.


from pathlib import Path

import pytest
import yaml
from pytest_operator.plugin import OpsTest

DB_METADATA = yaml.safe_load(Path("./metadata.yaml").read_text())
SCALE_APPS = 7
SCALE_UNITS = 3


@pytest.mark.group(1)
@pytest.mark.abort_on_fail
async def test_build_and_deploy(ops_test: OpsTest):
"""Build the charm and deploy 1 units to ensure a cluster is formed."""
# Build and deploy charm from local source folder
db_charm = await ops_test.build_charm(".")

config = {"profile": "testing"}
taurus-forever marked this conversation as resolved.
Show resolved Hide resolved
resources = {"mysql-image": DB_METADATA["resources"]["mysql-image"]["upstream-source"]}

await ops_test.model.deploy(
db_charm,
application_name="mysql",
config=config,
num_units=1,
resources=resources,
series="jammy",
trust=True,
)

for i in range(SCALE_APPS):
config = {"database_name": f"database{i}", "sleep_interval": "2000"}
await ops_test.model.deploy(
"mysql-test-app",
application_name=f"app{i}",
num_units=1,
channel="latest/edge",
paulomach marked this conversation as resolved.
Show resolved Hide resolved
config=config,
)
await ops_test.model.deploy(
"mysql-router-k8s",
application_name=f"router{i}",
num_units=1,
channel="8.0/edge",
trust=True,
)


@pytest.mark.group(1)
@pytest.mark.abort_on_fail
async def test_relate_all(ops_test: OpsTest):
"""Relate all the applications to the database."""
for i in range(SCALE_APPS):
await ops_test.model.relate("mysql:database", f"router{i}:backend-database")
await ops_test.model.relate(f"app{i}:database", f"router{i}:database")

await ops_test.model.block_until(
lambda: all(unit.workload_status == "active" for unit in ops_test.model.units.values()),
timeout=60 * 25,
wait_period=5,
)


@pytest.mark.group(1)
@pytest.mark.abort_on_fail
async def test_scale_out(ops_test: OpsTest):
"""Scale database and routers."""
await ops_test.model.applications["mysql"].scale(SCALE_UNITS)
for i in range(SCALE_APPS):
await ops_test.model.applications[f"router{i}"].scale(SCALE_UNITS)
expected_unit_sum = SCALE_UNITS + 4 * SCALE_APPS
await ops_test.model.block_until(
lambda: all(unit.workload_status == "active" for unit in ops_test.model.units.values())
and len(ops_test.model.units) == expected_unit_sum,
timeout=60 * 30,
wait_period=5,
)


@pytest.mark.group(1)
@pytest.mark.abort_on_fail
async def test_scale_in(ops_test: OpsTest):
"""Scale database and routers."""
await ops_test.model.applications["mysql"].scale(1)
for i in range(SCALE_APPS):
await ops_test.model.applications[f"router{i}"].scale(1)
expected_unit_sum = 1 + 2 * SCALE_APPS
await ops_test.model.block_until(
lambda: all(unit.workload_status == "active" for unit in ops_test.model.units.values())
and len(ops_test.model.units) == expected_unit_sum,
timeout=60 * 15,
wait_period=5,
)
Loading