For #26380 - Wait in tests until telemetry is recorded.
This commit is contained in:
parent
862d74587c
commit
1332d408da
|
@ -10,6 +10,7 @@ import androidx.annotation.VisibleForTesting.PRIVATE
|
|||
import androidx.lifecycle.DefaultLifecycleObserver
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import kotlinx.coroutines.CoroutineDispatcher
|
||||
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
|
@ -67,14 +68,19 @@ class StartupTypeTelemetry(
|
|||
@VisibleForTesting(otherwise = NONE)
|
||||
fun getTestCallbacks() = StartupTypeLifecycleObserver()
|
||||
|
||||
/**
|
||||
* Record startup telemetry based on the available [startupStateProvider] and [startupPathProvider].
|
||||
*
|
||||
* @param dispatcher used to control the thread on which telemetry will be recorded. Defaults to [Dispatchers.IO].
|
||||
*/
|
||||
@VisibleForTesting(otherwise = PRIVATE)
|
||||
fun record() {
|
||||
fun record(dispatcher: CoroutineDispatcher = Dispatchers.IO) {
|
||||
val startupState = startupStateProvider.getStartupStateForStartedActivity(activityClass)
|
||||
val startupPath = startupPathProvider.startupPathForActivity
|
||||
val label = getTelemetryLabel(startupState, startupPath)
|
||||
|
||||
@OptIn(DelicateCoroutinesApi::class)
|
||||
GlobalScope.launch(Dispatchers.IO) {
|
||||
GlobalScope.launch(dispatcher) {
|
||||
PerfStartup.startupType[label].add(1)
|
||||
logger.info("Recorded start up: $label")
|
||||
}
|
||||
|
|
|
@ -12,8 +12,11 @@ import io.mockk.impl.annotations.MockK
|
|||
import io.mockk.mockk
|
||||
import io.mockk.spyk
|
||||
import io.mockk.verify
|
||||
import kotlinx.coroutines.test.advanceUntilIdle
|
||||
import mozilla.components.support.ktx.kotlin.crossProduct
|
||||
import mozilla.components.support.test.robolectric.testContext
|
||||
import mozilla.components.support.test.rule.MainCoroutineRule
|
||||
import mozilla.components.support.test.rule.runTestOnMain
|
||||
import mozilla.telemetry.glean.testing.GleanTestRule
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertNull
|
||||
|
@ -38,6 +41,9 @@ private val activityClass = HomeActivity::class.java
|
|||
@RunWith(AndroidJUnit4::class)
|
||||
class StartupTypeTelemetryTest {
|
||||
|
||||
@get:Rule
|
||||
val coroutinesTestRule = MainCoroutineRule()
|
||||
|
||||
@get:Rule
|
||||
val gleanTestRule = GleanTestRule(testContext)
|
||||
|
||||
|
@ -62,7 +68,7 @@ class StartupTypeTelemetryTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN all possible path and state combinations WHEN record telemetry THEN the labels are incremented the appropriate number of times`() {
|
||||
fun `GIVEN all possible path and state combinations WHEN record telemetry THEN the labels are incremented the appropriate number of times`() = runTestOnMain {
|
||||
val allPossibleInputArgs = StartupState.values().toList().crossProduct(
|
||||
StartupPath.values().toList()
|
||||
) { state, path ->
|
||||
|
@ -73,7 +79,8 @@ class StartupTypeTelemetryTest {
|
|||
every { stateProvider.getStartupStateForStartedActivity(activityClass) } returns state
|
||||
every { pathProvider.startupPathForActivity } returns path
|
||||
|
||||
telemetry.record()
|
||||
telemetry.record(coroutinesTestRule.testDispatcher)
|
||||
advanceUntilIdle()
|
||||
}
|
||||
|
||||
validTelemetryLabels.forEach { label ->
|
||||
|
@ -87,11 +94,12 @@ class StartupTypeTelemetryTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
fun `WHEN record is called THEN telemetry is recorded with the appropriate label`() {
|
||||
fun `WHEN record is called THEN telemetry is recorded with the appropriate label`() = runTestOnMain {
|
||||
every { stateProvider.getStartupStateForStartedActivity(activityClass) } returns StartupState.COLD
|
||||
every { pathProvider.startupPathForActivity } returns StartupPath.MAIN
|
||||
|
||||
telemetry.record()
|
||||
telemetry.record(coroutinesTestRule.testDispatcher)
|
||||
advanceUntilIdle()
|
||||
|
||||
assertEquals(1, PerfStartup.startupType["cold_main"].testGetValue())
|
||||
}
|
||||
|
@ -99,33 +107,33 @@ class StartupTypeTelemetryTest {
|
|||
@Test
|
||||
fun `GIVEN the activity is launched WHEN onResume is called THEN we record the telemetry`() {
|
||||
launchApp()
|
||||
verify(exactly = 1) { telemetry.record() }
|
||||
verify(exactly = 1) { telemetry.record(any()) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN the activity is launched WHEN the activity is paused and resumed THEN record is not called`() {
|
||||
// This part of the test duplicates another test but it's needed to initialize the state of this test.
|
||||
launchApp()
|
||||
verify(exactly = 1) { telemetry.record() }
|
||||
verify(exactly = 1) { telemetry.record(any()) }
|
||||
|
||||
callbacks.onPause(mockk())
|
||||
callbacks.onResume(mockk())
|
||||
|
||||
verify(exactly = 1) { telemetry.record() } // i.e. this shouldn't be called again.
|
||||
verify(exactly = 1) { telemetry.record(any()) } // i.e. this shouldn't be called again.
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN the activity is launched WHEN the activity is stopped and resumed THEN record is called again`() {
|
||||
// This part of the test duplicates another test but it's needed to initialize the state of this test.
|
||||
launchApp()
|
||||
verify(exactly = 1) { telemetry.record() }
|
||||
verify(exactly = 1) { telemetry.record(any()) }
|
||||
|
||||
callbacks.onPause(mockk())
|
||||
callbacks.onStop(mockk())
|
||||
callbacks.onStart(mockk())
|
||||
callbacks.onResume(mockk())
|
||||
|
||||
verify(exactly = 2) { telemetry.record() } // i.e. this should be called again.
|
||||
verify(exactly = 2) { telemetry.record(any()) } // i.e. this should be called again.
|
||||
}
|
||||
|
||||
private fun launchApp() {
|
||||
|
|
Loading…
Reference in New Issue