208
194
def startTest(self, test):
209
195
unittest.TestResult.startTest(self, test)
210
196
self.report_test_start(test)
197
test.number = self.count
211
198
self._recordTestStartTime()
213
200
def _recordTestStartTime(self):
214
201
"""Record that a test has started."""
215
202
self._start_time = time.time()
204
def _cleanupLogFile(self, test):
205
# We can only do this if we have one of our TestCases, not if
207
setKeepLogfile = getattr(test, 'setKeepLogfile', None)
208
if setKeepLogfile is not None:
217
211
def addError(self, test, err):
212
"""Tell result that test finished with an error.
214
Called from the TestCase run() method when the test
215
fails with an unexpected error.
217
self._testConcluded(test)
218
218
if isinstance(err[1], TestSkipped):
219
return self.addSkipped(test, err)
220
unittest.TestResult.addError(self, test, err)
221
# We can only do this if we have one of our TestCases, not if
223
setKeepLogfile = getattr(test, 'setKeepLogfile', None)
224
if setKeepLogfile is not None:
226
self.extractBenchmarkTime(test)
227
self.report_error(test, err)
219
return self._addSkipped(test, err)
220
elif isinstance(err[1], UnavailableFeature):
221
return self.addNotSupported(test, err[1].args[0])
223
unittest.TestResult.addError(self, test, err)
224
self.error_count += 1
225
self.report_error(test, err)
228
self._cleanupLogFile(test)
231
230
def addFailure(self, test, err):
232
unittest.TestResult.addFailure(self, test, err)
233
# We can only do this if we have one of our TestCases, not if
235
setKeepLogfile = getattr(test, 'setKeepLogfile', None)
236
if setKeepLogfile is not None:
238
self.extractBenchmarkTime(test)
239
self.report_failure(test, err)
231
"""Tell result that test failed.
233
Called from the TestCase run() method when the test
234
fails because e.g. an assert() method failed.
236
self._testConcluded(test)
237
if isinstance(err[1], KnownFailure):
238
return self._addKnownFailure(test, err)
240
unittest.TestResult.addFailure(self, test, err)
241
self.failure_count += 1
242
self.report_failure(test, err)
245
self._cleanupLogFile(test)
243
247
def addSuccess(self, test):
244
self.extractBenchmarkTime(test)
248
"""Tell result that test completed successfully.
250
Called from the TestCase run()
252
self._testConcluded(test)
245
253
if self._bench_history is not None:
246
if self._benchmarkTime is not None:
254
benchmark_time = self._extractBenchmarkTime(test)
255
if benchmark_time is not None:
247
256
self._bench_history.write("%s %s\n" % (
248
self._formatTime(self._benchmarkTime),
257
self._formatTime(benchmark_time),
250
259
self.report_success(test)
260
self._cleanupLogFile(test)
251
261
unittest.TestResult.addSuccess(self, test)
253
def addSkipped(self, test, skip_excinfo):
254
self.extractBenchmarkTime(test)
255
self.report_skip(test, skip_excinfo)
256
# seems best to treat this as success from point-of-view of unittest
257
# -- it actually does nothing so it barely matters :)
262
test._log_contents = ''
264
def _testConcluded(self, test):
265
"""Common code when a test has finished.
267
Called regardless of whether it succeded, failed, etc.
271
def _addKnownFailure(self, test, err):
272
self.known_failure_count += 1
273
self.report_known_failure(test, err)
275
def addNotSupported(self, test, feature):
276
"""The test will not be run because of a missing feature.
278
# this can be called in two different ways: it may be that the
279
# test started running, and then raised (through addError)
280
# UnavailableFeature. Alternatively this method can be called
281
# while probing for features before running the tests; in that
282
# case we will see startTest and stopTest, but the test will never
284
self.unsupported.setdefault(str(feature), 0)
285
self.unsupported[str(feature)] += 1
286
self.report_unsupported(test, feature)
288
def _addSkipped(self, test, skip_excinfo):
289
if isinstance(skip_excinfo[1], TestNotApplicable):
290
self.not_applicable_count += 1
291
self.report_not_applicable(test, skip_excinfo)
294
self.report_skip(test, skip_excinfo)
260
297
except KeyboardInterrupt:
263
self.addError(test, test.__exc_info())
300
self.addError(test, test._exc_info())
302
# seems best to treat this as success from point-of-view of unittest
303
# -- it actually does nothing so it barely matters :)
265
304
unittest.TestResult.addSuccess(self, test)
305
test._log_contents = ''
267
307
def printErrorList(self, flavour, errors):
268
308
for test, err in errors:
269
309
self.stream.writeln(self.separator1)
270
self.stream.writeln("%s: %s" % (flavour, self.getDescription(test)))
310
self.stream.write("%s: " % flavour)
311
self.stream.writeln(self.getDescription(test))
271
312
if getattr(test, '_get_log', None) is not None:
273
print >>self.stream, \
274
('vvvv[log from %s]' % test.id()).ljust(78,'-')
275
print >>self.stream, test._get_log()
276
print >>self.stream, \
277
('^^^^[log from %s]' % test.id()).ljust(78,'-')
313
self.stream.write('\n')
315
('vvvv[log from %s]' % test.id()).ljust(78,'-'))
316
self.stream.write('\n')
317
self.stream.write(test._get_log())
318
self.stream.write('\n')
320
('^^^^[log from %s]' % test.id()).ljust(78,'-'))
321
self.stream.write('\n')
278
322
self.stream.writeln(self.separator2)
279
323
self.stream.writeln("%s" % err)
1674
2286
def setUp(self):
1675
2287
super(ChrootedTestCase, self).setUp()
1676
if not self.transport_server == MemoryServer:
2288
if not self.vfs_transport_factory == MemoryServer:
1677
2289
self.transport_readonly_server = HttpServer
2292
def condition_id_re(pattern):
2293
"""Create a condition filter which performs a re check on a test's id.
2295
:param pattern: A regular expression string.
2296
:return: A callable that returns True if the re matches.
2298
filter_re = re.compile(pattern)
2299
def condition(test):
2301
return filter_re.search(test_id)
2305
def condition_isinstance(klass_or_klass_list):
2306
"""Create a condition filter which returns isinstance(param, klass).
2308
:return: A callable which when called with one parameter obj return the
2309
result of isinstance(obj, klass_or_klass_list).
2312
return isinstance(obj, klass_or_klass_list)
2316
def condition_id_in_list(id_list):
2317
"""Create a condition filter which verify that test's id in a list.
2319
:param id_list: A TestIdList object.
2320
:return: A callable that returns True if the test's id appears in the list.
2322
def condition(test):
2323
return id_list.includes(test.id())
2327
def condition_id_startswith(starts):
2328
"""Create a condition filter verifying that test's id starts with a string.
2330
:param starts: A list of string.
2331
:return: A callable that returns True if the test's id starts with one of
2334
def condition(test):
2335
for start in starts:
2336
if test.id().startswith(start):
2342
def exclude_tests_by_condition(suite, condition):
2343
"""Create a test suite which excludes some tests from suite.
2345
:param suite: The suite to get tests from.
2346
:param condition: A callable whose result evaluates True when called with a
2347
test case which should be excluded from the result.
2348
:return: A suite which contains the tests found in suite that fail
2352
for test in iter_suite_tests(suite):
2353
if not condition(test):
2355
return TestUtil.TestSuite(result)
2358
def filter_suite_by_condition(suite, condition):
2359
"""Create a test suite by filtering another one.
2361
:param suite: The source suite.
2362
:param condition: A callable whose result evaluates True when called with a
2363
test case which should be included in the result.
2364
:return: A suite which contains the tests found in suite that pass
2368
for test in iter_suite_tests(suite):
2371
return TestUtil.TestSuite(result)
1680
2374
def filter_suite_by_re(suite, pattern):
1681
result = TestUtil.TestSuite()
1682
filter_re = re.compile(pattern)
1683
for test in iter_suite_tests(suite):
1684
if filter_re.search(test.id()):
1685
result.addTest(test)
1689
def sort_suite_by_re(suite, pattern):
1692
filter_re = re.compile(pattern)
1693
for test in iter_suite_tests(suite):
1694
if filter_re.search(test.id()):
2375
"""Create a test suite by filtering another one.
2377
:param suite: the source suite
2378
:param pattern: pattern that names must match
2379
:returns: the newly created suite
2381
condition = condition_id_re(pattern)
2382
result_suite = filter_suite_by_condition(suite, condition)
2386
def filter_suite_by_id_list(suite, test_id_list):
2387
"""Create a test suite by filtering another one.
2389
:param suite: The source suite.
2390
:param test_id_list: A list of the test ids to keep as strings.
2391
:returns: the newly created suite
2393
condition = condition_id_in_list(test_id_list)
2394
result_suite = filter_suite_by_condition(suite, condition)
2398
def filter_suite_by_id_startswith(suite, start):
2399
"""Create a test suite by filtering another one.
2401
:param suite: The source suite.
2402
:param start: A list of string the test id must start with one of.
2403
:returns: the newly created suite
2405
condition = condition_id_startswith(start)
2406
result_suite = filter_suite_by_condition(suite, condition)
2410
def exclude_tests_by_re(suite, pattern):
2411
"""Create a test suite which excludes some tests from suite.
2413
:param suite: The suite to get tests from.
2414
:param pattern: A regular expression string. Test ids that match this
2415
pattern will be excluded from the result.
2416
:return: A TestSuite that contains all the tests from suite without the
2417
tests that matched pattern. The order of tests is the same as it was in
2420
return exclude_tests_by_condition(suite, condition_id_re(pattern))
2423
def preserve_input(something):
2424
"""A helper for performing test suite transformation chains.
2426
:param something: Anything you want to preserve.
2432
def randomize_suite(suite):
2433
"""Return a new TestSuite with suite's tests in random order.
2435
The tests in the input suite are flattened into a single suite in order to
2436
accomplish this. Any nested TestSuites are removed to provide global
2439
tests = list(iter_suite_tests(suite))
2440
random.shuffle(tests)
2441
return TestUtil.TestSuite(tests)
2444
def split_suite_by_condition(suite, condition):
2445
"""Split a test suite into two by a condition.
2447
:param suite: The suite to split.
2448
:param condition: The condition to match on. Tests that match this
2449
condition are returned in the first test suite, ones that do not match
2450
are in the second suite.
2451
:return: A tuple of two test suites, where the first contains tests from
2452
suite matching the condition, and the second contains the remainder
2453
from suite. The order within each output suite is the same as it was in
2458
for test in iter_suite_tests(suite):
2460
matched.append(test)
1698
return TestUtil.TestSuite(first + second)
2462
did_not_match.append(test)
2463
return TestUtil.TestSuite(matched), TestUtil.TestSuite(did_not_match)
2466
def split_suite_by_re(suite, pattern):
2467
"""Split a test suite into two by a regular expression.
2469
:param suite: The suite to split.
2470
:param pattern: A regular expression string. Test ids that match this
2471
pattern will be in the first test suite returned, and the others in the
2472
second test suite returned.
2473
:return: A tuple of two test suites, where the first contains tests from
2474
suite matching pattern, and the second contains the remainder from
2475
suite. The order within each output suite is the same as it was in
2478
return split_suite_by_condition(suite, condition_id_re(pattern))
1701
2481
def run_suite(suite, name='test', verbose=False, pattern=".*",
1702
stop_on_failure=False, keep_output=False,
2482
stop_on_failure=False,
1703
2483
transport=None, lsprof_timed=None, bench_history=None,
1704
matching_tests_first=None):
2484
matching_tests_first=None,
2487
exclude_pattern=None,
1705
2489
TestCase._gather_lsprof_in_benchmarks = lsprof_timed
1741
2566
transport = default_transport
1742
2567
old_transport = default_transport
1743
2568
default_transport = transport
2569
global selftest_debug_flags
2570
old_debug_flags = selftest_debug_flags
2571
if debug_flags is not None:
2572
selftest_debug_flags = set(debug_flags)
2574
if load_list is None:
2577
keep_only = load_test_id_list(load_list)
1745
2578
if test_suite_factory is None:
1746
suite = test_suite()
2579
suite = test_suite(keep_only, starting_with)
1748
2581
suite = test_suite_factory()
1749
2582
return run_suite(suite, 'testbzr', verbose=verbose, pattern=pattern,
1750
stop_on_failure=stop_on_failure, keep_output=keep_output,
2583
stop_on_failure=stop_on_failure,
1751
2584
transport=transport,
1752
2585
lsprof_timed=lsprof_timed,
1753
2586
bench_history=bench_history,
1754
matching_tests_first=matching_tests_first)
2587
matching_tests_first=matching_tests_first,
2588
list_only=list_only,
2589
random_seed=random_seed,
2590
exclude_pattern=exclude_pattern,
1756
2593
default_transport = old_transport
2594
selftest_debug_flags = old_debug_flags
2597
def load_test_id_list(file_name):
2598
"""Load a test id list from a text file.
2600
The format is one test id by line. No special care is taken to impose
2601
strict rules, these test ids are used to filter the test suite so a test id
2602
that do not match an existing test will do no harm. This allows user to add
2603
comments, leave blank lines, etc.
2607
ftest = open(file_name, 'rt')
2609
if e.errno != errno.ENOENT:
2612
raise errors.NoSuchFile(file_name)
2614
for test_name in ftest.readlines():
2615
test_list.append(test_name.strip())
2620
def suite_matches_id_list(test_suite, id_list):
2621
"""Warns about tests not appearing or appearing more than once.
2623
:param test_suite: A TestSuite object.
2624
:param test_id_list: The list of test ids that should be found in
2627
:return: (absents, duplicates) absents is a list containing the test found
2628
in id_list but not in test_suite, duplicates is a list containing the
2629
test found multiple times in test_suite.
2631
When using a prefined test id list, it may occurs that some tests do not
2632
exist anymore or that some tests use the same id. This function warns the
2633
tester about potential problems in his workflow (test lists are volatile)
2634
or in the test suite itself (using the same id for several tests does not
2635
help to localize defects).
2637
# Build a dict counting id occurrences
2639
for test in iter_suite_tests(test_suite):
2641
tests[id] = tests.get(id, 0) + 1
2646
occurs = tests.get(id, 0)
2648
not_found.append(id)
2650
duplicates.append(id)
2652
return not_found, duplicates
2655
class TestIdList(object):
2656
"""Test id list to filter a test suite.
2658
Relying on the assumption that test ids are built as:
2659
<module>[.<class>.<method>][(<param>+)], <module> being in python dotted
2660
notation, this class offers methods to :
2661
- avoid building a test suite for modules not refered to in the test list,
2662
- keep only the tests listed from the module test suite.
2665
def __init__(self, test_id_list):
2666
# When a test suite needs to be filtered against us we compare test ids
2667
# for equality, so a simple dict offers a quick and simple solution.
2668
self.tests = dict().fromkeys(test_id_list, True)
2670
# While unittest.TestCase have ids like:
2671
# <module>.<class>.<method>[(<param+)],
2672
# doctest.DocTestCase can have ids like:
2675
# <module>.<function>
2676
# <module>.<class>.<method>
2678
# Since we can't predict a test class from its name only, we settle on
2679
# a simple constraint: a test id always begins with its module name.
2682
for test_id in test_id_list:
2683
parts = test_id.split('.')
2684
mod_name = parts.pop(0)
2685
modules[mod_name] = True
2687
mod_name += '.' + part
2688
modules[mod_name] = True
2689
self.modules = modules
2691
def refers_to(self, module_name):
2692
"""Is there tests for the module or one of its sub modules."""
2693
return self.modules.has_key(module_name)
2695
def includes(self, test_id):
2696
return self.tests.has_key(test_id)
2699
class TestPrefixAliasRegistry(registry.Registry):
2700
"""A registry for test prefix aliases.
2702
This helps implement shorcuts for the --starting-with selftest
2703
option. Overriding existing prefixes is not allowed but not fatal (a
2704
warning will be emitted).
2707
def register(self, key, obj, help=None, info=None,
2708
override_existing=False):
2709
"""See Registry.register.
2711
Trying to override an existing alias causes a warning to be emitted,
2712
not a fatal execption.
2715
super(TestPrefixAliasRegistry, self).register(
2716
key, obj, help=help, info=info, override_existing=False)
2718
actual = self.get(key)
2719
note('Test prefix alias %s is already used for %s, ignoring %s'
2720
% (key, actual, obj))
2722
def resolve_alias(self, id_start):
2723
"""Replace the alias by the prefix in the given string.
2725
Using an unknown prefix is an error to help catching typos.
2727
parts = id_start.split('.')
2729
parts[0] = self.get(parts[0])
2731
raise errors.BzrCommandError(
2732
'%s is not a known test prefix alias' % parts[0])
2733
return '.'.join(parts)
2736
test_prefix_alias_registry = TestPrefixAliasRegistry()
2737
"""Registry of test prefix aliases."""
2740
# This alias allows to detect typos ('bzrlin.') by making all valid test ids
2741
# appear prefixed ('bzrlib.' is "replaced" by 'bzrlib.').
2742
test_prefix_alias_registry.register('bzrlib', 'bzrlib')
2744
# Obvious higest levels prefixes, feel free to add your own via a plugin
2745
test_prefix_alias_registry.register('bd', 'bzrlib.doc')
2746
test_prefix_alias_registry.register('bu', 'bzrlib.utils')
2747
test_prefix_alias_registry.register('bt', 'bzrlib.tests')
2748
test_prefix_alias_registry.register('bb', 'bzrlib.tests.blackbox')
2749
test_prefix_alias_registry.register('bp', 'bzrlib.plugins')
2752
def test_suite(keep_only=None, starting_with=None):
1760
2753
"""Build and return TestSuite for the whole of bzrlib.
2755
:param keep_only: A list of test ids limiting the suite returned.
2757
:param starting_with: An id limiting the suite returned to the tests
1762
2760
This function can be replaced if you need to change the default test
1763
2761
suite on a global basis, but it is not encouraged.
1765
2763
testmod_names = [
2765
'bzrlib.tests.blackbox',
2766
'bzrlib.tests.branch_implementations',
2767
'bzrlib.tests.bzrdir_implementations',
2768
'bzrlib.tests.commands',
2769
'bzrlib.tests.interrepository_implementations',
2770
'bzrlib.tests.intertree_implementations',
2771
'bzrlib.tests.inventory_implementations',
2772
'bzrlib.tests.per_lock',
2773
'bzrlib.tests.per_repository',
2774
'bzrlib.tests.per_repository_reference',
2775
'bzrlib.tests.test__dirstate_helpers',
2776
'bzrlib.tests.test__walkdirs_win32',
1766
2777
'bzrlib.tests.test_ancestry',
1767
2778
'bzrlib.tests.test_annotate',
1768
2779
'bzrlib.tests.test_api',
1769
2780
'bzrlib.tests.test_atomicfile',
1770
2781
'bzrlib.tests.test_bad_files',
2782
'bzrlib.tests.test_bisect_multi',
1771
2783
'bzrlib.tests.test_branch',
2784
'bzrlib.tests.test_branchbuilder',
2785
'bzrlib.tests.test_btree_index',
2786
'bzrlib.tests.test_bugtracker',
1772
2787
'bzrlib.tests.test_bundle',
1773
2788
'bzrlib.tests.test_bzrdir',
1774
2789
'bzrlib.tests.test_cache_utf8',
2790
'bzrlib.tests.test_chunk_writer',
2791
'bzrlib.tests.test__chunks_to_lines',
1775
2792
'bzrlib.tests.test_commands',
1776
2793
'bzrlib.tests.test_commit',
1777
2794
'bzrlib.tests.test_commit_merge',
1778
2795
'bzrlib.tests.test_config',
1779
2796
'bzrlib.tests.test_conflicts',
2797
'bzrlib.tests.test_counted_lock',
1780
2798
'bzrlib.tests.test_decorators',
1781
2799
'bzrlib.tests.test_delta',
2800
'bzrlib.tests.test_deprecated_graph',
1782
2801
'bzrlib.tests.test_diff',
2802
'bzrlib.tests.test_directory_service',
1783
2803
'bzrlib.tests.test_dirstate',
1784
'bzrlib.tests.test_doc_generate',
2804
'bzrlib.tests.test_email_message',
1785
2805
'bzrlib.tests.test_errors',
1786
'bzrlib.tests.test_escaped_store',
2806
'bzrlib.tests.test_extract',
1787
2807
'bzrlib.tests.test_fetch',
2808
'bzrlib.tests.test_fifo_cache',
1788
2809
'bzrlib.tests.test_ftp_transport',
2810
'bzrlib.tests.test_foreign',
1789
2811
'bzrlib.tests.test_generate_docs',
1790
2812
'bzrlib.tests.test_generate_ids',
1791
2813
'bzrlib.tests.test_globbing',
1792
2814
'bzrlib.tests.test_gpg',
1793
2815
'bzrlib.tests.test_graph',
1794
2816
'bzrlib.tests.test_hashcache',
2817
'bzrlib.tests.test_help',
2818
'bzrlib.tests.test_hooks',
1795
2819
'bzrlib.tests.test_http',
2820
'bzrlib.tests.test_http_implementations',
1796
2821
'bzrlib.tests.test_http_response',
2822
'bzrlib.tests.test_https_ca_bundle',
1797
2823
'bzrlib.tests.test_identitymap',
1798
2824
'bzrlib.tests.test_ignores',
2825
'bzrlib.tests.test_index',
2826
'bzrlib.tests.test_info',
1799
2827
'bzrlib.tests.test_inv',
1800
2828
'bzrlib.tests.test_knit',
1801
2829
'bzrlib.tests.test_lazy_import',
1802
2830
'bzrlib.tests.test_lazy_regex',
2831
'bzrlib.tests.test_lockable_files',
1803
2832
'bzrlib.tests.test_lockdir',
1804
'bzrlib.tests.test_lockable_files',
1805
2833
'bzrlib.tests.test_log',
2834
'bzrlib.tests.test_lru_cache',
2835
'bzrlib.tests.test_lsprof',
2836
'bzrlib.tests.test_mail_client',
1806
2837
'bzrlib.tests.test_memorytree',
1807
2838
'bzrlib.tests.test_merge',
1808
2839
'bzrlib.tests.test_merge3',
1809
2840
'bzrlib.tests.test_merge_core',
2841
'bzrlib.tests.test_merge_directive',
1810
2842
'bzrlib.tests.test_missing',
1811
2843
'bzrlib.tests.test_msgeditor',
2844
'bzrlib.tests.test_multiparent',
2845
'bzrlib.tests.test_mutabletree',
1812
2846
'bzrlib.tests.test_nonascii',
1813
2847
'bzrlib.tests.test_options',
1814
2848
'bzrlib.tests.test_osutils',
1815
2849
'bzrlib.tests.test_osutils_encodings',
2850
'bzrlib.tests.test_pack',
2851
'bzrlib.tests.test_pack_repository',
1816
2852
'bzrlib.tests.test_patch',
1817
2853
'bzrlib.tests.test_patches',
1818
2854
'bzrlib.tests.test_permissions',
1819
2855
'bzrlib.tests.test_plugins',
1820
2856
'bzrlib.tests.test_progress',
2857
'bzrlib.tests.test_read_bundle',
1821
2858
'bzrlib.tests.test_reconcile',
2859
'bzrlib.tests.test_reconfigure',
1822
2860
'bzrlib.tests.test_registry',
2861
'bzrlib.tests.test_remote',
1823
2862
'bzrlib.tests.test_repository',
1824
2863
'bzrlib.tests.test_revert',
1825
2864
'bzrlib.tests.test_revision',
1826
'bzrlib.tests.test_revisionnamespaces',
2865
'bzrlib.tests.test_revisionspec',
1827
2866
'bzrlib.tests.test_revisiontree',
1828
2867
'bzrlib.tests.test_rio',
2868
'bzrlib.tests.test_rules',
1829
2869
'bzrlib.tests.test_sampler',
1830
2870
'bzrlib.tests.test_selftest',
1831
2871
'bzrlib.tests.test_setup',
1832
2872
'bzrlib.tests.test_sftp_transport',
2873
'bzrlib.tests.test_shelf',
2874
'bzrlib.tests.test_shelf_ui',
2875
'bzrlib.tests.test_smart',
1833
2876
'bzrlib.tests.test_smart_add',
1834
2877
'bzrlib.tests.test_smart_transport',
2878
'bzrlib.tests.test_smtp_connection',
1835
2879
'bzrlib.tests.test_source',
2880
'bzrlib.tests.test_ssh_transport',
1836
2881
'bzrlib.tests.test_status',
1837
2882
'bzrlib.tests.test_store',
2883
'bzrlib.tests.test_strace',
2884
'bzrlib.tests.test_subsume',
2885
'bzrlib.tests.test_switch',
1838
2886
'bzrlib.tests.test_symbol_versioning',
2887
'bzrlib.tests.test_tag',
1839
2888
'bzrlib.tests.test_testament',
1840
2889
'bzrlib.tests.test_textfile',
1841
2890
'bzrlib.tests.test_textmerge',
2891
'bzrlib.tests.test_timestamp',
1842
2892
'bzrlib.tests.test_trace',
1843
2893
'bzrlib.tests.test_transactions',
1844
2894
'bzrlib.tests.test_transform',
1845
2895
'bzrlib.tests.test_transport',
2896
'bzrlib.tests.test_transport_implementations',
2897
'bzrlib.tests.test_transport_log',
1846
2898
'bzrlib.tests.test_tree',
1847
2899
'bzrlib.tests.test_treebuilder',
1848
2900
'bzrlib.tests.test_tsort',
1849
2901
'bzrlib.tests.test_tuned_gzip',
1850
2902
'bzrlib.tests.test_ui',
2903
'bzrlib.tests.test_uncommit',
1851
2904
'bzrlib.tests.test_upgrade',
2905
'bzrlib.tests.test_upgrade_stacked',
1852
2906
'bzrlib.tests.test_urlutils',
1853
'bzrlib.tests.test_versionedfile',
1854
2907
'bzrlib.tests.test_version',
1855
2908
'bzrlib.tests.test_version_info',
2909
'bzrlib.tests.test_versionedfile',
1856
2910
'bzrlib.tests.test_weave',
1857
2911
'bzrlib.tests.test_whitebox',
2912
'bzrlib.tests.test_win32utils',
1858
2913
'bzrlib.tests.test_workingtree',
1859
2914
'bzrlib.tests.test_workingtree_4',
1860
2915
'bzrlib.tests.test_wsgi',
1861
2916
'bzrlib.tests.test_xml',
2917
'bzrlib.tests.tree_implementations',
2918
'bzrlib.tests.workingtree_implementations',
2919
'bzrlib.util.tests.test_bencode',
1863
test_transport_implementations = [
1864
'bzrlib.tests.test_transport_implementations',
1865
'bzrlib.tests.test_read_bundle',
1867
suite = TestUtil.TestSuite()
1868
2922
loader = TestUtil.TestLoader()
2925
starting_with = [test_prefix_alias_registry.resolve_alias(start)
2926
for start in starting_with]
2927
# We take precedence over keep_only because *at loading time* using
2928
# both options means we will load less tests for the same final result.
2929
def interesting_module(name):
2930
for start in starting_with:
2932
# Either the module name starts with the specified string
2933
name.startswith(start)
2934
# or it may contain tests starting with the specified string
2935
or start.startswith(name)
2939
loader = TestUtil.FilteredByModuleTestLoader(interesting_module)
2941
elif keep_only is not None:
2942
id_filter = TestIdList(keep_only)
2943
loader = TestUtil.FilteredByModuleTestLoader(id_filter.refers_to)
2944
def interesting_module(name):
2945
return id_filter.refers_to(name)
2948
loader = TestUtil.TestLoader()
2949
def interesting_module(name):
2950
# No filtering, all modules are interesting
2953
suite = loader.suiteClass()
2955
# modules building their suite with loadTestsFromModuleNames
1869
2956
suite.addTest(loader.loadTestsFromModuleNames(testmod_names))
1870
from bzrlib.transport import TransportTestProviderAdapter
1871
adapter = TransportTestProviderAdapter()
1872
adapt_modules(test_transport_implementations, adapter, loader, suite)
1873
for package in packages_to_test():
1874
suite.addTest(package.test_suite())
1875
for m in MODULES_TO_TEST:
1876
suite.addTest(loader.loadTestsFromModule(m))
1877
for m in MODULES_TO_DOCTEST:
2958
modules_to_doctest = [
2960
'bzrlib.branchbuilder',
2963
'bzrlib.iterablefile',
2967
'bzrlib.symbol_versioning',
2970
'bzrlib.version_info_formats.format_custom',
2973
for mod in modules_to_doctest:
2974
if not interesting_module(mod):
2975
# No tests to keep here, move along
1879
suite.addTest(doctest.DocTestSuite(m))
2978
# note that this really does mean "report only" -- doctest
2979
# still runs the rest of the examples
2980
doc_suite = doctest.DocTestSuite(mod,
2981
optionflags=doctest.REPORT_ONLY_FIRST_FAILURE)
1880
2982
except ValueError, e:
1881
print '**failed to get doctest for: %s\n%s' %(m,e)
2983
print '**failed to get doctest for: %s\n%s' % (mod, e)
1883
for name, plugin in bzrlib.plugin.all_plugins().items():
1884
if getattr(plugin, 'test_suite', None) is not None:
1885
default_encoding = sys.getdefaultencoding()
1887
plugin_suite = plugin.test_suite()
1888
except ImportError, e:
1889
bzrlib.trace.warning(
1890
'Unable to test plugin "%s": %s', name, e)
1892
suite.addTest(plugin_suite)
1893
if default_encoding != sys.getdefaultencoding():
1894
bzrlib.trace.warning(
1895
'Plugin "%s" tried to reset default encoding to: %s', name,
1896
sys.getdefaultencoding())
1898
sys.setdefaultencoding(default_encoding)
2985
if len(doc_suite._tests) == 0:
2986
raise errors.BzrError("no doctests found in %s" % (mod,))
2987
suite.addTest(doc_suite)
2989
default_encoding = sys.getdefaultencoding()
2990
for name, plugin in bzrlib.plugin.plugins().items():
2991
if not interesting_module(plugin.module.__name__):
2993
plugin_suite = plugin.test_suite()
2994
# We used to catch ImportError here and turn it into just a warning,
2995
# but really if you don't have --no-plugins this should be a failure.
2996
# mbp 20080213 - see http://bugs.launchpad.net/bugs/189771
2997
if plugin_suite is None:
2998
plugin_suite = plugin.load_plugin_tests(loader)
2999
if plugin_suite is not None:
3000
suite.addTest(plugin_suite)
3001
if default_encoding != sys.getdefaultencoding():
3002
bzrlib.trace.warning(
3003
'Plugin "%s" tried to reset default encoding to: %s', name,
3004
sys.getdefaultencoding())
3006
sys.setdefaultencoding(default_encoding)
3009
suite = filter_suite_by_id_startswith(suite, starting_with)
3011
if keep_only is not None:
3012
# Now that the referred modules have loaded their tests, keep only the
3014
suite = filter_suite_by_id_list(suite, id_filter)
3015
# Do some sanity checks on the id_list filtering
3016
not_found, duplicates = suite_matches_id_list(suite, keep_only)
3018
# The tester has used both keep_only and starting_with, so he is
3019
# already aware that some tests are excluded from the list, there
3020
# is no need to tell him which.
3023
# Some tests mentioned in the list are not in the test suite. The
3024
# list may be out of date, report to the tester.
3025
for id in not_found:
3026
bzrlib.trace.warning('"%s" not found in the test suite', id)
3027
for id in duplicates:
3028
bzrlib.trace.warning('"%s" is used as an id by several tests', id)
3033
def multiply_tests_from_modules(module_name_list, scenario_iter, loader=None):
3034
"""Adapt all tests in some given modules to given scenarios.
3036
This is the recommended public interface for test parameterization.
3037
Typically the test_suite() method for a per-implementation test
3038
suite will call multiply_tests_from_modules and return the
3041
:param module_name_list: List of fully-qualified names of test
3043
:param scenario_iter: Iterable of pairs of (scenario_name,
3044
scenario_param_dict).
3045
:param loader: If provided, will be used instead of a new
3046
bzrlib.tests.TestLoader() instance.
3048
This returns a new TestSuite containing the cross product of
3049
all the tests in all the modules, each repeated for each scenario.
3050
Each test is adapted by adding the scenario name at the end
3051
of its name, and updating the test object's __dict__ with the
3052
scenario_param_dict.
3054
>>> r = multiply_tests_from_modules(
3055
... ['bzrlib.tests.test_sampler'],
3056
... [('one', dict(param=1)),
3057
... ('two', dict(param=2))])
3058
>>> tests = list(iter_suite_tests(r))
3062
'bzrlib.tests.test_sampler.DemoTest.test_nothing(one)'
3068
# XXX: Isn't load_tests() a better way to provide the same functionality
3069
# without forcing a predefined TestScenarioApplier ? --vila 080215
3071
loader = TestUtil.TestLoader()
3073
suite = loader.suiteClass()
3075
adapter = TestScenarioApplier()
3076
adapter.scenarios = list(scenario_iter)
3077
adapt_modules(module_name_list, adapter, loader, suite)
3081
def multiply_scenarios(scenarios_left, scenarios_right):
3082
"""Multiply two sets of scenarios.
3084
:returns: the cartesian product of the two sets of scenarios, that is
3085
a scenario for every possible combination of a left scenario and a
3089
('%s,%s' % (left_name, right_name),
3090
dict(left_dict.items() + right_dict.items()))
3091
for left_name, left_dict in scenarios_left
3092
for right_name, right_dict in scenarios_right]
1902
3096
def adapt_modules(mods_list, adapter, loader, suite):
1903
3097
"""Adapt the modules in mods_list using adapter and add to suite."""
1904
for test in iter_suite_tests(loader.loadTestsFromModuleNames(mods_list)):
3098
tests = loader.loadTestsFromModuleNames(mods_list)
3099
adapt_tests(tests, adapter, suite)
3102
def adapt_tests(tests_list, adapter, suite):
3103
"""Adapt the tests in tests_list using adapter and add to suite."""
3104
for test in iter_suite_tests(tests_list):
1905
3105
suite.addTests(adapter.adapt(test))
1908
def clean_selftest_output(root=None, quiet=False):
1909
"""Remove all selftest output directories from root directory.
1911
:param root: root directory for clean
1912
(if ommitted or None then clean current directory).
1913
:param quiet: suppress report about deleting directories
1918
re_dir = re.compile(r'''test\d\d\d\d\.tmp''')
1921
for i in os.listdir(root):
1922
if os.path.isdir(i) and re_dir.match(i):
1924
print 'delete directory:', i
3108
def _rmtree_temp_dir(dirname):
3109
# If LANG=C we probably have created some bogus paths
3110
# which rmtree(unicode) will fail to delete
3111
# so make sure we are using rmtree(str) to delete everything
3112
# except on win32, where rmtree(str) will fail
3113
# since it doesn't have the property of byte-stream paths
3114
# (they are either ascii or mbcs)
3115
if sys.platform == 'win32':
3116
# make sure we are using the unicode win32 api
3117
dirname = unicode(dirname)
3119
dirname = dirname.encode(sys.getfilesystemencoding())
3121
osutils.rmtree(dirname)
3123
if sys.platform == 'win32' and e.errno == errno.EACCES:
3124
sys.stderr.write(('Permission denied: '
3125
'unable to remove testing dir '
3126
'%s\n' % os.path.basename(dirname)))
3131
class Feature(object):
3132
"""An operating system Feature."""
3135
self._available = None
3137
def available(self):
3138
"""Is the feature available?
3140
:return: True if the feature is available.
3142
if self._available is None:
3143
self._available = self._probe()
3144
return self._available
3147
"""Implement this method in concrete features.
3149
:return: True if the feature is available.
3151
raise NotImplementedError
3154
if getattr(self, 'feature_name', None):
3155
return self.feature_name()
3156
return self.__class__.__name__
3159
class _SymlinkFeature(Feature):
3162
return osutils.has_symlinks()
3164
def feature_name(self):
3167
SymlinkFeature = _SymlinkFeature()
3170
class _HardlinkFeature(Feature):
3173
return osutils.has_hardlinks()
3175
def feature_name(self):
3178
HardlinkFeature = _HardlinkFeature()
3181
class _OsFifoFeature(Feature):
3184
return getattr(os, 'mkfifo', None)
3186
def feature_name(self):
3187
return 'filesystem fifos'
3189
OsFifoFeature = _OsFifoFeature()
3192
class _UnicodeFilenameFeature(Feature):
3193
"""Does the filesystem support Unicode filenames?"""
3197
# Check for character combinations unlikely to be covered by any
3198
# single non-unicode encoding. We use the characters
3199
# - greek small letter alpha (U+03B1) and
3200
# - braille pattern dots-123456 (U+283F).
3201
os.stat(u'\u03b1\u283f')
3202
except UnicodeEncodeError:
3204
except (IOError, OSError):
3205
# The filesystem allows the Unicode filename but the file doesn't
3209
# The filesystem allows the Unicode filename and the file exists,
3213
UnicodeFilenameFeature = _UnicodeFilenameFeature()
3216
class TestScenarioApplier(object):
3217
"""A tool to apply scenarios to tests."""
3219
def adapt(self, test):
3220
"""Return a TestSuite containing a copy of test for each scenario."""
3221
result = unittest.TestSuite()
3222
for scenario in self.scenarios:
3223
result.addTest(self.adapt_test_to_scenario(test, scenario))
3226
def adapt_test_to_scenario(self, test, scenario):
3227
"""Copy test and apply scenario to it.
3229
:param test: A test to adapt.
3230
:param scenario: A tuple describing the scenarion.
3231
The first element of the tuple is the new test id.
3232
The second element is a dict containing attributes to set on the
3234
:return: The adapted test.
3236
from copy import deepcopy
3237
new_test = deepcopy(test)
3238
for name, value in scenario[1].items():
3239
setattr(new_test, name, value)
3240
new_id = "%s(%s)" % (new_test.id(), scenario[0])
3241
new_test.id = lambda: new_id
3245
def probe_unicode_in_user_encoding():
3246
"""Try to encode several unicode strings to use in unicode-aware tests.
3247
Return first successfull match.
3249
:return: (unicode value, encoded plain string value) or (None, None)
3251
possible_vals = [u'm\xb5', u'\xe1', u'\u0410']
3252
for uni_val in possible_vals:
3254
str_val = uni_val.encode(osutils.get_user_encoding())
3255
except UnicodeEncodeError:
3256
# Try a different character
3259
return uni_val, str_val
3263
def probe_bad_non_ascii(encoding):
3264
"""Try to find [bad] character with code [128..255]
3265
that cannot be decoded to unicode in some encoding.
3266
Return None if all non-ascii characters is valid
3269
for i in xrange(128, 256):
3272
char.decode(encoding)
3273
except UnicodeDecodeError:
3278
class _FTPServerFeature(Feature):
3279
"""Some tests want an FTP Server, check if one is available.
3281
Right now, the only way this is available is if 'medusa' is installed.
3282
http://www.amk.ca/python/code/medusa.html
3287
import bzrlib.tests.ftp_server
3292
def feature_name(self):
3296
FTPServerFeature = _FTPServerFeature()
3299
class _HTTPSServerFeature(Feature):
3300
"""Some tests want an https Server, check if one is available.
3302
Right now, the only way this is available is under python2.6 which provides
3313
def feature_name(self):
3314
return 'HTTPSServer'
3317
HTTPSServerFeature = _HTTPSServerFeature()
3320
class _UnicodeFilename(Feature):
3321
"""Does the filesystem support Unicode filenames?"""
3326
except UnicodeEncodeError:
3328
except (IOError, OSError):
3329
# The filesystem allows the Unicode filename but the file doesn't
3333
# The filesystem allows the Unicode filename and the file exists,
3337
UnicodeFilename = _UnicodeFilename()
3340
class _UTF8Filesystem(Feature):
3341
"""Is the filesystem UTF-8?"""
3344
if osutils._fs_enc.upper() in ('UTF-8', 'UTF8'):
3348
UTF8Filesystem = _UTF8Filesystem()
3351
class _CaseInsCasePresFilenameFeature(Feature):
3352
"""Is the file-system case insensitive, but case-preserving?"""
3355
fileno, name = tempfile.mkstemp(prefix='MixedCase')
3357
# first check truly case-preserving for created files, then check
3358
# case insensitive when opening existing files.
3359
name = osutils.normpath(name)
3360
base, rel = osutils.split(name)
3361
found_rel = osutils.canonical_relpath(base, name)
3362
return (found_rel == rel
3363
and os.path.isfile(name.upper())
3364
and os.path.isfile(name.lower()))
3369
def feature_name(self):
3370
return "case-insensitive case-preserving filesystem"
3372
CaseInsCasePresFilenameFeature = _CaseInsCasePresFilenameFeature()
3375
class _CaseInsensitiveFilesystemFeature(Feature):
3376
"""Check if underlying filesystem is case-insensitive but *not* case
3379
# Note that on Windows, Cygwin, MacOS etc, the file-systems are far
3380
# more likely to be case preserving, so this case is rare.
3383
if CaseInsCasePresFilenameFeature.available():
3386
if TestCaseWithMemoryTransport.TEST_ROOT is None:
3387
root = osutils.mkdtemp(prefix='testbzr-', suffix='.tmp')
3388
TestCaseWithMemoryTransport.TEST_ROOT = root
3390
root = TestCaseWithMemoryTransport.TEST_ROOT
3391
tdir = osutils.mkdtemp(prefix='case-sensitive-probe-', suffix='',
3393
name_a = osutils.pathjoin(tdir, 'a')
3394
name_A = osutils.pathjoin(tdir, 'A')
3396
result = osutils.isdir(name_A)
3397
_rmtree_temp_dir(tdir)
3400
def feature_name(self):
3401
return 'case-insensitive filesystem'
3403
CaseInsensitiveFilesystemFeature = _CaseInsensitiveFilesystemFeature()