Skip to content

Commit da66db9

Browse files
[DPE-7502] Improve upgrade tests to support both (in)compatible scenarios (#955)
*Issue*: The newly merged PR (with snap bump) has passed PR testing[1] but failing on release[2]. The reason here is a test imperfection (we've missed the on-Git case): on-PR: we are testing incompatible case (due to +dirty charm.py version) on-Git: we are testing compatible case, paused after the first unit upgrade [1] #943 [2] https://github.com/canonical/postgresql-operator/actions/runs/15539934165/job/43748494710 *Solution*: Improve the test to support both cases: on-PR and on-Git for already merged PRs. Checklist [x] I have added or updated any relevant documentation. [x] I have cleaned any remaining cloud resources from my accounts.
1 parent 4ba3220 commit da66db9

File tree

2 files changed

+36
-28
lines changed

2 files changed

+36
-28
lines changed

tests/integration/ha_tests/test_upgrade.py

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ async def test_deploy_latest(ops_test: OpsTest) -> None:
4949
APPLICATION_NAME,
5050
num_units=1,
5151
channel="latest/edge",
52+
config={"sleep_interval": 500},
5253
)
5354
logger.info("Wait for applications to become active")
5455
async with ops_test.fast_forward():
@@ -90,40 +91,43 @@ async def test_upgrade_from_edge(ops_test: OpsTest, continuous_writes, charm) ->
9091

9192
logger.info("Wait for upgrade to start")
9293
try:
93-
# Blocked status is expected due to compatibility checks.
94+
# Blocked status is expected due to:
95+
# (on PR) compatibility checks (on PR charm revision is '16/1.25.0+dirty...')
96+
# (non-PR) the first unit upgraded and paused (pause_after_unit_refresh=first)
9497
await ops_test.model.block_until(lambda: application.status == "blocked", timeout=60 * 3)
9598

96-
logger.info("Wait for refresh to block due to compatibility checks")
99+
logger.info("Wait for refresh to block as paused or incompatible")
97100
async with ops_test.fast_forward("60s"):
98101
await ops_test.model.wait_for_idle(
99102
apps=[DATABASE_APP_NAME], idle_period=30, timeout=TIMEOUT
100103
)
101104

102-
assert "Refresh incompatible" in application.status_message, (
103-
"Application refresh not blocked due to incompatibility"
104-
)
105-
106105
# Highest to lowest unit number
107106
refresh_order = sorted(
108107
application.units, key=lambda unit: int(unit.name.split("/")[1]), reverse=True
109108
)
110-
action = await refresh_order[0].run_action(
111-
"force-refresh-start", **{"check-compatibility": False}
112-
)
113-
await action.wait()
114109

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
110+
if "Refresh incompatible" in application.status_message:
111+
logger.info("Application refresh is blocked due to incompatibility")
112+
113+
action = await refresh_order[0].run_action(
114+
"force-refresh-start", **{"check-compatibility": False}
119115
)
116+
await action.wait()
117+
118+
logger.info("Wait for first incompatible unit to upgrade")
119+
async with ops_test.fast_forward("60s"):
120+
await ops_test.model.wait_for_idle(
121+
apps=[DATABASE_APP_NAME], idle_period=30, timeout=TIMEOUT
122+
)
120123

121124
logger.info("Run resume-refresh action")
122125
action = await refresh_order[1].run_action("resume-refresh")
123126
await action.wait()
124127
except TimeoutError:
125128
# If the application didn't get into the blocked state, it should have upgraded only
126129
# the charm code because the snap revision didn't change.
130+
logger.info("Upgrade completed without snap refresh (charm.py upgrade only)")
127131
assert application.status == "active", (
128132
"Application didn't reach blocked or active state after refresh attempt"
129133
)

tests/integration/ha_tests/test_upgrade_from_stable.py

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ async def test_deploy_stable(ops_test: OpsTest) -> None:
4141
APPLICATION_NAME,
4242
num_units=1,
4343
channel="latest/edge",
44+
config={"sleep_interval": 500},
4445
)
4546
logger.info("Wait for applications to become active")
4647
async with ops_test.fast_forward():
@@ -83,40 +84,43 @@ async def test_upgrade_from_stable(ops_test: OpsTest, charm):
8384

8485
logger.info("Wait for upgrade to start")
8586
try:
86-
# Blocked status is expected due to compatibility checks.
87+
# Blocked status is expected due to:
88+
# (on PR) compatibility checks (on PR charm revision is '16/1.25.0+dirty...')
89+
# (non-PR) the first unit upgraded and paused (pause_after_unit_refresh=first)
8790
await ops_test.model.block_until(lambda: application.status == "blocked", timeout=60 * 3)
8891

89-
logger.info("Wait for refresh to block due to compatibility checks")
92+
logger.info("Wait for refresh to block as paused or incompatible")
9093
async with ops_test.fast_forward("60s"):
9194
await ops_test.model.wait_for_idle(
9295
apps=[DATABASE_APP_NAME], idle_period=30, timeout=TIMEOUT
9396
)
9497

95-
assert "Refresh incompatible" in application.status_message, (
96-
"Application refresh not blocked due to incompatibility"
97-
)
98-
9998
# Highest to lowest unit number
10099
refresh_order = sorted(
101100
application.units, key=lambda unit: int(unit.name.split("/")[1]), reverse=True
102101
)
103-
action = await refresh_order[0].run_action(
104-
"force-refresh-start", **{"check-compatibility": False}
105-
)
106-
await action.wait()
107102

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
103+
if "Refresh incompatible" in application.status_message:
104+
logger.info("Application refresh is blocked due to incompatibility")
105+
106+
action = await refresh_order[0].run_action(
107+
"force-refresh-start", **{"check-compatibility": False}
112108
)
109+
await action.wait()
110+
111+
logger.info("Wait for first incompatible unit to upgrade")
112+
async with ops_test.fast_forward("60s"):
113+
await ops_test.model.wait_for_idle(
114+
apps=[DATABASE_APP_NAME], idle_period=30, timeout=TIMEOUT
115+
)
113116

114117
logger.info("Run resume-refresh action")
115118
action = await refresh_order[1].run_action("resume-refresh")
116119
await action.wait()
117120
except TimeoutError:
118121
# If the application didn't get into the blocked state, it should have upgraded only
119122
# the charm code because the snap revision didn't change.
123+
logger.info("Upgrade completed without snap refresh (charm.py upgrade only)")
120124
assert application.status == "active", (
121125
"Application didn't reach blocked or active state after refresh attempt"
122126
)

0 commit comments

Comments
 (0)