1
# Copyright (C) 2005, 2006 Canonical Ltd
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
# GNU General Public License for more details.
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
# "weren't nothing promised to you. do i look like i got a promise face?"
19
"""Tests for trace library"""
21
from cStringIO import StringIO
29
from bzrlib.tests import TestCaseInTempDir, TestCase
30
from bzrlib.trace import (
31
mutter, mutter_callsite, report_exception,
32
set_verbosity_level, get_verbosity_level, is_quiet, is_verbose, be_quiet,
36
def _format_exception():
37
"""Format an exception as it would normally be displayed to the user"""
39
report_exception(sys.exc_info(), buf)
43
class TestTrace(TestCase):
45
def test_format_sys_exception(self):
47
raise NotImplementedError, "time travel"
48
except NotImplementedError:
50
err = _format_exception()
51
self.assertEqualDiff(err.splitlines()[0],
52
'bzr: ERROR: exceptions.NotImplementedError: time travel')
53
self.assertContainsRe(err,
54
r'File.*test_trace.py')
56
def test_format_interrupt_exception(self):
58
raise KeyboardInterrupt()
59
except KeyboardInterrupt:
60
# XXX: Some risk that a *real* keyboard interrupt won't be seen
62
msg = _format_exception()
63
self.assertTrue(len(msg) > 0)
64
self.assertEqualDiff(msg, 'bzr: interrupted\n')
66
def test_format_os_error(self):
68
file('nosuchfile22222')
69
except (OSError, IOError):
71
msg = _format_exception()
72
self.assertContainsRe(msg, r'^bzr: ERROR: \[Errno .*\] No such file.*nosuchfile')
74
def test_format_unicode_error(self):
76
raise errors.BzrCommandError(u'argument foo\xb5 does not exist')
77
except errors.BzrCommandError:
79
msg = _format_exception()
81
def test_format_exception(self):
82
"""Short formatting of bzr exceptions"""
84
raise errors.NotBranchError('wibble')
85
except errors.NotBranchError:
87
msg = _format_exception()
88
self.assertTrue(len(msg) > 0)
89
self.assertEqualDiff(msg, 'bzr: ERROR: Not a branch: \"wibble\".\n')
91
def test_trace_unicode(self):
92
"""Write Unicode to trace log"""
93
self.log(u'the unicode character for benzene is \N{BENZENE RING}')
94
self.assertContainsRe(self._get_log(keep_log_file=True),
95
"the unicode character for benzene is")
97
def test_trace_argument_unicode(self):
98
"""Write a Unicode argument to the trace log"""
99
mutter(u'the unicode character for benzene is %s', u'\N{BENZENE RING}')
100
self.assertContainsRe(self._get_log(keep_log_file=True),
101
'the unicode character')
103
def test_trace_argument_utf8(self):
104
"""Write a Unicode argument to the trace log"""
105
mutter(u'the unicode character for benzene is %s',
106
u'\N{BENZENE RING}'.encode('utf-8'))
107
self.assertContainsRe(self._get_log(keep_log_file=True),
108
'the unicode character')
110
def test_report_broken_pipe(self):
112
raise IOError(errno.EPIPE, 'broken pipe foofofo')
114
msg = _format_exception()
115
self.assertEquals(msg, "bzr: broken pipe\n")
117
self.fail("expected error not raised")
119
def test_mutter_callsite_1(self):
120
"""mutter_callsite can capture 1 level of stack frame."""
121
mutter_callsite(1, "foo %s", "a string")
122
log = self._get_log(keep_log_file=True)
123
# begin with the message
124
self.assertStartsWith(log, 'foo a string\nCalled from:\n')
125
# should show two frame: this frame and the one above
126
self.assertContainsRe(log,
127
'test_trace\.py", line \d+, in test_mutter_callsite_1\n')
128
# this frame should be the final one
129
self.assertEndsWith(log, ' "a string")\n')
131
def test_mutter_callsite_2(self):
132
"""mutter_callsite can capture 2 levels of stack frame."""
133
mutter_callsite(2, "foo %s", "a string")
134
log = self._get_log(keep_log_file=True)
135
# begin with the message
136
self.assertStartsWith(log, 'foo a string\nCalled from:\n')
137
# should show two frame: this frame and the one above
138
self.assertContainsRe(log,
139
'test_trace.py", line \d+, in test_mutter_callsite_2\n')
140
# this frame should be the final one
141
self.assertEndsWith(log, ' "a string")\n')
143
def test_mutter_never_fails(self):
144
# Even if the decode/encode stage fails, mutter should not
146
mutter(u'Writing a greek mu (\xb5) works in a unicode string')
147
mutter('But fails in an ascii string \xb5')
148
mutter('and in an ascii argument: %s', '\xb5')
149
log = self._get_log(keep_log_file=True)
150
self.assertContainsRe(log, 'Writing a greek mu')
151
self.assertContainsRe(log, "But fails in an ascii string")
152
self.assertContainsRe(log, u"ascii argument: \xb5")
155
class TestVerbosityLevel(TestCase):
157
def test_verbosity_level(self):
158
set_verbosity_level(1)
159
self.assertEqual(1, get_verbosity_level())
160
self.assertTrue(is_verbose())
161
self.assertFalse(is_quiet())
162
set_verbosity_level(-1)
163
self.assertEqual(-1, get_verbosity_level())
164
self.assertFalse(is_verbose())
165
self.assertTrue(is_quiet())
166
set_verbosity_level(0)
167
self.assertEqual(0, get_verbosity_level())
168
self.assertFalse(is_verbose())
169
self.assertFalse(is_quiet())
171
def test_be_quiet(self):
172
# Confirm the old API still works
174
self.assertEqual(-1, get_verbosity_level())
176
self.assertEqual(0, get_verbosity_level())