110
107
default_transport = LocalURLServer
113
MODULES_TO_DOCTEST = [
124
bzrlib.version_info_formats.format_custom,
125
# quoted to avoid module-loading circularity
130
def packages_to_test():
131
"""Return a list of packages to test.
133
The packages are not globally imported so that import failures are
134
triggered when running selftest, not when importing the command.
137
import bzrlib.tests.blackbox
138
import bzrlib.tests.branch_implementations
139
import bzrlib.tests.bzrdir_implementations
140
import bzrlib.tests.commands
141
import bzrlib.tests.interrepository_implementations
142
import bzrlib.tests.interversionedfile_implementations
143
import bzrlib.tests.intertree_implementations
144
import bzrlib.tests.inventory_implementations
145
import bzrlib.tests.per_lock
146
import bzrlib.tests.repository_implementations
147
import bzrlib.tests.revisionstore_implementations
148
import bzrlib.tests.tree_implementations
149
import bzrlib.tests.workingtree_implementations
152
bzrlib.tests.blackbox,
153
bzrlib.tests.branch_implementations,
154
bzrlib.tests.bzrdir_implementations,
155
bzrlib.tests.commands,
156
bzrlib.tests.interrepository_implementations,
157
bzrlib.tests.interversionedfile_implementations,
158
bzrlib.tests.intertree_implementations,
159
bzrlib.tests.inventory_implementations,
160
bzrlib.tests.per_lock,
161
bzrlib.tests.repository_implementations,
162
bzrlib.tests.revisionstore_implementations,
163
bzrlib.tests.tree_implementations,
164
bzrlib.tests.workingtree_implementations,
168
110
class ExtendedTestResult(unittest._TextTestResult):
169
111
"""Accepts, reports and accumulates the results of running tests.
417
361
self.pb.update('[test 0/%d] starting...' % (self.num_tests))
419
363
def _progress_prefix_text(self):
420
a = '[%d' % self.count
364
# the longer this text, the less space we have to show the test
366
a = '[%d' % self.count # total that have been run
367
# tests skipped as known not to be relevant are not important enough
369
## if self.skip_count:
370
## a += ', %d skip' % self.skip_count
371
## if self.known_failure_count:
372
## a += '+%dX' % self.known_failure_count
421
373
if self.num_tests is not None:
422
374
a +='/%d' % self.num_tests
423
a += ' in %ds' % (time.time() - self._overall_start_time)
376
runtime = time.time() - self._overall_start_time
378
a += '%dm%ds' % (runtime / 60, runtime % 60)
424
381
if self.error_count:
425
a += ', %d errors' % self.error_count
382
a += ', %d err' % self.error_count
426
383
if self.failure_count:
427
a += ', %d failed' % self.failure_count
428
if self.known_failure_count:
429
a += ', %d known failures' % self.known_failure_count
431
a += ', %d skipped' % self.skip_count
384
a += ', %d fail' % self.failure_count
432
385
if self.unsupported:
433
a += ', %d missing features' % len(self.unsupported)
386
a += ', %d missing' % len(self.unsupported)
2309
2312
return TestUtil.TestSuite(result)
2312
def filter_suite_by_re(suite, pattern, exclude_pattern=DEPRECATED_PARAMETER,
2313
random_order=DEPRECATED_PARAMETER):
2315
def filter_suite_by_re(suite, pattern):
2314
2316
"""Create a test suite by filtering another one.
2316
2318
:param suite: the source suite
2317
2319
:param pattern: pattern that names must match
2318
:param exclude_pattern: A pattern that names must not match. This parameter
2319
is deprecated as of bzrlib 1.0. Please use the separate function
2320
exclude_tests_by_re instead.
2321
:param random_order: If True, tests in the new suite will be put in
2322
random order. This parameter is deprecated as of bzrlib 1.0. Please
2323
use the separate function randomize_suite instead.
2324
2320
:returns: the newly created suite
2326
if deprecated_passed(exclude_pattern):
2327
symbol_versioning.warn(
2328
one_zero % "passing exclude_pattern to filter_suite_by_re",
2329
DeprecationWarning, stacklevel=2)
2330
if exclude_pattern is not None:
2331
suite = exclude_tests_by_re(suite, exclude_pattern)
2332
2322
condition = condition_id_re(pattern)
2333
2323
result_suite = filter_suite_by_condition(suite, condition)
2334
if deprecated_passed(random_order):
2335
symbol_versioning.warn(
2336
one_zero % "passing random_order to filter_suite_by_re",
2337
DeprecationWarning, stacklevel=2)
2339
result_suite = randomize_suite(result_suite)
2340
2324
return result_suite
2386
2382
return TestUtil.TestSuite(tests)
2389
@deprecated_function(one_zero)
2390
def sort_suite_by_re(suite, pattern, exclude_pattern=None,
2391
random_order=False, append_rest=True):
2392
"""DEPRECATED: Create a test suite by sorting another one.
2394
This method has been decomposed into separate helper methods that should be
2396
- filter_suite_by_re
2397
- exclude_tests_by_re
2385
def split_suite_by_condition(suite, condition):
2386
"""Split a test suite into two by a condition.
2401
:param suite: the source suite
2402
:param pattern: pattern that names must match in order to go
2403
first in the new suite
2404
:param exclude_pattern: pattern that names must not match, if any
2405
:param random_order: if True, tests in the new suite will be put in
2406
random order (with all tests matching pattern
2408
:param append_rest: if False, pattern is a strict filter and not
2409
just an ordering directive
2410
:returns: the newly created suite
2388
:param suite: The suite to split.
2389
:param condition: The condition to match on. Tests that match this
2390
condition are returned in the first test suite, ones that do not match
2391
are in the second suite.
2392
:return: A tuple of two test suites, where the first contains tests from
2393
suite matching the condition, and the second contains the remainder
2394
from suite. The order within each output suite is the same as it was in
2412
if exclude_pattern is not None:
2413
suite = exclude_tests_by_re(suite, exclude_pattern)
2415
order_changer = randomize_suite
2417
order_changer = preserve_input
2419
suites = map(order_changer, split_suite_by_re(suite, pattern))
2420
return TestUtil.TestSuite(suites)
2422
return order_changer(filter_suite_by_re(suite, pattern))
2399
for test in iter_suite_tests(suite):
2401
matched.append(test)
2403
did_not_match.append(test)
2404
return TestUtil.TestSuite(matched), TestUtil.TestSuite(did_not_match)
2425
2407
def split_suite_by_re(suite, pattern):
2574
2558
return test_list
2561
def suite_matches_id_list(test_suite, id_list):
2562
"""Warns about tests not appearing or appearing more than once.
2564
:param test_suite: A TestSuite object.
2565
:param test_id_list: The list of test ids that should be found in
2568
:return: (absents, duplicates) absents is a list containing the test found
2569
in id_list but not in test_suite, duplicates is a list containing the
2570
test found multiple times in test_suite.
2572
When using a prefined test id list, it may occurs that some tests do not
2573
exist anymore or that some tests use the same id. This function warns the
2574
tester about potential problems in his workflow (test lists are volatile)
2575
or in the test suite itself (using the same id for several tests does not
2576
help to localize defects).
2578
# Build a dict counting id occurrences
2580
for test in iter_suite_tests(test_suite):
2582
tests[id] = tests.get(id, 0) + 1
2587
occurs = tests.get(id, 0)
2589
not_found.append(id)
2591
duplicates.append(id)
2593
return not_found, duplicates
2577
2596
class TestIdList(object):
2578
2597
"""Test id list to filter a test suite.
2610
2629
modules[mod_name] = True
2611
2630
self.modules = modules
2613
def is_module_name_used(self, module_name):
2632
def refers_to(self, module_name):
2614
2633
"""Is there tests for the module or one of its sub modules."""
2615
2634
return self.modules.has_key(module_name)
2617
def test_in(self, test_id):
2636
def includes(self, test_id):
2618
2637
return self.tests.has_key(test_id)
2621
def test_suite(keep_only=None):
2640
def test_suite(keep_only=None, starting_with=None):
2622
2641
"""Build and return TestSuite for the whole of bzrlib.
2624
2643
:param keep_only: A list of test ids limiting the suite returned.
2645
:param starting_with: An id limiting the suite returned to the tests
2626
2648
This function can be replaced if you need to change the default test
2627
2649
suite on a global basis, but it is not encouraged.
2629
2651
testmod_names = [
2630
2653
'bzrlib.util.tests.test_bencode',
2654
'bzrlib.tests.blackbox',
2655
'bzrlib.tests.branch_implementations',
2656
'bzrlib.tests.bzrdir_implementations',
2657
'bzrlib.tests.commands',
2658
'bzrlib.tests.inventory_implementations',
2659
'bzrlib.tests.interrepository_implementations',
2660
'bzrlib.tests.intertree_implementations',
2661
'bzrlib.tests.interversionedfile_implementations',
2662
'bzrlib.tests.per_lock',
2663
'bzrlib.tests.repository_implementations',
2664
'bzrlib.tests.revisionstore_implementations',
2631
2665
'bzrlib.tests.test__dirstate_helpers',
2632
2666
'bzrlib.tests.test_ancestry',
2633
2667
'bzrlib.tests.test_annotate',
2738
2774
'bzrlib.tests.test_transactions',
2739
2775
'bzrlib.tests.test_transform',
2740
2776
'bzrlib.tests.test_transport',
2777
'bzrlib.tests.test_transport_implementations',
2741
2778
'bzrlib.tests.test_tree',
2742
2779
'bzrlib.tests.test_treebuilder',
2743
2780
'bzrlib.tests.test_tsort',
2744
2781
'bzrlib.tests.test_tuned_gzip',
2745
2782
'bzrlib.tests.test_ui',
2783
'bzrlib.tests.test_uncommit',
2746
2784
'bzrlib.tests.test_upgrade',
2747
2785
'bzrlib.tests.test_urlutils',
2748
2786
'bzrlib.tests.test_versionedfile',
2755
2793
'bzrlib.tests.test_workingtree_4',
2756
2794
'bzrlib.tests.test_wsgi',
2757
2795
'bzrlib.tests.test_xml',
2796
'bzrlib.tests.tree_implementations',
2797
'bzrlib.tests.workingtree_implementations',
2759
test_transport_implementations = [
2760
'bzrlib.tests.test_transport_implementations',
2761
'bzrlib.tests.test_read_bundle',
2763
suite = TestUtil.TestSuite()
2764
2800
loader = TestUtil.TestLoader()
2766
if keep_only is not None:
2802
if starting_with is not None:
2803
# We take precedence over keep_only because *at loading time* using
2804
# both options means we will load less tests for the same final result.
2805
def interesting_module(name):
2807
# Either the module name starts with the specified string
2808
name.startswith(starting_with)
2809
# or it may contain tests starting with the specified string
2810
or starting_with.startswith(name)
2812
loader = TestUtil.FilteredByModuleTestLoader(interesting_module)
2814
elif keep_only is not None:
2767
2815
id_filter = TestIdList(keep_only)
2816
loader = TestUtil.FilteredByModuleTestLoader(id_filter.refers_to)
2817
def interesting_module(name):
2818
return id_filter.refers_to(name)
2821
loader = TestUtil.TestLoader()
2822
def interesting_module(name):
2823
# No filtering, all modules are interesting
2826
suite = loader.suiteClass()
2769
2828
# modules building their suite with loadTestsFromModuleNames
2770
if keep_only is None:
2771
suite.addTest(loader.loadTestsFromModuleNames(testmod_names))
2773
for mod in [m for m in testmod_names
2774
if id_filter.is_module_name_used(m)]:
2775
mod_suite = loader.loadTestsFromModuleNames([mod])
2776
mod_suite = filter_suite_by_id_list(mod_suite, id_filter)
2777
suite.addTest(mod_suite)
2779
# modules adapted for transport implementations
2780
from bzrlib.tests.test_transport_implementations import TransportTestProviderAdapter
2781
adapter = TransportTestProviderAdapter()
2782
if keep_only is None:
2783
adapt_modules(test_transport_implementations, adapter, loader, suite)
2785
for mod in [m for m in test_transport_implementations
2786
if id_filter.is_module_name_used(m)]:
2787
mod_suite = TestUtil.TestSuite()
2788
adapt_modules([mod], adapter, loader, mod_suite)
2789
mod_suite = filter_suite_by_id_list(mod_suite, id_filter)
2790
suite.addTest(mod_suite)
2792
# modules defining their own test_suite()
2793
for package in [p for p in packages_to_test()
2794
if (keep_only is None
2795
or id_filter.is_module_name_used(p.__name__))]:
2796
pack_suite = package.test_suite()
2797
if keep_only is not None:
2798
pack_suite = filter_suite_by_id_list(pack_suite, id_filter)
2799
suite.addTest(pack_suite)
2801
# XXX: MODULES_TO_TEST should be obsoleted ?
2802
for mod in [m for m in MODULES_TO_TEST
2803
if keep_only is None or id_filter.is_module_name_used(m)]:
2804
mod_suite = loader.loadTestsFromModule(mod)
2805
if keep_only is not None:
2806
mod_suite = filter_suite_by_id_list(mod_suite, id_filter)
2807
suite.addTest(mod_suite)
2809
for mod in MODULES_TO_DOCTEST:
2829
suite.addTest(loader.loadTestsFromModuleNames(testmod_names))
2831
modules_to_doctest = [
2836
'bzrlib.iterablefile',
2841
'bzrlib.symbol_versioning',
2844
'bzrlib.version_info_formats.format_custom',
2847
for mod in modules_to_doctest:
2848
if not interesting_module(mod):
2849
# No tests to keep here, move along
2811
2852
doc_suite = doctest.DocTestSuite(mod)
2812
2853
except ValueError, e:
2813
2854
print '**failed to get doctest for: %s\n%s' % (mod, e)
2815
if keep_only is not None:
2816
# DocTests may use ids which doesn't contain the module name
2817
doc_suite = filter_suite_by_id_list(doc_suite, id_filter)
2818
2856
suite.addTest(doc_suite)
2820
2858
default_encoding = sys.getdefaultencoding()
2821
2859
for name, plugin in bzrlib.plugin.plugins().items():
2822
if keep_only is not None:
2823
if not id_filter.is_module_name_used(plugin.module.__name__):
2860
if not interesting_module(plugin.module.__name__):
2825
2862
plugin_suite = plugin.test_suite()
2826
2863
# We used to catch ImportError here and turn it into just a warning,
2827
2864
# but really if you don't have --no-plugins this should be a failure.
2828
2865
# mbp 20080213 - see http://bugs.launchpad.net/bugs/189771
2866
if plugin_suite is None:
2867
plugin_suite = plugin.load_plugin_tests(loader)
2829
2868
if plugin_suite is not None:
2830
if keep_only is not None:
2831
plugin_suite = filter_suite_by_id_list(plugin_suite,
2833
2869
suite.addTest(plugin_suite)
2834
2870
if default_encoding != sys.getdefaultencoding():
2835
2871
bzrlib.trace.warning(
2837
2873
sys.getdefaultencoding())
2839
2875
sys.setdefaultencoding(default_encoding)
2877
if starting_with is not None:
2878
suite = filter_suite_by_id_startswith(suite, starting_with)
2880
if keep_only is not None:
2881
# Now that the referred modules have loaded their tests, keep only the
2883
suite = filter_suite_by_id_list(suite, id_filter)
2884
# Do some sanity checks on the id_list filtering
2885
not_found, duplicates = suite_matches_id_list(suite, keep_only)
2886
if starting_with is not None:
2887
# The tester has used both keep_only and starting_with, so he is
2888
# already aware that some tests are excluded from the list, there
2889
# is no need to tell him which.
2892
# Some tests mentioned in the list are not in the test suite. The
2893
# list may be out of date, report to the tester.
2894
for id in not_found:
2895
bzrlib.trace.warning('"%s" not found in the test suite', id)
2896
for id in duplicates:
2897
bzrlib.trace.warning('"%s" is used as an id by several tests', id)
2843
def multiply_tests_from_modules(module_name_list, scenario_iter):
2902
def multiply_tests_from_modules(module_name_list, scenario_iter, loader=None):
2844
2903
"""Adapt all tests in some given modules to given scenarios.
2846
2905
This is the recommended public interface for test parameterization.