~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/__init__.py

[merge] bzr.dev 1491

Show diffs side-by-side

added added

removed removed

Lines of Context:
26
26
import tempfile
27
27
import unittest
28
28
import time
 
29
import codecs
29
30
 
 
31
import bzrlib.branch
30
32
import bzrlib.commands
 
33
from bzrlib.errors import BzrError
 
34
import bzrlib.inventory
 
35
import bzrlib.merge3
 
36
import bzrlib.osutils
 
37
import bzrlib.plugin
 
38
import bzrlib.store
31
39
import bzrlib.trace
32
 
import bzrlib.osutils as osutils
33
40
from bzrlib.trace import mutter
34
41
from bzrlib.tests.TestUtil import TestLoader, TestSuite
35
42
from bzrlib.tests.treeshape import build_tree_contents
36
 
from bzrlib.errors import BzrError
37
43
 
38
44
MODULES_TO_TEST = []
39
 
MODULES_TO_DOCTEST = []
40
 
 
 
45
MODULES_TO_DOCTEST = [
 
46
                      bzrlib.branch,
 
47
                      bzrlib.commands,
 
48
                      bzrlib.errors,
 
49
                      bzrlib.inventory,
 
50
                      bzrlib.merge3,
 
51
                      bzrlib.osutils,
 
52
                      bzrlib.store,
 
53
                      ]
 
54
def packages_to_test():
 
55
    import bzrlib.tests.blackbox
 
56
    return [
 
57
            bzrlib.tests.blackbox
 
58
            ]
41
59
 
42
60
 
43
61
class EarlyStoppingTestResultAdapter(object):
69
87
    Shows output in a different format, including displaying runtime for tests.
70
88
    """
71
89
 
72
 
    # assumes 80-column window, less 'ERROR 99999ms' = 13ch
73
90
    def _elapsedTime(self):
74
91
        return "%5dms" % (1000 * (time.time() - self._start_time))
75
92
 
79
96
        # the beginning, but in an id, the important words are
80
97
        # at the end
81
98
        SHOW_DESCRIPTIONS = False
82
 
        what = SHOW_DESCRIPTIONS and test.shortDescription()
83
 
        if what:
84
 
            if len(what) > 65:
85
 
                what = what[:62] + '...'
86
 
        else:
87
 
            what = test.id()
88
 
            if what.startswith('bzrlib.tests.'):
89
 
                what = what[13:]
90
 
            if len(what) > 65:
91
 
                what = '...' + what[-62:]
92
99
        if self.showAll:
93
 
            self.stream.write('%-65.65s' % what)
 
100
            width = bzrlib.osutils.terminal_width()
 
101
            name_width = width - 15
 
102
            what = None
 
103
            if SHOW_DESCRIPTIONS:
 
104
                what = test.shortDescription()
 
105
                if what:
 
106
                    if len(what) > name_width:
 
107
                        what = what[:name_width-3] + '...'
 
108
            if what is None:
 
109
                what = test.id()
 
110
                if what.startswith('bzrlib.tests.'):
 
111
                    what = what[13:]
 
112
                if len(what) > name_width:
 
113
                    what = '...' + what[3-name_width:]
 
114
            what = what.ljust(name_width)
 
115
            self.stream.write(what)
94
116
        self.stream.flush()
95
117
        self._start_time = time.time()
96
118
 
97
119
    def addError(self, test, err):
 
120
        if isinstance(err[1], TestSkipped):
 
121
            return self.addSkipped(test, err)    
98
122
        unittest.TestResult.addError(self, test, err)
99
123
        if self.showAll:
100
124
            self.stream.writeln("ERROR %s" % self._elapsedTime())
118
142
        self.stream.flush()
119
143
        unittest.TestResult.addSuccess(self, test)
120
144
 
 
145
    def addSkipped(self, test, skip_excinfo):
 
146
        if self.showAll:
 
147
            print >>self.stream, ' SKIP %s' % self._elapsedTime()
 
148
            print >>self.stream, '     %s' % skip_excinfo[1]
 
149
        elif self.dots:
 
150
            self.stream.write('S')
 
151
        self.stream.flush()
 
152
        # seems best to treat this as success from point-of-view of unittest
 
153
        # -- it actually does nothing so it barely matters :)
 
154
        unittest.TestResult.addSuccess(self, test)
 
155
 
121
156
    def printErrorList(self, flavour, errors):
122
157
        for test, err in errors:
123
158
            self.stream.writeln(self.separator1)
124
159
            self.stream.writeln("%s: %s" % (flavour,self.getDescription(test)))
125
160
            if hasattr(test, '_get_log'):
126
 
                self.stream.writeln()
127
 
                self.stream.writeln('log from this test:')
 
161
                print >>self.stream
 
162
                print >>self.stream, \
 
163
                        ('vvvv[log from %s]' % test).ljust(78,'-')
128
164
                print >>self.stream, test._get_log()
 
165
                print >>self.stream, \
 
166
                        ('^^^^[log from %s]' % test).ljust(78,'-')
129
167
            self.stream.writeln(self.separator2)
130
168
            self.stream.writeln("%s" % err)
131
169
 
226
264
            raise AssertionError('pattern "%s" not found in "%s"'
227
265
                    % (needle_re, haystack))
228
266
 
 
267
    def AssertSubset(self, sublist, superlist):
 
268
        """Assert that every entry in sublist is present in superlist."""
 
269
        missing = []
 
270
        for entry in sublist:
 
271
            if entry not in superlist:
 
272
                missing.append(entry)
 
273
        if len(missing) > 0:
 
274
            raise AssertionError("value(s) %r not present in container %r" % 
 
275
                                 (missing, superlist))
 
276
 
229
277
    def _startLogFile(self):
230
278
        """Send bzr and test log messages to a temporary file.
231
279
 
232
280
        The file is removed as the test is torn down.
233
281
        """
234
282
        fileno, name = tempfile.mkstemp(suffix='.log', prefix='testbzr')
235
 
        self._log_file = os.fdopen(fileno, 'w+')
 
283
        encoder, decoder, stream_reader, stream_writer = codecs.lookup('UTF-8')
 
284
        self._log_file = stream_writer(os.fdopen(fileno, 'w+'))
236
285
        bzrlib.trace.enable_test_log(self._log_file)
237
286
        self._log_file_name = name
238
287
        self.addCleanup(self._finishLogFile)
303
352
 
304
353
        This should only be called from TestCase.tearDown.
305
354
        """
306
 
        for callable in reversed(self._cleanups):
307
 
            callable()
 
355
        for cleanup_fn in reversed(self._cleanups):
 
356
            cleanup_fn()
308
357
 
309
358
    def log(self, *args):
310
359
        mutter(*args)
523
572
                f.close()
524
573
 
525
574
    def build_tree_contents(self, shape):
526
 
        bzrlib.tests.build_tree_contents(shape)
 
575
        build_tree_contents(shape)
527
576
 
528
577
    def failUnlessExists(self, path):
529
578
        """Fail unless path, which may be abs or relative, exists."""
530
 
        self.failUnless(osutils.lexists(path))
 
579
        self.failUnless(bzrlib.osutils.lexists(path))
531
580
        
532
581
    def assertFileEqual(self, content, path):
533
582
        """Fail if path does not contain 'content'."""
534
 
        self.failUnless(osutils.lexists(path))
 
583
        self.failUnless(bzrlib.osutils.lexists(path))
535
584
        self.assertEqualDiff(content, open(path, 'r').read())
536
585
        
537
586
 
538
 
class MetaTestLog(TestCase):
539
 
    def test_logging(self):
540
 
        """Test logs are captured when a test fails."""
541
 
        self.log('a test message')
542
 
        self._log_file.flush()
543
 
        self.assertContainsRe(self._get_log(), 'a test message\n')
544
 
 
545
 
 
546
587
def filter_suite_by_re(suite, pattern):
547
 
    result = TestUtil.TestSuite()
 
588
    result = TestSuite()
548
589
    filter_re = re.compile(pattern)
549
590
    for test in iter_suite_tests(suite):
550
591
        if filter_re.search(test.id()):
586
627
 
587
628
def test_suite():
588
629
    """Build and return TestSuite for the whole program."""
589
 
    import bzrlib.store, bzrlib.inventory, bzrlib.branch
590
 
    import bzrlib.osutils, bzrlib.merge3, bzrlib.plugin
591
630
    from doctest import DocTestSuite
592
631
 
593
 
    global MODULES_TO_TEST, MODULES_TO_DOCTEST
 
632
    global MODULES_TO_DOCTEST
594
633
 
595
 
    # FIXME: If these fail to load, e.g. because of a syntax error, the
596
 
    # exception is hidden by unittest.  Sucks.  Should either fix that or
597
 
    # perhaps import them and pass them to unittest as modules.
598
 
    testmod_names = \
599
 
                  ['bzrlib.tests.MetaTestLog',
 
634
    testmod_names = [ \
 
635
                   'bzrlib.tests.test_ancestry',
 
636
                   'bzrlib.tests.test_annotate',
600
637
                   'bzrlib.tests.test_api',
601
 
                   'bzrlib.tests.test_gpg',
602
 
                   'bzrlib.tests.test_identitymap',
603
 
                   'bzrlib.tests.test_inv',
604
 
                   'bzrlib.tests.test_ancestry',
 
638
                   'bzrlib.tests.test_bad_files',
 
639
                   'bzrlib.tests.test_branch',
 
640
                   'bzrlib.tests.test_command',
605
641
                   'bzrlib.tests.test_commit',
606
 
                   'bzrlib.tests.test_command',
607
642
                   'bzrlib.tests.test_commit_merge',
608
643
                   'bzrlib.tests.test_config',
609
 
                   'bzrlib.tests.test_merge3',
610
 
                   'bzrlib.tests.test_merge',
 
644
                   'bzrlib.tests.test_conflicts',
 
645
                   'bzrlib.tests.test_diff',
 
646
                   'bzrlib.tests.test_fetch',
 
647
                   'bzrlib.tests.test_gpg',
 
648
                   'bzrlib.tests.test_graph',
611
649
                   'bzrlib.tests.test_hashcache',
612
 
                   'bzrlib.tests.test_status',
 
650
                   'bzrlib.tests.test_http',
 
651
                   'bzrlib.tests.test_identitymap',
 
652
                   'bzrlib.tests.test_inv',
613
653
                   'bzrlib.tests.test_log',
614
 
                   'bzrlib.tests.test_revisionnamespaces',
615
 
                   'bzrlib.tests.test_branch',
 
654
                   'bzrlib.tests.test_merge',
 
655
                   'bzrlib.tests.test_merge3',
 
656
                   'bzrlib.tests.test_merge_core',
 
657
                   'bzrlib.tests.test_missing',
 
658
                   'bzrlib.tests.test_msgeditor',
 
659
                   'bzrlib.tests.test_nonascii',
 
660
                   'bzrlib.tests.test_options',
 
661
                   'bzrlib.tests.test_parent',
 
662
                   'bzrlib.tests.test_plugins',
 
663
                   'bzrlib.tests.test_remove',
616
664
                   'bzrlib.tests.test_revision',
617
665
                   'bzrlib.tests.test_revision_info',
618
 
                   'bzrlib.tests.test_merge_core',
 
666
                   'bzrlib.tests.test_revisionnamespaces',
 
667
                   'bzrlib.tests.test_revprops',
 
668
                   'bzrlib.tests.test_reweave',
 
669
                   'bzrlib.tests.test_rio',
 
670
                   'bzrlib.tests.test_sampler',
 
671
                   'bzrlib.tests.test_selftest',
 
672
                   'bzrlib.tests.test_setup',
 
673
                   'bzrlib.tests.test_sftp',
619
674
                   'bzrlib.tests.test_smart_add',
620
 
                   'bzrlib.tests.test_bad_files',
621
 
                   'bzrlib.tests.test_diff',
622
 
                   'bzrlib.tests.test_parent',
623
 
                   'bzrlib.tests.test_xml',
624
 
                   'bzrlib.tests.test_weave',
625
 
                   'bzrlib.tests.test_fetch',
626
 
                   'bzrlib.tests.test_whitebox',
 
675
                   'bzrlib.tests.test_source',
 
676
                   'bzrlib.tests.test_status',
627
677
                   'bzrlib.tests.test_store',
628
 
                   'bzrlib.tests.blackbox',
629
 
                   'bzrlib.tests.blackbox.versioning',
630
 
                   'bzrlib.tests.blackbox.test_bound_branch',
631
 
                   'bzrlib.tests.test_sampler',
 
678
                   'bzrlib.tests.test_testament',
 
679
                   'bzrlib.tests.test_trace',
632
680
                   'bzrlib.tests.test_transactions',
633
681
                   'bzrlib.tests.test_transport',
634
 
                   'bzrlib.tests.test_sftp',
635
 
                   'bzrlib.tests.test_graph',
 
682
                   'bzrlib.tests.test_tsort',
 
683
                   'bzrlib.tests.test_ui',
 
684
                   'bzrlib.tests.test_uncommit',
 
685
                   'bzrlib.tests.test_upgrade',
 
686
                   'bzrlib.tests.test_weave',
 
687
                   'bzrlib.tests.test_whitebox',
636
688
                   'bzrlib.tests.test_workingtree',
637
 
                   'bzrlib.tests.test_upgrade',
638
 
                   'bzrlib.tests.test_uncommit',
639
 
                   'bzrlib.tests.test_conflicts',
640
 
                   'bzrlib.tests.test_testament',
641
 
                   'bzrlib.tests.test_annotate',
642
 
                   'bzrlib.tests.test_revprops',
643
 
                   'bzrlib.tests.test_options',
644
 
                   'bzrlib.tests.test_http',
645
 
                   'bzrlib.tests.test_nonascii',
646
 
                   'bzrlib.tests.test_reweave',
647
 
                   'bzrlib.tests.test_tsort',
648
 
                   'bzrlib.tests.test_trace',
649
 
                   'bzrlib.tests.test_basicio',
 
689
                   'bzrlib.tests.test_xml',
650
690
                   ]
651
691
 
652
 
    for m in (bzrlib.store, bzrlib.inventory, bzrlib.branch,
653
 
              bzrlib.osutils, bzrlib.commands, bzrlib.merge3,
654
 
              bzrlib.errors,
655
 
              ):
656
 
        if m not in MODULES_TO_DOCTEST:
657
 
            MODULES_TO_DOCTEST.append(m)
658
 
 
659
 
    TestCase.BZRPATH = os.path.join(os.path.realpath(os.path.dirname(bzrlib.__path__[0])), 'bzr')
660
 
    print '%-30s %s' % ('bzr binary', TestCase.BZRPATH)
 
692
    print '%10s: %s' % ('bzr', os.path.realpath(sys.argv[0]))
 
693
    print '%10s: %s' % ('bzrlib', bzrlib.__path__[0])
661
694
    print
662
695
    suite = TestSuite()
663
 
    suite.addTest(TestLoader().loadTestsFromNames(testmod_names))
 
696
    # python2.4's TestLoader.loadTestsFromNames gives very poor 
 
697
    # errors if it fails to load a named module - no indication of what's
 
698
    # actually wrong, just "no such module".  We should probably override that
 
699
    # class, but for the moment just load them ourselves. (mbp 20051202)
 
700
    loader = TestLoader()
 
701
    for mod_name in testmod_names:
 
702
        mod = _load_module_by_name(mod_name)
 
703
        suite.addTest(loader.loadTestsFromModule(mod))
 
704
    for package in packages_to_test():
 
705
        suite.addTest(package.test_suite())
664
706
    for m in MODULES_TO_TEST:
665
 
         suite.addTest(TestLoader().loadTestsFromModule(m))
 
707
        suite.addTest(loader.loadTestsFromModule(m))
666
708
    for m in (MODULES_TO_DOCTEST):
667
709
        suite.addTest(DocTestSuite(m))
668
 
    for p in bzrlib.plugin.all_plugins:
669
 
        if hasattr(p, 'test_suite'):
670
 
            suite.addTest(p.test_suite())
 
710
    for name, plugin in bzrlib.plugin.all_plugins().items():
 
711
        if hasattr(plugin, 'test_suite'):
 
712
            suite.addTest(plugin.test_suite())
671
713
    return suite
672
714
 
 
715
 
 
716
def _load_module_by_name(mod_name):
 
717
    parts = mod_name.split('.')
 
718
    module = __import__(mod_name)
 
719
    del parts[0]
 
720
    # for historical reasons python returns the top-level module even though
 
721
    # it loads the submodule; we need to walk down to get the one we want.
 
722
    while parts:
 
723
        module = getattr(module, parts.pop(0))
 
724
    return module