Commit 28b335f9 authored by MozLando's avatar MozLando
Browse files

Merge #8275



8275: Closes #8273: Set timestamp of crash reports to when crash occurred r=pocmo a=rocketsroger
Co-authored-by: default avatarRoger Yang <royang@mozilla.com>
parents 9c5ceec0 008ef2fa
......@@ -19,6 +19,9 @@ private const val INTENT_EXCEPTION = "exception"
// Breadcrumbs intent extras
private const val INTENT_BREADCRUMBS = "breadcrumbs"
// Crash timestamp intent extras
private const val INTENT_CRASH_TIMESTAMP = "crashTimestamp"
// Native code crash intent extras (Mirroring GeckoView values)
private const val INTENT_UUID = "uuid"
private const val INTENT_MINIDUMP_PATH = "minidumpPath"
......@@ -38,10 +41,12 @@ sealed class Crash {
/**
* A crash caused by an uncaught exception.
*
* @property timestamp Time of when the crash happened.
* @property throwable The [Throwable] that caused the crash.
* @property breadcrumbs List of breadcrumbs to send with the crash report.
*/
data class UncaughtExceptionCrash(
val timestamp: Long,
val throwable: Throwable,
val breadcrumbs: ArrayList<Breadcrumb>,
override val uuid: String = UUID.randomUUID().toString()
......@@ -49,6 +54,7 @@ sealed class Crash {
override fun toBundle() = Bundle().apply {
putString(INTENT_UUID, uuid)
putSerializable(INTENT_EXCEPTION, throwable as Serializable)
putLong(INTENT_CRASH_TIMESTAMP, timestamp)
putParcelableArrayList(INTENT_BREADCRUMBS, breadcrumbs)
}
......@@ -56,7 +62,8 @@ sealed class Crash {
internal fun fromBundle(bundle: Bundle) = UncaughtExceptionCrash(
uuid = bundle.getString(INTENT_UUID) as String,
throwable = bundle.getSerializable(INTENT_EXCEPTION) as Throwable,
breadcrumbs = bundle.getParcelableArrayList(INTENT_BREADCRUMBS) ?: arrayListOf()
breadcrumbs = bundle.getParcelableArrayList(INTENT_BREADCRUMBS) ?: arrayListOf(),
timestamp = bundle.getLong(INTENT_CRASH_TIMESTAMP, System.currentTimeMillis())
)
}
}
......@@ -64,6 +71,7 @@ sealed class Crash {
/**
* A crash that happened in native code.
*
* @property timestamp Time of when the crash happened.
* @property minidumpPath Path to a Breakpad minidump file containing information about the crash.
* @property minidumpSuccess Indicating whether or not the crash dump was successfully retrieved. If this is false,
* the dump file may be corrupted or incomplete.
......@@ -76,6 +84,7 @@ sealed class Crash {
* @property breadcrumbs List of breadcrumbs to send with the crash report.
*/
data class NativeCodeCrash(
val timestamp: Long,
val minidumpPath: String?,
val minidumpSuccess: Boolean,
val extrasPath: String?,
......@@ -89,6 +98,7 @@ sealed class Crash {
putBoolean(INTENT_MINIDUMP_SUCCESS, minidumpSuccess)
putString(INTENT_EXTRAS_PATH, extrasPath)
putBoolean(INTENT_FATAL, isFatal)
putLong(INTENT_CRASH_TIMESTAMP, timestamp)
putParcelableArrayList(INTENT_BREADCRUMBS, breadcrumbs)
}
......@@ -99,7 +109,8 @@ sealed class Crash {
minidumpSuccess = bundle.getBoolean(INTENT_MINIDUMP_SUCCESS, false),
extrasPath = bundle.getString(INTENT_EXTRAS_PATH, null),
isFatal = bundle.getBoolean(INTENT_FATAL, false),
breadcrumbs = bundle.getParcelableArrayList(INTENT_BREADCRUMBS) ?: arrayListOf()
breadcrumbs = bundle.getParcelableArrayList(INTENT_BREADCRUMBS) ?: arrayListOf(),
timestamp = bundle.getLong(INTENT_CRASH_TIMESTAMP, System.currentTimeMillis())
)
}
}
......
......@@ -36,6 +36,7 @@ class ExceptionHandler(
crashReporter.onCrash(
context,
Crash.UncaughtExceptionCrash(
timestamp = System.currentTimeMillis(),
throwable = throwable,
breadcrumbs = crashReporter.crashBreadcrumbsCopy()
)
......
......@@ -112,6 +112,7 @@ class MozillaSocorroService(
override fun report(crash: Crash.UncaughtExceptionCrash): String? {
return sendReport(
crash.timestamp,
crash.throwable,
miniDumpFilePath = null,
extrasFilePath = null,
......@@ -123,6 +124,7 @@ class MozillaSocorroService(
override fun report(crash: Crash.NativeCodeCrash): String? {
return sendReport(
crash.timestamp,
throwable = null,
miniDumpFilePath = crash.minidumpPath,
extrasFilePath = crash.extrasPath,
......@@ -140,6 +142,7 @@ class MozillaSocorroService(
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
@Suppress("LongParameterList")
internal fun sendReport(
timestamp: Long,
throwable: Throwable?,
miniDumpFilePath: String?,
extrasFilePath: String?,
......@@ -163,7 +166,7 @@ class MozillaSocorroService(
conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=$boundary")
conn.setRequestProperty("Content-Encoding", "gzip")
sendCrashData(conn.outputStream, boundary, throwable, miniDumpFilePath, extrasFilePath,
sendCrashData(conn.outputStream, boundary, timestamp, throwable, miniDumpFilePath, extrasFilePath,
isNativeCodeCrash, isFatalCrash, breadcrumbsJson.toString())
BufferedReader(InputStreamReader(conn.inputStream)).use { reader ->
......@@ -211,6 +214,7 @@ class MozillaSocorroService(
private fun sendCrashData(
os: OutputStream,
boundary: String,
timestamp: Long,
throwable: Throwable?,
miniDumpFilePath: String?,
extrasFilePath: String?,
......@@ -268,7 +272,7 @@ class MozillaSocorroService(
sendPart(gzipOs, boundary, "StartupTime",
TimeUnit.MILLISECONDS.toSeconds(startTime).toString(), nameSet)
sendPart(gzipOs, boundary, "CrashTime",
TimeUnit.MILLISECONDS.toSeconds(System.currentTimeMillis()).toString(), nameSet)
TimeUnit.MILLISECONDS.toSeconds(timestamp).toString(), nameSet)
sendPart(gzipOs, boundary, "Android_PackageName", applicationContext.packageName, nameSet)
sendPart(gzipOs, boundary, "Android_Manufacturer", Build.MANUFACTURER, nameSet)
sendPart(gzipOs, boundary, "Android_Model", Build.MODEL, nameSet)
......
......@@ -18,6 +18,7 @@ import io.sentry.event.EventBuilder
import io.sentry.event.interfaces.ExceptionInterface
import mozilla.components.Build
import mozilla.components.lib.crash.Crash
import java.util.Date
import mozilla.components.support.base.crash.Breadcrumb as CrashBreadcrumb
/**
......@@ -83,6 +84,7 @@ class SentryService(
}
val eventBuilder = EventBuilder().withMessage(createMessage(crash))
.withTimestamp(Date(crash.timestamp))
.withLevel(Event.Level.FATAL)
.withSentryInterface(ExceptionInterface(crash.throwable))
......@@ -104,6 +106,7 @@ class SentryService(
}
val eventBuilder = EventBuilder()
.withTimestamp(Date(crash.timestamp))
.withMessage(createMessage(crash))
.withLevel(level)
......
......@@ -155,6 +155,7 @@ class CrashReporterTest {
).install(testContext))
val crash = Crash.NativeCodeCrash(
0,
"dump.path",
true,
"extras.path",
......@@ -346,7 +347,7 @@ class CrashReporterTest {
).install(testContext))
reporter.submitReport(
Crash.UncaughtExceptionCrash(RuntimeException(), arrayListOf())
Crash.UncaughtExceptionCrash(0, RuntimeException(), arrayListOf())
).joinBlocking()
assertTrue(exceptionCrash)
}
......@@ -379,7 +380,7 @@ class CrashReporterTest {
).install(testContext))
reporter.submitReport(
Crash.NativeCodeCrash("", true, "", false, arrayListOf())
Crash.NativeCodeCrash(0, "", true, "", false, arrayListOf())
).joinBlocking()
assertTrue(nativeCrash)
}
......@@ -499,7 +500,7 @@ class CrashReporterTest {
).install(testContext))
reporter.submitCrashTelemetry(
Crash.NativeCodeCrash("", true, "", false, arrayListOf())
Crash.NativeCodeCrash(0, "", true, "", false, arrayListOf())
).joinBlocking()
assertTrue(nativeCrash)
}
......@@ -539,6 +540,7 @@ class CrashReporterTest {
).install(context)
val nativeCrash = Crash.NativeCodeCrash(
0,
"dump.path",
true,
"extras.path",
......@@ -575,6 +577,7 @@ class CrashReporterTest {
).install(testContext))
val nativeCrash = Crash.NativeCodeCrash(
0,
"dump.path",
true,
"extras.path",
......@@ -601,6 +604,7 @@ class CrashReporterTest {
).install(testContext))
val nativeCrash = Crash.NativeCodeCrash(
0,
"dump.path",
true,
"extras.path",
......@@ -742,6 +746,6 @@ class CrashReporterTest {
private fun createUncaughtExceptionCrash(): Crash.UncaughtExceptionCrash {
return Crash.UncaughtExceptionCrash(
RuntimeException(), ArrayList()
0, RuntimeException(), ArrayList()
)
}
\ No newline at end of file
......@@ -19,6 +19,7 @@ class CrashTest {
@Test
fun `fromIntent() can deserialize a GeckoView crash Intent`() {
val originalCrash = Crash.NativeCodeCrash(
123,
"/data/data/org.mozilla.samples.browser/files/mozilla/Crash Reports/pending/3ba5f665-8422-dc8e-a88e-fc65c081d304.dmp",
true,
"/data/data/org.mozilla.samples.browser/files/mozilla/Crash Reports/pending/3ba5f665-8422-dc8e-a88e-fc65c081d304.extra",
......@@ -32,6 +33,7 @@ class CrashTest {
val recoveredCrash = Crash.fromIntent(intent) as? Crash.NativeCodeCrash
?: throw AssertionError("Expected NativeCodeCrash instance")
assertEquals(recoveredCrash.timestamp, 123)
assertEquals(recoveredCrash.minidumpSuccess, true)
assertEquals(recoveredCrash.isFatal, false)
assertEquals(
......@@ -48,7 +50,7 @@ class CrashTest {
fun `Serialize and deserialize UncaughtExceptionCrash`() {
val exception = RuntimeException("Hello World!")
val originalCrash = Crash.UncaughtExceptionCrash(exception, arrayListOf())
val originalCrash = Crash.UncaughtExceptionCrash(0, exception, arrayListOf())
val intent = Intent()
originalCrash.fillIn(intent)
......@@ -70,13 +72,13 @@ class CrashTest {
assertTrue(Crash.isCrashIntent(
Intent().apply {
Crash.UncaughtExceptionCrash(RuntimeException(), arrayListOf()).fillIn(this)
Crash.UncaughtExceptionCrash(0, RuntimeException(), arrayListOf()).fillIn(this)
}
))
assertTrue(Crash.isCrashIntent(
Intent().apply {
val crash = Crash.NativeCodeCrash("", true, "", false, arrayListOf())
val crash = Crash.NativeCodeCrash(0, "", true, "", false, arrayListOf())
crash.fillIn(this)
}
))
......
......@@ -49,6 +49,7 @@ class NativeCodeCrashTest {
@Test
fun `to and from bundle`() {
val crash = Crash.NativeCodeCrash(
0,
"minidumpPath",
true,
"extrasPath",
......
......@@ -16,7 +16,7 @@ class UncaughtExceptionCrashTest {
fun `UncaughtExceptionCrash wraps exception`() {
val exception = RuntimeException("Kaput")
val crash = Crash.UncaughtExceptionCrash(exception, arrayListOf())
val crash = Crash.UncaughtExceptionCrash(0, exception, arrayListOf())
assertEquals(exception, crash.throwable)
}
......@@ -24,7 +24,7 @@ class UncaughtExceptionCrashTest {
@Test
fun `to and from bundle`() {
val exception = RuntimeException("Kaput")
val crash = Crash.UncaughtExceptionCrash(exception, arrayListOf())
val crash = Crash.UncaughtExceptionCrash(0, exception, arrayListOf())
val bundle = crash.toBundle()
val otherCrash = Crash.UncaughtExceptionCrash.fromBundle(bundle)
......
......@@ -23,6 +23,7 @@ class CrashNotificationTest {
@Test
fun shouldShowNotificationInsteadOfPrompt() {
val nonFatalNativeCrash = Crash.NativeCodeCrash(
timestamp = 0,
minidumpPath = "",
minidumpSuccess = true,
extrasPath = "",
......@@ -43,6 +44,7 @@ class CrashNotificationTest {
assertFalse(CrashNotification.shouldShowNotificationInsteadOfPrompt(nonFatalNativeCrash, sdkLevel = 31))
val fatalNativeCrash = Crash.NativeCodeCrash(
timestamp = 0,
minidumpPath = "",
minidumpSuccess = true,
extrasPath = "",
......@@ -62,7 +64,7 @@ class CrashNotificationTest {
assertTrue(CrashNotification.shouldShowNotificationInsteadOfPrompt(fatalNativeCrash, sdkLevel = 30))
assertTrue(CrashNotification.shouldShowNotificationInsteadOfPrompt(fatalNativeCrash, sdkLevel = 31))
val exceptionCrash = Crash.UncaughtExceptionCrash(RuntimeException("Boom"), arrayListOf())
val exceptionCrash = Crash.UncaughtExceptionCrash(0, RuntimeException("Boom"), arrayListOf())
assertFalse(CrashNotification.shouldShowNotificationInsteadOfPrompt(exceptionCrash, sdkLevel = 21))
assertFalse(CrashNotification.shouldShowNotificationInsteadOfPrompt(exceptionCrash, sdkLevel = 22))
......@@ -85,7 +87,7 @@ class CrashNotificationTest {
assertEquals(0, shadowNotificationManager.notificationChannels.size)
assertEquals(0, shadowNotificationManager.size())
val crash = Crash.UncaughtExceptionCrash(RuntimeException("Boom"), arrayListOf())
val crash = Crash.UncaughtExceptionCrash(0, RuntimeException("Boom"), arrayListOf())
val crashNotification = CrashNotification(testContext, crash, CrashReporter.PromptConfiguration(
appName = "TestApp"
......
......@@ -63,7 +63,7 @@ class CrashReporterActivityTest {
scope = scope
).install(testContext)
val crash = Crash.UncaughtExceptionCrash(RuntimeException("Hello World"), arrayListOf())
val crash = Crash.UncaughtExceptionCrash(0, RuntimeException("Hello World"), arrayListOf())
val scenario = launchActivityWith(crash)
scenario.onActivity { activity ->
......@@ -87,7 +87,7 @@ class CrashReporterActivityTest {
scope = scope
).install(testContext)
val crash = Crash.UncaughtExceptionCrash(RuntimeException("Hello World"), arrayListOf())
val crash = Crash.UncaughtExceptionCrash(0, RuntimeException("Hello World"), arrayListOf())
val scenario = launchActivityWith(crash)
scenario.onActivity { activity ->
......@@ -114,7 +114,7 @@ class CrashReporterActivityTest {
services = listOf(mock())
).install(testContext)
val crash = Crash.UncaughtExceptionCrash(RuntimeException("Hello World"), arrayListOf())
val crash = Crash.UncaughtExceptionCrash(0, RuntimeException("Hello World"), arrayListOf())
val scenario = launchActivityWith(crash)
scenario.onActivity { activity ->
......@@ -132,7 +132,7 @@ class CrashReporterActivityTest {
scope = scope
).install(testContext)
val crash = Crash.UncaughtExceptionCrash(RuntimeException("Hello World"), arrayListOf())
val crash = Crash.UncaughtExceptionCrash(0, RuntimeException("Hello World"), arrayListOf())
val scenario = launchActivityWith(crash)
scenario.onActivity { activity ->
......
......@@ -45,7 +45,7 @@ class GleanCrashReporterServiceTest {
assertFalse("No previous persisted crashes must exist", service.file.exists())
val crash = Crash.NativeCodeCrash("", true, "", true, arrayListOf())
val crash = Crash.NativeCodeCrash(0, "", true, "", true, arrayListOf())
service.record(crash)
verify(service).record(crash)
......@@ -84,7 +84,7 @@ class GleanCrashReporterServiceTest {
assertFalse("No previous persisted crashes must exist", service.file.exists())
val crash = Crash.NativeCodeCrash("", true, "", false, arrayListOf())
val crash = Crash.NativeCodeCrash(0, "", true, "", false, arrayListOf())
service.record(crash)
assertTrue("Persistence file must exist", service.file.exists())
......@@ -121,7 +121,7 @@ class GleanCrashReporterServiceTest {
assertFalse("No previous persisted crashes must exist", service.file.exists())
val crash = Crash.UncaughtExceptionCrash(RuntimeException("Test"), arrayListOf())
val crash = Crash.UncaughtExceptionCrash(0, RuntimeException("Test"), arrayListOf())
service.record(crash)
assertTrue("Persistence file must exist", service.file.exists())
......@@ -203,9 +203,9 @@ class GleanCrashReporterServiceTest {
assertFalse("No previous persisted crashes must exist", service.file.exists())
val uncaughtExceptionCrash = Crash.UncaughtExceptionCrash(RuntimeException("Test"), arrayListOf())
val fatalNativeCodeCrash = Crash.NativeCodeCrash("", true, "", true, arrayListOf())
val nonfatalNativeCodeCrash = Crash.NativeCodeCrash("", true, "", false, arrayListOf())
val uncaughtExceptionCrash = Crash.UncaughtExceptionCrash(0, RuntimeException("Test"), arrayListOf())
val fatalNativeCodeCrash = Crash.NativeCodeCrash(0, "", true, "", true, arrayListOf())
val nonfatalNativeCodeCrash = Crash.NativeCodeCrash(0, "", true, "", false, arrayListOf())
// Record some crashes
service.record(uncaughtExceptionCrash)
......@@ -255,7 +255,7 @@ class GleanCrashReporterServiceTest {
assertFalse("No previous persisted crashes must exist", service.file.exists())
val crash = Crash.UncaughtExceptionCrash(RuntimeException("Test"), arrayListOf())
val crash = Crash.UncaughtExceptionCrash(0, RuntimeException("Test"), arrayListOf())
service.record(crash)
assertTrue("Persistence file must exist", service.file.exists())
......@@ -279,7 +279,7 @@ class GleanCrashReporterServiceTest {
assertFalse("No previous persisted crashes must exist", service.file.exists())
val crash = Crash.NativeCodeCrash("", true, "", true, arrayListOf())
val crash = Crash.NativeCodeCrash(0, "", true, "", true, arrayListOf())
service.record(crash)
assertTrue("Persistence file must exist", service.file.exists())
......
......@@ -18,6 +18,7 @@ import org.junit.Assert.assertNull
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyBoolean
import org.mockito.ArgumentMatchers.anyLong
import org.mockito.Mockito.doReturn
import org.mockito.Mockito.never
import org.mockito.Mockito.spy
......@@ -37,13 +38,13 @@ class MozillaSocorroServiceTest {
testContext,
"Test App"
))
doReturn("").`when`(service).sendReport(any(), any(), any(), anyBoolean(), anyBoolean(), any())
doReturn("").`when`(service).sendReport(anyLong(), any(), any(), any(), anyBoolean(), anyBoolean(), any())
val crash = Crash.NativeCodeCrash("", true, "", false, arrayListOf())
val crash = Crash.NativeCodeCrash(123, "", true, "", false, arrayListOf())
service.report(crash)
verify(service).report(crash)
verify(service).sendReport(null, crash.minidumpPath, crash.extrasPath, true, false, crash.breadcrumbs)
verify(service).sendReport(123, null, crash.minidumpPath, crash.extrasPath, true, false, crash.breadcrumbs)
}
@Test
......@@ -65,13 +66,13 @@ class MozillaSocorroServiceTest {
testContext,
"Test App"
))
doReturn("").`when`(service).sendReport(any(), any(), any(), anyBoolean(), anyBoolean(), any())
doReturn("").`when`(service).sendReport(anyLong(), any(), any(), any(), anyBoolean(), anyBoolean(), any())
val crash = Crash.UncaughtExceptionCrash(RuntimeException("Test"), arrayListOf())
val crash = Crash.UncaughtExceptionCrash(123, RuntimeException("Test"), arrayListOf())
service.report(crash)
verify(service).report(crash)
verify(service).sendReport(crash.throwable, null, null, false, true, crash.breadcrumbs)
verify(service).sendReport(123, crash.throwable, null, null, false, true, crash.breadcrumbs)
}
@Test
......@@ -80,13 +81,13 @@ class MozillaSocorroServiceTest {
testContext,
"Test App"
))
doReturn("").`when`(service).sendReport(any(), any(), any(), anyBoolean(), anyBoolean(), any())
doReturn("").`when`(service).sendReport(anyLong(), any(), any(), any(), anyBoolean(), anyBoolean(), any())
val throwable = RuntimeException("Test")
val breadcrumbs: ArrayList<Breadcrumb> = arrayListOf()
val id = service.report(throwable, breadcrumbs)
verify(service).report(throwable, breadcrumbs)
verify(service, never()).sendReport(any(), any(), any(), anyBoolean(), anyBoolean(), any())
verify(service, never()).sendReport(anyLong(), any(), any(), any(), anyBoolean(), anyBoolean(), any())
assertNull(id)
}
......@@ -111,6 +112,7 @@ class MozillaSocorroServiceTest {
)
val crash = Crash.NativeCodeCrash(
123456,
"dump.path",
true,
"extras.path",
......@@ -133,9 +135,10 @@ class MozillaSocorroServiceTest {
assert(request.contains("name=Android_PackageName\r\n\r\nmozilla.components.lib.crash.test"))
assert(request.contains("name=Android_Device\r\n\r\nrobolectric"))
assert(request.contains("name=CrashType\r\n\r\n$FATAL_NATIVE_CRASH_TYPE"))
assert(request.contains("name=CrashTime\r\n\r\n123"))
verify(service).report(crash)
verify(service).sendReport(null, "dump.path", "extras.path", true, true, crash.breadcrumbs)
verify(service).sendReport(123456, null, "dump.path", "extras.path", true, true, crash.breadcrumbs)
} finally {
mockWebServer.shutdown()
}
......@@ -162,6 +165,7 @@ class MozillaSocorroServiceTest {
)
val crash = Crash.NativeCodeCrash(
123456,
"dump.path",
true,
"extras.path",
......@@ -184,9 +188,10 @@ class MozillaSocorroServiceTest {
assert(request.contains("name=Android_PackageName\r\n\r\nmozilla.components.lib.crash.test"))
assert(request.contains("name=Android_Device\r\n\r\nrobolectric"))
assert(request.contains("name=CrashType\r\n\r\n$NON_FATAL_NATIVE_CRASH_TYPE"))
assert(request.contains("name=CrashTime\r\n\r\n123"))
verify(service).report(crash)
verify(service).sendReport(null, "dump.path", "extras.path", true, false, crash.breadcrumbs)
verify(service).sendReport(123456, null, "dump.path", "extras.path", true, false, crash.breadcrumbs)
} finally {
mockWebServer.shutdown()
}
......@@ -212,7 +217,7 @@ class MozillaSocorroServiceTest {
)
)
val crash = Crash.UncaughtExceptionCrash(RuntimeException("Test"), arrayListOf())
val crash = Crash.UncaughtExceptionCrash(123456, RuntimeException("Test"), arrayListOf())
service.report(crash)
val fileInputStream =
......@@ -230,9 +235,10 @@ class MozillaSocorroServiceTest {
assert(request.contains("name=Android_PackageName\r\n\r\nmozilla.components.lib.crash.test"))
assert(request.contains("name=Android_Device\r\n\r\nrobolectric"))
assert(request.contains("name=CrashType\r\n\r\n$UNCAUGHT_EXCEPTION_TYPE"))
assert(request.contains("name=CrashTime\r\n\r\n123"))
verify(service).report(crash)
verify(service).sendReport(crash.throwable, null, null, false, true, crash.breadcrumbs)
verify(service).sendReport(123456, crash.throwable, null, null, false, true, crash.breadcrumbs)
} finally {
mockWebServer.shutdown()
}
......@@ -257,12 +263,12 @@ class MozillaSocorroServiceTest {
)
)
val crash = Crash.UncaughtExceptionCrash(RuntimeException("Test"), arrayListOf())
val crash = Crash.UncaughtExceptionCrash(123, RuntimeException("Test"), arrayListOf())
service.report(crash)
mockWebServer.shutdown()
verify(service).report(crash)
verify(service).sendReport(crash.throwable, null, null, false, true, crash.breadcrumbs)
verify(service).sendReport(123, crash.throwable, null, null, false, true, crash.breadcrumbs)
} finally {
mockWebServer.shutdown()
}
......@@ -284,12 +290,12 @@ class MozillaSocorroServiceTest {
)
)
val crash = Crash.NativeCodeCrash(null, true, null, false, arrayListOf())
val crash = Crash.NativeCodeCrash(123, null, true, null, false, arrayListOf())
service.report(crash)
mockWebServer.shutdown()
verify(service).report(crash)
verify(service).sendReport(null, crash.minidumpPath, crash.extrasPath, true, false, crash.breadcrumbs)
verify(service).sendReport(123, null, crash.minidumpPath, crash.extrasPath, true, false, crash.breadcrumbs)
} finally {
mockWebServer.shutdown()
}
......@@ -432,6 +438,7 @@ class MozillaSocorroServiceTest {