diff --git a/doc/source/user/config.rst b/doc/source/user/config.rst index 5719c50f2..8d8116a68 100644 --- a/doc/source/user/config.rst +++ b/doc/source/user/config.rst @@ -238,6 +238,20 @@ in :ref:`tobiko-conf` file:: floating_network = public +Skipping resources creation +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In some cases, for example when Tobiko is run after upgrade of cloud, it may be expected +that resources used for tests should be already created. Tobiko should not try to create +resources than and just run tests using what is already created. +To configure Tobiko to not create test resources, environment variable ``TOBIKO_PREVENT_CREATE`` +can be used:: + + export TOBIKO_PREVENT_CREATE=True + +If this is set to ``True`` or ``1`` then Tobiko will not try to create resources like VMs, +networks or routers and just run validation of what is exists in the cloud already. + What's Next ----------- diff --git a/tobiko/config.py b/tobiko/config.py index 72a23b4b2..58269ccfb 100644 --- a/tobiko/config.py +++ b/tobiko/config.py @@ -251,4 +251,18 @@ def get_int_env(name): return None +def get_bool_env(name): + value = get_env(name) + if value: + value = str(value).lower() + if value in ["true", "1"]: + return True + elif value in ["false", '0']: + return False + else: + LOG.exception("Environment variable %r is not a boolean: %r", + name, value) + return None + + init_config() diff --git a/tobiko/openstack/heat/_stack.py b/tobiko/openstack/heat/_stack.py index 608cce9e6..b61de314f 100644 --- a/tobiko/openstack/heat/_stack.py +++ b/tobiko/openstack/heat/_stack.py @@ -20,6 +20,7 @@ from heatclient import exc from oslo_log import log import tobiko +from tobiko import config from tobiko.openstack.heat import _client from tobiko.openstack.heat import _template @@ -75,10 +76,19 @@ class HeatStackFixture(tobiko.SharedFixture): self.parameters = _stack_parameters( stack=self, obj=(parameters or self.parameters)) self.client = client or self.client + if config.get_bool_env('TOBIKO_PREVENT_CREATE'): + self.retry_create_stack = 0 if wait_interval: self.wait_interval = wait_interval + def _get_retry_value(self, retry): + if retry is None: + retry = self.retry_create_stack + if retry is None: + retry = 1 + return int(retry) + def setup_fixture(self): self.setup_template() self.setup_client() @@ -99,7 +109,7 @@ class HeatStackFixture(tobiko.SharedFixture): def create_stack(self, retry=None): """Creates stack based on passed parameters.""" created_stack_ids = set() - retry = retry or self.retry_create_stack or 1 + retry = self._get_retry_value(retry) while True: stack = self.wait_for_stack_status( expected_status={CREATE_COMPLETE, CREATE_FAILED, diff --git a/tobiko/tests/unit/openstack/heat/test_stack.py b/tobiko/tests/unit/openstack/heat/test_stack.py index 4b094956b..762aff7b2 100644 --- a/tobiko/tests/unit/openstack/heat/test_stack.py +++ b/tobiko/tests/unit/openstack/heat/test_stack.py @@ -238,6 +238,11 @@ class HeatStackFixtureTest(openstack.OpenstackTest): def test_setup_when_create_conflict(self): self.test_setup(create_conflict=True) + def test_setup_when_prevent_to_create_set(self): + with mock.patch.dict('os.environ', {'TOBIKO_PREVENT_CREATE': 'True'}): + self.test_setup(stacks=[mock_stack('CREATE_COMPLETE')], + call_create=False) + def test_cleanup(self): client = MockClient() stack = MyStack(client=client) diff --git a/tobiko/tests/unit/test_config.py b/tobiko/tests/unit/test_config.py index 87323e5c7..24ad40141 100644 --- a/tobiko/tests/unit/test_config.py +++ b/tobiko/tests/unit/test_config.py @@ -16,6 +16,8 @@ from __future__ import absolute_import import os +import mock + from tobiko.tests import unit from tobiko import config @@ -103,3 +105,22 @@ class HttpProxyFixtureTest(unit.TobikoUnitTest): self.assertEqual(self.MY_HTTP_PROXY, fixture.http_proxy) self.assertEqual({'no_proxy': self.MY_NO_PROXY, 'http_proxy': self.MY_HTTP_PROXY}, os.environ) + + def test_get_bool_env(self): + env_option = "TEST_OPTION" + + true_values = ['True', 'true', 'TRUE', 'TrUe', '1'] + false_values = ['False', 'false', 'FALSE', 'FaLsE', '0'] + invalid_values = [None, 'something else', ''] + + for value in true_values: + with mock.patch.dict('os.environ', {env_option: value}): + self.assertIs(True, config.get_bool_env(env_option)) + + for value in false_values: + with mock.patch.dict('os.environ', {env_option: value}): + self.assertIs(False, config.get_bool_env(env_option)) + + for value in invalid_values: + with mock.patch.dict('os.environ', {env_option: value}): + self.assertIsNone(config.get_bool_env(env_option))