/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_trace.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2006-11-16 18:33:33 UTC
  • mfrom: (2138.1.1 robuster.external.diff)
  • Revision ID: pqm@pqm.ubuntu.com-20061116183333-5f56523d7b44e564
(Dmitry Vasiliev) Robuster external diff output handling.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005 by Canonical Ltd
2
 
#   Authors: Robert Collins <robert.collins@canonical.com>
 
1
# Copyright (C) 2005, 2006 Canonical Ltd
3
2
#
4
3
# This program is free software; you can redistribute it and/or modify
5
4
# it under the terms of the GNU General Public License as published by
19
18
 
20
19
"""Tests for trace library"""
21
20
 
 
21
from cStringIO import StringIO
 
22
import errno
22
23
import os
23
24
import sys
24
25
 
25
 
from bzrlib.tests import TestCaseInTempDir, TestCase
26
 
from bzrlib.trace import format_exception_short, mutter
27
 
from bzrlib.errors import NotBranchError, BzrError, BzrNewError
 
26
from bzrlib import (
 
27
    errors,
 
28
    plugin,
 
29
    trace,
 
30
    )
 
31
from bzrlib.tests import TestCaseInTempDir, TestCase, TestSkipped
 
32
from bzrlib.trace import mutter, report_exception
 
33
 
 
34
 
 
35
def _format_exception():
 
36
    """Format an exception as it would normally be displayed to the user"""
 
37
    buf = StringIO()
 
38
    report = report_exception(sys.exc_info(), buf)
 
39
    return buf.getvalue(), report
 
40
 
28
41
 
29
42
class TestTrace(TestCase):
30
 
    def test_format_sys_exception(self):
31
 
        """Short formatting of exceptions"""
32
 
        try:
33
 
            raise NotImplementedError, "time travel"
34
 
        except NotImplementedError:
35
 
            pass
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$')
 
43
 
 
44
    def test_format_sys_exception_no_apport(self):
 
45
        try:
 
46
            raise NotImplementedError, "time travel"
 
47
        except NotImplementedError:
 
48
            pass
 
49
        old_use_apport = trace._use_apport
 
50
        trace._use_apport = False
 
51
        try:
 
52
            err, report = _format_exception()
 
53
        finally:
 
54
            trace._use_apport = old_use_apport
 
55
        self.assertEqual(None, report)
 
56
        self.assertEqualDiff(err.splitlines()[0],
 
57
                'bzr: ERROR: exceptions.NotImplementedError: time travel')
 
58
        self.assertContainsRe(err,
 
59
                r'File.*test_trace.py')
 
60
 
 
61
    def test_format_sys_exception_apport(self):
 
62
        try:
 
63
            import problem_report
 
64
        except ImportError:
 
65
            raise TestSkipped('Apport not installed')
 
66
        try:
 
67
            raise NotImplementedError, "time travel"
 
68
        except NotImplementedError:
 
69
            pass
 
70
        old_argv = sys.argv
 
71
        sys.argv = ['foo', 'bar', 'quux']
 
72
        try:
 
73
            err, (report, report_filename) = _format_exception()
 
74
        finally:
 
75
            sys.argv = old_argv
 
76
        self.assertIsInstance(report, problem_report.ProblemReport)
 
77
        # the error formatting is checked by the blackbox ui command.
 
78
        # here we need to check that the file on disk - the problem report
 
79
        # will contain the right information.
 
80
        # the report needs:
 
81
        #  - the command line.
 
82
        #  - package data
 
83
        #  - plugins list
 
84
        #  - backtrace.
 
85
        # check the report logical data.
 
86
        self.assertEqual('foo bar quux', report['CommandLine'])
 
87
        known_plugins = ' '.join(plugin.all_plugins())
 
88
        self.assertEqual(known_plugins, report['BzrPlugins'])
 
89
        self.assertContainsRe(report['Traceback'], r'Traceback')
 
90
        # Stock apport facilities we just invoke, no need to test their
 
91
        # content
 
92
        self.assertNotEqual(None, report['Package'])
 
93
        self.assertNotEqual(None, report['Uname'])
 
94
        # check the file 'looks' like a good file, because we dont
 
95
        # want apport changes to break the user interface.
 
96
        report_file = file(report_filename, 'r')
 
97
        try:
 
98
            report_text = report_file.read()
 
99
        finally:
 
100
            report_file.close()
 
101
        # so we check this by looking across two fields and they should
 
102
        # be just \n separated.
 
103
        self.assertTrue('ProblemType: Crash\n'
 
104
            'BzrPlugins: ' in report_text)
 
105
 
 
106
    def test_format_interrupt_exception(self):
 
107
        try:
 
108
            raise KeyboardInterrupt()
 
109
        except KeyboardInterrupt:
 
110
            # XXX: Some risk that a *real* keyboard interrupt won't be seen
 
111
            # We can probably detect that by checking for the specific line
 
112
            # that we raise from in the test being in the backtrace.
 
113
            pass
 
114
        msg, report = _format_exception()
 
115
        self.assertTrue(len(msg) > 0)
 
116
        self.assertEqualDiff(msg, 'bzr: interrupted\n')
 
117
 
 
118
    def test_format_os_error(self):
 
119
        try:
 
120
            file('nosuchfile22222')
 
121
        except (OSError, IOError):
 
122
            pass
 
123
        msg, report = _format_exception()
 
124
        self.assertContainsRe(msg, r'^bzr: ERROR: \[Errno .*\] No such file.*nosuchfile')
 
125
 
 
126
    def test_format_unicode_error(self):
 
127
        try:
 
128
            raise errors.BzrCommandError(u'argument foo\xb5 does not exist')
 
129
        except errors.BzrCommandError:
 
130
            pass
 
131
        msg, report = _format_exception()
43
132
 
44
133
    def test_format_exception(self):
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')
 
134
        """Short formatting of bzr exceptions"""
 
135
        try:
 
136
            raise errors.NotBranchError('wibble')
 
137
        except errors.NotBranchError:
 
138
            pass
 
139
        msg, report = _format_exception()
 
140
        self.assertTrue(len(msg) > 0)
 
141
        self.assertEqualDiff(msg, 'bzr: ERROR: Not a branch: wibble\n')
63
142
 
64
143
    def test_trace_unicode(self):
65
144
        """Write Unicode to trace log"""
66
145
        self.log(u'the unicode character for benzene is \N{BENZENE RING}')
67
 
        self.assertContainsRe('the unicode character',
68
 
                self._get_log())
 
146
        self.assertContainsRe(self._get_log(keep_log_file=True),
 
147
                              "the unicode character for benzene is")
 
148
    
 
149
    def test_trace_argument_unicode(self):
 
150
        """Write a Unicode argument to the trace log"""
 
151
        mutter(u'the unicode character for benzene is %s', u'\N{BENZENE RING}')
 
152
        self.assertContainsRe(self._get_log(keep_log_file=True),
 
153
                              'the unicode character')
 
154
 
 
155
    def test_trace_argument_utf8(self):
 
156
        """Write a Unicode argument to the trace log"""
 
157
        mutter(u'the unicode character for benzene is %s',
 
158
               u'\N{BENZENE RING}'.encode('utf-8'))
 
159
        self.assertContainsRe(self._get_log(keep_log_file=True),
 
160
                              'the unicode character')
 
161
 
 
162
    def test_report_broken_pipe(self):
 
163
        try:
 
164
            raise IOError(errno.EPIPE, 'broken pipe foofofo')
 
165
        except IOError, e:
 
166
            msg, report = _format_exception()
 
167
            self.assertEquals(msg, "bzr: broken pipe\n")
 
168
        else:
 
169
            self.fail("expected error not raised")
 
170
 
 
171
    def test_mutter_never_fails(self):
 
172
        # Even if the decode/encode stage fails, mutter should not
 
173
        # raise an exception
 
174
        mutter(u'Writing a greek mu (\xb5) works in a unicode string')
 
175
        mutter('But fails in an ascii string \xb5')
 
176
        mutter('and in an ascii argument: %s', '\xb5')
 
177
        log = self._get_log(keep_log_file=True)
 
178
        self.assertContainsRe(log, 'Writing a greek mu')
 
179
        self.assertContainsRe(log, "But fails in an ascii string")
 
180
        self.assertContainsRe(log, u"ascii argument: \xb5")