Merge "tests: removed 'retargetable' framework"
This commit is contained in:
commit
78459837db
|
@ -28,12 +28,6 @@ eventlet_utils.monkey_patch()
|
|||
|
||||
def load_tests(loader, tests, pattern):
|
||||
this_dir = os.path.dirname(__file__)
|
||||
parent_dir = os.path.dirname(this_dir)
|
||||
target_dirs = [
|
||||
this_dir,
|
||||
os.path.join(parent_dir, 'retargetable'),
|
||||
]
|
||||
for start_dir in target_dirs:
|
||||
new_tests = loader.discover(start_dir=start_dir, pattern=pattern)
|
||||
tests.addTests(new_tests)
|
||||
new_tests = loader.discover(start_dir=this_dir, pattern=pattern)
|
||||
tests.addTests(new_tests)
|
||||
return tests
|
||||
|
|
|
@ -1,80 +0,0 @@
|
|||
# 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.plugins.ml2 import test_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_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 alongside 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)
|
|
@ -1,120 +0,0 @@
|
|||
# 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
|
||||
from neutron_lib import context
|
||||
from neutron_lib import exceptions as n_exc
|
||||
from neutron_lib.plugins import directory
|
||||
import six
|
||||
|
||||
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):
|
||||
super(PluginClientFixture, self).__init__()
|
||||
self.plugin_conf = plugin_conf
|
||||
|
||||
def _setUp(self):
|
||||
super(PluginClientFixture, self)._setUp()
|
||||
self.useFixture(testlib_api.StaticSqlFixture())
|
||||
self.useFixture(self.plugin_conf)
|
||||
self.useFixture(base.PluginFixture(self.plugin_conf.plugin_name))
|
||||
manager.init()
|
||||
|
||||
@property
|
||||
def ctx(self):
|
||||
if not hasattr(self, '_ctx'):
|
||||
self._ctx = context.Context('', 'test-tenant')
|
||||
return self._ctx
|
||||
|
||||
@property
|
||||
def plugin(self):
|
||||
return directory.get_plugin()
|
||||
|
||||
@property
|
||||
def NotFound(self):
|
||||
return n_exc.NetworkNotFound
|
||||
|
||||
def create_network(self, **kwargs):
|
||||
# Supply defaults that are expected to be set by the api
|
||||
# framework
|
||||
kwargs.setdefault('admin_state_up', True)
|
||||
kwargs.setdefault('shared', False)
|
||||
kwargs.setdefault('tenant_id', self.ctx.tenant_id)
|
||||
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_)
|
|
@ -1,70 +0,0 @@
|
|||
# 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 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_)
|
|
@ -1,39 +0,0 @@
|
|||
# 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.common import utils
|
||||
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=utils.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)
|
|
@ -1,10 +1,9 @@
|
|||
WARNING
|
||||
=======
|
||||
|
||||
The files under this path were copied from tempest as part of the move
|
||||
of the api tests, and they will be removed as required over time to
|
||||
minimize the dependency on the tempest testing framework.
|
||||
While it exists, only neutron.tests.tempest.api and neutron.tests.retargetable
|
||||
should be importing files from this path. neutron.tests.tempest.config uses
|
||||
the global cfg.CONF instance and importing it outside of the api tests
|
||||
has the potential to break Neutron's use of cfg.CONF.
|
||||
Some files under this path were copied from tempest as part of the move of the
|
||||
api tests, and they will be removed as required over time to minimize the
|
||||
dependency on the tempest testing framework. While it exists, only
|
||||
neutron.tests.tempest.* should be importing files from this path.
|
||||
neutron.tests.tempest.config uses the global cfg.CONF instance and importing it
|
||||
outside of the api tests has the potential to break Neutron's use of cfg.CONF.
|
||||
|
|
Loading…
Reference in New Issue