From 063a59b08ed9e8b313bdb0c6f0cee878f8a1704c Mon Sep 17 00:00:00 2001 From: Suraj Deshmukh Date: Wed, 17 Feb 2016 04:52:56 -0500 Subject: [PATCH] Wrong provider name in answers.conf, exits AtomicApp with readable error When provider name in answers.conf is wrong then AtomicApp fails with stack-trace and no error output which is user understandable. This happened because there was no check for the condition if given provider_key does not match with any of the providers that are supported for now. Fixes Issue #562. --- atomicapp/nulecule/lib.py | 9 ++++++- tests/units/nulecule/test_lib.py | 40 ++++++++++++++++++++++++++++++++ tests/units/test_plugin.py | 27 +++++++++++++++++++++ 3 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 tests/units/nulecule/test_lib.py create mode 100644 tests/units/test_plugin.py diff --git a/atomicapp/nulecule/lib.py b/atomicapp/nulecule/lib.py index c1e052da..b38e47e4 100644 --- a/atomicapp/nulecule/lib.py +++ b/atomicapp/nulecule/lib.py @@ -5,9 +5,11 @@ LOGGER_COCKPIT, NAME_KEY, DEFAULTNAME_KEY, - PROVIDER_KEY) + PROVIDER_KEY, + PROVIDERS) from atomicapp.utils import Utils from atomicapp.plugin import Plugin +from atomicapp.nulecule.exceptions import NuleculeException cockpit_logger = logging.getLogger(LOGGER_COCKPIT) @@ -101,6 +103,11 @@ def get_provider(self, provider_key=None, dry=False): if provider_key is None: provider_key = self.config.get(GLOBAL_CONF)[PROVIDER_KEY] provider_class = self.plugin.getProvider(provider_key) + if provider_class is None: + raise NuleculeException("Invalid Provider - '{}', provided in " + "answers.conf (choose from {})" + .format(provider_key, ', ' + .join(PROVIDERS))) return provider_key, provider_class( self.get_context(), self.basepath, dry) diff --git a/tests/units/nulecule/test_lib.py b/tests/units/nulecule/test_lib.py new file mode 100644 index 00000000..742738d8 --- /dev/null +++ b/tests/units/nulecule/test_lib.py @@ -0,0 +1,40 @@ +import mock +import unittest + +from atomicapp.nulecule.lib import NuleculeBase +from atomicapp.nulecule.exceptions import NuleculeException + + +class TestNuleculeBaseGetProvider(unittest.TestCase): + """ Test NuleculeBase get_provider""" + def test_get_provider_success(self): + """ + Test if get_provider method when passed a particular valid key returns + the corresponding class. + """ + nb = NuleculeBase(params = [], basepath = '', namespace = '') + provider_key = u'openshift' + # method `get_provider` will read from this config, we give it here + # since we have neither provided it before nor it is auto-generated + nb.config = {u'general': {u'provider': provider_key}} + + return_provider = mock.Mock() + # mocking return value of method plugin.getProvider,because it returns + # provider class and that class gets called with values + nb.plugin.getProvider = mock.Mock(return_value=return_provider) + ret_provider_key, ret_provider = nb.get_provider() + self.assertEqual(provider_key, ret_provider_key) + return_provider.assert_called_with({u'provider': provider_key}, + '', False) + + def test_get_provider_failure(self): + """ + Test if get_provider method when passed an invalid key raises an + exception. + """ + nb = NuleculeBase(params = [], basepath = '', namespace = '') + # purposefully give the wrong provider key + provider_key = u'mesos' + nb.config = {u'general': {u'provider': provider_key}} + with self.assertRaises(NuleculeException): + nb.get_provider() diff --git a/tests/units/test_plugin.py b/tests/units/test_plugin.py new file mode 100644 index 00000000..9a2699c9 --- /dev/null +++ b/tests/units/test_plugin.py @@ -0,0 +1,27 @@ +import mock +import unittest + +from atomicapp.plugin import Plugin + +class TestPluginGetProvider(unittest.TestCase): + + """Test Plugin getProvider""" + def test_getProvider(self): + """ + Test if getProvider is returning appropriate classes to the + corresponding keys. + """ + p = Plugin() + + docker_mock = mock.Mock() + kubernetes_mock = mock.Mock() + # keep some mock objects in place of the actual corresponding + # classes, getProvider reads from `plugins` dict. + p.plugins = { + 'docker': docker_mock, + 'kubernetes': kubernetes_mock, + } + self.assertEqual(p.getProvider('docker'), docker_mock) + self.assertEqual(p.getProvider('kubernetes'), kubernetes_mock) + # if non-existent key provided + self.assertEqual(p.getProvider('some_random'), None)