def test_merge_unreal_context_event(self): with open(get_unreal_crash_file(), 'rb') as f: event = {} unreal_crash = process_unreal_crash( f.read(), 'ebff51ef3c4878627823eebd9ff40eb4|2e7d369327054a448be6c8d3601213cb|C52DC39D-DAF3-5E36-A8D3-BF5F53A5D38F', 'Production', event) merge_unreal_context_event(unreal_crash.get_context(), event, self.project) assert event['environment'] == 'Production' assert event['tags'][ 'machine_id'] == 'C52DC39D-DAF3-5E36-A8D3-BF5F53A5D38F' assert event['tags'][ 'epic_account_id'] == '2e7d369327054a448be6c8d3601213cb' assert event['user']['id'] == 'ebff51ef3c4878627823eebd9ff40eb4' assert event[ 'message'] == 'Access violation - code c0000005 (first/second chance not available)' assert event['user']['username'] == 'bruno' assert event['contexts']['device']['memory_size'] == 6896832512 assert event['contexts']['os']['name'] == 'Windows 10' assert event['contexts']['gpu'][ 'name'] == 'Parallels Display Adapter (WDDM)' assert len(event['stacktrace']['frames']) == 20 assert 'ntdll' == event['stacktrace']['frames'][0]['package'] assert 'YetAnother' == event['stacktrace']['frames'][2]['package'] assert 'YetAnother' == event['stacktrace']['frames'][2]['package']
def test_merge_unreal_context_event(self): with open(get_unreal_crash_file(), 'rb') as f: event = {'event_id': MOCK_EVENT_ID} user_id = 'ebff51ef3c4878627823eebd9ff40eb4|2e7d369327054a448be6c8d3601213cb|C52DC39D-DAF3-5E36-A8D3-BF5F53A5D38F' unreal_crash = process_unreal_crash(f.read(), user_id, 'Production', event) merge_unreal_context_event(unreal_crash.get_context(), event, self.project) self.insta_snapshot(event)
def post(self, request, project, **kwargs): attachments_enabled = features.has('organizations:event-attachments', project.organization, actor=request.user) event_id = uuid.uuid4().hex data = { 'event_id': event_id, 'environment': request.GET.get('AppEnvironment'), } user_id = request.GET.get('UserID') if user_id: data['user'] = {'id': user_id} attachments = [] try: unreal = process_unreal_crash(request.body) process_state = unreal.process_minidump() except (ProcessMinidumpError, Unreal4Error) as e: minidumps_logger.exception(e) raise APIError(e.message.split('\n', 1)[0]) if process_state: merge_process_state_event(data, process_state) else: raise APIError("missing minidump in unreal crash report") try: unreal_context = unreal.get_context() if unreal_context is not None: merge_unreal_context_event(unreal_context, data, project) except Unreal4Error as e: # we'll continue without the context data minidumps_logger.exception(e) for file in unreal.files(): # Always store the minidump in attachments so we can access it during # processing, regardless of the event-attachments feature. This will # allow us to stack walk again with CFI once symbols are loaded. if file.type == "minidump" or attachments_enabled: attachments.append( CachedAttachment( name=file.name, data=file.open_stream().read(), type=unreal_attachment_type(file), )) response_or_event_id = self.process(request, attachments=attachments, data=data, project=project, **kwargs) # The return here is only useful for consistency # because the UE4 crash reporter doesn't care about it. if isinstance(response_or_event_id, HttpResponse): return response_or_event_id return HttpResponse(six.text_type(uuid.UUID(response_or_event_id)), content_type='text/plain')
def test_merge_unreal_context_event(self): with open(get_unreal_crash_file(), "rb") as f: event = {"event_id": MOCK_EVENT_ID, "environment": "Production"} user_id = "ebff51ef3c4878627823eebd9ff40eb4|2e7d369327054a448be6c8d3601213cb|C52DC39D-DAF3-5E36-A8D3-BF5F53A5D38F" merge_unreal_user(event, user_id) unreal_crash = Unreal4Crash.from_bytes(f.read()) merge_unreal_context_event(unreal_crash.get_context(), event, self.project) self.insta_snapshot(event)
def test_merge_unreal_context_event(self): with open(get_unreal_crash_file(), 'rb') as f: event = {'event_id': MOCK_EVENT_ID} user_id = 'ebff51ef3c4878627823eebd9ff40eb4|2e7d369327054a448be6c8d3601213cb|C52DC39D-DAF3-5E36-A8D3-BF5F53A5D38F' unreal_crash = process_unreal_crash(f.read(), user_id, 'Production', event) merge_unreal_context_event(unreal_crash.get_context(), event, self.project) self.insta_snapshot(event)
def test_merge_unreal_context_event_pcallstack_no_threads(self): event = {} unreal_context = { 'runtime_properties': { 'portable_call_stack': '0x00000000fc440000 + ffffffff PackageA 0x000000003fb70000 + e23831 PackageA 0x000000003fb70000 + 495d7b PackageA 0x000000003fb70000 + 1cbb89', 'threads': [], } } merge_unreal_context_event(unreal_context, event, self.project) assert event.get('threads') is None
def test_merge_unreal_context_event_without_user(self): expected_message = "user comments" context = {"runtime_properties": {"user_description": expected_message}} event = {"event_id": MOCK_EVENT_ID} merge_unreal_context_event(context, event, self.project) user_report = UserReport.objects.get(event_id=MOCK_EVENT_ID, project=self.project) assert user_report.comments == expected_message assert user_report.name == "unknown" assert event.get("user") is None
def test_merge_unreal_context_event_pcallstack_no_threads(self): event = {} unreal_context = { 'runtime_properties': { 'portable_call_stack': '0x00000000fc440000 + ffffffff PackageA 0x000000003fb70000 + e23831 PackageA 0x000000003fb70000 + 495d7b PackageA 0x000000003fb70000 + 1cbb89', 'threads': [], } } merge_unreal_context_event(unreal_context, event, self.project) assert event.get('threads') is None
def test_merge_unreal_context_event_without_user_description(self): expected_username = "******" context = {"runtime_properties": {"username": expected_username}} event = {"event_id": MOCK_EVENT_ID} merge_unreal_context_event(context, event, self.project) try: user_report = UserReport.objects.get(event_id=MOCK_EVENT_ID, project=self.project) except UserReport.DoesNotExist: user_report = None assert user_report is None assert event["user"]["username"] == expected_username
def test_merge_unreal_context_event(self): with open(get_unreal_crash_file(), 'rb') as f: unreal_crash = process_unreal_crash(f.read()) event = {} merge_unreal_context_event(unreal_crash.get_context(), event, self.project) assert event['message'] == 'Access violation - code c0000005 (first/second chance not available)' assert event['user']['username'] == 'bruno' assert event['contexts']['device']['memory_size'] == 6896832512 assert event['contexts']['os']['name'] == 'Windows 10' assert event['contexts']['gpu']['name'] == 'Parallels Display Adapter (WDDM)' assert len(event['stacktrace']['frames']) == 20 assert 'ntdll' == event['stacktrace']['frames'][0]['package'] assert 'YetAnother' == event['stacktrace']['frames'][2]['package'] assert 'YetAnother' == event['stacktrace']['frames'][2]['package']
def test_merge_unreal_context_event_with_user(self): expected_message = "user comments" expected_username = "******" context = { "runtime_properties": { "username": expected_username, "user_description": expected_message, } } event = {"event_id": MOCK_EVENT_ID} merge_unreal_context_event(context, event, self.project) user_report = UserReport.objects.get(event_id=event["event_id"], project=self.project) assert user_report.comments == expected_message assert user_report.name == expected_username assert event["user"]["username"] == expected_username
def test_merge_unreal_context_event_without_user(self): expected_message = 'user comments' context = { 'runtime_properties': { 'user_description': expected_message } } event = {'event_id': MOCK_EVENT_ID} merge_unreal_context_event(context, event, self.project) user_report = UserReport.objects.get( event_id=MOCK_EVENT_ID, project=self.project, ) assert user_report.comments == expected_message assert user_report.name == 'unknown' assert event.get('user') is None
def test_merge_unreal_context_event_without_user(self): expected_message = 'user comments' context = { 'runtime_properties': { 'user_description': expected_message } } event = {'event_id': MOCK_EVENT_ID} merge_unreal_context_event(context, event, self.project) user_report = UserReport.objects.get( event_id=MOCK_EVENT_ID, project=self.project, ) assert user_report.comments == expected_message assert user_report.name == 'unknown' assert event.get('user') is None
def test_merge_unreal_context_event(self): with open(get_unreal_crash_file(), 'rb') as f: unreal_crash = process_unreal_crash(f.read()) event = {} merge_unreal_context_event(unreal_crash.get_context(), event, self.project) assert event[ 'message'] == 'Access violation - code c0000005 (first/second chance not available)' assert event['user']['username'] == 'bruno' assert event['contexts']['device']['memory_size'] == 6896832512 assert event['contexts']['os']['name'] == 'Windows 10' assert event['contexts']['gpu'][ 'name'] == 'Parallels Display Adapter (WDDM)' assert len(event['stacktrace']['frames']) == 20 assert 'ntdll' == event['stacktrace']['frames'][0]['package'] assert 'YetAnother' == event['stacktrace']['frames'][2]['package'] assert 'YetAnother' == event['stacktrace']['frames'][2]['package']
def test_merge_unreal_context_event_with_user(self): expected_message = 'user comments' expected_username = '******' context = { 'runtime_properties': { 'username': expected_username, 'user_description': expected_message } } event = {'event_id': MOCK_EVENT_ID} merge_unreal_context_event(context, event, self.project) user_report = UserReport.objects.get( event_id=event['event_id'], project=self.project, ) assert user_report.comments == expected_message assert user_report.name == expected_username assert event['user']['username'] == expected_username
def test_merge_unreal_context_event_with_user(self): expected_message = 'user comments' expected_username = '******' context = { 'runtime_properties': { 'username': expected_username, 'user_description': expected_message } } event = {'event_id': MOCK_EVENT_ID} merge_unreal_context_event(context, event, self.project) user_report = UserReport.objects.get( event_id=event['event_id'], project=self.project, ) assert user_report.comments == expected_message assert user_report.name == expected_username assert event['user']['username'] == expected_username
def test_merge_unreal_context_event_without_user_description(self): expected_username = '******' context = { 'runtime_properties': { 'username': expected_username, } } event = {'event_id': MOCK_EVENT_ID} merge_unreal_context_event(context, event, self.project) try: user_report = UserReport.objects.get( event_id=MOCK_EVENT_ID, project=self.project, ) except UserReport.DoesNotExist: user_report = None assert user_report is None assert event['user']['username'] == expected_username
def test_merge_unreal_context_event_without_user_description(self): expected_username = '******' context = { 'runtime_properties': { 'username': expected_username, } } event = {'event_id': MOCK_EVENT_ID} merge_unreal_context_event(context, event, self.project) try: user_report = UserReport.objects.get( event_id=MOCK_EVENT_ID, project=self.project, ) except UserReport.DoesNotExist: user_report = None assert user_report is None assert event['user']['username'] == expected_username
def post(self, request, project, project_config, **kwargs): attachments_enabled = features.has( "organizations:event-attachments", project.organization, actor=request.user ) attachments = [] event = {"event_id": uuid.uuid4().hex, "environment": request.GET.get("AppEnvironment")} user_id = request.GET.get("UserID") if user_id: merge_unreal_user(event, user_id) try: unreal = Unreal4Crash.from_bytes(request.body) except (ProcessMinidumpError, Unreal4Error) as e: minidumps_logger.exception(e) track_outcome( project_config.organization_id, project_config.project_id, None, Outcome.INVALID, "process_unreal", ) raise APIError(e.message.split("\n", 1)[0]) try: unreal_context = unreal.get_context() except Unreal4Error as e: # we'll continue without the context data unreal_context = None minidumps_logger.exception(e) else: if unreal_context is not None: merge_unreal_context_event(unreal_context, event, project) try: unreal_logs = unreal.get_logs() except Unreal4Error as e: # we'll continue without the breadcrumbs minidumps_logger.exception(e) else: if unreal_logs is not None: merge_unreal_logs_event(unreal_logs, event) is_minidump = False is_applecrashreport = False for file in unreal.files(): # Known attachment: msgpack event if file.name == "__sentry-event": merge_attached_event(file.open_stream(), event) continue if file.name in ("__sentry-breadcrumb1", "__sentry-breadcrumb2"): merge_attached_breadcrumbs(file.open_stream(), event) continue if file.type == "minidump": is_minidump = True if file.type == "applecrashreport": is_applecrashreport = True # Always store attachments that can be processed, regardless of the # event-attachments feature. if file.type in self.required_attachments or attachments_enabled: attachments.append( CachedAttachment( name=file.name, data=file.open_stream().read(), type=unreal_attachment_type(file), ) ) if is_minidump: write_minidump_placeholder(event) elif is_applecrashreport: write_applecrashreport_placeholder(event) event_id = self.process( request, attachments=attachments, data=event, project=project, project_config=project_config, **kwargs ) # The return here is only useful for consistency # because the UE4 crash reporter doesn't care about it. return HttpResponse(six.text_type(uuid.UUID(event_id)), content_type="text/plain")
def post(self, request, project, relay_config, **kwargs): attachments_enabled = features.has('organizations:event-attachments', project.organization, actor=request.user) is_apple_crash_report = False attachments = [] event = {'event_id': uuid.uuid4().hex} try: unreal = process_unreal_crash(request.body, request.GET.get('UserID'), request.GET.get('AppEnvironment'), event) apple_crash_report = unreal.get_apple_crash_report() if apple_crash_report: merge_apple_crash_report(apple_crash_report, event) is_apple_crash_report = True except (ProcessMinidumpError, Unreal4Error) as e: minidumps_logger.exception(e) track_outcome(relay_config.organization_id, relay_config.project_id, None, Outcome.INVALID, "process_minidump_unreal") raise APIError(e.message.split('\n', 1)[0]) try: unreal_context = unreal.get_context() if unreal_context is not None: merge_unreal_context_event(unreal_context, event, project) except Unreal4Error as e: # we'll continue without the context data minidumps_logger.exception(e) try: unreal_logs = unreal.get_logs() if unreal_logs is not None: merge_unreal_logs_event(unreal_logs, event) except Unreal4Error as e: # we'll continue without the breadcrumbs minidumps_logger.exception(e) is_minidump = False for file in unreal.files(): # Known attachment: msgpack event if file.name == "__sentry-event": merge_attached_event(file.open_stream(), event) continue if file.name in ("__sentry-breadcrumb1", "__sentry-breadcrumb2"): merge_attached_breadcrumbs(file.open_stream(), event) continue if file.type == "minidump" and not is_apple_crash_report: is_minidump = True # Always store the minidump in attachments so we can access it during # processing, regardless of the event-attachments feature. This will # allow us to stack walk again with CFI once symbols are loaded. if file.type == "minidump" or attachments_enabled: attachments.append( CachedAttachment( name=file.name, data=file.open_stream().read(), type=unreal_attachment_type(file), )) if is_minidump: write_minidump_placeholder(event) event_id = self.process(request, attachments=attachments, data=event, project=project, relay_config=relay_config, **kwargs) # The return here is only useful for consistency # because the UE4 crash reporter doesn't care about it. return HttpResponse(six.text_type(uuid.UUID(event_id)), content_type='text/plain')
def post(self, request, project, **kwargs): attachments_enabled = features.has('organizations:event-attachments', project.organization, actor=request.user) event_id = uuid.uuid4().hex data = { 'event_id': event_id, 'environment': request.GET.get('AppEnvironment'), } user_id = request.GET.get('UserID') if user_id: data['user'] = { 'id': user_id } attachments = [] try: unreal = process_unreal_crash(request.body) process_state = unreal.process_minidump() except (ProcessMinidumpError, Unreal4Error) as e: minidumps_logger.exception(e) raise APIError(e.message.split('\n', 1)[0]) if process_state: merge_process_state_event(data, process_state) else: raise APIError("missing minidump in unreal crash report") try: unreal_context = unreal.get_context() if unreal_context is not None: merge_unreal_context_event(unreal_context, data, project) except Unreal4Error as e: # we'll continue without the context data minidumps_logger.exception(e) try: unreal_logs = unreal.get_logs() if unreal_logs is not None: merge_unreal_logs_event(unreal_logs, data) except Unreal4Error as e: # we'll continue without the breadcrumbs minidumps_logger.exception(e) for file in unreal.files(): # Always store the minidump in attachments so we can access it during # processing, regardless of the event-attachments feature. This will # allow us to stack walk again with CFI once symbols are loaded. if file.type == "minidump" or attachments_enabled: attachments.append(CachedAttachment( name=file.name, data=file.open_stream().read(), type=unreal_attachment_type(file), )) response_or_event_id = self.process( request, attachments=attachments, data=data, project=project, **kwargs) # The return here is only useful for consistency # because the UE4 crash reporter doesn't care about it. if isinstance(response_or_event_id, HttpResponse): return response_or_event_id return HttpResponse( six.text_type(uuid.UUID(response_or_event_id)), content_type='text/plain' )
def post(self, request, project, **kwargs): attachments_enabled = features.has('organizations:event-attachments', project.organization, actor=request.user) attachments = [] event = {'event_id': uuid.uuid4().hex} try: unreal = process_unreal_crash(request.body, request.GET.get( 'UserID'), request.GET.get('AppEnvironment'), event) process_state = unreal.process_minidump() if process_state: merge_process_state_event(event, process_state) else: apple_crash_report = unreal.get_apple_crash_report() if apple_crash_report: merge_apple_crash_report(apple_crash_report, event) else: track_outcome(project.organization_id, project.id, None, Outcome.INVALID, "missing_minidump_unreal") raise APIError("missing minidump in unreal crash report") except (ProcessMinidumpError, Unreal4Error) as e: minidumps_logger.exception(e) track_outcome( project.organization_id, project.id, None, Outcome.INVALID, "process_minidump_unreal") raise APIError(e.message.split('\n', 1)[0]) try: unreal_context = unreal.get_context() if unreal_context is not None: merge_unreal_context_event(unreal_context, event, project) except Unreal4Error as e: # we'll continue without the context data minidumps_logger.exception(e) try: unreal_logs = unreal.get_logs() if unreal_logs is not None: merge_unreal_logs_event(unreal_logs, event) except Unreal4Error as e: # we'll continue without the breadcrumbs minidumps_logger.exception(e) for file in unreal.files(): # Known attachment: msgpack event if file.name == "__sentry-event": merge_attached_event(file.open_stream(), event) continue if file.name in ("__sentry-breadcrumb1", "__sentry-breadcrumb2"): merge_attached_breadcrumbs(file.open_stream(), event) continue # Always store the minidump in attachments so we can access it during # processing, regardless of the event-attachments feature. This will # allow us to stack walk again with CFI once symbols are loaded. if file.type == "minidump" or attachments_enabled: attachments.append(CachedAttachment( name=file.name, data=file.open_stream().read(), type=unreal_attachment_type(file), )) event_id = self.process( request, attachments=attachments, data=event, project=project, **kwargs) # The return here is only useful for consistency # because the UE4 crash reporter doesn't care about it. return HttpResponse( six.text_type(uuid.UUID(event_id)), content_type='text/plain' )