@@ -5,7 +5,10 @@ import androidx.test.core.app.launchActivity
55import androidx.test.ext.junit.runners.AndroidJUnit4
66import io.sentry.ProfilingTraceData
77import io.sentry.Sentry
8+ import io.sentry.SentryIntegrationPackageStorage
89import io.sentry.android.core.AndroidLogger
10+ import io.sentry.android.core.CurrentActivityHolder
11+ import io.sentry.android.core.NdkIntegration
912import io.sentry.android.core.SentryAndroidOptions
1013import io.sentry.assertEnvelopeTransaction
1114import io.sentry.protocol.SentryTransaction
@@ -15,6 +18,7 @@ import org.junit.runner.RunWith
1518import shark.AndroidReferenceMatchers
1619import shark.IgnoredReferenceMatcher
1720import shark.ReferencePattern
21+ import java.util.concurrent.CountDownLatch
1822import kotlin.test.Test
1923import kotlin.test.assertEquals
2024import kotlin.test.assertTrue
@@ -215,4 +219,74 @@ class SdkInitTests : BaseUiTest() {
215219
216220 LeakAssertions .assertNoLeaks()
217221 }
222+
223+ @Test
224+ fun foregroundInitInstallsDefaultIntegrations () {
225+ val activityScenario = launchActivity<ComposeActivity >()
226+ activityScenario.moveToState(Lifecycle .State .RESUMED )
227+ activityScenario.onActivity { activity ->
228+ // Our SentryInitProvider does not run in this test
229+ // so we need to set the current activity manually
230+ CurrentActivityHolder .getInstance().setActivity(activity)
231+ initSentry(false ) { options: SentryAndroidOptions ->
232+ options.tracesSampleRate = 1.0
233+ options.profilesSampleRate = 1.0
234+ }
235+ }
236+ activityScenario.moveToState(Lifecycle .State .DESTROYED )
237+ assertDefaultIntegrations()
238+ }
239+
240+ @Test
241+ fun backgroundInitInstallsDefaultIntegrations () {
242+ val initLatch = CountDownLatch (1 )
243+
244+ val activityScenario = launchActivity<ComposeActivity >()
245+ activityScenario.moveToState(Lifecycle .State .RESUMED )
246+ activityScenario.onActivity { activity ->
247+ // Our SentryInitProvider does not run in this test
248+ // so we need to set the current activity manually
249+ CurrentActivityHolder .getInstance().setActivity(activity)
250+ Thread {
251+ initSentry(false ) { options: SentryAndroidOptions ->
252+ options.tracesSampleRate = 1.0
253+ options.profilesSampleRate = 1.0
254+ }
255+ initLatch.countDown()
256+ }.start()
257+ }
258+ initLatch.await()
259+
260+ activityScenario.moveToState(Lifecycle .State .DESTROYED )
261+
262+ assertDefaultIntegrations()
263+ }
264+
265+ private fun assertDefaultIntegrations () {
266+ val integrations = mutableListOf (
267+ " UncaughtExceptionHandler" ,
268+ " ShutdownHook" ,
269+ " SendCachedEnvelope" ,
270+ " AppLifecycle" ,
271+ " EnvelopeFileObserver" ,
272+ " AnrV2" ,
273+ " ActivityLifecycle" ,
274+ " ActivityBreadcrumbs" ,
275+ " UserInteraction" ,
276+ " AppComponentsBreadcrumbs" ,
277+ " NetworkBreadcrumbs"
278+ )
279+
280+ // NdkIntegration is not always available, so we check for its presence
281+ try {
282+ Class .forName(NdkIntegration .SENTRY_NDK_CLASS_NAME )
283+ integrations.add(" Ndk" )
284+ } catch (_: ClassNotFoundException ) {
285+ // ignored, in case the app is build without NDK support
286+ }
287+
288+ for (integration in integrations) {
289+ assertTrue(SentryIntegrationPackageStorage .getInstance().integrations.contains(integration), " Integration $integration was expected, but was not registered" )
290+ }
291+ }
218292}
0 commit comments