Loading components/lib/crash/src/main/java/mozilla/components/lib/crash/CrashReporter.kt +9 −6 Original line number Diff line number Diff line Loading @@ -153,15 +153,17 @@ class CrashReporter( logger.info("Received crash: $crash") if (shouldSendIntent(crash)) { // This crash was not fatal and the app has registered a pending intent launchCrashIntent(context, crash) } if (telemetryServices.isNotEmpty()) { sendCrashTelemetry(context, crash) } // If crash is native code and non fatal then the view will handle the user prompt if (shouldSendIntent(crash)) { // App has registered a pending intent sendNonFatalCrashIntent(context, crash) return } if (services.isNotEmpty()) { if (CrashPrompt.shouldPromptForCrash(shouldPrompt, crash)) { showPromptOrNotification(context, crash) Loading @@ -171,7 +173,8 @@ class CrashReporter( } } private fun launchCrashIntent(context: Context, crash: Crash) { @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) internal fun sendNonFatalCrashIntent(context: Context, crash: Crash) { logger.info("Invoking non-fatal PendingIntent") val additionalIntent = Intent() Loading components/lib/crash/src/test/java/mozilla/components/lib/crash/CrashReporterTest.kt +59 −2 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mockito.never import org.mockito.Mockito.spy import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.robolectric.Robolectric import org.robolectric.Shadows.shadowOf Loading Loading @@ -132,7 +133,7 @@ class CrashReporterTest { } @Test fun `CrashReporter will show prompt for native crash and with setup Prompt-ONLY_NATIVE_CRASH`() { fun `CrashReporter will show prompt for fatal native crash and with setup Prompt-ONLY_NATIVE_CRASH`() { val service: CrashReporterService = mock() val telemetryService: CrashReporterService = mock() Loading @@ -143,7 +144,12 @@ class CrashReporterTest { scope = scope ).install(testContext)) val crash: Crash.NativeCodeCrash = mock() val crash = Crash.NativeCodeCrash( "dump.path", true, "extras.path", isFatal = true, breadcrumbs = arrayListOf()) reporter.onCrash(testContext, crash) Loading Loading @@ -455,6 +461,57 @@ class CrashReporterTest { assertEquals(false, receivedCrash.isFatal) } @Test fun `CrashReporter sends telemetry but don't send native crash if the crash is non-fatal and nonFatalPendingIntent is not null`() { val service: CrashReporterService = mock() val telemetryService: CrashReporterService = mock() val reporter = spy(CrashReporter( services = listOf(service), telemetryServices = listOf(telemetryService), shouldPrompt = CrashReporter.Prompt.NEVER, nonFatalCrashIntent = mock(), scope = scope ).install(testContext)) val nativeCrash = Crash.NativeCodeCrash( "dump.path", true, "extras.path", isFatal = false, breadcrumbs = arrayListOf()) reporter.onCrash(testContext, nativeCrash) verify(reporter, never()).sendCrashReport(testContext, nativeCrash) verify(reporter, times(1)).sendCrashTelemetry(testContext, nativeCrash) verify(reporter, never()).showPrompt(any(), eq(nativeCrash)) } @Test fun `CrashReporter sends telemetry and crash if the crash is non-fatal and nonFatalPendingIntent is null`() { val service: CrashReporterService = mock() val telemetryService: CrashReporterService = mock() val reporter = spy(CrashReporter( services = listOf(service), telemetryServices = listOf(telemetryService), shouldPrompt = CrashReporter.Prompt.NEVER, scope = scope ).install(testContext)) val nativeCrash = Crash.NativeCodeCrash( "dump.path", true, "extras.path", isFatal = false, breadcrumbs = arrayListOf()) reporter.onCrash(testContext, nativeCrash) verify(reporter, times(1)).sendCrashReport(testContext, nativeCrash) verify(reporter, times(1)).sendCrashTelemetry(testContext, nativeCrash) verify(reporter, never()).showPrompt(any(), eq(nativeCrash)) } @Test fun `CrashReporter instance writes are visible across threads`() { val instanceField = CrashReporter::class.java.getDeclaredField("instance") Loading components/lib/crash/src/test/java/mozilla/components/lib/crash/handler/CrashHandlerServiceTest.kt +7 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mockito.doNothing import org.mockito.Mockito.never import org.mockito.Mockito.spy import org.mockito.Mockito.verify Loading @@ -41,6 +42,7 @@ class CrashHandlerServiceTest { reporter = spy(CrashReporter( shouldPrompt = CrashReporter.Prompt.NEVER, services = listOf(mock()), nonFatalCrashIntent = mock(), scope = scope )).install(testContext) Loading Loading @@ -72,7 +74,9 @@ class CrashHandlerServiceTest { intent?.putExtra("fatal", true) service?.onStartCommand(intent, 0, 0) verify(reporter)?.onCrash(any(), any()) verify(reporter)?.sendCrashReport(any(), any()) verify(reporter, never())?.sendNonFatalCrashIntent(any(), any()) } @Test Loading @@ -81,6 +85,8 @@ class CrashHandlerServiceTest { intent?.putExtra("fatal", false) service?.onStartCommand(intent, 0, 0) verify(reporter)?.sendCrashReport(any(), any()) verify(reporter)?.onCrash(any(), any()) verify(reporter)?.sendNonFatalCrashIntent(any(), any()) verify(reporter, never())?.sendCrashReport(any(), any()) } } Loading
components/lib/crash/src/main/java/mozilla/components/lib/crash/CrashReporter.kt +9 −6 Original line number Diff line number Diff line Loading @@ -153,15 +153,17 @@ class CrashReporter( logger.info("Received crash: $crash") if (shouldSendIntent(crash)) { // This crash was not fatal and the app has registered a pending intent launchCrashIntent(context, crash) } if (telemetryServices.isNotEmpty()) { sendCrashTelemetry(context, crash) } // If crash is native code and non fatal then the view will handle the user prompt if (shouldSendIntent(crash)) { // App has registered a pending intent sendNonFatalCrashIntent(context, crash) return } if (services.isNotEmpty()) { if (CrashPrompt.shouldPromptForCrash(shouldPrompt, crash)) { showPromptOrNotification(context, crash) Loading @@ -171,7 +173,8 @@ class CrashReporter( } } private fun launchCrashIntent(context: Context, crash: Crash) { @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) internal fun sendNonFatalCrashIntent(context: Context, crash: Crash) { logger.info("Invoking non-fatal PendingIntent") val additionalIntent = Intent() Loading
components/lib/crash/src/test/java/mozilla/components/lib/crash/CrashReporterTest.kt +59 −2 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mockito.never import org.mockito.Mockito.spy import org.mockito.Mockito.times import org.mockito.Mockito.verify import org.robolectric.Robolectric import org.robolectric.Shadows.shadowOf Loading Loading @@ -132,7 +133,7 @@ class CrashReporterTest { } @Test fun `CrashReporter will show prompt for native crash and with setup Prompt-ONLY_NATIVE_CRASH`() { fun `CrashReporter will show prompt for fatal native crash and with setup Prompt-ONLY_NATIVE_CRASH`() { val service: CrashReporterService = mock() val telemetryService: CrashReporterService = mock() Loading @@ -143,7 +144,12 @@ class CrashReporterTest { scope = scope ).install(testContext)) val crash: Crash.NativeCodeCrash = mock() val crash = Crash.NativeCodeCrash( "dump.path", true, "extras.path", isFatal = true, breadcrumbs = arrayListOf()) reporter.onCrash(testContext, crash) Loading Loading @@ -455,6 +461,57 @@ class CrashReporterTest { assertEquals(false, receivedCrash.isFatal) } @Test fun `CrashReporter sends telemetry but don't send native crash if the crash is non-fatal and nonFatalPendingIntent is not null`() { val service: CrashReporterService = mock() val telemetryService: CrashReporterService = mock() val reporter = spy(CrashReporter( services = listOf(service), telemetryServices = listOf(telemetryService), shouldPrompt = CrashReporter.Prompt.NEVER, nonFatalCrashIntent = mock(), scope = scope ).install(testContext)) val nativeCrash = Crash.NativeCodeCrash( "dump.path", true, "extras.path", isFatal = false, breadcrumbs = arrayListOf()) reporter.onCrash(testContext, nativeCrash) verify(reporter, never()).sendCrashReport(testContext, nativeCrash) verify(reporter, times(1)).sendCrashTelemetry(testContext, nativeCrash) verify(reporter, never()).showPrompt(any(), eq(nativeCrash)) } @Test fun `CrashReporter sends telemetry and crash if the crash is non-fatal and nonFatalPendingIntent is null`() { val service: CrashReporterService = mock() val telemetryService: CrashReporterService = mock() val reporter = spy(CrashReporter( services = listOf(service), telemetryServices = listOf(telemetryService), shouldPrompt = CrashReporter.Prompt.NEVER, scope = scope ).install(testContext)) val nativeCrash = Crash.NativeCodeCrash( "dump.path", true, "extras.path", isFatal = false, breadcrumbs = arrayListOf()) reporter.onCrash(testContext, nativeCrash) verify(reporter, times(1)).sendCrashReport(testContext, nativeCrash) verify(reporter, times(1)).sendCrashTelemetry(testContext, nativeCrash) verify(reporter, never()).showPrompt(any(), eq(nativeCrash)) } @Test fun `CrashReporter instance writes are visible across threads`() { val instanceField = CrashReporter::class.java.getDeclaredField("instance") Loading
components/lib/crash/src/test/java/mozilla/components/lib/crash/handler/CrashHandlerServiceTest.kt +7 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import org.junit.Rule import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mockito.doNothing import org.mockito.Mockito.never import org.mockito.Mockito.spy import org.mockito.Mockito.verify Loading @@ -41,6 +42,7 @@ class CrashHandlerServiceTest { reporter = spy(CrashReporter( shouldPrompt = CrashReporter.Prompt.NEVER, services = listOf(mock()), nonFatalCrashIntent = mock(), scope = scope )).install(testContext) Loading Loading @@ -72,7 +74,9 @@ class CrashHandlerServiceTest { intent?.putExtra("fatal", true) service?.onStartCommand(intent, 0, 0) verify(reporter)?.onCrash(any(), any()) verify(reporter)?.sendCrashReport(any(), any()) verify(reporter, never())?.sendNonFatalCrashIntent(any(), any()) } @Test Loading @@ -81,6 +85,8 @@ class CrashHandlerServiceTest { intent?.putExtra("fatal", false) service?.onStartCommand(intent, 0, 0) verify(reporter)?.sendCrashReport(any(), any()) verify(reporter)?.onCrash(any(), any()) verify(reporter)?.sendNonFatalCrashIntent(any(), any()) verify(reporter, never())?.sendCrashReport(any(), any()) } }