[CtsStatsdHostTestCases] Updated MetadataTests

Restructured test to have 2 distinct test apks

Ignore-AOSP-First: will cp to aosp

Flag: EXEMPT bugfix

Bug: 323424122
Test: atest android.cts.statsd.metadata.MetadataTests

Merged-In: I05f70721fff84e7c6b721b2442dc79b601e85ff3
Change-Id: I05f70721fff84e7c6b721b2442dc79b601e85ff3
diff --git a/tests/Android.bp b/tests/Android.bp
index cf12ddf..133955b 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -49,6 +49,5 @@
         "**/*.pbtxt",
         ":CtsStatsdApp",
         ":StatsdAtomStormApp",
-        ":StatsdAtomStormApp2",
     ],
 }
diff --git a/tests/AndroidTest.xml b/tests/AndroidTest.xml
index 781813a..e33c2a0 100644
--- a/tests/AndroidTest.xml
+++ b/tests/AndroidTest.xml
@@ -36,10 +36,4 @@
         <option name="set-global-setting" key="verifier_verify_adb_installs" value="0" />
         <option name="restore-settings" value="true" />
     </target_preparer>
-
-    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
-        <option name="cleanup-apks" value="true" />
-        <option name="test-file-name" value="StatsdAtomStormApp.apk" />
-        <option name="test-file-name" value="StatsdAtomStormApp2.apk" />
-    </target_preparer>
 </configuration>
diff --git a/tests/apps/atomstormapp/Android.bp b/tests/apps/atomstormapp/Android.bp
index 86e5953..1162c55 100644
--- a/tests/apps/atomstormapp/Android.bp
+++ b/tests/apps/atomstormapp/Android.bp
@@ -38,27 +38,3 @@
     ],
     compile_multilib: "both",
 }
-
-android_test_helper_app {
-    name: "StatsdAtomStormApp2",
-    manifest: "AndroidManifest2.xml",
-    defaults: ["cts_defaults"],
-    platform_apis: true,
-    min_sdk_version: "24",
-    srcs: [
-        "src/**/*.java",
-    ],
-    libs: [
-        "android.test.runner",
-        "junit",
-        "org.apache.http.legacy",
-    ],
-    privileged: true,
-    static_libs: [
-        "ctstestrunner-axt",
-        "compatibility-device-util-axt",
-        "androidx.legacy_legacy-support-v4",
-        "androidx.test.rules",
-    ],
-    compile_multilib: "both",
-}
diff --git a/tests/apps/atomstormapp/AndroidManifest2.xml b/tests/apps/atomstormapp/AndroidManifest2.xml
deleted file mode 100644
index 310397f..0000000
--- a/tests/apps/atomstormapp/AndroidManifest2.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- * 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.
- -->
-
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.statsd.app.atomstorm.copy">
-    <!-- Using gms shared uid is necessary for the receivers to work. -->
-
-    <!-- GTS started at 14; do not change minSdkVersion. -->
-    <uses-sdk android:minSdkVersion="19" android:targetSdkVersion="28"/>
-
-    <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
-                     android:targetPackage="com.android.statsd.app.atomstorm.copy"
-                     android:label="CTS tests of android.os.statsd stats collection">
-    </instrumentation>
-</manifest>
diff --git a/tests/apps/atomstormapp/src/com/android/statsd/app/atomstorm/StatsdAtomStorm.java b/tests/apps/atomstormapp/src/com/android/statsd/app/atomstorm/StatsdAtomStorm.java
index 6e55a84..cf7471d 100644
--- a/tests/apps/atomstormapp/src/com/android/statsd/app/atomstorm/StatsdAtomStorm.java
+++ b/tests/apps/atomstormapp/src/com/android/statsd/app/atomstorm/StatsdAtomStorm.java
@@ -27,7 +27,7 @@
 @MediumTest
 @RunWith(AndroidJUnit4.class)
 public class StatsdAtomStorm {
-    private static final int EventStormAtomsCount = 10000;
+    private static final int EventStormAtomsCount = 50000;
     private static final int RelaxedLoggingAtomsCount = 10;
     private static final int RecommendedLoggingIntervalMs = 10;
 
diff --git a/tests/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdStressLogging.java b/tests/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdStressLogging.java
index 62dfe78..70f787e 100644
--- a/tests/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdStressLogging.java
+++ b/tests/apps/statsdapp/src/com/android/server/cts/device/statsd/StatsdStressLogging.java
@@ -16,31 +16,39 @@
 
 package com.android.server.cts.device.statsd;
 
-import android.os.SystemClock;
 import android.util.StatsLog;
 
 import org.junit.Test;
 
 public class StatsdStressLogging {
-    private static final int EVENT_STORM_ATOMS_COUNT = 100000;
+    private static final int EventStormAtomsCount = 50000;
+    private static final int RelaxedLoggingAtomsCount = 10;
+    private static final int RecommendedLoggingIntervalMs = 10;
 
-    /** Tests that logging many atoms back to back leads to socket overflow and data loss. */
+    /** Tests socket overflow. */
     @Test
     public void testLogAtomsBackToBack() throws Exception {
         // logging back to back many atoms to force socket overflow
-        logAtoms(EVENT_STORM_ATOMS_COUNT);
+        logAtomsBackToBack(EventStormAtomsCount, 0);
 
-        // Using sleep to allow bypass libstatsocket dumpAtomsLossStats() cooldown timer
-        SystemClock.sleep(100);
-
-        // Try to log atoms into socket successfully to trigger libstatsocket dumpAtomsLossStats()
-        logAtoms(1);
+        // Due to the nature of stress test there is some unpredictability aspect, repeating
+        // natural atom logging flow several times to have higher guaranty of atom delivery
+        // including recommended delay between logging atoms
+        for (int i = 0; i < RelaxedLoggingAtomsCount; i++) {
+            Thread.sleep(RecommendedLoggingIntervalMs);
+            // give chance for libstatssocket send loss stats to statsd triggering
+            // successful logging
+            logAtomsBackToBack(1, RecommendedLoggingIntervalMs);
+        }
     }
 
-    private void logAtoms(int iterations) {
+    private void logAtomsBackToBack(int iterations, int loggingDelay) throws Exception {
         // single atom logging takes ~2us excluding JNI interactions
         for (int i = 0; i < iterations; i++) {
             StatsLog.logStart(i);
+            if (loggingDelay > 0) {
+                Thread.sleep(loggingDelay);
+            }
             StatsLog.logStop(i);
         }
     }
diff --git a/tests/src/android/cts/statsd/metadata/MetadataTests.java b/tests/src/android/cts/statsd/metadata/MetadataTests.java
index 78faace..7c890ba 100644
--- a/tests/src/android/cts/statsd/metadata/MetadataTests.java
+++ b/tests/src/android/cts/statsd/metadata/MetadataTests.java
@@ -227,47 +227,65 @@
 
     /** Test libstatssocket logging queue atom id distribution collection */
     public void testAtomIdLossDistributionCollection() throws Exception {
+        final String testPkgName = "com.android.statsd.app.atomstorm";
+        final String testApk = "StatsdAtomStormApp.apk";
+
         if (!ApiLevelUtil.codenameEquals(getDevice(), "VanillaIceCream")) {
             return;
         }
 
-        String[] testApks = {"StatsdAtomStormApp.apk", "StatsdAtomStormApp2.apk"};
-        String[] testPkgs = {
-            "com.android.statsd.app.atomstorm", "com.android.statsd.app.atomstorm.copy"
+        String[][] testPkgs = {
+            {testPkgName, ".StatsdAtomStorm", "testLogManyAtomsBackToBack"},
+            {
+                MetricsUtils.DEVICE_SIDE_TEST_PACKAGE,
+                ".StatsdStressLogging",
+                "testLogAtomsBackToBack"
+            }
         };
 
-        for (String pkg : testPkgs) {
-            DeviceUtils.uninstallTestApp(getDevice(), pkg);
-        }
+        DeviceUtils.uninstallTestApp(getDevice(), testPkgName);
 
-        final int testAppsCount = testApks.length;
-        for (int i = 0; i < testAppsCount; i++) {
-            DeviceUtils.installTestApp(getDevice(), testApks[i], testPkgs[i], mCtsBuild);
-        }
+        DeviceUtils.installTestApp(getDevice(), testApk, testPkgName, mCtsBuild);
 
+        StatsdStatsReport report = getStatsdStatsReport();
+        assertThat(report).isNotNull();
+
+        // since the statsdstats accumulated from boot - we need to look only into diff if any
+        final HashSet<Integer> initialUids = getSocketLossUids(report);
         HashSet<Integer> reportedUids = new HashSet<Integer>();
-        for (String pkg : testPkgs) {
-            DeviceUtils.runDeviceTests(getDevice(), pkg, null, null);
 
-            StatsdStatsReport report = getStatsdStatsReport();
+        // intention is to run two distinct package tests to collect 2 different uids
+        for (String[] pkg : testPkgs) {
+            DeviceUtils.runDeviceTests(getDevice(), pkg[0], pkg[1], pkg[2]);
+
+            // the sleep is required since atoms are processed in async way by statsd
+            // need to give time so statsd will process SocketLossStats atom
+            RunUtil.getDefault().sleep(AtomTestUtils.WAIT_TIME_SHORT);
+            LogUtil.CLog.d(
+                    "testAtomIdLossDistributionCollection getStatsdStatsReport for " + pkg[0]);
+            report = getStatsdStatsReport();
             assertThat(report).isNotNull();
-            if (report.getDetectedLogLossList().size() == 0) {
-                // It is Ok if system throughput sufficient to process all atoms
-                return;
-            }
-
-            assertThat(report.getSocketLossStats()).isNotNull();
-            assertThat(report.getSocketLossStats().getLossStatsPerUidList().size())
-                    .isGreaterThan(1);
-            for (LossStatsPerUid lossStats : report.getSocketLossStats().getLossStatsPerUidList()) {
-                reportedUids.add(lossStats.getUid());
-            }
+            reportedUids.addAll(getSocketLossUids(report));
         }
 
+        // obtaining the diff between initial loss info and loss info collected during the test
+        reportedUids.removeAll(initialUids);
         assertThat(reportedUids.size()).isGreaterThan(1);
 
-        for (String pkg : testPkgs) {
-            DeviceUtils.uninstallTestApp(getDevice(), pkg);
+        DeviceUtils.uninstallTestApp(getDevice(), testPkgName);
+    }
+
+    static private HashSet<Integer> getSocketLossUids(StatsdStatsReport report) {
+        HashSet<Integer> result = new HashSet<Integer>();
+        assertThat(report.getSocketLossStats()).isNotNull();
+        assertThat(report.getSocketLossStats().getLossStatsPerUidList().size())
+                .isGreaterThan(0);
+        for (LossStatsPerUid lossStats : report.getSocketLossStats().getLossStatsPerUidList()) {
+            LogUtil.CLog.d(
+                    "getSocketLossUids() collecting loss stats for uid "
+                            + lossStats.getUid());
+            result.add(lossStats.getUid());
         }
+        return result;
     }
 }