for unit in application.units))
await application.remove()
- await machine3.destroy()
- await machine2.destroy()
- await machine1.destroy()
+
+ await machine3.destroy(force=True)
+ await machine2.destroy(force=True)
+ await machine1.destroy(force=True)
finally:
await model.disconnect()
async def destroy(self, force=False):
"""Remove this machine from the model.
+ Blocks until the machine is actually removed.
+
"""
facade = client.ClientFacade()
facade.connect(self.connection)
log.debug(
'Destroying machine %s', self.id)
- return await facade.DestroyMachines(force, [self.id])
+ await facade.DestroyMachines(force, [self.id])
+ return await self.model._wait(
+ 'machine', self.id, 'remove')
remove = destroy
def run(self, command, timeout=None):
:param entity_type: The entity's type.
:param entity_id: The entity's id.
- :param action: the type of action (e.g., 'add' or 'change')
+ :param action: the type of action (e.g., 'add', 'change', or 'remove')
:param predicate: optional callable that must take as an
argument a delta, and must return a boolean, indicating
whether the delta contains the specific action we're looking
self.add_observer(callback, entity_type, action, entity_id, predicate)
entity_id = await q.get()
- return self.state._live_entity_map(entity_type)[entity_id]
+ # object might not be in the entity_map if we were waiting for a
+ # 'remove' action
+ return self.state._live_entity_map(entity_type).get(entity_id)
async def _wait_for_new(self, entity_type, entity_id=None, predicate=None):
"""Wait for a new object to appear in the Model and return it.
+import uuid
import subprocess
import pytest
+from juju.controller import Controller
+
def is_bootstrapped():
result = subprocess.run(['juju', 'switch'], stdout=subprocess.PIPE)
bootstrapped = pytest.mark.skipif(
not is_bootstrapped(),
reason='bootstrapped Juju environment required')
+
+
+class CleanModel():
+ def __init__(self):
+ self.controller = None
+ self.model = None
+
+ async def __aenter__(self):
+ self.controller = Controller()
+ await self.controller.connect_current()
+
+ model_name = 'model-{}'.format(uuid.uuid4())
+ self.model = await self.controller.add_model(model_name)
+
+ return self.model
+
+ async def __aexit__(self, exc_type, exc, tb):
+ await self.model.disconnect()
+ await self.controller.destroy_model(self.model.info.uuid)
+ await self.controller.disconnect()
import pytest
-from juju.client.connection import Connection
from juju.client import client
-from ..base import bootstrapped
+from .. import base
-@bootstrapped
+@base.bootstrapped
@pytest.mark.asyncio
async def test_user_info(event_loop):
- conn = await Connection.connect_current()
- controller_conn = await conn.controller()
+ async with base.CleanModel() as model:
+ controller_conn = await model.connection.controller()
- um = client.UserManagerFacade()
- um.connect(controller_conn)
- result = await um.UserInfo(
- [client.Entity('user-admin')], True)
- await conn.close()
- await controller_conn.close()
+ um = client.UserManagerFacade()
+ um.connect(controller_conn)
+ result = await um.UserInfo(
+ [client.Entity('user-admin')], True)
+ await controller_conn.close()
- assert isinstance(result, client.UserInfoResults)
- for r in result.results:
- assert isinstance(r, client.UserInfoResult)
+ assert isinstance(result, client.UserInfoResults)
+ for r in result.results:
+ assert isinstance(r, client.UserInfoResult)
import pytest
from juju.client.connection import Connection
-from ..base import bootstrapped
+from .. import base
-@bootstrapped
+@base.bootstrapped
@pytest.mark.asyncio
async def test_connect_current(event_loop):
- conn = await Connection.connect_current()
+ async with base.CleanModel():
+ conn = await Connection.connect_current()
- assert isinstance(conn, Connection)
- await conn.close()
+ assert isinstance(conn, Connection)
+ await conn.close()
-import uuid
-
import pytest
-from juju.controller import Controller
-
-from ..base import bootstrapped
+from .. import base
MB = 1
GB = 1024
-class CleanModel():
- def __init__(self):
- self.controller = None
- self.model = None
-
- async def __aenter__(self):
- self.controller = Controller()
- await self.controller.connect_current()
-
- model_name = 'model-{}'.format(uuid.uuid4())
- self.model = await self.controller.add_model(model_name)
-
- return self.model
-
- async def __aexit__(self, exc_type, exc, tb):
- await self.model.disconnect()
- await self.controller.destroy_model(self.model.info.uuid)
- await self.controller.disconnect()
-
-
-@bootstrapped
+@base.bootstrapped
@pytest.mark.asyncio
async def test_add_machine(event_loop):
from juju.machine import Machine
- async with CleanModel() as model:
+ async with base.CleanModel() as model:
# add a new default machine
machine1 = await model.add_machine()
assert isinstance(m, Machine)
assert len(model.machines) == 3
+
+ await machine3.destroy(force=True)
+ await machine2.destroy(force=True)
+ res = await machine1.destroy(force=True)
+
+ assert res is None
+ assert len(model.machines) == 0