For #26380 - Wait in tests until telemetry is recorded.

This commit is contained in:
Mugurell 2022-08-19 16:31:57 +03:00 committed by mergify[bot]
parent 862d74587c
commit 1332d408da
2 changed files with 25 additions and 11 deletions

View File

@ -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")
}

View File

@ -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() {