1
# Copyright (c) 2010, 2011, Canonical Ltd
3
# This program is free software: you can redistribute it and/or modify
4
# it under the terms of the GNU Affero General Public License as published by
5
# the Free Software Foundation, either version 3 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 Affero General Public License for more details.
13
# You should have received a copy of the GNU Affero General Public License
14
# along with this program. If not, see <http://www.gnu.org/licenses/>.
15
# GNU Affero General Public License version 3 (see the file LICENSE).
17
"""Tests for the legacy rfc822 based [de]serializer."""
23
from textwrap import dedent
28
from oops.serializer_rfc822 import (
35
class TestParsing(testtools.TestCase):
38
"""Test ErrorReport.read()."""
39
fp = StringIO.StringIO(dedent("""\
41
Exception-Type: NotFound
42
Exception-Value: error message
43
Date: 2005-04-01T00:00:00+00:00
44
Page-Id: IFoo:+foo-template
46
URL: http://localhost:9000/foo
49
HTTP_USER_AGENT=Mozilla/5.0
50
HTTP_REFERER=http://localhost:9000/
51
name%3Dfoo=hello%0Aworld
53
00001-00005@store_a SELECT 1
54
00005-00010@store_b SELECT 2
58
self.assertEqual(report['id'], 'OOPS-A0001')
59
self.assertEqual(report['type'], 'NotFound')
60
self.assertEqual(report['value'], 'error message')
62
report['time'], datetime.datetime(2005, 4, 1, tzinfo=utc))
63
self.assertEqual(report['pageid'], 'IFoo:+foo-template')
64
self.assertEqual(report['tb_text'], 'traceback-text')
65
self.assertEqual(report['username'], 'Sample User')
66
self.assertEqual(report['url'], 'http://localhost:9000/foo')
67
self.assertEqual(report['duration'], 42)
68
self.assertEqual(len(report['req_vars']), 3)
69
self.assertEqual(report['req_vars'][0], ('HTTP_USER_AGENT',
71
self.assertEqual(report['req_vars'][1], ('HTTP_REFERER',
72
'http://localhost:9000/'))
73
self.assertEqual(report['req_vars'][2], ('name=foo', 'hello\nworld'))
74
self.assertEqual(len(report['db_statements']), 2)
76
report['db_statements'][0],
77
(1, 5, 'store_a', 'SELECT 1'))
79
report['db_statements'][1],
80
(5, 10, 'store_b', 'SELECT 2'))
82
def test_read_no_store_id(self):
83
"""Test ErrorReport.read() for old logs with no store_id."""
84
fp = StringIO.StringIO(dedent("""\
86
Exception-Type: NotFound
87
Exception-Value: error message
88
Date: 2005-04-01T00:00:00+00:00
89
Page-Id: IFoo:+foo-template
91
URL: http://localhost:9000/foo
94
HTTP_USER_AGENT=Mozilla/5.0
95
HTTP_REFERER=http://localhost:9000/
96
name%3Dfoo=hello%0Aworld
103
self.assertEqual(report['id'], 'OOPS-A0001')
104
self.assertEqual(report['type'], 'NotFound')
105
self.assertEqual(report['value'], 'error message')
107
report['time'], datetime.datetime(2005, 4, 1, tzinfo=utc))
108
self.assertEqual(report['pageid'], 'IFoo:+foo-template')
109
self.assertEqual(report['tb_text'], 'traceback-text')
110
self.assertEqual(report['username'], 'Sample User')
111
self.assertEqual(report['url'], 'http://localhost:9000/foo')
112
self.assertEqual(report['duration'], 42)
113
self.assertEqual(len(report['req_vars']), 3)
114
self.assertEqual(report['req_vars'][0], ('HTTP_USER_AGENT',
116
self.assertEqual(report['req_vars'][1], ('HTTP_REFERER',
117
'http://localhost:9000/'))
118
self.assertEqual(report['req_vars'][2], ('name=foo', 'hello\nworld'))
119
self.assertEqual(len(report['db_statements']), 2)
120
self.assertEqual(report['db_statements'][0], (1, 5, None, 'SELECT 1'))
121
self.assertEqual(report['db_statements'][1], (5, 10, None, 'SELECT 2'))
122
self.assertFalse(report['informational'])
124
def test_read_branch_nick_revno(self):
125
"""Test ErrorReport.read()."""
126
fp = StringIO.StringIO(dedent("""\
128
Exception-Type: NotFound
129
Exception-Value: error message
130
Date: 2005-04-01T00:00:00+00:00
131
Page-Id: IFoo:+foo-template
133
URL: http://localhost:9000/foo
138
HTTP_USER_AGENT=Mozilla/5.0
139
HTTP_REFERER=http://localhost:9000/
140
name%3Dfoo=hello%0Aworld
142
00001-00005@store_a SELECT 1
143
00005-00010@store_b SELECT 2
147
self.assertEqual(report['branch_nick'], 'mybranch')
148
self.assertEqual(report['revno'], '45')
150
def test_minimal_oops(self):
151
# If we get a crazy-small oops, we can read it sensibly. Because there
152
# is existing legacy code, all keys are filled in with None, [] rather
154
fp = StringIO.StringIO(dedent("""\
158
self.assertEqual(report['id'], 'OOPS-A0001')
159
self.assertEqual(report['type'], None)
160
self.assertEqual(report['value'], None)
161
self.assertEqual(report['time'], None)
162
self.assertEqual(report['pageid'], None)
163
self.assertEqual(report['tb_text'], '')
164
self.assertEqual(report['username'], None)
165
self.assertEqual(report['url'], None)
166
self.assertEqual(report['duration'], -1)
167
self.assertEqual(len(report['req_vars']), 0)
168
self.assertEqual(len(report['db_statements']), 0)
169
self.assertFalse(report['informational'])
170
self.assertEqual(report['branch_nick'], None)
171
self.assertEqual(report['revno'], None)
174
class TestSerializing(testtools.TestCase):
176
def test_write_file(self):
177
output = StringIO.StringIO()
181
'value': 'error message',
182
'time': datetime.datetime(2005, 04, 01, 00, 00, 00, tzinfo=utc),
183
'pageid': 'IFoo:+foo-template',
184
'tb_text': 'traceback-text',
185
'username': 'Sample User',
186
'url': 'http://localhost:9000/foo',
188
'req_vars': [('HTTP_USER_AGENT', 'Mozilla/5.0'),
189
('HTTP_REFERER', 'http://localhost:9000/'),
190
('name=foo', 'hello\nworld')],
191
'db_statements': [(1, 5, 'store_a', 'SELECT 1'),
192
(5, 10, 'store_b', 'SELECT\n2')],
193
'informational': False,
194
'branch_nick': 'mybranch',
197
write(report, output)
198
self.assertEqual(output.getvalue(), dedent("""\
200
Exception-Type: NotFound
201
Exception-Value: error message
202
Date: 2005-04-01T00:00:00+00:00
203
Page-Id: IFoo:+foo-template
207
URL: http://localhost:9000/foo
211
HTTP_USER_AGENT=Mozilla/5.0
212
HTTP_REFERER=http://localhost:9000/
213
name%3Dfoo=hello%0Aworld
215
00001-00005@store_a SELECT 1
216
00005-00010@store_b SELECT 2
220
def test_to_chunks(self):
224
'value': 'error message',
225
'time': datetime.datetime(2005, 04, 01, 00, 00, 00, tzinfo=utc),
226
'pageid': 'IFoo:+foo-template',
227
'tb_text': 'traceback-text',
228
'username': 'Sample User',
229
'url': 'http://localhost:9000/foo',
231
'req_vars': [('HTTP_USER_AGENT', 'Mozilla/5.0'),
232
('HTTP_REFERER', 'http://localhost:9000/'),
233
('name=foo', 'hello\nworld')],
234
'db_statements': [(1, 5, 'store_a', 'SELECT 1'),
235
(5, 10, 'store_b', 'SELECT\n2')],
236
'informational': False,
237
'branch_nick': 'mybranch',
241
"Oops-Id: OOPS-A0001\n",
242
"Exception-Type: NotFound\n",
243
"Exception-Value: error message\n",
244
"Date: 2005-04-01T00:00:00+00:00\n",
245
"Page-Id: IFoo:+foo-template\n",
246
"Branch: mybranch\n",
248
"User: Sample User\n",
249
"URL: http://localhost:9000/foo\n",
251
"Informational: False\n",
253
"HTTP_USER_AGENT=Mozilla/5.0\n",
254
"HTTP_REFERER=http://localhost:9000/\n",
255
"name%3Dfoo=hello%0Aworld\n",
257
"00001-00005@store_a SELECT 1\n",
258
"00005-00010@store_b SELECT 2\n",
264
def test_minimal_oops(self):
265
# An oops with just an id, though arguably crazy, is written
267
report = {'id': 'OOPS-1234'}
269
"Oops-Id: OOPS-1234\n",
271
], to_chunks(report))