/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/__init__.py

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
49
50
import bzrlib.bundle.serializer
50
51
import bzrlib.errors as errors
 
52
import bzrlib.export
51
53
import bzrlib.inventory
52
54
import bzrlib.iterablefile
53
55
import bzrlib.lockdir
88
90
                      bzrlib.bundle.serializer,
89
91
                      bzrlib.commands,
90
92
                      bzrlib.errors,
 
93
                      bzrlib.export,
91
94
                      bzrlib.inventory,
92
95
                      bzrlib.iterablefile,
93
96
                      bzrlib.lockdir,
94
97
                      bzrlib.merge3,
95
98
                      bzrlib.option,
96
99
                      bzrlib.osutils,
97
 
                      bzrlib.store
 
100
                      bzrlib.store,
 
101
                      bzrlib.transport,
98
102
                      ]
99
103
 
100
104
 
150
154
            from bzrlib.version import _get_bzr_source_tree
151
155
            src_tree = _get_bzr_source_tree()
152
156
            if src_tree:
153
 
                revision_id = src_tree.last_revision()
 
157
                try:
 
158
                    revision_id = src_tree.get_parent_ids()[0]
 
159
                except IndexError:
 
160
                    # XXX: if this is a brand new tree, do the same as if there
 
161
                    # is no branch.
 
162
                    revision_id = ''
154
163
            else:
155
164
                # XXX: If there's no branch, what should we do?
156
165
                revision_id = ''
233
242
        if isinstance(err[1], TestSkipped):
234
243
            return self.addSkipped(test, err)    
235
244
        unittest.TestResult.addError(self, test, err)
 
245
        # We can only do this if we have one of our TestCases, not if
 
246
        # we have a doctest.
 
247
        setKeepLogfile = getattr(test, 'setKeepLogfile', None)
 
248
        if setKeepLogfile is not None:
 
249
            setKeepLogfile()
236
250
        self.extractBenchmarkTime(test)
237
251
        if self.showAll:
238
252
            self.stream.writeln("ERROR %s" % self._testTimeString())
249
263
 
250
264
    def addFailure(self, test, err):
251
265
        unittest.TestResult.addFailure(self, test, err)
 
266
        # We can only do this if we have one of our TestCases, not if
 
267
        # we have a doctest.
 
268
        setKeepLogfile = getattr(test, 'setKeepLogfile', None)
 
269
        if setKeepLogfile is not None:
 
270
            setKeepLogfile()
252
271
        self.extractBenchmarkTime(test)
253
272
        if self.showAll:
254
273
            self.stream.writeln(" FAIL %s" % self._testTimeString())
475
494
 
476
495
    _log_file_name = None
477
496
    _log_contents = ''
 
497
    _keep_log_file = False
478
498
    # record lsprof data when performing benchmark calls.
479
499
    _gather_lsprof_in_benchmarks = False
480
500
 
655
675
    def _finishLogFile(self):
656
676
        """Finished with the log file.
657
677
 
658
 
        Read contents into memory, close, and delete.
 
678
        Close the file and delete it, unless setKeepLogfile was called.
659
679
        """
660
680
        if self._log_file is None:
661
681
            return
662
682
        bzrlib.trace.disable_test_log(self._log_nonce)
663
 
        self._log_file.seek(0)
664
 
        self._log_contents = self._log_file.read()
665
683
        self._log_file.close()
666
 
        os.remove(self._log_file_name)
667
 
        self._log_file = self._log_file_name = None
 
684
        self._log_file = None
 
685
        if not self._keep_log_file:
 
686
            os.remove(self._log_file_name)
 
687
            self._log_file_name = None
 
688
 
 
689
    def setKeepLogfile(self):
 
690
        """Make the logfile not be deleted when _finishLogFile is called."""
 
691
        self._keep_log_file = True
668
692
 
669
693
    def addCleanup(self, callable):
670
694
        """Arrange to run a callable when this case is torn down.
684
708
            'BZR_EMAIL': None,
685
709
            'BZREMAIL': None, # may still be present in the environment
686
710
            'EMAIL': None,
 
711
            'BZR_PROGRESS_BAR': None,
687
712
        }
688
713
        self.__old_env = {}
689
714
        self.addCleanup(self._restoreEnvironment)
690
715
        for name, value in new_env.iteritems():
691
716
            self._captureVar(name, value)
692
717
 
693
 
 
694
718
    def _captureVar(self, name, newvalue):
695
 
        """Set an environment variable, preparing it to be reset when finished."""
696
 
        self.__old_env[name] = os.environ.get(name, None)
697
 
        if newvalue is None:
698
 
            if name in os.environ:
699
 
                del os.environ[name]
700
 
        else:
701
 
            os.environ[name] = newvalue
702
 
 
703
 
    @staticmethod
704
 
    def _restoreVar(name, value):
705
 
        if value is None:
706
 
            if name in os.environ:
707
 
                del os.environ[name]
708
 
        else:
709
 
            os.environ[name] = value
 
719
        """Set an environment variable, and reset it when finished."""
 
720
        self.__old_env[name] = osutils.set_or_unset_env(name, newvalue)
710
721
 
711
722
    def _restoreEnvironment(self):
712
723
        for name, value in self.__old_env.iteritems():
713
 
            self._restoreVar(name, value)
 
724
            osutils.set_or_unset_env(name, value)
714
725
 
715
726
    def tearDown(self):
716
727
        self._runCleanups()
751
762
    def log(self, *args):
752
763
        mutter(*args)
753
764
 
754
 
    def _get_log(self):
755
 
        """Return as a string the log for this test"""
756
 
        if self._log_file_name:
757
 
            return open(self._log_file_name).read()
758
 
        else:
 
765
    def _get_log(self, keep_log_file=False):
 
766
        """Return as a string the log for this test. If the file is still
 
767
        on disk and keep_log_file=False, delete the log file and store the
 
768
        content in self._log_contents."""
 
769
        # flush the log file, to get all content
 
770
        import bzrlib.trace
 
771
        bzrlib.trace._trace_file.flush()
 
772
        if self._log_contents:
759
773
            return self._log_contents
760
 
        # TODO: Delete the log after it's been read in
 
774
        if self._log_file_name is not None:
 
775
            logfile = open(self._log_file_name)
 
776
            try:
 
777
                log_contents = logfile.read()
 
778
            finally:
 
779
                logfile.close()
 
780
            if not keep_log_file:
 
781
                self._log_contents = log_contents
 
782
                os.remove(self._log_file_name)
 
783
            return log_contents
 
784
        else:
 
785
            return "DELETED log file to reduce memory footprint"
761
786
 
762
787
    def capture(self, cmd, retcode=0):
763
788
        """Shortcut that splits cmd into words, runs, and returns stdout"""
764
789
        return self.run_bzr_captured(cmd.split(), retcode=retcode)[0]
765
790
 
766
 
    def run_bzr_captured(self, argv, retcode=0, encoding=None, stdin=None):
 
791
    def run_bzr_captured(self, argv, retcode=0, encoding=None, stdin=None,
 
792
                         working_dir=None):
767
793
        """Invoke bzr and return (stdout, stderr).
768
794
 
769
795
        Useful for code that wants to check the contents of the
784
810
        :param retcode: expected return code, or None for don't-care.
785
811
        :param encoding: encoding for sys.stdout and sys.stderr
786
812
        :param stdin: A string to be used as stdin for the command.
 
813
        :param working_dir: Change to this directory before running
787
814
        """
788
815
        if encoding is None:
789
816
            encoding = bzrlib.user_encoding
805
832
            stdout=stdout,
806
833
            stderr=stderr)
807
834
        bzrlib.ui.ui_factory.stdin = stdin
 
835
 
 
836
        cwd = None
 
837
        if working_dir is not None:
 
838
            cwd = osutils.getcwd()
 
839
            os.chdir(working_dir)
 
840
 
808
841
        try:
809
842
            result = self.apply_redirected(stdin, stdout, stderr,
810
843
                                           bzrlib.commands.run_bzr_catch_errors,
812
845
        finally:
813
846
            logger.removeHandler(handler)
814
847
            bzrlib.ui.ui_factory = old_ui_factory
 
848
            if cwd is not None:
 
849
                os.chdir(cwd)
815
850
 
816
851
        out = stdout.getvalue()
817
852
        err = stderr.getvalue()
838
873
        retcode = kwargs.pop('retcode', 0)
839
874
        encoding = kwargs.pop('encoding', None)
840
875
        stdin = kwargs.pop('stdin', None)
841
 
        return self.run_bzr_captured(args, retcode=retcode, encoding=encoding, stdin=stdin)
 
876
        working_dir = kwargs.pop('working_dir', None)
 
877
        return self.run_bzr_captured(args, retcode=retcode, encoding=encoding,
 
878
                                     stdin=stdin, working_dir=working_dir)
842
879
 
843
880
    def run_bzr_decode(self, *args, **kwargs):
844
881
        if 'encoding' in kwargs:
891
928
            variables. A value of None will unset the env variable.
892
929
            The values must be strings. The change will only occur in the
893
930
            child, so you don't need to fix the environment after running.
 
931
        :param universal_newlines: Convert CRLF => LF
894
932
        """
895
933
        env_changes = kwargs.get('env_changes', {})
 
934
        working_dir = kwargs.get('working_dir', None)
 
935
        process = self.start_bzr_subprocess(args, env_changes=env_changes,
 
936
                                            working_dir=working_dir)
 
937
        # We distinguish between retcode=None and retcode not passed.
 
938
        supplied_retcode = kwargs.get('retcode', 0)
 
939
        return self.finish_bzr_subprocess(process, retcode=supplied_retcode,
 
940
            universal_newlines=kwargs.get('universal_newlines', False),
 
941
            process_args=args)
 
942
 
 
943
    def start_bzr_subprocess(self, process_args, env_changes=None,
 
944
                             skip_if_plan_to_signal=False,
 
945
                             working_dir=None):
 
946
        """Start bzr in a subprocess for testing.
 
947
 
 
948
        This starts a new Python interpreter and runs bzr in there.
 
949
        This should only be used for tests that have a justifiable need for
 
950
        this isolation: e.g. they are testing startup time, or signal
 
951
        handling, or early startup code, etc.  Subprocess code can't be
 
952
        profiled or debugged so easily.
 
953
 
 
954
        :param process_args: a list of arguments to pass to the bzr executable,
 
955
            for example `['--version']`.
 
956
        :param env_changes: A dictionary which lists changes to environment
 
957
            variables. A value of None will unset the env variable.
 
958
            The values must be strings. The change will only occur in the
 
959
            child, so you don't need to fix the environment after running.
 
960
        :param skip_if_plan_to_signal: raise TestSkipped when true and os.kill
 
961
            is not available.
 
962
 
 
963
        :returns: Popen object for the started process.
 
964
        """
 
965
        if skip_if_plan_to_signal:
 
966
            if not getattr(os, 'kill', None):
 
967
                raise TestSkipped("os.kill not available.")
 
968
 
 
969
        if env_changes is None:
 
970
            env_changes = {}
 
971
        old_env = {}
 
972
 
896
973
        def cleanup_environment():
897
974
            for env_var, value in env_changes.iteritems():
898
 
                if value is None:
899
 
                    if env_var in os.environ:
900
 
                        del os.environ[env_var]
901
 
                else:
902
 
                    os.environ[env_var] = value
903
 
 
 
975
                old_env[env_var] = osutils.set_or_unset_env(env_var, value)
 
976
 
 
977
        def restore_environment():
 
978
            for env_var, value in old_env.iteritems():
 
979
                osutils.set_or_unset_env(env_var, value)
 
980
 
 
981
        bzr_path = self.get_bzr_path()
 
982
 
 
983
        cwd = None
 
984
        if working_dir is not None:
 
985
            cwd = osutils.getcwd()
 
986
            os.chdir(working_dir)
 
987
 
 
988
        try:
 
989
            # win32 subprocess doesn't support preexec_fn
 
990
            # so we will avoid using it on all platforms, just to
 
991
            # make sure the code path is used, and we don't break on win32
 
992
            cleanup_environment()
 
993
            process = Popen([sys.executable, bzr_path] + list(process_args),
 
994
                             stdin=PIPE, stdout=PIPE, stderr=PIPE)
 
995
        finally:
 
996
            restore_environment()
 
997
            if cwd is not None:
 
998
                os.chdir(cwd)
 
999
 
 
1000
        return process
 
1001
 
 
1002
    def get_bzr_path(self):
 
1003
        """Return the path of the 'bzr' executable for this test suite."""
904
1004
        bzr_path = os.path.dirname(os.path.dirname(bzrlib.__file__))+'/bzr'
905
 
        args = list(args)
906
 
        process = Popen([sys.executable, bzr_path]+args,
907
 
                         stdout=PIPE, stderr=PIPE,
908
 
                         preexec_fn=cleanup_environment)
909
 
        out = process.stdout.read()
910
 
        err = process.stderr.read()
911
 
        retcode = process.wait()
912
 
        supplied_retcode = kwargs.get('retcode', 0)
913
 
        if supplied_retcode is not None:
914
 
            assert supplied_retcode == retcode
 
1005
        if not os.path.isfile(bzr_path):
 
1006
            # We are probably installed. Assume sys.argv is the right file
 
1007
            bzr_path = sys.argv[0]
 
1008
        return bzr_path
 
1009
 
 
1010
    def finish_bzr_subprocess(self, process, retcode=0, send_signal=None,
 
1011
                              universal_newlines=False, process_args=None):
 
1012
        """Finish the execution of process.
 
1013
 
 
1014
        :param process: the Popen object returned from start_bzr_subprocess.
 
1015
        :param retcode: The status code that is expected.  Defaults to 0.  If
 
1016
            None is supplied, the status code is not checked.
 
1017
        :param send_signal: an optional signal to send to the process.
 
1018
        :param universal_newlines: Convert CRLF => LF
 
1019
        :returns: (stdout, stderr)
 
1020
        """
 
1021
        if send_signal is not None:
 
1022
            os.kill(process.pid, send_signal)
 
1023
        out, err = process.communicate()
 
1024
 
 
1025
        if universal_newlines:
 
1026
            out = out.replace('\r\n', '\n')
 
1027
            err = err.replace('\r\n', '\n')
 
1028
 
 
1029
        if retcode is not None and retcode != process.returncode:
 
1030
            if process_args is None:
 
1031
                process_args = "(unknown args)"
 
1032
            mutter('Output of bzr %s:\n%s', process_args, out)
 
1033
            mutter('Error for bzr %s:\n%s', process_args, err)
 
1034
            self.fail('Command bzr %s failed with retcode %s != %s'
 
1035
                      % (process_args, retcode, process.returncode))
915
1036
        return [out, err]
916
1037
 
917
1038
    def check_inventory_shape(self, inv, shape):
1052
1173
                i = i + 1
1053
1174
                continue
1054
1175
            else:
1055
 
                self.test_dir = candidate_dir
 
1176
                os.mkdir(candidate_dir)
 
1177
                self.test_home_dir = candidate_dir + '/home'
 
1178
                os.mkdir(self.test_home_dir)
 
1179
                self.test_dir = candidate_dir + '/work'
1056
1180
                os.mkdir(self.test_dir)
1057
1181
                os.chdir(self.test_dir)
1058
1182
                break
1059
 
        os.environ['HOME'] = self.test_dir
1060
 
        os.environ['APPDATA'] = self.test_dir
 
1183
        os.environ['HOME'] = self.test_home_dir
 
1184
        os.environ['APPDATA'] = self.test_home_dir
1061
1185
        def _leaveDirectory():
1062
1186
            os.chdir(_currentdir)
1063
1187
        self.addCleanup(_leaveDirectory)
1190
1314
        return self.__server
1191
1315
 
1192
1316
    def get_url(self, relpath=None):
1193
 
        """Get a URL for the readwrite transport.
 
1317
        """Get a URL (or maybe a path) for the readwrite transport.
1194
1318
 
1195
1319
        This will either be backed by '.' or to an equivalent non-file based
1196
1320
        facility.
1201
1325
        if relpath is not None and relpath != '.':
1202
1326
            if not base.endswith('/'):
1203
1327
                base = base + '/'
1204
 
            base = base + urlutils.escape(relpath)
 
1328
            # XXX: Really base should be a url; we did after all call
 
1329
            # get_url()!  But sometimes it's just a path (from
 
1330
            # LocalAbspathServer), and it'd be wrong to append urlescaped data
 
1331
            # to a non-escaped local path.
 
1332
            if base.startswith('./') or base.startswith('/'):
 
1333
                base += relpath
 
1334
            else:
 
1335
                base += urlutils.escape(relpath)
1205
1336
        return base
1206
1337
 
1207
1338
    def get_transport(self):
1227
1358
 
1228
1359
    def make_bzrdir(self, relpath, format=None):
1229
1360
        try:
1230
 
            url = self.get_url(relpath)
1231
 
            mutter('relpath %r => url %r', relpath, url)
1232
 
            segments = url.split('/')
1233
 
            if segments and segments[-1] not in ('', '.'):
1234
 
                parent = '/'.join(segments[:-1])
1235
 
                t = get_transport(parent)
 
1361
            # might be a relative or absolute path
 
1362
            maybe_a_url = self.get_url(relpath)
 
1363
            segments = maybe_a_url.rsplit('/', 1)
 
1364
            t = get_transport(maybe_a_url)
 
1365
            if len(segments) > 1 and segments[-1] not in ('', '.'):
1236
1366
                try:
1237
 
                    t.mkdir(segments[-1])
 
1367
                    t.mkdir('.')
1238
1368
                except errors.FileExists:
1239
1369
                    pass
1240
1370
            if format is None:
1241
 
                format=bzrlib.bzrdir.BzrDirFormat.get_default_format()
1242
 
            # FIXME: make this use a single transport someday. RBC 20060418
1243
 
            return format.initialize_on_transport(get_transport(relpath))
 
1371
                format = bzrlib.bzrdir.BzrDirFormat.get_default_format()
 
1372
            return format.initialize_on_transport(t)
1244
1373
        except errors.UninitializableFormat:
1245
1374
            raise TestSkipped("Format %s is not initializable." % format)
1246
1375
 
1249
1378
        made_control = self.make_bzrdir(relpath, format=format)
1250
1379
        return made_control.create_repository(shared=shared)
1251
1380
 
 
1381
    def make_branch_and_memory_tree(self, relpath):
 
1382
        """Create a branch on the default transport and a MemoryTree for it."""
 
1383
        b = self.make_branch(relpath)
 
1384
        return memorytree.MemoryTree.create_on_branch(b)
 
1385
 
1252
1386
    def make_branch_and_tree(self, relpath, format=None):
1253
1387
        """Create a branch on the transport and a tree locally.
1254
1388
 
1255
 
        Returns the tree.
 
1389
        If the transport is not a LocalTransport, the Tree can't be created on
 
1390
        the transport.  In that case the working tree is created in the local
 
1391
        directory, and the returned tree's branch and repository will also be
 
1392
        accessed locally.
 
1393
 
 
1394
        This will fail if the original default transport for this test
 
1395
        case wasn't backed by the working directory, as the branch won't
 
1396
        be on disk for us to open it.  
 
1397
 
 
1398
        :param format: The BzrDirFormat.
 
1399
        :returns: the WorkingTree.
1256
1400
        """
1257
1401
        # TODO: always use the local disk path for the working tree,
1258
1402
        # this obviously requires a format that supports branch references
1262
1406
        try:
1263
1407
            return b.bzrdir.create_workingtree()
1264
1408
        except errors.NotLocalUrl:
1265
 
            # new formats - catch No tree error and create
1266
 
            # a branch reference and a checkout.
1267
 
            # old formats at that point - raise TestSkipped.
1268
 
            # TODO: rbc 20060208
1269
 
            return WorkingTreeFormat2().initialize(bzrdir.BzrDir.open(relpath))
 
1409
            # We can only make working trees locally at the moment.  If the
 
1410
            # transport can't support them, then reopen the branch on a local
 
1411
            # transport, and create the working tree there.  
 
1412
            #
 
1413
            # Possibly we should instead keep
 
1414
            # the non-disk-backed branch and create a local checkout?
 
1415
            bd = bzrdir.BzrDir.open(relpath)
 
1416
            return bd.create_workingtree()
1270
1417
 
1271
1418
    def assertIsDirectory(self, relpath, transport):
1272
1419
        """Assert that relpath within transport is a directory.
1393
1540
                   'bzrlib.tests.test_errors',
1394
1541
                   'bzrlib.tests.test_escaped_store',
1395
1542
                   'bzrlib.tests.test_fetch',
 
1543
                   'bzrlib.tests.test_ftp_transport',
1396
1544
                   'bzrlib.tests.test_gpg',
1397
1545
                   'bzrlib.tests.test_graph',
1398
1546
                   'bzrlib.tests.test_hashcache',
1402
1550
                   'bzrlib.tests.test_ignores',
1403
1551
                   'bzrlib.tests.test_inv',
1404
1552
                   'bzrlib.tests.test_knit',
 
1553
                   'bzrlib.tests.test_lazy_import',
1405
1554
                   'bzrlib.tests.test_lockdir',
1406
1555
                   'bzrlib.tests.test_lockable_files',
1407
1556
                   'bzrlib.tests.test_log',
 
1557
                   'bzrlib.tests.test_memorytree',
1408
1558
                   'bzrlib.tests.test_merge',
1409
1559
                   'bzrlib.tests.test_merge3',
1410
1560
                   'bzrlib.tests.test_merge_core',
1429
1579
                   'bzrlib.tests.test_selftest',
1430
1580
                   'bzrlib.tests.test_setup',
1431
1581
                   'bzrlib.tests.test_sftp_transport',
1432
 
                   'bzrlib.tests.test_ftp_transport',
1433
1582
                   'bzrlib.tests.test_smart_add',
 
1583
                   'bzrlib.tests.test_smart_transport',
1434
1584
                   'bzrlib.tests.test_source',
1435
1585
                   'bzrlib.tests.test_status',
1436
1586
                   'bzrlib.tests.test_store',
1443
1593
                   'bzrlib.tests.test_transform',
1444
1594
                   'bzrlib.tests.test_transport',
1445
1595
                   'bzrlib.tests.test_tree',
 
1596
                   'bzrlib.tests.test_treebuilder',
1446
1597
                   'bzrlib.tests.test_tsort',
1447
1598
                   'bzrlib.tests.test_tuned_gzip',
1448
1599
                   'bzrlib.tests.test_ui',
1450
1601
                   'bzrlib.tests.test_urlutils',
1451
1602
                   'bzrlib.tests.test_versionedfile',
1452
1603
                   'bzrlib.tests.test_version',
 
1604
                   'bzrlib.tests.test_version_info',
1453
1605
                   'bzrlib.tests.test_weave',
1454
1606
                   'bzrlib.tests.test_whitebox',
1455
1607
                   'bzrlib.tests.test_workingtree',