Skip to content

Commit c7d0a10

Browse files
authored
Merge pull request #890 from cderici/wait-for-at-least-units-param-rename
#890 #### Description This is to clear a bit the semantics of `wait_for_units` parameter in `model.wait_for_idle`, which is to wait for a certain amount of units across all the given applications and return when those are available, regardless of the state of the other units (they can be in an error state or whatever just don't care and return) Fixes #886 #### QA Steps We got a couple of tests specific to `wait_for_idle` and `wait_for_units`, so all of them should pass, some important ones are the following: ``` tox -e py3 -- tests/unit/test_model.py::TestModelWaitForIdle ``` ``` tox -e integration -- tests/integration/test_model.py::test_wait_for_idle_with_enough_units ``` ``` tox -e integration -- tests/integration/test_model.py::test_wait_for_idle_with_exact_units ``` ``` tox -e integration -- tests/integration/test_model.py::test_wait_for_idle_with_exact_units_scale_down ``` ``` tox -e integration -- tests/integration/test_model.py::test_wait_for_idle_with_exact_units_scale_down_zero ```
2 parents b067dc1 + c22f799 commit c7d0a10

2 files changed

Lines changed: 25 additions & 22 deletions

File tree

juju/model.py

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2574,55 +2574,56 @@ async def _get_source_api(self, url, controller_name=None):
25742574

25752575
async def wait_for_idle(self, apps=None, raise_on_error=True, raise_on_blocked=False,
25762576
wait_for_active=False, timeout=10 * 60, idle_period=15, check_freq=0.5,
2577-
status=None, wait_for_units=None, wait_for_exact_units=None):
2577+
status=None, wait_for_at_least_units=None, wait_for_exact_units=None):
25782578
"""Wait for applications in the model to settle into an idle state.
25792579
2580-
:param apps (list[str]): Optional list of specific app names to wait on.
2580+
:param List[str] apps: Optional list of specific app names to wait on.
25812581
If given, all apps must be present in the model and idle, while other
25822582
apps in the model can still be busy. If not given, all apps currently
25832583
in the model must be idle.
25842584
2585-
:param raise_on_error (bool): If True, then any unit or app going into
2585+
:param bool raise_on_error: If True, then any unit or app going into
25862586
"error" status immediately raises either a JujuAppError or a JujuUnitError.
25872587
Note that machine or agent failures will always raise an exception (either
25882588
JujuMachineError or JujuAgentError), regardless of this param. The default
25892589
is True.
25902590
2591-
:param raise_on_blocked (bool): If True, then any unit or app going into
2591+
:param bool raise_on_blocked: If True, then any unit or app going into
25922592
"blocked" status immediately raises either a JujuAppError or a JujuUnitError.
2593-
The defaul tis False.
2593+
The default is False.
25942594
2595-
:param wait_for_active (bool): If True, then also wait for all unit workload
2595+
:param bool wait_for_active: If True, then also wait for all unit workload
25962596
statuses to be "active" as well. The default is False.
25972597
2598-
:param timeout (float): How long to wait, in seconds, for the bundle settles
2598+
:param float timeout: How long to wait, in seconds, for the bundle settles
25992599
before raising an asyncio.TimeoutError. If None, will wait forever.
26002600
The default is 10 minutes.
26012601
2602-
:param idle_period (float): How long, in seconds, the agent statuses of all
2602+
:param float idle_period: How long, in seconds, the agent statuses of all
26032603
units of all apps need to be `idle`. This delay is used to ensure that
26042604
any pending hooks have a chance to start to avoid false positives.
26052605
The default is 15 seconds.
26062606
2607-
:param check_freq (float): How frequently, in seconds, to check the model.
2607+
:param float check_freq: How frequently, in seconds, to check the model.
26082608
The default is every half-second.
26092609
2610-
:param status (str): The status to wait for. If None, not waiting.
2610+
:param str status: The status to wait for. If None, not waiting.
26112611
The default is None (not waiting for any status).
26122612
2613-
:param wait_for_units (int): The least number of units to be expected before
2614-
going into the idle state.
2613+
:param int wait_for_at_least_units: The least number of units to go into the idle
2614+
state. wait_for_idle will return after that many units are available (across all the
2615+
given applications).
26152616
The default is 1 unit.
26162617
2617-
:param wait_for_exact_units (int): The exact number of units to be expected before
2618+
:param int wait_for_exact_units: The exact number of units to be expected before
26182619
going into the idle state. (e.g. useful for scaling down).
26192620
When set, takes precedence over the `wait_for_units` parameter.
26202621
"""
26212622
if wait_for_active:
26222623
warnings.warn("wait_for_active is deprecated; use status", DeprecationWarning)
26232624
status = "active"
26242625

2625-
_wait_for_units = wait_for_units if wait_for_units is not None else 1
2626+
_wait_for_units = wait_for_at_least_units if wait_for_at_least_units is not None else 1
26262627

26272628
timeout = timedelta(seconds=timeout) if timeout is not None else None
26282629
idle_period = timedelta(seconds=idle_period)
@@ -2689,10 +2690,11 @@ def _raise_for_status(entities, status):
26892690
busy.append(app.name + " (not enough units yet - %s/%s)" %
26902691
(len(app.units), _wait_for_units))
26912692
continue
2692-
# User wants to see a certain # of units, and we have enough
2693-
elif wait_for_units and len(units_ready) >= _wait_for_units:
2693+
# User is waiting for at least a certain # of units, and we have enough
2694+
elif wait_for_at_least_units and len(units_ready) >= _wait_for_units:
26942695
# So no need to keep looking, we have the desired number of units ready to go,
2695-
# exit the loop. Don't return, though, we might still have some errors to raise
2696+
# exit the loop. Don't just return here, though, we might still have some
2697+
# errors to raise at the end
26962698
break
26972699
for unit in app.units:
26982700
if unit.machine is not None and unit.machine.status == "error":
@@ -2711,7 +2713,8 @@ def _raise_for_status(entities, status):
27112713
if not waiting_for_a_particular_status and unit.agent_status == "idle":
27122714
# We'll be here in two cases:
27132715
# 1) We're not waiting for a particular status and the agent is "idle"
2714-
# 2) We're waiting for a particular status and the workload is in that status
2716+
# 2) We're waiting for a particular status and the workload is in that
2717+
# status
27152718
# Either way, the unit is ready, start measuring the time period that
27162719
# it needs to stay in that state (i.e. idle_period)
27172720
units_ready.add(unit.name)

tests/integration/test_model.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -865,7 +865,7 @@ async def test_wait_for_idle_with_not_enough_units(event_loop):
865865
num_units=2,
866866
)
867867
with pytest.raises(jasyncio.TimeoutError):
868-
await model.wait_for_idle(timeout=5 * 60, wait_for_units=3)
868+
await model.wait_for_idle(timeout=5 * 60, wait_for_at_least_units=3)
869869

870870

871871
@base.bootstrapped
@@ -885,9 +885,9 @@ async def test_wait_for_idle_more_units_than_needed(event_loop):
885885
num_units=1,
886886
)
887887

888-
# because the wait_for_units=1, wait_for_idle should return without timing out
888+
# because the wait_for_at_least_units=1, wait_for_idle should return without timing out
889889
# even though there are two more units that aren't active/idle
890-
await model.wait_for_idle(timeout=5 * 60, wait_for_units=1, status='active')
890+
await model.wait_for_idle(timeout=5 * 60, wait_for_at_least_units=1, status='active')
891891

892892

893893
@base.bootstrapped
@@ -902,7 +902,7 @@ async def test_wait_for_idle_with_enough_units(event_loop):
902902
channel='stable',
903903
num_units=3,
904904
)
905-
await model.wait_for_idle(timeout=5 * 60, wait_for_units=3)
905+
await model.wait_for_idle(timeout=5 * 60, wait_for_at_least_units=3)
906906

907907

908908
@base.bootstrapped

0 commit comments

Comments
 (0)