From 9748aba878665573b52f3bf5034ee6807d4e0cd9 Mon Sep 17 00:00:00 2001 From: Pritesh Nandgaonkar Date: Thu, 20 Dec 2018 05:17:10 -0800 Subject: [PATCH] show crash notifications only for a particular device Summary: Before this diff we used to show crash notifications for all kind of crashes. This diff adds the check, which makes sure that only the crashes of a selected device is shown Also added tests and updated few tests Reviewed By: danielbuechele Differential Revision: D13518019 fbshipit-source-id: 6d640d078a43480274242a5d86f2d135d875d630 --- src/dispatcher/iOSDevice.js | 40 +++++++++++- .../testCrashReporterPlugin.electron.js | 62 ++++++++++++++++++- 2 files changed, 97 insertions(+), 5 deletions(-) diff --git a/src/dispatcher/iOSDevice.js b/src/dispatcher/iOSDevice.js index 471adc4ea..5a91da272 100644 --- a/src/dispatcher/iOSDevice.js +++ b/src/dispatcher/iOSDevice.js @@ -65,10 +65,10 @@ window.addEventListener('beforeunload', () => { }); export function parseCrashLog(content: string): Crash { - const regex = /Exception Type: *[aA-zZ0-9]*/; + const regex = /Exception Type: *[\w]*/; const arr = regex.exec(content); const exceptionString = arr ? arr[0] : ''; - const exceptionRegex = /[aA-zZ0-9]*$/; + const exceptionRegex = /[\w]*$/; const tmp = exceptionRegex.exec(exceptionString); const exception = tmp && tmp[0].length ? tmp[0] : 'Cannot figure out the cause'; @@ -79,6 +79,21 @@ export function parseCrashLog(content: string): Crash { }; return crash; } +export function parsePath(content: string): ?string { + const regex = /Path: *[\w\-\/\.\t\ \_\%]*\n/; + const arr = regex.exec(content); + if (!arr || arr.length <= 0) { + return null; + } + const pathString = arr[0]; + const pathRegex = /[\w\-\/\.\t\ \_\%]*\n/; + const tmp = pathRegex.exec(pathString); + if (!tmp || tmp.length == 0) { + return null; + } + const path = tmp[0]; + return path.trim(); +} export function getPersistedState( pluginKey: string, @@ -119,7 +134,28 @@ export function getNewPersisitedStateFromCrashLog( return newPluginState; } +export function shouldShowCrashNotification( + baseDevice: ?BaseDevice, + content: string, +): boolean { + const appPath = parsePath(content); + const serial: string = baseDevice?.serial || 'unknown'; + if (!appPath || !appPath.includes(serial)) { + // Do not show notifications for the app which are not the selected one + return false; + } + return true; +} + function parseCrashLogAndUpdateState(store: Store, content: string) { + if ( + !shouldShowCrashNotification( + store.getState().connections.selectedDevice, + content, + ) + ) { + return; + } const pluginID = 'CrashReporter'; const pluginKey = getPluginKey( store.getState().connections.selectedDevice, diff --git a/src/plugins/crash_reporter/__tests__/testCrashReporterPlugin.electron.js b/src/plugins/crash_reporter/__tests__/testCrashReporterPlugin.electron.js index 5c0a37195..70e4cac65 100644 --- a/src/plugins/crash_reporter/__tests__/testCrashReporterPlugin.electron.js +++ b/src/plugins/crash_reporter/__tests__/testCrashReporterPlugin.electron.js @@ -10,6 +10,8 @@ import { getPluginKey, getPersistedState, getNewPersisitedStateFromCrashLog, + parsePath, + shouldShowCrashNotification, } from '../../../dispatcher/iOSDevice.js'; import BaseDevice from '../../../devices/BaseDevice'; import CrashReporterPlugin from '../../crash_reporter'; @@ -54,7 +56,8 @@ afterAll(() => { }); test('test the parsing of the reason for crash when log matches the predefined regex', () => { - const log = 'Blaa Blaaa \n Blaa Blaaa \n Exception Type: SIGSEGV'; + const log = + 'Blaa Blaaa \n Blaa Blaaa \n Exception Type: SIGSEGV \n Blaa Blaa \n Blaa Blaa'; const crash = parseCrashLog(log); expect(crash.callstack).toEqual(log); expect(crash.reason).toEqual('SIGSEGV'); @@ -69,7 +72,8 @@ test('test the parsing of the crash log when log does not match the predefined r }); test('test the parsing of the reason for crash when log does not match the predefined regex contains unicode character', () => { - const log = 'Blaa Blaaa \n Blaa Blaaa \n Exception Type: 🍕🐬'; + const log = + 'Blaa Blaaa \n Blaa Blaaa \n Exception Type: 🍕🐬 \n Blaa Blaa \n Blaa Blaa'; const crash = parseCrashLog(log); expect(crash.callstack).toEqual(log); expect(crash.reason).toEqual('Cannot figure out the cause'); @@ -134,7 +138,8 @@ test('test getNewPersisitedStateFromCrashLog for non-empty defaultPersistedState CrashReporterPlugin, pluginStates, ); - const content = 'Blaa Blaaa \n Blaa Blaaa \n Exception Type: SIGSEGV'; + const content = + 'Blaa Blaaa \n Blaa Blaaa \n Exception Type: SIGSEGV \n Blaa Blaa \n Blaa Blaa'; expect(perisistedState).toEqual({crashes: [pluginStateCrash]}); const newPersistedState = getNewPersisitedStateFromCrashLog( perisistedState, @@ -198,3 +203,54 @@ test('test getNewPersisitedStateFromCrashLog for non-empty defaultPersistedState ], }); }); +test('test parsing of path when inputs are correct', () => { + const content = + 'Blaa Blaaa \n Blaa Blaaa \n Path: path/to/simulator/TH1S-15DEV1CE-1D/AppName.app/AppName \n Blaa Blaa \n Blaa Blaa'; + const id = parsePath(content); + expect(id).toEqual('path/to/simulator/TH1S-15DEV1CE-1D/AppName.app/AppName'); +}); +test('test parsing of path when path has special characters in it', () => { + let content = + 'Blaa Blaaa \n Blaa Blaaa \n Path: path/to/simulator/TH1S-15DEV1CE-1D/App Name.app/App Name \n Blaa Blaa \n Blaa Blaa'; + let id = parsePath(content); + expect(id).toEqual( + 'path/to/simulator/TH1S-15DEV1CE-1D/App Name.app/App Name', + ); + content = + 'Blaa Blaaa \n Blaa Blaaa \n Path: path/to/simulator/TH1S-15DEV1CE-1D/App_Name.app/App_Name \n Blaa Blaa \n Blaa Blaa'; + id = parsePath(content); + expect(id).toEqual( + 'path/to/simulator/TH1S-15DEV1CE-1D/App_Name.app/App_Name', + ); + content = + 'Blaa Blaaa \n Blaa Blaaa \n Path: path/to/simulator/TH1S-15DEV1CE-1D/App%20Name.app/App%20Name \n Blaa Blaa \n Blaa Blaa'; + id = parsePath(content); + expect(id).toEqual( + 'path/to/simulator/TH1S-15DEV1CE-1D/App%20Name.app/App%20Name', + ); +}); +test('test parsing of path when a regex is not present', () => { + const content = 'Blaa Blaaa \n Blaa Blaaa \n Blaa Blaa \n Blaa Blaa'; + const id = parsePath(content); + expect(id).toEqual(null); +}); +test('test shouldShowCrashNotification function for all correct inputs', () => { + const device = new BaseDevice('TH1S-15DEV1CE-1D', 'emulator', 'test device'); + let content = + 'Blaa Blaaa \n Blaa Blaaa \n Path: path/to/simulator/TH1S-15DEV1CE-1D/App Name.app/App Name \n Blaa Blaa \n Blaa Blaa'; + const shouldShowNotification = shouldShowCrashNotification(device, content); + expect(shouldShowNotification).toEqual(true); +}); +test('test shouldShowCrashNotification function for all correct inputs but incorrect id', () => { + const device = new BaseDevice('TH1S-15DEV1CE-1D', 'emulator', 'test device'); + let content = + 'Blaa Blaaa \n Blaa Blaaa \n Path: path/to/simulator/TH1S-1598DEV1CE-2D/App Name.app/App Name \n Blaa Blaa \n Blaa Blaa'; + const shouldShowNotification = shouldShowCrashNotification(device, content); + expect(shouldShowNotification).toEqual(false); +}); +test('test shouldShowCrashNotification function for undefined device', () => { + let content = + 'Blaa Blaaa \n Blaa Blaaa \n Path: path/to/simulator/TH1S-1598DEV1CE-2D/App Name.app/App Name \n Blaa Blaa \n Blaa Blaa'; + const shouldShowNotification = shouldShowCrashNotification(null, content); + expect(shouldShowNotification).toEqual(false); +});