Merge "Define SafeFixture base fixture"

This commit is contained in:
Jenkins 2015-06-27 03:43:16 +00:00 committed by Gerrit Code Review
commit 90b4852d33
11 changed files with 163 additions and 32 deletions

View File

@ -244,7 +244,7 @@ class DietTestCase(testtools.TestCase):
{'key': k, 'exp': v, 'act': actual_superset[k]}) {'key': k, 'exp': v, 'act': actual_superset[k]})
class ProcessMonitorFixture(fixtures.Fixture): class ProcessMonitorFixture(tools.SafeFixture):
"""Test fixture to capture and cleanup any spawn process monitor.""" """Test fixture to capture and cleanup any spawn process monitor."""
def setUp(self): def setUp(self):
super(ProcessMonitorFixture, self).setUp() super(ProcessMonitorFixture, self).setUp()
@ -410,9 +410,10 @@ class BaseTestCase(DietTestCase):
cfg.CONF.set_override("notification_driver", notification_driver) cfg.CONF.set_override("notification_driver", notification_driver)
class PluginFixture(fixtures.Fixture): class PluginFixture(tools.SafeFixture):
def __init__(self, core_plugin=None): def __init__(self, core_plugin=None):
super(PluginFixture, self).__init__()
self.core_plugin = core_plugin self.core_plugin = core_plugin
def setUp(self): def setUp(self):

View File

@ -12,13 +12,13 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
# #
import fixtures
from neutron.agent.linux import ip_lib from neutron.agent.linux import ip_lib
from neutron.tests.common import net_helpers from neutron.tests.common import net_helpers
from neutron.tests import tools
class FakeMachine(fixtures.Fixture): class FakeMachine(tools.SafeFixture):
"""Create a fake machine. """Create a fake machine.
:ivar bridge: bridge on which the fake machine is bound :ivar bridge: bridge on which the fake machine is bound
@ -66,7 +66,7 @@ class FakeMachine(fixtures.Fixture):
net_helpers.assert_no_ping(self.namespace, dst_ip) net_helpers.assert_no_ping(self.namespace, dst_ip)
class PeerMachines(fixtures.Fixture): class PeerMachines(tools.SafeFixture):
"""Create 'amount' peered machines on an ip_cidr. """Create 'amount' peered machines on an ip_cidr.
:ivar bridge: bridge on which peer machines are bound :ivar bridge: bridge on which peer machines are bound

View File

@ -15,7 +15,6 @@
import abc import abc
import fixtures
import netaddr import netaddr
from oslo_utils import uuidutils from oslo_utils import uuidutils
import six import six
@ -106,7 +105,7 @@ def assert_no_arping(src_namespace, dst_ip, source=None, timeout=1, count=1):
{'ns': src_namespace, 'destination': dst_ip}) {'ns': src_namespace, 'destination': dst_ip})
class NamespaceFixture(fixtures.Fixture): class NamespaceFixture(tools.SafeFixture):
"""Create a namespace. """Create a namespace.
:ivar ip_wrapper: created namespace :ivar ip_wrapper: created namespace
@ -131,7 +130,7 @@ class NamespaceFixture(fixtures.Fixture):
self.ip_wrapper.netns.delete(self.name) self.ip_wrapper.netns.delete(self.name)
class VethFixture(fixtures.Fixture): class VethFixture(tools.SafeFixture):
"""Create a veth. """Create a veth.
:ivar ports: created veth ports :ivar ports: created veth ports
@ -170,7 +169,7 @@ class VethFixture(fixtures.Fixture):
@six.add_metaclass(abc.ABCMeta) @six.add_metaclass(abc.ABCMeta)
class PortFixture(fixtures.Fixture): class PortFixture(tools.SafeFixture):
"""Create a port. """Create a port.
:ivar port: created port :ivar port: created port
@ -179,6 +178,7 @@ class PortFixture(fixtures.Fixture):
""" """
def __init__(self, bridge=None, namespace=None): def __init__(self, bridge=None, namespace=None):
super(PortFixture, self).__init__()
self.bridge = bridge self.bridge = bridge
self.namespace = namespace self.namespace = namespace
@ -204,7 +204,7 @@ class PortFixture(fixtures.Fixture):
tools.fail('Unexpected bridge type: %s' % type(bridge)) tools.fail('Unexpected bridge type: %s' % type(bridge))
class OVSBridgeFixture(fixtures.Fixture): class OVSBridgeFixture(tools.SafeFixture):
"""Create an OVS bridge. """Create an OVS bridge.
:ivar prefix: bridge name prefix :ivar prefix: bridge name prefix
@ -214,6 +214,7 @@ class OVSBridgeFixture(fixtures.Fixture):
""" """
def __init__(self, prefix=BR_PREFIX): def __init__(self, prefix=BR_PREFIX):
super(OVSBridgeFixture, self).__init__()
self.prefix = prefix self.prefix = prefix
def setUp(self): def setUp(self):
@ -251,7 +252,7 @@ class OVSPortFixture(PortFixture):
return name return name
class LinuxBridgeFixture(fixtures.Fixture): class LinuxBridgeFixture(tools.SafeFixture):
"""Create a linux bridge. """Create a linux bridge.
:ivar bridge: created bridge :ivar bridge: created bridge
@ -315,7 +316,7 @@ class VethBridge(object):
len(self.ports)) len(self.ports))
class VethBridgeFixture(fixtures.Fixture): class VethBridgeFixture(tools.SafeFixture):
"""Simulate a bridge with a veth. """Simulate a bridge with a veth.
:ivar bridge: created bridge :ivar bridge: created bridge

View File

@ -15,13 +15,13 @@
import os.path import os.path
import tempfile import tempfile
import fixtures
import six import six
from neutron.common import constants from neutron.common import constants
from neutron.tests import base from neutron.tests import base
from neutron.tests.common import helpers as c_helpers from neutron.tests.common import helpers as c_helpers
from neutron.tests.functional.agent.linux import helpers from neutron.tests.functional.agent.linux import helpers
from neutron.tests import tools
class ConfigDict(base.AttributeDict): class ConfigDict(base.AttributeDict):
@ -41,7 +41,7 @@ class ConfigDict(base.AttributeDict):
self.convert_to_attr_dict(value) self.convert_to_attr_dict(value)
class ConfigFileFixture(fixtures.Fixture): class ConfigFileFixture(tools.SafeFixture):
"""A fixture that knows how to translate configurations to files. """A fixture that knows how to translate configurations to files.
:param base_filename: the filename to use on disk. :param base_filename: the filename to use on disk.
@ -74,7 +74,7 @@ class ConfigFileFixture(fixtures.Fixture):
return config_parser return config_parser
class ConfigFixture(fixtures.Fixture): class ConfigFixture(tools.SafeFixture):
"""A fixture that holds an actual Neutron configuration. """A fixture that holds an actual Neutron configuration.
Note that 'self.config' is intended to only be updated once, during Note that 'self.config' is intended to only be updated once, during
@ -83,6 +83,7 @@ class ConfigFixture(fixtures.Fixture):
is initializing a new instance of the class. is initializing a new instance of the class.
""" """
def __init__(self, temp_dir, base_filename): def __init__(self, temp_dir, base_filename):
super(ConfigFixture, self).__init__()
self.config = ConfigDict() self.config = ConfigDict()
self.temp_dir = temp_dir self.temp_dir = temp_dir
self.base_filename = base_filename self.base_filename = base_filename

View File

@ -28,6 +28,7 @@ from neutron.agent.linux import utils
from neutron.tests import base from neutron.tests import base
from neutron.tests.common import net_helpers from neutron.tests.common import net_helpers
from neutron.tests.fullstack import config_fixtures from neutron.tests.fullstack import config_fixtures
from neutron.tests import tools
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@ -35,8 +36,9 @@ LOG = logging.getLogger(__name__)
DEFAULT_LOG_DIR = '/tmp/fullstack-logs/' DEFAULT_LOG_DIR = '/tmp/fullstack-logs/'
class ProcessFixture(fixtures.Fixture): class ProcessFixture(tools.SafeFixture):
def __init__(self, test_name, process_name, exec_name, config_filenames): def __init__(self, test_name, process_name, exec_name, config_filenames):
super(ProcessFixture, self).__init__()
self.test_name = test_name self.test_name = test_name
self.process_name = process_name self.process_name = process_name
self.exec_name = exec_name self.exec_name = exec_name
@ -68,7 +70,7 @@ class ProcessFixture(fixtures.Fixture):
super(ProcessFixture, self).cleanUp(*args, **kwargs) super(ProcessFixture, self).cleanUp(*args, **kwargs)
class RabbitmqEnvironmentFixture(fixtures.Fixture): class RabbitmqEnvironmentFixture(tools.SafeFixture):
def setUp(self): def setUp(self):
super(RabbitmqEnvironmentFixture, self).setUp() super(RabbitmqEnvironmentFixture, self).setUp()
@ -91,8 +93,9 @@ class RabbitmqEnvironmentFixture(fixtures.Fixture):
utils.execute(cmd, run_as_root=True) utils.execute(cmd, run_as_root=True)
class FullstackFixture(fixtures.Fixture): class FullstackFixture(tools.SafeFixture):
def __init__(self): def __init__(self):
super(FullstackFixture, self).__init__()
self.test_name = None self.test_name = None
def setUp(self): def setUp(self):
@ -117,11 +120,12 @@ class FullstackFixture(fixtures.Fixture):
return False return False
class NeutronServerFixture(fixtures.Fixture): class NeutronServerFixture(tools.SafeFixture):
NEUTRON_SERVER = "neutron-server" NEUTRON_SERVER = "neutron-server"
def __init__(self, test_name, temp_dir, rabbitmq_environment): def __init__(self, test_name, temp_dir, rabbitmq_environment):
super(NeutronServerFixture, self).__init__()
self.test_name = test_name self.test_name = test_name
self.temp_dir = temp_dir self.temp_dir = temp_dir
self.rabbitmq_environment = rabbitmq_environment self.rabbitmq_environment = rabbitmq_environment
@ -165,11 +169,12 @@ class NeutronServerFixture(fixtures.Fixture):
return client.Client(auth_strategy="noauth", endpoint_url=url) return client.Client(auth_strategy="noauth", endpoint_url=url)
class OVSAgentFixture(fixtures.Fixture): class OVSAgentFixture(tools.SafeFixture):
NEUTRON_OVS_AGENT = "neutron-openvswitch-agent" NEUTRON_OVS_AGENT = "neutron-openvswitch-agent"
def __init__(self, test_name, neutron_cfg_fixture, ml2_cfg_fixture): def __init__(self, test_name, neutron_cfg_fixture, ml2_cfg_fixture):
super(OVSAgentFixture, self).__init__()
self.test_name = test_name self.test_name = test_name
self.neutron_cfg_fixture = neutron_cfg_fixture self.neutron_cfg_fixture = neutron_cfg_fixture
self.plugin_cfg_fixture = ml2_cfg_fixture self.plugin_cfg_fixture = ml2_cfg_fixture
@ -199,12 +204,13 @@ class OVSAgentFixture(fixtures.Fixture):
return self.plugin_config.ovs.bridge_mappings.split(':')[1] return self.plugin_config.ovs.bridge_mappings.split(':')[1]
class L3AgentFixture(fixtures.Fixture): class L3AgentFixture(tools.SafeFixture):
NEUTRON_L3_AGENT = "neutron-l3-agent" NEUTRON_L3_AGENT = "neutron-l3-agent"
def __init__(self, test_name, temp_dir, def __init__(self, test_name, temp_dir,
neutron_cfg_fixture, integration_bridge_name): neutron_cfg_fixture, integration_bridge_name):
super(L3AgentFixture, self).__init__()
self.test_name = test_name self.test_name = test_name
self.temp_dir = temp_dir self.temp_dir = temp_dir
self.neutron_cfg_fixture = neutron_cfg_fixture self.neutron_cfg_fixture = neutron_cfg_fixture

View File

@ -20,11 +20,10 @@ import select
import shlex import shlex
import subprocess import subprocess
import fixtures
from neutron.agent.common import config from neutron.agent.common import config
from neutron.agent.linux import ip_lib from neutron.agent.linux import ip_lib
from neutron.agent.linux import utils from neutron.agent.linux import utils
from neutron.tests import tools
CHILD_PROCESS_TIMEOUT = os.environ.get('OS_TEST_CHILD_PROCESS_TIMEOUT', 20) CHILD_PROCESS_TIMEOUT = os.environ.get('OS_TEST_CHILD_PROCESS_TIMEOUT', 20)
CHILD_PROCESS_SLEEP = os.environ.get('OS_TEST_CHILD_PROCESS_SLEEP', 0.5) CHILD_PROCESS_SLEEP = os.environ.get('OS_TEST_CHILD_PROCESS_SLEEP', 0.5)
@ -34,7 +33,7 @@ SS_SOURCE_PORT_PATTERN = re.compile(
r'^.*\s+\d+\s+.*:(?P<port>\d+)\s+[0-9:].*') r'^.*\s+\d+\s+.*:(?P<port>\d+)\s+[0-9:].*')
class RecursivePermDirFixture(fixtures.Fixture): class RecursivePermDirFixture(tools.SafeFixture):
"""Ensure at least perms permissions on directory and ancestors.""" """Ensure at least perms permissions on directory and ancestors."""
def __init__(self, directory, perms): def __init__(self, directory, perms):

View File

@ -0,0 +1,81 @@
# Copyright (c) 2015 Thales Services SAS
# 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.
import fixtures
import testscenarios
from neutron.tests import base
from neutron.tests import tools
class NoErrorFixture(tools.SafeFixture):
def __init__(self):
super(NoErrorFixture, self).__init__()
self.cleaned = False
self.called = False
def setUp(self):
super(NoErrorFixture, self).setUp()
self.called = True
def cleanUp(self):
self.cleaned = True
super(NoErrorFixture, self).cleanUp()
class ErrorAfterFixtureSetup(NoErrorFixture):
def setUp(self):
super(tools.SafeFixture, self).setUp()
raise ValueError
class ErrorBeforeFixtureSetup(NoErrorFixture):
def setUp(self):
raise ValueError
class TestSafeFixture(testscenarios.WithScenarios, base.BaseTestCase):
scenarios = [
('testtools useFixture', dict(fixtures=False)),
('fixtures useFixture', dict(fixtures=True)),
]
def setUp(self):
super(TestSafeFixture, self).setUp()
if self.fixtures:
self.parent = self.useFixture(fixtures.Fixture())
else:
self.parent = self
def test_no_error(self):
fixture = NoErrorFixture()
self.parent.useFixture(fixture)
self.assertTrue(fixture.called)
self.assertFalse(fixture.cleaned)
def test_error_after_root_setup(self):
fixture = ErrorAfterFixtureSetup()
self.assertRaises(ValueError, self.parent.useFixture, fixture)
self.assertTrue(fixture.cleaned)
def test_error_before_root_setup(self):
fixture = ErrorBeforeFixtureSetup()
# NOTE(cbrandily); testtools.useFixture crashs badly if Fixture.setUp
# is not called or fails.
self.assertRaises(AttributeError, self.parent.useFixture, fixture)
self.assertFalse(fixture.cleaned)

View File

@ -17,18 +17,18 @@ Neutron API via different methods.
import abc import abc
import fixtures
import six import six
from neutron.common import exceptions as q_exc from neutron.common import exceptions as q_exc
from neutron import context from neutron import context
from neutron import manager from neutron import manager
from neutron.tests import base from neutron.tests import base
from neutron.tests import tools
from neutron.tests.unit import testlib_api from neutron.tests.unit import testlib_api
@six.add_metaclass(abc.ABCMeta) @six.add_metaclass(abc.ABCMeta)
class AbstractClientFixture(fixtures.Fixture): class AbstractClientFixture(tools.SafeFixture):
""" """
Base class for a client that can interact the neutron api in some Base class for a client that can interact the neutron api in some
manner. manner.
@ -68,6 +68,7 @@ class PluginClientFixture(AbstractClientFixture):
"""Targets the Neutron API via the plugin API""" """Targets the Neutron API via the plugin API"""
def __init__(self, plugin_conf): def __init__(self, plugin_conf):
super(PluginClientFixture, self).__init__()
self.plugin_conf = plugin_conf self.plugin_conf = plugin_conf
def setUp(self): def setUp(self):

View File

@ -16,12 +16,52 @@
import warnings import warnings
import fixtures import fixtures
from oslo_utils import excutils
import six import six
from neutron.api.v2 import attributes from neutron.api.v2 import attributes
class AttributeMapMemento(fixtures.Fixture): class SafeFixture(fixtures.Fixture):
"""Base Fixture ensuring cleanups are done even if setUp fails.
Required until testtools/fixtures bugs #1456353 #1456370 are solved.
"""
def __init__(self):
unsafe_setup = self.setUp
self.setUp = lambda: self.safe_setUp(unsafe_setup)
self.initialized = True
def setUp(self):
assert getattr(self, 'initialized', True)
super(SafeFixture, self).setUp()
def safe_setUp(self, unsafe_setup):
"""Ensure cleanup is done even if setUp fails."""
try:
unsafe_setup()
except Exception:
with excutils.save_and_reraise_exception():
self.safe_cleanUp()
def safe_cleanUp(self):
"""Perform cleanUp if required.
Fixture.addCleanup/cleanUp can be called only after Fixture.setUp
successful call. It implies we cannot and don't need to call cleanUp
if Fixture.setUp fails or is not called.
This method assumes Fixture.setUp was called successfully if
self._detail_sources is defined (Fixture.setUp last action).
"""
root_setup_succeed = hasattr(self, '_detail_sources')
if root_setup_succeed:
self.cleanUp()
class AttributeMapMemento(SafeFixture):
"""Create a copy of the resource attribute map so it can be restored during """Create a copy of the resource attribute map so it can be restored during
test cleanup. test cleanup.
@ -51,7 +91,7 @@ class AttributeMapMemento(fixtures.Fixture):
attributes.RESOURCE_ATTRIBUTE_MAP = self.contents_backup attributes.RESOURCE_ATTRIBUTE_MAP = self.contents_backup
class WarningsFixture(fixtures.Fixture): class WarningsFixture(SafeFixture):
"""Filters out warnings during test runs.""" """Filters out warnings during test runs."""
warning_types = ( warning_types = (

View File

@ -20,7 +20,6 @@ import testtools
import uuid import uuid
import webob import webob
import fixtures
from oslo_db import exception as db_exc from oslo_db import exception as db_exc
from oslo_utils import uuidutils from oslo_utils import uuidutils
from sqlalchemy.orm import exc as sqla_exc from sqlalchemy.orm import exc as sqla_exc
@ -49,6 +48,7 @@ from neutron.plugins.ml2.drivers import type_vlan
from neutron.plugins.ml2 import models from neutron.plugins.ml2 import models
from neutron.plugins.ml2 import plugin as ml2_plugin from neutron.plugins.ml2 import plugin as ml2_plugin
from neutron.tests import base from neutron.tests import base
from neutron.tests import tools
from neutron.tests.unit import _test_extension_portbindings as test_bindings from neutron.tests.unit import _test_extension_portbindings as test_bindings
from neutron.tests.unit.agent import test_securitygroups_rpc as test_sg_rpc from neutron.tests.unit.agent import test_securitygroups_rpc as test_sg_rpc
from neutron.tests.unit.db import test_allowedaddresspairs_db as test_pair from neutron.tests.unit.db import test_allowedaddresspairs_db as test_pair
@ -71,10 +71,11 @@ HOST = 'fake_host'
# TODO(marun) - Move to somewhere common for reuse # TODO(marun) - Move to somewhere common for reuse
class PluginConfFixture(fixtures.Fixture): class PluginConfFixture(tools.SafeFixture):
"""Plugin configuration shared across the unit and functional tests.""" """Plugin configuration shared across the unit and functional tests."""
def __init__(self, plugin_name, parent_setup=None): def __init__(self, plugin_name, parent_setup=None):
super(PluginConfFixture, self).__init__()
self.plugin_name = plugin_name self.plugin_name = plugin_name
self.parent_setup = parent_setup self.parent_setup = parent_setup

View File

@ -13,7 +13,6 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
import fixtures
import six import six
import testtools import testtools
@ -22,6 +21,7 @@ from neutron.db import api as db_api
from neutron.db.migration.models import head # noqa from neutron.db.migration.models import head # noqa
from neutron.db import model_base from neutron.db import model_base
from neutron.tests import base from neutron.tests import base
from neutron.tests import tools
from neutron import wsgi from neutron import wsgi
@ -57,7 +57,7 @@ def create_request(path, body, content_type, method='GET',
return req return req
class SqlFixture(fixtures.Fixture): class SqlFixture(tools.SafeFixture):
# flag to indicate that the models have been loaded # flag to indicate that the models have been loaded
_TABLES_ESTABLISHED = False _TABLES_ESTABLISHED = False