Add controller module
The controller module allows us to run commands against the controller including listing all models and getting the cloud configuration name.
This commit is contained in:
80
unit_tests/test_zaza_controller.py
Normal file
80
unit_tests/test_zaza_controller.py
Normal file
@@ -0,0 +1,80 @@
|
||||
import mock
|
||||
|
||||
import unit_tests.utils as ut_utils
|
||||
|
||||
import zaza.controller as controller
|
||||
|
||||
|
||||
class TestController(ut_utils.BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestController, self).setUp()
|
||||
|
||||
async def _disconnect():
|
||||
return
|
||||
|
||||
async def _connect():
|
||||
return
|
||||
|
||||
async def _list_models():
|
||||
return self.models
|
||||
|
||||
async def _add_model(model_name):
|
||||
return self.model1
|
||||
|
||||
async def _destroy_model(model_name):
|
||||
return
|
||||
|
||||
async def _get_cloud():
|
||||
return self.cloud
|
||||
|
||||
# Cloud
|
||||
self.cloud = "FakeCloud"
|
||||
|
||||
# Model
|
||||
self.Model_mock = mock.MagicMock()
|
||||
self.Model_mock.connect.side_effect = _connect
|
||||
self.Model_mock.disconnect.side_effect = _disconnect
|
||||
self.Model_mock.disconnect.side_effect = _disconnect
|
||||
self.model1 = self.Model_mock
|
||||
self.model2 = mock.MagicMock()
|
||||
self.model1.info.name = "model1"
|
||||
self.model2.info.name = "model2"
|
||||
self.models = [self.model1.info.name, self.model2.info.name]
|
||||
|
||||
# Controller
|
||||
self.Controller_mock = mock.MagicMock()
|
||||
self.Controller_mock.connect.side_effect = _connect
|
||||
self.Controller_mock.disconnect.side_effect = _disconnect
|
||||
self.Controller_mock.add_model.side_effect = _add_model
|
||||
self.Controller_mock.destroy_model.side_effect = _destroy_model
|
||||
self.Controller_mock.list_models.side_effect = _list_models
|
||||
self.Controller_mock.get_cloud.side_effect = _get_cloud
|
||||
self.controller_name = "testcontroller"
|
||||
self.Controller_mock.info.name = self.controller_name
|
||||
self.patch_object(controller, 'Controller')
|
||||
self.Controller.return_value = self.Controller_mock
|
||||
|
||||
def test_add_model(self):
|
||||
self.assertEqual(controller.add_model(self.model1.info.name),
|
||||
self.model1.info.name)
|
||||
self.Controller_mock.add_model.assert_called_once_with(
|
||||
self.model1.info.name)
|
||||
self.model1.connect.assert_called_once()
|
||||
|
||||
def test_destroy_model(self):
|
||||
controller.destroy_model(self.model1.info.name)
|
||||
self.Controller_mock.destroy_model.assert_called_once_with(
|
||||
self.model1.info.name)
|
||||
|
||||
def test_get_cloud(self):
|
||||
self.assertEqual(
|
||||
controller.get_cloud(),
|
||||
self.cloud)
|
||||
self.Controller_mock.get_cloud.assert_called_once()
|
||||
|
||||
def test_list_models(self):
|
||||
self.assertEqual(
|
||||
controller.list_models(),
|
||||
self.models)
|
||||
self.Controller_mock.list_models.assert_called_once()
|
||||
@@ -0,0 +1,30 @@
|
||||
import asyncio
|
||||
|
||||
|
||||
def run(*steps):
|
||||
"""Run the given steps in an asyncio loop
|
||||
|
||||
:returns: The result of the asyncio.Task
|
||||
:rtype: Any
|
||||
"""
|
||||
if not steps:
|
||||
return
|
||||
loop = asyncio.get_event_loop()
|
||||
|
||||
for step in steps:
|
||||
task = loop.create_task(step)
|
||||
loop.run_until_complete(asyncio.wait([task], loop=loop))
|
||||
return task.result()
|
||||
|
||||
|
||||
def sync_wrapper(f):
|
||||
"""Convert the given async function into a sync function
|
||||
|
||||
:returns: The de-async'd function
|
||||
:rtype: function
|
||||
"""
|
||||
def _wrapper(*args, **kwargs):
|
||||
async def _run_it():
|
||||
return await f(*args, **kwargs)
|
||||
return run(_run_it())
|
||||
return _wrapper
|
||||
|
||||
47
zaza/controller.py
Normal file
47
zaza/controller.py
Normal file
@@ -0,0 +1,47 @@
|
||||
import logging
|
||||
from juju.controller import Controller
|
||||
from zaza import sync_wrapper
|
||||
|
||||
|
||||
async def async_add_model(model_name):
|
||||
controller = Controller()
|
||||
await controller.connect()
|
||||
logging.debug("Adding model {}".format(model_name))
|
||||
model = await controller.add_model(model_name)
|
||||
await model.connect()
|
||||
model_name = model.info.name
|
||||
await model.disconnect()
|
||||
await controller.disconnect()
|
||||
return model_name
|
||||
|
||||
add_model = sync_wrapper(async_add_model)
|
||||
|
||||
|
||||
async def async_destroy_model(model_name):
|
||||
controller = Controller()
|
||||
await controller.connect()
|
||||
logging.debug("Destroying model {}".format(model_name))
|
||||
await controller.destroy_model(model_name)
|
||||
await controller.disconnect()
|
||||
|
||||
destroy_model = sync_wrapper(async_destroy_model)
|
||||
|
||||
|
||||
async def async_get_cloud():
|
||||
controller = Controller()
|
||||
await controller.connect()
|
||||
cloud = await controller.get_cloud()
|
||||
await controller.disconnect()
|
||||
return cloud
|
||||
|
||||
get_cloud = sync_wrapper(async_get_cloud)
|
||||
|
||||
|
||||
async def async_list_models():
|
||||
controller = Controller()
|
||||
await controller.connect()
|
||||
models = await controller.list_models()
|
||||
await controller.disconnect()
|
||||
return models
|
||||
|
||||
list_models = sync_wrapper(async_list_models)
|
||||
@@ -10,6 +10,8 @@ from juju import loop
|
||||
from juju.errors import JujuError
|
||||
from juju.model import Model
|
||||
|
||||
from zaza import sync_wrapper
|
||||
|
||||
|
||||
async def deployed(filter=None):
|
||||
# Create a Model instance. We need to connect our Model to a Juju api
|
||||
@@ -46,35 +48,6 @@ def get_unit_from_name(unit_name, model):
|
||||
return unit
|
||||
|
||||
|
||||
def run(*steps):
|
||||
"""Run the given steps in an asyncio loop
|
||||
|
||||
:returns: The result of the asyncio.Task
|
||||
:rtype: Any
|
||||
"""
|
||||
if not steps:
|
||||
return
|
||||
loop = asyncio.get_event_loop()
|
||||
|
||||
for step in steps:
|
||||
task = loop.create_task(step)
|
||||
loop.run_until_complete(asyncio.wait([task], loop=loop))
|
||||
return task.result()
|
||||
|
||||
|
||||
def sync_wrapper(f):
|
||||
"""Convert the given async function into a sync function
|
||||
|
||||
:returns: The de-async'd function
|
||||
:rtype: function
|
||||
"""
|
||||
def _wrapper(*args, **kwargs):
|
||||
async def _run_it():
|
||||
return await f(*args, **kwargs)
|
||||
return run(_run_it())
|
||||
return _wrapper
|
||||
|
||||
|
||||
@asynccontextmanager
|
||||
@async_generator
|
||||
async def run_in_model(model_name):
|
||||
|
||||
Reference in New Issue
Block a user