875
877
# this hook should always be installed
876
878
request._install_hook()
880
def disable_directory_isolation(self):
881
"""Turn off directory isolation checks."""
882
self._directory_isolation = False
884
def enable_directory_isolation(self):
885
"""Enable directory isolation checks."""
886
self._directory_isolation = True
878
888
def _silenceUI(self):
879
889
"""Turn off UI for duration of test"""
880
890
# by default the UI is off; tests can turn it on if they want it.
935
945
def _lock_broken(self, result):
936
946
self._lock_actions.append(('broken', result))
948
def permit_dir(self, name):
949
"""Permit a directory to be used by this test. See permit_url."""
950
name_transport = get_transport(name)
951
self.permit_url(name)
952
self.permit_url(name_transport.base)
954
def permit_url(self, url):
955
"""Declare that url is an ok url to use in this test.
957
Do this for memory transports, temporary test directory etc.
959
Do not do this for the current working directory, /tmp, or any other
960
preexisting non isolated url.
962
if not url.endswith('/'):
964
self._bzr_selftest_roots.append(url)
966
def permit_source_tree_branch_repo(self):
967
"""Permit the source tree bzr is running from to be opened.
969
Some code such as bzrlib.version attempts to read from the bzr branch
970
that bzr is executing from (if any). This method permits that directory
971
to be used in the test suite.
973
path = self.get_source_path()
974
self.disable_directory_isolation()
977
tree = workingtree.WorkingTree.open(path)
978
except errors.NoWorkingTree:
981
self.enable_directory_isolation()
982
self.permit_url(tree.bzrdir.root_transport.base)
983
self.permit_url(tree.branch.bzrdir.root_transport.base)
984
self.permit_url(tree.branch.repository.bzrdir.root_transport.base)
986
def _preopen_isolate_transport(self, transport):
987
"""Check that all transport openings are done in the test work area."""
988
if isinstance(transport, chroot.ChrootTransport):
989
# Unwrap chrooted transports
990
url = transport.server.backing_transport.clone(
991
transport._safe_relpath('.')).base
994
# ReadonlySmartTCPServer_for_testing decorates the backing transport
995
# urls it is given by prepending readonly+. This is appropriate as the
996
# client shouldn't know that the server is readonly (or not readonly).
997
# We could register all servers twice, with readonly+ prepending, but
998
# that makes for a long list; this is about the same but easier to
1000
if url.startswith('readonly+'):
1001
url = url[len('readonly+'):]
1002
self._preopen_isolate_url(url)
1004
def _preopen_isolate_url(self, url):
1005
if not self._directory_isolation:
1007
# This prevents all transports, including e.g. sftp ones backed on disk
1008
# from working unless they are explicitly granted permission. We then
1009
# depend on the code that sets up test transports to check that they are
1010
# appropriately isolated and enable their use by calling
1011
# self.permit_transport()
1012
if not osutils.is_inside_any(self._bzr_selftest_roots, url):
1013
raise errors.BzrError("Attempt to escape test isolation: %r %r"
1014
% (url, self._bzr_selftest_roots))
938
1016
def start_server(self, transport_server, backing_server=None):
939
1017
"""Start transport_server for this test.
947
1025
transport_server.setUp(backing_server)
948
1026
self.addCleanup(transport_server.tearDown)
1027
# Obtain a real transport because if the server supplies a password, it
1028
# will be hidden from the base on the client side.
1029
t = get_transport(transport_server.get_url())
1030
# Some transport servers effectively chroot the backing transport;
1031
# others like SFTPServer don't - users of the transport can walk up the
1032
# transport to read the entire backing transport. This wouldn't matter
1033
# except that the workdir tests are given - and that they expect the
1034
# server's url to point at - is one directory under the safety net. So
1035
# Branch operations into the transport will attempt to walk up one
1036
# directory. Chrooting all servers would avoid this but also mean that
1037
# we wouldn't be testing directly against non-root urls. Alternatively
1038
# getting the test framework to start the server with a backing server
1039
# at the actual safety net directory would work too, but this then
1040
# means that the self.get_url/self.get_transport methods would need
1041
# to transform all their results. On balance its cleaner to handle it
1042
# here, and permit a higher url when we have one of these transports.
1043
if t.base.endswith('/work/'):
1044
# we have safety net/test root/work
1045
t = t.clone('../..')
1046
elif isinstance(transport_server, server.SmartTCPServer_for_testing):
1047
# The smart server adds a path similar to work, which is traversed
1048
# up from by the client. But the server is chrooted - the actual
1049
# backing transport is not escaped from, and VFS requests to the
1050
# root will error (because they try to escape the chroot).
1052
while t2.base != t.base:
1055
self.permit_url(t.base)
1057
def _track_transports(self):
1058
"""Install checks for transport usage."""
1059
# TestCase has no safe place it can write to.
1060
self._bzr_selftest_roots = []
1061
# Currently the easiest way to be sure that nothing is going on is to
1062
# hook into bzr dir opening. This leaves a small window of error for
1063
# transport tests, but they are well known, and we can improve on this
1065
bzrdir.BzrDir.hooks.install_named_hook("pre_open",
1066
self._preopen_isolate_transport, "Check bzr directories are safe.")
950
1068
def _ndiff_strings(self, a, b):
951
1069
"""Return ndiff between two strings containing lines.
1870
1988
return Popen(*args, **kwargs)
1990
def get_source_path(self):
1991
"""Return the path of the directory containing bzrlib."""
1992
return os.path.dirname(os.path.dirname(bzrlib.__file__))
1872
1994
def get_bzr_path(self):
1873
1995
"""Return the path of the 'bzr' executable for this test suite."""
1874
bzr_path = os.path.dirname(os.path.dirname(bzrlib.__file__))+'/bzr'
1996
bzr_path = self.get_source_path()+'/bzr'
1875
1997
if not os.path.isfile(bzr_path):
1876
1998
# We are probably installed. Assume sys.argv is the right file
1877
1999
bzr_path = sys.argv[0]
2375
2500
if os.path.exists(name):
2376
2501
name = name_prefix + '_' + str(i)
2503
# now create test and home directories within this dir
2504
self.test_base_dir = name
2505
self.addCleanup(self.deleteTestDir)
2506
os.mkdir(self.test_base_dir)
2380
# now create test and home directories within this dir
2381
self.test_base_dir = name
2508
self.permit_dir(self.test_base_dir)
2509
# 'sprouting' and 'init' of a branch both walk up the tree to find
2510
# stacking policy to honour; create a bzr dir with an unshared
2511
# repository (but not a branch - our code would be trying to escape
2512
# then!) to stop them, and permit it to be read.
2513
# control = bzrdir.BzrDir.create(self.test_base_dir)
2514
# control.create_repository()
2382
2515
self.test_home_dir = self.test_base_dir + '/home'
2383
2516
os.mkdir(self.test_home_dir)
2384
2517
self.test_dir = self.test_base_dir + '/work'