~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/__init__.py

  • Committer: Aaron Bentley
  • Date: 2006-03-18 23:40:51 UTC
  • mto: This revision was merged to the branch mainline in revision 1615.
  • Revision ID: aaron.bentley@utoronto.ca-20060318234051-415e5fcb51da82e4
Allow merge against self, make fetching self a noop

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