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:
David Ames
2018-05-09 14:29:54 -07:00
parent 4cf4b7b5c4
commit ea120ee0a5
4 changed files with 159 additions and 29 deletions

View 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()

View File

@@ -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
View 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)

View File

@@ -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):