~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_trace.py

  • Committer: John Arbash Meinel
  • Date: 2009-08-25 18:45:40 UTC
  • mto: (4634.6.15 2.0)
  • mto: This revision was merged to the branch mainline in revision 4667.
  • Revision ID: john@arbash-meinel.com-20090825184540-6dn3xjq62xhgj2gq
Add support for skipping ghost nodes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2005, 2006 Canonical Ltd
 
1
# Copyright (C) 2005, 2006, 2007, 2008, 2009 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
12
12
#
13
13
# You should have received a copy of the GNU General Public License
14
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
 
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
16
 
17
17
# "weren't nothing promised to you.  do i look like i got a promise face?"
18
18
 
21
21
from cStringIO import StringIO
22
22
import errno
23
23
import os
 
24
import re
24
25
import sys
 
26
import tempfile
25
27
 
26
28
from bzrlib import (
27
29
    errors,
28
30
    )
29
31
from bzrlib.tests import TestCaseInTempDir, TestCase
30
 
from bzrlib.trace import mutter, mutter_callsite, report_exception
 
32
from bzrlib.trace import (
 
33
    mutter, mutter_callsite, report_exception,
 
34
    set_verbosity_level, get_verbosity_level, is_quiet, is_verbose, be_quiet,
 
35
    pop_log_file,
 
36
    push_log_file,
 
37
    _rollover_trace_maybe,
 
38
    )
31
39
 
32
40
 
33
41
def _format_exception():
40
48
class TestTrace(TestCase):
41
49
 
42
50
    def test_format_sys_exception(self):
 
51
        # Test handling of an internal/unexpected error that probably
 
52
        # indicates a bug in bzr.  The details of the message may vary
 
53
        # depending on whether apport is available or not.  See test_crash for
 
54
        # more.
43
55
        try:
44
56
            raise NotImplementedError, "time travel"
45
57
        except NotImplementedError:
48
60
        self.assertEqualDiff(err.splitlines()[0],
49
61
                'bzr: ERROR: exceptions.NotImplementedError: time travel')
50
62
        self.assertContainsRe(err,
51
 
                r'File.*test_trace.py')
 
63
            'Bazaar has encountered an internal error.')
52
64
 
53
65
    def test_format_interrupt_exception(self):
54
66
        try:
62
74
 
63
75
    def test_format_os_error(self):
64
76
        try:
 
77
            os.rmdir('nosuchfile22222')
 
78
        except OSError:
 
79
            pass
 
80
        msg = _format_exception()
 
81
        self.assertContainsRe(msg,
 
82
            r'^bzr: ERROR: \[Errno .*\] No such file.*nosuchfile22222')
 
83
 
 
84
    def test_format_io_error(self):
 
85
        try:
65
86
            file('nosuchfile22222')
66
 
        except (OSError, IOError):
 
87
        except IOError:
67
88
            pass
68
89
        msg = _format_exception()
69
90
        self.assertContainsRe(msg, r'^bzr: ERROR: \[Errno .*\] No such file.*nosuchfile')
85
106
        self.assertTrue(len(msg) > 0)
86
107
        self.assertEqualDiff(msg, 'bzr: ERROR: Not a branch: \"wibble\".\n')
87
108
 
 
109
    def test_report_external_import_error(self):
 
110
        """Short friendly message for missing system modules."""
 
111
        try:
 
112
            import ImaginaryModule
 
113
        except ImportError, e:
 
114
            pass
 
115
        else:
 
116
            self.fail("somehow succeeded in importing %r" % ImaginaryModule)
 
117
        msg = _format_exception()
 
118
        self.assertEqual(msg,
 
119
            'bzr: ERROR: No module named ImaginaryModule\n'
 
120
            'You may need to install this Python library separately.\n')
 
121
 
 
122
    def test_report_import_syntax_error(self):
 
123
        try:
 
124
            raise ImportError("syntax error")
 
125
        except ImportError, e:
 
126
            pass
 
127
        msg = _format_exception()
 
128
        self.assertContainsRe(msg,
 
129
            r'Bazaar has encountered an internal error')
 
130
 
88
131
    def test_trace_unicode(self):
89
132
        """Write Unicode to trace log"""
90
133
        self.log(u'the unicode character for benzene is \N{BENZENE RING}')
91
134
        self.assertContainsRe(self._get_log(keep_log_file=True),
92
135
                              "the unicode character for benzene is")
93
 
    
 
136
 
94
137
    def test_trace_argument_unicode(self):
95
138
        """Write a Unicode argument to the trace log"""
96
139
        mutter(u'the unicode character for benzene is %s', u'\N{BENZENE RING}')
113
156
        else:
114
157
            self.fail("expected error not raised")
115
158
 
 
159
    def assertLogStartsWith(self, log, string):
 
160
        """Like assertStartsWith, but skips the log timestamp."""
 
161
        self.assertContainsRe(log,
 
162
            '^\\d+\\.\\d+  ' + re.escape(string))
 
163
 
116
164
    def test_mutter_callsite_1(self):
117
165
        """mutter_callsite can capture 1 level of stack frame."""
118
166
        mutter_callsite(1, "foo %s", "a string")
119
167
        log = self._get_log(keep_log_file=True)
120
168
        # begin with the message
121
 
        self.assertStartsWith(log, 'foo a string\nCalled from:\n')
 
169
        self.assertLogStartsWith(log, 'foo a string\nCalled from:\n')
122
170
        # should show two frame: this frame and the one above
123
171
        self.assertContainsRe(log,
124
 
            'test_trace\.py", line \d+, in test_mutter_callsite_1\n')
 
172
            'test_trace\\.py", line \\d+, in test_mutter_callsite_1\n')
125
173
        # this frame should be the final one
126
174
        self.assertEndsWith(log, ' "a string")\n')
127
175
 
130
178
        mutter_callsite(2, "foo %s", "a string")
131
179
        log = self._get_log(keep_log_file=True)
132
180
        # begin with the message
133
 
        self.assertStartsWith(log, 'foo a string\nCalled from:\n')
 
181
        self.assertLogStartsWith(log, 'foo a string\nCalled from:\n')
134
182
        # should show two frame: this frame and the one above
135
183
        self.assertContainsRe(log,
136
184
            'test_trace.py", line \d+, in test_mutter_callsite_2\n')
148
196
        self.assertContainsRe(log, "But fails in an ascii string")
149
197
        self.assertContainsRe(log, u"ascii argument: \xb5")
150
198
 
 
199
    def test_push_log_file(self):
 
200
        """Can push and pop log file, and this catches mutter messages.
 
201
 
 
202
        This is primarily for use in the test framework.
 
203
        """
 
204
        tmp1 = tempfile.NamedTemporaryFile()
 
205
        tmp2 = tempfile.NamedTemporaryFile()
 
206
        try:
 
207
            memento1 = push_log_file(tmp1)
 
208
            mutter("comment to file1")
 
209
            try:
 
210
                memento2 = push_log_file(tmp2)
 
211
                try:
 
212
                    mutter("comment to file2")
 
213
                finally:
 
214
                    pop_log_file(memento2)
 
215
                mutter("again to file1")
 
216
            finally:
 
217
                pop_log_file(memento1)
 
218
            # the files were opened in binary mode, so should have exactly
 
219
            # these bytes.  and removing the file as the log target should
 
220
            # have caused them to be flushed out.  need to match using regexps
 
221
            # as there's a timestamp at the front.
 
222
            tmp1.seek(0)
 
223
            self.assertContainsRe(tmp1.read(),
 
224
                r"\d+\.\d+  comment to file1\n\d+\.\d+  again to file1\n")
 
225
            tmp2.seek(0)
 
226
            self.assertContainsRe(tmp2.read(),
 
227
                r"\d+\.\d+  comment to file2\n")
 
228
        finally:
 
229
            tmp1.close()
 
230
            tmp2.close()
 
231
 
 
232
 
 
233
class TestVerbosityLevel(TestCase):
 
234
 
 
235
    def test_verbosity_level(self):
 
236
        set_verbosity_level(1)
 
237
        self.assertEqual(1, get_verbosity_level())
 
238
        self.assertTrue(is_verbose())
 
239
        self.assertFalse(is_quiet())
 
240
        set_verbosity_level(-1)
 
241
        self.assertEqual(-1, get_verbosity_level())
 
242
        self.assertFalse(is_verbose())
 
243
        self.assertTrue(is_quiet())
 
244
        set_verbosity_level(0)
 
245
        self.assertEqual(0, get_verbosity_level())
 
246
        self.assertFalse(is_verbose())
 
247
        self.assertFalse(is_quiet())
 
248
 
 
249
    def test_be_quiet(self):
 
250
        # Confirm the old API still works
 
251
        be_quiet(True)
 
252
        self.assertEqual(-1, get_verbosity_level())
 
253
        be_quiet(False)
 
254
        self.assertEqual(0, get_verbosity_level())
 
255
 
 
256
 
 
257
class TestBzrLog(TestCaseInTempDir):
 
258
 
 
259
    def test_log_rollover(self):
 
260
        temp_log_name = 'test-log'
 
261
        trace_file = open(temp_log_name, 'at')
 
262
        trace_file.write('test_log_rollover padding\n' * 1000000)
 
263
        trace_file.close()
 
264
        _rollover_trace_maybe(temp_log_name)
 
265
        # should have been rolled over
 
266
        self.assertFalse(os.access(temp_log_name, os.R_OK))