Adds CTS tests for uid map for statsd.

We verify that a snapshot is always available and the change events
occur as expected.

Test: Verified that the new CTS tests pass on marlin-eng.
Bug: 76220601
Change-Id: Iae0b326c2575973d69e098a0ad87a6d088485dd1
diff --git a/tests/src/android/cts/statsd/uidmap/UidMapTests.java b/tests/src/android/cts/statsd/uidmap/UidMapTests.java
index e69de29..75d7c1e 100644
--- a/tests/src/android/cts/statsd/uidmap/UidMapTests.java
+++ b/tests/src/android/cts/statsd/uidmap/UidMapTests.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2018 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.cts.statsd.uidmap;
+
+import static org.junit.Assert.assertTrue;
+
+import android.cts.statsd.atom.DeviceAtomTestCase;
+import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper;
+import com.android.internal.os.StatsdConfigProto;
+import com.android.os.StatsLog.ConfigMetricsReportList;
+import com.android.os.StatsLog.ConfigMetricsReport;
+import com.android.os.StatsLog.UidMapping;
+import com.android.os.StatsLog.UidMapping.PackageInfoSnapshot;
+
+import java.util.List;
+
+public class UidMapTests extends DeviceAtomTestCase {
+
+    // Tests that every report has at least one snapshot.
+    public void testUidSnapshotIncluded() throws Exception {
+        // There should be at least the test app installed during the test setup.
+        uploadConfig(createConfigBuilder().build());
+
+        ConfigMetricsReportList reports = getReportList();
+        assertTrue(reports.getReportsCount() > 0);
+
+        for (ConfigMetricsReport report : reports.getReportsList()) {
+            UidMapping uidmap = report.getUidMap();
+            assertTrue(uidmap.getSnapshotsCount() > 0);
+            for (PackageInfoSnapshot snapshot : uidmap.getSnapshotsList()) {
+                // There must be at least one element in each snapshot (at least one package is
+                // installed).
+                assertTrue(snapshot.getPackageInfoCount() > 0);
+            }
+        }
+    }
+
+    private boolean hasMatchingChange(UidMapping uidmap, boolean expectDeletion) {
+        for (UidMapping.Change change : uidmap.getChangesList()) {
+            if (change.getApp().equals(DEVICE_SIDE_TEST_PACKAGE)) {
+                if (change.getDeletion() == expectDeletion) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    // Tests that delta event included during app installation.
+    public void testChangeFromInstallation() throws Exception {
+        getDevice().uninstallPackage(DEVICE_SIDE_TEST_PACKAGE);
+        uploadConfig(createConfigBuilder().build());
+        // Install the package after the config is sent to statsd. The uid map is not guaranteed to
+        // be updated if there's no config in statsd.
+        CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild);
+        final String result = getDevice().installPackage(
+                buildHelper.getTestFile(DEVICE_SIDE_TEST_APK), false, true);
+
+        ConfigMetricsReportList reports = getReportList();
+        assertTrue(reports.getReportsCount() > 0);
+
+        boolean found = false;
+        for (ConfigMetricsReport report : reports.getReportsList()) {
+            if (hasMatchingChange(report.getUidMap(), false)) {
+                found = true;
+            }
+        }
+        assertTrue(found);
+    }
+
+    // We check that a re-installation gives a change event (similar to an app upgrade).
+    public void testChangeFromReinstall() throws Exception {
+        CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild);
+        getDevice().installPackage(buildHelper.getTestFile(DEVICE_SIDE_TEST_APK), false, true);
+        uploadConfig(createConfigBuilder().build());
+        // Now enable re-installation.
+        getDevice().installPackage(buildHelper.getTestFile(DEVICE_SIDE_TEST_APK), true, true);
+
+        ConfigMetricsReportList reports = getReportList();
+        assertTrue(reports.getReportsCount() > 0);
+
+        boolean found = false;
+        for (ConfigMetricsReport report : reports.getReportsList()) {
+            if (hasMatchingChange(report.getUidMap(), false)) {
+                found = true;
+            }
+        }
+        assertTrue(found);
+    }
+
+    public void testChangeFromUninstall() throws Exception {
+        CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild);
+        getDevice().installPackage(buildHelper.getTestFile(DEVICE_SIDE_TEST_APK), true, true);
+        uploadConfig(createConfigBuilder().build());
+        getDevice().uninstallPackage(DEVICE_SIDE_TEST_PACKAGE);
+
+        ConfigMetricsReportList reports = getReportList();
+        assertTrue(reports.getReportsCount() > 0);
+
+        boolean found = false;
+        for (ConfigMetricsReport report : reports.getReportsList()) {
+            if (hasMatchingChange(report.getUidMap(), true)) {
+                found = true;
+            }
+        }
+        assertTrue(found);
+    }
+}