162
161
class ExtendedTestResult(unittest._TextTestResult):
163
162
"""Accepts, reports and accumulates the results of running tests.
165
Compared to this unittest version this class adds support for
164
Compared to the unittest version this class adds support for
166
165
profiling, benchmarking, stopping as soon as a test fails, and
167
166
skipping tests. There are further-specialized subclasses for
168
167
different types of display.
343
342
except KeyboardInterrupt:
346
self.addError(test, test.__exc_info())
345
self.addError(test, test._exc_info())
348
347
# seems best to treat this as success from point-of-view of unittest
349
348
# -- it actually does nothing so it barely matters :)
983
982
self.assertEqual(mode, actual_mode,
984
983
'mode of %r incorrect (%o != %o)' % (path, mode, actual_mode))
985
def assertIsSameRealPath(self, path1, path2):
986
"""Fail if path1 and path2 points to different files"""
987
self.assertEqual(osutils.realpath(path1),
988
osutils.realpath(path2),
989
"apparent paths:\na = %s\nb = %s\n," % (path1, path2))
986
991
def assertIsInstance(self, obj, kls):
987
992
"""Fail if obj is not an instance of kls"""
988
993
if not isinstance(obj, kls):
1148
1153
'BZR_HOME': None, # Don't inherit BZR_HOME to all the tests.
1149
1154
'HOME': os.getcwd(),
1150
1155
'APPDATA': None, # bzr now use Win32 API and don't rely on APPDATA
1156
'BZR_EDITOR': None, # test_msgeditor manipulates this variable
1151
1157
'BZR_EMAIL': None,
1152
1158
'BZREMAIL': None, # may still be present in the environment
1285
1291
return "DELETED log file to reduce memory footprint"
1287
@deprecated_method(zero_eighteen)
1288
def capture(self, cmd, retcode=0):
1289
"""Shortcut that splits cmd into words, runs, and returns stdout"""
1290
return self.run_bzr_captured(cmd.split(), retcode=retcode)[0]
1292
1293
def requireFeature(self, feature):
1293
1294
"""This test requires a specific feature is available.
1297
1298
if not feature.available():
1298
1299
raise UnavailableFeature(feature)
1300
@deprecated_method(zero_eighteen)
1301
def run_bzr_captured(self, argv, retcode=0, encoding=None, stdin=None,
1303
"""Invoke bzr and return (stdout, stderr).
1305
Don't call this method, just use run_bzr() which is equivalent.
1307
:param argv: Arguments to invoke bzr. This may be either a
1308
single string, in which case it is split by shlex into words,
1309
or a list of arguments.
1310
:param retcode: Expected return code, or None for don't-care.
1311
:param encoding: Encoding for sys.stdout and sys.stderr
1312
:param stdin: A string to be used as stdin for the command.
1313
:param working_dir: Change to this directory before running
1315
return self._run_bzr_autosplit(argv, retcode=retcode,
1316
encoding=encoding, stdin=stdin, working_dir=working_dir,
1319
1301
def _run_bzr_autosplit(self, args, retcode, encoding, stdin,
1321
1303
"""Run bazaar command line, splitting up a string command line."""
1322
1304
if isinstance(args, basestring):
1323
args = list(shlex.split(args))
1305
# shlex don't understand unicode strings,
1306
# so args should be plain string (bialix 20070906)
1307
args = list(shlex.split(str(args)))
1324
1308
return self._run_bzr_core(args, retcode=retcode,
1325
1309
encoding=encoding, stdin=stdin, working_dir=working_dir,
1370
1354
message='Unexpected return code')
1371
1355
return out, err
1373
def run_bzr(self, *args, **kwargs):
1357
def run_bzr(self, args, retcode=0, encoding=None, stdin=None,
1358
working_dir=None, error_regexes=[], output_encoding=None):
1374
1359
"""Invoke bzr, as if it were run from the command line.
1376
1361
The argument list should not include the bzr program name - the
1384
1369
2- A single string, eg "add a". This is the most convenient
1385
1370
for hardcoded commands.
1387
3- Several varargs parameters, eg run_bzr("add", "a").
1388
This is not recommended for new code.
1390
1372
This runs bzr through the interface that catches and reports
1391
1373
errors, and with logging set to something approximating the
1392
1374
default, so that error reporting can be checked.
1405
1387
:keyword error_regexes: A list of expected error messages. If
1406
1388
specified they must be seen in the error output of the command.
1408
retcode = kwargs.pop('retcode', 0)
1409
encoding = kwargs.pop('encoding', None)
1410
stdin = kwargs.pop('stdin', None)
1411
working_dir = kwargs.pop('working_dir', None)
1412
error_regexes = kwargs.pop('error_regexes', [])
1415
raise TypeError("run_bzr() got unexpected keyword arguments '%s'"
1419
if isinstance(args[0], (list, basestring)):
1422
symbol_versioning.warn(zero_eighteen % "passing varargs to run_bzr",
1423
DeprecationWarning, stacklevel=3)
1425
out, err = self._run_bzr_autosplit(args=args,
1390
out, err = self._run_bzr_autosplit(
1426
1392
retcode=retcode,
1427
encoding=encoding, stdin=stdin, working_dir=working_dir,
1395
working_dir=working_dir,
1430
1397
for regex in error_regexes:
1431
1398
self.assertContainsRe(err, regex)
1432
1399
return out, err
1434
def run_bzr_decode(self, *args, **kwargs):
1435
if 'encoding' in kwargs:
1436
encoding = kwargs['encoding']
1438
encoding = bzrlib.user_encoding
1439
return self.run_bzr(*args, **kwargs)[0].decode(encoding)
1441
1401
def run_bzr_error(self, error_regexes, *args, **kwargs):
1442
1402
"""Run bzr, and check that stderr contains the supplied regexes
1875
1835
base = self.get_vfs_only_server().get_url()
1876
1836
return self._adjust_url(base, relpath)
1838
def _create_safety_net(self):
1839
"""Make a fake bzr directory.
1841
This prevents any tests propagating up onto the TEST_ROOT directory's
1844
root = TestCaseWithMemoryTransport.TEST_ROOT
1845
bzrdir.BzrDir.create_standalone_workingtree(root)
1847
def _check_safety_net(self):
1848
"""Check that the safety .bzr directory have not been touched.
1850
_make_test_root have created a .bzr directory to prevent tests from
1851
propagating. This method ensures than a test did not leaked.
1853
root = TestCaseWithMemoryTransport.TEST_ROOT
1854
wt = workingtree.WorkingTree.open(root)
1855
last_rev = wt.last_revision()
1856
if last_rev != 'null:':
1857
# The current test have modified the /bzr directory, we need to
1858
# recreate a new one or all the followng tests will fail.
1859
# If you need to inspect its content uncomment the following line
1860
# import pdb; pdb.set_trace()
1861
_rmtree_temp_dir(root + '/.bzr')
1862
self._create_safety_net()
1863
raise AssertionError('%s/.bzr should not be modified' % root)
1878
1865
def _make_test_root(self):
1879
if TestCaseWithMemoryTransport.TEST_ROOT is not None:
1881
root = tempfile.mkdtemp(prefix='testbzr-', suffix='.tmp')
1882
TestCaseWithMemoryTransport.TEST_ROOT = root
1884
# make a fake bzr directory there to prevent any tests propagating
1885
# up onto the source directory's real branch
1886
bzrdir.BzrDir.create_standalone_workingtree(root)
1888
# The same directory is used by all tests, and we're not specifically
1889
# told when all tests are finished. This will do.
1890
atexit.register(_rmtree_temp_dir, root)
1866
if TestCaseWithMemoryTransport.TEST_ROOT is None:
1867
root = osutils.mkdtemp(prefix='testbzr-', suffix='.tmp')
1868
TestCaseWithMemoryTransport.TEST_ROOT = root
1870
self._create_safety_net()
1872
# The same directory is used by all tests, and we're not
1873
# specifically told when all tests are finished. This will do.
1874
atexit.register(_rmtree_temp_dir, root)
1876
self.addCleanup(self._check_safety_net)
1892
1878
def makeAndChdirToTestDir(self):
1893
1879
"""Create a temporary directories for this one test.
1994
1980
name and then create two subdirs - test and home under it.
1996
1982
# create a directory within the top level test directory
1997
candidate_dir = tempfile.mkdtemp(dir=self.TEST_ROOT)
1983
candidate_dir = osutils.mkdtemp(dir=self.TEST_ROOT)
1998
1984
# now create test and home directories within this dir
1999
1985
self.test_base_dir = candidate_dir
2000
1986
self.test_home_dir = self.test_base_dir + '/home'
2361
2347
'bzrlib.tests.test_api',
2362
2348
'bzrlib.tests.test_atomicfile',
2363
2349
'bzrlib.tests.test_bad_files',
2350
'bzrlib.tests.test_bisect_multi',
2364
2351
'bzrlib.tests.test_branch',
2365
2352
'bzrlib.tests.test_branchbuilder',
2366
2353
'bzrlib.tests.test_bugtracker',
2426
2413
'bzrlib.tests.test_permissions',
2427
2414
'bzrlib.tests.test_plugins',
2428
2415
'bzrlib.tests.test_progress',
2416
'bzrlib.tests.test_reconfigure',
2429
2417
'bzrlib.tests.test_reconcile',
2430
2418
'bzrlib.tests.test_registry',
2431
2419
'bzrlib.tests.test_remote',
2548
def multiply_scenarios(scenarios_left, scenarios_right):
2549
"""Multiply two sets of scenarios.
2551
:returns: the cartesian product of the two sets of scenarios, that is
2552
a scenario for every possible combination of a left scenario and a
2556
('%s,%s' % (left_name, right_name),
2557
dict(left_dict.items() + right_dict.items()))
2558
for left_name, left_dict in scenarios_left
2559
for right_name, right_dict in scenarios_right]
2560
2563
def adapt_modules(mods_list, adapter, loader, suite):
2561
2564
"""Adapt the modules in mods_list using adapter and add to suite."""
2562
2565
for test in iter_suite_tests(loader.loadTestsFromModuleNames(mods_list)):
2614
2617
return self.__class__.__name__
2620
class _SymlinkFeature(Feature):
2623
return osutils.has_symlinks()
2625
def feature_name(self):
2628
SymlinkFeature = _SymlinkFeature()
2617
2631
class TestScenarioApplier(object):
2618
2632
"""A tool to apply scenarios to tests."""
2641
2655
new_id = "%s(%s)" % (new_test.id(), scenario[0])
2642
2656
new_test.id = lambda: new_id
2643
2657
return new_test
2660
def probe_unicode_in_user_encoding():
2661
"""Try to encode several unicode strings to use in unicode-aware tests.
2662
Return first successfull match.
2664
:return: (unicode value, encoded plain string value) or (None, None)
2666
possible_vals = [u'm\xb5', u'\xe1', u'\u0410']
2667
for uni_val in possible_vals:
2669
str_val = uni_val.encode(bzrlib.user_encoding)
2670
except UnicodeEncodeError:
2671
# Try a different character
2674
return uni_val, str_val
2678
def probe_bad_non_ascii(encoding):
2679
"""Try to find [bad] character with code [128..255]
2680
that cannot be decoded to unicode in some encoding.
2681
Return None if all non-ascii characters is valid
2684
for i in xrange(128, 256):
2687
char.decode(encoding)
2688
except UnicodeDecodeError: