574
579
for feature, count in sorted(result.unsupported.items()):
575
580
self.stream.writeln("Missing feature '%s' skipped %d tests." %
576
581
(feature, count))
577
result.report_cleaning_up()
578
# This is still a little bogus,
579
# but only a little. Folk not using our testrunner will
580
# have to delete their temp directories themselves.
581
test_root = TestCaseWithMemoryTransport.TEST_ROOT
582
if result.wasSuccessful() or not self.keep_output:
583
if test_root is not None:
584
# If LANG=C we probably have created some bogus paths
585
# which rmtree(unicode) will fail to delete
586
# so make sure we are using rmtree(str) to delete everything
587
# except on win32, where rmtree(str) will fail
588
# since it doesn't have the property of byte-stream paths
589
# (they are either ascii or mbcs)
590
if sys.platform == 'win32':
591
# make sure we are using the unicode win32 api
592
test_root = unicode(test_root)
594
test_root = test_root.encode(
595
sys.getfilesystemencoding())
596
_rmtree_temp_dir(test_root)
598
note("Failed tests working directories are in '%s'\n", test_root)
599
TestCaseWithMemoryTransport.TEST_ROOT = None
600
582
result.finished()
770
752
self._benchcalls = []
771
753
self._benchtime = None
772
754
self._clear_hooks()
755
self._clear_debug_flags()
757
def _clear_debug_flags(self):
758
"""Prevent externally set debug flags affecting tests.
760
Tests that want to use debug flags can just set them in the
761
debug_flags set during setup/teardown.
763
self._preserved_debug_flags = set(debug.debug_flags)
764
debug.debug_flags.clear()
765
self.addCleanup(self._restore_debug_flags)
774
767
def _clear_hooks(self):
775
768
# prevent hooks affecting tests
839
829
if message is None:
840
830
message = "texts not equal:\n"
841
raise AssertionError(message +
842
self._ndiff_strings(a, b))
831
raise AssertionError(message +
832
self._ndiff_strings(a, b))
844
834
def assertEqualMode(self, mode, mode_test):
845
835
self.assertEqual(mode, mode_test,
857
847
def assertContainsRe(self, haystack, needle_re):
858
848
"""Assert that a contains something matching a regular expression."""
859
849
if not re.search(needle_re, haystack):
860
raise AssertionError('pattern "%r" not found in "%r"'
861
% (needle_re, haystack))
850
if '\n' in haystack or len(haystack) > 60:
851
# a long string, format it in a more readable way
852
raise AssertionError(
853
'pattern "%s" not found in\n"""\\\n%s"""\n'
854
% (needle_re, haystack))
856
raise AssertionError('pattern "%s" not found in "%s"'
857
% (needle_re, haystack))
863
859
def assertNotContainsRe(self, haystack, needle_re):
864
860
"""Assert that a does not match a regular expression"""
894
890
excName = str(excClass)
895
891
raise self.failureException, "%s not raised" % excName
897
def assertRaises(self, excClass, func, *args, **kwargs):
893
def assertRaises(self, excClass, callableObj, *args, **kwargs):
898
894
"""Assert that a callable raises a particular exception.
900
896
:param excClass: As for the except statement, this may be either an
901
exception class, or a tuple of classes.
897
exception class, or a tuple of classes.
898
:param callableObj: A callable, will be passed ``*args`` and
903
901
Returns the exception so that you can examine it.
906
func(*args, **kwargs)
904
callableObj(*args, **kwargs)
907
905
except excClass, e:
988
986
:param args: The positional arguments for the callable
989
987
:param kwargs: The keyword arguments for the callable
990
988
:return: A tuple (warnings, result). result is the result of calling
991
a_callable(*args, **kwargs).
989
a_callable(``*args``, ``**kwargs``).
993
991
local_warnings = []
994
992
def capture_warnings(msg, cls=None, stacklevel=None):
1007
1005
def applyDeprecated(self, deprecation_format, a_callable, *args, **kwargs):
1008
1006
"""Call a deprecated callable without warning the user.
1008
Note that this only captures warnings raised by symbol_versioning.warn,
1009
not other callers that go direct to the warning module.
1010
1011
:param deprecation_format: The deprecation format that the callable
1011
should have been deprecated with. This is the same type as the
1012
parameter to deprecated_method/deprecated_function. If the
1012
should have been deprecated with. This is the same type as the
1013
parameter to deprecated_method/deprecated_function. If the
1013
1014
callable is not deprecated with this format, an assertion error
1014
1015
will be raised.
1015
1016
:param a_callable: A callable to call. This may be a bound method or
1016
a regular function. It will be called with *args and **kwargs.
1017
a regular function. It will be called with ``*args`` and
1017
1019
:param args: The positional arguments for the callable
1018
1020
:param kwargs: The keyword arguments for the callable
1019
:return: The result of a_callable(*args, **kwargs)
1021
:return: The result of a_callable(``*args``, ``**kwargs``)
1021
1023
call_warnings, result = self._capture_warnings(a_callable,
1022
1024
*args, **kwargs)
1036
1038
as it allows you to simply specify the deprecation format being used
1037
1039
and will ensure that that is issued for the function being called.
1041
Note that this only captures warnings raised by symbol_versioning.warn,
1042
not other callers that go direct to the warning module.
1039
1044
:param expected: a list of the deprecation warnings expected, in order
1040
1045
:param callable: The callable to call
1041
1046
:param args: The positional arguments for the callable
1119
1125
"""Set an environment variable, and reset it when finished."""
1120
1126
self.__old_env[name] = osutils.set_or_unset_env(name, newvalue)
1128
def _restore_debug_flags(self):
1129
debug.debug_flags.clear()
1130
debug.debug_flags.update(self._preserved_debug_flags)
1122
1132
def _restoreEnvironment(self):
1123
1133
for name, value in self.__old_env.iteritems():
1124
1134
osutils.set_or_unset_env(name, value)
1227
1238
if not feature.available():
1228
1239
raise UnavailableFeature(feature)
1241
@deprecated_method(zero_eighteen)
1230
1242
def run_bzr_captured(self, argv, retcode=0, encoding=None, stdin=None,
1231
1243
working_dir=None):
1232
1244
"""Invoke bzr and return (stdout, stderr).
1234
Useful for code that wants to check the contents of the
1235
output, the way error messages are presented, etc.
1237
This should be the main method for tests that want to exercise the
1238
overall behavior of the bzr application (rather than a unit test
1239
or a functional test of the library.)
1241
Much of the old code runs bzr by forking a new copy of Python, but
1242
that is slower, harder to debug, and generally not necessary.
1244
This runs bzr through the interface that catches and reports
1245
errors, and with logging set to something approximating the
1246
default, so that error reporting can be checked.
1248
:param argv: arguments to invoke bzr
1249
:param retcode: expected return code, or None for don't-care.
1250
:param encoding: encoding for sys.stdout and sys.stderr
1246
Don't call this method, just use run_bzr() which is equivalent.
1248
:param argv: Arguments to invoke bzr. This may be either a
1249
single string, in which case it is split by shlex into words,
1250
or a list of arguments.
1251
:param retcode: Expected return code, or None for don't-care.
1252
:param encoding: Encoding for sys.stdout and sys.stderr
1251
1253
:param stdin: A string to be used as stdin for the command.
1252
1254
:param working_dir: Change to this directory before running
1256
return self._run_bzr_autosplit(argv, retcode=retcode,
1257
encoding=encoding, stdin=stdin, working_dir=working_dir,
1260
def _run_bzr_autosplit(self, args, retcode, encoding, stdin,
1262
"""Run bazaar command line, splitting up a string command line."""
1263
if isinstance(args, basestring):
1264
args = list(shlex.split(args))
1265
return self._run_bzr_core(args, retcode=retcode,
1266
encoding=encoding, stdin=stdin, working_dir=working_dir,
1269
def _run_bzr_core(self, args, retcode, encoding, stdin,
1254
1271
if encoding is None:
1255
1272
encoding = bzrlib.user_encoding
1256
1273
stdout = StringIOWrapper()
1258
1275
stdout.encoding = encoding
1259
1276
stderr.encoding = encoding
1261
self.log('run bzr: %r', argv)
1278
self.log('run bzr: %r', args)
1262
1279
# FIXME: don't call into logging here
1263
1280
handler = logging.StreamHandler(stderr)
1264
1281
handler.setLevel(logging.INFO)
1273
1290
os.chdir(working_dir)
1276
saved_debug_flags = frozenset(debug.debug_flags)
1277
debug.debug_flags.clear()
1279
result = self.apply_redirected(ui.ui_factory.stdin,
1281
bzrlib.commands.run_bzr_catch_errors,
1284
debug.debug_flags.update(saved_debug_flags)
1293
result = self.apply_redirected(ui.ui_factory.stdin,
1295
bzrlib.commands.run_bzr_catch_errors,
1286
1298
logger.removeHandler(handler)
1287
1299
ui.ui_factory = old_ui_factory
1302
1314
def run_bzr(self, *args, **kwargs):
1303
1315
"""Invoke bzr, as if it were run from the command line.
1317
The argument list should not include the bzr program name - the
1318
first argument is normally the bzr command. Arguments may be
1319
passed in three ways:
1321
1- A list of strings, eg ["commit", "a"]. This is recommended
1322
when the command contains whitespace or metacharacters, or
1323
is built up at run time.
1325
2- A single string, eg "add a". This is the most convenient
1326
for hardcoded commands.
1328
3- Several varargs parameters, eg run_bzr("add", "a").
1329
This is not recommended for new code.
1331
This runs bzr through the interface that catches and reports
1332
errors, and with logging set to something approximating the
1333
default, so that error reporting can be checked.
1305
1335
This should be the main method for tests that want to exercise the
1306
1336
overall behavior of the bzr application (rather than a unit test
1307
1337
or a functional test of the library.)
1309
1339
This sends the stdout/stderr results into the test's log,
1310
1340
where it may be useful for debugging. See also run_captured.
1312
:param stdin: A string to be used as stdin for the command.
1313
:param retcode: The status code the command should return
1314
:param working_dir: The directory to run the command in
1342
:keyword stdin: A string to be used as stdin for the command.
1343
:keyword retcode: The status code the command should return;
1345
:keyword working_dir: The directory to run the command in
1346
:keyword error_regexes: A list of expected error messages. If
1347
specified they must be seen in the error output of the command.
1316
1349
retcode = kwargs.pop('retcode', 0)
1317
1350
encoding = kwargs.pop('encoding', None)
1319
1352
working_dir = kwargs.pop('working_dir', None)
1320
1353
error_regexes = kwargs.pop('error_regexes', [])
1322
out, err = self.run_bzr_captured(args, retcode=retcode,
1323
encoding=encoding, stdin=stdin, working_dir=working_dir)
1356
if isinstance(args[0], (list, basestring)):
1359
symbol_versioning.warn(zero_eighteen % "passing varargs to run_bzr",
1360
DeprecationWarning, stacklevel=3)
1362
out, err = self._run_bzr_autosplit(args=args,
1364
encoding=encoding, stdin=stdin, working_dir=working_dir,
1325
1367
for regex in error_regexes:
1326
1368
self.assertContainsRe(err, regex)
1327
1369
return out, err
1330
1371
def run_bzr_decode(self, *args, **kwargs):
1331
1372
if 'encoding' in kwargs:
1332
1373
encoding = kwargs['encoding']
1337
1378
def run_bzr_error(self, error_regexes, *args, **kwargs):
1338
1379
"""Run bzr, and check that stderr contains the supplied regexes
1340
:param error_regexes: Sequence of regular expressions which
1381
:param error_regexes: Sequence of regular expressions which
1341
1382
must each be found in the error output. The relative ordering
1342
1383
is not enforced.
1343
1384
:param args: command-line arguments for bzr
1344
1385
:param kwargs: Keyword arguments which are interpreted by run_bzr
1345
1386
This function changes the default value of retcode to be 3,
1346
1387
since in most cases this is run when you expect bzr to fail.
1347
:return: (out, err) The actual output of running the command (in case you
1348
want to do more inspection)
1389
:return: (out, err) The actual output of running the command (in case
1390
you want to do more inspection)
1351
1394
# Make sure that commit is failing because there is nothing to do
1352
1395
self.run_bzr_error(['no changes to commit'],
1353
1396
'commit', '-m', 'my commit comment')
1358
1401
'commit', '--strict', '-m', 'my commit comment')
1360
1403
kwargs.setdefault('retcode', 3)
1361
out, err = self.run_bzr(error_regexes=error_regexes, *args, **kwargs)
1404
kwargs['error_regexes'] = error_regexes
1405
out, err = self.run_bzr(*args, **kwargs)
1362
1406
return out, err
1364
1408
def run_bzr_subprocess(self, *args, **kwargs):
1370
1414
handling, or early startup code, etc. Subprocess code can't be
1371
1415
profiled or debugged so easily.
1373
:param retcode: The status code that is expected. Defaults to 0. If
1417
:keyword retcode: The status code that is expected. Defaults to 0. If
1374
1418
None is supplied, the status code is not checked.
1375
:param env_changes: A dictionary which lists changes to environment
1419
:keyword env_changes: A dictionary which lists changes to environment
1376
1420
variables. A value of None will unset the env variable.
1377
1421
The values must be strings. The change will only occur in the
1378
1422
child, so you don't need to fix the environment after running.
1379
:param universal_newlines: Convert CRLF => LF
1380
:param allow_plugins: By default the subprocess is run with
1423
:keyword universal_newlines: Convert CRLF => LF
1424
:keyword allow_plugins: By default the subprocess is run with
1381
1425
--no-plugins to ensure test reproducibility. Also, it is possible
1382
1426
for system-wide plugins to create unexpected output on stderr,
1383
1427
which can cause unnecessary test failures.
1407
1451
profiled or debugged so easily.
1409
1453
:param process_args: a list of arguments to pass to the bzr executable,
1410
for example `['--version']`.
1454
for example ``['--version']``.
1411
1455
:param env_changes: A dictionary which lists changes to environment
1412
1456
variables. A value of None will unset the env variable.
1413
1457
The values must be strings. The change will only occur in the
1554
1598
sys.stderr = real_stderr
1555
1599
sys.stdin = real_stdin
1557
@symbol_versioning.deprecated_method(symbol_versioning.zero_eleven)
1558
def merge(self, branch_from, wt_to):
1559
"""A helper for tests to do a ui-less merge.
1561
This should move to the main library when someone has time to integrate
1564
# minimal ui-less merge.
1565
wt_to.branch.fetch(branch_from)
1566
base_rev = common_ancestor(branch_from.last_revision(),
1567
wt_to.branch.last_revision(),
1568
wt_to.branch.repository)
1569
merge_inner(wt_to.branch, branch_from.basis_tree(),
1570
wt_to.branch.repository.revision_tree(base_rev),
1572
wt_to.add_parent_tree_id(branch_from.last_revision())
1574
1601
def reduceLockdirTimeout(self):
1575
1602
"""Reduce the default lock timeout for the duration of the test, so that
1576
1603
if LockContention occurs during a test, it does so quickly.
1600
1625
file defaults for the transport in tests, nor does it obey the command line
1601
1626
override, so tests that accidentally write to the common directory should
1629
:cvar TEST_ROOT: Directory containing all temporary directories, plus
1630
a .bzr directory that stops us ascending higher into the filesystem.
1605
1633
TEST_ROOT = None
1606
1634
_TEST_NAME = 'test'
1609
1636
def __init__(self, methodName='runTest'):
1610
1637
# allow test parameterisation after test construction and before test
1611
1638
# execution. Variables that the parameteriser sets need to be
1616
1643
self.transport_readonly_server = None
1617
1644
self.__vfs_server = None
1619
def get_transport(self):
1620
"""Return a writeable transport for the test scratch space"""
1621
t = get_transport(self.get_url())
1646
def get_transport(self, relpath=None):
1647
"""Return a writeable transport.
1649
This transport is for the test scratch space relative to
1652
:param relpath: a path relative to the base url.
1654
t = get_transport(self.get_url(relpath))
1622
1655
self.assertFalse(t.is_readonly())
1625
def get_readonly_transport(self):
1658
def get_readonly_transport(self, relpath=None):
1626
1659
"""Return a readonly transport for the test scratch space
1628
1661
This can be used to test that operations which should only need
1629
1662
readonly access in fact do not try to write.
1664
:param relpath: a path relative to the base url.
1631
t = get_transport(self.get_readonly_url())
1666
t = get_transport(self.get_readonly_url(relpath))
1632
1667
self.assertTrue(t.is_readonly())
1750
1781
capabilities of the local filesystem, but it might actually be a
1751
1782
MemoryTransport or some other similar virtual filesystem.
1753
This is the backing transport (if any) of the server returned by
1784
This is the backing transport (if any) of the server returned by
1754
1785
get_url and get_readonly_url.
1756
1787
:param relpath: provides for clients to get a path relative to the base
1757
1788
url. These should only be downwards relative, not upwards.
1759
1791
base = self.get_vfs_only_server().get_url()
1760
1792
return self._adjust_url(base, relpath)
1762
1794
def _make_test_root(self):
1763
1795
if TestCaseWithMemoryTransport.TEST_ROOT is not None:
1767
root = u'test%04d.tmp' % i
1771
if e.errno == errno.EEXIST:
1776
# successfully created
1777
TestCaseWithMemoryTransport.TEST_ROOT = osutils.abspath(root)
1797
root = tempfile.mkdtemp(prefix='testbzr-', suffix='.tmp')
1798
TestCaseWithMemoryTransport.TEST_ROOT = root
1779
1800
# make a fake bzr directory there to prevent any tests propagating
1780
1801
# up onto the source directory's real branch
1781
bzrdir.BzrDir.create_standalone_workingtree(
1782
TestCaseWithMemoryTransport.TEST_ROOT)
1802
bzrdir.BzrDir.create_standalone_workingtree(root)
1804
# The same directory is used by all tests, and we're not specifically
1805
# told when all tests are finished. This will do.
1806
atexit.register(_rmtree_temp_dir, root)
1784
1808
def makeAndChdirToTestDir(self):
1785
1809
"""Create a temporary directories for this one test.
1859
1883
All test cases create their own directory within that. If the
1860
1884
tests complete successfully, the directory is removed.
1862
InTempDir is an old alias for FunctionalTestCase.
1886
:ivar test_base_dir: The path of the top-level directory for this
1887
test, which contains a home directory and a work directory.
1889
:ivar test_home_dir: An initially empty directory under test_base_dir
1890
which is used as $HOME for this test.
1892
:ivar test_dir: A directory under test_base_dir used as the current
1893
directory when the test proper is run.
1865
1896
OVERRIDE_PYTHON = 'python'
1879
1910
For TestCaseInTempDir we create a temporary directory based on the test
1880
1911
name and then create two subdirs - test and home under it.
1882
if self.use_numbered_dirs: # strongly recommended on Windows
1883
# due the path length limitation (260 ch.)
1884
candidate_dir = '%s/%dK/%05d' % (self.TEST_ROOT,
1885
int(self.number/1000),
1887
os.makedirs(candidate_dir)
1888
self.test_home_dir = candidate_dir + '/home'
1889
os.mkdir(self.test_home_dir)
1890
self.test_dir = candidate_dir + '/work'
1891
os.mkdir(self.test_dir)
1892
os.chdir(self.test_dir)
1893
# put name of test inside
1894
f = file(candidate_dir + '/name', 'w')
1913
# create a directory within the top level test directory
1914
candidate_dir = tempfile.mkdtemp(dir=self.TEST_ROOT)
1915
# now create test and home directories within this dir
1916
self.test_base_dir = candidate_dir
1917
self.test_home_dir = self.test_base_dir + '/home'
1918
os.mkdir(self.test_home_dir)
1919
self.test_dir = self.test_base_dir + '/work'
1920
os.mkdir(self.test_dir)
1921
os.chdir(self.test_dir)
1922
# put name of test inside
1923
f = file(self.test_base_dir + '/name', 'w')
1895
1925
f.write(self.id())
1899
# shorten the name, to avoid test failures due to path length
1900
short_id = self.id().replace('bzrlib.tests.', '') \
1901
.replace('__main__.', '')[-100:]
1902
# it's possible the same test class is run several times for
1903
# parameterized tests, so make sure the names don't collide.
1907
candidate_dir = '%s/%s.%d' % (self.TEST_ROOT, short_id, i)
1909
candidate_dir = '%s/%s' % (self.TEST_ROOT, short_id)
1910
if os.path.exists(candidate_dir):
1914
os.mkdir(candidate_dir)
1915
self.test_home_dir = candidate_dir + '/home'
1916
os.mkdir(self.test_home_dir)
1917
self.test_dir = candidate_dir + '/work'
1918
os.mkdir(self.test_dir)
1919
os.chdir(self.test_dir)
1928
self.addCleanup(self.deleteTestDir)
1930
def deleteTestDir(self):
1931
os.chdir(self.TEST_ROOT)
1932
_rmtree_temp_dir(self.test_base_dir)
1922
1934
def build_tree(self, shape, line_endings='binary', transport=None):
1923
1935
"""Build a test tree according to a pattern.
1928
1940
This assumes that all the elements in the tree being built are new.
1930
1942
This doesn't add anything to a branch.
1931
1944
:param line_endings: Either 'binary' or 'native'
1932
in binary mode, exact contents are written
1933
in native mode, the line endings match the
1934
default platform endings.
1936
:param transport: A transport to write to, for building trees on
1937
VFS's. If the transport is readonly or None,
1938
"." is opened automatically.
1945
in binary mode, exact contents are written in native mode, the
1946
line endings match the default platform endings.
1947
:param transport: A transport to write to, for building trees on VFS's.
1948
If the transport is readonly or None, "." is opened automatically.
1940
1951
# It's OK to just create them using forward slashes on windows.
1941
1952
if transport is None or transport.is_readonly():
2161
2172
def run_suite(suite, name='test', verbose=False, pattern=".*",
2162
stop_on_failure=False, keep_output=False,
2173
stop_on_failure=False,
2163
2174
transport=None, lsprof_timed=None, bench_history=None,
2164
2175
matching_tests_first=None,
2165
2176
numbered_dirs=None,
2243
2252
suite = test_suite_factory()
2244
2253
return run_suite(suite, 'testbzr', verbose=verbose, pattern=pattern,
2245
stop_on_failure=stop_on_failure, keep_output=keep_output,
2254
stop_on_failure=stop_on_failure,
2246
2255
transport=transport,
2247
2256
lsprof_timed=lsprof_timed,
2248
2257
bench_history=bench_history,
2269
2278
'bzrlib.tests.test_atomicfile',
2270
2279
'bzrlib.tests.test_bad_files',
2271
2280
'bzrlib.tests.test_branch',
2281
'bzrlib.tests.test_branchbuilder',
2272
2282
'bzrlib.tests.test_bugtracker',
2273
2283
'bzrlib.tests.test_bundle',
2274
2284
'bzrlib.tests.test_bzrdir',
2278
2288
'bzrlib.tests.test_commit_merge',
2279
2289
'bzrlib.tests.test_config',
2280
2290
'bzrlib.tests.test_conflicts',
2291
'bzrlib.tests.test_pack',
2292
'bzrlib.tests.test_counted_lock',
2281
2293
'bzrlib.tests.test_decorators',
2282
2294
'bzrlib.tests.test_delta',
2295
'bzrlib.tests.test_deprecated_graph',
2283
2296
'bzrlib.tests.test_diff',
2284
2297
'bzrlib.tests.test_dirstate',
2285
2298
'bzrlib.tests.test_errors',
2294
2307
'bzrlib.tests.test_graph',
2295
2308
'bzrlib.tests.test_hashcache',
2296
2309
'bzrlib.tests.test_help',
2310
'bzrlib.tests.test_hooks',
2297
2311
'bzrlib.tests.test_http',
2298
2312
'bzrlib.tests.test_http_response',
2299
2313
'bzrlib.tests.test_https_ca_bundle',
2300
2314
'bzrlib.tests.test_identitymap',
2301
2315
'bzrlib.tests.test_ignores',
2316
'bzrlib.tests.test_info',
2302
2317
'bzrlib.tests.test_inv',
2303
2318
'bzrlib.tests.test_knit',
2304
2319
'bzrlib.tests.test_lazy_import',
2306
2321
'bzrlib.tests.test_lockdir',
2307
2322
'bzrlib.tests.test_lockable_files',
2308
2323
'bzrlib.tests.test_log',
2324
'bzrlib.tests.test_lsprof',
2309
2325
'bzrlib.tests.test_memorytree',
2310
2326
'bzrlib.tests.test_merge',
2311
2327
'bzrlib.tests.test_merge3',
2338
2354
'bzrlib.tests.test_smart',
2339
2355
'bzrlib.tests.test_smart_add',
2340
2356
'bzrlib.tests.test_smart_transport',
2357
'bzrlib.tests.test_smtp_connection',
2341
2358
'bzrlib.tests.test_source',
2342
2359
'bzrlib.tests.test_ssh_transport',
2343
2360
'bzrlib.tests.test_status',
2378
2395
suite = TestUtil.TestSuite()
2379
2396
loader = TestUtil.TestLoader()
2380
2397
suite.addTest(loader.loadTestsFromModuleNames(testmod_names))
2381
from bzrlib.transport import TransportTestProviderAdapter
2398
from bzrlib.tests.test_transport_implementations import TransportTestProviderAdapter
2382
2399
adapter = TransportTestProviderAdapter()
2383
2400
adapt_modules(test_transport_implementations, adapter, loader, suite)
2384
2401
for package in packages_to_test():
2419
2436
def _rmtree_temp_dir(dirname):
2437
# If LANG=C we probably have created some bogus paths
2438
# which rmtree(unicode) will fail to delete
2439
# so make sure we are using rmtree(str) to delete everything
2440
# except on win32, where rmtree(str) will fail
2441
# since it doesn't have the property of byte-stream paths
2442
# (they are either ascii or mbcs)
2443
if sys.platform == 'win32':
2444
# make sure we are using the unicode win32 api
2445
dirname = unicode(dirname)
2447
dirname = dirname.encode(sys.getfilesystemencoding())
2421
2449
osutils.rmtree(dirname)
2422
2450
except OSError, e:
2472
2500
if getattr(self, 'feature_name', None):
2473
2501
return self.feature_name()
2474
2502
return self.__class__.__name__
2505
class TestScenarioApplier(object):
2506
"""A tool to apply scenarios to tests."""
2508
def adapt(self, test):
2509
"""Return a TestSuite containing a copy of test for each scenario."""
2510
result = unittest.TestSuite()
2511
for scenario in self.scenarios:
2512
result.addTest(self.adapt_test_to_scenario(test, scenario))
2515
def adapt_test_to_scenario(self, test, scenario):
2516
"""Copy test and apply scenario to it.
2518
:param test: A test to adapt.
2519
:param scenario: A tuple describing the scenarion.
2520
The first element of the tuple is the new test id.
2521
The second element is a dict containing attributes to set on the
2523
:return: The adapted test.
2525
from copy import deepcopy
2526
new_test = deepcopy(test)
2527
for name, value in scenario[1].items():
2528
setattr(new_test, name, value)
2529
new_id = "%s(%s)" % (new_test.id(), scenario[0])
2530
new_test.id = lambda: new_id