Completed
Push — master ( 3a5649...6a4ed1 )
by
unknown
42s
created

SendStackTraceTest   A

Complexity

Total Complexity 1

Size/Duplication

Total Lines 127
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 127
rs 10
c 0
b 0
f 0
wmc 1

1 Method

Rating   Name   Duplication   Size   Complexity  
B test_send_stacktrace() 0 126 1
1
# coding: utf8
2
3
"""
4
This software is licensed under the Apache 2 license, quoted below.
5
6
Copyright 2014 Crystalnix Limited
7
8
Licensed under the Apache License, Version 2.0 (the "License"); you may not
9
use this file except in compliance with the License. You may obtain a copy of
10
the License at
11
12
    http://www.apache.org/licenses/LICENSE-2.0
13
14
Unless required by applicable law or agreed to in writing, software
15
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
17
License for the specific language governing permissions and limitations under
18
the License.
19
"""
20
21
from builtins import bytes
22
23
import os
24
25
from mock import patch
26
27
from django import test
28
from django.core.files.uploadedfile import SimpleUploadedFile
29
from django.core.urlresolvers import reverse
30
31
from omaha_server.utils import is_private
32
from crash.utils import (
33
    get_stacktrace,
34
    add_signature_to_frame,
35
    parse_stacktrace,
36
    get_signature,
37
    get_channel,
38
    send_stacktrace,
39
    parse_debug_meta_info,
40
)
41
42
from crash.models import Crash
43
from crash.tests.test_stacktrace_to_json import stacktrace
44
from omaha.factories import VersionFactory
45
from omaha.models import Version
46
from sparkle.factories import SparkleVersionFactory
47
from sparkle.models import SparkleVersion
48
49
BASE_DIR = os.path.dirname(__file__)
50
TEST_DATA_DIR = os.path.join(BASE_DIR, 'testdata')
51
SYMBOLS_PATH = os.path.join(TEST_DATA_DIR, 'symbols')
52
CRASH_DUMP_PATH = os.path.join(TEST_DATA_DIR, '7b05e196-7e23-416b-bd13-99287924e214.dmp')
53
STACKTRACE_PATH = os.path.join(TEST_DATA_DIR, 'stacktrace.txt')
54
55
56
class ShTest(test.TestCase):
57
    def test_get_stacktrace(self):
58
        with open(STACKTRACE_PATH, 'rb') as f:
59
            stacktrace = f.read()
60
61
        result = get_stacktrace(CRASH_DUMP_PATH)
62
63
        self.assertEqual(bytes(result.stdout, 'utf8'), stacktrace)
64
65
66
class SignatureTest(test.TestCase):
67
    test_data = [
68
        ({'frame': 0,
69
          'module': 'bad.dll',
70
          'function': 'Func(A * a,B b)',
71
          'file': 'hg:hg.m.org/repo/name:dname/fname:rev',
72
          'line': 576},
73
         {'function': 'Func(A* a, B b)',
74
          'short_signature': 'Func',
75
          'line': 576,
76
          'file': 'hg:hg.m.org/repo/name:dname/fname:rev',
77
          'frame': 0,
78
          'signature': 'Func(A* a, B b)',
79
          'module': 'bad.dll'}),
80
        ({'file': r'c:\work\breakpadtestapp\breakpadtestapp\breakpadtestapp.cpp',
81
          'frame': 0,
82
          'function': 'crashedFunc()',
83
          'line': 34,
84
          'module': 'BreakpadTestApp.exe'},
85
         {'file': r'c:\work\breakpadtestapp\breakpadtestapp\breakpadtestapp.cpp',
86
          'frame': 0,
87
          'function': 'crashedFunc()',
88
          'line': 34,
89
          'module': 'BreakpadTestApp.exe',
90
          'short_signature': 'crashedFunc',
91
          'signature': 'crashedFunc()'})
92
    ]
93
94
    def test_add_signature_to_frame(self):
95
        for i in self.test_data:
96
            self.assertDictEqual(add_signature_to_frame(i[0]), i[1])
97
98
    def test_parse_stacktrace(self):
99
        stacktrace_dict = parse_stacktrace(stacktrace)
100
        self.assertDictEqual(stacktrace_dict['crashing_thread']['frames'][0],
101
                             {'abs_path': r'c:\work\breakpadtestapp\breakpadtestapp\breakpadtestapp.cpp',
102
                              'frame': 0,
103
                              'function': 'crashedFunc()',
104
                              'lineno': 34,
105
                              'filename': 'BreakpadTestApp.exe',
106
                              'short_signature': 'crashedFunc',
107
                              'signature': 'crashedFunc()'})
108
109
    def test_get_signature(self):
110
        self.assertEqual(get_signature(parse_stacktrace(stacktrace)), 'crashedFunc()')
111
112
113
class SendStackTraceTest(test.TestCase):
114
    @patch('crash.utils.crash_sender')
115
    @test.override_settings(HOST_NAME='example.com',
116
                            CELERY_EAGER_PROPAGATES_EXCEPTIONS=False,)
117
    @is_private(False)
118
    def test_send_stacktrace(self, mock_client):
119
        meta = dict(
120
            lang='en',
121
            version='1.0.0.1',
122
        )
123
        crash = Crash(
124
            pk=123,
125
            upload_file_minidump=SimpleUploadedFile('./dump.dat', False),
126
            stacktrace=stacktrace,
127
            stacktrace_json=parse_stacktrace(stacktrace),
128
            appid='{D0AB2EBC-931B-4013-9FEB-C9C4C2225C8C}',
129
            userid='{2882CF9B-D9C2-4edb-9AAF-8ED5FCF366F7}',
130
            meta=meta,
131
            signature='signature',
132
        )
133
134
        send_stacktrace(crash)
135
136
        extra = {
137
            'crash_admin_panel_url': 'http://{}{}'.format(
138
                'example.com',
139
                '/admin/crash/crash/%s/' % crash.pk),
140
            'crashdump_url': crash.upload_file_minidump.url,
141
            'lang': 'en',
142
            'version': '1.0.0.1'}
143
144
        data = {
145
            'sentry.interfaces.User': {
146
                'id': '{2882CF9B-D9C2-4edb-9AAF-8ED5FCF366F7}'
147
            },
148
            'sentry.interfaces.Exception': {
149
                'values': [
150
                    {'stacktrace': {
151
                        'frames': [
152
                            {'function': 'crashedFunc()',
153
                             'abs_path': r'c:\work\breakpadtestapp\breakpadtestapp\breakpadtestapp.cpp',
154
                             'short_signature': 'crashedFunc',
155
                             'frame': 0,
156
                             'filename': 'BreakpadTestApp.exe',
157
                             'lineno': 34,
158
                             'signature': 'crashedFunc()'},
159
                            {'function': 'deeperFunc()',
160
                             'abs_path': r'c:\work\breakpadtestapp\breakpadtestapp\breakpadtestapp.cpp',
161
                             'short_signature': 'deeperFunc',
162
                             'frame': 1,
163
                             'filename': 'BreakpadTestApp.exe',
164
                             'lineno': 39,
165
                             'signature': 'deeperFunc()'},
166
                            {'function': 'deepFunc()',
167
                             'abs_path': r'c:\work\breakpadtestapp\breakpadtestapp\breakpadtestapp.cpp',
168
                             'short_signature': 'deepFunc',
169
                             'frame': 2,
170
                             'filename': 'BreakpadTestApp.exe',
171
                             'lineno': 44,
172
                             'signature': 'deepFunc()'},
173
                            {'function': 'anotherFunc()',
174
                             'abs_path': r'c:\work\breakpadtestapp\breakpadtestapp\breakpadtestapp.cpp',
175
                             'short_signature': 'anotherFunc',
176
                             'frame': 3,
177
                             'filename': 'BreakpadTestApp.exe',
178
                             'lineno': 49,
179
                             'signature': 'anotherFunc()'},
180
                            {'function': 'someFunc()',
181
                             'abs_path': r'c:\work\breakpadtestapp\breakpadtestapp\breakpadtestapp.cpp',
182
                             'short_signature': 'someFunc',
183
                             'frame': 4,
184
                             'filename': 'BreakpadTestApp.exe',
185
                             'lineno': 54,
186
                             'signature': 'someFunc()'}, {
187
                                'function': 'func()',
188
                                'abs_path': r'c:\work\breakpadtestapp\breakpadtestapp\breakpadtestapp.cpp',
189
                                'short_signature': 'func',
190
                                'frame': 5,
191
                                'filename': 'BreakpadTestApp.exe',
192
                                'lineno': 59,
193
                                'signature': 'func()'},
194
                            {'function': 'wmain',
195
                             'abs_path': r'c:\work\breakpadtestapp\breakpadtestapp\breakpadtestapp.cpp',
196
                             'short_signature': 'wmain',
197
                             'frame': 6,
198
                             'filename': 'BreakpadTestApp.exe',
199
                             'lineno': 84,
200
                             'signature': 'wmain'}, {
201
                                'function': '__tmainCRTStartup',
202
                                'abs_path': r'f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c',
203
                                'short_signature': '__tmainCRTStartup',
204
                                'frame': 7,
205
                                'filename': 'BreakpadTestApp.exe',
206
                                'lineno': 579,
207
                                'signature': '__tmainCRTStartup'},
208
                            {'frame': 8,
209
                             'module_offset': '0x13676',
210
                             'signature': 'kernel32.dll@0x13676',
211
                             'short_signature': 'kernel32.dll@0x13676',
212
                             'filename': 'kernel32.dll'},
213
                            {'frame': 9,
214
                             'module_offset': '0x39d41',
215
                             'signature': 'ntdll.dll@0x39d41',
216
                             'short_signature': 'ntdll.dll@0x39d41',
217
                             'filename': 'ntdll.dll'}],
218
                        'total_frames': 11, 'threads_index': 0},
219
                     'type': 'EXCEPTION_ACCESS_VIOLATION_WRITE',
220
                     'value': '0x0'}
221
                ]
222
            }
223
        }
224
225
        tags = {
226
            'cpu_arch': 'x86',
227
            'cpu_count': 4,
228
            'appid': '{D0AB2EBC-931B-4013-9FEB-C9C4C2225C8C}',
229
            'cpu_info': 'GenuineIntel family 6 model 42 stepping 7',
230
            'os': 'Windows NT',
231
            'os_ver': '6.1.7600'
232
        }
233
234
        mock_client.send.assert_called_once_with(
235
            'signature',
236
            extra=extra,
237
            sentry_data=data,
238
            tags=tags,
239
            crash_obj=crash
240
        )
241
242
243
class UtilsTest(test.TestCase):
244
    def test_parse_debug_meta_info(self):
245
        head = b'MODULE windows x86 C1C0FA629EAA4B4D9DD2ADE270A231CC1 BreakpadTestApp.pdb'
246
        self.assertDictEqual(parse_debug_meta_info(head),
247
                             dict(debug_id='C1C0FA629EAA4B4D9DD2ADE270A231CC1',
248
                                  debug_file='BreakpadTestApp.pdb'))
249
250
        head = b'MODULE mac x86_64 476350E1D4033CF180A2A7E388A7B6E40 Chromium Framework'
251
        self.assertDictEqual(parse_debug_meta_info(head),
252
                             dict(debug_id='476350E1D4033CF180A2A7E388A7B6E40',
253
                                  debug_file='Chromium Framework'))
254
255
256
class BaseGetChannelTest(object):
257
    factory = None
258
    os = None
259
260
    def get_number_version(self, version):
261
        if isinstance(version, Version):
262
            return version.version
263
        else:
264
            return version.short_version
265
266
    def test_version(self):
267
        version = self.factory()
268
        build_number = self.get_number_version(version)
269
        channel = get_channel(build_number, self.os)
270
        self.assertEqual(channel, version.channel.name)
271
272
    def test_ambiguity(self):
273
        version = self.factory.create_batch(2)[0]
274
        build_number = self.get_number_version(version)
275
        channel = get_channel(build_number, self.os)
276
        self.assertEqual(channel, 'undefined')
277
278
    def test_not_version(self):
279
        build_number = '0.0.0.1'
280
        channel = get_channel(build_number, self.os)
281
        self.assertEqual(channel, 'undefined')
282
283
    def test_invalid_build_number(self):
284
        version = self.factory()
285
        build_number = "%s-devel" % self.get_number_version(version)
286
        channel = get_channel(build_number, self.os)
287
        self.assertEqual(channel, 'undefined')
288
289
290
class OmahaGetChannelTest(test.TestCase, BaseGetChannelTest):
291
    factory = VersionFactory
292
    os = 'Windows NT'
293
294
295
class SparkleGetChannelTest(test.TestCase, BaseGetChannelTest):
296
    factory = SparkleVersionFactory
297
    os = 'Mac OS X'