2226
2240
self.transport_readonly_server = HttpServer
2229
def filter_suite_by_re(suite, pattern, exclude_pattern=None,
2230
random_order=False):
2243
def condition_id_re(pattern):
2244
"""Create a condition filter which performs a re check on a test's id.
2246
:param pattern: A regular expression string.
2247
:return: A callable that returns True if the re matches.
2249
filter_re = re.compile(pattern)
2250
def condition(test):
2252
return filter_re.search(test_id)
2256
def condition_isinstance(klass_or_klass_list):
2257
"""Create a condition filter which returns isinstance(param, klass).
2259
:return: A callable which when called with one parameter obj return the
2260
result of isinstance(obj, klass_or_klass_list).
2263
return isinstance(obj, klass_or_klass_list)
2267
def condition_id_in_list(id_list):
2268
"""Create a condition filter which verify that test's id in a list.
2270
:param name: A TestIdList object.
2271
:return: A callable that returns True if the test's id appears in the list.
2273
def condition(test):
2274
return id_list.test_in(test.id())
2278
def exclude_tests_by_condition(suite, condition):
2279
"""Create a test suite which excludes some tests from suite.
2281
:param suite: The suite to get tests from.
2282
:param condition: A callable whose result evaluates True when called with a
2283
test case which should be excluded from the result.
2284
:return: A suite which contains the tests found in suite that fail
2288
for test in iter_suite_tests(suite):
2289
if not condition(test):
2291
return TestUtil.TestSuite(result)
2294
def filter_suite_by_condition(suite, condition):
2295
"""Create a test suite by filtering another one.
2297
:param suite: The source suite.
2298
:param condition: A callable whose result evaluates True when called with a
2299
test case which should be included in the result.
2300
:return: A suite which contains the tests found in suite that pass
2304
for test in iter_suite_tests(suite):
2307
return TestUtil.TestSuite(result)
2310
def filter_suite_by_re(suite, pattern, exclude_pattern=DEPRECATED_PARAMETER,
2311
random_order=DEPRECATED_PARAMETER):
2231
2312
"""Create a test suite by filtering another one.
2233
2314
:param suite: the source suite
2234
2315
:param pattern: pattern that names must match
2235
:param exclude_pattern: pattern that names must not match, if any
2236
:param random_order: if True, tests in the new suite will be put in
2316
:param exclude_pattern: A pattern that names must not match. This parameter
2317
is deprecated as of bzrlib 1.0. Please use the separate function
2318
exclude_tests_by_re instead.
2319
:param random_order: If True, tests in the new suite will be put in
2320
random order. This parameter is deprecated as of bzrlib 1.0. Please
2321
use the separate function randomize_suite instead.
2238
2322
:returns: the newly created suite
2240
return sort_suite_by_re(suite, pattern, exclude_pattern,
2241
random_order, False)
2324
if deprecated_passed(exclude_pattern):
2325
symbol_versioning.warn(
2326
one_zero % "passing exclude_pattern to filter_suite_by_re",
2327
DeprecationWarning, stacklevel=2)
2328
if exclude_pattern is not None:
2329
suite = exclude_tests_by_re(suite, exclude_pattern)
2330
condition = condition_id_re(pattern)
2331
result_suite = filter_suite_by_condition(suite, condition)
2332
if deprecated_passed(random_order):
2333
symbol_versioning.warn(
2334
one_zero % "passing random_order to filter_suite_by_re",
2335
DeprecationWarning, stacklevel=2)
2337
result_suite = randomize_suite(result_suite)
2341
def filter_suite_by_id_list(suite, test_id_list):
2342
"""Create a test suite by filtering another one.
2344
:param suite: The source suite.
2345
:param test_id_list: A list of the test ids to keep as strings.
2346
:returns: the newly created suite
2348
condition = condition_id_in_list(test_id_list)
2349
result_suite = filter_suite_by_condition(suite, condition)
2353
def exclude_tests_by_re(suite, pattern):
2354
"""Create a test suite which excludes some tests from suite.
2356
:param suite: The suite to get tests from.
2357
:param pattern: A regular expression string. Test ids that match this
2358
pattern will be excluded from the result.
2359
:return: A TestSuite that contains all the tests from suite without the
2360
tests that matched pattern. The order of tests is the same as it was in
2363
return exclude_tests_by_condition(suite, condition_id_re(pattern))
2366
def preserve_input(something):
2367
"""A helper for performing test suite transformation chains.
2369
:param something: Anything you want to preserve.
2375
def randomize_suite(suite):
2376
"""Return a new TestSuite with suite's tests in random order.
2378
The tests in the input suite are flattened into a single suite in order to
2379
accomplish this. Any nested TestSuites are removed to provide global
2382
tests = list(iter_suite_tests(suite))
2383
random.shuffle(tests)
2384
return TestUtil.TestSuite(tests)
2387
@deprecated_function(one_zero)
2244
2388
def sort_suite_by_re(suite, pattern, exclude_pattern=None,
2245
2389
random_order=False, append_rest=True):
2246
"""Create a test suite by sorting another one.
2390
"""DEPRECATED: Create a test suite by sorting another one.
2392
This method has been decomposed into separate helper methods that should be
2394
- filter_suite_by_re
2395
- exclude_tests_by_re
2248
2399
:param suite: the source suite
2249
2400
:param pattern: pattern that names must match in order to go
2250
2401
first in the new suite
2251
2402
:param exclude_pattern: pattern that names must not match, if any
2252
2403
:param random_order: if True, tests in the new suite will be put in
2404
random order (with all tests matching pattern
2254
2406
:param append_rest: if False, pattern is a strict filter and not
2255
2407
just an ordering directive
2256
2408
:returns: the newly created suite
2410
if exclude_pattern is not None:
2411
suite = exclude_tests_by_re(suite, exclude_pattern)
2413
order_changer = randomize_suite
2415
order_changer = preserve_input
2417
suites = map(order_changer, split_suite_by_re(suite, pattern))
2418
return TestUtil.TestSuite(suites)
2420
return order_changer(filter_suite_by_re(suite, pattern))
2423
def split_suite_by_re(suite, pattern):
2424
"""Split a test suite into two by a regular expression.
2426
:param suite: The suite to split.
2427
:param pattern: A regular expression string. Test ids that match this
2428
pattern will be in the first test suite returned, and the others in the
2429
second test suite returned.
2430
:return: A tuple of two test suites, where the first contains tests from
2431
suite matching pattern, and the second contains the remainder from
2432
suite. The order within each output suite is the same as it was in
2260
2437
filter_re = re.compile(pattern)
2261
if exclude_pattern is not None:
2262
exclude_re = re.compile(exclude_pattern)
2263
2438
for test in iter_suite_tests(suite):
2264
2439
test_id = test.id()
2265
if exclude_pattern is None or not exclude_re.search(test_id):
2266
if filter_re.search(test_id):
2271
random.shuffle(first)
2272
random.shuffle(second)
2273
return TestUtil.TestSuite(first + second)
2440
if filter_re.search(test_id):
2441
matched.append(test)
2443
did_not_match.append(test)
2444
return TestUtil.TestSuite(matched), TestUtil.TestSuite(did_not_match)
2276
2447
def run_suite(suite, name='test', verbose=False, pattern=".*",
2368
2549
default_transport = old_transport
2552
def load_test_id_list(file_name):
2553
"""Load a test id list from a text file.
2555
The format is one test id by line. No special care is taken to impose
2556
strict rules, these test ids are used to filter the test suite so a test id
2557
that do not match an existing test will do no harm. This allows user to add
2558
comments, leave blank lines, etc.
2562
ftest = open(file_name, 'rt')
2564
if e.errno != errno.ENOENT:
2567
raise errors.NoSuchFile(file_name)
2569
for test_name in ftest.readlines():
2570
test_list.append(test_name.strip())
2575
class TestIdList(object):
2576
"""Test id list to filter a test suite.
2578
Relying on the assumption that test ids are built as:
2579
<module>[.<class>.<method>][(<param>+)], <module> being in python dotted
2580
notation, this class offers methods to :
2581
- avoid building a test suite for modules not refered to in the test list,
2582
- keep only the tests listed from the module test suite.
2585
def __init__(self, test_id_list):
2586
# When a test suite needs to be filtered against us we compare test ids
2587
# for equality, so a simple dict offers a quick and simple solution.
2588
self.tests = dict().fromkeys(test_id_list, True)
2590
# While unittest.TestCase have ids like:
2591
# <module>.<class>.<method>[(<param+)],
2592
# doctest.DocTestCase can have ids like:
2595
# <module>.<function>
2596
# <module>.<class>.<method>
2598
# Since we can't predict a test class from its name only, we settle on
2599
# a simple constraint: a test id always begins with its module name.
2602
for test_id in test_id_list:
2603
parts = test_id.split('.')
2604
mod_name = parts.pop(0)
2605
modules[mod_name] = True
2607
mod_name += '.' + part
2608
modules[mod_name] = True
2609
self.modules = modules
2611
def is_module_name_used(self, module_name):
2612
"""Is there tests for the module or one of its sub modules."""
2613
return self.modules.has_key(module_name)
2615
def test_in(self, test_id):
2616
return self.tests.has_key(test_id)
2619
def test_suite(keep_only=None):
2372
2620
"""Build and return TestSuite for the whole of bzrlib.
2622
:param keep_only: A list of test ids limiting the suite returned.
2374
2624
This function can be replaced if you need to change the default test
2375
2625
suite on a global basis, but it is not encouraged.
2508
2760
suite = TestUtil.TestSuite()
2509
2761
loader = TestUtil.TestLoader()
2510
suite.addTest(loader.loadTestsFromModuleNames(testmod_names))
2763
if keep_only is not None:
2764
id_filter = TestIdList(keep_only)
2766
# modules building their suite with loadTestsFromModuleNames
2767
if keep_only is None:
2768
suite.addTest(loader.loadTestsFromModuleNames(testmod_names))
2770
for mod in [m for m in testmod_names
2771
if id_filter.is_module_name_used(m)]:
2772
mod_suite = loader.loadTestsFromModuleNames([mod])
2773
mod_suite = filter_suite_by_id_list(mod_suite, id_filter)
2774
suite.addTest(mod_suite)
2776
# modules adapted for transport implementations
2511
2777
from bzrlib.tests.test_transport_implementations import TransportTestProviderAdapter
2512
2778
adapter = TransportTestProviderAdapter()
2513
adapt_modules(test_transport_implementations, adapter, loader, suite)
2514
for package in packages_to_test():
2515
suite.addTest(package.test_suite())
2516
for m in MODULES_TO_TEST:
2517
suite.addTest(loader.loadTestsFromModule(m))
2518
for m in MODULES_TO_DOCTEST:
2779
if keep_only is None:
2780
adapt_modules(test_transport_implementations, adapter, loader, suite)
2782
for mod in [m for m in test_transport_implementations
2783
if id_filter.is_module_name_used(m)]:
2784
mod_suite = TestUtil.TestSuite()
2785
adapt_modules([mod], adapter, loader, mod_suite)
2786
mod_suite = filter_suite_by_id_list(mod_suite, id_filter)
2787
suite.addTest(mod_suite)
2789
# modules defining their own test_suite()
2790
for package in [p for p in packages_to_test()
2791
if (keep_only is None
2792
or id_filter.is_module_name_used(p.__name__))]:
2793
pack_suite = package.test_suite()
2794
if keep_only is not None:
2795
pack_suite = filter_suite_by_id_list(pack_suite, id_filter)
2796
suite.addTest(pack_suite)
2798
# XXX: MODULES_TO_TEST should be obsoleted ?
2799
for mod in [m for m in MODULES_TO_TEST
2800
if keep_only is None or id_filter.is_module_name_used(m)]:
2801
mod_suite = loader.loadTestsFromModule(mod)
2802
if keep_only is not None:
2803
mod_suite = filter_suite_by_id_list(mod_suite, id_filter)
2804
suite.addTest(mod_suite)
2806
for mod in MODULES_TO_DOCTEST:
2520
suite.addTest(doctest.DocTestSuite(m))
2808
doc_suite = doctest.DocTestSuite(mod)
2521
2809
except ValueError, e:
2522
print '**failed to get doctest for: %s\n%s' %(m,e)
2810
print '**failed to get doctest for: %s\n%s' % (mod, e)
2812
if keep_only is not None:
2813
# DocTests may use ids which doesn't contain the module name
2814
doc_suite = filter_suite_by_id_list(doc_suite, id_filter)
2815
suite.addTest(doc_suite)
2524
2817
default_encoding = sys.getdefaultencoding()
2525
for name, plugin in bzrlib.plugin.plugins().items():
2818
for name, plugin in [(n, p) for (n, p) in bzrlib.plugin.plugins().items()
2819
if (keep_only is None
2820
or id_filter.is_module_name_used(
2821
p.module.__name__))]:
2527
2823
plugin_suite = plugin.test_suite()
2528
2824
except ImportError, e: