~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_trace.py

Don't encode unicode messages to UTF-8 in mutter() (the stream writer does it).

Use a codec wrapped log file in tests to match the real environment.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006 Canonical Ltd
 
1
# Copyright (C) 2005 by Canonical Ltd
 
2
#   Authors: Robert Collins <robert.collins@canonical.com>
2
3
#
3
4
# This program is free software; you can redistribute it and/or modify
4
5
# it under the terms of the GNU General Public License as published by
18
19
 
19
20
"""Tests for trace library"""
20
21
 
21
 
from cStringIO import StringIO
22
 
import errno
23
22
import os
24
23
import sys
25
24
 
26
 
from bzrlib import (
27
 
    errors,
28
 
    )
29
25
from bzrlib.tests import TestCaseInTempDir, TestCase
30
 
from bzrlib.trace import mutter, report_exception
31
 
 
32
 
 
33
 
def _format_exception():
34
 
    """Format an exception as it would normally be displayed to the user"""
35
 
    buf = StringIO()
36
 
    report_exception(sys.exc_info(), buf)
37
 
    return buf.getvalue()
38
 
 
 
26
from bzrlib.trace import format_exception_short, mutter
 
27
from bzrlib.errors import NotBranchError, BzrError, BzrNewError
39
28
 
40
29
class TestTrace(TestCase):
41
 
 
42
30
    def test_format_sys_exception(self):
 
31
        """Short formatting of exceptions"""
43
32
        try:
44
33
            raise NotImplementedError, "time travel"
45
34
        except NotImplementedError:
46
35
            pass
47
 
        err = _format_exception()
48
 
        self.assertEqualDiff(err.splitlines()[0],
49
 
                'bzr: ERROR: exceptions.NotImplementedError: time travel')
50
 
        self.assertContainsRe(err,
51
 
                r'File.*test_trace.py')
52
 
 
53
 
    def test_format_interrupt_exception(self):
54
 
        try:
55
 
            raise KeyboardInterrupt()
56
 
        except KeyboardInterrupt:
57
 
            # XXX: Some risk that a *real* keyboard interrupt won't be seen
58
 
            pass
59
 
        msg = _format_exception()
60
 
        self.assertTrue(len(msg) > 0)
61
 
        self.assertEqualDiff(msg, 'bzr: interrupted\n')
62
 
 
63
 
    def test_format_os_error(self):
64
 
        try:
65
 
            file('nosuchfile22222')
66
 
        except (OSError, IOError):
67
 
            pass
68
 
        msg = _format_exception()
69
 
        self.assertContainsRe(msg, r'^bzr: ERROR: \[Errno .*\] No such file.*nosuchfile')
70
 
 
71
 
    def test_format_unicode_error(self):
72
 
        try:
73
 
            raise errors.BzrCommandError(u'argument foo\xb5 does not exist')
74
 
        except errors.BzrCommandError:
75
 
            pass
76
 
        msg = _format_exception()
 
36
        error_lines = format_exception_short(sys.exc_info()).splitlines()
 
37
        self.assertEqualDiff(error_lines[0], 
 
38
                'exceptions.NotImplementedError: time travel')
 
39
        self.assertContainsRe(error_lines[1], 
 
40
                r'^  at .*trace\.py line \d+$')  
 
41
        self.assertContainsRe(error_lines[2], 
 
42
                r'^  in test_format_sys_exception$')
77
43
 
78
44
    def test_format_exception(self):
79
 
        """Short formatting of bzr exceptions"""
80
 
        try:
81
 
            raise errors.NotBranchError('wibble')
82
 
        except errors.NotBranchError:
83
 
            pass
84
 
        msg = _format_exception()
85
 
        self.assertTrue(len(msg) > 0)
86
 
        self.assertEqualDiff(msg, 'bzr: ERROR: Not a branch: wibble\n')
 
45
        """Short formatting of exceptions"""
 
46
        try:
 
47
            raise NotBranchError, 'wibble'
 
48
        except NotBranchError:
 
49
            pass
 
50
        msg = format_exception_short(sys.exc_info())
 
51
        self.assertEqualDiff(msg, 'Not a branch: wibble')
 
52
 
 
53
    def test_format_old_exception(self):
 
54
        # format a class that doesn't descend from BzrNewError; 
 
55
        # remove this test when everything is unified there
 
56
        self.assertFalse(issubclass(BzrError, BzrNewError))
 
57
        try:
 
58
            raise BzrError('some old error')
 
59
        except BzrError:
 
60
            pass
 
61
        msg = format_exception_short(sys.exc_info())
 
62
        self.assertEqualDiff(msg, 'some old error')
87
63
 
88
64
    def test_trace_unicode(self):
89
65
        """Write Unicode to trace log"""
90
66
        self.log(u'the unicode character for benzene is \N{BENZENE RING}')
91
 
        self.assertContainsRe(self._get_log(keep_log_file=True),
92
 
                              "the unicode character for benzene is")
93
 
    
94
 
    def test_trace_argument_unicode(self):
95
 
        """Write a Unicode argument to the trace log"""
96
 
        mutter(u'the unicode character for benzene is %s', u'\N{BENZENE RING}')
97
 
        self.assertContainsRe(self._get_log(keep_log_file=True),
98
 
                              'the unicode character')
99
 
 
100
 
    def test_trace_argument_utf8(self):
101
 
        """Write a Unicode argument to the trace log"""
102
 
        mutter(u'the unicode character for benzene is %s',
103
 
               u'\N{BENZENE RING}'.encode('utf-8'))
104
 
        self.assertContainsRe(self._get_log(keep_log_file=True),
105
 
                              'the unicode character')
106
 
 
107
 
    def test_report_broken_pipe(self):
108
 
        try:
109
 
            raise IOError(errno.EPIPE, 'broken pipe foofofo')
110
 
        except IOError, e:
111
 
            msg = _format_exception()
112
 
            self.assertEquals(msg, "bzr: broken pipe\n")
113
 
        else:
114
 
            self.fail("expected error not raised")
115
 
 
116
 
    def test_mutter_never_fails(self):
117
 
        # Even if the decode/encode stage fails, mutter should not
118
 
        # raise an exception
119
 
        mutter(u'Writing a greek mu (\xb5) works in a unicode string')
120
 
        mutter('But fails in an ascii string \xb5')
121
 
        mutter('and in an ascii argument: %s', '\xb5')
122
 
        log = self._get_log(keep_log_file=True)
123
 
        self.assertContainsRe(log, 'Writing a greek mu')
124
 
        self.assertContainsRe(log, "But fails in an ascii string")
125
 
        self.assertContainsRe(log, u"ascii argument: \xb5")
 
67
        self.assertContainsRe('the unicode character',
 
68
                self._get_log())