summaryrefslogtreecommitdiff
path: root/tests/hostside
diff options
context:
space:
mode:
author Max Spencer <maxspencer@google.com> 2023-04-11 14:40:30 +0000
committer Max Spencer <maxspencer@google.com> 2023-04-18 14:20:26 +0000
commit0bcd6616b16b54c6f5f27313b1cfae2e925f2f21 (patch)
tree5a8a455c49173be26cce2b3aa4405caad7e6fb11 /tests/hostside
parent64914b8eef408dc8d122ee42df22e05fe7f89602 (diff)
Host/helper logging tests for state
Bug: 268309211 Test: atest SafetySourceStateCollectedLoggingHostTest Change-Id: Ibe3342f9c299757a904a5b708b7ec8dd6d891258
Diffstat (limited to 'tests/hostside')
-rw-r--r--tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetySourceStateCollectedLoggingHelperTests.kt64
-rw-r--r--tests/hostside/safetycenter/src/android/safetycenter/hostside/HelperApp.kt23
-rw-r--r--tests/hostside/safetycenter/src/android/safetycenter/hostside/ITestDeviceExtensions.kt47
-rw-r--r--tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetyCenterInteractionLoggingHostTest.kt137
-rw-r--r--tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetySourceStateCollectedLoggingHostTest.kt134
5 files changed, 313 insertions, 92 deletions
diff --git a/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetySourceStateCollectedLoggingHelperTests.kt b/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetySourceStateCollectedLoggingHelperTests.kt
new file mode 100644
index 000000000..7c85ea02a
--- /dev/null
+++ b/tests/hostside/safetycenter/helper-app/src/android/safetycenter/hostside/device/SafetySourceStateCollectedLoggingHelperTests.kt
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.safetycenter.hostside.device
+
+import android.content.Context
+import androidx.test.core.app.ApplicationProvider
+import androidx.test.ext.junit.runners.AndroidJUnit4
+import com.android.compatibility.common.util.SystemUtil
+import com.android.safetycenter.testing.SafetyCenterFlags
+import com.android.safetycenter.testing.SafetyCenterTestConfigs
+import com.android.safetycenter.testing.SafetyCenterTestConfigs.Companion.SOURCE_ID_1
+import com.android.safetycenter.testing.SafetyCenterTestHelper
+import com.android.safetycenter.testing.SafetySourceTestData
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+@RunWith(AndroidJUnit4::class)
+class SafetySourceStateCollectedLoggingHelperTests {
+ private val context: Context = ApplicationProvider.getApplicationContext()
+ private val safetyCenterTestHelper = SafetyCenterTestHelper(context)
+ private val safetySourceTestData = SafetySourceTestData(context)
+ private val safetyCenterTestConfigs = SafetyCenterTestConfigs(context)
+
+ @Before
+ fun setUp() {
+ safetyCenterTestHelper.setup()
+ SafetyCenterFlags.allowStatsdLogging = true
+ safetyCenterTestHelper.setConfig(safetyCenterTestConfigs.multipleSourcesConfig)
+ }
+
+ @After
+ fun tearDown() {
+ safetyCenterTestHelper.reset()
+ }
+
+ @Test
+ fun triggerStatsPull() {
+ val label = 1 // Arbitrary label in [0, 16)
+ val state = 3 // START
+ val command = "cmd stats log-app-breadcrumb $label $state"
+ SystemUtil.runShellCommandOrThrow(command)
+ }
+
+ @Test
+ fun setSafetySourceData_source1() {
+ safetyCenterTestHelper.setData(SOURCE_ID_1, safetySourceTestData.information)
+ }
+}
diff --git a/tests/hostside/safetycenter/src/android/safetycenter/hostside/HelperApp.kt b/tests/hostside/safetycenter/src/android/safetycenter/hostside/HelperApp.kt
new file mode 100644
index 000000000..810cce5c9
--- /dev/null
+++ b/tests/hostside/safetycenter/src/android/safetycenter/hostside/HelperApp.kt
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.safetycenter.hostside
+
+/** Constants related to the hostside test helper app */
+internal object HelperApp {
+ const val APK_NAME = "SafetyCenterHostSideTestsHelper.apk"
+ const val PACKAGE_NAME = "android.safetycenter.hostside.device"
+}
diff --git a/tests/hostside/safetycenter/src/android/safetycenter/hostside/ITestDeviceExtensions.kt b/tests/hostside/safetycenter/src/android/safetycenter/hostside/ITestDeviceExtensions.kt
new file mode 100644
index 000000000..f8d4d64c0
--- /dev/null
+++ b/tests/hostside/safetycenter/src/android/safetycenter/hostside/ITestDeviceExtensions.kt
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.safetycenter.hostside
+
+import android.cts.statsdatom.lib.DeviceUtils
+import com.android.tradefed.device.ITestDevice
+import com.android.tradefed.util.CommandStatus
+import java.io.IOException
+
+/** Runs a test in the Safety Center hostside test helper app */
+internal fun ITestDevice.runTest(testClassName: String, testMethodName: String) {
+ DeviceUtils.runDeviceTests(this, HelperApp.PACKAGE_NAME, testClassName, testMethodName)
+}
+
+/** Checks whether this [ITestDevice] supports Safety Center. */
+internal fun ITestDevice.supportsSafetyCenter(): Boolean =
+ executeShellCommandOrThrow("cmd safety_center supported").toBoolean()
+
+/** Checks whether Safety Center is currently enabled on this [ITestDevice]. */
+internal fun ITestDevice.isSafetyCenterEnabled(): Boolean =
+ executeShellCommandOrThrow("cmd safety_center enabled").toBoolean()
+
+/** Returns the package name of Safety Center on this [ITestDevice]. */
+internal fun ITestDevice.getSafetyCenterPackageName(): String =
+ executeShellCommandOrThrow("cmd safety_center package-name")
+
+private fun ITestDevice.executeShellCommandOrThrow(command: String): String {
+ val result = executeShellV2Command(command)
+ if (result.status != CommandStatus.SUCCESS) {
+ throw IOException("$command exited with status ${result.exitCode}")
+ }
+ return result.stdout.trim()
+}
diff --git a/tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetyCenterInteractionLoggingHostTest.kt b/tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetyCenterInteractionLoggingHostTest.kt
index 4fa3b5830..c49e20c15 100644
--- a/tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetyCenterInteractionLoggingHostTest.kt
+++ b/tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetyCenterInteractionLoggingHostTest.kt
@@ -16,16 +16,15 @@
package android.safetycenter.hostside
-import android.cts.statsdatom.lib.AtomTestUtils
import android.cts.statsdatom.lib.ConfigUtils
import android.cts.statsdatom.lib.DeviceUtils
import android.cts.statsdatom.lib.ReportUtils
import com.android.os.AtomsProto.Atom
import com.android.os.AtomsProto.SafetyCenterInteractionReported
-import com.android.tradefed.device.ITestDevice
+import com.android.os.AtomsProto.SafetyCenterInteractionReported.Action
+import com.android.os.AtomsProto.SafetyCenterInteractionReported.ViewType
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner
import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test
-import com.android.tradefed.util.CommandStatus
import com.google.common.truth.Truth.assertThat
import org.junit.After
import org.junit.Assume.assumeTrue
@@ -58,12 +57,10 @@ class SafetyCenterInteractionLoggingHostTest : BaseHostJUnit4Test() {
ReportUtils.clearReports(device)
ConfigUtils.uploadConfigForPushedAtom(
device,
- getSafetyCenterPackageName(),
+ device.getSafetyCenterPackageName(),
Atom.SAFETY_CENTER_INTERACTION_REPORTED_FIELD_NUMBER
)
- Thread.sleep(AtomTestUtils.WAIT_TIME_LONG.toLong())
-
- DeviceUtils.installTestApp(device, HELPER_APK_NAME, HELPER_PACKAGE, build)
+ DeviceUtils.installTestApp(device, HelperApp.APK_NAME, HelperApp.PACKAGE_NAME, build)
// TODO(b/239682646): Consider adding a target preparer that unlocks the device (like CTS)
}
@@ -74,132 +71,88 @@ class SafetyCenterInteractionLoggingHostTest : BaseHostJUnit4Test() {
ConfigUtils.removeConfig(device)
ReportUtils.clearReports(device)
- DeviceUtils.uninstallTestApp(device, HELPER_PACKAGE)
+ DeviceUtils.uninstallTestApp(device, HelperApp.PACKAGE_NAME)
}
@Test
fun openSafetyCenter_recordsSafetyCenterViewedEvent() {
- executeDeviceTest(testMethodName = "openSafetyCenter")
+ device.runTest(TEST_CLASS_NAME, testMethodName = "openSafetyCenter")
- val safetyCenterViewedEvents =
- filterEventsByAction(SafetyCenterInteractionReported.Action.SAFETY_CENTER_VIEWED)
+ val safetyCenterViewedAtoms = getInteractionReportedAtoms(Action.SAFETY_CENTER_VIEWED)
- assertThat(safetyCenterViewedEvents).isNotEmpty()
+ assertThat(safetyCenterViewedAtoms).isNotEmpty()
}
@Test
fun sendNotification_recordsNotificationPostedEvent() {
- executeDeviceTest(
+ device.runTest(
testClassName = ".SafetyCenterNotificationLoggingHelperTests",
testMethodName = "sendNotification"
)
- val notificationPostedEvents =
- filterEventsByAction(SafetyCenterInteractionReported.Action.NOTIFICATION_POSTED)
+ val notificationPostedAtoms = getInteractionReportedAtoms(Action.NOTIFICATION_POSTED)
- assertThat(notificationPostedEvents).hasSize(1)
- val atom = notificationPostedEvents.first().atom.safetyCenterInteractionReported
- assertThat(atom.viewType)
- .isEqualTo(SafetyCenterInteractionReported.ViewType.VIEW_TYPE_NOTIFICATION)
+ assertThat(notificationPostedAtoms).hasSize(1)
+ assertThat(notificationPostedAtoms.first().viewType)
+ .isEqualTo(ViewType.VIEW_TYPE_NOTIFICATION)
}
@Test
fun openSubpageFromIntentExtra_recordsEventWithUnknownNavigationSource() {
- executeDeviceTest(testMethodName = "openSubpageFromIntentExtra")
+ device.runTest(TEST_CLASS_NAME, testMethodName = "openSubpageFromIntentExtra")
- val safetyCenterViewedEvents =
- filterEventsByAction(SafetyCenterInteractionReported.Action.SAFETY_CENTER_VIEWED)
+ val safetyCenterViewedAtoms = getInteractionReportedAtoms(Action.SAFETY_CENTER_VIEWED)
- assertThat(safetyCenterViewedEvents).hasSize(1)
- val atom = safetyCenterViewedEvents.first().atom.safetyCenterInteractionReported
- assertThat(atom.viewType).isEqualTo(SafetyCenterInteractionReported.ViewType.SUBPAGE)
- assertThat(atom.navigationSource)
- .isEqualTo(SafetyCenterInteractionReported.NavigationSource.SOURCE_UNKNOWN)
- assertThat(atom.sessionId).isNotNull()
+ assertThat(safetyCenterViewedAtoms).hasSize(1)
+ with(safetyCenterViewedAtoms.first()) {
+ assertThat(viewType).isEqualTo(ViewType.SUBPAGE)
+ assertThat(navigationSource)
+ .isEqualTo(SafetyCenterInteractionReported.NavigationSource.SOURCE_UNKNOWN)
+ assertThat(sessionId).isNotNull()
+ }
}
@Test
+ @Ignore
+ // TODO(b/278202773): Fix/de-flake this test
fun openSubpageFromHomepage_recordsEventWithSafetyCenterNavigationSource() {
- executeDeviceTest(testMethodName = "openSubpageFromHomepage")
-
- val safetyCenterViewedEvents =
- filterEventsByAction(SafetyCenterInteractionReported.Action.SAFETY_CENTER_VIEWED)
+ device.runTest(TEST_CLASS_NAME, testMethodName = "openSubpageFromHomepage")
- assertThat(safetyCenterViewedEvents).hasSize(3)
- val firstAtom = safetyCenterViewedEvents[0].atom.safetyCenterInteractionReported
- assertThat(firstAtom.viewType).isEqualTo(SafetyCenterInteractionReported.ViewType.FULL)
+ val safetyCenterViewedAtoms = getInteractionReportedAtoms(Action.SAFETY_CENTER_VIEWED)
- val secondAtom = safetyCenterViewedEvents[1].atom.safetyCenterInteractionReported
- assertThat(secondAtom.viewType).isEqualTo(SafetyCenterInteractionReported.ViewType.SUBPAGE)
- assertThat(secondAtom.navigationSource)
+ assertThat(safetyCenterViewedAtoms.map { it.viewType })
+ .containsExactly(ViewType.FULL, ViewType.SUBPAGE, ViewType.FULL)
+ .inOrder()
+ assertThat(safetyCenterViewedAtoms[1].navigationSource)
.isEqualTo(SafetyCenterInteractionReported.NavigationSource.SAFETY_CENTER)
-
- val thirdAtom = safetyCenterViewedEvents[2].atom.safetyCenterInteractionReported
- assertThat(thirdAtom.viewType).isEqualTo(SafetyCenterInteractionReported.ViewType.FULL)
-
- assertThat(firstAtom.sessionId).isEqualTo(secondAtom.sessionId)
- assertThat(secondAtom.sessionId).isEqualTo(thirdAtom.sessionId)
+ assertThat(safetyCenterViewedAtoms.map { it.sessionId }.distinct()).hasSize(1)
}
@Test
@Ignore
// TODO(b/278202773): Fix/de-flake this test
fun openSubpageFromSettingsSearch_recordsEventWithSettingsNavigationSource() {
- executeDeviceTest(testMethodName = "openSubpageFromSettingsSearch")
-
- val safetyCenterViewedEvents =
- filterEventsByAction(SafetyCenterInteractionReported.Action.SAFETY_CENTER_VIEWED)
-
- assertThat(safetyCenterViewedEvents).hasSize(1)
- val atom = safetyCenterViewedEvents.first().atom.safetyCenterInteractionReported
- assertThat(atom.viewType).isEqualTo(SafetyCenterInteractionReported.ViewType.SUBPAGE)
- assertThat(atom.navigationSource)
- .isEqualTo(SafetyCenterInteractionReported.NavigationSource.SETTINGS)
- assertThat(atom.sessionId).isNotNull()
- }
-
- // TODO(b/239682646): Add more tests
+ device.runTest(TEST_CLASS_NAME, testMethodName = "openSubpageFromSettingsSearch")
- private fun ITestDevice.supportsSafetyCenter(): Boolean {
- val commandResult = executeShellV2Command("cmd safety_center supported")
+ val safetyCenterViewedAtoms = getInteractionReportedAtoms(Action.SAFETY_CENTER_VIEWED)
- if (commandResult.status != CommandStatus.SUCCESS) {
- throw AssertionError("Unable to check if Safety Center is supported: $commandResult")
+ assertThat(safetyCenterViewedAtoms).hasSize(1)
+ with(safetyCenterViewedAtoms.first()) {
+ assertThat(viewType).isEqualTo(ViewType.SUBPAGE)
+ assertThat(navigationSource)
+ .isEqualTo(SafetyCenterInteractionReported.NavigationSource.SETTINGS)
+ assertThat(sessionId).isNotNull()
}
-
- return commandResult.stdout.trim().toBoolean()
}
- private fun ITestDevice.isSafetyCenterEnabled(): Boolean {
- val commandResult = executeShellV2Command("cmd safety_center enabled")
-
- if (commandResult.status != CommandStatus.SUCCESS) {
- throw AssertionError("Unable to check if Safety Center is enabled: $commandResult")
- }
-
- return commandResult.stdout.trim().toBoolean()
- }
-
- private fun getSafetyCenterPackageName(): String =
- device.executeShellCommand("cmd safety_center package-name").trim()
-
- private fun executeDeviceTest(
- testPkgName: String = HELPER_PACKAGE,
- testClassName: String = HELPER_TEST_CLASS_NAME,
- testMethodName: String = "openSafetyCenter"
- ) {
- DeviceUtils.runDeviceTests(device, testPkgName, testClassName, testMethodName)
- Thread.sleep(AtomTestUtils.WAIT_TIME_LONG.toLong()) // Wait for report to be updated
- }
+ // TODO(b/239682646): Add more tests
- private fun filterEventsByAction(action: SafetyCenterInteractionReported.Action) =
- ReportUtils.getEventMetricDataList(device).filter {
- it.atom.safetyCenterInteractionReported.action == action
- }
+ private fun getInteractionReportedAtoms(action: SafetyCenterInteractionReported.Action) =
+ ReportUtils.getEventMetricDataList(device)
+ .mapNotNull { it.atom.safetyCenterInteractionReported }
+ .filter { it.action == action }
private companion object {
- const val HELPER_APK_NAME = "SafetyCenterHostSideTestsHelper.apk"
- const val HELPER_PACKAGE = "android.safetycenter.hostside.device"
- const val HELPER_TEST_CLASS_NAME = ".SafetyCenterInteractionLoggingHelperTests"
+ const val TEST_CLASS_NAME = ".SafetyCenterInteractionLoggingHelperTests"
}
}
diff --git a/tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetySourceStateCollectedLoggingHostTest.kt b/tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetySourceStateCollectedLoggingHostTest.kt
new file mode 100644
index 000000000..610f1111f
--- /dev/null
+++ b/tests/hostside/safetycenter/src/android/safetycenter/hostside/SafetySourceStateCollectedLoggingHostTest.kt
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.safetycenter.hostside
+
+import android.cts.statsdatom.lib.ConfigUtils
+import android.cts.statsdatom.lib.DeviceUtils
+import android.cts.statsdatom.lib.ReportUtils
+import com.android.os.AtomsProto.Atom
+import com.android.os.AtomsProto.SafetySourceStateCollected
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner
+import com.android.tradefed.testtype.junit4.BaseHostJUnit4Test
+import com.google.common.truth.Truth.assertThat
+import org.junit.After
+import org.junit.Assume.assumeTrue
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+
+/** Host-side tests for Safety Center statsd logging. */
+@RunWith(DeviceJUnit4ClassRunner::class)
+class SafetySourceStateCollectedLoggingHostTest : BaseHostJUnit4Test() {
+
+ // Use lazy here because device is not available when the test is first constructed
+ private val shouldRunTests: Boolean by lazy {
+ // TODO(b/239682646): These tests should enable Safety Center
+ device.supportsSafetyCenter() && device.isSafetyCenterEnabled()
+ }
+
+ @Before
+ fun assumeDeviceSupportsSafetyCenterToRunTests() {
+ assumeTrue(shouldRunTests)
+ }
+
+ @Before
+ fun setUp() {
+ if (!shouldRunTests) return
+
+ ConfigUtils.removeConfig(device)
+ ReportUtils.clearReports(device)
+
+ val config = ConfigUtils.createConfigBuilder(device.getSafetyCenterPackageName())
+ ConfigUtils.addGaugeMetric(config, Atom.SAFETY_STATE_FIELD_NUMBER)
+ ConfigUtils.addEventMetric(config, Atom.SAFETY_SOURCE_STATE_COLLECTED_FIELD_NUMBER)
+ ConfigUtils.uploadConfig(device, config)
+ DeviceUtils.installTestApp(device, HelperApp.APK_NAME, HelperApp.PACKAGE_NAME, build)
+
+ // TODO(b/239682646): Consider adding a target preparer that unlocks the device (like CTS)
+ }
+
+ @After
+ fun tearDown() {
+ if (!shouldRunTests) return
+
+ ReportUtils.clearReports(device)
+ ConfigUtils.removeConfig(device)
+ DeviceUtils.uninstallTestApp(device, HelperApp.PACKAGE_NAME)
+ }
+
+ @Test
+ fun triggerStatsPull_atomsPushedForAllSources() {
+ device.runTest(TEST_CLASS_NAME, "triggerStatsPull")
+
+ val sourceStateAtoms = getSafetySourceStateCollectedAtoms()
+
+ assertThat(sourceStateAtoms.map { it.encodedSafetySourceId })
+ .containsExactly(
+ SOURCE_1_ENCODED_SOURCE_ID,
+ SOURCE_2_ENCODED_SOURCE_ID,
+ SOURCE_3_ENCODED_SOURCE_ID
+ )
+ }
+
+ @Test
+ fun triggerStatsPull_atomsHaveCollectionTypeAutomatic() {
+ device.runTest(TEST_CLASS_NAME, "triggerStatsPull")
+
+ val sourceStateAtoms = getSafetySourceStateCollectedAtoms()
+
+ assertThat(sourceStateAtoms.map { it.collectionType }.distinct())
+ .containsExactly(SafetySourceStateCollected.CollectionType.AUTOMATIC)
+ }
+
+ @Test
+ fun setSafetySourceData_atomPushedForThatSource() {
+ device.runTest(TEST_CLASS_NAME, "setSafetySourceData_source1")
+
+ val sourceStateAtoms = getSafetySourceStateCollectedAtoms()
+
+ assertThat(sourceStateAtoms.map { it.encodedSafetySourceId })
+ .containsExactly(SOURCE_1_ENCODED_SOURCE_ID)
+ }
+
+ @Test
+ fun setSafetySourceData_atomHasCollectionTypeSourceUpdated() {
+ device.runTest(TEST_CLASS_NAME, "setSafetySourceData_source1")
+
+ val sourceStateAtoms = getSafetySourceStateCollectedAtoms()
+
+ assertThat(sourceStateAtoms.map { it.collectionType })
+ .containsExactly(SafetySourceStateCollected.CollectionType.SOURCE_UPDATED)
+ }
+
+ private fun getSafetySourceStateCollectedAtoms() =
+ ReportUtils.getEventMetricDataList(device)
+ .mapNotNull { it.atom.safetySourceStateCollected }
+ .filterNot {
+ // Installing/uninstalling the helper app can cause Play Protect to run a scan and
+ // push new data to Safety Center which interferes with the test results so we
+ // specifically filter the resultant atoms out using the real encoded source ID
+ it.encodedSafetySourceId == PLAY_PROTECT_ENCODED_SOURCE_ID
+ }
+
+ private companion object {
+ const val TEST_CLASS_NAME = ".SafetySourceStateCollectedLoggingHelperTests"
+ const val PLAY_PROTECT_ENCODED_SOURCE_ID = 7711894340233229936L
+ const val SOURCE_1_ENCODED_SOURCE_ID = 6446219357586936066L
+ const val SOURCE_2_ENCODED_SOURCE_ID = -5887429047684886602L
+ const val SOURCE_3_ENCODED_SOURCE_ID = -619470868366498469L
+ }
+}