886
888
:param universal_newlines: Convert CRLF => LF
888
890
env_changes = kwargs.get('env_changes', {})
891
process = self.start_bzr_subprocess(args, env_changes=env_changes)
892
# We distinguish between retcode=None and retcode not passed.
893
supplied_retcode = kwargs.get('retcode', 0)
894
return self.finish_bzr_subprocess(process, retcode=supplied_retcode,
895
universal_newlines=kwargs.get('universal_newlines', False),
898
def start_bzr_subprocess(self, process_args, env_changes=None,
899
skip_if_plan_to_signal=False):
900
"""Start bzr in a subprocess for testing.
902
This starts a new Python interpreter and runs bzr in there.
903
This should only be used for tests that have a justifiable need for
904
this isolation: e.g. they are testing startup time, or signal
905
handling, or early startup code, etc. Subprocess code can't be
906
profiled or debugged so easily.
908
:param process_args: a list of arguments to pass to the bzr executable,
909
for example `['--version']`.
910
:param env_changes: A dictionary which lists changes to environment
911
variables. A value of None will unset the env variable.
912
The values must be strings. The change will only occur in the
913
child, so you don't need to fix the environment after running.
914
:param skip_if_plan_to_signal: raise TestSkipped when true and os.kill
917
:returns: Popen object for the started process.
919
if skip_if_plan_to_signal:
920
if not getattr(os, 'kill', None):
921
raise TestSkipped("os.kill not available.")
923
if env_changes is None:
892
927
def cleanup_environment():
897
932
for env_var, value in old_env.iteritems():
898
933
osutils.set_or_unset_env(env_var, value)
900
bzr_path = os.path.dirname(os.path.dirname(bzrlib.__file__))+'/bzr'
935
bzr_path = self.get_bzr_path()
904
938
# win32 subprocess doesn't support preexec_fn
905
939
# so we will avoid using it on all platforms, just to
906
940
# make sure the code path is used, and we don't break on win32
907
941
cleanup_environment()
908
process = Popen([sys.executable, bzr_path]+args,
909
stdout=PIPE, stderr=PIPE)
942
process = Popen([sys.executable, bzr_path] + list(process_args),
943
stdin=PIPE, stdout=PIPE, stderr=PIPE)
911
945
restore_environment()
913
out = process.stdout.read()
914
err = process.stderr.read()
916
if kwargs.get('universal_newlines', False):
948
def get_bzr_path(self):
949
"""Return the path of the 'bzr' executable for this test suite."""
950
bzr_path = os.path.dirname(os.path.dirname(bzrlib.__file__))+'/bzr'
951
if not os.path.isfile(bzr_path):
952
# We are probably installed. Assume sys.argv is the right file
953
bzr_path = sys.argv[0]
956
def finish_bzr_subprocess(self, process, retcode=0, send_signal=None,
957
universal_newlines=False, process_args=None):
958
"""Finish the execution of process.
960
:param process: the Popen object returned from start_bzr_subprocess.
961
:param retcode: The status code that is expected. Defaults to 0. If
962
None is supplied, the status code is not checked.
963
:param send_signal: an optional signal to send to the process.
964
:param universal_newlines: Convert CRLF => LF
965
:returns: (stdout, stderr)
967
if send_signal is not None:
968
os.kill(process.pid, send_signal)
969
out, err = process.communicate()
971
if universal_newlines:
917
972
out = out.replace('\r\n', '\n')
918
973
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
975
if retcode is not None and retcode != process.returncode:
976
if process_args is None:
977
process_args = "(unknown args)"
978
mutter('Output of bzr %s:\n%s', process_args, out)
979
mutter('Error for bzr %s:\n%s', process_args, err)
980
self.fail('Command bzr %s failed with retcode %s != %s'
981
% (process_args, retcode, process.returncode))
924
982
return [out, err]
926
984
def check_inventory_shape(self, inv, shape):
1213
1271
if relpath is not None and relpath != '.':
1214
1272
if not base.endswith('/'):
1215
1273
base = base + '/'
1216
base = base + urlutils.escape(relpath)
1274
# XXX: Really base should be a url; we did after all call
1275
# get_url()! But sometimes it's just a path (from
1276
# LocalAbspathServer), and it'd be wrong to append urlescaped data
1277
# to a non-escaped local path.
1278
if base.startswith('./') or base.startswith('/'):
1281
base += urlutils.escape(relpath)
1219
1284
def get_transport(self):
1240
1305
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)
1307
# might be a relative or absolute path
1308
maybe_a_url = self.get_url(relpath)
1309
segments = maybe_a_url.rsplit('/', 1)
1310
t = get_transport(maybe_a_url)
1311
if len(segments) > 1 and segments[-1] not in ('', '.'):
1249
t.mkdir(segments[-1])
1250
1314
except errors.FileExists:
1252
1316
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))
1317
format = bzrlib.bzrdir.BzrDirFormat.get_default_format()
1318
return format.initialize_on_transport(t)
1256
1319
except errors.UninitializableFormat:
1257
1320
raise TestSkipped("Format %s is not initializable." % format)
1261
1324
made_control = self.make_bzrdir(relpath, format=format)
1262
1325
return made_control.create_repository(shared=shared)
1327
def make_branch_and_memory_tree(self, relpath):
1328
"""Create a branch on the default transport and a MemoryTree for it."""
1329
b = self.make_branch(relpath)
1330
return memorytree.MemoryTree.create_on_branch(b)
1264
1332
def make_branch_and_tree(self, relpath, format=None):
1265
1333
"""Create a branch on the transport and a tree locally.
1335
If the transport is not a LocalTransport, the Tree can't be created on
1336
the transport. In that case the working tree is created in the local
1337
directory, and the returned tree's branch and repository will also be
1340
This will fail if the original default transport for this test
1341
case wasn't backed by the working directory, as the branch won't
1342
be on disk for us to open it.
1344
:param format: The BzrDirFormat.
1345
:returns: the WorkingTree.
1269
1347
# TODO: always use the local disk path for the working tree,
1270
1348
# this obviously requires a format that supports branch references
1275
1353
return b.bzrdir.create_workingtree()
1276
1354
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))
1355
# We can only make working trees locally at the moment. If the
1356
# transport can't support them, then reopen the branch on a local
1357
# transport, and create the working tree there.
1359
# Possibly we should instead keep
1360
# the non-disk-backed branch and create a local checkout?
1361
bd = bzrdir.BzrDir.open(relpath)
1362
return bd.create_workingtree()
1283
1364
def assertIsDirectory(self, relpath, transport):
1284
1365
"""Assert that relpath within transport is a directory.
1405
1486
'bzrlib.tests.test_errors',
1406
1487
'bzrlib.tests.test_escaped_store',
1407
1488
'bzrlib.tests.test_fetch',
1489
'bzrlib.tests.test_ftp_transport',
1408
1490
'bzrlib.tests.test_gpg',
1409
1491
'bzrlib.tests.test_graph',
1410
1492
'bzrlib.tests.test_hashcache',
1414
1496
'bzrlib.tests.test_ignores',
1415
1497
'bzrlib.tests.test_inv',
1416
1498
'bzrlib.tests.test_knit',
1499
'bzrlib.tests.test_lazy_import',
1417
1500
'bzrlib.tests.test_lockdir',
1418
1501
'bzrlib.tests.test_lockable_files',
1419
1502
'bzrlib.tests.test_log',
1503
'bzrlib.tests.test_memorytree',
1420
1504
'bzrlib.tests.test_merge',
1421
1505
'bzrlib.tests.test_merge3',
1422
1506
'bzrlib.tests.test_merge_core',
1441
1525
'bzrlib.tests.test_selftest',
1442
1526
'bzrlib.tests.test_setup',
1443
1527
'bzrlib.tests.test_sftp_transport',
1444
'bzrlib.tests.test_ftp_transport',
1445
1528
'bzrlib.tests.test_smart_add',
1529
'bzrlib.tests.test_smart_transport',
1446
1530
'bzrlib.tests.test_source',
1447
1531
'bzrlib.tests.test_status',
1448
1532
'bzrlib.tests.test_store',
1455
1539
'bzrlib.tests.test_transform',
1456
1540
'bzrlib.tests.test_transport',
1457
1541
'bzrlib.tests.test_tree',
1542
'bzrlib.tests.test_treebuilder',
1458
1543
'bzrlib.tests.test_tsort',
1459
1544
'bzrlib.tests.test_tuned_gzip',
1460
1545
'bzrlib.tests.test_ui',