diff --git a/unit_tests/test_zaza_charm_lifecycle_destroy.py b/unit_tests/test_zaza_charm_lifecycle_destroy.py index 55e9e83..8934a5f 100644 --- a/unit_tests/test_zaza_charm_lifecycle_destroy.py +++ b/unit_tests/test_zaza_charm_lifecycle_destroy.py @@ -4,14 +4,8 @@ import unit_tests.utils as ut_utils class TestCharmLifecycleDestroy(ut_utils.BaseTestCase): - def test_destroy_model(self): - self.patch_object(lc_destroy.subprocess, 'check_call') - lc_destroy.destroy_model('doomed') - self.check_call.assert_called_once_with( - ['juju', 'destroy-model', '--yes', 'doomed']) - def test_destroy(self): - self.patch_object(lc_destroy, 'destroy_model') + self.patch_object(lc_destroy.zaza.model, 'destroy_model') lc_destroy.destroy('doomed') self.destroy_model.assert_called_once_with('doomed') diff --git a/unit_tests/test_zaza_charm_lifecycle_prepare.py b/unit_tests/test_zaza_charm_lifecycle_prepare.py index 510588b..4c8b3c2 100644 --- a/unit_tests/test_zaza_charm_lifecycle_prepare.py +++ b/unit_tests/test_zaza_charm_lifecycle_prepare.py @@ -4,26 +4,20 @@ import unit_tests.utils as ut_utils class TestCharmLifecyclePrepare(ut_utils.BaseTestCase): - def test_add_model(self): - self.patch_object(lc_prepare.subprocess, 'check_call') - lc_prepare.add_model('newmodel') - self.check_call.assert_called_once_with( - [ - 'juju', 'add-model', 'newmodel', - '--config', 'agent-stream=proposed', - '--config', 'default-series=xenial', - '--config', 'image-stream=daily', - '--config', 'test-mode=true', - '--config', 'transmit-vendor-metrics=false', - '--config', 'enable-os-upgrade=false', - '--config', 'automatically-retry-hooks=false', - '--config', 'use-default-secgroup=true' - ]) - def test_prepare(self): - self.patch_object(lc_prepare, 'add_model') - lc_prepare.add_model('newmodel') - self.add_model.assert_called_once_with('newmodel') + self.patch_object(lc_prepare.zaza.model, 'add_model') + lc_prepare.prepare('newmodel') + self.add_model.assert_called_once_with( + 'newmodel', + config={ + 'agent-stream': 'proposed', + 'default-series': 'xenial', + 'image-stream': 'daily', + 'test-mode': 'true', + 'transmit-vendor-metrics': 'false', + 'enable-os-upgrade': 'false', + 'automatically-retry-hooks': 'false', + 'use-default-secgroup': 'true'}) def test_parser(self): args = lc_prepare.parse_args(['-m', 'newmodel']) diff --git a/unit_tests/test_zaza_model.py b/unit_tests/test_zaza_model.py index 17d2635..3379797 100644 --- a/unit_tests/test_zaza_model.py +++ b/unit_tests/test_zaza_model.py @@ -99,6 +99,15 @@ class TestModel(ut_utils.BaseTestCase): async def _connect(): return + async def _ctrl_connect(): + return + + async def _ctrl_add_model(model_name, config=None): + return + + async def _ctrl_destroy_models(model_name): + return + self.Model_mock.connect.side_effect = _connect self.Model_mock.connect_model.side_effect = _connect_model self.Model_mock.disconnect.side_effect = _disconnect @@ -109,6 +118,36 @@ class TestModel(ut_utils.BaseTestCase): self.model_name = "testmodel" self.Model_mock.info.name = self.model_name + self.Controller_mock = mock.MagicMock() + self.Controller_mock.connect.side_effect = _ctrl_connect + self.Controller_mock.add_model.side_effect = _ctrl_add_model + self.Controller_mock.destroy_models.side_effect = _ctrl_destroy_models + + def test_add_model(self): + self.patch_object(model, 'Controller') + self.Controller.return_value = self.Controller_mock + model.add_model('newmodel') + self.Controller_mock.connect.assert_called_once_with() + self.Controller_mock.add_model.assert_called_once_with( + 'newmodel', + config=None) + + def test_add_model_config(self): + self.patch_object(model, 'Controller') + self.Controller.return_value = self.Controller_mock + model.add_model('newmodel', config={'run-faster': 'true'}) + self.Controller_mock.connect.assert_called_once_with() + self.Controller_mock.add_model.assert_called_once_with( + 'newmodel', + config={'run-faster': 'true'}) + + def test_destroy_model(self): + self.patch_object(model, 'Controller') + self.Controller.return_value = self.Controller_mock + model.destroy_model('newmodel') + self.Controller_mock.connect.assert_called_once_with() + self.Controller_mock.destroy_models.assert_called_once_with('newmodel') + def test_run_in_model(self): self.patch_object(model, 'Model') self.Model.return_value = self.Model_mock diff --git a/zaza/charm_lifecycle/destroy.py b/zaza/charm_lifecycle/destroy.py index 07c2704..be0db80 100644 --- a/zaza/charm_lifecycle/destroy.py +++ b/zaza/charm_lifecycle/destroy.py @@ -1,17 +1,8 @@ import argparse import logging -import subprocess import sys - -def destroy_model(model_name): - """Remove a model with the given name - - :param model: Name of model to remove - :type bundle: str - """ - logging.info("Remove model {}".format(model_name)) - subprocess.check_call(['juju', 'destroy-model', '--yes', model_name]) +import zaza.model def destroy(model_name): @@ -20,7 +11,7 @@ def destroy(model_name): :param model: Name of model to remove :type bundle: str """ - destroy_model(model_name) + zaza.model.destroy_model(model_name) def parse_args(args): diff --git a/zaza/charm_lifecycle/prepare.py b/zaza/charm_lifecycle/prepare.py index 00e6002..19a1515 100644 --- a/zaza/charm_lifecycle/prepare.py +++ b/zaza/charm_lifecycle/prepare.py @@ -1,33 +1,23 @@ import argparse import logging -import subprocess import sys +import zaza.model -MODEL_DEFAULTS = [ +MODEL_DEFAULTS = { # Model defaults from charm-test-infra # https://jujucharms.com/docs/2.1/models-config - '--config', 'agent-stream=proposed', - '--config', 'default-series=xenial', - '--config', 'image-stream=daily', - '--config', 'test-mode=true', - '--config', 'transmit-vendor-metrics=false', + 'agent-stream': 'proposed', + 'default-series': 'xenial', + 'image-stream': 'daily', + 'test-mode': 'true', + 'transmit-vendor-metrics': 'false', # https://bugs.launchpad.net/juju/+bug/1685351 # enable-os-refresh-update: false - '--config', 'enable-os-upgrade=false', - '--config', 'automatically-retry-hooks=false', - '--config', 'use-default-secgroup=true', -] - - -def add_model(model_name): - """Add a model with the given name - - :param model: Name of model to add - :type bundle: str - """ - logging.info("Adding model {}".format(model_name)) - subprocess.check_call(['juju', 'add-model', model_name] + MODEL_DEFAULTS) + 'enable-os-upgrade': 'false', + 'automatically-retry-hooks': 'false', + 'use-default-secgroup': 'true', +} def prepare(model_name): @@ -36,7 +26,7 @@ def prepare(model_name): :param model: Name of model to add :type bundle: str """ - add_model(model_name) + zaza.model.add_model(model_name, config=MODEL_DEFAULTS) def parse_args(args): diff --git a/zaza/model.py b/zaza/model.py index 1ca7e86..3527b1e 100644 --- a/zaza/model.py +++ b/zaza/model.py @@ -8,12 +8,39 @@ import yaml from oslo_config import cfg from juju import loop +from juju.controller import Controller from juju.errors import JujuError from juju.model import Model from zaza import sync_wrapper +async def async_add_model(model_name, config=None): + """Add a model to the current controller + + :param model_name: Name to give the new model. + :type model_name: str + :param config: Model configuration. + :type config: dict""" + controller = Controller() + await controller.connect() + await controller.add_model(model_name, config=config) + +add_model = sync_wrapper(async_add_model) + + +async def async_destroy_model(model_name): + """Remove a model from the current controller + + :param model_name: Name of model to remove + :type model_name: str""" + controller = Controller() + await controller.connect() + await controller.destroy_models(model_name) + +destroy_model = sync_wrapper(async_destroy_model) + + async def deployed(filter=None): # Create a Model instance. We need to connect our Model to a Juju api # server before we can use it.