/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-05-20 17:51:13 UTC
  • mfrom: (1718 +trunk)
  • mto: This revision was merged to the branch mainline in revision 1727.
  • Revision ID: aaron.bentley@utoronto.ca-20060520175113-4549e0023f9210bf
Merge from bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
33
33
import logging
34
34
import os
35
35
import re
36
 
import shutil
37
36
import stat
38
37
import sys
39
38
import tempfile
48
47
import bzrlib.inventory
49
48
import bzrlib.iterablefile
50
49
import bzrlib.lockdir
 
50
from bzrlib.merge import merge_inner
51
51
import bzrlib.merge3
52
52
import bzrlib.osutils
53
53
import bzrlib.osutils as osutils
54
54
import bzrlib.plugin
 
55
import bzrlib.progress as progress
 
56
from bzrlib.revision import common_ancestor
55
57
import bzrlib.store
56
58
import bzrlib.trace
57
59
from bzrlib.transport import urlescape, get_transport
112
114
    Shows output in a different format, including displaying runtime for tests.
113
115
    """
114
116
    stop_early = False
115
 
 
116
 
    def _elapsedTime(self):
117
 
        return "%5dms" % (1000 * (time.time() - self._start_time))
 
117
    
 
118
    def __init__(self, stream, descriptions, verbosity, pb=None):
 
119
        unittest._TextTestResult.__init__(self, stream, descriptions, verbosity)
 
120
        self.pb = pb
 
121
    
 
122
    def extractBenchmarkTime(self, testCase):
 
123
        """Add a benchmark time for the current test case."""
 
124
        self._benchmarkTime = getattr(testCase, "_benchtime", None)
 
125
    
 
126
    def _elapsedTestTimeString(self):
 
127
        """Return a time string for the overall time the current test has taken."""
 
128
        return self._formatTime(time.time() - self._start_time)
 
129
 
 
130
    def _testTimeString(self):
 
131
        if self._benchmarkTime is not None:
 
132
            return "%s/%s" % (
 
133
                self._formatTime(self._benchmarkTime),
 
134
                self._elapsedTestTimeString())
 
135
        else:
 
136
            return "      %s" % self._elapsedTestTimeString()
 
137
 
 
138
    def _formatTime(self, seconds):
 
139
        """Format seconds as milliseconds with leading spaces."""
 
140
        return "%5dms" % (1000 * seconds)
 
141
 
 
142
    def _ellipsise_unimportant_words(self, a_string, final_width,
 
143
                                   keep_start=False):
 
144
        """Add ellipses (sp?) for overly long strings.
 
145
        
 
146
        :param keep_start: If true preserve the start of a_string rather
 
147
                           than the end of it.
 
148
        """
 
149
        if keep_start:
 
150
            if len(a_string) > final_width:
 
151
                result = a_string[:final_width-3] + '...'
 
152
            else:
 
153
                result = a_string
 
154
        else:
 
155
            if len(a_string) > final_width:
 
156
                result = '...' + a_string[3-final_width:]
 
157
            else:
 
158
                result = a_string
 
159
        return result.ljust(final_width)
118
160
 
119
161
    def startTest(self, test):
120
162
        unittest.TestResult.startTest(self, test)
122
164
        # the beginning, but in an id, the important words are
123
165
        # at the end
124
166
        SHOW_DESCRIPTIONS = False
 
167
 
 
168
        if not self.showAll and self.dots and self.pb is not None:
 
169
            final_width = 13
 
170
        else:
 
171
            final_width = osutils.terminal_width()
 
172
            final_width = final_width - 15 - 8
 
173
        what = None
 
174
        if SHOW_DESCRIPTIONS:
 
175
            what = test.shortDescription()
 
176
            if what:
 
177
                what = self._ellipsise_unimportant_words(what, final_width, keep_start=True)
 
178
        if what is None:
 
179
            what = test.id()
 
180
            if what.startswith('bzrlib.tests.'):
 
181
                what = what[13:]
 
182
            what = self._ellipsise_unimportant_words(what, final_width)
125
183
        if self.showAll:
126
 
            width = osutils.terminal_width()
127
 
            name_width = width - 15
128
 
            what = None
129
 
            if SHOW_DESCRIPTIONS:
130
 
                what = test.shortDescription()
131
 
                if what:
132
 
                    if len(what) > name_width:
133
 
                        what = what[:name_width-3] + '...'
134
 
            if what is None:
135
 
                what = test.id()
136
 
                if what.startswith('bzrlib.tests.'):
137
 
                    what = what[13:]
138
 
                if len(what) > name_width:
139
 
                    what = '...' + what[3-name_width:]
140
 
            what = what.ljust(name_width)
141
184
            self.stream.write(what)
 
185
        elif self.dots and self.pb is not None:
 
186
            self.pb.update(what, self.testsRun - 1, None)
142
187
        self.stream.flush()
 
188
        self._recordTestStartTime()
 
189
 
 
190
    def _recordTestStartTime(self):
 
191
        """Record that a test has started."""
143
192
        self._start_time = time.time()
144
193
 
145
194
    def addError(self, test, err):
146
195
        if isinstance(err[1], TestSkipped):
147
196
            return self.addSkipped(test, err)    
148
197
        unittest.TestResult.addError(self, test, err)
 
198
        self.extractBenchmarkTime(test)
149
199
        if self.showAll:
150
 
            self.stream.writeln("ERROR %s" % self._elapsedTime())
151
 
        elif self.dots:
 
200
            self.stream.writeln("ERROR %s" % self._testTimeString())
 
201
        elif self.dots and self.pb is None:
152
202
            self.stream.write('E')
 
203
        elif self.dots:
 
204
            self.pb.update(self._ellipsise_unimportant_words('ERROR', 13), self.testsRun, None)
153
205
        self.stream.flush()
154
206
        if self.stop_early:
155
207
            self.stop()
156
208
 
157
209
    def addFailure(self, test, err):
158
210
        unittest.TestResult.addFailure(self, test, err)
 
211
        self.extractBenchmarkTime(test)
159
212
        if self.showAll:
160
 
            self.stream.writeln(" FAIL %s" % self._elapsedTime())
161
 
        elif self.dots:
 
213
            self.stream.writeln(" FAIL %s" % self._testTimeString())
 
214
        elif self.dots and self.pb is None:
162
215
            self.stream.write('F')
 
216
        elif self.dots:
 
217
            self.pb.update(self._ellipsise_unimportant_words('FAIL', 13), self.testsRun, None)
163
218
        self.stream.flush()
164
219
        if self.stop_early:
165
220
            self.stop()
166
221
 
167
222
    def addSuccess(self, test):
 
223
        self.extractBenchmarkTime(test)
168
224
        if self.showAll:
169
 
            self.stream.writeln('   OK %s' % self._elapsedTime())
170
 
        elif self.dots:
 
225
            self.stream.writeln('   OK %s' % self._testTimeString())
 
226
        elif self.dots and self.pb is None:
171
227
            self.stream.write('~')
 
228
        elif self.dots:
 
229
            self.pb.update(self._ellipsise_unimportant_words('OK', 13), self.testsRun, None)
172
230
        self.stream.flush()
173
231
        unittest.TestResult.addSuccess(self, test)
174
232
 
175
233
    def addSkipped(self, test, skip_excinfo):
 
234
        self.extractBenchmarkTime(test)
176
235
        if self.showAll:
177
 
            print >>self.stream, ' SKIP %s' % self._elapsedTime()
 
236
            print >>self.stream, ' SKIP %s' % self._testTimeString()
178
237
            print >>self.stream, '     %s' % skip_excinfo[1]
179
 
        elif self.dots:
 
238
        elif self.dots and self.pb is None:
180
239
            self.stream.write('S')
 
240
        elif self.dots:
 
241
            self.pb.update(self._ellipsise_unimportant_words('SKIP', 13), self.testsRun, None)
181
242
        self.stream.flush()
182
243
        # seems best to treat this as success from point-of-view of unittest
183
244
        # -- it actually does nothing so it barely matters :)
198
259
            self.stream.writeln("%s" % err)
199
260
 
200
261
 
201
 
class TextTestRunner(unittest.TextTestRunner):
 
262
class TextTestRunner(object):
202
263
    stop_on_failure = False
203
264
 
 
265
    def __init__(self,
 
266
                 stream=sys.stderr,
 
267
                 descriptions=0,
 
268
                 verbosity=1,
 
269
                 keep_output=False,
 
270
                 pb=None):
 
271
        self.stream = unittest._WritelnDecorator(stream)
 
272
        self.descriptions = descriptions
 
273
        self.verbosity = verbosity
 
274
        self.keep_output = keep_output
 
275
        self.pb = pb
 
276
 
204
277
    def _makeResult(self):
205
 
        result = _MyResult(self.stream, self.descriptions, self.verbosity)
 
278
        result = _MyResult(self.stream,
 
279
                           self.descriptions,
 
280
                           self.verbosity,
 
281
                           pb=self.pb)
206
282
        result.stop_early = self.stop_on_failure
207
283
        return result
208
284
 
 
285
    def run(self, test):
 
286
        "Run the given test case or test suite."
 
287
        result = self._makeResult()
 
288
        startTime = time.time()
 
289
        if self.pb is not None:
 
290
            self.pb.update('Running tests', 0, test.countTestCases())
 
291
        test.run(result)
 
292
        stopTime = time.time()
 
293
        timeTaken = stopTime - startTime
 
294
        result.printErrors()
 
295
        self.stream.writeln(result.separator2)
 
296
        run = result.testsRun
 
297
        self.stream.writeln("Ran %d test%s in %.3fs" %
 
298
                            (run, run != 1 and "s" or "", timeTaken))
 
299
        self.stream.writeln()
 
300
        if not result.wasSuccessful():
 
301
            self.stream.write("FAILED (")
 
302
            failed, errored = map(len, (result.failures, result.errors))
 
303
            if failed:
 
304
                self.stream.write("failures=%d" % failed)
 
305
            if errored:
 
306
                if failed: self.stream.write(", ")
 
307
                self.stream.write("errors=%d" % errored)
 
308
            self.stream.writeln(")")
 
309
        else:
 
310
            self.stream.writeln("OK")
 
311
        if self.pb is not None:
 
312
            self.pb.update('Cleaning up', 0, 1)
 
313
        # This is still a little bogus, 
 
314
        # but only a little. Folk not using our testrunner will
 
315
        # have to delete their temp directories themselves.
 
316
        test_root = TestCaseInTempDir.TEST_ROOT
 
317
        if result.wasSuccessful() or not self.keep_output:
 
318
            if test_root is not None:
 
319
                    osutils.rmtree(test_root)
 
320
        else:
 
321
            if self.pb is not None:
 
322
                self.pb.note("Failed tests working directories are in '%s'\n",
 
323
                             test_root)
 
324
            else:
 
325
                self.stream.writeln(
 
326
                    "Failed tests working directories are in '%s'\n" %
 
327
                    test_root)
 
328
        TestCaseInTempDir.TEST_ROOT = None
 
329
        if self.pb is not None:
 
330
            self.pb.clear()
 
331
        return result
 
332
 
209
333
 
210
334
def iter_suite_tests(suite):
211
335
    """Return all tests in a suite, recursing through nested suites"""
249
373
    accidentally overlooked.
250
374
    """
251
375
 
252
 
    BZRPATH = 'bzr'
253
376
    _log_file_name = None
254
377
    _log_contents = ''
255
378
 
262
385
        self._cleanEnvironment()
263
386
        bzrlib.trace.disable_default_logging()
264
387
        self._startLogFile()
 
388
        self._benchtime = None
265
389
 
266
390
    def _ndiff_strings(self, a, b):
267
391
        """Return ndiff between two strings containing lines.
301
425
            raise AssertionError('string %r does not start with %r' % (s, prefix))
302
426
 
303
427
    def assertEndsWith(self, s, suffix):
304
 
        if not s.endswith(prefix):
 
428
        """Asserts that s ends with suffix."""
 
429
        if not s.endswith(suffix):
305
430
            raise AssertionError('string %r does not end with %r' % (s, suffix))
306
431
 
307
432
    def assertContainsRe(self, haystack, needle_re):
327
452
    def assertTransportMode(self, transport, path, mode):
328
453
        """Fail if a path does not have mode mode.
329
454
        
330
 
        If modes are not supported on this platform, the test is skipped.
 
455
        If modes are not supported on this transport, the assertion is ignored.
331
456
        """
332
 
        if sys.platform == 'win32':
 
457
        if not transport._can_roundtrip_unix_modebits():
333
458
            return
334
459
        path_stat = transport.stat(path)
335
460
        actual_mode = stat.S_IMODE(path_stat.st_mode)
339
464
    def assertIsInstance(self, obj, kls):
340
465
        """Fail if obj is not an instance of kls"""
341
466
        if not isinstance(obj, kls):
342
 
            self.fail("%r is not an instance of %s" % (obj, kls))
 
467
            self.fail("%r is an instance of %s rather than %s" % (
 
468
                obj, obj.__class__, kls))
343
469
 
344
470
    def _startLogFile(self):
345
471
        """Send bzr and test log messages to a temporary file.
414
540
        self._runCleanups()
415
541
        unittest.TestCase.tearDown(self)
416
542
 
 
543
    def time(self, callable, *args, **kwargs):
 
544
        """Run callable and accrue the time it takes to the benchmark time."""
 
545
        if self._benchtime is None:
 
546
            self._benchtime = 0
 
547
        start = time.time()
 
548
        try:
 
549
            callable(*args, **kwargs)
 
550
        finally:
 
551
            self._benchtime += time.time() - start
 
552
 
417
553
    def _runCleanups(self):
418
554
        """Run registered cleanup functions. 
419
555
 
439
575
        """Shortcut that splits cmd into words, runs, and returns stdout"""
440
576
        return self.run_bzr_captured(cmd.split(), retcode=retcode)[0]
441
577
 
442
 
    def run_bzr_captured(self, argv, retcode=0):
 
578
    def run_bzr_captured(self, argv, retcode=0, stdin=None):
443
579
        """Invoke bzr and return (stdout, stderr).
444
580
 
445
581
        Useful for code that wants to check the contents of the
458
594
 
459
595
        argv -- arguments to invoke bzr
460
596
        retcode -- expected return code, or None for don't-care.
 
597
        :param stdin: A string to be used as stdin for the command.
461
598
        """
 
599
        if stdin is not None:
 
600
            stdin = StringIO(stdin)
462
601
        stdout = StringIO()
463
602
        stderr = StringIO()
464
603
        self.log('run bzr: %s', ' '.join(argv))
468
607
        handler.setLevel(logging.INFO)
469
608
        logger = logging.getLogger('')
470
609
        logger.addHandler(handler)
 
610
        old_ui_factory = bzrlib.ui.ui_factory
 
611
        bzrlib.ui.ui_factory = bzrlib.tests.blackbox.TestUIFactory(
 
612
            stdout=stdout,
 
613
            stderr=stderr)
 
614
        bzrlib.ui.ui_factory.stdin = stdin
471
615
        try:
472
 
            result = self.apply_redirected(None, stdout, stderr,
 
616
            result = self.apply_redirected(stdin, stdout, stderr,
473
617
                                           bzrlib.commands.run_bzr_catch_errors,
474
618
                                           argv)
475
619
        finally:
476
620
            logger.removeHandler(handler)
 
621
            bzrlib.ui.ui_factory = old_ui_factory
477
622
        out = stdout.getvalue()
478
623
        err = stderr.getvalue()
479
624
        if out:
493
638
 
494
639
        This sends the stdout/stderr results into the test's log,
495
640
        where it may be useful for debugging.  See also run_captured.
 
641
 
 
642
        :param stdin: A string to be used as stdin for the command.
496
643
        """
497
644
        retcode = kwargs.pop('retcode', 0)
498
 
        return self.run_bzr_captured(args, retcode)
 
645
        stdin = kwargs.pop('stdin', None)
 
646
        return self.run_bzr_captured(args, retcode, stdin)
499
647
 
500
648
    def check_inventory_shape(self, inv, shape):
501
649
        """Compare an inventory to a list of expected names.
549
697
            sys.stderr = real_stderr
550
698
            sys.stdin = real_stdin
551
699
 
 
700
    def merge(self, branch_from, wt_to):
 
701
        """A helper for tests to do a ui-less merge.
 
702
 
 
703
        This should move to the main library when someone has time to integrate
 
704
        it in.
 
705
        """
 
706
        # minimal ui-less merge.
 
707
        wt_to.branch.fetch(branch_from)
 
708
        base_rev = common_ancestor(branch_from.last_revision(),
 
709
                                   wt_to.branch.last_revision(),
 
710
                                   wt_to.branch.repository)
 
711
        merge_inner(wt_to.branch, branch_from.basis_tree(), 
 
712
                    wt_to.branch.repository.revision_tree(base_rev),
 
713
                    this_tree=wt_to)
 
714
        wt_to.add_pending_merge(branch_from.last_revision())
 
715
 
552
716
 
553
717
BzrTestBase = TestCase
554
718
 
775
939
        self.assertTrue(t.is_readonly())
776
940
        return t
777
941
 
778
 
    def make_branch(self, relpath):
 
942
    def make_branch(self, relpath, format=None):
779
943
        """Create a branch on the transport at relpath."""
780
 
        repo = self.make_repository(relpath)
 
944
        repo = self.make_repository(relpath, format=format)
781
945
        return repo.bzrdir.create_branch()
782
946
 
783
 
    def make_bzrdir(self, relpath):
 
947
    def make_bzrdir(self, relpath, format=None):
784
948
        try:
785
949
            url = self.get_url(relpath)
786
950
            segments = relpath.split('/')
791
955
                    t.mkdir(segments[-1])
792
956
                except errors.FileExists:
793
957
                    pass
794
 
            return bzrlib.bzrdir.BzrDir.create(url)
 
958
            if format is None:
 
959
                format=bzrlib.bzrdir.BzrDirFormat.get_default_format()
 
960
            # FIXME: make this use a single transport someday. RBC 20060418
 
961
            return format.initialize_on_transport(get_transport(relpath))
795
962
        except errors.UninitializableFormat:
796
 
            raise TestSkipped("Format %s is not initializable.")
 
963
            raise TestSkipped("Format %s is not initializable." % format)
797
964
 
798
 
    def make_repository(self, relpath, shared=False):
 
965
    def make_repository(self, relpath, shared=False, format=None):
799
966
        """Create a repository on our default transport at relpath."""
800
 
        made_control = self.make_bzrdir(relpath)
 
967
        made_control = self.make_bzrdir(relpath, format=format)
801
968
        return made_control.create_repository(shared=shared)
802
969
 
803
 
    def make_branch_and_tree(self, relpath):
 
970
    def make_branch_and_tree(self, relpath, format=None):
804
971
        """Create a branch on the transport and a tree locally.
805
972
 
806
973
        Returns the tree.
809
976
        # this obviously requires a format that supports branch references
810
977
        # so check for that by checking bzrdir.BzrDirFormat.get_default_format()
811
978
        # RBC 20060208
812
 
        b = self.make_branch(relpath)
 
979
        b = self.make_branch(relpath, format=format)
813
980
        try:
814
981
            return b.bzrdir.create_workingtree()
815
982
        except errors.NotLocalUrl:
868
1035
    TestCaseInTempDir._TEST_NAME = name
869
1036
    if verbose:
870
1037
        verbosity = 2
 
1038
        pb = None
871
1039
    else:
872
1040
        verbosity = 1
 
1041
        pb = progress.ProgressBar()
873
1042
    runner = TextTestRunner(stream=sys.stdout,
874
1043
                            descriptions=0,
875
 
                            verbosity=verbosity)
 
1044
                            verbosity=verbosity,
 
1045
                            keep_output=keep_output,
 
1046
                            pb=pb)
876
1047
    runner.stop_on_failure=stop_on_failure
877
1048
    if pattern != '.*':
878
1049
        suite = filter_suite_by_re(suite, pattern)
879
1050
    result = runner.run(suite)
880
 
    # This is still a little bogus, 
881
 
    # but only a little. Folk not using our testrunner will
882
 
    # have to delete their temp directories themselves.
883
 
    test_root = TestCaseInTempDir.TEST_ROOT
884
 
    if result.wasSuccessful() or not keep_output:
885
 
        if test_root is not None:
886
 
            print 'Deleting test root %s...' % test_root
887
 
            try:
888
 
                shutil.rmtree(test_root)
889
 
            finally:
890
 
                print
891
 
    else:
892
 
        print "Failed tests working directories are in '%s'\n" % TestCaseInTempDir.TEST_ROOT
893
1051
    return result.wasSuccessful()
894
1052
 
895
1053
 
896
1054
def selftest(verbose=False, pattern=".*", stop_on_failure=True,
897
1055
             keep_output=False,
898
 
             transport=None):
 
1056
             transport=None,
 
1057
             test_suite_factory=None):
899
1058
    """Run the whole test suite under the enhanced runner"""
900
1059
    global default_transport
901
1060
    if transport is None:
902
1061
        transport = default_transport
903
1062
    old_transport = default_transport
904
1063
    default_transport = transport
905
 
    suite = test_suite()
906
1064
    try:
 
1065
        if test_suite_factory is None:
 
1066
            suite = test_suite()
 
1067
        else:
 
1068
            suite = test_suite_factory()
907
1069
        return run_suite(suite, 'testbzr', verbose=verbose, pattern=pattern,
908
1070
                     stop_on_failure=stop_on_failure, keep_output=keep_output,
909
1071
                     transport=transport)
911
1073
        default_transport = old_transport
912
1074
 
913
1075
 
914
 
 
915
1076
def test_suite():
916
 
    """Build and return TestSuite for the whole program."""
 
1077
    """Build and return TestSuite for the whole of bzrlib.
 
1078
    
 
1079
    This function can be replaced if you need to change the default test
 
1080
    suite on a global basis, but it is not encouraged.
 
1081
    """
917
1082
    from doctest import DocTestSuite
918
1083
 
919
1084
    global MODULES_TO_DOCTEST
920
1085
 
921
1086
    testmod_names = [ \
922
1087
                   'bzrlib.tests.test_ancestry',
923
 
                   'bzrlib.tests.test_annotate',
924
1088
                   'bzrlib.tests.test_api',
925
1089
                   'bzrlib.tests.test_bad_files',
926
 
                   'bzrlib.tests.test_basis_inventory',
927
1090
                   'bzrlib.tests.test_branch',
928
1091
                   'bzrlib.tests.test_bzrdir',
929
1092
                   'bzrlib.tests.test_command',
935
1098
                   'bzrlib.tests.test_diff',
936
1099
                   'bzrlib.tests.test_doc_generate',
937
1100
                   'bzrlib.tests.test_errors',
 
1101
                   'bzrlib.tests.test_escaped_store',
938
1102
                   'bzrlib.tests.test_fetch',
939
1103
                   'bzrlib.tests.test_gpg',
940
1104
                   'bzrlib.tests.test_graph',
954
1118
                   'bzrlib.tests.test_nonascii',
955
1119
                   'bzrlib.tests.test_options',
956
1120
                   'bzrlib.tests.test_osutils',
 
1121
                   'bzrlib.tests.test_patch',
957
1122
                   'bzrlib.tests.test_permissions',
958
1123
                   'bzrlib.tests.test_plugins',
959
1124
                   'bzrlib.tests.test_progress',
969
1134
                   'bzrlib.tests.test_sftp_transport',
970
1135
                   'bzrlib.tests.test_smart_add',
971
1136
                   'bzrlib.tests.test_source',
 
1137
                   'bzrlib.tests.test_status',
972
1138
                   'bzrlib.tests.test_store',
973
1139
                   'bzrlib.tests.test_symbol_versioning',
974
1140
                   'bzrlib.tests.test_testament',
 
1141
                   'bzrlib.tests.test_textfile',
 
1142
                   'bzrlib.tests.test_textmerge',
975
1143
                   'bzrlib.tests.test_trace',
976
1144
                   'bzrlib.tests.test_transactions',
977
1145
                   'bzrlib.tests.test_transform',
978
1146
                   'bzrlib.tests.test_transport',
979
1147
                   'bzrlib.tests.test_tsort',
 
1148
                   'bzrlib.tests.test_tuned_gzip',
980
1149
                   'bzrlib.tests.test_ui',
981
 
                   'bzrlib.tests.test_uncommit',
982
1150
                   'bzrlib.tests.test_upgrade',
983
1151
                   'bzrlib.tests.test_versionedfile',
984
1152
                   'bzrlib.tests.test_weave',
989
1157
    test_transport_implementations = [
990
1158
        'bzrlib.tests.test_transport_implementations']
991
1159
 
992
 
    TestCase.BZRPATH = osutils.pathjoin(
993
 
            osutils.realpath(osutils.dirname(bzrlib.__path__[0])), 'bzr')
994
 
    print '%10s: %s' % ('bzr', osutils.realpath(sys.argv[0]))
995
 
    print '%10s: %s' % ('bzrlib', bzrlib.__path__[0])
996
 
    print
997
1160
    suite = TestSuite()
998
 
    # python2.4's TestLoader.loadTestsFromNames gives very poor 
999
 
    # errors if it fails to load a named module - no indication of what's
1000
 
    # actually wrong, just "no such module".  We should probably override that
1001
 
    # class, but for the moment just load them ourselves. (mbp 20051202)
1002
 
    loader = TestLoader()
 
1161
    loader = TestUtil.TestLoader()
1003
1162
    from bzrlib.transport import TransportTestProviderAdapter
1004
1163
    adapter = TransportTestProviderAdapter()
1005
1164
    adapt_modules(test_transport_implementations, adapter, loader, suite)
1006
 
    for mod_name in testmod_names:
1007
 
        mod = _load_module_by_name(mod_name)
1008
 
        suite.addTest(loader.loadTestsFromModule(mod))
 
1165
    suite.addTest(loader.loadTestsFromModuleNames(testmod_names))
1009
1166
    for package in packages_to_test():
1010
1167
        suite.addTest(package.test_suite())
1011
1168
    for m in MODULES_TO_TEST:
1020
1177
 
1021
1178
def adapt_modules(mods_list, adapter, loader, suite):
1022
1179
    """Adapt the modules in mods_list using adapter and add to suite."""
1023
 
    for mod_name in mods_list:
1024
 
        mod = _load_module_by_name(mod_name)
1025
 
        for test in iter_suite_tests(loader.loadTestsFromModule(mod)):
1026
 
            suite.addTests(adapter.adapt(test))
1027
 
 
1028
 
 
1029
 
def _load_module_by_name(mod_name):
1030
 
    parts = mod_name.split('.')
1031
 
    module = __import__(mod_name)
1032
 
    del parts[0]
1033
 
    # for historical reasons python returns the top-level module even though
1034
 
    # it loads the submodule; we need to walk down to get the one we want.
1035
 
    while parts:
1036
 
        module = getattr(module, parts.pop(0))
1037
 
    return module
 
1180
    for test in iter_suite_tests(loader.loadTestsFromModuleNames(mods_list)):
 
1181
        suite.addTests(adapter.adapt(test))