diff --git a/.testr.conf b/.testr.conf index c180b0319fb..d96d48ed296 100644 --- a/.testr.conf +++ b/.testr.conf @@ -1,4 +1,8 @@ [DEFAULT] -test_command=OS_STDOUT_CAPTURE=1 OS_STDERR_CAPTURE=1 OS_LOG_CAPTURE=1 ${PYTHON:-python} -m subunit.run discover -t ./ ${OS_TEST_PATH:-./neutron/tests/unit} $LISTOPT $IDOPTION +test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \ + OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \ + OS_LOG_CAPTURE=${OS_LOG_CAPTURE:-1} \ + OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-160} \ + ${PYTHON:-python} -m subunit.run discover -t ./ ${OS_TEST_PATH:-./neutron/tests/unit} $LISTOPT $IDOPTION test_id_option=--load-list $IDFILE test_list_option=--list diff --git a/neutron/tests/base.py b/neutron/tests/base.py index 9d683de8d6e..44435910ca3 100644 --- a/neutron/tests/base.py +++ b/neutron/tests/base.py @@ -426,3 +426,34 @@ class PluginFixture(fixtures.Fixture): if plugin() and not isinstance(plugin(), mock.Base): raise AssertionError( 'The plugin for this test was not deallocated.') + + +class Timeout(fixtures.Fixture): + """Setup per test timeouts. + + In order to avoid test deadlocks we support setting up a test + timeout parameter read from the environment. In almost all + cases where the timeout is reached this means a deadlock. + + A scaling factor allows extremely long tests to specify they + need more time. + """ + + def __init__(self, timeout=None, scaling=1): + super(Timeout, self).__init__() + if timeout is None: + timeout = os.environ.get('OS_TEST_TIMEOUT', 0) + try: + self.test_timeout = int(timeout) + except ValueError: + # If timeout value is invalid do not set a timeout. + self.test_timeout = 0 + if scaling >= 1: + self.test_timeout *= scaling + else: + raise ValueError('scaling value must be >= 1') + + def setUp(self): + super(Timeout, self).setUp() + if self.test_timeout > 0: + self.useFixture(fixtures.Timeout(self.test_timeout, gentle=True)) diff --git a/neutron/tests/functional/db/test_migrations.py b/neutron/tests/functional/db/test_migrations.py index 725d4321a29..e86ce6eed3d 100644 --- a/neutron/tests/functional/db/test_migrations.py +++ b/neutron/tests/functional/db/test_migrations.py @@ -30,6 +30,7 @@ import subprocess from neutron.db.migration.alembic_migrations import external from neutron.db.migration import cli as migration from neutron.db.migration.models import head as head_models +from neutron.tests import base as test_base from neutron.tests.unit import testlib_api cfg.CONF.import_opt('core_plugin', 'neutron.conf.common') @@ -129,6 +130,7 @@ class _TestModelsMigrations(test_migrations.ModelsMigrationsSync): ''' BUILD_SCHEMA = False + TIMEOUT_SCALING_FACTOR = 4 def setUp(self): super(_TestModelsMigrations, self).setUp() @@ -137,6 +139,9 @@ class _TestModelsMigrations(test_migrations.ModelsMigrationsSync): self.alembic_config = migration.get_neutron_config() self.alembic_config.neutron_config = cfg.CONF + # Migration tests can take a long time + self.useFixture(test_base.Timeout(scaling=self.TIMEOUT_SCALING_FACTOR)) + def db_sync(self, engine): upgrade(engine, self.alembic_config)