From f6259b953b4dfdc81d9aca18e29f761095bc8ced Mon Sep 17 00:00:00 2001 From: Edmilson Monteiro Rodrigues Neto Date: Wed, 27 Nov 2024 15:50:53 +0000 Subject: [PATCH] chore: changed all references of jasyncio to asyncio or _jasyncio. Also ran ruff format and -fix --- docs/readme.rst | 4 +- examples/action.py | 4 +- examples/add_k8s.py | 4 +- examples/add_machine.py | 4 +- examples/add_model.py | 4 +- examples/add_secrets_backend.py | 4 +- examples/allwatcher.py | 4 +- examples/charmhub_deploy_k8s.py | 4 +- examples/charmhub_deploy_machine.py | 4 +- examples/charmhub_find.py | 4 +- examples/charmhub_info.py | 4 +- examples/cloud.py | 4 +- examples/clouds.py | 4 +- examples/config.py | 4 +- examples/connect_current_model.py | 4 +- examples/controller.py | 4 +- examples/credential.py | 4 +- examples/crossmodel.py | 4 +- examples/crossmodel_bundle.py | 4 +- examples/crossmodel_controller.py | 4 +- examples/crossmodel_relation.py | 4 +- examples/debug-log.py | 4 +- examples/deploy.py | 4 +- examples/deploy_bundle.py | 4 +- examples/deploy_bundle_charmhub.py | 4 +- examples/deploy_bundle_with_trust.py | 4 +- examples/deploy_constraints.py | 4 +- examples/deploy_local_big_k8s_bundle.py | 4 +- .../deploy_local_bundle_with_resources.py | 4 +- examples/deploy_local_file_resource.py | 4 +- examples/deploy_local_resource.py | 4 +- examples/deploy_with_revision.py | 4 +- examples/expose-application.py | 4 +- examples/formatted_status.py | 9 +- examples/fullstatus.py | 4 +- examples/future.py | 4 +- examples/get_cloud.py | 4 +- examples/leadership.py | 4 +- examples/list_secrets.py | 4 +- examples/livemodel.py | 6 +- examples/local_refresh.py | 4 +- examples/localcharm.py | 4 +- examples/machine_hostname.py | 4 +- examples/model.py | 4 +- examples/modelsummaries.py | 4 +- examples/relate.py | 4 +- examples/run_action.py | 4 +- examples/scp.py | 4 +- examples/status.py | 9 +- examples/unitrun.py | 4 +- examples/upgrade_local_charm_k8s.py | 4 +- juju/_jasyncio.py | 7 +- juju/application.py | 13 +- juju/bundle.py | 9 +- juju/charmhub.py | 5 +- juju/client/connection.py | 79 ++++----- juju/controller.py | 47 +++--- juju/jasyncio.py | 2 +- juju/loop.py | 2 +- juju/machine.py | 13 +- juju/model.py | 93 ++++++----- juju/utils.py | 14 +- tests/integration/test_application.py | 4 +- tests/integration/test_charmhub.py | 9 +- tests/integration/test_connection.py | 31 ++-- tests/integration/test_crossmodel.py | 7 +- tests/integration/test_model.py | 50 +++--- tests/integration/test_unit.py | 6 +- tests/unit/test_bundle.py | 10 +- tests/unit/test_connection.py | 156 ++++++++++-------- tests/unit/test_definitions.py | 156 +++++++++--------- tests/unit/test_loop.py | 15 +- tests/unit/test_model.py | 6 +- tests/unit/test_proxy.py | 32 ++-- 74 files changed, 517 insertions(+), 465 deletions(-) diff --git a/docs/readme.rst b/docs/readme.rst index 2cc967cd9..28038be5e 100644 --- a/docs/readme.rst +++ b/docs/readme.rst @@ -49,7 +49,7 @@ Note : Pylibjuju requires an already bootstrapped Juju controller to connect to. import logging import sys - from juju import jasyncio + from juju import _jasyncio from juju.model import Model @@ -87,7 +87,7 @@ Note : Pylibjuju requires an already bootstrapped Juju controller to connect to. # Run the deploy coroutine in an asyncio event loop, using a helper # that abstracts loop creation and teardown. - jasyncio.run(deploy()) + _jasyncio.run(deploy()) if __name__ == '__main__': diff --git a/examples/action.py b/examples/action.py index e1023377b..75d1c12af 100644 --- a/examples/action.py +++ b/examples/action.py @@ -12,7 +12,7 @@ import logging -from juju import jasyncio +from juju import _jasyncio from juju.model import Model @@ -50,4 +50,4 @@ async def main(): logging.basicConfig(level=logging.DEBUG) ws_logger = logging.getLogger("websockets.protocol") ws_logger.setLevel(logging.INFO) - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/add_k8s.py b/examples/add_k8s.py index fdd67ac6d..82efefc35 100644 --- a/examples/add_k8s.py +++ b/examples/add_k8s.py @@ -16,7 +16,7 @@ import yaml -from juju import jasyncio +from juju import _jasyncio from juju.client import client from juju.controller import Controller @@ -58,4 +58,4 @@ async def main(): logging.basicConfig(level=logging.DEBUG) ws_logger = logging.getLogger("websockets.protocol") ws_logger.setLevel(logging.INFO) - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/add_machine.py b/examples/add_machine.py index 589fcf5ad..ee8e4552b 100755 --- a/examples/add_machine.py +++ b/examples/add_machine.py @@ -13,7 +13,7 @@ import logging -from juju import jasyncio +from juju import _jasyncio from juju.model import Model MB = 1 @@ -69,4 +69,4 @@ async def main(): ws_logger = logging.getLogger("websockets.protocol") ws_logger.setLevel(logging.INFO) - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/add_model.py b/examples/add_model.py index 892e1c6e1..a31f81aab 100644 --- a/examples/add_model.py +++ b/examples/add_model.py @@ -13,7 +13,7 @@ import uuid from logging import getLogger -from juju import jasyncio, utils +from juju import _jasyncio, utils from juju.controller import Controller LOG = getLogger(__name__) @@ -65,4 +65,4 @@ async def main(): if __name__ == "__main__": - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/add_secrets_backend.py b/examples/add_secrets_backend.py index 55ed4d596..1cc058852 100644 --- a/examples/add_secrets_backend.py +++ b/examples/add_secrets_backend.py @@ -3,7 +3,7 @@ import hvac -from juju import jasyncio +from juju import _jasyncio from juju.model import Model @@ -75,4 +75,4 @@ async def main(): if __name__ == "__main__": - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/allwatcher.py b/examples/allwatcher.py index cc74f4f94..b43eee42e 100644 --- a/examples/allwatcher.py +++ b/examples/allwatcher.py @@ -12,7 +12,7 @@ import logging -from juju import jasyncio +from juju import _jasyncio from juju.client import client from juju.model import Model @@ -34,4 +34,4 @@ async def watch(): ws_logger.setLevel(logging.INFO) # Run loop until the process is manually stopped (watch will loop # forever). - jasyncio.run(watch()) + _jasyncio.run(watch()) diff --git a/examples/charmhub_deploy_k8s.py b/examples/charmhub_deploy_k8s.py index cac858522..a342ca410 100644 --- a/examples/charmhub_deploy_k8s.py +++ b/examples/charmhub_deploy_k8s.py @@ -9,7 +9,7 @@ """ -from juju import jasyncio +from juju import _jasyncio from juju.model import Model @@ -40,4 +40,4 @@ async def main(): if __name__ == "__main__": - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/charmhub_deploy_machine.py b/examples/charmhub_deploy_machine.py index b48811119..f474a7285 100644 --- a/examples/charmhub_deploy_machine.py +++ b/examples/charmhub_deploy_machine.py @@ -9,7 +9,7 @@ """ -from juju import jasyncio +from juju import _jasyncio from juju.model import Model @@ -37,4 +37,4 @@ async def main(): if __name__ == "__main__": - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/charmhub_find.py b/examples/charmhub_find.py index 2010962bb..8b90307b0 100644 --- a/examples/charmhub_find.py +++ b/examples/charmhub_find.py @@ -7,7 +7,7 @@ import logging -from juju import jasyncio +from juju import _jasyncio from juju.model import Model log = logging.getLogger(__name__) @@ -33,4 +33,4 @@ async def main(): if __name__ == "__main__": logging.basicConfig(level=logging.INFO) - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/charmhub_info.py b/examples/charmhub_info.py index 11f563893..dad42ad99 100644 --- a/examples/charmhub_info.py +++ b/examples/charmhub_info.py @@ -7,7 +7,7 @@ import logging -from juju import jasyncio +from juju import _jasyncio from juju.model import Model log = logging.getLogger(__name__) @@ -29,4 +29,4 @@ async def main(): if __name__ == "__main__": logging.basicConfig(level=logging.INFO) - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/cloud.py b/examples/cloud.py index d818df9c6..186e5db24 100644 --- a/examples/cloud.py +++ b/examples/cloud.py @@ -11,7 +11,7 @@ import logging -from juju import jasyncio +from juju import _jasyncio from juju.controller import Controller @@ -28,4 +28,4 @@ async def main(): logging.basicConfig(level=logging.DEBUG) ws_logger = logging.getLogger("websockets.protocol") ws_logger.setLevel(logging.INFO) - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/clouds.py b/examples/clouds.py index 1dee35b16..5336b62a8 100644 --- a/examples/clouds.py +++ b/examples/clouds.py @@ -11,7 +11,7 @@ import logging -from juju import jasyncio +from juju import _jasyncio from juju.controller import Controller @@ -28,4 +28,4 @@ async def main(): logging.basicConfig(level=logging.DEBUG) ws_logger = logging.getLogger("websockets.protocol") ws_logger.setLevel(logging.INFO) - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/config.py b/examples/config.py index b6388b938..998ed94ef 100644 --- a/examples/config.py +++ b/examples/config.py @@ -11,7 +11,7 @@ import logging -from juju import jasyncio +from juju import _jasyncio from juju.model import Model log = logging.getLogger(__name__) @@ -59,4 +59,4 @@ async def main(): # logging.basicConfig(level=logging.DEBUG) ws_logger = logging.getLogger("websockets.protocol") ws_logger.setLevel(logging.INFO) - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/connect_current_model.py b/examples/connect_current_model.py index c8996b1d0..c46f07ad2 100644 --- a/examples/connect_current_model.py +++ b/examples/connect_current_model.py @@ -7,7 +7,7 @@ import logging -from juju import jasyncio +from juju import _jasyncio from juju.model import Model log = logging.getLogger(__name__) @@ -27,4 +27,4 @@ async def main(): if __name__ == "__main__": logging.basicConfig(level=logging.INFO) - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/controller.py b/examples/controller.py index d269a16a2..d13648545 100644 --- a/examples/controller.py +++ b/examples/controller.py @@ -13,7 +13,7 @@ import logging -from juju import jasyncio +from juju import _jasyncio from juju.controller import Controller @@ -41,4 +41,4 @@ async def main(): logging.basicConfig(level=logging.DEBUG) ws_logger = logging.getLogger("websockets.protocol") ws_logger.setLevel(logging.INFO) - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/credential.py b/examples/credential.py index 257462736..30c4e9a29 100644 --- a/examples/credential.py +++ b/examples/credential.py @@ -3,7 +3,7 @@ import sys -from juju import jasyncio +from juju import _jasyncio from juju.controller import Controller @@ -47,4 +47,4 @@ async def main(cloud_name, credential_name): if __name__ == "__main__": assert len(sys.argv) > 2, "Please provide a cloud and credential name" - jasyncio.run(main(sys.argv[1], sys.argv[2])) + _jasyncio.run(main(sys.argv[1], sys.argv[2])) diff --git a/examples/crossmodel.py b/examples/crossmodel.py index 226ef4e77..bc7e97a5d 100644 --- a/examples/crossmodel.py +++ b/examples/crossmodel.py @@ -14,7 +14,7 @@ import tempfile from logging import getLogger -from juju import jasyncio +from juju import _jasyncio from juju.controller import Controller log = getLogger(__name__) @@ -83,4 +83,4 @@ async def main(): if __name__ == "__main__": - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/crossmodel_bundle.py b/examples/crossmodel_bundle.py index 06e85d4d9..e8c97db30 100644 --- a/examples/crossmodel_bundle.py +++ b/examples/crossmodel_bundle.py @@ -17,7 +17,7 @@ from logging import getLogger from pathlib import Path -from juju import jasyncio +from juju import _jasyncio from juju.controller import Controller log = getLogger(__name__) @@ -87,4 +87,4 @@ async def main(): if __name__ == "__main__": - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/crossmodel_controller.py b/examples/crossmodel_controller.py index ec12d02be..8ed07539d 100644 --- a/examples/crossmodel_controller.py +++ b/examples/crossmodel_controller.py @@ -18,7 +18,7 @@ import tempfile from logging import getLogger -from juju import jasyncio +from juju import _jasyncio from juju.controller import Controller log = getLogger(__name__) @@ -92,4 +92,4 @@ async def main(): if __name__ == "__main__": - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/crossmodel_relation.py b/examples/crossmodel_relation.py index 80ffb3a14..4a45d694c 100644 --- a/examples/crossmodel_relation.py +++ b/examples/crossmodel_relation.py @@ -17,7 +17,7 @@ import time from logging import getLogger -from juju import jasyncio +from juju import _jasyncio from juju.controller import Controller log = getLogger(__name__) @@ -106,4 +106,4 @@ async def main(): if __name__ == "__main__": - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/debug-log.py b/examples/debug-log.py index b7e712063..a0b3152b2 100644 --- a/examples/debug-log.py +++ b/examples/debug-log.py @@ -3,7 +3,7 @@ """This example demonstrate how debug-log works""" -from juju import jasyncio +from juju import _jasyncio from juju.model import Model @@ -34,4 +34,4 @@ async def main(): if __name__ == "__main__": - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/deploy.py b/examples/deploy.py index 831ae85d2..a417f2947 100644 --- a/examples/deploy.py +++ b/examples/deploy.py @@ -9,7 +9,7 @@ """ -from juju import jasyncio +from juju import _jasyncio from juju.model import Model @@ -39,4 +39,4 @@ async def main(): if __name__ == "__main__": - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/deploy_bundle.py b/examples/deploy_bundle.py index dad615eec..475391fef 100644 --- a/examples/deploy_bundle.py +++ b/examples/deploy_bundle.py @@ -9,7 +9,7 @@ """ -from juju import jasyncio +from juju import _jasyncio from juju.controller import Controller @@ -59,4 +59,4 @@ async def deploy_and_wait_for_bundle(model, url, channel=None): if __name__ == "__main__": - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/deploy_bundle_charmhub.py b/examples/deploy_bundle_charmhub.py index f3f63b154..d019dfdde 100644 --- a/examples/deploy_bundle_charmhub.py +++ b/examples/deploy_bundle_charmhub.py @@ -7,7 +7,7 @@ 3. Destroys the unit and application """ -from juju import jasyncio +from juju import _jasyncio from juju.model import Model @@ -33,4 +33,4 @@ async def main(): if __name__ == "__main__": - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/deploy_bundle_with_trust.py b/examples/deploy_bundle_with_trust.py index 0a122e021..ffa0a8ab3 100644 --- a/examples/deploy_bundle_with_trust.py +++ b/examples/deploy_bundle_with_trust.py @@ -9,7 +9,7 @@ """ -from juju import jasyncio +from juju import _jasyncio from juju.model import Model @@ -44,4 +44,4 @@ async def main(): if __name__ == "__main__": - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/deploy_constraints.py b/examples/deploy_constraints.py index dd876c58a..5e035753c 100644 --- a/examples/deploy_constraints.py +++ b/examples/deploy_constraints.py @@ -9,7 +9,7 @@ """ -from juju import jasyncio +from juju import _jasyncio from juju.controller import Controller @@ -35,4 +35,4 @@ async def main(): if __name__ == "__main__": - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/deploy_local_big_k8s_bundle.py b/examples/deploy_local_big_k8s_bundle.py index 447206ff5..d7eaf859a 100644 --- a/examples/deploy_local_big_k8s_bundle.py +++ b/examples/deploy_local_big_k8s_bundle.py @@ -9,7 +9,7 @@ """ -from juju import jasyncio +from juju import _jasyncio from juju.model import Model @@ -33,4 +33,4 @@ async def main(): if __name__ == "__main__": - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/deploy_local_bundle_with_resources.py b/examples/deploy_local_bundle_with_resources.py index c35382c5c..72779db80 100644 --- a/examples/deploy_local_bundle_with_resources.py +++ b/examples/deploy_local_bundle_with_resources.py @@ -9,7 +9,7 @@ """ -from juju import jasyncio +from juju import _jasyncio from juju.model import Model @@ -44,4 +44,4 @@ async def main(): if __name__ == "__main__": - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/deploy_local_file_resource.py b/examples/deploy_local_file_resource.py index 3aa2b5ccf..cbccb779e 100644 --- a/examples/deploy_local_file_resource.py +++ b/examples/deploy_local_file_resource.py @@ -12,7 +12,7 @@ from pathlib import Path -from juju import jasyncio +from juju import _jasyncio from juju.model import Model @@ -49,4 +49,4 @@ async def main(): if __name__ == "__main__": - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/deploy_local_resource.py b/examples/deploy_local_resource.py index cbe086a40..0f3d7415f 100644 --- a/examples/deploy_local_resource.py +++ b/examples/deploy_local_resource.py @@ -12,7 +12,7 @@ from pathlib import Path -from juju import jasyncio +from juju import _jasyncio from juju.model import Model @@ -46,4 +46,4 @@ async def main(): if __name__ == "__main__": - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/deploy_with_revision.py b/examples/deploy_with_revision.py index f7ce3b11d..1f3a0228c 100644 --- a/examples/deploy_with_revision.py +++ b/examples/deploy_with_revision.py @@ -1,7 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -from juju import jasyncio +from juju import _jasyncio from juju.model import Model @@ -33,4 +33,4 @@ async def main(): if __name__ == "__main__": - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/expose-application.py b/examples/expose-application.py index b43a2c679..4d2e60308 100644 --- a/examples/expose-application.py +++ b/examples/expose-application.py @@ -11,7 +11,7 @@ NOTE: this test must be run against a 2.9 controller. """ -from juju import jasyncio +from juju import _jasyncio from juju.application import ExposedEndpoint from juju.model import Model @@ -81,4 +81,4 @@ async def main(): if __name__ == "__main__": - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/formatted_status.py b/examples/formatted_status.py index d772d7923..47d34ed45 100644 --- a/examples/formatted_status.py +++ b/examples/formatted_status.py @@ -6,12 +6,13 @@ check examples/fullstatus.py """ +import asyncio import logging import sys import tempfile from logging import getLogger -from juju import jasyncio +from juju import _jasyncio from juju.model import Model from juju.status import formatted_status @@ -30,7 +31,7 @@ async def main(): channel="stable", ) - await jasyncio.sleep(10) + await asyncio.sleep(10) tmp = tempfile.NamedTemporaryFile(delete=False) # noqa: SIM115 LOG.info("status dumped to %s", tmp.name) with open(tmp.name, "w") as f: @@ -40,10 +41,10 @@ async def main(): # await formatted_status(model, target=sys.stdout) await formatted_status(model, target=f) f.write("-----------\n") - await jasyncio.sleep(1) + await asyncio.sleep(1) await application.remove() await model.disconnect() if __name__ == "__main__": - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/fullstatus.py b/examples/fullstatus.py index 2cee31210..3d37b31a6 100644 --- a/examples/fullstatus.py +++ b/examples/fullstatus.py @@ -1,7 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -from juju import jasyncio +from juju import _jasyncio from juju.model import Model @@ -20,4 +20,4 @@ async def status(): if __name__ == "__main__": - jasyncio.run(status()) + _jasyncio.run(status()) diff --git a/examples/future.py b/examples/future.py index f69775522..7a3b70a11 100644 --- a/examples/future.py +++ b/examples/future.py @@ -5,7 +5,7 @@ import logging -from juju import jasyncio +from juju import _jasyncio from juju.model import Model @@ -44,4 +44,4 @@ async def main(): logging.basicConfig(level=logging.DEBUG) ws_logger = logging.getLogger("websockets.protocol") ws_logger.setLevel(logging.INFO) - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/get_cloud.py b/examples/get_cloud.py index 657aac556..181cabe42 100644 --- a/examples/get_cloud.py +++ b/examples/get_cloud.py @@ -11,7 +11,7 @@ import logging -from juju import jasyncio +from juju import _jasyncio from juju.controller import Controller @@ -29,4 +29,4 @@ async def main(): logging.basicConfig(level=logging.DEBUG) ws_logger = logging.getLogger("websockets.protocol") ws_logger.setLevel(logging.INFO) - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/leadership.py b/examples/leadership.py index ddd6bddb6..5c2fce7ca 100644 --- a/examples/leadership.py +++ b/examples/leadership.py @@ -9,7 +9,7 @@ """ -from juju import jasyncio +from juju import _jasyncio from juju.model import Model @@ -26,4 +26,4 @@ async def report_leadership(): if __name__ == "__main__": - jasyncio.run(report_leadership()) + _jasyncio.run(report_leadership()) diff --git a/examples/list_secrets.py b/examples/list_secrets.py index 0aabc70d9..2af085dbc 100644 --- a/examples/list_secrets.py +++ b/examples/list_secrets.py @@ -1,7 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -from juju import jasyncio +from juju import _jasyncio from juju.model import Model @@ -15,4 +15,4 @@ async def main(): if __name__ == "__main__": - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/livemodel.py b/examples/livemodel.py index 268ac4a0d..2932579e1 100644 --- a/examples/livemodel.py +++ b/examples/livemodel.py @@ -9,11 +9,11 @@ """ -from juju import jasyncio +from juju import _jasyncio from juju.model import Model -async def on_model_change(delta, old, new, model): # noqa: RUF029 +async def on_model_change(delta, old, new, model): print(delta.entity, delta.type, delta.data) print(old) print(new) @@ -31,4 +31,4 @@ async def watch_model(): if __name__ == "__main__": # Run loop until the process is manually stopped (watch_model will loop # forever). - jasyncio.run(watch_model()) + _jasyncio.run(watch_model()) diff --git a/examples/local_refresh.py b/examples/local_refresh.py index 68e581275..7b6de8444 100644 --- a/examples/local_refresh.py +++ b/examples/local_refresh.py @@ -8,7 +8,7 @@ """ -from juju import jasyncio +from juju import _jasyncio from juju.model import Model @@ -30,4 +30,4 @@ async def main(): if __name__ == "__main__": - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/localcharm.py b/examples/localcharm.py index dd2489bad..2321bcce1 100644 --- a/examples/localcharm.py +++ b/examples/localcharm.py @@ -11,7 +11,7 @@ import logging -from juju import jasyncio +from juju import _jasyncio from juju.model import Model @@ -33,4 +33,4 @@ async def main(): logging.basicConfig(level=logging.DEBUG) ws_logger = logging.getLogger("websockets.protocol") ws_logger.setLevel(logging.INFO) - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/machine_hostname.py b/examples/machine_hostname.py index 5ac74d37b..1903e3136 100644 --- a/examples/machine_hostname.py +++ b/examples/machine_hostname.py @@ -14,7 +14,7 @@ import logging -from juju import jasyncio +from juju import _jasyncio from juju.model import Model MB = 1 @@ -44,4 +44,4 @@ async def main(): ws_logger = logging.getLogger("websockets.protocol") ws_logger.setLevel(logging.INFO) - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/model.py b/examples/model.py index 8a53f6973..0c543fb21 100755 --- a/examples/model.py +++ b/examples/model.py @@ -11,7 +11,7 @@ """ -from juju import jasyncio +from juju import _jasyncio from juju.errors import JujuEntityNotFoundError from juju.model import Model @@ -32,4 +32,4 @@ async def main(): if __name__ == "__main__": - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/modelsummaries.py b/examples/modelsummaries.py index 0d1568a0b..dea4157fc 100644 --- a/examples/modelsummaries.py +++ b/examples/modelsummaries.py @@ -13,7 +13,7 @@ import asyncio import logging -from juju import jasyncio +from juju import _jasyncio from juju.controller import Controller @@ -41,4 +41,4 @@ def callback(summary): logging.getLogger("juju.client.connection").setLevel(logging.INFO) # Run loop until the process is manually stopped (watch will loop # forever). - jasyncio.run(watch()) + _jasyncio.run(watch()) diff --git a/examples/relate.py b/examples/relate.py index 1d5f43814..1fbd3bce1 100644 --- a/examples/relate.py +++ b/examples/relate.py @@ -13,7 +13,7 @@ import asyncio import logging -from juju import jasyncio +from juju import _jasyncio from juju.model import Model, ModelObserver @@ -120,4 +120,4 @@ async def main(): logging.basicConfig(level=logging.INFO) ws_logger = logging.getLogger("websockets.protocol") ws_logger.setLevel(logging.INFO) - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/run_action.py b/examples/run_action.py index 2f1cf83bc..97ac0a6cd 100644 --- a/examples/run_action.py +++ b/examples/run_action.py @@ -1,7 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. -from juju import jasyncio +from juju import _jasyncio from juju.model import Model # logging.basicConfig(level='DEBUG') @@ -38,4 +38,4 @@ async def _get_password(): if __name__ == "__main__": - jasyncio.run(_get_password()) + _jasyncio.run(_get_password()) diff --git a/examples/scp.py b/examples/scp.py index 9660282f2..a53493d5d 100644 --- a/examples/scp.py +++ b/examples/scp.py @@ -10,7 +10,7 @@ import logging -from juju import jasyncio +from juju import _jasyncio from juju.model import Model log = logging.getLogger(__name__) @@ -35,4 +35,4 @@ async def main(): if __name__ == "__main__": logging.basicConfig(level=logging.INFO) - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/status.py b/examples/status.py index ba617f66d..d370fc4de 100644 --- a/examples/status.py +++ b/examples/status.py @@ -3,11 +3,12 @@ """This example demonstrate how status works""" +import asyncio import logging import sys from logging import getLogger -from juju import jasyncio +from juju import _jasyncio from juju.model import Model from juju.status import formatted_status @@ -25,7 +26,7 @@ async def main(): series="jammy", channel="stable", ) - await jasyncio.sleep(10) + await asyncio.sleep(10) # Print the status to observe the evolution # during a minute for _ in range(12): @@ -38,7 +39,7 @@ async def main(): print(status) except Exception as e: print(e) - await jasyncio.sleep(5) + await asyncio.sleep(5) print("Removing ubuntu") await application.remove() @@ -48,4 +49,4 @@ async def main(): if __name__ == "__main__": - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/unitrun.py b/examples/unitrun.py index 3ca761466..6b0febe08 100644 --- a/examples/unitrun.py +++ b/examples/unitrun.py @@ -12,7 +12,7 @@ import logging -from juju import jasyncio +from juju import _jasyncio from juju.model import Model @@ -66,4 +66,4 @@ async def main(): DEBUG:root:Action status: completed DEBUG:root:Action results: {'return-code': 0, 'stdout': '10.42.51.101\n'} """ - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/examples/upgrade_local_charm_k8s.py b/examples/upgrade_local_charm_k8s.py index bfec519d7..d685750ce 100644 --- a/examples/upgrade_local_charm_k8s.py +++ b/examples/upgrade_local_charm_k8s.py @@ -10,7 +10,7 @@ """ -from juju import jasyncio +from juju import _jasyncio from juju.model import Model @@ -46,4 +46,4 @@ async def main(): if __name__ == "__main__": - jasyncio.run(main()) + _jasyncio.run(main()) diff --git a/juju/_jasyncio.py b/juju/_jasyncio.py index 0645c1fe8..9c54aea73 100644 --- a/juju/_jasyncio.py +++ b/juju/_jasyncio.py @@ -74,7 +74,7 @@ def run(*steps: Coroutine[Any, Any, Any]) -> Any: return task = None - _sigint = False + run._sigint = False # Use a singleton class to force a single event loop instance loop = SingletonEventLoop().loop @@ -82,8 +82,7 @@ def abort(): if task is None: return task.cancel() - nonlocal _sigint - _sigint = True + run._sigint = True added = False try: @@ -97,7 +96,7 @@ def abort(): for step in steps: task = loop.create_task(step) loop.run_until_complete(asyncio.wait([task])) - if _sigint: + if run._sigint: raise KeyboardInterrupt() if task.exception(): raise task.exception() diff --git a/juju/application.py b/juju/application.py index a57e336c6..4a1a9c915 100644 --- a/juju/application.py +++ b/juju/application.py @@ -1,6 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. +import asyncio import hashlib import json import logging @@ -9,7 +10,7 @@ from typing_extensions import deprecated -from . import jasyncio, model, tag, utils +from . import model, tag, utils from .annotationhelper import _get_annotations, _set_annotations from .bundle import get_charm_series, is_local_charm from .client import _definitions, client @@ -207,10 +208,12 @@ async def add_unit(self, count=1, to=None, attach_storage=[]): attach_storage=attach_storage, ) - return await jasyncio.gather(*[ - jasyncio.ensure_future(self.model._wait_for_new("unit", unit_id)) - for unit_id in result.units - ]) + return await asyncio.gather( + *[ + asyncio.ensure_future(self.model._wait_for_new("unit", unit_id)) + for unit_id in result.units + ] + ) add_units = add_unit diff --git a/juju/bundle.py b/juju/bundle.py index 6f136ec77..7377b0398 100644 --- a/juju/bundle.py +++ b/juju/bundle.py @@ -1,6 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. +import asyncio import base64 import io import logging @@ -14,7 +15,7 @@ import yaml from toposort import toposort_flatten -from . import jasyncio, utils +from . import utils from .client import client from .constraints import parse as parse_constraints from .constraints import parse_storage_constraint @@ -152,9 +153,9 @@ async def _handle_local_charms(self, bundle, bundle_dir): if apps: # If we have apps to update, spawn all the coroutines concurrently # and wait for them to finish. - charm_urls = await jasyncio.gather(*[ - self.model.add_local_charm_dir(*params) for params in args - ]) + charm_urls = await asyncio.gather( + *[self.model.add_local_charm_dir(*params) for params in args] + ) # Update the 'charm:' entry for each app with the new 'local:' url. for app_name, charm_url, (charm_dir, series) in zip(apps, charm_urls, args): diff --git a/juju/charmhub.py b/juju/charmhub.py index 61cbfcca6..cf2fdcc32 100644 --- a/juju/charmhub.py +++ b/juju/charmhub.py @@ -1,12 +1,11 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. +import asyncio import json import requests -from juju import jasyncio - from .client import client from .errors import JujuError @@ -24,7 +23,7 @@ async def request_charmhub_with_retry(self, url, retries): _response = requests.get(url) # noqa: S113 if _response.status_code == 200: return _response - await jasyncio.sleep(5) + await asyncio.sleep(5) raise JujuError(f"Got {_response.status_code} from {url}") async def get_charm_id(self, charm_name): diff --git a/juju/client/connection.py b/juju/client/connection.py index e79f2ea7e..63d14131f 100644 --- a/juju/client/connection.py +++ b/juju/client/connection.py @@ -2,6 +2,7 @@ # Licensed under the Apache V2, see LICENCE file for details. from __future__ import annotations +import asyncio import base64 import json import logging @@ -18,7 +19,7 @@ from dateutil.parser import parse from typing_extensions import Self, TypeAlias, overload -from juju import errors, jasyncio, tag, utils +from juju import errors, tag, utils from juju.client import client from juju.utils import IdQueue from juju.version import CLIENT_VERSION @@ -54,8 +55,8 @@ class Monitor: def __init__(self, connection: Connection): self.connection = weakref.ref(connection) - self.reconnecting = jasyncio.Lock() - self.close_called = jasyncio.Event() + self.reconnecting = asyncio.Lock() + self.close_called = asyncio.Event() @property def status(self): @@ -324,7 +325,7 @@ async def _open(self, endpoint, cacert) -> tuple[_WebSocket, str, str, str]: server_hostname = "juju-app" def _exit_tasks(): - for task in jasyncio.all_tasks(): + for task in asyncio.all_tasks(): task.cancel() return ( @@ -365,8 +366,8 @@ async def close(self, to_reconnect=False): if not to_reconnect: try: log.debug("Gathering all tasks for connection close") - await jasyncio.gather(*tasks_need_to_be_gathered) - except jasyncio.CancelledError: + await asyncio.gather(*tasks_need_to_be_gathered) + except asyncio.CancelledError: pass except websockets.exceptions.ConnectionClosed: pass @@ -457,26 +458,26 @@ async def _debug_logger(self): self.debug_log_shown_lines += number_of_lines_written if self.debug_log_shown_lines >= self.debug_log_params["limit"]: - jasyncio.create_task(self.close(), name="Task_Close") + asyncio.create_task(self.close(), name="Task_Close") return except KeyError as e: log.exception("Unexpected debug line -- %s" % e) - jasyncio.create_task(self.close(), name="Task_Close") + asyncio.create_task(self.close(), name="Task_Close") raise - except jasyncio.CancelledError: - jasyncio.create_task(self.close(), name="Task_Close") + except asyncio.CancelledError: + asyncio.create_task(self.close(), name="Task_Close") raise except websockets.exceptions.ConnectionClosed: log.warning("Debug Logger: Connection closed, reconnecting") # the reconnect has to be done as a task because the receiver will # be cancelled by the reconnect and we don't want the reconnect # to be aborted half-way through - jasyncio.ensure_future(self.reconnect()) + asyncio.ensure_future(self.reconnect()) return except Exception as e: log.exception("Error in debug logger : %s" % e) - jasyncio.create_task(self.close(), name="Task_Close") + asyncio.create_task(self.close(), name="Task_Close") raise async def _receiver(self): @@ -490,7 +491,7 @@ async def _receiver(self): if result is not None: result = json.loads(result) await self.messages.put(result["request-id"], result) - except jasyncio.CancelledError: + except asyncio.CancelledError: log.debug("Receiver: Cancelled") pass except websockets.exceptions.ConnectionClosed as e: @@ -499,7 +500,7 @@ async def _receiver(self): # the reconnect has to be done as a task because the receiver will # be cancelled by the reconnect and we don't want the reconnect # to be aborted half-way through - jasyncio.ensure_future(self.reconnect()) + asyncio.ensure_future(self.reconnect()) return except Exception as e: log.exception("Error in receiver") @@ -519,7 +520,7 @@ async def _do_ping(): try: log.debug(f"Pinger {self._pinger_task}: pinging") await pinger_facade.Ping() - except jasyncio.CancelledError: + except asyncio.CancelledError: raise pinger_facade = client.PingerFacade.from_connection(self) @@ -530,8 +531,8 @@ async def _do_ping(): ) if self.monitor.close_called.is_set(): break - await jasyncio.sleep(10) - except jasyncio.CancelledError: + await asyncio.sleep(10) + except asyncio.CancelledError: log.debug("Pinger: Cancelled") pass except websockets.exceptions.ConnectionClosed: @@ -588,7 +589,7 @@ async def rpc( # if it is triggered by the pinger, then this RPC call will # be cancelled when the pinger is cancelled by the reconnect, # and we don't want the reconnect to be aborted halfway through - await jasyncio.wait([jasyncio.create_task(self.reconnect())]) + await asyncio.wait([asyncio.create_task(self.reconnect())]) if self.monitor.status != Monitor.CONNECTED: # reconnect failed; abort and shutdown log.error("RPC: Automatic reconnect failed") @@ -720,7 +721,7 @@ async def reconnect(self): self._build_facades(res.get("facades", {})) if not self._pinger_task: log.debug("reconnect: scheduling a pinger task") - self._pinger_task = jasyncio.create_task( + self._pinger_task = asyncio.create_task( self._pinger(), name="Task_Pinger" ) @@ -732,20 +733,20 @@ async def _try_endpoint( endpoint, cacert, delay ) -> tuple[_WebSocket, str, str, str]: if delay: - await jasyncio.sleep(delay) + await asyncio.sleep(delay) return await self._open(endpoint, cacert) # Try all endpoints in parallel, with slight increasing delay (+100ms # for each subsequent endpoint); the delay allows us to prefer the # earlier endpoints over the latter. Use first successful connection. tasks = [ - jasyncio.ensure_future(_try_endpoint(endpoint, cacert, 0.1 * i)) + asyncio.ensure_future(_try_endpoint(endpoint, cacert, 0.1 * i)) for i, (endpoint, cacert) in enumerate(endpoints) ] result: tuple[_WebSocket, str, str, str] | None = None for attempt in range(self._retries + 1): - for task in jasyncio.as_completed(tasks): + for task in asyncio.as_completed(tasks): try: result = await task break @@ -757,7 +758,7 @@ async def _try_endpoint( log.debug( f"Retrying connection to endpoints: {_endpoints_str}; attempt {attempt + 1} of {self._retries + 1}" ) - await jasyncio.sleep((attempt + 1) * self._retry_backoff) + await asyncio.sleep((attempt + 1) * self._retry_backoff) continue else: raise errors.JujuConnectionError( @@ -780,7 +781,7 @@ async def _try_endpoint( # If this is a debug-log connection, and the _debug_log_task # is not created yet, then go ahead and schedule it if self.is_debug_log_connection and not self._debug_log_task: - self._debug_log_task = jasyncio.create_task( + self._debug_log_task = asyncio.create_task( self._debug_logger(), name="Task_Debug_Log" ) @@ -788,7 +789,7 @@ async def _try_endpoint( # receiver_task yet, then schedule a _receiver_task elif not self.is_debug_log_connection and not self._receiver_task: log.debug("_connect: scheduling a receiver task") - self._receiver_task = jasyncio.create_task( + self._receiver_task = asyncio.create_task( self._receiver(), name="Task_Receiver" ) @@ -845,7 +846,7 @@ async def _connect_with_redirect(self, endpoints): self._build_facades(login_result.get("facades", {})) if not self._pinger_task: log.debug("_connect_with_redirect: scheduling a pinger task") - self._pinger_task = jasyncio.create_task(self._pinger(), name="Task_Pinger") + self._pinger_task = asyncio.create_task(self._pinger(), name="Task_Pinger") # _build_facades takes the facade list that comes from the connection with the controller, # validates that the client knows about them (client_facade_versions) and builds the facade list @@ -890,12 +891,14 @@ async def login(self): ] try: - return await self.rpc({ - "type": "Admin", - "request": "Login", - "version": 3, - "params": params, - }) + return await self.rpc( + { + "type": "Admin", + "request": "Login", + "version": 3, + "params": params, + } + ) except errors.JujuAPIError as e: if e.error_code != "redirection required": raise @@ -913,11 +916,13 @@ async def login(self): # we can safely close the connection after login # fails. redirect_info = ( - await self.rpc({ - "type": "Admin", - "request": "RedirectInfo", - "version": 3, - }) + await self.rpc( + { + "type": "Admin", + "request": "RedirectInfo", + "version": 3, + } + ) )["response"] raise errors.JujuRedirectException(redirect_info, True) from e diff --git a/juju/controller.py b/juju/controller.py index c5b077daa..93e943725 100644 --- a/juju/controller.py +++ b/juju/controller.py @@ -1,6 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. +import asyncio import json import logging from concurrent.futures import CancelledError @@ -8,7 +9,7 @@ import websockets -from . import errors, jasyncio, tag, utils +from . import errors, tag, utils from .client import client, connector from .errors import JujuAPIError from .offerendpoints import ParseError as OfferParseError @@ -841,7 +842,7 @@ async def watch_model_summaries(self, callback, as_admin=False): all models in the controller. If the user isn't a superuser they will get a permission error. """ - stop_event = jasyncio.Event() + stop_event = asyncio.Event() async def _watcher(stop_event): try: @@ -882,7 +883,7 @@ async def _watcher(stop_event): raise log.debug("Starting watcher task for model summaries") - jasyncio.ensure_future(_watcher(stop_event)) + asyncio.ensure_future(_watcher(stop_event)) return stop_event async def add_secret_backends(self, id_, name, backend_type, config): @@ -905,15 +906,17 @@ async def add_secret_backends(self, id_, name, backend_type, config): """ facade = client.SecretBackendsFacade.from_connection(self.connection()) - return await facade.AddSecretBackends([ - { - "id": id_, - "backend-type": backend_type, - "config": config, - "name": name, - "token-rotate-interval": config.get("token-rotate-interval", None), - } - ]) + return await facade.AddSecretBackends( + [ + { + "id": id_, + "backend-type": backend_type, + "config": config, + "name": name, + "token-rotate-interval": config.get("token-rotate-interval", None), + } + ] + ) async def list_secret_backends(self, reveal=False): """Return the list of secret backends @@ -973,15 +976,17 @@ async def update_secret_backends( """ facade = client.SecretBackendsFacade.from_connection(self.connection()) - return await facade.UpdateSecretBackends([ - { - "name": name, - "config": config, - "force": force, - "token-rotate-interval": token_rotate_interval, - "name-change": name_change, - } - ]) + return await facade.UpdateSecretBackends( + [ + { + "name": name, + "config": config, + "force": force, + "token-rotate-interval": token_rotate_interval, + "name-change": name_change, + } + ] + ) class ConnectedController(Controller): diff --git a/juju/jasyncio.py b/juju/jasyncio.py index b962719b9..bbb11fe99 100644 --- a/juju/jasyncio.py +++ b/juju/jasyncio.py @@ -84,7 +84,7 @@ import websockets warnings.warn( - "The jasyncio module is deprecated and will be removed in a future release.", + "juju.jasyncio module is being deprecated by 3.0, use asyncio or juju._jasyncio instead", DeprecationWarning, stacklevel=2, ) diff --git a/juju/loop.py b/juju/loop.py index d9d2e8f8a..fa0da6d67 100644 --- a/juju/loop.py +++ b/juju/loop.py @@ -6,7 +6,7 @@ import warnings warnings.warn( - "juju.loop module is being deprecated by 3.0, use juju.jasyncio instead", + "juju.loop module is being deprecated by 3.0, use juju._jasyncio instead", DeprecationWarning, stacklevel=2, ) diff --git a/juju/machine.py b/juju/machine.py index 70b7327bd..3fdd43692 100644 --- a/juju/machine.py +++ b/juju/machine.py @@ -1,6 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. +import asyncio import ipaddress import logging import typing @@ -9,7 +10,7 @@ from juju.utils import block_until, juju_ssh_key_paths -from . import jasyncio, model, tag +from . import model, tag from .annotationhelper import _get_annotations, _set_annotations from .client import client from .errors import JujuError @@ -158,11 +159,11 @@ async def _scp(self, source, destination, scp_opts): retry_backoff = 2 retries = 10 for _ in range(retries): - process = await jasyncio.create_subprocess_exec(*cmd) + process = await asyncio.create_subprocess_exec(*cmd) await process.wait() if process.returncode == 0: break - await jasyncio.sleep(retry_backoff) + await asyncio.sleep(retry_backoff) if process.returncode != 0: raise JujuError(f"command failed after {retries} attempts: {cmd}") @@ -211,13 +212,13 @@ async def ssh( retry_backoff = 2 retries = 10 for _ in range(retries): - process = await jasyncio.create_subprocess_exec( - *cmd, stdout=jasyncio.subprocess.PIPE, stderr=jasyncio.subprocess.PIPE + process = await asyncio.create_subprocess_exec( + *cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE ) stdout, stderr = await process.communicate() if process.returncode == 0: break - await jasyncio.sleep(retry_backoff) + await asyncio.sleep(retry_backoff) if process.returncode != 0: raise JujuError( f"command failed: {cmd} after {retries} attempts, with {stderr.decode()}" diff --git a/juju/model.py b/juju/model.py index ada4ac29b..2475914a8 100644 --- a/juju/model.py +++ b/juju/model.py @@ -2,6 +2,7 @@ # Licensed under the Apache V2, see LICENCE file for details. from __future__ import annotations +import asyncio import base64 import collections import hashlib @@ -24,7 +25,7 @@ import websockets import yaml -from . import jasyncio, provisioner, tag, utils +from . import provisioner, tag, utils from .annotationhelper import _get_annotations, _set_annotations from .bundle import BundleHandler, get_charm_series, is_local_charm from .charmhub import CharmHub @@ -609,9 +610,9 @@ def __init__( self.state = ModelState(self) self._info = None self._mode = None - self._watch_stopping = jasyncio.Event() - self._watch_stopped = jasyncio.Event() - self._watch_received = jasyncio.Event() + self._watch_stopping = asyncio.Event() + self._watch_stopped = asyncio.Event() + self._watch_received = asyncio.Event() self._watch_stopped.set() self._charmhub = CharmHub(self) @@ -783,7 +784,7 @@ async def _after_connect(self, model_name=None, model_uuid=None): async def watch_received_waiter(): await self._watch_received.wait() - waiter = jasyncio.create_task(watch_received_waiter()) + waiter = asyncio.create_task(watch_received_waiter()) # If we just wait for the _watch_received event and the _all_watcher task # fails (e.g. because API fails like migration is in progress), then @@ -792,8 +793,8 @@ async def watch_received_waiter(): # If _all_watcher is done before the _watch_received, then we should see # (and raise) an exception coming from the _all_watcher # Otherwise (i.e. _watch_received is set), then we're good to go - done, _pending = await jasyncio.wait( - [waiter, self._watcher_task], return_when=jasyncio.FIRST_COMPLETED + done, _pending = await asyncio.wait( + [waiter, self._watcher_task], return_when=asyncio.FIRST_COMPLETED ) if self._watcher_task in done: # Cancel the _watch_received.wait @@ -853,7 +854,7 @@ async def add_local_charm_dir(self, charm_dir, series): CharmArchiveGenerator(str(charm_dir)).make_archive(fn) with open(str(fn), "rb") as fh: func = partial(self.add_local_charm, fh, series, os.stat(str(fn)).st_size) - loop = jasyncio.get_running_loop() + loop = asyncio.get_running_loop() charm_url = await loop.run_in_executor(None, func) log.debug("Uploaded local charm: %s -> %s", charm_dir, charm_url) @@ -1322,7 +1323,7 @@ async def _all_watcher(): self._watch_received.clear() self._watch_stopping.clear() self._watch_stopped.clear() - self._watcher_task = jasyncio.create_task(_all_watcher()) + self._watcher_task = asyncio.create_task(_all_watcher()) async def _notify_observers(self, delta, old_obj, new_obj): """Call observing callbacks, notifying them of a change in model state @@ -1342,7 +1343,7 @@ async def _notify_observers(self, delta, old_obj, new_obj): for o in self._observers: if o.cares_about(delta): - jasyncio.ensure_future(o(delta, old_obj, new_obj, self)) + asyncio.ensure_future(o(delta, old_obj, new_obj, self)) async def _wait(self, entity_type, entity_id, action, predicate=None): """Block the calling routine until a given action has happened to the @@ -1358,7 +1359,7 @@ async def _wait(self, entity_type, entity_id, action, predicate=None): has a 'completed' status. See the _Observer class for details. """ - q = jasyncio.Queue() + q = asyncio.Queue() async def callback(delta, old, new, model): await q.put(delta.get_id()) @@ -1843,10 +1844,14 @@ async def deploy( if pending_apps: # new apps will usually be in the model by now, but if some # haven't made it yet we'll need to wait on them to be added - await jasyncio.gather(*[ - jasyncio.ensure_future(self._wait_for_new("application", app_name)) - for app_name in pending_apps - ]) + await asyncio.gather( + *[ + asyncio.ensure_future( + self._wait_for_new("application", app_name) + ) + for app_name in pending_apps + ] + ) return [ app for name, app in self.applications.items() @@ -2316,13 +2321,15 @@ async def destroy_units( if unit_tag is None: log.error("Error converting %s to a valid unit tag", unit_id) raise JujuUnitError("Error converting %s to a valid unit tag", unit_id) - units_to_destroy.append({ - "unit-tag": unit_tag, - "destroy-storage": destroy_storage, - "force": force, - "max-wait": max_wait, - "dry-run": dry_run, - }) + units_to_destroy.append( + { + "unit-tag": unit_tag, + "destroy-storage": destroy_storage, + "force": force, + "max-wait": max_wait, + "dry-run": dry_run, + } + ) log.debug("Destroying units %s", unit_names) return await app_facade.DestroyUnit(units=units_to_destroy) @@ -2554,9 +2561,9 @@ async def _wait_for_action_status(): if action_output.results[0].status in ("completed", "failed"): return else: - await jasyncio.sleep(1) + await asyncio.sleep(1) - await jasyncio.wait_for(_wait_for_action_status(), timeout=wait) + await asyncio.wait_for(_wait_for_action_status(), timeout=wait) action_results = await action_facade.Actions(entities=entity) return action_results.results[0] @@ -2789,13 +2796,15 @@ async def add_secret(self, name, data_args, file="", info=""): raise JujuNotSupportedError("user secrets") secrets_facade = client.SecretsFacade.from_connection(self.connection()) - results = await secrets_facade.CreateSecrets([ - { - "content": {"data": data}, - "description": info, - "label": name, - } - ]) + results = await secrets_facade.CreateSecrets( + [ + { + "content": {"data": data}, + "description": info, + "label": name, + } + ] + ) if len(results.results) != 1: raise JujuAPIError(f"expected 1 result, got {len(results.results)}") result = results.results[0] @@ -2824,14 +2833,16 @@ async def update_secret(self, name, data_args=[], new_name="", file="", info="") if client.SecretsFacade.best_facade_version(self.connection()) < 2: raise JujuNotSupportedError("user secrets") secrets_facade = client.SecretsFacade.from_connection(self.connection()) - results = await secrets_facade.UpdateSecrets([ - { - "content": {"data": data}, - "description": info, - "existing-label": name, - "label": new_name, - } - ]) + results = await secrets_facade.UpdateSecrets( + [ + { + "content": {"data": data}, + "description": info, + "existing-label": name, + "label": new_name, + } + ] + ) if len(results.results) != 1: raise JujuAPIError(f"expected 1 result, got {len(results.results)}") result_error = results.results[0] @@ -3132,11 +3143,11 @@ def _raise_for_status(entities, status): break busy = "\n ".join(busy) if timeout is not None and datetime.now() - start_time > timeout: - raise jasyncio.TimeoutError("Timed out waiting for model:\n" + busy) + raise asyncio.TimeoutError("Timed out waiting for model:\n" + busy) if last_log_time is None or datetime.now() - last_log_time > log_interval: log.info("Waiting for model:\n " + busy) last_log_time = datetime.now() - await jasyncio.sleep(check_freq) + await asyncio.sleep(check_freq) def _create_consume_args(offer, macaroon, controller_info): diff --git a/juju/utils.py b/juju/utils.py index 710fcc56e..e5b4604ac 100644 --- a/juju/utils.py +++ b/juju/utils.py @@ -15,7 +15,9 @@ from pyasn1.codec.der.encoder import encode from pyasn1.type import char, univ -from . import errors, jasyncio, origin +from juju import _jasyncio + +from . import errors, origin from .client import client from .errors import JujuError @@ -186,17 +188,17 @@ async def run_with_interrupt(task, *events, log=None): :param events: One or more `asyncio.Event`s which, if set, will interrupt `task` and cause it to be cancelled. """ - task = jasyncio.create_task_with_handler(task, "tmp", log) - event_tasks = [jasyncio.ensure_future(event.wait()) for event in events] - done, pending = await jasyncio.wait( - [task, *event_tasks], return_when=jasyncio.FIRST_COMPLETED + task = _jasyncio.create_task_with_handler(task, "tmp", log) + event_tasks = [asyncio.ensure_future(event.wait()) for event in events] + done, pending = await asyncio.wait( + [task, *event_tasks], return_when=asyncio.FIRST_COMPLETED ) for f in pending: f.cancel() # cancel unfinished tasks for f in pending: try: await f - except jasyncio.CancelledError: + except asyncio.CancelledError: pass for f in done: f.exception() # prevent "exception was not retrieved" errors diff --git a/tests/integration/test_application.py b/tests/integration/test_application.py index 06b48cd2d..07c6935a7 100644 --- a/tests/integration/test_application.py +++ b/tests/integration/test_application.py @@ -7,7 +7,7 @@ import pytest -from juju import errors, jasyncio +from juju import errors from juju.application import Application from juju.client import client from juju.url import URL, Schema @@ -24,7 +24,7 @@ async def test_action(): async with base.CleanModel() as model: app = await model.deploy("juju-qa-test") - await jasyncio.sleep(10) + await asyncio.sleep(10) actions = await app.get_actions(schema=True) assert "fortune" in actions diff --git a/tests/integration/test_charmhub.py b/tests/integration/test_charmhub.py index b09dda053..5f2fe744b 100644 --- a/tests/integration/test_charmhub.py +++ b/tests/integration/test_charmhub.py @@ -1,9 +1,10 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. +import asyncio + import pytest -from juju import jasyncio from juju.errors import JujuError from .. import base @@ -103,11 +104,11 @@ async def test_subordinate_charm_zero_units(): async with base.CleanModel() as model: # rsyslog-forwarder-ha is a subordinate charm app = await model.deploy("rsyslog-forwarder-ha") - await jasyncio.sleep(5) + await asyncio.sleep(5) assert len(app.units) == 0 await app.destroy() - await jasyncio.sleep(5) + await asyncio.sleep(5) # note that it'll error if the user tries to use num_units with pytest.raises(JujuError): @@ -116,7 +117,7 @@ async def test_subordinate_charm_zero_units(): # (full disclosure: it'll quietly switch to 0 if user enters # num_units=1, instead of erroring) app2 = await model.deploy("rsyslog-forwarder-ha", num_units=1) - await jasyncio.sleep(5) + await asyncio.sleep(5) assert len(app2.units) == 0 diff --git a/tests/integration/test_connection.py b/tests/integration/test_connection.py index a47f96d0c..ac3d5f585 100644 --- a/tests/integration/test_connection.py +++ b/tests/integration/test_connection.py @@ -1,6 +1,6 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. - +import asyncio import http import logging import socket @@ -11,7 +11,6 @@ import pytest import websockets -from juju import jasyncio from juju.client import client from juju.client.connection import Connection from juju.client.jujudata import FileJujuData @@ -46,7 +45,7 @@ async def test_monitor_catches_error(): await conn._ws.close() # this could be racy with reconnect # if auto-reconnect is not disabled by lock, force this # test to fail by deferring to the reconnect task via sleep - await jasyncio.sleep(0.1) + await asyncio.sleep(0.1) assert conn.monitor.status == "error" finally: await conn.close() @@ -74,7 +73,7 @@ async def test_reconnect(): kwargs = model.connection().connect_params() conn = await Connection.connect(**kwargs) try: - await jasyncio.sleep(0.1) + await asyncio.sleep(0.1) assert conn.is_open await conn._ws.close() assert not conn.is_open @@ -133,12 +132,12 @@ async def test_redirect(): class RedirectServer: def __init__(self, destination): self.destination = destination - self._start = jasyncio.Event() - self._stop = jasyncio.Event() - self._terminate = jasyncio.Event() - self.running = jasyncio.Event() - self.stopped = jasyncio.Event() - self.terminated = jasyncio.Event() + self._start = asyncio.Event() + self._stop = asyncio.Event() + self._terminate = asyncio.Event() + self.running = asyncio.Event() + self.stopped = asyncio.Event() + self.terminated = asyncio.Event() if hasattr(ssl, "PROTOCOL_TLS_SERVER"): # python 3.6+ protocol = ssl.PROTOCOL_TLS_SERVER @@ -148,7 +147,7 @@ def __init__(self, destination): self.ssl_context.load_cert_chain(str(crt_file), str(key_file)) self.status = None self.port = None - self._task = jasyncio.create_task(self.run()) + self._task = asyncio.create_task(self.run()) def start(self, status): self.status = status @@ -166,7 +165,7 @@ def terminate(self): def exception(self): try: return self._task.exception() - except (jasyncio.CancelledError, jasyncio.InvalidStateError): + except (asyncio.CancelledError, asyncio.InvalidStateError): return None async def run(self): @@ -192,16 +191,16 @@ async def redirect(path, request_headers): host="localhost", port=self.port, ssl=self.ssl_context, - loop=jasyncio.get_running_loop(), + loop=asyncio.get_running_loop(), ): self.stopped.clear() self.running.set() logger.debug("server: started") while not self._stop.is_set(): - await run_with_interrupt(jasyncio.sleep(1), self._stop) + await run_with_interrupt(asyncio.sleep(1), self._stop) logger.debug("server: tick") logger.debug("server: stopping") - except jasyncio.CancelledError: + except asyncio.CancelledError: break finally: self.stopped.set() @@ -209,7 +208,7 @@ async def redirect(path, request_headers): self.running.clear() logger.debug("server: stopped") logger.debug("server: terminating") - except jasyncio.CancelledError: + except asyncio.CancelledError: pass finally: self._start.clear() diff --git a/tests/integration/test_crossmodel.py b/tests/integration/test_crossmodel.py index 6d2eef437..444826a4b 100644 --- a/tests/integration/test_crossmodel.py +++ b/tests/integration/test_crossmodel.py @@ -1,13 +1,12 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. +import asyncio import tempfile from pathlib import Path import pytest -from juju import jasyncio - from .. import base @@ -86,7 +85,7 @@ async def test_remove_saas(): await model_2.consume(f"admin/{model_1.name}.ubuntu") await model_2.remove_saas("ubuntu") - await jasyncio.sleep(5) + await asyncio.sleep(5) status = await model_2.get_status() if "ubuntu" in status.remote_applications: @@ -137,7 +136,7 @@ async def test_relate_with_offer(): raise Exception("Expected postgresql in saas") await model_2.remove_saas("postgresql") - await jasyncio.sleep(5) + await asyncio.sleep(5) status = await model_2.get_status() if "postgresql" in status.remote_applications: diff --git a/tests/integration/test_model.py b/tests/integration/test_model.py index e843a774d..85f3afad0 100644 --- a/tests/integration/test_model.py +++ b/tests/integration/test_model.py @@ -1,6 +1,6 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. - +import asyncio import json import os import random @@ -13,7 +13,7 @@ import pylxd import pytest -from juju import jasyncio, tag, url +from juju import tag, url from juju.client import client from juju.client._definitions import FullStatus from juju.errors import JujuConnectionError, JujuError, JujuModelError, JujuUnitError @@ -296,7 +296,7 @@ async def test_wait_local_charm_waiting_timeout(): await model.deploy(str(charm_path), config={"status": "waiting"}) assert "charm" in model.applications await model.wait_for_idle() - with pytest.raises(jasyncio.TimeoutError): + with pytest.raises(asyncio.TimeoutError): await model.wait_for_idle(status="active", timeout=30) @@ -712,14 +712,14 @@ async def test_relate(): num_units=0, ) - relation_added = jasyncio.Event() - timeout = jasyncio.Event() + relation_added = asyncio.Event() + timeout = asyncio.Event() class TestObserver(ModelObserver): async def on_relation_add(self, delta, old, new, model): if set(new.key.split()) == {"nrpe:general-info", "ubuntu:juju-info"}: relation_added.set() - jasyncio.get_running_loop().call_later(10, timeout.set) + asyncio.get_running_loop().call_later(10, timeout.set) model.add_observer(TestObserver()) @@ -896,7 +896,7 @@ async def test_wait_for_idle_without_units(): channel="stable", num_units=0, ) - with pytest.raises(jasyncio.TimeoutError): + with pytest.raises(asyncio.TimeoutError): await model.wait_for_idle(timeout=10) @@ -910,7 +910,7 @@ async def test_wait_for_idle_with_not_enough_units(): channel="stable", num_units=2, ) - with pytest.raises(jasyncio.TimeoutError): + with pytest.raises(asyncio.TimeoutError): await model.wait_for_idle(timeout=5 * 60, wait_for_at_least_units=3) @@ -1052,10 +1052,12 @@ async def test_config(): # first test get_config with nothing. result = await model.get_config() assert "extra-info" not in result - await model.set_config({ - "extra-info": "booyah", - "test-mode": client.ConfigValue(value=True), - }) + await model.set_config( + { + "extra-info": "booyah", + "test-mode": client.ConfigValue(value=True), + } + ) result = await model.get_config() assert "extra-info" in result assert result["extra-info"].source == "model" @@ -1070,10 +1072,12 @@ async def test_config_with_json(): assert "extra-complex-info" not in result # test model config with more complex data expected = ["foo", {"bar": 1}] - await model.set_config({ - "extra-complex-info": json.dumps(expected), - "test-mode": client.ConfigValue(value=True), - }) + await model.set_config( + { + "extra-complex-info": json.dumps(expected), + "test-mode": client.ConfigValue(value=True), + } + ) result = await model.get_config() assert "extra-complex-info" in result assert result["extra-complex-info"].source == "model" @@ -1280,7 +1284,7 @@ async def test_model_attach_storage_at_deploy(): storage_id = ret[0] await unit.detach_storage(storage_id, force=True) - await jasyncio.sleep(10) + await asyncio.sleep(10) storages1 = await model.list_storage() assert any([storage_id in s["storage-tag"] for s in storages1]) @@ -1288,7 +1292,7 @@ async def test_model_attach_storage_at_deploy(): # juju remove-application # actually removes the storage even though the destroy_storage=false await app.destroy(destroy_storage=False) - await jasyncio.sleep(10) + await asyncio.sleep(10) storages2 = await model.list_storage() assert any([storage_id in s["storage-tag"] for s in storages2]) @@ -1309,14 +1313,14 @@ async def test_detach_storage(): unit = app.units[0] storage_ids = await unit.add_storage("pgdata") storage_id = storage_ids[0] - await jasyncio.sleep(5) + await asyncio.sleep(5) _storage_details_1 = await model.show_storage_details(storage_id) storage_details_1 = _storage_details_1[0] assert "unit-postgresql-0" in storage_details_1["attachments"] await unit.detach_storage(storage_id, force=True) - await jasyncio.sleep(20) + await asyncio.sleep(20) _storage_details_2 = await model.show_storage_details(storage_id) storage_details_2 = _storage_details_2[0] @@ -1326,7 +1330,7 @@ async def test_detach_storage(): # remove_storage await model.remove_storage(storage_id, force=True) - await jasyncio.sleep(10) + await asyncio.sleep(10) storages = await model.list_storage() assert all([storage_id not in s["storage-tag"] for s in storages]) @@ -1341,7 +1345,7 @@ async def test_add_and_list_storage(): # All we need is to make sure a unit is up, doesn't even need to # be in 'active' or 'idle', i.e. # await model.wait_for_idle(status="waiting", wait_for_exact_units=1) - await jasyncio.sleep(5) + await asyncio.sleep(5) unit = app.units[0] await unit.add_storage("pgdata", size=512) storages = await model.list_storage() @@ -1363,6 +1367,6 @@ async def test_storage_pools_on_lxd(): assert "test-pool" in [p["name"] for p in pools] await model.remove_storage_pool("test-pool") - await jasyncio.sleep(5) + await asyncio.sleep(5) pools = await model.list_storage_pools() assert "test-pool" not in [p["name"] for p in pools] diff --git a/tests/integration/test_unit.py b/tests/integration/test_unit.py index 4f7be5468..1055754aa 100644 --- a/tests/integration/test_unit.py +++ b/tests/integration/test_unit.py @@ -7,7 +7,7 @@ import pytest -from juju import jasyncio, utils +from juju import utils from .. import base @@ -164,7 +164,7 @@ def check_results(results, out): async def test_scp(): # ensure that asyncio.subprocess will work; try: - asyncio.get_child_watcher().attach_loop(jasyncio.get_running_loop()) + asyncio.get_child_watcher().attach_loop(asyncio.get_running_loop()) except RuntimeError: pytest.skip("test_scp will always fail outside of MainThread") async with base.CleanModel() as model: @@ -197,7 +197,7 @@ async def test_scp(): async def test_ssh(): # ensure that asyncio.subprocess will work; try: - asyncio.get_child_watcher().attach_loop(jasyncio.get_running_loop()) + asyncio.get_child_watcher().attach_loop(asyncio.get_running_loop()) except RuntimeError: pytest.skip("test_ssh will always fail outside of MainThread") async with base.CleanModel() as model: diff --git a/tests/unit/test_bundle.py b/tests/unit/test_bundle.py index b5f92756e..f1f18a254 100644 --- a/tests/unit/test_bundle.py +++ b/tests/unit/test_bundle.py @@ -934,10 +934,12 @@ async def test_run(self): assert result is None model.applications["application1"].expose.assert_called_once() - model.applications["application1"].expose.assert_called_with({ - "": {"to-spaces": ["alpha"], "to-cidrs": ["10.0.0.0/24"]}, - "foo": {"to-spaces": ["alien"], "to-cidrs": ["0.0.0.0/0", "::/0"]}, - }) + model.applications["application1"].expose.assert_called_with( + { + "": {"to-spaces": ["alpha"], "to-cidrs": ["10.0.0.0/24"]}, + "foo": {"to-spaces": ["alien"], "to-cidrs": ["0.0.0.0/0", "::/0"]}, + } + ) class TestScaleChange(unittest.TestCase): diff --git a/tests/unit/test_connection.py b/tests/unit/test_connection.py index a7cc808cb..9a0fd22af 100644 --- a/tests/unit/test_connection.py +++ b/tests/unit/test_connection.py @@ -35,11 +35,13 @@ async def close(self): async def test_out_of_order(): - ws = WebsocketMock([ - {"request-id": 1}, - {"request-id": 3}, - {"request-id": 2}, - ]) + ws = WebsocketMock( + [ + {"request-id": 1}, + {"request-id": 3}, + {"request-id": 2}, + ] + ) expected_responses = [ {"request-id": 1}, {"request-id": 2}, @@ -78,33 +80,35 @@ async def test_bubble_redirect_exception(): -----BEGIN CERTIFICATE----- SOMECERT -----END CERTIFICATE-----""" - ws = WebsocketMock([ - { - "request-id": 1, - "error": "redirection to alternative server required", - "error-code": "redirection required", - "error-info": { - "ca-cert": ca_cert, - "servers": [ - [ - { - "port": 17070, - "scope": "local-cloud", - "type": "ipv4", - "value": "42.42.42.42", - }, - { - "port": 4242, - "scope": "public", - "type": "ipv4", - "value": "42.42.42.42", - }, - ] - ], + ws = WebsocketMock( + [ + { + "request-id": 1, + "error": "redirection to alternative server required", + "error-code": "redirection required", + "error-info": { + "ca-cert": ca_cert, + "servers": [ + [ + { + "port": 17070, + "scope": "local-cloud", + "type": "ipv4", + "value": "42.42.42.42", + }, + { + "port": 4242, + "scope": "public", + "type": "ipv4", + "value": "42.42.42.42", + }, + ] + ], + }, + "response": {}, }, - "response": {}, - }, - ]) + ] + ) with pytest.raises(JujuRedirectException) as caught_ex: with mock.patch("websockets.connect", mock.AsyncMock(return_value=ws)): await Connection.connect("0.1.2.3:999") @@ -123,48 +127,52 @@ async def test_follow_redirect(): -----BEGIN CERTIFICATE----- SOMECERT -----END CERTIFICATE-----""" - cont1 = WebsocketMock([ - { - "request-id": 1, - "error": "redirection to alternative server required", - "error-code": "redirection required", - "response": {}, - }, - { - "request-id": 2, - "response": { - "ca-cert": ca_cert, - "servers": [ - [ - { - "port": 17070, - "scope": "local-cloud", - "type": "ipv4", - "value": "42.42.42.42", - }, - { - "port": 4242, - "scope": "public", - "type": "ipv4", - "value": "42.42.42.42", - }, - ] - ], + cont1 = WebsocketMock( + [ + { + "request-id": 1, + "error": "redirection to alternative server required", + "error-code": "redirection required", + "response": {}, + }, + { + "request-id": 2, + "response": { + "ca-cert": ca_cert, + "servers": [ + [ + { + "port": 17070, + "scope": "local-cloud", + "type": "ipv4", + "value": "42.42.42.42", + }, + { + "port": 4242, + "scope": "public", + "type": "ipv4", + "value": "42.42.42.42", + }, + ] + ], + }, }, - }, - ]) + ] + ) minimal_facades = [{"name": "Pinger", "versions": [1]}] - cont2 = WebsocketMock([ - {"request-id": 1}, - {"request-id": 2}, - { - "request-id": 3, - "response": { - "result": minimal_facades, - "server-version": "3.0", + cont2 = WebsocketMock( + [ + {"request-id": 1}, + {"request-id": 2}, + { + "request-id": 3, + "response": { + "result": minimal_facades, + "server-version": "3.0", + }, }, - }, - ]) + ] + ) con = None try: @@ -181,9 +189,11 @@ async def test_follow_redirect(): async def test_rpc_none_results(): - ws = WebsocketMock([ - {"request-id": 1, "response": {"results": None}}, - ]) + ws = WebsocketMock( + [ + {"request-id": 1, "response": {"results": None}}, + ] + ) expected_responses = [ {"request-id": 1, "response": {"results": None}}, ] diff --git a/tests/unit/test_definitions.py b/tests/unit/test_definitions.py index 1ec7776ec..2d5f70bcf 100644 --- a/tests/unit/test_definitions.py +++ b/tests/unit/test_definitions.py @@ -8,25 +8,27 @@ class TestDefinitions(unittest.TestCase): def test_dict_legacy(self): - status = client.FullStatus.from_json({ - "relations": [ - { - "endpoints": [ - { - "application": "application", - "name": "name", - "role": "role", - "subordinate": True, - } - ], - "id": 1, - "interface": "interface", - "key": "key", - "scope": "scope", - "status": [], - } - ] - }) + status = client.FullStatus.from_json( + { + "relations": [ + { + "endpoints": [ + { + "application": "application", + "name": "name", + "role": "role", + "subordinate": True, + } + ], + "id": 1, + "interface": "interface", + "key": "key", + "scope": "scope", + "status": [], + } + ] + } + ) if status.relations != status["relations"]: raise Exception("subscript not equal to attr") if status.relations != status.get("relations"): @@ -35,63 +37,65 @@ def test_dict_legacy(self): raise Exception("get defaulting missing attr") def test_parse(self): - status = client.FullStatus.from_json({ - "relations": [ - { - "endpoints": [ - { - "application": "application", - "name": "name", - "role": "role", - "subordinate": True, - } - ], - "id": 1, - "interface": "interface", - "key": "key", - "scope": "scope", - "status": [], - } - ], - "applications": { - "app": { - "can-upgrade-to": "something", - "charm": "charm", - "charm-profile": "profile", - "charm-version": "2", - "endpoint-bindings": None, - "err": None, - "exposed": True, - "int": 0, - "life": "life", - "meter-statuses": {}, - "provider-id": "provider-id", - "public-address": "1.1.1.1", - "relations": { - "a": ["b", "c"], - }, - "series": "focal", - "status": {}, - "subordinate-to": ["other"], - "units": { - "unit-id": { - "address": "1.1.1.1", - "agent-status": {}, - "charm": "charm", - "leader": True, - "machine": "machine-0", - "opened-ports": ["1234"], - "provider-id": "provider", - "public-address": "1.1.1.2", - "subordinates": {}, - "workload-status": {}, - "workload-version": "1.2", - } - }, - "workload-version": "1.2", - } - }, - }) + status = client.FullStatus.from_json( + { + "relations": [ + { + "endpoints": [ + { + "application": "application", + "name": "name", + "role": "role", + "subordinate": True, + } + ], + "id": 1, + "interface": "interface", + "key": "key", + "scope": "scope", + "status": [], + } + ], + "applications": { + "app": { + "can-upgrade-to": "something", + "charm": "charm", + "charm-profile": "profile", + "charm-version": "2", + "endpoint-bindings": None, + "err": None, + "exposed": True, + "int": 0, + "life": "life", + "meter-statuses": {}, + "provider-id": "provider-id", + "public-address": "1.1.1.1", + "relations": { + "a": ["b", "c"], + }, + "series": "focal", + "status": {}, + "subordinate-to": ["other"], + "units": { + "unit-id": { + "address": "1.1.1.1", + "agent-status": {}, + "charm": "charm", + "leader": True, + "machine": "machine-0", + "opened-ports": ["1234"], + "provider-id": "provider", + "public-address": "1.1.1.2", + "subordinates": {}, + "workload-status": {}, + "workload-version": "1.2", + } + }, + "workload-version": "1.2", + } + }, + } + ) if status.relations != status["relations"]: raise Exception("subscript not equal to attr") if status["relations"][0]["endpoints"][0]["application"] != "application": diff --git a/tests/unit/test_loop.py b/tests/unit/test_loop.py index c0abda127..82371f7fc 100644 --- a/tests/unit/test_loop.py +++ b/tests/unit/test_loop.py @@ -1,15 +1,16 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. +import asyncio import unittest -from juju import jasyncio +from juju import _jasyncio class TestLoop(unittest.TestCase): def setUp(self): # new event loop for each test - policy = jasyncio.get_event_loop_policy() + policy = asyncio.get_event_loop_policy() self.loop = policy.new_event_loop() policy.set_event_loop(self.loop) @@ -17,21 +18,21 @@ def tearDown(self): self.loop.close() async def test_run(self): - assert jasyncio.get_running_loop() == self.loop + assert asyncio.get_running_loop() == self.loop async def _test(): return "success" - self.assertEqual(jasyncio.run(_test()), "success") + self.assertEqual(_jasyncio.run(_test()), "success") async def test_run_interrupt(self): async def _test(): - jasyncio.run._sigint = True + _jasyncio.run._sigint = True - self.assertRaises(KeyboardInterrupt, jasyncio.run, _test()) + self.assertRaises(KeyboardInterrupt, _jasyncio.run, _test()) async def test_run_exception(self): async def _test(): raise ValueError() - self.assertRaises(ValueError, jasyncio.run, _test()) + self.assertRaises(ValueError, _jasyncio.run, _test()) diff --git a/tests/unit/test_model.py b/tests/unit/test_model.py index 0ec452d16..091043217 100644 --- a/tests/unit/test_model.py +++ b/tests/unit/test_model.py @@ -1,6 +1,7 @@ # Copyright 2023 Canonical Ltd. # Licensed under the Apache V2, see LICENCE file for details. +import asyncio import datetime import unittest from unittest import mock @@ -8,7 +9,6 @@ import pytest -from juju import jasyncio from juju.application import Application from juju.client.jujudata import FileJujuData from juju.errors import JujuConnectionError, JujuError @@ -267,7 +267,7 @@ async def test_apps_no_lst(self): async def test_timeout(self): m = Model() - with self.assertRaises(jasyncio.TimeoutError) as cm: + with self.assertRaises(asyncio.TimeoutError) as cm: # no apps so should timeout after timeout period await m.wait_for_idle(apps=["nonexisting_app"]) self.assertEqual( @@ -351,7 +351,7 @@ async def test_wait_for_active_units_waiting_application(self): mock_apps.return_value = apps m = Model() - with self.assertRaises(jasyncio.TimeoutError): + with self.assertRaises(asyncio.TimeoutError): await m.wait_for_idle(apps=["dummy_app"], status="active") mock_apps.assert_called_with() diff --git a/tests/unit/test_proxy.py b/tests/unit/test_proxy.py index 5af4b8cbe..a231e03e6 100644 --- a/tests/unit/test_proxy.py +++ b/tests/unit/test_proxy.py @@ -24,9 +24,11 @@ def test_proxy_from_config_unknown_type(self): def test_proxy_from_config_missing_type(self): """Test that a nil proxy type returns None.""" self.assertIsNone( - proxy_from_config({ - "config": {}, - }) + proxy_from_config( + { + "config": {}, + } + ) ) def test_proxy_from_config_non_arg(self): @@ -37,16 +39,18 @@ def test_proxy_from_config_non_arg(self): def test_proxy_from_config_kubernetes(self): """Tests that a Kubernetes proxy is correctly created from config.""" - proxy = proxy_from_config({ - "type": "kubernetes-port-forward", - "config": { - "api-host": "https://localhost:8456", - "namespace": "controller-python-test", - "remote-port": "1234", - "service": "controller", - "service-account-token": "==AA", - "ca-cert": "==AA", - }, - }) + proxy = proxy_from_config( + { + "type": "kubernetes-port-forward", + "config": { + "api-host": "https://localhost:8456", + "namespace": "controller-python-test", + "remote-port": "1234", + "service": "controller", + "service-account-token": "==AA", + "ca-cert": "==AA", + }, + } + ) self.assertIs(type(proxy), KubernetesProxy)