/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

  • Committer: Aaron Bentley
  • Date: 2006-09-28 13:48:10 UTC
  • mfrom: (2049 +trunk)
  • mto: This revision was merged to the branch mainline in revision 2268.
  • Revision ID: abentley@panoramicfeedback.com-20060928134810-2c8ae086a4a70f43
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
63
65
import bzrlib.plugin
64
66
import bzrlib.progress as progress
65
67
from bzrlib.revision import common_ancestor
66
 
from bzrlib.revisionspec import RevisionSpec
67
68
import bzrlib.store
68
69
from bzrlib import symbol_versioning
69
70
import bzrlib.trace
89
90
                      bzrlib.bundle.serializer,
90
91
                      bzrlib.commands,
91
92
                      bzrlib.errors,
 
93
                      bzrlib.export,
92
94
                      bzrlib.inventory,
93
95
                      bzrlib.iterablefile,
94
96
                      bzrlib.lockdir,
95
97
                      bzrlib.merge3,
96
98
                      bzrlib.option,
97
99
                      bzrlib.osutils,
98
 
                      bzrlib.store
 
100
                      bzrlib.store,
 
101
                      bzrlib.transport,
99
102
                      ]
100
103
 
101
104
 
151
154
            from bzrlib.version import _get_bzr_source_tree
152
155
            src_tree = _get_bzr_source_tree()
153
156
            if src_tree:
154
 
                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 = ''
155
163
            else:
156
164
                # XXX: If there's no branch, what should we do?
157
165
                revision_id = ''
234
242
        if isinstance(err[1], TestSkipped):
235
243
            return self.addSkipped(test, err)    
236
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()
237
250
        self.extractBenchmarkTime(test)
238
251
        if self.showAll:
239
252
            self.stream.writeln("ERROR %s" % self._testTimeString())
250
263
 
251
264
    def addFailure(self, test, err):
252
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()
253
271
        self.extractBenchmarkTime(test)
254
272
        if self.showAll:
255
273
            self.stream.writeln(" FAIL %s" % self._testTimeString())
476
494
 
477
495
    _log_file_name = None
478
496
    _log_contents = ''
 
497
    _keep_log_file = False
479
498
    # record lsprof data when performing benchmark calls.
480
499
    _gather_lsprof_in_benchmarks = False
481
500
 
577
596
            self.fail("%r is an instance of %s rather than %s" % (
578
597
                obj, obj.__class__, kls))
579
598
 
580
 
    def callDeprecated(self, expected, callable, *args, **kwargs):
581
 
        """Assert that a callable is deprecated in a particular way.
 
599
    def _capture_warnings(self, a_callable, *args, **kwargs):
 
600
        """A helper for callDeprecated and applyDeprecated.
582
601
 
583
 
        :param expected: a list of the deprecation warnings expected, in order
584
 
        :param callable: The callable to call
 
602
        :param a_callable: A callable to call.
585
603
        :param args: The positional arguments for the callable
586
604
        :param kwargs: The keyword arguments for the callable
 
605
        :return: A tuple (warnings, result). result is the result of calling
 
606
            a_callable(*args, **kwargs).
587
607
        """
588
608
        local_warnings = []
589
609
        def capture_warnings(msg, cls, stacklevel=None):
 
610
            # we've hooked into a deprecation specific callpath,
 
611
            # only deprecations should getting sent via it.
590
612
            self.assertEqual(cls, DeprecationWarning)
591
613
            local_warnings.append(msg)
592
 
        method = symbol_versioning.warn
 
614
        original_warning_method = symbol_versioning.warn
593
615
        symbol_versioning.set_warning_method(capture_warnings)
594
616
        try:
595
 
            result = callable(*args, **kwargs)
 
617
            result = a_callable(*args, **kwargs)
596
618
        finally:
597
 
            symbol_versioning.set_warning_method(method)
598
 
        self.assertEqual(expected, local_warnings)
 
619
            symbol_versioning.set_warning_method(original_warning_method)
 
620
        return (local_warnings, result)
 
621
 
 
622
    def applyDeprecated(self, deprecation_format, a_callable, *args, **kwargs):
 
623
        """Call a deprecated callable without warning the user.
 
624
 
 
625
        :param deprecation_format: The deprecation format that the callable
 
626
            should have been deprecated with. This is the same type as the 
 
627
            parameter to deprecated_method/deprecated_function. If the 
 
628
            callable is not deprecated with this format, an assertion error
 
629
            will be raised.
 
630
        :param a_callable: A callable to call. This may be a bound method or
 
631
            a regular function. It will be called with *args and **kwargs.
 
632
        :param args: The positional arguments for the callable
 
633
        :param kwargs: The keyword arguments for the callable
 
634
        :return: The result of a_callable(*args, **kwargs)
 
635
        """
 
636
        call_warnings, result = self._capture_warnings(a_callable,
 
637
            *args, **kwargs)
 
638
        expected_first_warning = symbol_versioning.deprecation_string(
 
639
            a_callable, deprecation_format)
 
640
        if len(call_warnings) == 0:
 
641
            self.fail("No assertion generated by call to %s" %
 
642
                a_callable)
 
643
        self.assertEqual(expected_first_warning, call_warnings[0])
 
644
        return result
 
645
 
 
646
    def callDeprecated(self, expected, callable, *args, **kwargs):
 
647
        """Assert that a callable is deprecated in a particular way.
 
648
 
 
649
        This is a very precise test for unusual requirements. The 
 
650
        applyDeprecated helper function is probably more suited for most tests
 
651
        as it allows you to simply specify the deprecation format being used
 
652
        and will ensure that that is issued for the function being called.
 
653
 
 
654
        :param expected: a list of the deprecation warnings expected, in order
 
655
        :param callable: The callable to call
 
656
        :param args: The positional arguments for the callable
 
657
        :param kwargs: The keyword arguments for the callable
 
658
        """
 
659
        call_warnings, result = self._capture_warnings(callable,
 
660
            *args, **kwargs)
 
661
        self.assertEqual(expected, call_warnings)
599
662
        return result
600
663
 
601
664
    def _startLogFile(self):
612
675
    def _finishLogFile(self):
613
676
        """Finished with the log file.
614
677
 
615
 
        Read contents into memory, close, and delete.
 
678
        Close the file and delete it, unless setKeepLogfile was called.
616
679
        """
617
680
        if self._log_file is None:
618
681
            return
619
682
        bzrlib.trace.disable_test_log(self._log_nonce)
620
 
        self._log_file.seek(0)
621
 
        self._log_contents = self._log_file.read()
622
683
        self._log_file.close()
623
 
        os.remove(self._log_file_name)
624
 
        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
625
692
 
626
693
    def addCleanup(self, callable):
627
694
        """Arrange to run a callable when this case is torn down.
641
708
            'BZR_EMAIL': None,
642
709
            'BZREMAIL': None, # may still be present in the environment
643
710
            'EMAIL': None,
 
711
            'BZR_PROGRESS_BAR': None,
644
712
        }
645
713
        self.__old_env = {}
646
714
        self.addCleanup(self._restoreEnvironment)
647
715
        for name, value in new_env.iteritems():
648
716
            self._captureVar(name, value)
649
717
 
650
 
 
651
718
    def _captureVar(self, name, newvalue):
652
 
        """Set an environment variable, preparing it to be reset when finished."""
653
 
        self.__old_env[name] = os.environ.get(name, None)
654
 
        if newvalue is None:
655
 
            if name in os.environ:
656
 
                del os.environ[name]
657
 
        else:
658
 
            os.environ[name] = newvalue
659
 
 
660
 
    @staticmethod
661
 
    def _restoreVar(name, value):
662
 
        if value is None:
663
 
            if name in os.environ:
664
 
                del os.environ[name]
665
 
        else:
666
 
            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)
667
721
 
668
722
    def _restoreEnvironment(self):
669
723
        for name, value in self.__old_env.iteritems():
670
 
            self._restoreVar(name, value)
 
724
            osutils.set_or_unset_env(name, value)
671
725
 
672
726
    def tearDown(self):
673
727
        self._runCleanups()
708
762
    def log(self, *args):
709
763
        mutter(*args)
710
764
 
711
 
    def _get_log(self):
712
 
        """Return as a string the log for this test"""
713
 
        if self._log_file_name:
714
 
            return open(self._log_file_name).read()
715
 
        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:
716
773
            return self._log_contents
717
 
        # 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"
718
786
 
719
787
    def capture(self, cmd, retcode=0):
720
788
        """Shortcut that splits cmd into words, runs, and returns stdout"""
721
789
        return self.run_bzr_captured(cmd.split(), retcode=retcode)[0]
722
790
 
723
 
    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):
724
793
        """Invoke bzr and return (stdout, stderr).
725
794
 
726
795
        Useful for code that wants to check the contents of the
741
810
        :param retcode: expected return code, or None for don't-care.
742
811
        :param encoding: encoding for sys.stdout and sys.stderr
743
812
        :param stdin: A string to be used as stdin for the command.
 
813
        :param working_dir: Change to this directory before running
744
814
        """
745
815
        if encoding is None:
746
816
            encoding = bzrlib.user_encoding
762
832
            stdout=stdout,
763
833
            stderr=stderr)
764
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
 
765
841
        try:
766
842
            result = self.apply_redirected(stdin, stdout, stderr,
767
843
                                           bzrlib.commands.run_bzr_catch_errors,
769
845
        finally:
770
846
            logger.removeHandler(handler)
771
847
            bzrlib.ui.ui_factory = old_ui_factory
 
848
            if cwd is not None:
 
849
                os.chdir(cwd)
772
850
 
773
851
        out = stdout.getvalue()
774
852
        err = stderr.getvalue()
795
873
        retcode = kwargs.pop('retcode', 0)
796
874
        encoding = kwargs.pop('encoding', None)
797
875
        stdin = kwargs.pop('stdin', None)
798
 
        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)
799
879
 
800
880
    def run_bzr_decode(self, *args, **kwargs):
801
 
        if kwargs.has_key('encoding'):
 
881
        if 'encoding' in kwargs:
802
882
            encoding = kwargs['encoding']
803
883
        else:
804
884
            encoding = bzrlib.user_encoding
843
923
        profiled or debugged so easily.
844
924
 
845
925
        :param retcode: The status code that is expected.  Defaults to 0.  If
846
 
        None is supplied, the status code is not checked.
847
 
        """
 
926
            None is supplied, the status code is not checked.
 
927
        :param env_changes: A dictionary which lists changes to environment
 
928
            variables. A value of None will unset the env variable.
 
929
            The values must be strings. The change will only occur in the
 
930
            child, so you don't need to fix the environment after running.
 
931
        :param universal_newlines: Convert CRLF => LF
 
932
        """
 
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
 
 
973
        def cleanup_environment():
 
974
            for env_var, value in env_changes.iteritems():
 
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."""
848
1004
        bzr_path = os.path.dirname(os.path.dirname(bzrlib.__file__))+'/bzr'
849
 
        args = list(args)
850
 
        process = Popen([sys.executable, bzr_path]+args, stdout=PIPE, 
851
 
                         stderr=PIPE)
852
 
        out = process.stdout.read()
853
 
        err = process.stderr.read()
854
 
        retcode = process.wait()
855
 
        supplied_retcode = kwargs.get('retcode', 0)
856
 
        if supplied_retcode is not None:
857
 
            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))
858
1036
        return [out, err]
859
1037
 
860
1038
    def check_inventory_shape(self, inv, shape):
909
1087
            sys.stderr = real_stderr
910
1088
            sys.stdin = real_stdin
911
1089
 
 
1090
    @symbol_versioning.deprecated_method(symbol_versioning.zero_eleven)
912
1091
    def merge(self, branch_from, wt_to):
913
1092
        """A helper for tests to do a ui-less merge.
914
1093
 
920
1099
        base_rev = common_ancestor(branch_from.last_revision(),
921
1100
                                   wt_to.branch.last_revision(),
922
1101
                                   wt_to.branch.repository)
923
 
        merge_inner(wt_to.branch, branch_from.basis_tree(), 
 
1102
        merge_inner(wt_to.branch, branch_from.basis_tree(),
924
1103
                    wt_to.branch.repository.revision_tree(base_rev),
925
1104
                    this_tree=wt_to)
926
 
        wt_to.add_pending_merge(branch_from.last_revision())
 
1105
        wt_to.add_parent_tree_id(branch_from.last_revision())
927
1106
 
928
1107
 
929
1108
BzrTestBase = TestCase
994
1173
                i = i + 1
995
1174
                continue
996
1175
            else:
997
 
                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'
998
1180
                os.mkdir(self.test_dir)
999
1181
                os.chdir(self.test_dir)
1000
1182
                break
1001
 
        os.environ['HOME'] = self.test_dir
1002
 
        os.environ['APPDATA'] = self.test_dir
 
1183
        os.environ['HOME'] = self.test_home_dir
 
1184
        os.environ['APPDATA'] = self.test_home_dir
1003
1185
        def _leaveDirectory():
1004
1186
            os.chdir(_currentdir)
1005
1187
        self.addCleanup(_leaveDirectory)
1044
1226
                # On jam's machine, make_kernel_like_tree is:
1045
1227
                #   put:    4.5-7.5s (averaging 6s)
1046
1228
                #   append: 2.9-4.5s
1047
 
                transport.append(urlutils.escape(name), StringIO(content))
 
1229
                #   put_non_atomic: 2.9-4.5s
 
1230
                transport.put_bytes_non_atomic(urlutils.escape(name), content)
1048
1231
 
1049
1232
    def build_tree_contents(self, shape):
1050
1233
        build_tree_contents(shape)
1131
1314
        return self.__server
1132
1315
 
1133
1316
    def get_url(self, relpath=None):
1134
 
        """Get a URL for the readwrite transport.
 
1317
        """Get a URL (or maybe a path) for the readwrite transport.
1135
1318
 
1136
1319
        This will either be backed by '.' or to an equivalent non-file based
1137
1320
        facility.
1142
1325
        if relpath is not None and relpath != '.':
1143
1326
            if not base.endswith('/'):
1144
1327
                base = base + '/'
1145
 
            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)
1146
1336
        return base
1147
1337
 
1148
1338
    def get_transport(self):
1168
1358
 
1169
1359
    def make_bzrdir(self, relpath, format=None):
1170
1360
        try:
1171
 
            url = self.get_url(relpath)
1172
 
            mutter('relpath %r => url %r', relpath, url)
1173
 
            segments = url.split('/')
1174
 
            if segments and segments[-1] not in ('', '.'):
1175
 
                parent = '/'.join(segments[:-1])
1176
 
                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 ('', '.'):
1177
1366
                try:
1178
 
                    t.mkdir(segments[-1])
 
1367
                    t.mkdir('.')
1179
1368
                except errors.FileExists:
1180
1369
                    pass
1181
1370
            if format is None:
1182
 
                format=bzrlib.bzrdir.BzrDirFormat.get_default_format()
1183
 
            # FIXME: make this use a single transport someday. RBC 20060418
1184
 
            return format.initialize_on_transport(get_transport(relpath))
 
1371
                format = bzrlib.bzrdir.BzrDirFormat.get_default_format()
 
1372
            return format.initialize_on_transport(t)
1185
1373
        except errors.UninitializableFormat:
1186
1374
            raise TestSkipped("Format %s is not initializable." % format)
1187
1375
 
1190
1378
        made_control = self.make_bzrdir(relpath, format=format)
1191
1379
        return made_control.create_repository(shared=shared)
1192
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
 
1193
1386
    def make_branch_and_tree(self, relpath, format=None):
1194
1387
        """Create a branch on the transport and a tree locally.
1195
1388
 
1196
 
        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.
1197
1400
        """
1198
1401
        # TODO: always use the local disk path for the working tree,
1199
1402
        # this obviously requires a format that supports branch references
1203
1406
        try:
1204
1407
            return b.bzrdir.create_workingtree()
1205
1408
        except errors.NotLocalUrl:
1206
 
            # new formats - catch No tree error and create
1207
 
            # a branch reference and a checkout.
1208
 
            # old formats at that point - raise TestSkipped.
1209
 
            # TODO: rbc 20060208
1210
 
            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()
1211
1417
 
1212
1418
    def assertIsDirectory(self, relpath, transport):
1213
1419
        """Assert that relpath within transport is a directory.
1334
1540
                   'bzrlib.tests.test_errors',
1335
1541
                   'bzrlib.tests.test_escaped_store',
1336
1542
                   'bzrlib.tests.test_fetch',
 
1543
                   'bzrlib.tests.test_ftp_transport',
1337
1544
                   'bzrlib.tests.test_gpg',
1338
1545
                   'bzrlib.tests.test_graph',
1339
1546
                   'bzrlib.tests.test_hashcache',
1343
1550
                   'bzrlib.tests.test_ignores',
1344
1551
                   'bzrlib.tests.test_inv',
1345
1552
                   'bzrlib.tests.test_knit',
 
1553
                   'bzrlib.tests.test_lazy_import',
1346
1554
                   'bzrlib.tests.test_lockdir',
1347
1555
                   'bzrlib.tests.test_lockable_files',
1348
1556
                   'bzrlib.tests.test_log',
 
1557
                   'bzrlib.tests.test_memorytree',
1349
1558
                   'bzrlib.tests.test_merge',
1350
1559
                   'bzrlib.tests.test_merge3',
1351
1560
                   'bzrlib.tests.test_merge_core',
1361
1570
                   'bzrlib.tests.test_progress',
1362
1571
                   'bzrlib.tests.test_reconcile',
1363
1572
                   'bzrlib.tests.test_repository',
 
1573
                   'bzrlib.tests.test_revert',
1364
1574
                   'bzrlib.tests.test_revision',
1365
1575
                   'bzrlib.tests.test_revisionnamespaces',
1366
1576
                   'bzrlib.tests.test_revisiontree',
1369
1579
                   'bzrlib.tests.test_selftest',
1370
1580
                   'bzrlib.tests.test_setup',
1371
1581
                   'bzrlib.tests.test_sftp_transport',
1372
 
                   'bzrlib.tests.test_ftp_transport',
1373
1582
                   'bzrlib.tests.test_smart_add',
 
1583
                   'bzrlib.tests.test_smart_transport',
1374
1584
                   'bzrlib.tests.test_source',
1375
1585
                   'bzrlib.tests.test_status',
1376
1586
                   'bzrlib.tests.test_store',
1383
1593
                   'bzrlib.tests.test_transform',
1384
1594
                   'bzrlib.tests.test_transport',
1385
1595
                   'bzrlib.tests.test_tree',
 
1596
                   'bzrlib.tests.test_treebuilder',
1386
1597
                   'bzrlib.tests.test_tsort',
1387
1598
                   'bzrlib.tests.test_tuned_gzip',
1388
1599
                   'bzrlib.tests.test_ui',
1390
1601
                   'bzrlib.tests.test_urlutils',
1391
1602
                   'bzrlib.tests.test_versionedfile',
1392
1603
                   'bzrlib.tests.test_version',
 
1604
                   'bzrlib.tests.test_version_info',
1393
1605
                   'bzrlib.tests.test_weave',
1394
1606
                   'bzrlib.tests.test_whitebox',
1395
1607
                   'bzrlib.tests.test_workingtree',