~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/__init__.py

  • Committer: Robert Collins
  • Date: 2009-12-06 00:12:45 UTC
  • mto: This revision was merged to the branch mainline in revision 4920.
  • Revision ID: robertc@robertcollins.net-20091206001245-x1nv37nkl21xktyy
Move the passing of test logs to the result to be via the getDetails API and remove all public use of TestCase._get_log.

Show diffs side-by-side

added added

removed removed

Lines of Context:
46
46
import tempfile
47
47
import threading
48
48
import time
 
49
import traceback
49
50
import unittest
50
51
import warnings
51
52
 
364
365
        self.not_applicable_count += 1
365
366
        self.report_not_applicable(test, reason)
366
367
 
367
 
    def printErrorList(self, flavour, errors):
368
 
        for test, err in errors:
369
 
            self.stream.writeln(self.separator1)
370
 
            self.stream.write("%s: " % flavour)
371
 
            self.stream.writeln(self.getDescription(test))
372
 
            if getattr(test, '_get_log', None) is not None:
373
 
                log_contents = test._get_log()
374
 
                if log_contents:
375
 
                    self.stream.write('\n')
376
 
                    self.stream.write(
377
 
                            ('vvvv[log from %s]' % test.id()).ljust(78,'-'))
378
 
                    self.stream.write('\n')
379
 
                    self.stream.write(log_contents)
380
 
                    self.stream.write('\n')
381
 
                    self.stream.write(
382
 
                            ('^^^^[log from %s]' % test.id()).ljust(78,'-'))
383
 
                    self.stream.write('\n')
384
 
            self.stream.writeln(self.separator2)
385
 
            self.stream.writeln("%s" % err)
386
 
 
387
368
    def _post_mortem(self):
388
369
        """Start a PDB post mortem session."""
389
370
        if os.environ.get('BZR_TEST_PDB', None):
602
583
            applied left to right - the first element in the list is the 
603
584
            innermost decorator.
604
585
        """
 
586
        # stream may know claim to know to write unicode strings, but in older
 
587
        # pythons this goes sufficiently wrong that it is a bad idea. (
 
588
        # specifically a built in file with encoding 'UTF-8' will still try
 
589
        # to encode using ascii.
 
590
        new_encoding = osutils.get_terminal_encoding()
 
591
        stream = codecs.getwriter(new_encoding)(stream)
 
592
        stream.encoding = new_encoding
605
593
        self.stream = unittest._WritelnDecorator(stream)
606
594
        self.descriptions = descriptions
607
595
        self.verbosity = verbosity
670
658
    """
671
659
 
672
660
 
 
661
# traceback._some_str fails to format exceptions that have the default
 
662
# __str__ which does an implicit ascii conversion. However, repr() on those
 
663
# objects works, for all that its not quite what the doctor may have ordered.
 
664
def _clever_some_str(value):
 
665
    try:
 
666
        return str(value)
 
667
    except:
 
668
        try:
 
669
            return repr(value).replace('\\n', '\n')
 
670
        except:
 
671
            return '<unprintable %s object>' % type(value).__name__
 
672
 
 
673
traceback._some_str = _clever_some_str
 
674
 
 
675
 
 
676
 
673
677
class KnownFailure(AssertionError):
674
678
    """Indicates that a test failed in a precisely expected manner.
675
679
 
798
802
            (TestNotApplicable, self._do_not_applicable))
799
803
        self.exception_handlers.insert(0,
800
804
            (KnownFailure, self._do_known_failure))
 
805
 
 
806
    def setUp(self):
 
807
        super(TestCase, self).setUp()
 
808
        for feature in getattr(self, '_test_needs_features', []):
 
809
            self.requireFeature(feature)
801
810
        self._log_contents = None
802
811
        self.addDetail("log", content.Content(content.ContentType("text",
803
812
            "plain", {"charset": "utf8"}),
804
 
            lambda:[self._get_log(keep_log_file=True)]))
805
 
 
806
 
    def setUp(self):
807
 
        super(TestCase, self).setUp()
808
 
        for feature in getattr(self, '_test_needs_features', []):
809
 
            self.requireFeature(feature)
 
813
            lambda:[self._get_log(keep_log_file=True, _utf8=True)]))
810
814
        self._cleanEnvironment()
811
815
        self._silenceUI()
812
816
        self._startLogFile()
1631
1635
    def log(self, *args):
1632
1636
        mutter(*args)
1633
1637
 
1634
 
    def _get_log(self, keep_log_file=False):
 
1638
    def _get_log(self, keep_log_file=False, _utf8=False):
1635
1639
        """Get the log from bzrlib.trace calls from this test.
1636
1640
 
1637
1641
        :param keep_log_file: When True, if the log is still a file on disk
1638
1642
            leave it as a file on disk. When False, if the log is still a file
1639
1643
            on disk, the log file is deleted and the log preserved as
1640
1644
            self._log_contents.
 
1645
        :param _utf8: Private for the getDetails callback; used to ensure that
 
1646
            the returned content is valid utf8.
1641
1647
        :return: A string containing the log.
1642
1648
        """
1643
1649
        if self._log_contents is not None:
 
1650
            if _utf8:
 
1651
                try:
 
1652
                    self._log_contents.decode('utf8')
 
1653
                except UnicodeDecodeError:
 
1654
                    unicodestr = self._log_contents.decode('utf8', 'replace')
 
1655
                    self._log_contents = unicodestr.encode('utf8')
1644
1656
            return self._log_contents
1645
1657
        import bzrlib.trace
1646
1658
        if bzrlib.trace._trace_file:
1652
1664
                log_contents = logfile.read()
1653
1665
            finally:
1654
1666
                logfile.close()
 
1667
            if _utf8:
 
1668
                try:
 
1669
                    log_contents.decode('utf8')
 
1670
                except UnicodeDecodeError:
 
1671
                    unicodestr = log_contents.decode('utf8', 'replace')
 
1672
                    log_contents = unicodestr.encode('utf8')
1655
1673
            if not keep_log_file:
1656
1674
                # Permit multiple calls to get_log.
1657
1675
                self._log_contents = log_contents
3075
3093
        if self.randomised:
3076
3094
            return iter(self._tests)
3077
3095
        self.randomised = True
3078
 
        self.stream.writeln("Randomizing test order using seed %s\n" %
 
3096
        self.stream.write("Randomizing test order using seed %s\n" %
3079
3097
            (self.actual_seed()))
3080
3098
        # Initialise the random number generator.
3081
3099
        random.seed(self.actual_seed())