@@ -20,6 +20,7 @@ import com.datadog.android.rum.assertj.VitalAppLaunchEventAssert
2020import com.datadog.android.rum.assertj.VitalAppLaunchPropertiesAssert.Companion.assertThat
2121import com.datadog.android.rum.internal.domain.InfoProvider
2222import com.datadog.android.rum.internal.domain.RumContext
23+ import com.datadog.android.rum.internal.domain.Time
2324import com.datadog.android.rum.internal.domain.battery.BatteryInfo
2425import com.datadog.android.rum.internal.domain.display.DisplayInfo
2526import com.datadog.android.rum.internal.domain.scope.RumRawEvent
@@ -53,6 +54,7 @@ import org.mockito.junit.jupiter.MockitoExtension
5354import org.mockito.junit.jupiter.MockitoSettings
5455import org.mockito.kotlin.any
5556import org.mockito.kotlin.argumentCaptor
57+ import org.mockito.kotlin.atLeastOnce
5658import org.mockito.kotlin.doAnswer
5759import org.mockito.kotlin.doReturn
5860import org.mockito.kotlin.eq
@@ -64,6 +66,7 @@ import org.mockito.kotlin.verifyNoMoreInteractions
6466import org.mockito.kotlin.whenever
6567import org.mockito.quality.Strictness
6668import java.lang.ref.WeakReference
69+ import java.util.concurrent.TimeUnit
6770import java.util.stream.Stream
6871
6972@Extensions(
@@ -309,7 +312,7 @@ internal class RumSessionScopeStartupManagerTest {
309312
310313 val ttidEvent = RumRawEvent .AppStartTTIDEvent (info = info)
311314
312- val ttfdEvent = RumRawEvent . AppStartTTFDEvent ( )
315+ val ttfdEvent = forge.createTTFDEvent(scenario.initialTime )
313316
314317 // When
315318 manager.onAppStartEvent(RumRawEvent .AppStartEvent (scenario = scenario))
@@ -371,8 +374,8 @@ internal class RumSessionScopeStartupManagerTest {
371374 val ttidEvent1 = RumRawEvent .AppStartTTIDEvent (info = info1)
372375 val ttidEvent2 = RumRawEvent .AppStartTTIDEvent (info = info2)
373376
374- val ttfdEvent1 = RumRawEvent . AppStartTTFDEvent ( )
375- val ttfdEvent2 = RumRawEvent . AppStartTTFDEvent ( )
377+ val ttfdEvent1 = forge.createTTFDEvent(scenario1.initialTime )
378+ val ttfdEvent2 = forge.createTTFDEvent(scenario2.initialTime )
376379
377380 // When
378381 manager.onAppStartEvent(appStartEvent1)
@@ -545,6 +548,109 @@ internal class RumSessionScopeStartupManagerTest {
545548 }
546549 }
547550
551+ @ParameterizedTest
552+ @MethodSource(" testScenarios" )
553+ fun `M not send TTID vital event W onTTIDEvent { duration is too large }` (
554+ scenario : RumStartupScenario ,
555+ forge : Forge
556+ ) {
557+ // Given
558+ val info = RumTTIDInfo (
559+ scenario = scenario,
560+ durationNs = forge.aLong(
561+ min = RumSessionScopeStartupManagerImpl .DURATION_SUITABLE_TO_REPORT_THRESHOLD + 1
562+ )
563+ )
564+
565+ val ttidEvent = RumRawEvent .AppStartTTIDEvent (
566+ info = info
567+ )
568+
569+ // When
570+ manager.onAppStartEvent(RumRawEvent .AppStartEvent (scenario = scenario))
571+
572+ manager.onTTIDEvent(
573+ event = ttidEvent,
574+ datadogContext = fakeDatadogContext,
575+ writeScope = mockEventWriteScope,
576+ writer = mockWriter,
577+ rumContext = rumContext,
578+ customAttributes = fakeParentAttributes
579+ )
580+
581+ // Then
582+ verifyNoInteractions(mockWriter)
583+
584+ mockInternalLogger.verifyLog(
585+ level = InternalLogger .Level .WARN ,
586+ target = InternalLogger .Target .USER ,
587+ message = RumSessionScopeStartupManagerImpl .TTID_TOO_LARGE_MESSAGE ,
588+ throwable = null ,
589+ onlyOnce = false ,
590+ additionalProperties = null
591+ )
592+ }
593+
594+ @ParameterizedTest
595+ @MethodSource(" testScenarios" )
596+ fun `M not send TTFD vital event W onTTFDEvent { duration is too large }` (
597+ scenario : RumStartupScenario ,
598+ forge : Forge
599+ ) {
600+ // Given
601+ val info = RumTTIDInfo (
602+ scenario = scenario,
603+ durationNs = forge.aLong(min = 0 , max = 10000 )
604+ )
605+
606+ val ttidEvent = RumRawEvent .AppStartTTIDEvent (info = info)
607+
608+ val ttfdEvent = forge.createTTFDEvent(
609+ initialTime = scenario.initialTime,
610+ offsetNs = RumSessionScopeStartupManagerImpl .DURATION_SUITABLE_TO_REPORT_THRESHOLD + 1
611+ )
612+
613+ // When
614+ manager.onAppStartEvent(RumRawEvent .AppStartEvent (scenario = scenario))
615+
616+ manager.onTTIDEvent(
617+ event = ttidEvent,
618+ datadogContext = fakeDatadogContext,
619+ writeScope = mockEventWriteScope,
620+ writer = mockWriter,
621+ rumContext = rumContext,
622+ customAttributes = fakeParentAttributes
623+ )
624+
625+ manager.onTTFDEvent(
626+ event = ttfdEvent,
627+ datadogContext = fakeDatadogContext,
628+ writeScope = mockEventWriteScope,
629+ writer = mockWriter,
630+ rumContext = rumContext,
631+ customAttributes = fakeParentAttributes
632+ )
633+
634+ // Then
635+ inOrder(mockWriter) {
636+ argumentCaptor<RumVitalAppLaunchEvent > {
637+ verify(mockWriter, times(1 )).write(eq(mockEventBatchWriter), capture(), eq(EventType .DEFAULT ))
638+ verifyTTID(value = firstValue, info = info)
639+ }
640+ verifyNoMoreInteractions()
641+ }
642+
643+ mockInternalLogger.verifyLog(
644+ level = InternalLogger .Level .WARN ,
645+ target = InternalLogger .Target .USER ,
646+ message = RumSessionScopeStartupManagerImpl .TTFD_TOO_LARGE_MESSAGE ,
647+ throwable = null ,
648+ onlyOnce = false ,
649+ additionalProperties = null ,
650+ mode = atLeastOnce()
651+ )
652+ }
653+
548654 private fun verifyTTID (value : RumVitalAppLaunchEvent , info : RumTTIDInfo ) {
549655 VitalAppLaunchEventAssert .assertThat(value).apply {
550656 hasDate(info.scenario.initialTime.timestamp + fakeTimeInfo.serverTimeOffsetMs)
@@ -680,4 +786,18 @@ internal class RumSessionScopeStartupManagerTest {
680786 .stream()
681787 }
682788 }
789+
790+ private fun Forge.createTTFDEvent (
791+ initialTime : Time ,
792+ offsetNs : Long = aLong(min = 0, max = 10000)
793+ ): RumRawEvent .AppStartTTFDEvent {
794+ val offsetMs = TimeUnit .NANOSECONDS .toMillis(offsetNs)
795+
796+ return RumRawEvent .AppStartTTFDEvent (
797+ eventTime = Time (
798+ timestamp = initialTime.timestamp + offsetMs,
799+ nanoTime = initialTime.nanoTime + offsetNs
800+ )
801+ )
802+ }
683803}
0 commit comments