Completed
Push — master ( 836a98...37dfd2 )
by
unknown
44s
created

BaseGetChannelTest.test_not_version()   A

Complexity

Conditions 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
c 1
b 0
f 0
dl 0
loc 4
rs 10
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_sentry,
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
        rezult, stderr = get_stacktrace(CRASH_DUMP_PATH)
62
63
        self.assertEqual(bytes(rezult.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.client')
115
    @test.override_settings(HOST_NAME='example.com',
116
                            CELERY_EAGER_PROPAGATES_EXCEPTIONS=False,)
117
    @is_private(False)
118
    def test_send_stacktrace_sentry(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_sentry(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.capture.assert_called_once_with(
235
            'raven.events.Message', message='signature',
236
            extra=extra,
237
            data=data,
238
            tags=tags,
239
        )
240
241
242
class UtilsTest(test.TestCase):
243
    def test_parse_debug_meta_info(self):
244
        head = b'MODULE windows x86 C1C0FA629EAA4B4D9DD2ADE270A231CC1 BreakpadTestApp.pdb'
245
        self.assertDictEqual(parse_debug_meta_info(head),
246
                             dict(debug_id='C1C0FA629EAA4B4D9DD2ADE270A231CC1',
247
                                  debug_file='BreakpadTestApp.pdb'))
248
249
        head = b'MODULE mac x86_64 476350E1D4033CF180A2A7E388A7B6E40 Chromium Framework'
250
        self.assertDictEqual(parse_debug_meta_info(head),
251
                             dict(debug_id='476350E1D4033CF180A2A7E388A7B6E40',
252
                                  debug_file='Chromium Framework'))
253
254
255
class BaseGetChannelTest(object):
256
    factory = None
257
    os = None
258
259
    def get_number_version(self, version):
260
        if isinstance(version, Version):
261
            return version.version
262
        else:
263
            return version.short_version
264
265
    def test_version(self):
266
        version = self.factory()
267
        build_number = self.get_number_version(version)
268
        channel = get_channel(build_number, self.os)
269
        self.assertEqual(channel, version.channel.name)
270
271
    def test_ambiguity(self):
272
        version = self.factory.create_batch(2)[0]
273
        build_number = self.get_number_version(version)
274
        channel = get_channel(build_number, self.os)
275
        self.assertEqual(channel, 'undefined')
276
277
    def test_not_version(self):
278
        build_number = '0.0.0.1'
279
        channel = get_channel(build_number, self.os)
280
        self.assertEqual(channel, 'undefined')
281
282
    def test_invalid_build_number(self):
283
        version = self.factory()
284
        build_number = "%s-devel" % self.get_number_version(version)
285
        channel = get_channel(build_number, self.os)
286
        self.assertEqual(channel, 'undefined')
287
288
289
class OmahaGetChannelTest(test.TestCase, BaseGetChannelTest):
290
    factory = VersionFactory
291
    os = 'Windows NT'
292
293
294
class SparkleGetChannelTest(test.TestCase, BaseGetChannelTest):
295
    factory = SparkleVersionFactory
296
    os = 'Mac OS X'