# Allow the retargetable and tempest api tests to be executed as part
# of the same job by ensuring that tests from both tests are
# discovered.
-#
-# TODO(marun) Remove once the tempest tests have been moved to api/
def _discover(loader, path, pattern):
loader = unittest.loader.TestLoader()
suite.addTests(_discover(loader, "./neutron/tests/api", pattern))
+ # TODO(marun) Remove once the tempest tests have been moved to api/
suite.addTests(_discover(loader,
"./neutron/tests/tempest/api/network",
pattern))
+ suite.addTests(_discover(loader,
+ "./neutron/tests/retargetable",
+ pattern))
return suite
+++ /dev/null
-# Copyright 2014, Red Hat Inc.
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-This module defines functional tests for the Neutron V2 API in the
-BaseTestApi class. The intention is that the class will be overridden
-and configured for use with testscenarios as follows:
-
- - A subclass should override the 'scenarios' class member with a
- list of tuple pairs, e.g.
-
- scenarios = [('scenario_id', dict(client=Client())]
-
- The first element of each scenario tuple is a user-defined textual
- id, and the second element is a dictionary whose client parameter
- should be a subclass of BaseNeutronClient.
-
- - The module containing the test class should defines a 'load_tests'
- variable as follows:
-
- load_tests = testscenarios.load_tests_apply_scenarios
-
-Examples of use include:
-
- neutron.tests.functional.api.test_v2_plugin - targets the plugin api
- for each configured plugin
-
- neutron.tests.api.test_v2_rest_client - targets neutron server
- via the tempest rest client
-
- The tests in neutron.tests.api depend on Neutron and Tempest being
- deployed (e.g. with Devstack) and are intended to be run in advisory
- check jobs.
-
-Reference: https://pypi.python.org/pypi/testscenarios/
-"""
-
-import abc
-
-import six
-import testtools
-
-from neutron.tests import base
-
-
-@six.add_metaclass(abc.ABCMeta)
-class BaseNeutronClient(object):
- """
- Base class for a client that can interact the neutron api in some
- manner.
-
- Reference: :file:`neutron/neutron_plugin_base_v2.py`
- """
-
- def setUp(self, test_case):
- """Configure the api for use with a test case
-
- :param test_case: The test case that will exercise the api
- """
- self.test_case = test_case
-
- @abc.abstractproperty
- def NotFound(self):
- """The exception that indicates a resource could not be found.
-
- Tests can use this property to assert for a missing resource
- in a client-agnostic way.
- """
-
- @abc.abstractmethod
- def create_network(self, **kwargs):
- pass
-
- @abc.abstractmethod
- def update_network(self, id_, **kwargs):
- pass
-
- @abc.abstractmethod
- def get_network(self, id_, fields=None):
- pass
-
- @abc.abstractmethod
- def get_networks(self, filters=None, fields=None,
- sorts=None, limit=None, marker=None, page_reverse=False):
- pass
-
- @abc.abstractmethod
- def delete_network(self, id_):
- pass
-
-
-class BaseTestApi(base.BaseTestCase):
-
- scenarios = ()
-
- def setUp(self, setup_parent=True):
- # Calling the parent setUp is optional - the subclass may be
- # calling it already via a different ancestor.
- if setup_parent:
- super(BaseTestApi, self).setUp()
- self.client.setUp(self)
-
- def test_network_lifecycle(self):
- net = self.client.create_network(name=base.get_rand_name())
- listed_networks = dict((x.id, x.name)
- for x in self.client.get_networks())
- self.assertIn(net.id, listed_networks)
- self.assertEqual(listed_networks[net.id], net.name,
- 'Listed network name is not as expected.')
- updated_name = 'new %s' % net.name
- updated_net = self.client.update_network(net.id, name=updated_name)
- self.assertEqual(updated_name, updated_net.name,
- 'Updated network name is not as expected.')
- self.client.delete_network(net.id)
- with testtools.ExpectedException(self.client.NotFound,
- msg='Network was not deleted'):
- self.client.get_network(net.id)
+++ /dev/null
-# Copyright 2014, Red Hat Inc.
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-This module implements BaseNeutronClient for the Tempest rest client
-and configures the api tests with scenarios targeting the Neutron API.
-"""
-
-from tempest_lib import exceptions
-import testscenarios
-
-from neutron.tests.api import base_v2
-from neutron.tests import base
-from neutron.tests.tempest.api.network import base as t_base
-
-# Required to generate tests from scenarios. Not compatible with nose.
-load_tests = testscenarios.load_tests_apply_scenarios
-
-
-class TempestRestClient(base_v2.BaseNeutronClient):
-
- @property
- def client(self):
- if not hasattr(self, '_client'):
- manager = t_base.BaseNetworkTest.get_client_manager()
- self._client = manager.network_client
- return self._client
-
- @property
- def NotFound(self):
- return exceptions.NotFound
-
- def _cleanup_network(self, id_):
- try:
- self.delete_network(id_)
- except self.NotFound:
- pass
-
- def create_network(self, **kwargs):
- network = self._create_network(**kwargs)
- self.test_case.addCleanup(self._cleanup_network, network.id)
- return network
-
- def _create_network(self, **kwargs):
- # Internal method - use create_network() instead
- body = self.client.create_network(**kwargs)
- return base.AttributeDict(body['network'])
-
- def update_network(self, id_, **kwargs):
- body = self.client.update_network(id_, **kwargs)
- return base.AttributeDict(body['network'])
-
- def get_network(self, id_, **kwargs):
- body = self.client.show_network(id_, **kwargs)
- return base.AttributeDict(body['network'])
-
- def get_networks(self, **kwargs):
- body = self.client.list_networks(**kwargs)
- return [base.AttributeDict(x) for x in body['networks']]
-
- def delete_network(self, id_):
- self.client.delete_network(id_)
-
-
-class TestApiWithRestClient(base_v2.BaseTestApi):
- scenarios = [('tempest', {'client': TempestRestClient()})]
-
- def setUp(self):
- raise self.skipException(
- 'Tempest fixture requirements prevent this test from running')
# under the License.
"""
-Previously, running 'tox -e dsvm-functional' simply ran a normal test discovery
-of the ./neutron/tests/functional tree. In order to save gate resources, we
-decided to forgo adding a new gate job specifically for the full-stack
-framework, and instead discover tests that are present in
-./neutron/tests/fullstack.
-
-In short, running 'tox -e dsvm-functional' now runs both functional tests and
-full-stack tests, and this code allows for the test discovery needed.
+In order to save gate resources, test paths that have similar
+environmental requirements to the functional path are marked for
+discovery.
"""
-import os
import unittest
loader = unittest.loader.TestLoader()
suite.addTests(_discover(loader, "./neutron/tests/functional", pattern))
-
- if os.getenv('OS_RUN_FULLSTACK') == '1':
- suite.addTests(_discover(loader, "./neutron/tests/fullstack", pattern))
+ suite.addTests(_discover(loader, "./neutron/tests/fullstack", pattern))
+ suite.addTests(_discover(loader, "./neutron/tests/retargetable",
+ pattern))
return suite
+++ /dev/null
-# Copyright 2014, Red Hat Inc.
-# All Rights Reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License"); you may
-# not use this file except in compliance with the License. You may obtain
-# a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-# License for the specific language governing permissions and limitations
-# under the License.
-
-"""
-This module implements BaseNeutronClient for the programmatic plugin
-api and configures the api tests with scenarios targeting individual
-plugins.
-"""
-
-import testscenarios
-
-from neutron.common import exceptions as q_exc
-from neutron import context
-from neutron import manager
-from neutron.tests.api import base_v2
-from neutron.tests import base
-from neutron.tests.unit.ml2 import test_ml2_plugin
-from neutron.tests.unit import testlib_api
-
-
-# Each plugin must add a class to plugin_configurations that can configure the
-# plugin for use with PluginClient. For a given plugin, the setup
-# used for NeutronDbPluginV2TestCase can usually be reused. See the
-# configuration classes listed below for examples of this reuse.
-
-#TODO(marun) Discover plugin conf via a metaclass
-plugin_configurations = [
- test_ml2_plugin.Ml2PluginConf,
-]
-
-
-# Required to generate tests from scenarios. Not compatible with nose.
-load_tests = testscenarios.load_tests_apply_scenarios
-
-
-class PluginClient(base_v2.BaseNeutronClient):
-
- @property
- def ctx(self):
- if not hasattr(self, '_ctx'):
- self._ctx = context.Context('', 'test-tenant')
- return self._ctx
-
- @property
- def plugin(self):
- return manager.NeutronManager.get_plugin()
-
- @property
- def NotFound(self):
- return q_exc.NetworkNotFound
-
- def create_network(self, **kwargs):
- # Supply defaults that are expected to be set by the api
- # framwork
- kwargs.setdefault('admin_state_up', True)
- kwargs.setdefault('vlan_transparent', False)
- kwargs.setdefault('shared', False)
- data = dict(network=kwargs)
- result = self.plugin.create_network(self.ctx, data)
- return base.AttributeDict(result)
-
- def update_network(self, id_, **kwargs):
- data = dict(network=kwargs)
- result = self.plugin.update_network(self.ctx, id_, data)
- return base.AttributeDict(result)
-
- def get_network(self, *args, **kwargs):
- result = self.plugin.get_network(self.ctx, *args, **kwargs)
- return base.AttributeDict(result)
-
- def get_networks(self, *args, **kwargs):
- result = self.plugin.get_networks(self.ctx, *args, **kwargs)
- return [base.AttributeDict(x) for x in result]
-
- def delete_network(self, id_):
- self.plugin.delete_network(self.ctx, id_)
-
-
-def get_scenarios():
- scenarios = []
- client = PluginClient()
- for conf in plugin_configurations:
- name = conf.plugin_name
- class_name = name[name.rfind('.') + 1:]
- scenarios.append((class_name, {'client': client, 'plugin_conf': conf}))
- return scenarios
-
-
-class TestPluginApi(base_v2.BaseTestApi,
- testlib_api.SqlTestCase):
-
- scenarios = get_scenarios()
-
- def setUp(self):
- # BaseTestApi is not based on BaseTestCase to avoid import
- # errors when importing Tempest. When targeting the plugin
- # api, it is necessary to avoid calling BaseTestApi's parent
- # setUp, since that setup will be called by SqlTestCase.setUp.
- super(TestPluginApi, self).setUp(setup_parent=False)
- testlib_api.SqlTestCase.setUp(self)
- self.useFixture(base.PluginFixture(self.plugin_conf.plugin_name))
- self.plugin_conf.setUp(self)
--- /dev/null
+# Licensed under the Apache License, Version 2.0 (the "License"); you
+# may not use this file except in compliance with the License. You may
+# obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+
+"""
+This module defines a base test case that uses testscenarios to
+parametize the test methods of subclasses by varying the client
+fixture used to target the Neutron API.
+
+PluginClientFixture targets the Neutron API directly via the plugin
+api, and will be executed by default. testscenarios will ensure that
+each test is run against all plugins defined in plugin_configurations.
+
+RestClientFixture targets a deployed Neutron daemon, and will be used
+instead of PluginClientFixture only if OS_TEST_API_WITH_REST is set to 1.
+
+Reference: https://pypi.python.org/pypi/testscenarios/
+"""
+
+import testscenarios
+
+from neutron.tests import base as tests_base
+from neutron.tests.retargetable import client_fixtures
+from neutron.tests.unit.ml2 import test_ml2_plugin
+
+
+# Each plugin must add a class to plugin_configurations that can configure the
+# plugin for use with PluginClient. For a given plugin, the setup
+# used for NeutronDbPluginV2TestCase can usually be reused. See the
+# configuration classes listed below for examples of this reuse.
+
+# TODO(marun) Discover plugin conf via a metaclass
+plugin_configurations = [
+ test_ml2_plugin.Ml2ConfFixture(),
+]
+
+
+def rest_enabled():
+ return tests_base.bool_from_env('OS_TEST_API_WITH_REST')
+
+
+def get_plugin_scenarios():
+ scenarios = []
+ for conf in plugin_configurations:
+ name = conf.plugin_name
+ class_name = name.rsplit('.', 1)[-1]
+ client = client_fixtures.PluginClientFixture(conf)
+ scenarios.append((class_name, {'client': client}))
+ return scenarios
+
+
+def get_scenarios():
+ if rest_enabled():
+ # FIXME(marun) Remove local import once tempest config is safe
+ # to import alonside neutron config
+ from neutron.tests.retargetable import rest_fixture
+ return [('tempest', {'client': rest_fixture.RestClientFixture()})]
+ else:
+ return get_plugin_scenarios()
+
+
+class RetargetableApiTest(testscenarios.WithScenarios,
+ tests_base.BaseTestCase):
+
+ scenarios = get_scenarios()
+
+ def setUp(self):
+ super(RetargetableApiTest, self).setUp()
+ if rest_enabled():
+ raise self.skipException(
+ 'Tempest fixture requirements prevent this test from running')
+ self.useFixture(self.client)
--- /dev/null
+# Licensed under the Apache License, Version 2.0 (the "License"); you
+# may not use this file except in compliance with the License. You may
+# obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+
+"""
+This module defines client fixtures that can be used to target the
+Neutron API via different methods.
+"""
+
+import abc
+
+import fixtures
+import six
+
+from neutron.common import exceptions as q_exc
+from neutron import context
+from neutron import manager
+from neutron.tests import base
+from neutron.tests.unit import testlib_api
+
+
+@six.add_metaclass(abc.ABCMeta)
+class AbstractClientFixture(fixtures.Fixture):
+ """
+ Base class for a client that can interact the neutron api in some
+ manner.
+ """
+
+ @abc.abstractproperty
+ def NotFound(self):
+ """The exception that indicates a resource could not be found.
+
+ Tests can use this property to assert for a missing resource
+ in a client-agnostic way.
+ """
+
+ @abc.abstractmethod
+ def create_network(self, **kwargs):
+ pass
+
+ @abc.abstractmethod
+ def update_network(self, id_, **kwargs):
+ pass
+
+ @abc.abstractmethod
+ def get_network(self, id_, fields=None):
+ pass
+
+ @abc.abstractmethod
+ def get_networks(self, filters=None, fields=None,
+ sorts=None, limit=None, marker=None, page_reverse=False):
+ pass
+
+ @abc.abstractmethod
+ def delete_network(self, id_):
+ pass
+
+
+class PluginClientFixture(AbstractClientFixture):
+ """Targets the Neutron API via the plugin API"""
+
+ def __init__(self, plugin_conf):
+ self.plugin_conf = plugin_conf
+
+ def setUp(self):
+ super(PluginClientFixture, self).setUp()
+ self.useFixture(testlib_api.SqlFixture())
+ self.useFixture(self.plugin_conf)
+ self.useFixture(base.PluginFixture(self.plugin_conf.plugin_name))
+
+ @property
+ def ctx(self):
+ if not hasattr(self, '_ctx'):
+ self._ctx = context.Context('', 'test-tenant')
+ return self._ctx
+
+ @property
+ def plugin(self):
+ return manager.NeutronManager.get_plugin()
+
+ @property
+ def NotFound(self):
+ return q_exc.NetworkNotFound
+
+ def create_network(self, **kwargs):
+ # Supply defaults that are expected to be set by the api
+ # framwork
+ kwargs.setdefault('admin_state_up', True)
+ kwargs.setdefault('vlan_transparent', False)
+ kwargs.setdefault('shared', False)
+ data = dict(network=kwargs)
+ result = self.plugin.create_network(self.ctx, data)
+ return base.AttributeDict(result)
+
+ def update_network(self, id_, **kwargs):
+ data = dict(network=kwargs)
+ result = self.plugin.update_network(self.ctx, id_, data)
+ return base.AttributeDict(result)
+
+ def get_network(self, *args, **kwargs):
+ result = self.plugin.get_network(self.ctx, *args, **kwargs)
+ return base.AttributeDict(result)
+
+ def get_networks(self, *args, **kwargs):
+ result = self.plugin.get_networks(self.ctx, *args, **kwargs)
+ return [base.AttributeDict(x) for x in result]
+
+ def delete_network(self, id_):
+ self.plugin.delete_network(self.ctx, id_)
--- /dev/null
+# Licensed under the Apache License, Version 2.0 (the "License"); you
+# may not use this file except in compliance with the License. You may
+# obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+
+"""
+This module defines a client fixture that can be used to target a
+deployed neutron daemon. The potential for conflict between Tempest
+configuration and Neutron configuration requires that
+neutron.tests.tempest imports be isolated in this module for now.
+"""
+
+from tempest_lib import exceptions as tlib_exceptions
+
+from neutron.tests import base
+from neutron.tests.retargetable import client_fixtures
+from neutron.tests.tempest import test as t_test
+
+
+class RestClientFixture(client_fixtures.AbstractClientFixture):
+ """Targets the Neutron API via REST."""
+
+ @property
+ def client(self):
+ if not hasattr(self, '_client'):
+ manager = t_test.BaseTestCase.get_client_manager()
+ self._client = manager.network_client
+ return self._client
+
+ @property
+ def NotFound(self):
+ return tlib_exceptions.NotFound
+
+ def _cleanup_network(self, id_):
+ try:
+ self.delete_network(id_)
+ except self.NotFound:
+ pass
+
+ def create_network(self, **kwargs):
+ network = self._create_network(**kwargs)
+ self.addCleanup(self._cleanup_network, network.id)
+ return network
+
+ def _create_network(self, **kwargs):
+ # Internal method - use create_network() instead
+ body = self.client.create_network(**kwargs)
+ return base.AttributeDict(body['network'])
+
+ def update_network(self, id_, **kwargs):
+ body = self.client.update_network(id_, **kwargs)
+ return base.AttributeDict(body['network'])
+
+ def get_network(self, id_, **kwargs):
+ body = self.client.show_network(id_, **kwargs)
+ return base.AttributeDict(body['network'])
+
+ def get_networks(self, **kwargs):
+ body = self.client.list_networks(**kwargs)
+ return [base.AttributeDict(x) for x in body['networks']]
+
+ def delete_network(self, id_):
+ self.client.delete_network(id_)
--- /dev/null
+# Licensed under the Apache License, Version 2.0 (the "License"); you
+# may not use this file except in compliance with the License. You may
+# obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+
+import testtools
+
+from neutron.tests import base as tests_base
+from neutron.tests.retargetable import base
+
+
+class TestExample(base.RetargetableApiTest):
+ """This class is an example of how to write a retargetable api test.
+
+ See the parent class for details about how the 'client' attribute
+ is configured via testscenarios.
+ """
+
+ def test_network_lifecycle(self):
+ net = self.client.create_network(name=tests_base.get_rand_name())
+ listed_networks = {x.id: x.name for x in self.client.get_networks()}
+ self.assertIn(net.id, listed_networks)
+ self.assertEqual(listed_networks[net.id], net.name,
+ 'Listed network name is not as expected.')
+ updated_name = 'new %s' % net.name
+ updated_net = self.client.update_network(net.id, name=updated_name)
+ self.assertEqual(updated_name, updated_net.name,
+ 'Updated network name is not as expected.')
+ self.client.delete_network(net.id)
+ with testtools.ExpectedException(self.client.NotFound,
+ msg='Network was not deleted'):
+ self.client.get_network(net.id)
The files under this path are maintained automatically by the script
tools/copy_api_tests_from_tempest.sh. It's contents should not be
manually modified until further notice.
+
+Note that neutron.tests.tempest.config uses the global cfg.CONF
+instance for now and importing it outside of the api tests has the
+potential to break Neutron's use of cfg.CONF.
import uuid
import webob
+import fixtures
from oslo_db import exception as db_exc
from neutron.callbacks import registry
HOST = 'fake_host'
-class Ml2PluginConf(object):
- """Plugin configuration shared across the unit and functional tests.
+# TODO(marun) - Move to somewhere common for reuse
+class PluginConfFixture(fixtures.Fixture):
+ """Plugin configuration shared across the unit and functional tests."""
- TODO(marun) Evolve a configuration interface usable across all plugins.
- """
+ def __init__(self, plugin_name, parent_setup=None):
+ self.plugin_name = plugin_name
+ self.parent_setup = parent_setup
+
+ def setUp(self):
+ super(PluginConfFixture, self).setUp()
+ if self.parent_setup:
+ self.parent_setup()
- plugin_name = PLUGIN_NAME
- @staticmethod
- def setUp(test_case, parent_setup=None):
- """Perform additional configuration around the parent's setUp."""
- if parent_setup:
- parent_setup()
- test_case.port_create_status = 'DOWN'
+class Ml2ConfFixture(PluginConfFixture):
+
+ def __init__(self, parent_setup=None):
+ super(Ml2ConfFixture, self).__init__(PLUGIN_NAME, parent_setup)
class Ml2PluginV2TestCase(test_plugin.NeutronDbPluginV2TestCase):
# by the common configuration setUp.
parent_setup = functools.partial(
super(Ml2PluginV2TestCase, self).setUp,
- plugin=Ml2PluginConf.plugin_name,
+ plugin=PLUGIN_NAME,
service_plugins=service_plugins,
)
- Ml2PluginConf.setUp(self, parent_setup)
+ self.useFixture(Ml2ConfFixture(parent_setup))
+ self.port_create_status = 'DOWN'
def setUp(self):
# Enable the test mechanism driver to ensure that
# License for the specific language governing permissions and limitations
# under the License.
+import fixtures
import testtools
from neutron.db import api as db_api
return req
-class SqlTestCase(base.BaseTestCase):
+class SqlFixture(fixtures.Fixture):
# flag to indicate that the models have been loaded
_TABLES_ESTABLISHED = False
def setUp(self):
- super(SqlTestCase, self).setUp()
+ super(SqlFixture, self).setUp()
# Register all data models
engine = db_api.get_engine()
- if not SqlTestCase._TABLES_ESTABLISHED:
+ if not SqlFixture._TABLES_ESTABLISHED:
model_base.BASEV2.metadata.create_all(engine)
- SqlTestCase._TABLES_ESTABLISHED = True
+ SqlFixture._TABLES_ESTABLISHED = True
def clear_tables():
with engine.begin() as conn:
self.addCleanup(clear_tables)
+class SqlTestCase(base.BaseTestCase):
+
+ def setUp(self):
+ super(SqlTestCase, self).setUp()
+ self.useFixture(SqlFixture())
+
+
class WebTestCase(SqlTestCase):
fmt = 'json'
[testenv:api]
setenv = OS_TEST_PATH=./neutron/tests/api
TEMPEST_CONFIG_DIR={env:TEMPEST_CONFIG_DIR:/opt/stack/tempest/etc}
+ OS_TEST_API_WITH_REST=1
[testenv:functional]
setenv = OS_TEST_PATH=./neutron/tests/functional
OS_ROOTWRAP_DAEMON_CMD=sudo {envbindir}/neutron-rootwrap-daemon {envdir}/etc/neutron/rootwrap.conf
OS_FAIL_ON_MISSING_DEPS=1
OS_TEST_TIMEOUT=90
- OS_RUN_FULLSTACK=1
sitepackages=True
deps =
{[testenv:functional]deps}