Skip to content

Commit 68208fe

Browse files
Fix integration tests
1 parent b3b182c commit 68208fe

File tree

4 files changed

+54
-144
lines changed

4 files changed

+54
-144
lines changed

poetry.lock

Lines changed: 14 additions & 43 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ package-mode = false
66
requires-poetry = ">=2.0.0"
77

88
[tool.poetry.dependencies]
9-
python = "^3.8.6" # ^3.8.6 required by juju
9+
python = "^3.9.0" # ^3.9.0 required by tomli-w
1010
# breaking change in ops 2.10.0: https://github.com/canonical/operator/pull/1091#issuecomment-1888644075
1111
ops = "^2.9.0, <2.10"
1212
tenacity = "^9.0.0"
@@ -55,6 +55,8 @@ mysql-connector-python = "~8.0.33"
5555
tenacity = "^9.0.0"
5656
ops = "^2.9.0"
5757
allure-pytest-default-results = "^0.1.2"
58+
tomli = "^2.2.1"
59+
tomli-w = "^1.2.0"
5860

5961
[tool.poetry.group.build-refresh-version]
6062
optional = true

tests/integration/helpers.py

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
from typing import Dict, List, Optional
99

1010
import tenacity
11-
from juju.model import Model
1211
from juju.unit import Unit
1312
from pytest_operator.plugin import OpsTest
1413

@@ -410,41 +409,6 @@ async def ensure_all_units_continuous_writes_incrementing(
410409
last_max_written_value = max_written_value
411410

412411

413-
async def get_workload_version(ops_test: OpsTest, unit_name: str) -> str:
414-
"""Get the workload version of the deployed router charm."""
415-
return_code, output, _ = await ops_test.juju(
416-
"ssh",
417-
unit_name,
418-
"sudo",
419-
"cat",
420-
f"/var/lib/juju/agents/unit-{unit_name.replace('/', '-')}/charm/workload_version",
421-
)
422-
423-
assert return_code == 0
424-
return output.strip()
425-
426-
427-
async def get_leader_unit(
428-
ops_test: Optional[OpsTest], app_name: str, model: Optional[Model] = None
429-
) -> Optional[Unit]:
430-
"""Get the leader unit of a given application.
431-
432-
Args:
433-
ops_test: The ops test framework instance
434-
app_name: The name of the application
435-
model: The model to use (overrides ops_test.model)
436-
"""
437-
leader_unit = None
438-
if not model:
439-
model = ops_test.model
440-
for unit in model.applications[app_name].units:
441-
if await unit.is_leader_from_status():
442-
leader_unit = unit
443-
break
444-
445-
return leader_unit
446-
447-
448412
def get_juju_status(model_name: str) -> str:
449413
"""Return the juju status output.
450414

tests/integration/test_upgrade.py

Lines changed: 37 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,21 @@
55
import logging
66
import os
77
import pathlib
8-
import platform
9-
import re
108
import shutil
119
import typing
1210
import zipfile
1311

1412
import pytest
15-
import tenacity
13+
import tomli
14+
import tomli_w
15+
from packaging.version import Version
1616
from pytest_operator.plugin import OpsTest
1717

18-
import snap
19-
2018
from .helpers import (
2119
APPLICATION_DEFAULT_APP_NAME,
2220
MYSQL_DEFAULT_APP_NAME,
2321
MYSQL_ROUTER_DEFAULT_APP_NAME,
2422
ensure_all_units_continuous_writes_incrementing,
25-
get_juju_status,
26-
get_leader_unit,
27-
get_workload_version,
2823
)
2924
from .juju_ import run_action
3025

@@ -91,9 +86,6 @@ async def test_upgrade_from_edge(ops_test: OpsTest, charm, continuous_writes) ->
9186
await ensure_all_units_continuous_writes_incrementing(ops_test)
9287

9388
mysql_router_application = ops_test.model.applications[MYSQL_ROUTER_APP_NAME]
94-
mysql_router_unit = mysql_router_application.units[0]
95-
96-
old_workload_version = await get_workload_version(ops_test, mysql_router_unit.name)
9789

9890
logger.info("Build charm locally")
9991
global temporary_charm
@@ -111,23 +103,26 @@ async def test_upgrade_from_edge(ops_test: OpsTest, charm, continuous_writes) ->
111103
lambda: mysql_router_application.status == "blocked", timeout=TIMEOUT
112104
)
113105
assert (
114-
"resume-upgrade" in mysql_router_application.status_message
115-
), "mysql router application status not indicating that user should resume upgrade"
116-
117-
for attempt in tenacity.Retrying(
118-
reraise=True,
119-
stop=tenacity.stop_after_delay(SMALL_TIMEOUT),
120-
wait=tenacity.wait_fixed(10),
121-
):
122-
with attempt:
123-
assert "+testupgrade" in get_juju_status(
124-
ops_test.model.name
125-
), "None of the units are upgraded"
106+
"resume-refresh" in mysql_router_application.status_message
107+
), "mysql router application status not indicating that user should resume refresh"
108+
109+
logger.info("Wait for first unit to upgrade")
110+
async with ops_test.fast_forward("60s"):
111+
await ops_test.model.wait_for_idle(
112+
[MYSQL_ROUTER_APP_NAME],
113+
idle_period=30,
114+
timeout=TIMEOUT,
115+
)
126116

127-
mysql_router_leader_unit = await get_leader_unit(ops_test, MYSQL_ROUTER_APP_NAME)
117+
# Highest to lowest unit number
118+
refresh_order = sorted(
119+
mysql_router_application.units,
120+
key=lambda unit: int(unit.name.split("/")[1]),
121+
reverse=True,
122+
)
128123

129-
logger.info("Running resume-upgrade on the mysql router leader unit")
130-
await run_action(mysql_router_leader_unit, "resume-upgrade")
124+
logger.info("Running resume-refresh on the mysql router leader unit")
125+
await run_action(refresh_order[1], "resume-refresh")
131126

132127
logger.info("Waiting for upgrade to complete on all units")
133128
await ops_test.model.wait_for_idle(
@@ -137,14 +132,6 @@ async def test_upgrade_from_edge(ops_test: OpsTest, charm, continuous_writes) ->
137132
timeout=UPGRADE_TIMEOUT,
138133
)
139134

140-
workload_version_file = pathlib.Path("workload_version")
141-
repo_workload_version = workload_version_file.read_text().strip()
142-
143-
for unit in mysql_router_application.units:
144-
workload_version = await get_workload_version(ops_test, unit.name)
145-
assert workload_version == f"{repo_workload_version}+testupgrade"
146-
assert old_workload_version != workload_version
147-
148135
await ensure_all_units_continuous_writes_incrementing(ops_test)
149136

150137
await ops_test.model.wait_for_idle(
@@ -193,17 +180,6 @@ async def test_fail_and_rollback(ops_test: OpsTest, charm, continuous_writes) ->
193180
apps=[MYSQL_ROUTER_APP_NAME], status="active", timeout=TIMEOUT, idle_period=30
194181
)
195182

196-
workload_version_file = pathlib.Path("workload_version")
197-
repo_workload_version = workload_version_file.read_text().strip()
198-
199-
for unit in mysql_router_application.units:
200-
charm_workload_version = await get_workload_version(ops_test, unit.name)
201-
assert charm_workload_version == f"{repo_workload_version}+testupgrade"
202-
203-
await ops_test.model.wait_for_idle(
204-
apps=[MYSQL_ROUTER_APP_NAME], status="active", timeout=TIMEOUT
205-
)
206-
207183
logger.info("Ensure continuous writes after rollback procedure")
208184
await ensure_all_units_continuous_writes_incrementing(ops_test)
209185

@@ -216,31 +192,28 @@ def create_valid_upgrade_charm(charm_file: typing.Union[str, pathlib.Path]) -> N
216192
217193
Upgrades require a new snap revision to avoid no-oping.
218194
"""
219-
workload_version_file = pathlib.Path("workload_version")
220-
workload_version = workload_version_file.read_text().strip()
195+
with pathlib.Path("refresh_versions.toml").open("rb") as file:
196+
versions = tomli.load(file)
197+
198+
# charm needs to refresh snap to be able to avoid no-op when upgrading.
199+
# set an old revision of the snap
200+
versions["snap"]["revisions"]["x86_64"] = "121"
201+
versions["snap"]["revisions"]["aarch64"] = "122"
221202

222203
with zipfile.ZipFile(charm_file, mode="a") as charm_zip:
223-
charm_zip.writestr("workload_version", f"{workload_version}+testupgrade\n")
224-
225-
# charm needs to refresh snap to be able to avoid no-op when upgrading.
226-
# set an old revision of the snap
227-
snap_file = pathlib.Path("src/snap.py")
228-
content = snap_file.read_text()
229-
old_revision = {"x86_64": "121", "aarch64": "122"}[platform.machine()]
230-
new_snap_content = re.sub(
231-
f'"{platform.machine()}": "{snap.revision}"',
232-
f'"{platform.machine()}": "{old_revision}"',
233-
str(content),
234-
)
235-
charm_zip.writestr("src/snap.py", new_snap_content)
204+
charm_zip.writestr("refresh_versions.toml", tomli_w.dumps(versions))
236205

237206

238207
def create_invalid_upgrade_charm(charm_file: typing.Union[str, pathlib.Path]) -> None:
239208
"""Create an invalid mysql router charm for upgrade."""
240-
workload_version_file = pathlib.Path("workload_version")
241-
old_workload_version = workload_version_file.read_text().strip()
242-
[major, minor, patch] = old_workload_version.split(".")
209+
with pathlib.Path("refresh_versions.toml").open("rb") as file:
210+
versions = tomli.load(file)
211+
212+
old_version = Version(versions["workload"])
213+
new_version = Version(f"{old_version.major - 1}.{old_version.minor}.{old_version.micro}")
214+
versions["workload"] = str(new_version)
215+
versions["charm"] = "8.0/0.0.0"
243216

244217
with zipfile.ZipFile(charm_file, mode="a") as charm_zip:
245218
# an invalid charm version because the major workload_version is one less than the current workload_version
246-
charm_zip.writestr("workload_version", f"{int(major) - 1}.{minor}.{patch}+testrollback\n")
219+
charm_zip.writestr("refresh_versions.toml", tomli_w.dumps(versions))

0 commit comments

Comments
 (0)