76
68
self.assertTrue(len(msg) > 0)
77
69
self.assertEqualDiff(msg, 'bzr: interrupted\n')
79
def test_format_memory_error(self):
84
msg = _format_exception()
86
"bzr: out of memory\nUse -Dmem_dump to dump memory to a file.\n")
88
def test_format_mem_dump(self):
89
self.requireFeature(features.meliae)
90
debug.debug_flags.add('mem_dump')
95
msg = _format_exception()
96
self.assertStartsWith(msg,
97
"bzr: out of memory\nMemory dumped to ")
99
71
def test_format_os_error(self):
101
os.rmdir('nosuchfile22222')
104
msg = _format_exception()
105
# Linux seems to give "No such file" but Windows gives "The system
106
# cannot find the file specified".
107
self.assertEqual('bzr: ERROR: %s\n' % (e_str,), msg)
109
def test_format_io_error(self):
111
73
file('nosuchfile22222')
114
msg = _format_exception()
115
# Even though Windows and Linux differ for 'os.rmdir', they both give
116
# 'No such file' for open()
117
# However it now gets translated so we can not test for a specific message
118
self.assertContainsRe(msg,
119
r'^bzr: ERROR: \[Errno .*\] .*nosuchfile')
121
def test_format_pywintypes_error(self):
122
self.requireFeature(features.pywintypes)
123
import pywintypes, win32file
125
win32file.RemoveDirectory('nosuchfile22222')
126
except pywintypes.error:
128
msg = _format_exception()
129
# GZ 2010-05-03: Formatting for pywintypes.error is basic, a 3-tuple
130
# with errno, function name, and locale error message
131
self.assertContainsRe(msg,
132
r"^bzr: ERROR: \(2, 'RemoveDirectory[AW]?', .*\)")
134
def test_format_sockets_error(self):
137
sock = socket.socket()
138
sock.send("This should fail.")
141
msg = _format_exception()
143
self.assertNotContainsRe(msg,
144
r"Traceback (most recent call last):")
74
except (OSError, IOError):
76
msg = _format_exception()
77
self.assertContainsRe(msg, r'^bzr: ERROR: \[Errno .*\] No such file.*nosuchfile')
146
79
def test_format_unicode_error(self):
181
114
msg = _format_exception()
182
115
self.assertContainsRe(msg,
183
r'Bazaar has encountered an internal error')
116
r"Traceback \(most recent call last\)")
185
118
def test_trace_unicode(self):
186
119
"""Write Unicode to trace log"""
187
120
self.log(u'the unicode character for benzene is \N{BENZENE RING}')
189
self.assertContainsRe(log, "the unicode character for benzene is")
121
self.assertContainsRe(self._get_log(keep_log_file=True),
122
"the unicode character for benzene is")
191
124
def test_trace_argument_unicode(self):
192
125
"""Write a Unicode argument to the trace log"""
193
126
mutter(u'the unicode character for benzene is %s', u'\N{BENZENE RING}')
195
self.assertContainsRe(log, 'the unicode character')
127
self.assertContainsRe(self._get_log(keep_log_file=True),
128
'the unicode character')
197
130
def test_trace_argument_utf8(self):
198
131
"""Write a Unicode argument to the trace log"""
199
132
mutter(u'the unicode character for benzene is %s',
200
133
u'\N{BENZENE RING}'.encode('utf-8'))
202
self.assertContainsRe(log, 'the unicode character')
134
self.assertContainsRe(self._get_log(keep_log_file=True),
135
'the unicode character')
204
137
def test_report_broken_pipe(self):
206
139
raise IOError(errno.EPIPE, 'broken pipe foofofo')
208
141
msg = _format_exception()
209
self.assertEqual(msg, "bzr: broken pipe\n")
142
self.assertEquals(msg, "bzr: broken pipe\n")
211
144
self.fail("expected error not raised")
242
175
def test_mutter_never_fails(self):
243
176
# Even if the decode/encode stage fails, mutter should not
244
177
# raise an exception
245
# This test checks that mutter doesn't fail; the current behaviour
246
# is that it doesn't fail *and writes non-utf8*.
247
178
mutter(u'Writing a greek mu (\xb5) works in a unicode string')
248
179
mutter('But fails in an ascii string \xb5')
249
180
mutter('and in an ascii argument: %s', '\xb5')
181
log = self._get_log(keep_log_file=True)
251
182
self.assertContainsRe(log, 'Writing a greek mu')
252
183
self.assertContainsRe(log, "But fails in an ascii string")
253
# However, the log content object does unicode replacement on reading
254
# to let it get unicode back where good data has been written. So we
255
# have to do a replaceent here as well.
256
self.assertContainsRe(log, "ascii argument: \xb5".decode('utf8',
259
def test_show_error(self):
261
show_error(u'error2 \xb5 blah')
262
show_error('arg: %s', 'blah')
263
show_error('arg2: %(key)s', {'key':'stuff'})
265
raise Exception("oops")
267
show_error('kwarg', exc_info=True)
269
self.assertContainsRe(log, 'error1')
270
self.assertContainsRe(log, u'error2 \xb5 blah')
271
self.assertContainsRe(log, 'arg: blah')
272
self.assertContainsRe(log, 'arg2: stuff')
273
self.assertContainsRe(log, 'kwarg')
274
self.assertContainsRe(log, 'Traceback \\(most recent call last\\):')
275
self.assertContainsRe(log, 'File ".*test_trace.py", line .*, in test_show_error')
276
self.assertContainsRe(log, 'raise Exception\\("oops"\\)')
277
self.assertContainsRe(log, 'Exception: oops')
184
self.assertContainsRe(log, u"ascii argument: \xb5")
279
186
def test_push_log_file(self):
280
187
"""Can push and pop log file, and this catches mutter messages.
282
This is primarily for use in the test framework.
189
This is primarily for use in the test framework.
284
191
tmp1 = tempfile.NamedTemporaryFile()
285
192
tmp2 = tempfile.NamedTemporaryFile()
312
def test__open_bzr_log_uses_stderr_for_failures(self):
313
# If _open_bzr_log cannot open the file, then we should write the
314
# warning to stderr. Since this is normally happening before logging is
316
self.overrideAttr(sys, 'stderr', StringIO())
317
# Set the log file to something that cannot exist
318
self.overrideEnv('BZR_LOG', os.getcwd() + '/no-dir/bzr.log')
319
self.overrideAttr(trace, '_bzr_log_filename')
320
logf = trace._open_bzr_log()
321
self.assertIs(None, logf)
322
self.assertContainsRe(sys.stderr.getvalue(),
323
'failed to open trace file: .*/no-dir/bzr.log')
326
220
class TestVerbosityLevel(TestCase):
347
241
self.assertEqual(0, get_verbosity_level())
350
class TestLogging(TestCase):
351
"""Check logging functionality robustly records information"""
355
self.assertEqual(" INFO Noted\n", self.get_log())
357
def test_warning(self):
358
trace.warning("Warned")
359
self.assertEqual(" WARNING Warned\n", self.get_log())
362
logging.getLogger("bzr").error("Errored")
363
self.assertEqual(" ERROR Errored\n", self.get_log())
365
def test_log_sub(self):
366
logging.getLogger("bzr.test_log_sub").debug("Whispered")
367
self.assertEqual(" DEBUG Whispered\n", self.get_log())
369
def test_log_unicode_msg(self):
370
logging.getLogger("bzr").debug(u"\xa7")
371
self.assertEqual(u" DEBUG \xa7\n", self.get_log())
373
def test_log_unicode_arg(self):
374
logging.getLogger("bzr").debug("%s", u"\xa7")
375
self.assertEqual(u" DEBUG \xa7\n", self.get_log())
377
def test_log_utf8_msg(self):
378
logging.getLogger("bzr").debug("\xc2\xa7")
379
self.assertEqual(u" DEBUG \xa7\n", self.get_log())
381
def test_log_utf8_arg(self):
382
logging.getLogger("bzr").debug("%s", "\xc2\xa7")
383
self.assertEqual(u" DEBUG \xa7\n", self.get_log())
385
def test_log_bytes_msg(self):
386
logging.getLogger("bzr").debug("\xa7")
388
self.assertContainsString(log, "UnicodeDecodeError: ")
389
self.assertContainsString(log,
390
"Logging record unformattable: '\\xa7' % ()\n")
392
def test_log_bytes_arg(self):
393
logging.getLogger("bzr").debug("%s", "\xa7")
395
self.assertContainsString(log, "UnicodeDecodeError: ")
396
self.assertContainsString(log,
397
"Logging record unformattable: '%s' % ('\\xa7',)\n")
399
def test_log_mixed_strings(self):
400
logging.getLogger("bzr").debug(u"%s", "\xa7")
402
self.assertContainsString(log, "UnicodeDecodeError: ")
403
self.assertContainsString(log,
404
"Logging record unformattable: u'%s' % ('\\xa7',)\n")
406
def test_log_repr_broken(self):
407
class BadRepr(object):
409
raise ValueError("Broken object")
410
logging.getLogger("bzr").debug("%s", BadRepr())
412
self.assertContainsRe(log, "ValueError: Broken object\n")
413
self.assertContainsRe(log, "Logging record unformattable: '%s' % .*\n")
416
244
class TestBzrLog(TestCaseInTempDir):
418
246
def test_log_rollover(self):
419
247
temp_log_name = 'test-log'
420
248
trace_file = open(temp_log_name, 'at')
421
trace_file.writelines(['test_log_rollover padding\n'] * 200000)
249
trace_file.write('test_log_rollover padding\n' * 1000000)
422
250
trace_file.close()
423
251
_rollover_trace_maybe(temp_log_name)
424
252
# should have been rolled over
425
253
self.assertFalse(os.access(temp_log_name, os.R_OK))
428
class TestTraceConfiguration(TestCaseInTempDir):
430
def test_default_config(self):
431
config = trace.DefaultConfig()
432
self.overrideAttr(trace, "_bzr_log_filename", None)
433
trace._bzr_log_filename = None
434
expected_filename = trace._get_bzr_log_filename()
435
self.assertEqual(None, trace._bzr_log_filename)
438
# Should have entered and setup a default filename.
439
self.assertEqual(expected_filename, trace._bzr_log_filename)
441
config.__exit__(None, None, None)
442
# Should have exited and cleaned up.
443
self.assertEqual(None, trace._bzr_log_filename)