Merge "tests: removed 'retargetable' framework"

This commit is contained in:
Jenkins 2017-05-27 04:47:51 +00:00 committed by Gerrit Code Review
commit 78459837db
7 changed files with 8 additions and 324 deletions

View File

@ -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

View File

@ -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)

View File

@ -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_)

View File

@ -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_)

View File

@ -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)

View File

@ -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.