Merge "Break optimize_db_test_loader into package and module level"
This commit is contained in:
commit
accd272d15
@ -14,9 +14,9 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import debtcollector
|
import debtcollector
|
||||||
|
import debtcollector.moves
|
||||||
import fixtures
|
import fixtures
|
||||||
import testresources
|
import testresources
|
||||||
import testscenarios
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from oslotest import base as test_base
|
from oslotest import base as test_base
|
||||||
@ -25,8 +25,6 @@ except ImportError:
|
|||||||
' test-requirements')
|
' test-requirements')
|
||||||
|
|
||||||
|
|
||||||
import os
|
|
||||||
|
|
||||||
from oslo_utils import reflection
|
from oslo_utils import reflection
|
||||||
import six
|
import six
|
||||||
|
|
||||||
@ -34,6 +32,7 @@ from oslo_db import exception
|
|||||||
from oslo_db.sqlalchemy import enginefacade
|
from oslo_db.sqlalchemy import enginefacade
|
||||||
from oslo_db.sqlalchemy import provision
|
from oslo_db.sqlalchemy import provision
|
||||||
from oslo_db.sqlalchemy import session
|
from oslo_db.sqlalchemy import session
|
||||||
|
from oslo_db.sqlalchemy.test_fixtures import optimize_package_test_loader
|
||||||
|
|
||||||
|
|
||||||
@debtcollector.removals.removed_class("DbFixture")
|
@debtcollector.removals.removed_class("DbFixture")
|
||||||
@ -245,39 +244,5 @@ class PostgreSQLOpportunisticTestCase(OpportunisticTestCase):
|
|||||||
FIXTURE = PostgreSQLOpportunisticFixture
|
FIXTURE = PostgreSQLOpportunisticFixture
|
||||||
|
|
||||||
|
|
||||||
def optimize_db_test_loader(file_):
|
optimize_db_test_loader = debtcollector.moves.moved_function(
|
||||||
"""Package level load_tests() function.
|
optimize_package_test_loader, "optimize_db_test_loader", __name__)
|
||||||
|
|
||||||
Will apply an optimizing test suite to all sub-tests, which groups DB
|
|
||||||
tests and other resources appropriately.
|
|
||||||
|
|
||||||
Place this in an __init__.py package file within the root of the test
|
|
||||||
suite, at the level where testresources loads it as a package::
|
|
||||||
|
|
||||||
from oslo_db.sqlalchemy import test_base
|
|
||||||
|
|
||||||
load_tests = test_base.optimize_db_test_loader(__file__)
|
|
||||||
|
|
||||||
Alternatively, the directive can be placed into a test module directly.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
this_dir = os.path.dirname(file_)
|
|
||||||
|
|
||||||
def load_tests(loader, found_tests, pattern):
|
|
||||||
# pattern is None if the directive is placed within
|
|
||||||
# a test module directly, as well as within certain test
|
|
||||||
# discovery patterns
|
|
||||||
|
|
||||||
if pattern is not None:
|
|
||||||
pkg_tests = loader.discover(start_dir=this_dir, pattern=pattern)
|
|
||||||
|
|
||||||
result = testresources.OptimisingTestSuite()
|
|
||||||
found_tests = testscenarios.load_tests_apply_scenarios(
|
|
||||||
loader, found_tests, pattern)
|
|
||||||
result.addTest(found_tests)
|
|
||||||
|
|
||||||
if pattern is not None:
|
|
||||||
result.addTest(pkg_tests)
|
|
||||||
return result
|
|
||||||
return load_tests
|
|
||||||
|
@ -15,7 +15,9 @@
|
|||||||
|
|
||||||
import fixtures
|
import fixtures
|
||||||
import logging
|
import logging
|
||||||
|
import os
|
||||||
import testresources
|
import testresources
|
||||||
|
import testscenarios
|
||||||
|
|
||||||
from oslo_db import exception
|
from oslo_db import exception
|
||||||
from oslo_db.sqlalchemy import enginefacade
|
from oslo_db.sqlalchemy import enginefacade
|
||||||
@ -544,3 +546,79 @@ class MySQLOpportunisticFixture(OpportunisticDbFixture):
|
|||||||
|
|
||||||
class PostgresqlOpportunisticFixture(OpportunisticDbFixture):
|
class PostgresqlOpportunisticFixture(OpportunisticDbFixture):
|
||||||
DRIVER = 'postgresql'
|
DRIVER = 'postgresql'
|
||||||
|
|
||||||
|
|
||||||
|
def optimize_package_test_loader(file_):
|
||||||
|
"""Organize package-level tests into a testresources.OptimizingTestSuite.
|
||||||
|
|
||||||
|
This function provides a unittest-compatible load_tests hook
|
||||||
|
for a given package; for per-module, use the
|
||||||
|
:func:`.optimize_module_test_loader` function.
|
||||||
|
|
||||||
|
When a unitest or subunit style
|
||||||
|
test runner is used, the function will be called in order to
|
||||||
|
return a TestSuite containing the tests to run; this function
|
||||||
|
ensures that this suite is an OptimisingTestSuite, which will organize
|
||||||
|
the production of test resources across groups of tests at once.
|
||||||
|
|
||||||
|
The function is invoked as::
|
||||||
|
|
||||||
|
from oslo_db.sqlalchemy import test_base
|
||||||
|
|
||||||
|
load_tests = test_base.optimize_package_test_loader(__file__)
|
||||||
|
|
||||||
|
The loader *must* be present in the package level __init__.py.
|
||||||
|
|
||||||
|
The function also applies testscenarios expansion to all test collections.
|
||||||
|
This so that an existing test suite that already needs to build
|
||||||
|
TestScenarios from a load_tests call can still have this take place when
|
||||||
|
replaced with this function.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
this_dir = os.path.dirname(file_)
|
||||||
|
|
||||||
|
def load_tests(loader, found_tests, pattern):
|
||||||
|
result = testresources.OptimisingTestSuite()
|
||||||
|
result.addTests(found_tests)
|
||||||
|
pkg_tests = loader.discover(start_dir=this_dir, pattern=pattern)
|
||||||
|
result.addTests(testscenarios.generate_scenarios(pkg_tests))
|
||||||
|
|
||||||
|
return result
|
||||||
|
return load_tests
|
||||||
|
|
||||||
|
|
||||||
|
def optimize_module_test_loader():
|
||||||
|
"""Organize module-level tests into a testresources.OptimizingTestSuite.
|
||||||
|
|
||||||
|
This function provides a unittest-compatible load_tests hook
|
||||||
|
for a given module; for per-package, use the
|
||||||
|
:func:`.optimize_package_test_loader` function.
|
||||||
|
|
||||||
|
When a unitest or subunit style
|
||||||
|
test runner is used, the function will be called in order to
|
||||||
|
return a TestSuite containing the tests to run; this function
|
||||||
|
ensures that this suite is an OptimisingTestSuite, which will organize
|
||||||
|
the production of test resources across groups of tests at once.
|
||||||
|
|
||||||
|
The function is invoked as::
|
||||||
|
|
||||||
|
from oslo_db.sqlalchemy import test_base
|
||||||
|
|
||||||
|
load_tests = test_base.optimize_module_test_loader()
|
||||||
|
|
||||||
|
The loader *must* be present in an individual module, and *not* the
|
||||||
|
package level __init__.py.
|
||||||
|
|
||||||
|
The function also applies testscenarios expansion to all test collections.
|
||||||
|
This so that an existing test suite that already needs to build
|
||||||
|
TestScenarios from a load_tests call can still have this take place when
|
||||||
|
replaced with this function.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def load_tests(loader, found_tests, pattern):
|
||||||
|
result = testresources.OptimisingTestSuite()
|
||||||
|
result.addTests(testscenarios.generate_scenarios(found_tests))
|
||||||
|
return result
|
||||||
|
return load_tests
|
||||||
|
@ -11,7 +11,10 @@
|
|||||||
# under the License.
|
# under the License.
|
||||||
|
|
||||||
import mock
|
import mock
|
||||||
|
import os
|
||||||
import testresources
|
import testresources
|
||||||
|
import testscenarios
|
||||||
|
import unittest
|
||||||
|
|
||||||
from oslo_db.sqlalchemy import enginefacade
|
from oslo_db.sqlalchemy import enginefacade
|
||||||
from oslo_db.sqlalchemy import provision
|
from oslo_db.sqlalchemy import provision
|
||||||
@ -19,6 +22,8 @@ from oslo_db.sqlalchemy import test_base as legacy_test_base
|
|||||||
from oslo_db.sqlalchemy import test_fixtures
|
from oslo_db.sqlalchemy import test_fixtures
|
||||||
from oslotest import base as oslo_test_base
|
from oslotest import base as oslo_test_base
|
||||||
|
|
||||||
|
start_dir = os.path.dirname(__file__)
|
||||||
|
|
||||||
|
|
||||||
class BackendSkipTest(oslo_test_base.BaseTestCase):
|
class BackendSkipTest(oslo_test_base.BaseTestCase):
|
||||||
|
|
||||||
@ -212,3 +217,82 @@ class LegacyBaseClassTest(oslo_test_base.BaseTestCase):
|
|||||||
|
|
||||||
db_resource = dict(st.resources)['db']
|
db_resource = dict(st.resources)['db']
|
||||||
self.assertTrue(db_resource.provision_new_database)
|
self.assertTrue(db_resource.provision_new_database)
|
||||||
|
|
||||||
|
|
||||||
|
class TestLoadHook(unittest.TestCase):
|
||||||
|
"""Test the 'load_tests' hook supplied by test_base.
|
||||||
|
|
||||||
|
The purpose of this loader is to organize tests into an
|
||||||
|
OptimisingTestSuite using the standard unittest load_tests hook.
|
||||||
|
The hook needs to detect if it is being invoked at the module
|
||||||
|
level or at the package level. It has to behave completely differently
|
||||||
|
in these two cases.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def test_module_level(self):
|
||||||
|
load_tests = test_fixtures.optimize_module_test_loader()
|
||||||
|
|
||||||
|
loader = unittest.TestLoader()
|
||||||
|
|
||||||
|
found_tests = loader.discover(start_dir, pattern="test_fixtures.py")
|
||||||
|
new_loader = load_tests(loader, found_tests, "test_fixtures.py")
|
||||||
|
|
||||||
|
self.assertTrue(
|
||||||
|
isinstance(new_loader, testresources.OptimisingTestSuite)
|
||||||
|
)
|
||||||
|
|
||||||
|
actual_tests = unittest.TestSuite(
|
||||||
|
testscenarios.generate_scenarios(found_tests)
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
new_loader.countTestCases(), actual_tests.countTestCases()
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_package_level(self):
|
||||||
|
self._test_package_level(test_fixtures.optimize_package_test_loader)
|
||||||
|
|
||||||
|
def test_package_level_legacy(self):
|
||||||
|
self._test_package_level(legacy_test_base.optimize_db_test_loader)
|
||||||
|
|
||||||
|
def _test_package_level(self, fn):
|
||||||
|
load_tests = fn(
|
||||||
|
os.path.join(start_dir, "__init__.py"))
|
||||||
|
|
||||||
|
loader = unittest.TestLoader()
|
||||||
|
|
||||||
|
new_loader = load_tests(
|
||||||
|
loader, unittest.suite.TestSuite(), "test_fixtures.py")
|
||||||
|
|
||||||
|
self.assertTrue(
|
||||||
|
isinstance(new_loader, testresources.OptimisingTestSuite)
|
||||||
|
)
|
||||||
|
|
||||||
|
actual_tests = unittest.TestSuite(
|
||||||
|
testscenarios.generate_scenarios(
|
||||||
|
loader.discover(start_dir, pattern="test_fixtures.py"))
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertEqual(
|
||||||
|
new_loader.countTestCases(), actual_tests.countTestCases()
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class TestWScenarios(unittest.TestCase):
|
||||||
|
"""a 'do nothing' test suite.
|
||||||
|
|
||||||
|
Should generate exactly four tests when testscenarios is used.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
def test_one(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_two(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
scenarios = [
|
||||||
|
('scenario1', dict(scenario='scenario 1')),
|
||||||
|
('scenario2', dict(scenario='scenario 2'))
|
||||||
|
]
|
||||||
|
Loading…
Reference in New Issue
Block a user