193
208
def startTest(self, test):
194
209
unittest.TestResult.startTest(self, test)
195
210
self.report_test_start(test)
196
test.number = self.count
197
211
self._recordTestStartTime()
199
213
def _recordTestStartTime(self):
200
214
"""Record that a test has started."""
201
215
self._start_time = time.time()
203
def _cleanupLogFile(self, test):
204
# We can only do this if we have one of our TestCases, not if
206
setKeepLogfile = getattr(test, 'setKeepLogfile', None)
207
if setKeepLogfile is not None:
210
217
def addError(self, test, err):
211
"""Tell result that test finished with an error.
213
Called from the TestCase run() method when the test
214
fails with an unexpected error.
216
self._testConcluded(test)
217
218
if isinstance(err[1], TestSkipped):
218
return self._addSkipped(test, err)
219
elif isinstance(err[1], UnavailableFeature):
220
return self.addNotSupported(test, err[1].args[0])
222
unittest.TestResult.addError(self, test, err)
223
self.error_count += 1
224
self.report_error(test, err)
227
self._cleanupLogFile(test)
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)
229
231
def addFailure(self, test, err):
230
"""Tell result that test failed.
232
Called from the TestCase run() method when the test
233
fails because e.g. an assert() method failed.
235
self._testConcluded(test)
236
if isinstance(err[1], KnownFailure):
237
return self._addKnownFailure(test, err)
239
unittest.TestResult.addFailure(self, test, err)
240
self.failure_count += 1
241
self.report_failure(test, err)
244
self._cleanupLogFile(test)
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)
246
243
def addSuccess(self, test):
247
"""Tell result that test completed successfully.
249
Called from the TestCase run()
251
self._testConcluded(test)
244
self.extractBenchmarkTime(test)
252
245
if self._bench_history is not None:
253
benchmark_time = self._extractBenchmarkTime(test)
254
if benchmark_time is not None:
246
if self._benchmarkTime is not None:
255
247
self._bench_history.write("%s %s\n" % (
256
self._formatTime(benchmark_time),
248
self._formatTime(self._benchmarkTime),
258
250
self.report_success(test)
259
self._cleanupLogFile(test)
260
251
unittest.TestResult.addSuccess(self, test)
261
test._log_contents = ''
263
def _testConcluded(self, test):
264
"""Common code when a test has finished.
266
Called regardless of whether it succeded, failed, etc.
270
def _addKnownFailure(self, test, err):
271
self.known_failure_count += 1
272
self.report_known_failure(test, err)
274
def addNotSupported(self, test, feature):
275
"""The test will not be run because of a missing feature.
277
# this can be called in two different ways: it may be that the
278
# test started running, and then raised (through addError)
279
# UnavailableFeature. Alternatively this method can be called
280
# while probing for features before running the tests; in that
281
# case we will see startTest and stopTest, but the test will never
283
self.unsupported.setdefault(str(feature), 0)
284
self.unsupported[str(feature)] += 1
285
self.report_unsupported(test, feature)
287
def _addSkipped(self, test, skip_excinfo):
288
if isinstance(skip_excinfo[1], TestNotApplicable):
289
self.not_applicable_count += 1
290
self.report_not_applicable(test, skip_excinfo)
293
self.report_skip(test, skip_excinfo)
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 :)
296
260
except KeyboardInterrupt:
299
self.addError(test, test._exc_info())
263
self.addError(test, test.__exc_info())
301
# seems best to treat this as success from point-of-view of unittest
302
# -- it actually does nothing so it barely matters :)
303
265
unittest.TestResult.addSuccess(self, test)
304
test._log_contents = ''
306
267
def printErrorList(self, flavour, errors):
307
268
for test, err in errors:
308
269
self.stream.writeln(self.separator1)
309
self.stream.write("%s: " % flavour)
310
self.stream.writeln(self.getDescription(test))
270
self.stream.writeln("%s: %s" % (flavour, self.getDescription(test)))
311
271
if getattr(test, '_get_log', None) is not None:
312
self.stream.write('\n')
314
('vvvv[log from %s]' % test.id()).ljust(78,'-'))
315
self.stream.write('\n')
316
self.stream.write(test._get_log())
317
self.stream.write('\n')
319
('^^^^[log from %s]' % test.id()).ljust(78,'-'))
320
self.stream.write('\n')
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,'-')
321
278
self.stream.writeln(self.separator2)
322
279
self.stream.writeln("%s" % err)
981
693
self.assertEqual(mode, actual_mode,
982
694
'mode of %r incorrect (%o != %o)' % (path, mode, actual_mode))
984
def assertIsSameRealPath(self, path1, path2):
985
"""Fail if path1 and path2 points to different files"""
986
self.assertEqual(osutils.realpath(path1),
987
osutils.realpath(path2),
988
"apparent paths:\na = %s\nb = %s\n," % (path1, path2))
990
696
def assertIsInstance(self, obj, kls):
991
697
"""Fail if obj is not an instance of kls"""
992
698
if not isinstance(obj, kls):
993
699
self.fail("%r is an instance of %s rather than %s" % (
994
700
obj, obj.__class__, kls))
996
def expectFailure(self, reason, assertion, *args, **kwargs):
997
"""Invoke a test, expecting it to fail for the given reason.
999
This is for assertions that ought to succeed, but currently fail.
1000
(The failure is *expected* but not *wanted*.) Please be very precise
1001
about the failure you're expecting. If a new bug is introduced,
1002
AssertionError should be raised, not KnownFailure.
1004
Frequently, expectFailure should be followed by an opposite assertion.
1007
Intended to be used with a callable that raises AssertionError as the
1008
'assertion' parameter. args and kwargs are passed to the 'assertion'.
1010
Raises KnownFailure if the test fails. Raises AssertionError if the
1015
self.expectFailure('Math is broken', self.assertNotEqual, 54,
1017
self.assertEqual(42, dynamic_val)
1019
This means that a dynamic_val of 54 will cause the test to raise
1020
a KnownFailure. Once math is fixed and the expectFailure is removed,
1021
only a dynamic_val of 42 will allow the test to pass. Anything other
1022
than 54 or 42 will cause an AssertionError.
1025
assertion(*args, **kwargs)
1026
except AssertionError:
1027
raise KnownFailure(reason)
1029
self.fail('Unexpected success. Should have failed: %s' % reason)
1031
def assertFileEqual(self, content, path):
1032
"""Fail if path does not contain 'content'."""
1033
self.failUnlessExists(path)
1034
f = file(path, 'rb')
1039
self.assertEqualDiff(content, s)
1041
def failUnlessExists(self, path):
1042
"""Fail unless path or paths, which may be abs or relative, exist."""
1043
if not isinstance(path, basestring):
1045
self.failUnlessExists(p)
1047
self.failUnless(osutils.lexists(path),path+" does not exist")
1049
def failIfExists(self, path):
1050
"""Fail if path or paths, which may be abs or relative, exist."""
1051
if not isinstance(path, basestring):
1053
self.failIfExists(p)
1055
self.failIf(osutils.lexists(path),path+" exists")
1057
def _capture_deprecation_warnings(self, a_callable, *args, **kwargs):
702
def _capture_warnings(self, a_callable, *args, **kwargs):
1058
703
"""A helper for callDeprecated and applyDeprecated.
1060
705
:param a_callable: A callable to call.
1061
706
:param args: The positional arguments for the callable
1062
707
:param kwargs: The keyword arguments for the callable
1063
708
:return: A tuple (warnings, result). result is the result of calling
1064
a_callable(``*args``, ``**kwargs``).
709
a_callable(*args, **kwargs).
1066
711
local_warnings = []
1067
712
def capture_warnings(msg, cls=None, stacklevel=None):
1350
901
if not keep_log_file:
1351
902
self._log_contents = log_contents
1353
os.remove(self._log_file_name)
1355
if sys.platform == 'win32' and e.errno == errno.EACCES:
1356
sys.stderr.write(('Unable to delete log file '
1357
' %r\n' % self._log_file_name))
903
os.remove(self._log_file_name)
1360
904
return log_contents
1362
906
return "DELETED log file to reduce memory footprint"
1364
def requireFeature(self, feature):
1365
"""This test requires a specific feature is available.
1367
:raises UnavailableFeature: When feature is not available.
908
def capture(self, cmd, retcode=0):
909
"""Shortcut that splits cmd into words, runs, and returns stdout"""
910
return self.run_bzr_captured(cmd.split(), retcode=retcode)[0]
912
def run_bzr_captured(self, argv, retcode=0, encoding=None, stdin=None,
914
"""Invoke bzr and return (stdout, stderr).
916
Useful for code that wants to check the contents of the
917
output, the way error messages are presented, etc.
919
This should be the main method for tests that want to exercise the
920
overall behavior of the bzr application (rather than a unit test
921
or a functional test of the library.)
923
Much of the old code runs bzr by forking a new copy of Python, but
924
that is slower, harder to debug, and generally not necessary.
926
This runs bzr through the interface that catches and reports
927
errors, and with logging set to something approximating the
928
default, so that error reporting can be checked.
930
:param argv: arguments to invoke bzr
931
:param retcode: expected return code, or None for don't-care.
932
:param encoding: encoding for sys.stdout and sys.stderr
933
:param stdin: A string to be used as stdin for the command.
934
:param working_dir: Change to this directory before running
1369
if not feature.available():
1370
raise UnavailableFeature(feature)
1372
def _run_bzr_autosplit(self, args, retcode, encoding, stdin,
1374
"""Run bazaar command line, splitting up a string command line."""
1375
if isinstance(args, basestring):
1376
# shlex don't understand unicode strings,
1377
# so args should be plain string (bialix 20070906)
1378
args = list(shlex.split(str(args)))
1379
return self._run_bzr_core(args, retcode=retcode,
1380
encoding=encoding, stdin=stdin, working_dir=working_dir,
1383
def _run_bzr_core(self, args, retcode, encoding, stdin,
1385
936
if encoding is None:
1386
937
encoding = bzrlib.user_encoding
938
if stdin is not None:
939
stdin = StringIO(stdin)
1387
940
stdout = StringIOWrapper()
1388
941
stderr = StringIOWrapper()
1389
942
stdout.encoding = encoding
1390
943
stderr.encoding = encoding
1392
self.log('run bzr: %r', args)
945
self.log('run bzr: %r', argv)
1393
946
# FIXME: don't call into logging here
1394
947
handler = logging.StreamHandler(stderr)
1395
948
handler.setLevel(logging.INFO)
1396
949
logger = logging.getLogger('')
1397
950
logger.addHandler(handler)
1398
old_ui_factory = ui.ui_factory
1399
ui.ui_factory = TestUIFactory(stdin=stdin, stdout=stdout, stderr=stderr)
951
old_ui_factory = bzrlib.ui.ui_factory
952
bzrlib.ui.ui_factory = bzrlib.tests.blackbox.TestUIFactory(
955
bzrlib.ui.ui_factory.stdin = stdin
1402
958
if working_dir is not None:
2263
1665
def setUp(self):
2264
1666
super(ChrootedTestCase, self).setUp()
2265
if not self.vfs_transport_factory == MemoryServer:
1667
if not self.transport_server == MemoryServer:
2266
1668
self.transport_readonly_server = HttpServer
2269
def condition_id_re(pattern):
2270
"""Create a condition filter which performs a re check on a test's id.
2272
:param pattern: A regular expression string.
2273
:return: A callable that returns True if the re matches.
2275
filter_re = re.compile(pattern)
2276
def condition(test):
2278
return filter_re.search(test_id)
2282
def condition_isinstance(klass_or_klass_list):
2283
"""Create a condition filter which returns isinstance(param, klass).
2285
:return: A callable which when called with one parameter obj return the
2286
result of isinstance(obj, klass_or_klass_list).
2289
return isinstance(obj, klass_or_klass_list)
2293
def condition_id_in_list(id_list):
2294
"""Create a condition filter which verify that test's id in a list.
2296
:param id_list: A TestIdList object.
2297
:return: A callable that returns True if the test's id appears in the list.
2299
def condition(test):
2300
return id_list.includes(test.id())
2304
def condition_id_startswith(start):
2305
"""Create a condition filter verifying that test's id starts with a string.
2307
:param start: A string.
2308
:return: A callable that returns True if the test's id starts with the
2311
def condition(test):
2312
return test.id().startswith(start)
2316
def exclude_tests_by_condition(suite, condition):
2317
"""Create a test suite which excludes some tests from suite.
2319
:param suite: The suite to get tests from.
2320
:param condition: A callable whose result evaluates True when called with a
2321
test case which should be excluded from the result.
2322
:return: A suite which contains the tests found in suite that fail
2326
for test in iter_suite_tests(suite):
2327
if not condition(test):
2329
return TestUtil.TestSuite(result)
2332
def filter_suite_by_condition(suite, condition):
2333
"""Create a test suite by filtering another one.
2335
:param suite: The source suite.
2336
:param condition: A callable whose result evaluates True when called with a
2337
test case which should be included in the result.
2338
:return: A suite which contains the tests found in suite that pass
2342
for test in iter_suite_tests(suite):
2345
return TestUtil.TestSuite(result)
2348
1671
def filter_suite_by_re(suite, pattern):
2349
"""Create a test suite by filtering another one.
2351
:param suite: the source suite
2352
:param pattern: pattern that names must match
2353
:returns: the newly created suite
2355
condition = condition_id_re(pattern)
2356
result_suite = filter_suite_by_condition(suite, condition)
2360
def filter_suite_by_id_list(suite, test_id_list):
2361
"""Create a test suite by filtering another one.
2363
:param suite: The source suite.
2364
:param test_id_list: A list of the test ids to keep as strings.
2365
:returns: the newly created suite
2367
condition = condition_id_in_list(test_id_list)
2368
result_suite = filter_suite_by_condition(suite, condition)
2372
def filter_suite_by_id_startswith(suite, start):
2373
"""Create a test suite by filtering another one.
2375
:param suite: The source suite.
2376
:param start: A string the test id must start with.
2377
:returns: the newly created suite
2379
condition = condition_id_startswith(start)
2380
result_suite = filter_suite_by_condition(suite, condition)
2384
def exclude_tests_by_re(suite, pattern):
2385
"""Create a test suite which excludes some tests from suite.
2387
:param suite: The suite to get tests from.
2388
:param pattern: A regular expression string. Test ids that match this
2389
pattern will be excluded from the result.
2390
:return: A TestSuite that contains all the tests from suite without the
2391
tests that matched pattern. The order of tests is the same as it was in
2394
return exclude_tests_by_condition(suite, condition_id_re(pattern))
2397
def preserve_input(something):
2398
"""A helper for performing test suite transformation chains.
2400
:param something: Anything you want to preserve.
2406
def randomize_suite(suite):
2407
"""Return a new TestSuite with suite's tests in random order.
2409
The tests in the input suite are flattened into a single suite in order to
2410
accomplish this. Any nested TestSuites are removed to provide global
2413
tests = list(iter_suite_tests(suite))
2414
random.shuffle(tests)
2415
return TestUtil.TestSuite(tests)
2418
def split_suite_by_condition(suite, condition):
2419
"""Split a test suite into two by a condition.
2421
:param suite: The suite to split.
2422
:param condition: The condition to match on. Tests that match this
2423
condition are returned in the first test suite, ones that do not match
2424
are in the second suite.
2425
:return: A tuple of two test suites, where the first contains tests from
2426
suite matching the condition, and the second contains the remainder
2427
from suite. The order within each output suite is the same as it was in
2432
for test in iter_suite_tests(suite):
2434
matched.append(test)
1672
result = TestUtil.TestSuite()
1673
filter_re = re.compile(pattern)
1674
for test in iter_suite_tests(suite):
1675
if filter_re.search(test.id()):
1676
result.addTest(test)
1680
def sort_suite_by_re(suite, pattern):
1683
filter_re = re.compile(pattern)
1684
for test in iter_suite_tests(suite):
1685
if filter_re.search(test.id()):
2436
did_not_match.append(test)
2437
return TestUtil.TestSuite(matched), TestUtil.TestSuite(did_not_match)
2440
def split_suite_by_re(suite, pattern):
2441
"""Split a test suite into two by a regular expression.
2443
:param suite: The suite to split.
2444
:param pattern: A regular expression string. Test ids that match this
2445
pattern will be in the first test suite returned, and the others in the
2446
second test suite returned.
2447
:return: A tuple of two test suites, where the first contains tests from
2448
suite matching pattern, and the second contains the remainder from
2449
suite. The order within each output suite is the same as it was in
2452
return split_suite_by_condition(suite, condition_id_re(pattern))
1689
return TestUtil.TestSuite(first + second)
2455
1692
def run_suite(suite, name='test', verbose=False, pattern=".*",
2456
stop_on_failure=False,
1693
stop_on_failure=False, keep_output=False,
2457
1694
transport=None, lsprof_timed=None, bench_history=None,
2458
matching_tests_first=None,
2461
exclude_pattern=None,
1695
matching_tests_first=None):
2463
1696
TestCase._gather_lsprof_in_benchmarks = lsprof_timed
2540
1732
transport = default_transport
2541
1733
old_transport = default_transport
2542
1734
default_transport = transport
2543
global selftest_debug_flags
2544
old_debug_flags = selftest_debug_flags
2545
if debug_flags is not None:
2546
selftest_debug_flags = set(debug_flags)
2548
if load_list is None:
2551
keep_only = load_test_id_list(load_list)
2552
1736
if test_suite_factory is None:
2553
suite = test_suite(keep_only, starting_with)
1737
suite = test_suite()
2555
1739
suite = test_suite_factory()
2556
1740
return run_suite(suite, 'testbzr', verbose=verbose, pattern=pattern,
2557
stop_on_failure=stop_on_failure,
1741
stop_on_failure=stop_on_failure, keep_output=keep_output,
2558
1742
transport=transport,
2559
1743
lsprof_timed=lsprof_timed,
2560
1744
bench_history=bench_history,
2561
matching_tests_first=matching_tests_first,
2562
list_only=list_only,
2563
random_seed=random_seed,
2564
exclude_pattern=exclude_pattern,
1745
matching_tests_first=matching_tests_first)
2567
1747
default_transport = old_transport
2568
selftest_debug_flags = old_debug_flags
2571
def load_test_id_list(file_name):
2572
"""Load a test id list from a text file.
2574
The format is one test id by line. No special care is taken to impose
2575
strict rules, these test ids are used to filter the test suite so a test id
2576
that do not match an existing test will do no harm. This allows user to add
2577
comments, leave blank lines, etc.
2581
ftest = open(file_name, 'rt')
2583
if e.errno != errno.ENOENT:
2586
raise errors.NoSuchFile(file_name)
2588
for test_name in ftest.readlines():
2589
test_list.append(test_name.strip())
2594
def suite_matches_id_list(test_suite, id_list):
2595
"""Warns about tests not appearing or appearing more than once.
2597
:param test_suite: A TestSuite object.
2598
:param test_id_list: The list of test ids that should be found in
2601
:return: (absents, duplicates) absents is a list containing the test found
2602
in id_list but not in test_suite, duplicates is a list containing the
2603
test found multiple times in test_suite.
2605
When using a prefined test id list, it may occurs that some tests do not
2606
exist anymore or that some tests use the same id. This function warns the
2607
tester about potential problems in his workflow (test lists are volatile)
2608
or in the test suite itself (using the same id for several tests does not
2609
help to localize defects).
2611
# Build a dict counting id occurrences
2613
for test in iter_suite_tests(test_suite):
2615
tests[id] = tests.get(id, 0) + 1
2620
occurs = tests.get(id, 0)
2622
not_found.append(id)
2624
duplicates.append(id)
2626
return not_found, duplicates
2629
class TestIdList(object):
2630
"""Test id list to filter a test suite.
2632
Relying on the assumption that test ids are built as:
2633
<module>[.<class>.<method>][(<param>+)], <module> being in python dotted
2634
notation, this class offers methods to :
2635
- avoid building a test suite for modules not refered to in the test list,
2636
- keep only the tests listed from the module test suite.
2639
def __init__(self, test_id_list):
2640
# When a test suite needs to be filtered against us we compare test ids
2641
# for equality, so a simple dict offers a quick and simple solution.
2642
self.tests = dict().fromkeys(test_id_list, True)
2644
# While unittest.TestCase have ids like:
2645
# <module>.<class>.<method>[(<param+)],
2646
# doctest.DocTestCase can have ids like:
2649
# <module>.<function>
2650
# <module>.<class>.<method>
2652
# Since we can't predict a test class from its name only, we settle on
2653
# a simple constraint: a test id always begins with its module name.
2656
for test_id in test_id_list:
2657
parts = test_id.split('.')
2658
mod_name = parts.pop(0)
2659
modules[mod_name] = True
2661
mod_name += '.' + part
2662
modules[mod_name] = True
2663
self.modules = modules
2665
def refers_to(self, module_name):
2666
"""Is there tests for the module or one of its sub modules."""
2667
return self.modules.has_key(module_name)
2669
def includes(self, test_id):
2670
return self.tests.has_key(test_id)
2673
def test_suite(keep_only=None, starting_with=None):
2674
1751
"""Build and return TestSuite for the whole of bzrlib.
2676
:param keep_only: A list of test ids limiting the suite returned.
2678
:param starting_with: An id limiting the suite returned to the tests
2681
1753
This function can be replaced if you need to change the default test
2682
1754
suite on a global basis, but it is not encouraged.
2684
1756
testmod_names = [
2686
'bzrlib.util.tests.test_bencode',
2687
'bzrlib.tests.blackbox',
2688
'bzrlib.tests.branch_implementations',
2689
'bzrlib.tests.bzrdir_implementations',
2690
'bzrlib.tests.commands',
2691
'bzrlib.tests.inventory_implementations',
2692
'bzrlib.tests.interrepository_implementations',
2693
'bzrlib.tests.intertree_implementations',
2694
'bzrlib.tests.per_lock',
2695
'bzrlib.tests.repository_implementations',
2696
'bzrlib.tests.test__dirstate_helpers',
2697
1757
'bzrlib.tests.test_ancestry',
2698
1758
'bzrlib.tests.test_annotate',
2699
1759
'bzrlib.tests.test_api',
2700
1760
'bzrlib.tests.test_atomicfile',
2701
1761
'bzrlib.tests.test_bad_files',
2702
'bzrlib.tests.test_bisect_multi',
2703
1762
'bzrlib.tests.test_branch',
2704
'bzrlib.tests.test_branchbuilder',
2705
'bzrlib.tests.test_bugtracker',
2706
1763
'bzrlib.tests.test_bundle',
2707
1764
'bzrlib.tests.test_bzrdir',
2708
1765
'bzrlib.tests.test_cache_utf8',
2746
1793
'bzrlib.tests.test_lockdir',
2747
1794
'bzrlib.tests.test_lockable_files',
2748
1795
'bzrlib.tests.test_log',
2749
'bzrlib.tests.test_lsprof',
2750
'bzrlib.tests.test_lru_cache',
2751
'bzrlib.tests.test_mail_client',
2752
1796
'bzrlib.tests.test_memorytree',
2753
1797
'bzrlib.tests.test_merge',
2754
1798
'bzrlib.tests.test_merge3',
2755
1799
'bzrlib.tests.test_merge_core',
2756
'bzrlib.tests.test_merge_directive',
2757
1800
'bzrlib.tests.test_missing',
2758
1801
'bzrlib.tests.test_msgeditor',
2759
'bzrlib.tests.test_multiparent',
2760
'bzrlib.tests.test_mutabletree',
2761
1802
'bzrlib.tests.test_nonascii',
2762
1803
'bzrlib.tests.test_options',
2763
1804
'bzrlib.tests.test_osutils',
2764
1805
'bzrlib.tests.test_osutils_encodings',
2765
'bzrlib.tests.test_pack',
2766
1806
'bzrlib.tests.test_patch',
2767
1807
'bzrlib.tests.test_patches',
2768
1808
'bzrlib.tests.test_permissions',
2769
1809
'bzrlib.tests.test_plugins',
2770
1810
'bzrlib.tests.test_progress',
2771
'bzrlib.tests.test_read_bundle',
2772
'bzrlib.tests.test_reconfigure',
2773
1811
'bzrlib.tests.test_reconcile',
2774
1812
'bzrlib.tests.test_registry',
2775
'bzrlib.tests.test_remote',
2776
1813
'bzrlib.tests.test_repository',
2777
'bzrlib.tests.per_repository_reference',
2778
1814
'bzrlib.tests.test_revert',
2779
1815
'bzrlib.tests.test_revision',
2780
'bzrlib.tests.test_revisionspec',
1816
'bzrlib.tests.test_revisionnamespaces',
2781
1817
'bzrlib.tests.test_revisiontree',
2782
1818
'bzrlib.tests.test_rio',
2783
'bzrlib.tests.test_rules',
2784
1819
'bzrlib.tests.test_sampler',
2785
1820
'bzrlib.tests.test_selftest',
2786
1821
'bzrlib.tests.test_setup',
2787
1822
'bzrlib.tests.test_sftp_transport',
2788
'bzrlib.tests.test_smart',
2789
1823
'bzrlib.tests.test_smart_add',
2790
1824
'bzrlib.tests.test_smart_transport',
2791
'bzrlib.tests.test_smtp_connection',
2792
1825
'bzrlib.tests.test_source',
2793
'bzrlib.tests.test_ssh_transport',
2794
1826
'bzrlib.tests.test_status',
2795
1827
'bzrlib.tests.test_store',
2796
'bzrlib.tests.test_strace',
2797
'bzrlib.tests.test_subsume',
2798
'bzrlib.tests.test_switch',
2799
1828
'bzrlib.tests.test_symbol_versioning',
2800
'bzrlib.tests.test_tag',
2801
1829
'bzrlib.tests.test_testament',
2802
1830
'bzrlib.tests.test_textfile',
2803
1831
'bzrlib.tests.test_textmerge',
2804
'bzrlib.tests.test_timestamp',
2805
1832
'bzrlib.tests.test_trace',
2806
1833
'bzrlib.tests.test_transactions',
2807
1834
'bzrlib.tests.test_transform',
2808
1835
'bzrlib.tests.test_transport',
2809
'bzrlib.tests.test_transport_implementations',
2810
1836
'bzrlib.tests.test_tree',
2811
1837
'bzrlib.tests.test_treebuilder',
2812
1838
'bzrlib.tests.test_tsort',
2813
1839
'bzrlib.tests.test_tuned_gzip',
2814
1840
'bzrlib.tests.test_ui',
2815
'bzrlib.tests.test_uncommit',
2816
1841
'bzrlib.tests.test_upgrade',
2817
1842
'bzrlib.tests.test_urlutils',
2818
1843
'bzrlib.tests.test_versionedfile',
2819
1844
'bzrlib.tests.test_version',
2820
1845
'bzrlib.tests.test_version_info',
2821
'bzrlib.tests.test__walkdirs_win32',
2822
1846
'bzrlib.tests.test_weave',
2823
1847
'bzrlib.tests.test_whitebox',
2824
'bzrlib.tests.test_win32utils',
2825
1848
'bzrlib.tests.test_workingtree',
2826
'bzrlib.tests.test_workingtree_4',
2827
1849
'bzrlib.tests.test_wsgi',
2828
1850
'bzrlib.tests.test_xml',
2829
'bzrlib.tests.tree_implementations',
2830
'bzrlib.tests.workingtree_implementations',
1852
test_transport_implementations = [
1853
'bzrlib.tests.test_transport_implementations',
1854
'bzrlib.tests.test_read_bundle',
1856
suite = TestUtil.TestSuite()
2833
1857
loader = TestUtil.TestLoader()
2835
if starting_with is not None:
2836
# We take precedence over keep_only because *at loading time* using
2837
# both options means we will load less tests for the same final result.
2838
def interesting_module(name):
2840
# Either the module name starts with the specified string
2841
name.startswith(starting_with)
2842
# or it may contain tests starting with the specified string
2843
or starting_with.startswith(name)
2845
loader = TestUtil.FilteredByModuleTestLoader(interesting_module)
2847
elif keep_only is not None:
2848
id_filter = TestIdList(keep_only)
2849
loader = TestUtil.FilteredByModuleTestLoader(id_filter.refers_to)
2850
def interesting_module(name):
2851
return id_filter.refers_to(name)
2854
loader = TestUtil.TestLoader()
2855
def interesting_module(name):
2856
# No filtering, all modules are interesting
2859
suite = loader.suiteClass()
2861
# modules building their suite with loadTestsFromModuleNames
2862
1858
suite.addTest(loader.loadTestsFromModuleNames(testmod_names))
2864
modules_to_doctest = [
2869
'bzrlib.iterablefile',
2874
'bzrlib.symbol_versioning',
2877
'bzrlib.version_info_formats.format_custom',
2880
for mod in modules_to_doctest:
2881
if not interesting_module(mod):
2882
# No tests to keep here, move along
1859
from bzrlib.transport import TransportTestProviderAdapter
1860
adapter = TransportTestProviderAdapter()
1861
adapt_modules(test_transport_implementations, adapter, loader, suite)
1862
for package in packages_to_test():
1863
suite.addTest(package.test_suite())
1864
for m in MODULES_TO_TEST:
1865
suite.addTest(loader.loadTestsFromModule(m))
1866
for m in MODULES_TO_DOCTEST:
2885
doc_suite = doctest.DocTestSuite(mod)
1868
suite.addTest(doctest.DocTestSuite(m))
2886
1869
except ValueError, e:
2887
print '**failed to get doctest for: %s\n%s' % (mod, e)
1870
print '**failed to get doctest for: %s\n%s' %(m,e)
2889
suite.addTest(doc_suite)
2891
default_encoding = sys.getdefaultencoding()
2892
for name, plugin in bzrlib.plugin.plugins().items():
2893
if not interesting_module(plugin.module.__name__):
2895
plugin_suite = plugin.test_suite()
2896
# We used to catch ImportError here and turn it into just a warning,
2897
# but really if you don't have --no-plugins this should be a failure.
2898
# mbp 20080213 - see http://bugs.launchpad.net/bugs/189771
2899
if plugin_suite is None:
2900
plugin_suite = plugin.load_plugin_tests(loader)
2901
if plugin_suite is not None:
2902
suite.addTest(plugin_suite)
2903
if default_encoding != sys.getdefaultencoding():
2904
bzrlib.trace.warning(
2905
'Plugin "%s" tried to reset default encoding to: %s', name,
2906
sys.getdefaultencoding())
2908
sys.setdefaultencoding(default_encoding)
2910
if starting_with is not None:
2911
suite = filter_suite_by_id_startswith(suite, starting_with)
2913
if keep_only is not None:
2914
# Now that the referred modules have loaded their tests, keep only the
2916
suite = filter_suite_by_id_list(suite, id_filter)
2917
# Do some sanity checks on the id_list filtering
2918
not_found, duplicates = suite_matches_id_list(suite, keep_only)
2919
if starting_with is not None:
2920
# The tester has used both keep_only and starting_with, so he is
2921
# already aware that some tests are excluded from the list, there
2922
# is no need to tell him which.
2925
# Some tests mentioned in the list are not in the test suite. The
2926
# list may be out of date, report to the tester.
2927
for id in not_found:
2928
bzrlib.trace.warning('"%s" not found in the test suite', id)
2929
for id in duplicates:
2930
bzrlib.trace.warning('"%s" is used as an id by several tests', id)
2935
def multiply_tests_from_modules(module_name_list, scenario_iter, loader=None):
2936
"""Adapt all tests in some given modules to given scenarios.
2938
This is the recommended public interface for test parameterization.
2939
Typically the test_suite() method for a per-implementation test
2940
suite will call multiply_tests_from_modules and return the
2943
:param module_name_list: List of fully-qualified names of test
2945
:param scenario_iter: Iterable of pairs of (scenario_name,
2946
scenario_param_dict).
2947
:param loader: If provided, will be used instead of a new
2948
bzrlib.tests.TestLoader() instance.
2950
This returns a new TestSuite containing the cross product of
2951
all the tests in all the modules, each repeated for each scenario.
2952
Each test is adapted by adding the scenario name at the end
2953
of its name, and updating the test object's __dict__ with the
2954
scenario_param_dict.
2956
>>> r = multiply_tests_from_modules(
2957
... ['bzrlib.tests.test_sampler'],
2958
... [('one', dict(param=1)),
2959
... ('two', dict(param=2))])
2960
>>> tests = list(iter_suite_tests(r))
2964
'bzrlib.tests.test_sampler.DemoTest.test_nothing(one)'
2970
# XXX: Isn't load_tests() a better way to provide the same functionality
2971
# without forcing a predefined TestScenarioApplier ? --vila 080215
2973
loader = TestUtil.TestLoader()
2975
suite = loader.suiteClass()
2977
adapter = TestScenarioApplier()
2978
adapter.scenarios = list(scenario_iter)
2979
adapt_modules(module_name_list, adapter, loader, suite)
2983
def multiply_scenarios(scenarios_left, scenarios_right):
2984
"""Multiply two sets of scenarios.
2986
:returns: the cartesian product of the two sets of scenarios, that is
2987
a scenario for every possible combination of a left scenario and a
2991
('%s,%s' % (left_name, right_name),
2992
dict(left_dict.items() + right_dict.items()))
2993
for left_name, left_dict in scenarios_left
2994
for right_name, right_dict in scenarios_right]
1872
for name, plugin in bzrlib.plugin.all_plugins().items():
1873
if getattr(plugin, 'test_suite', None) is not None:
1874
suite.addTest(plugin.test_suite())
2998
1878
def adapt_modules(mods_list, adapter, loader, suite):
2999
1879
"""Adapt the modules in mods_list using adapter and add to suite."""
3000
tests = loader.loadTestsFromModuleNames(mods_list)
3001
adapt_tests(tests, adapter, suite)
3004
def adapt_tests(tests_list, adapter, suite):
3005
"""Adapt the tests in tests_list using adapter and add to suite."""
3006
for test in iter_suite_tests(tests_list):
1880
for test in iter_suite_tests(loader.loadTestsFromModuleNames(mods_list)):
3007
1881
suite.addTests(adapter.adapt(test))
3010
def _rmtree_temp_dir(dirname):
3011
# If LANG=C we probably have created some bogus paths
3012
# which rmtree(unicode) will fail to delete
3013
# so make sure we are using rmtree(str) to delete everything
3014
# except on win32, where rmtree(str) will fail
3015
# since it doesn't have the property of byte-stream paths
3016
# (they are either ascii or mbcs)
3017
if sys.platform == 'win32':
3018
# make sure we are using the unicode win32 api
3019
dirname = unicode(dirname)
3021
dirname = dirname.encode(sys.getfilesystemencoding())
3023
osutils.rmtree(dirname)
3025
if sys.platform == 'win32' and e.errno == errno.EACCES:
3026
sys.stderr.write(('Permission denied: '
3027
'unable to remove testing dir '
3028
'%s\n' % os.path.basename(dirname)))
3033
class Feature(object):
3034
"""An operating system Feature."""
3037
self._available = None
3039
def available(self):
3040
"""Is the feature available?
3042
:return: True if the feature is available.
3044
if self._available is None:
3045
self._available = self._probe()
3046
return self._available
3049
"""Implement this method in concrete features.
3051
:return: True if the feature is available.
3053
raise NotImplementedError
3056
if getattr(self, 'feature_name', None):
3057
return self.feature_name()
3058
return self.__class__.__name__
3061
class _SymlinkFeature(Feature):
3064
return osutils.has_symlinks()
3066
def feature_name(self):
3069
SymlinkFeature = _SymlinkFeature()
3072
class _HardlinkFeature(Feature):
3075
return osutils.has_hardlinks()
3077
def feature_name(self):
3080
HardlinkFeature = _HardlinkFeature()
3083
class _OsFifoFeature(Feature):
3086
return getattr(os, 'mkfifo', None)
3088
def feature_name(self):
3089
return 'filesystem fifos'
3091
OsFifoFeature = _OsFifoFeature()
3094
class _UnicodeFilenameFeature(Feature):
3095
"""Does the filesystem support Unicode filenames?"""
3099
# Check for character combinations unlikely to be covered by any
3100
# single non-unicode encoding. We use the characters
3101
# - greek small letter alpha (U+03B1) and
3102
# - braille pattern dots-123456 (U+283F).
3103
os.stat(u'\u03b1\u283f')
3104
except UnicodeEncodeError:
3106
except (IOError, OSError):
3107
# The filesystem allows the Unicode filename but the file doesn't
3111
# The filesystem allows the Unicode filename and the file exists,
3115
UnicodeFilenameFeature = _UnicodeFilenameFeature()
3118
class TestScenarioApplier(object):
3119
"""A tool to apply scenarios to tests."""
3121
def adapt(self, test):
3122
"""Return a TestSuite containing a copy of test for each scenario."""
3123
result = unittest.TestSuite()
3124
for scenario in self.scenarios:
3125
result.addTest(self.adapt_test_to_scenario(test, scenario))
3128
def adapt_test_to_scenario(self, test, scenario):
3129
"""Copy test and apply scenario to it.
3131
:param test: A test to adapt.
3132
:param scenario: A tuple describing the scenarion.
3133
The first element of the tuple is the new test id.
3134
The second element is a dict containing attributes to set on the
3136
:return: The adapted test.
3138
from copy import deepcopy
3139
new_test = deepcopy(test)
3140
for name, value in scenario[1].items():
3141
setattr(new_test, name, value)
3142
new_id = "%s(%s)" % (new_test.id(), scenario[0])
3143
new_test.id = lambda: new_id
3147
def probe_unicode_in_user_encoding():
3148
"""Try to encode several unicode strings to use in unicode-aware tests.
3149
Return first successfull match.
3151
:return: (unicode value, encoded plain string value) or (None, None)
3153
possible_vals = [u'm\xb5', u'\xe1', u'\u0410']
3154
for uni_val in possible_vals:
3156
str_val = uni_val.encode(bzrlib.user_encoding)
3157
except UnicodeEncodeError:
3158
# Try a different character
3161
return uni_val, str_val
3165
def probe_bad_non_ascii(encoding):
3166
"""Try to find [bad] character with code [128..255]
3167
that cannot be decoded to unicode in some encoding.
3168
Return None if all non-ascii characters is valid
3171
for i in xrange(128, 256):
3174
char.decode(encoding)
3175
except UnicodeDecodeError:
3180
class _FTPServerFeature(Feature):
3181
"""Some tests want an FTP Server, check if one is available.
3183
Right now, the only way this is available is if 'medusa' is installed.
3184
http://www.amk.ca/python/code/medusa.html
3189
import bzrlib.tests.ftp_server
3194
def feature_name(self):
3197
FTPServerFeature = _FTPServerFeature()
3200
class _UnicodeFilename(Feature):
3201
"""Does the filesystem support Unicode filenames?"""
3206
except UnicodeEncodeError:
3208
except (IOError, OSError):
3209
# The filesystem allows the Unicode filename but the file doesn't
3213
# The filesystem allows the Unicode filename and the file exists,
3217
UnicodeFilename = _UnicodeFilename()
3220
class _UTF8Filesystem(Feature):
3221
"""Is the filesystem UTF-8?"""
3224
if osutils._fs_enc.upper() in ('UTF-8', 'UTF8'):
3228
UTF8Filesystem = _UTF8Filesystem()
3231
class _CaseInsensitiveFilesystemFeature(Feature):
3232
"""Check if underlined filesystem is case-insensitive
3233
(e.g. on Windows, Cygwin, MacOS)
3237
if TestCaseWithMemoryTransport.TEST_ROOT is None:
3238
root = osutils.mkdtemp(prefix='testbzr-', suffix='.tmp')
3239
TestCaseWithMemoryTransport.TEST_ROOT = root
3241
root = TestCaseWithMemoryTransport.TEST_ROOT
3242
tdir = osutils.mkdtemp(prefix='case-sensitive-probe-', suffix='',
3244
name_a = osutils.pathjoin(tdir, 'a')
3245
name_A = osutils.pathjoin(tdir, 'A')
3247
result = osutils.isdir(name_A)
3248
_rmtree_temp_dir(tdir)
3251
def feature_name(self):
3252
return 'case-insensitive filesystem'
3254
CaseInsensitiveFilesystemFeature = _CaseInsensitiveFilesystemFeature()
1884
def clean_selftest_output(root=None, quiet=False):
1885
"""Remove all selftest output directories from root directory.
1887
:param root: root directory for clean
1888
(if ommitted or None then clean current directory).
1889
:param quiet: suppress report about deleting directories
1894
re_dir = re.compile(r'''test\d\d\d\d\.tmp''')
1897
for i in os.listdir(root):
1898
if os.path.isdir(i) and re_dir.match(i):
1900
print 'delete directory:', i