From c6087a308c4fdda9f64355ea5d7ea863895dce7e Mon Sep 17 00:00:00 2001 From: Dima Tisnek Date: Wed, 18 Dec 2024 15:21:51 +0900 Subject: [PATCH] fix: async filter should output only one result for each input --- juju/model/_idle.py | 8 +++--- juju/version.py | 2 +- pyproject.toml | 2 +- tests/unit/test_idle_loop.py | 49 ++++++++++++++++++++++++++++++------ tox.ini | 1 + 5 files changed, 49 insertions(+), 13 deletions(-) diff --git a/juju/model/_idle.py b/juju/model/_idle.py index 6737fe12..7ac32c76 100644 --- a/juju/model/_idle.py +++ b/juju/model/_idle.py @@ -80,7 +80,7 @@ async def loop( wait_for_units, ) yield False - continue + break if ( wait_for_exact_units is not None @@ -93,9 +93,9 @@ async def loop( wait_for_exact_units, ) yield False - continue - - yield True + break + else: + yield True def check( diff --git a/juju/version.py b/juju/version.py index 86177ffd..c0cd876c 100644 --- a/juju/version.py +++ b/juju/version.py @@ -6,4 +6,4 @@ DEFAULT_ARCHITECTURE = "amd64" -CLIENT_VERSION = "3.6.1.0rc3" +CLIENT_VERSION = "3.6.1.0rc4" diff --git a/pyproject.toml b/pyproject.toml index d2eec1cc..6eedab93 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "juju" -version = "3.6.1.0rc3" # Stop-gap until dynamic versioning is done; must be in sync with juju/version.py:CLIENT_VERSION +version = "3.6.1.0rc4" # Stop-gap until dynamic versioning is done; must be in sync with juju/version.py:CLIENT_VERSION description = "Python library for Juju" readme = "docs/readme.rst" license = { file = "LICENSE" } diff --git a/tests/unit/test_idle_loop.py b/tests/unit/test_idle_loop.py index 34a8c672..491231df 100644 --- a/tests/unit/test_idle_loop.py +++ b/tests/unit/test_idle_loop.py @@ -2,12 +2,10 @@ # Licensed under the Apache V2, see LICENCE file for details. from __future__ import annotations -import pytest from freezegun import freeze_time from juju.model._idle import CheckStatus, loop - # Missing tests # # FIXME hexanator idle period 1 @@ -18,13 +16,15 @@ # FIXME expected idle 1s below # FIXME idle period 1 # FIXME sending status=None, meaning some apps are still missing -# -@pytest.mark.xfail(reason="FIXME I misunderstood what 'idle' means") + + async def test_at_least_units(): async def checks(): - yield CheckStatus({"u/0", "u/1", "u/2"}, {"u/0"}, set()) - yield CheckStatus({"u/0", "u/1", "u/2"}, {"u/0", "u/1"}, set()) - yield CheckStatus({"u/0", "u/1", "u/2"}, {"u/0", "u/1", "u/2"}, set()) + yield CheckStatus({"u/0", "u/1", "u/2"}, {"u/0"}, {"u/0", "u/1", "u/2"}) + yield CheckStatus({"u/0", "u/1", "u/2"}, {"u/0", "u/1"}, {"u/0", "u/1", "u/2"}) + yield CheckStatus( + {"u/0", "u/1", "u/2"}, {"u/0", "u/1", "u/2"}, {"u/0", "u/1", "u/2"} + ) with freeze_time(): assert [ @@ -38,6 +38,41 @@ async def checks(): ] == [False, True, True] +async def test_for_exact_units(): + good = CheckStatus( + {"u/0", "u/1", "u/2"}, + {"u/1", "u/2"}, + {"u/0", "u/1", "u/2"}, + ) + too_few = CheckStatus( + {"u/0", "u/1", "u/2"}, + {"u/2"}, + {"u/0", "u/1", "u/2"}, + ) + too_many = CheckStatus( + {"u/0", "u/1", "u/2"}, + {"u/1", "u/2", "u/0"}, + {"u/0", "u/1", "u/2"}, + ) + + async def checks(): + yield too_few + yield good + yield too_many + yield good + + assert [ + v + async for v in loop( + checks(), + apps=frozenset(["u"]), + wait_for_units=1, + wait_for_exact_units=2, + idle_period=0, + ) + ] == [False, True, False, True] + + async def test_ping_pong(): good = CheckStatus({"hexanator/0"}, {"hexanator/0"}, set()) bad = CheckStatus({"hexanator/0"}, set(), set()) diff --git a/tox.ini b/tox.ini index beae6956..5356d45f 100644 --- a/tox.ini +++ b/tox.ini @@ -43,6 +43,7 @@ commands = envdir = {toxworkdir}/py3 commands = pytest \ + --log-level=DEBUG \ --tb native \ -m 'not serial' \ {posargs} \