~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/__init__.py

  • Committer: Robert Collins
  • Date: 2006-09-17 21:03:04 UTC
  • mfrom: (2018 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2019.
  • Revision ID: robertc@robertcollins.net-20060917210304-3a697132f5fb68ac
Merge bzr.dev.

Show diffs side-by-side

added added

removed removed

Lines of Context:
43
43
import time
44
44
 
45
45
 
 
46
from bzrlib import memorytree
46
47
import bzrlib.branch
47
48
import bzrlib.bzrdir as bzrdir
48
49
import bzrlib.commands
94
95
                      bzrlib.merge3,
95
96
                      bzrlib.option,
96
97
                      bzrlib.osutils,
97
 
                      bzrlib.store
 
98
                      bzrlib.store,
 
99
                      bzrlib.transport,
98
100
                      ]
99
101
 
100
102
 
886
888
        :param universal_newlines: Convert CRLF => LF
887
889
        """
888
890
        env_changes = kwargs.get('env_changes', {})
889
 
 
 
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),
 
896
            process_args=args)
 
897
 
 
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.
 
901
 
 
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.
 
907
 
 
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
 
915
            is not available.
 
916
 
 
917
        :returns: Popen object for the started process.
 
918
        """
 
919
        if skip_if_plan_to_signal:
 
920
            if not getattr(os, 'kill', None):
 
921
                raise TestSkipped("os.kill not available.")
 
922
 
 
923
        if env_changes is None:
 
924
            env_changes = {}
890
925
        old_env = {}
891
926
 
892
927
        def cleanup_environment():
898
933
                osutils.set_or_unset_env(env_var, value)
899
934
 
900
935
        bzr_path = os.path.dirname(os.path.dirname(bzrlib.__file__))+'/bzr'
901
 
        args = list(args)
 
936
        if not os.path.isfile(bzr_path):
 
937
            # We are probably installed. Assume sys.argv is the right file
 
938
            bzr_path = sys.argv[0]
902
939
 
903
940
        try:
904
941
            # win32 subprocess doesn't support preexec_fn
905
942
            # so we will avoid using it on all platforms, just to
906
943
            # make sure the code path is used, and we don't break on win32
907
944
            cleanup_environment()
908
 
            process = Popen([sys.executable, bzr_path]+args,
909
 
                             stdout=PIPE, stderr=PIPE)
 
945
            process = Popen([sys.executable, bzr_path] + list(process_args),
 
946
                             stdin=PIPE, stdout=PIPE, stderr=PIPE)
910
947
        finally:
911
948
            restore_environment()
912
 
            
913
 
        out = process.stdout.read()
914
 
        err = process.stderr.read()
915
 
 
916
 
        if kwargs.get('universal_newlines', False):
 
949
        return process
 
950
 
 
951
    def finish_bzr_subprocess(self, process, retcode=0, send_signal=None,
 
952
                              universal_newlines=False, process_args=None):
 
953
        """Finish the execution of process.
 
954
 
 
955
        :param process: the Popen object returned from start_bzr_subprocess.
 
956
        :param retcode: The status code that is expected.  Defaults to 0.  If
 
957
            None is supplied, the status code is not checked.
 
958
        :param send_signal: an optional signal to send to the process.
 
959
        :param universal_newlines: Convert CRLF => LF
 
960
        :returns: (stdout, stderr)
 
961
        """
 
962
        if send_signal is not None:
 
963
            os.kill(process.pid, send_signal)
 
964
        out, err = process.communicate()
 
965
 
 
966
        if universal_newlines:
917
967
            out = out.replace('\r\n', '\n')
918
968
            err = err.replace('\r\n', '\n')
919
969
 
920
 
        retcode = process.wait()
921
 
        supplied_retcode = kwargs.get('retcode', 0)
922
 
        if supplied_retcode is not None:
923
 
            assert supplied_retcode == retcode
 
970
        if retcode is not None and retcode != process.returncode:
 
971
            if process_args is None:
 
972
                process_args = "(unknown args)"
 
973
            mutter('Output of bzr %s:\n%s', process_args, out)
 
974
            mutter('Error for bzr %s:\n%s', process_args, err)
 
975
            self.fail('Command bzr %s failed with retcode %s != %s'
 
976
                      % (process_args, retcode, process.returncode))
924
977
        return [out, err]
925
978
 
926
979
    def check_inventory_shape(self, inv, shape):
1202
1255
        return self.__server
1203
1256
 
1204
1257
    def get_url(self, relpath=None):
1205
 
        """Get a URL for the readwrite transport.
 
1258
        """Get a URL (or maybe a path) for the readwrite transport.
1206
1259
 
1207
1260
        This will either be backed by '.' or to an equivalent non-file based
1208
1261
        facility.
1213
1266
        if relpath is not None and relpath != '.':
1214
1267
            if not base.endswith('/'):
1215
1268
                base = base + '/'
1216
 
            base = base + urlutils.escape(relpath)
 
1269
            # XXX: Really base should be a url; we did after all call
 
1270
            # get_url()!  But sometimes it's just a path (from
 
1271
            # LocalAbspathServer), and it'd be wrong to append urlescaped data
 
1272
            # to a non-escaped local path.
 
1273
            if base.startswith('./') or base.startswith('/'):
 
1274
                base += relpath
 
1275
            else:
 
1276
                base += urlutils.escape(relpath)
1217
1277
        return base
1218
1278
 
1219
1279
    def get_transport(self):
1239
1299
 
1240
1300
    def make_bzrdir(self, relpath, format=None):
1241
1301
        try:
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)
 
1302
            # might be a relative or absolute path
 
1303
            maybe_a_url = self.get_url(relpath)
 
1304
            segments = maybe_a_url.rsplit('/', 1)
 
1305
            t = get_transport(maybe_a_url)
 
1306
            if len(segments) > 1 and segments[-1] not in ('', '.'):
1248
1307
                try:
1249
 
                    t.mkdir(segments[-1])
 
1308
                    t.mkdir('.')
1250
1309
                except errors.FileExists:
1251
1310
                    pass
1252
1311
            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))
 
1312
                format = bzrlib.bzrdir.BzrDirFormat.get_default_format()
 
1313
            return format.initialize_on_transport(t)
1256
1314
        except errors.UninitializableFormat:
1257
1315
            raise TestSkipped("Format %s is not initializable." % format)
1258
1316
 
1261
1319
        made_control = self.make_bzrdir(relpath, format=format)
1262
1320
        return made_control.create_repository(shared=shared)
1263
1321
 
 
1322
    def make_branch_and_memory_tree(self, relpath):
 
1323
        """Create a branch on the default transport and a MemoryTree for it."""
 
1324
        b = self.make_branch(relpath)
 
1325
        return memorytree.MemoryTree.create_on_branch(b)
 
1326
 
1264
1327
    def make_branch_and_tree(self, relpath, format=None):
1265
1328
        """Create a branch on the transport and a tree locally.
1266
1329
 
1267
 
        Returns the tree.
 
1330
        If the transport is not a LocalTransport, the Tree can't be created on
 
1331
        the transport.  In that case the working tree is created in the local
 
1332
        directory, and the returned tree's branch and repository will also be
 
1333
        accessed locally.
 
1334
 
 
1335
        This will fail if the original default transport for this test
 
1336
        case wasn't backed by the working directory, as the branch won't
 
1337
        be on disk for us to open it.  
 
1338
 
 
1339
        :param format: The BzrDirFormat.
 
1340
        :returns: the WorkingTree.
1268
1341
        """
1269
1342
        # TODO: always use the local disk path for the working tree,
1270
1343
        # this obviously requires a format that supports branch references
1274
1347
        try:
1275
1348
            return b.bzrdir.create_workingtree()
1276
1349
        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))
 
1350
            # We can only make working trees locally at the moment.  If the
 
1351
            # transport can't support them, then reopen the branch on a local
 
1352
            # transport, and create the working tree there.  
 
1353
            #
 
1354
            # Possibly we should instead keep
 
1355
            # the non-disk-backed branch and create a local checkout?
 
1356
            bd = bzrdir.BzrDir.open(relpath)
 
1357
            return bd.create_workingtree()
1282
1358
 
1283
1359
    def assertIsDirectory(self, relpath, transport):
1284
1360
        """Assert that relpath within transport is a directory.
1405
1481
                   'bzrlib.tests.test_errors',
1406
1482
                   'bzrlib.tests.test_escaped_store',
1407
1483
                   'bzrlib.tests.test_fetch',
 
1484
                   'bzrlib.tests.test_ftp_transport',
1408
1485
                   'bzrlib.tests.test_gpg',
1409
1486
                   'bzrlib.tests.test_graph',
1410
1487
                   'bzrlib.tests.test_hashcache',
1414
1491
                   'bzrlib.tests.test_ignores',
1415
1492
                   'bzrlib.tests.test_inv',
1416
1493
                   'bzrlib.tests.test_knit',
 
1494
                   'bzrlib.tests.test_lazy_import',
1417
1495
                   'bzrlib.tests.test_lockdir',
1418
1496
                   'bzrlib.tests.test_lockable_files',
1419
1497
                   'bzrlib.tests.test_log',
 
1498
                   'bzrlib.tests.test_memorytree',
1420
1499
                   'bzrlib.tests.test_merge',
1421
1500
                   'bzrlib.tests.test_merge3',
1422
1501
                   'bzrlib.tests.test_merge_core',
1441
1520
                   'bzrlib.tests.test_selftest',
1442
1521
                   'bzrlib.tests.test_setup',
1443
1522
                   'bzrlib.tests.test_sftp_transport',
1444
 
                   'bzrlib.tests.test_ftp_transport',
1445
1523
                   'bzrlib.tests.test_smart_add',
 
1524
                   'bzrlib.tests.test_smart_transport',
1446
1525
                   'bzrlib.tests.test_source',
1447
1526
                   'bzrlib.tests.test_status',
1448
1527
                   'bzrlib.tests.test_store',
1455
1534
                   'bzrlib.tests.test_transform',
1456
1535
                   'bzrlib.tests.test_transport',
1457
1536
                   'bzrlib.tests.test_tree',
 
1537
                   'bzrlib.tests.test_treebuilder',
1458
1538
                   'bzrlib.tests.test_tsort',
1459
1539
                   'bzrlib.tests.test_tuned_gzip',
1460
1540
                   'bzrlib.tests.test_ui',