Skip to content

Commit c8e274d

Browse files
committed
add unit tests
tested using tox -e unit -- tests/unit/test_model.py::TestModelWaitForIdle
1 parent 3d8e9fa commit c8e274d

4 files changed

Lines changed: 63 additions & 5 deletions

File tree

tests/integration/test_application.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,10 +151,10 @@ async def test_upgrade_local_charm(event_loop):
151151
tests_dir = Path(__file__).absolute().parent
152152
charm_path = tests_dir / 'upgrade-charm'
153153
app = await model.deploy('ubuntu', series='focal')
154-
await model.wait_for_idle(wait_for_active=True)
154+
await model.wait_for_idle(wait_for_status="active")
155155
assert app.data['charm-url'].startswith('cs:ubuntu')
156156
await app.upgrade_charm(path=charm_path)
157-
await model.wait_for_idle() # nb: can't use wait_for_active because test charm goes to "waiting"
157+
await model.wait_for_idle(wait_for_status="waiting")
158158
assert app.data['charm-url'] == 'local:focal/ubuntu-0'
159159

160160

tests/integration/test_model.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ async def test_deploy_local_charm(event_loop):
9797
async with base.CleanModel() as model:
9898
await model.deploy(str(charm_path))
9999
assert 'charm' in model.applications
100-
await model.wait_for_idle(wait_for_active=True)
100+
await model.wait_for_idle(wait_for_status="active")
101101
assert model.units['charm/0'].workload_status == 'active'
102102

103103

@@ -113,7 +113,7 @@ async def test_wait_local_charm_blocked(event_loop):
113113
assert 'charm' in model.applications
114114
await model.wait_for_idle()
115115
with pytest.raises(JujuUnitError):
116-
await model.wait_for_idle(wait_for_active=True,
116+
await model.wait_for_idle(wait_for_status="active",
117117
raise_on_blocked=True,
118118
timeout=30)
119119

@@ -130,7 +130,7 @@ async def test_wait_local_charm_waiting_timeout(event_loop):
130130
assert 'charm' in model.applications
131131
await model.wait_for_idle()
132132
with pytest.raises(asyncio.TimeoutError):
133-
await model.wait_for_idle(wait_for_active=True, timeout=30)
133+
await model.wait_for_idle(wait_for_status="active", timeout=30)
134134

135135

136136
@base.bootstrapped

tests/unit/test_model.py

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,3 +262,50 @@ async def test_with_posargs(self, mock_connect, mock_connect_model, _):
262262
macaroons='macaroons',
263263
loop='loop',
264264
max_frame_size='max_frame_size')
265+
266+
267+
class TestModelWaitForIdle(asynctest.TestCase):
268+
async def test_no_args(self):
269+
m = Model()
270+
with self.assertWarns(DeprecationWarning):
271+
# no apps so should return right away
272+
await m.wait_for_idle(wait_for_active=True)
273+
274+
async def test_timeout(self):
275+
m = Model()
276+
import asyncio
277+
with self.assertRaises(asyncio.TimeoutError) as cm:
278+
# no apps so should timeout after timeout period
279+
await m.wait_for_idle(apps=["nonexisting_app"], timeout=1, idle_period=0)
280+
self.assertEqual(str(cm.exception), "Timed out waiting for model:\nnonexisting_app (missing)")
281+
282+
async def test_wait_for_active_status(self):
283+
# create a custom apps mock
284+
from types import SimpleNamespace
285+
apps = {"dummy_app": SimpleNamespace(
286+
status="active",
287+
units=[SimpleNamespace(
288+
name="mockunit/0",
289+
workload_status="active",
290+
workload_status_message="workload_status_message",
291+
machine=None,
292+
agent_status="idle",
293+
)],
294+
)}
295+
296+
from unittest.mock import patch, PropertyMock
297+
with patch.object(Model, 'applications', new_callable=PropertyMock) as mock_apps:
298+
mock_apps.return_value = apps
299+
m = Model()
300+
301+
# pass "active" via `wait_for_status` (str)
302+
await m.wait_for_idle(apps=["dummy_app"], wait_for_status="active", timeout=5, idle_period=0)
303+
304+
# pass "active" via `wait_for_active` (bool; deprecated)
305+
await m.wait_for_idle(apps=["dummy_app"], wait_for_active=True, timeout=5, idle_period=0)
306+
307+
# use both `wait_for_status` and `wait_for_active` - `wait_for_active` takes precedence
308+
await m.wait_for_idle(apps=["dummy_app"], wait_for_active=True, wait_for_status="doesn't matter", timeout=5,
309+
idle_period=0)
310+
311+
mock_apps.assert_called()

tox.ini

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ skipsdist=True
1010
[pytest]
1111
markers =
1212
serial: mark a test that must run by itself
13+
filterwarnings =
14+
ignore::DeprecationWarning:asynctest
15+
ignore::DeprecationWarning:websockets
1316

1417
[testenv]
1518
usedevelop=True
@@ -49,6 +52,14 @@ commands =
4952
pip install pylxd
5053
py.test --tb native -ra -v -n auto -k 'integration' -m 'not serial' {posargs}
5154

55+
[testenv:unit]
56+
envdir = {toxworkdir}/py3
57+
commands =
58+
# These need to be installed in a specific order
59+
pip install urllib3==1.25.7
60+
pip install pylxd
61+
py.test --tb native -ra -v -n auto {toxinidir}/tests/unit {posargs}
62+
5263
[testenv:serial]
5364
# tests that can't be run in parallel
5465
envdir = {toxworkdir}/py3

0 commit comments

Comments
 (0)