238
242
if isinstance(err[1], TestSkipped):
239
243
return self.addSkipped(test, err)
240
244
unittest.TestResult.addError(self, test, err)
245
method = getattr(test, 'setKeepLogfile', None)
246
if method is not None:
241
248
self.extractBenchmarkTime(test)
243
250
self.stream.writeln("ERROR %s" % self._testTimeString())
660
671
def _finishLogFile(self):
661
672
"""Finished with the log file.
663
Read contents into memory, close, and delete.
674
Close the file and delete it, unless setKeepLogfile was called.
665
676
if self._log_file is None:
667
678
bzrlib.trace.disable_test_log(self._log_nonce)
668
self._log_file.seek(0)
669
self._log_contents = self._log_file.read()
670
679
self._log_file.close()
671
os.remove(self._log_file_name)
672
self._log_file = self._log_file_name = None
680
self._log_file = None
681
if not self._keep_log_file:
682
os.remove(self._log_file_name)
683
self._log_file_name = None
685
def setKeepLogfile(self):
686
"""Make the logfile not be deleted when _finishLogFile is called."""
687
self._keep_log_file = True
674
689
def addCleanup(self, callable):
675
690
"""Arrange to run a callable when this case is torn down.
743
758
def log(self, *args):
747
"""Return as a string the log for this test"""
748
if self._log_file_name:
749
return open(self._log_file_name).read()
761
def _get_log(self, keep_log_file=False):
762
"""Return as a string the log for this test. If the file is still
763
on disk and keep_log_file=False, delete the log file and store the
764
content in self._log_contents."""
765
# flush the log file, to get all content
767
bzrlib.trace._trace_file.flush()
768
if self._log_contents:
751
769
return self._log_contents
752
# TODO: Delete the log after it's been read in
770
if self._log_file_name is not None:
771
logfile = open(self._log_file_name)
773
log_contents = logfile.read()
776
if not keep_log_file:
777
self._log_contents = log_contents
778
os.remove(self._log_file_name)
781
return "DELETED log file to reduce memory footprint"
754
783
def capture(self, cmd, retcode=0):
755
784
"""Shortcut that splits cmd into words, runs, and returns stdout"""
886
915
:param universal_newlines: Convert CRLF => LF
888
917
env_changes = kwargs.get('env_changes', {})
918
process = self.start_bzr_subprocess(args, env_changes=env_changes)
919
# We distinguish between retcode=None and retcode not passed.
920
supplied_retcode = kwargs.get('retcode', 0)
921
return self.finish_bzr_subprocess(process, retcode=supplied_retcode,
922
universal_newlines=kwargs.get('universal_newlines', False),
925
def start_bzr_subprocess(self, process_args, env_changes=None,
926
skip_if_plan_to_signal=False):
927
"""Start bzr in a subprocess for testing.
929
This starts a new Python interpreter and runs bzr in there.
930
This should only be used for tests that have a justifiable need for
931
this isolation: e.g. they are testing startup time, or signal
932
handling, or early startup code, etc. Subprocess code can't be
933
profiled or debugged so easily.
935
:param process_args: a list of arguments to pass to the bzr executable,
936
for example `['--version']`.
937
:param env_changes: A dictionary which lists changes to environment
938
variables. A value of None will unset the env variable.
939
The values must be strings. The change will only occur in the
940
child, so you don't need to fix the environment after running.
941
:param skip_if_plan_to_signal: raise TestSkipped when true and os.kill
944
:returns: Popen object for the started process.
946
if skip_if_plan_to_signal:
947
if not getattr(os, 'kill', None):
948
raise TestSkipped("os.kill not available.")
950
if env_changes is None:
892
954
def cleanup_environment():
897
959
for env_var, value in old_env.iteritems():
898
960
osutils.set_or_unset_env(env_var, value)
900
bzr_path = os.path.dirname(os.path.dirname(bzrlib.__file__))+'/bzr'
962
bzr_path = self.get_bzr_path()
904
965
# win32 subprocess doesn't support preexec_fn
905
966
# so we will avoid using it on all platforms, just to
906
967
# make sure the code path is used, and we don't break on win32
907
968
cleanup_environment()
908
process = Popen([sys.executable, bzr_path]+args,
909
stdout=PIPE, stderr=PIPE)
969
process = Popen([sys.executable, bzr_path] + list(process_args),
970
stdin=PIPE, stdout=PIPE, stderr=PIPE)
911
972
restore_environment()
913
out = process.stdout.read()
914
err = process.stderr.read()
916
if kwargs.get('universal_newlines', False):
975
def get_bzr_path(self):
976
"""Return the path of the 'bzr' executable for this test suite."""
977
bzr_path = os.path.dirname(os.path.dirname(bzrlib.__file__))+'/bzr'
978
if not os.path.isfile(bzr_path):
979
# We are probably installed. Assume sys.argv is the right file
980
bzr_path = sys.argv[0]
983
def finish_bzr_subprocess(self, process, retcode=0, send_signal=None,
984
universal_newlines=False, process_args=None):
985
"""Finish the execution of process.
987
:param process: the Popen object returned from start_bzr_subprocess.
988
:param retcode: The status code that is expected. Defaults to 0. If
989
None is supplied, the status code is not checked.
990
:param send_signal: an optional signal to send to the process.
991
:param universal_newlines: Convert CRLF => LF
992
:returns: (stdout, stderr)
994
if send_signal is not None:
995
os.kill(process.pid, send_signal)
996
out, err = process.communicate()
998
if universal_newlines:
917
999
out = out.replace('\r\n', '\n')
918
1000
err = err.replace('\r\n', '\n')
920
retcode = process.wait()
921
supplied_retcode = kwargs.get('retcode', 0)
922
if supplied_retcode is not None:
923
assert supplied_retcode == retcode
1002
if retcode is not None and retcode != process.returncode:
1003
if process_args is None:
1004
process_args = "(unknown args)"
1005
mutter('Output of bzr %s:\n%s', process_args, out)
1006
mutter('Error for bzr %s:\n%s', process_args, err)
1007
self.fail('Command bzr %s failed with retcode %s != %s'
1008
% (process_args, retcode, process.returncode))
924
1009
return [out, err]
926
1011
def check_inventory_shape(self, inv, shape):
1213
1298
if relpath is not None and relpath != '.':
1214
1299
if not base.endswith('/'):
1215
1300
base = base + '/'
1216
base = base + urlutils.escape(relpath)
1301
# XXX: Really base should be a url; we did after all call
1302
# get_url()! But sometimes it's just a path (from
1303
# LocalAbspathServer), and it'd be wrong to append urlescaped data
1304
# to a non-escaped local path.
1305
if base.startswith('./') or base.startswith('/'):
1308
base += urlutils.escape(relpath)
1219
1311
def get_transport(self):
1240
1332
def make_bzrdir(self, relpath, format=None):
1242
url = self.get_url(relpath)
1243
mutter('relpath %r => url %r', relpath, url)
1244
segments = url.split('/')
1245
if segments and segments[-1] not in ('', '.'):
1246
parent = '/'.join(segments[:-1])
1247
t = get_transport(parent)
1334
# might be a relative or absolute path
1335
maybe_a_url = self.get_url(relpath)
1336
segments = maybe_a_url.rsplit('/', 1)
1337
t = get_transport(maybe_a_url)
1338
if len(segments) > 1 and segments[-1] not in ('', '.'):
1249
t.mkdir(segments[-1])
1250
1341
except errors.FileExists:
1252
1343
if format is None:
1253
format=bzrlib.bzrdir.BzrDirFormat.get_default_format()
1254
# FIXME: make this use a single transport someday. RBC 20060418
1255
return format.initialize_on_transport(get_transport(relpath))
1344
format = bzrlib.bzrdir.BzrDirFormat.get_default_format()
1345
return format.initialize_on_transport(t)
1256
1346
except errors.UninitializableFormat:
1257
1347
raise TestSkipped("Format %s is not initializable." % format)
1261
1351
made_control = self.make_bzrdir(relpath, format=format)
1262
1352
return made_control.create_repository(shared=shared)
1354
def make_branch_and_memory_tree(self, relpath):
1355
"""Create a branch on the default transport and a MemoryTree for it."""
1356
b = self.make_branch(relpath)
1357
return memorytree.MemoryTree.create_on_branch(b)
1264
1359
def make_branch_and_tree(self, relpath, format=None):
1265
1360
"""Create a branch on the transport and a tree locally.
1362
If the transport is not a LocalTransport, the Tree can't be created on
1363
the transport. In that case the working tree is created in the local
1364
directory, and the returned tree's branch and repository will also be
1367
This will fail if the original default transport for this test
1368
case wasn't backed by the working directory, as the branch won't
1369
be on disk for us to open it.
1371
:param format: The BzrDirFormat.
1372
:returns: the WorkingTree.
1269
1374
# TODO: always use the local disk path for the working tree,
1270
1375
# this obviously requires a format that supports branch references
1275
1380
return b.bzrdir.create_workingtree()
1276
1381
except errors.NotLocalUrl:
1277
# new formats - catch No tree error and create
1278
# a branch reference and a checkout.
1279
# old formats at that point - raise TestSkipped.
1280
# TODO: rbc 20060208
1281
return WorkingTreeFormat2().initialize(bzrdir.BzrDir.open(relpath))
1382
# We can only make working trees locally at the moment. If the
1383
# transport can't support them, then reopen the branch on a local
1384
# transport, and create the working tree there.
1386
# Possibly we should instead keep
1387
# the non-disk-backed branch and create a local checkout?
1388
bd = bzrdir.BzrDir.open(relpath)
1389
return bd.create_workingtree()
1283
1391
def assertIsDirectory(self, relpath, transport):
1284
1392
"""Assert that relpath within transport is a directory.
1405
1513
'bzrlib.tests.test_errors',
1406
1514
'bzrlib.tests.test_escaped_store',
1407
1515
'bzrlib.tests.test_fetch',
1516
'bzrlib.tests.test_ftp_transport',
1408
1517
'bzrlib.tests.test_gpg',
1409
1518
'bzrlib.tests.test_graph',
1410
1519
'bzrlib.tests.test_hashcache',
1414
1523
'bzrlib.tests.test_ignores',
1415
1524
'bzrlib.tests.test_inv',
1416
1525
'bzrlib.tests.test_knit',
1526
'bzrlib.tests.test_lazy_import',
1417
1527
'bzrlib.tests.test_lockdir',
1418
1528
'bzrlib.tests.test_lockable_files',
1419
1529
'bzrlib.tests.test_log',
1530
'bzrlib.tests.test_memorytree',
1420
1531
'bzrlib.tests.test_merge',
1421
1532
'bzrlib.tests.test_merge3',
1422
1533
'bzrlib.tests.test_merge_core',
1441
1552
'bzrlib.tests.test_selftest',
1442
1553
'bzrlib.tests.test_setup',
1443
1554
'bzrlib.tests.test_sftp_transport',
1444
'bzrlib.tests.test_ftp_transport',
1445
1555
'bzrlib.tests.test_smart_add',
1556
'bzrlib.tests.test_smart_transport',
1446
1557
'bzrlib.tests.test_source',
1447
1558
'bzrlib.tests.test_status',
1448
1559
'bzrlib.tests.test_store',
1455
1566
'bzrlib.tests.test_transform',
1456
1567
'bzrlib.tests.test_transport',
1457
1568
'bzrlib.tests.test_tree',
1569
'bzrlib.tests.test_treebuilder',
1458
1570
'bzrlib.tests.test_tsort',
1459
1571
'bzrlib.tests.test_tuned_gzip',
1460
1572
'bzrlib.tests.test_ui',
1462
1574
'bzrlib.tests.test_urlutils',
1463
1575
'bzrlib.tests.test_versionedfile',
1464
1576
'bzrlib.tests.test_version',
1577
'bzrlib.tests.test_version_info',
1465
1578
'bzrlib.tests.test_weave',
1466
1579
'bzrlib.tests.test_whitebox',
1467
1580
'bzrlib.tests.test_workingtree',