Skip to content

Commit e5c14a1

Browse files
Fix 16/edge refresh tests (including refresh to the same snap revision) (#918)
* Update refresh tests to modify charm to ensure refresh off edge or stable * Fix lint warnings * Store temporary charms in /tmp for upgrade_from_stable tests * Use force-refresh-start instead of forcing refresh by updating versions * Handle same snap revision situation in upgrade tests Signed-off-by: Marcelo Henrique Neppel <[email protected]> --------- Signed-off-by: Marcelo Henrique Neppel <[email protected]> Co-authored-by: Shayan Patel <[email protected]>
1 parent 8ac7b57 commit e5c14a1

File tree

2 files changed

+77
-32
lines changed

2 files changed

+77
-32
lines changed

tests/integration/ha_tests/test_upgrade.py

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
# See LICENSE file for licensing details.
33

44
import logging
5-
import pathlib
65
import platform
76
import shutil
87
import zipfile
@@ -40,7 +39,7 @@ async def test_deploy_latest(ops_test: OpsTest) -> None:
4039
"-n",
4140
3,
4241
"--channel",
43-
"16/edge/test-refresh-v3-workload2", # TODO remove branch
42+
"16/edge",
4443
"--config",
4544
"profile=testing",
4645
"--base",
@@ -90,21 +89,44 @@ async def test_upgrade_from_edge(ops_test: OpsTest, continuous_writes, charm) ->
9089
await application.refresh(path=charm)
9190

9291
logger.info("Wait for upgrade to start")
93-
await ops_test.model.block_until(lambda: application.status == "blocked", timeout=TIMEOUT)
94-
95-
logger.info("Wait for first unit to upgrade")
96-
async with ops_test.fast_forward("60s"):
97-
await ops_test.model.wait_for_idle(
98-
apps=[DATABASE_APP_NAME], idle_period=30, timeout=TIMEOUT
92+
try:
93+
# Blocked status is expected due to compatibility checks.
94+
await ops_test.model.block_until(lambda: application.status == "blocked", timeout=60 * 3)
95+
96+
logger.info("Wait for refresh to block due to compatibility checks")
97+
async with ops_test.fast_forward("60s"):
98+
await ops_test.model.wait_for_idle(
99+
apps=[DATABASE_APP_NAME], idle_period=30, timeout=TIMEOUT
100+
)
101+
102+
assert "Refresh incompatible" in application.status_message, (
103+
"Application refresh not blocked due to incompatibility"
99104
)
100105

101-
logger.info("Run resume-refresh action")
102-
# Highest to lowest unit number
103-
refresh_order = sorted(
104-
application.units, key=lambda unit: int(unit.name.split("/")[1]), reverse=True
105-
)
106-
action = await refresh_order[1].run_action("resume-refresh")
107-
await action.wait()
106+
# Highest to lowest unit number
107+
refresh_order = sorted(
108+
application.units, key=lambda unit: int(unit.name.split("/")[1]), reverse=True
109+
)
110+
action = await refresh_order[0].run_action(
111+
"force-refresh-start", **{"check-compatibility": False}
112+
)
113+
await action.wait()
114+
115+
logger.info("Wait for first unit to upgrade")
116+
async with ops_test.fast_forward("60s"):
117+
await ops_test.model.wait_for_idle(
118+
apps=[DATABASE_APP_NAME], idle_period=30, timeout=TIMEOUT
119+
)
120+
121+
logger.info("Run resume-refresh action")
122+
action = await refresh_order[1].run_action("resume-refresh")
123+
await action.wait()
124+
except TimeoutError:
125+
# If the application didn't get into the blocked state, it should have upgraded only
126+
# the charm code because the snap revision didn't change.
127+
assert application.status == "active", (
128+
"Application didn't reach blocked or active state after refresh attempt"
129+
)
108130

109131
logger.info("Wait for upgrade to complete")
110132
async with ops_test.fast_forward("60s"):
@@ -147,7 +169,7 @@ async def test_fail_and_rollback(ops_test, charm, continuous_writes) -> None:
147169
await action.wait()
148170

149171
filename = Path(charm).name
150-
fault_charm = Path("/tmp/", filename)
172+
fault_charm = Path("/tmp", f"{filename}.fault.charm")
151173
shutil.copy(charm, fault_charm)
152174

153175
logger.info("Inject dependency fault")
@@ -194,7 +216,7 @@ async def test_fail_and_rollback(ops_test, charm, continuous_writes) -> None:
194216

195217
async def inject_dependency_fault(charm_file: str | Path) -> None:
196218
"""Inject a dependency fault into the PostgreSQL charm."""
197-
with pathlib.Path("refresh_versions.toml").open("rb") as file:
219+
with Path("refresh_versions.toml").open("rb") as file:
198220
versions = tomli.load(file)
199221

200222
versions["charm"] = "16/0.0.0"

tests/integration/ha_tests/test_upgrade_from_stable.py

Lines changed: 38 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ async def test_deploy_stable(ops_test: OpsTest) -> None:
3131
DATABASE_APP_NAME,
3232
"-n",
3333
3,
34-
# TODO move to stable once we release refresh v3
34+
# TODO move to stable once we release refresh v3 to stable
3535
"--channel",
36-
"16/edge/test-refresh-v3-workload2",
36+
"16/edge",
3737
"--base",
3838
3939
)
@@ -82,21 +82,44 @@ async def test_upgrade_from_stable(ops_test: OpsTest, charm):
8282
await application.refresh(path=charm)
8383

8484
logger.info("Wait for upgrade to start")
85-
await ops_test.model.block_until(lambda: application.status == "blocked", timeout=TIMEOUT)
86-
87-
logger.info("Wait for first unit to upgrade")
88-
async with ops_test.fast_forward("60s"):
89-
await ops_test.model.wait_for_idle(
90-
apps=[DATABASE_APP_NAME], idle_period=30, timeout=TIMEOUT
85+
try:
86+
# Blocked status is expected due to compatibility checks.
87+
await ops_test.model.block_until(lambda: application.status == "blocked", timeout=60 * 3)
88+
89+
logger.info("Wait for refresh to block due to compatibility checks")
90+
async with ops_test.fast_forward("60s"):
91+
await ops_test.model.wait_for_idle(
92+
apps=[DATABASE_APP_NAME], idle_period=30, timeout=TIMEOUT
93+
)
94+
95+
assert "Refresh incompatible" in application.status_message, (
96+
"Application refresh not blocked due to incompatibility"
9197
)
9298

93-
logger.info("Run resume-refresh action")
94-
# Highest to lowest unit number
95-
refresh_order = sorted(
96-
application.units, key=lambda unit: int(unit.name.split("/")[1]), reverse=True
97-
)
98-
action = await refresh_order[1].run_action("resume-refresh")
99-
await action.wait()
99+
# Highest to lowest unit number
100+
refresh_order = sorted(
101+
application.units, key=lambda unit: int(unit.name.split("/")[1]), reverse=True
102+
)
103+
action = await refresh_order[0].run_action(
104+
"force-refresh-start", **{"check-compatibility": False}
105+
)
106+
await action.wait()
107+
108+
logger.info("Wait for first unit to upgrade")
109+
async with ops_test.fast_forward("60s"):
110+
await ops_test.model.wait_for_idle(
111+
apps=[DATABASE_APP_NAME], idle_period=30, timeout=TIMEOUT
112+
)
113+
114+
logger.info("Run resume-refresh action")
115+
action = await refresh_order[1].run_action("resume-refresh")
116+
await action.wait()
117+
except TimeoutError:
118+
# If the application didn't get into the blocked state, it should have upgraded only
119+
# the charm code because the snap revision didn't change.
120+
assert application.status == "active", (
121+
"Application didn't reach blocked or active state after refresh attempt"
122+
)
100123

101124
logger.info("Wait for upgrade to complete")
102125
async with ops_test.fast_forward("60s"):

0 commit comments

Comments
 (0)