@@ -54,6 +54,7 @@ import org.robolectric.shadow.api.Shadow
54
54
import org.robolectric.shadows.ShadowActivityManager
55
55
import java.util.Date
56
56
import java.util.concurrent.Future
57
+ import java.util.concurrent.TimeUnit
57
58
import kotlin.test.AfterTest
58
59
import kotlin.test.BeforeTest
59
60
import kotlin.test.Test
@@ -300,7 +301,7 @@ class ActivityLifecycleIntegrationTest {
300
301
val sut = fixture.getSut(initializer = {
301
302
it.tracesSampleRate = 1.0
302
303
it.isEnableTimeToFullDisplayTracing = true
303
- it.idleTimeout = 200
304
+ it.idleTimeout = 100
304
305
})
305
306
sut.register(fixture.scopes, fixture.options)
306
307
sut.onActivityCreated(activity, fixture.bundle)
@@ -318,7 +319,7 @@ class ActivityLifecycleIntegrationTest {
318
319
)
319
320
320
321
// but when idle timeout has passed
321
- Thread .sleep(400 )
322
+ Thread .sleep(200 )
322
323
323
324
// then the transaction should be finished
324
325
verify(fixture.scopes).captureTransaction(
@@ -815,7 +816,6 @@ class ActivityLifecycleIntegrationTest {
815
816
816
817
// when activity is resumed
817
818
sut.onActivityResumed(activity)
818
- Thread .sleep(1 )
819
819
runFirstDraw(view)
820
820
// end-time should be set
821
821
assertTrue(AppStartMetrics .getInstance().sdkInitTimeSpan.hasStopped())
@@ -863,17 +863,14 @@ class ActivityLifecycleIntegrationTest {
863
863
sut.onActivityCreated(activity, fixture.bundle)
864
864
sut.onActivityStarted(activity)
865
865
sut.onActivityResumed(activity)
866
- Thread .sleep(1 )
867
866
runFirstDraw(view)
868
867
869
868
val firstAppStartEndTime = AppStartMetrics .getInstance().sdkInitTimeSpan.projectedStopTimestamp
870
869
871
- Thread .sleep(1 )
872
870
sut.onActivityPaused(activity)
873
871
sut.onActivityStopped(activity)
874
872
sut.onActivityStarted(activity)
875
873
sut.onActivityResumed(activity)
876
- Thread .sleep(1 )
877
874
runFirstDraw(view)
878
875
879
876
// then the end time should not be overwritten
@@ -983,6 +980,36 @@ class ActivityLifecycleIntegrationTest {
983
980
)
984
981
}
985
982
983
+ @Test
984
+ fun `When isEnableTimeToFullDisplayTracing is true and reportFullyDrawn is called, ttfd is finished on first frame if ttid is running` () {
985
+ val sut = fixture.getSut()
986
+ val view = fixture.createView()
987
+ val activity = mock<Activity >()
988
+ whenever(activity.findViewById<View >(any())).thenReturn(view)
989
+ fixture.options.tracesSampleRate = 1.0
990
+ fixture.options.isEnableTimeToFullDisplayTracing = true
991
+ sut.register(fixture.scopes, fixture.options)
992
+ sut.onActivityCreated(activity, fixture.bundle)
993
+ sut.onActivityResumed(activity)
994
+ val ttidSpan = sut.ttidSpanMap[activity]
995
+ val ttfdSpan = sut.ttfdSpanMap[activity]
996
+
997
+ // Assert the ttfd span is running and a timeout autoCancel future has been scheduled
998
+ assertNotNull(ttidSpan)
999
+ assertNotNull(ttfdSpan)
1000
+ assertFalse(ttidSpan.isFinished)
1001
+ assertFalse(ttfdSpan.isFinished)
1002
+
1003
+ // ReportFullyDrawn should not finish the ttfd span, as the ttid is still running
1004
+ fixture.options.fullyDisplayedReporter.reportFullyDrawn()
1005
+ assertFalse(ttfdSpan.isFinished)
1006
+
1007
+ // But when ReportFullyDrawn should not finish the ttfd span, as the ttid is still running
1008
+ runFirstDraw(view)
1009
+ assertTrue(ttidSpan.isFinished)
1010
+ assertTrue(ttfdSpan.isFinished)
1011
+ }
1012
+
986
1013
@Test
987
1014
fun `When isEnableTimeToFullDisplayTracing is true and reportFullyDrawn is called, ttfd autoClose future is cancelled` () {
988
1015
val sut = fixture.getSut()
@@ -991,16 +1018,17 @@ class ActivityLifecycleIntegrationTest {
991
1018
sut.register(fixture.scopes, fixture.options)
992
1019
val activity = mock<Activity >()
993
1020
sut.onActivityCreated(activity, fixture.bundle)
1021
+ val ttidSpan = sut.ttidSpanMap[activity]
994
1022
val ttfdSpan = sut.ttfdSpanMap[activity]
995
1023
var autoCloseFuture = sut.getProperty<Future <* >? > (" ttfdAutoCloseFuture" )
1024
+ ttidSpan?.finish()
996
1025
997
1026
// Assert the ttfd span is running and a timeout autoCancel future has been scheduled
998
1027
assertNotNull(ttfdSpan)
999
1028
assertFalse(ttfdSpan.isFinished)
1000
1029
assertNotNull(autoCloseFuture)
1001
1030
1002
1031
// ReportFullyDrawn should finish the ttfd span and cancel the future
1003
- Thread .sleep(1 )
1004
1032
fixture.options.fullyDisplayedReporter.reportFullyDrawn()
1005
1033
assertTrue(ttfdSpan.isFinished)
1006
1034
assertNotEquals(SpanStatus .DEADLINE_EXCEEDED , ttfdSpan.status)
@@ -1077,7 +1105,6 @@ class ActivityLifecycleIntegrationTest {
1077
1105
assertFalse(ttidSpan.isFinished)
1078
1106
1079
1107
// Mock the draw of the view. The ttid span should finish now
1080
- Thread .sleep(1 )
1081
1108
runFirstDraw(view)
1082
1109
assertTrue(ttidSpan.isFinished)
1083
1110
@@ -1097,7 +1124,9 @@ class ActivityLifecycleIntegrationTest {
1097
1124
1098
1125
@Test
1099
1126
fun `When isEnableTimeToFullDisplayTracing is true and reportFullyDrawn is called too early, ttfd is adjusted to equal ttid` () {
1100
- val sut = fixture.getSut()
1127
+ val sut = fixture.getSut() {
1128
+ // it.fullyDisplayedReporter = mock()
1129
+ }
1101
1130
val view = fixture.createView()
1102
1131
val activity = mock<Activity >()
1103
1132
fixture.options.tracesSampleRate = 1.0
@@ -1116,18 +1145,28 @@ class ActivityLifecycleIntegrationTest {
1116
1145
assertFalse(ttfdSpan.isFinished)
1117
1146
1118
1147
// Let's finish the ttfd span too early (before the first view is drawn)
1119
- ttfdSpan.finish()
1120
- assertTrue(ttfdSpan.isFinished)
1121
- val oldEndDate = ttfdSpan.finishDate
1148
+ fixture.options.fullyDisplayedReporter.reportFullyDrawn()
1122
1149
1123
- // Mock the draw of the view. The ttid span should finish now and the ttfd end date should be adjusted
1150
+ // The TTFD shouldn't be finished yet
1151
+ assertFalse(ttfdSpan.isFinished)
1152
+
1153
+ // Mock the draw of the view. The ttid span should finish now and the ttfd, too
1124
1154
runFirstDraw(view)
1125
1155
assertTrue(ttidSpan.isFinished)
1126
- val newEndDate = ttfdSpan.finishDate
1127
- assertNotEquals(newEndDate, oldEndDate)
1128
- assertEquals(newEndDate, ttidSpan.finishDate)
1156
+ assertTrue(ttfdSpan.isFinished)
1157
+ assertEquals(ttfdSpan.finishDate, ttidSpan.finishDate)
1129
1158
1130
1159
sut.onActivityDestroyed(activity)
1160
+
1161
+ // The measurements should be set to the same value for ttid and ttfd
1162
+ val ttidDuration = TimeUnit .NANOSECONDS .toMillis(ttidSpan.finishDate!! .diff(ttidSpan.startDate))
1163
+ val ttfdDuration = TimeUnit .NANOSECONDS .toMillis(ttfdSpan.finishDate!! .diff(ttfdSpan.startDate))
1164
+ assertEquals(ttidDuration, ttfdDuration)
1165
+ // TTID also has initial display measurement, but TTFD has not
1166
+ assertEquals(ttidDuration, ttidSpan.measurements[MeasurementValue .KEY_TIME_TO_INITIAL_DISPLAY ]!! .value)
1167
+ assertEquals(ttidDuration, ttidSpan.measurements[MeasurementValue .KEY_TIME_TO_FULL_DISPLAY ]!! .value)
1168
+ assertEquals(ttidDuration, ttfdSpan.measurements[MeasurementValue .KEY_TIME_TO_FULL_DISPLAY ]!! .value)
1169
+
1131
1170
verify(fixture.scopes).captureTransaction(
1132
1171
check {
1133
1172
// ttid and ttfd measurements should be the same
@@ -1189,7 +1228,6 @@ class ActivityLifecycleIntegrationTest {
1189
1228
assertFalse(ttfdSpan.isFinished)
1190
1229
1191
1230
// Run the autoClose task 1 ms after finishing the ttid span and assert the ttfd span is finished
1192
- Thread .sleep(1 )
1193
1231
deferredExecutorService.runAll()
1194
1232
assertTrue(ttfdSpan.isFinished)
1195
1233
0 commit comments