1
1
package io.sentry.android.core
2
2
3
+ import android.app.Activity
3
4
import android.app.Application
5
+ import android.app.Application.ActivityLifecycleCallbacks
4
6
import android.content.pm.ProviderInfo
5
7
import android.os.Build
8
+ import android.os.Bundle
6
9
import androidx.test.ext.junit.runners.AndroidJUnit4
7
10
import io.sentry.ILogger
8
11
import io.sentry.JsonSerializer
@@ -26,6 +29,7 @@ import java.nio.file.Files
26
29
import kotlin.test.AfterTest
27
30
import kotlin.test.BeforeTest
28
31
import kotlin.test.Test
32
+ import kotlin.test.assertEquals
29
33
import kotlin.test.assertFailsWith
30
34
import kotlin.test.assertFalse
31
35
import kotlin.test.assertNotNull
@@ -48,6 +52,7 @@ class SentryPerformanceProviderTest {
48
52
val providerInfo = ProviderInfo ()
49
53
val logger = mock<ILogger >()
50
54
lateinit var configFile: File
55
+ var activityLifecycleCallback: ActivityLifecycleCallbacks ? = null
51
56
52
57
fun getSut (sdkVersion : Int = Build .VERSION_CODES .S , authority : String = AUTHORITY , handleFile : ((config: File ) -> Unit )? = null): SentryPerformanceProvider {
53
58
val buildInfoProvider: BuildInfoProvider = mock()
@@ -56,7 +61,10 @@ class SentryPerformanceProviderTest {
56
61
whenever(mockContext.applicationContext).thenReturn(mockContext)
57
62
configFile = File (sentryCache, Sentry .APP_START_PROFILING_CONFIG_FILE_NAME )
58
63
handleFile?.invoke(configFile)
59
-
64
+ whenever(mockContext.registerActivityLifecycleCallbacks(any())).then {
65
+ activityLifecycleCallback = it.arguments[0 ] as ActivityLifecycleCallbacks
66
+ return @then Unit
67
+ }
60
68
providerInfo.authority = authority
61
69
return SentryPerformanceProvider (logger, buildInfoProvider).apply {
62
70
attachInfo(mockContext, providerInfo)
@@ -232,6 +240,73 @@ class SentryPerformanceProviderTest {
232
240
assertFalse(AppStartMetrics .getInstance().appStartProfiler!! .isRunning)
233
241
}
234
242
243
+ @Test
244
+ fun `Sets app launch type to cold` () {
245
+ val provider = fixture.getSut()
246
+ val activity = mock<Activity >()
247
+ provider.onCreate()
248
+
249
+ assertEquals(AppStartMetrics .AppStartType .UNKNOWN , AppStartMetrics .getInstance().appStartType)
250
+
251
+ // when the first activity has no bundle
252
+ fixture.activityLifecycleCallback!! .onActivityCreated(activity, null )
253
+
254
+ // then the app start is considered cold
255
+ assertEquals(AppStartMetrics .AppStartType .COLD , AppStartMetrics .getInstance().appStartType)
256
+
257
+ // when any subsequent activity launches
258
+ fixture.activityLifecycleCallback!! .onActivityCreated(activity, mock<Bundle >())
259
+
260
+ // then the app start is still considered cold
261
+ assertEquals(AppStartMetrics .AppStartType .COLD , AppStartMetrics .getInstance().appStartType)
262
+ }
263
+
264
+ @Test
265
+ fun `Sets app launch type to warm if process init is too old` () {
266
+ val provider = fixture.getSut()
267
+ val activity = mock<Activity >()
268
+ provider.onCreate()
269
+
270
+ assertEquals(AppStartMetrics .AppStartType .UNKNOWN , AppStartMetrics .getInstance().appStartType)
271
+
272
+ AppStartMetrics .getInstance().appStartTimeSpan.setStartedAt(
273
+ AppStartMetrics .getInstance().appStartTimeSpan.startUptimeMs - 20000
274
+ )
275
+
276
+ // when the first activity has no bundle
277
+ fixture.activityLifecycleCallback!! .onActivityCreated(activity, null )
278
+
279
+ // then the app start is considered warm
280
+ assertEquals(AppStartMetrics .AppStartType .WARM , AppStartMetrics .getInstance().appStartType)
281
+
282
+ // when any subsequent activity launches
283
+ fixture.activityLifecycleCallback!! .onActivityCreated(activity, mock<Bundle >())
284
+
285
+ // then the app start is still considered warm
286
+ assertEquals(AppStartMetrics .AppStartType .WARM , AppStartMetrics .getInstance().appStartType)
287
+ }
288
+
289
+ @Test
290
+ fun `Sets app launch type to warm` () {
291
+ val provider = fixture.getSut()
292
+ val activity = mock<Activity >()
293
+ provider.onCreate()
294
+
295
+ assertEquals(AppStartMetrics .AppStartType .UNKNOWN , AppStartMetrics .getInstance().appStartType)
296
+
297
+ // when the first activity has a bundle
298
+ fixture.activityLifecycleCallback!! .onActivityCreated(activity, mock<Bundle >())
299
+
300
+ // then the app start is considered WARM
301
+ assertEquals(AppStartMetrics .AppStartType .WARM , AppStartMetrics .getInstance().appStartType)
302
+
303
+ // when any subsequent activity launches
304
+ fixture.activityLifecycleCallback!! .onActivityCreated(activity, null )
305
+
306
+ // then the app start is still considered warm
307
+ assertEquals(AppStartMetrics .AppStartType .WARM , AppStartMetrics .getInstance().appStartType)
308
+ }
309
+
235
310
private fun writeConfig (
236
311
configFile : File ,
237
312
profilingEnabled : Boolean = true,
0 commit comments