Add test for atoms VmCreationRequested, VmBooted, and VmExited

Bug: 239510882
Test: atest MicrodroidTestCase#testTelemetryPushedAtoms

Change-Id: I20ddce47523851520ecaa9f330208ad4a5be0159
diff --git a/tests/hostside/Android.bp b/tests/hostside/Android.bp
index 5ce19bd..d77f3de 100644
--- a/tests/hostside/Android.bp
+++ b/tests/hostside/Android.bp
@@ -15,6 +15,7 @@
     static_libs: [
         "MicrodroidHostTestHelper",
         "compatibility-host-util",
+        "cts-statsd-atom-host-test-utils",
     ],
     per_testcase_directory: true,
     data: [
diff --git a/tests/hostside/java/com/android/microdroid/test/MicrodroidTestCase.java b/tests/hostside/java/com/android/microdroid/test/MicrodroidTestCase.java
index fb92467..5eff94b 100644
--- a/tests/hostside/java/com/android/microdroid/test/MicrodroidTestCase.java
+++ b/tests/hostside/java/com/android/microdroid/test/MicrodroidTestCase.java
@@ -25,13 +25,19 @@
 import static org.hamcrest.CoreMatchers.containsString;
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.CoreMatchers.nullValue;
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertThat;
 import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 import static org.junit.Assume.assumeTrue;
 
+import android.cts.statsdatom.lib.ConfigUtils;
+import android.cts.statsdatom.lib.ReportUtils;
+
 import com.android.compatibility.common.util.CddTest;
+import com.android.os.AtomsProto;
+import com.android.os.StatsLog;
 import com.android.tradefed.device.DeviceNotAvailableException;
 import com.android.tradefed.result.TestDescription;
 import com.android.tradefed.result.TestResult;
@@ -469,6 +475,89 @@
     }
 
     @Test
+    public void testTelemetryPushedAtoms() throws Exception {
+        // Reset statsd config and report before the test
+        ConfigUtils.removeConfig(getDevice());
+        ReportUtils.clearReports(getDevice());
+
+        // Setup statsd config
+        int[] atomIds = {
+            AtomsProto.Atom.VM_CREATION_REQUESTED_FIELD_NUMBER,
+            AtomsProto.Atom.VM_BOOTED_FIELD_NUMBER,
+            AtomsProto.Atom.VM_EXITED_FIELD_NUMBER,
+        };
+        ConfigUtils.uploadConfigForPushedAtoms(getDevice(), PACKAGE_NAME, atomIds);
+
+        // Create VM with microdroid
+        final String configPath = "assets/vm_config_apex.json"; // path inside the APK
+        final String cid =
+                startMicrodroid(
+                        getDevice(),
+                        getBuild(),
+                        APK_NAME,
+                        PACKAGE_NAME,
+                        configPath,
+                        /* debug */ true,
+                        minMemorySize(),
+                        Optional.of(NUM_VCPUS),
+                        Optional.of(CPU_AFFINITY));
+
+        // Check VmCreationRequested atom and clear the statsd report
+        List<StatsLog.EventMetricData> data;
+        data = ReportUtils.getEventMetricDataList(getDevice());
+        assertEquals(1, data.size());
+        assertEquals(
+                AtomsProto.Atom.VM_CREATION_REQUESTED_FIELD_NUMBER,
+                data.get(0).getAtom().getPushedCase().getNumber());
+        AtomsProto.VmCreationRequested atomVmCreationRequested =
+                data.get(0).getAtom().getVmCreationRequested();
+        assertEquals(
+                AtomsProto.VmCreationRequested.Hypervisor.PKVM,
+                atomVmCreationRequested.getHypervisor());
+        assertFalse(atomVmCreationRequested.getIsProtected());
+        assertTrue(atomVmCreationRequested.getCreationSucceeded());
+        assertEquals(0, atomVmCreationRequested.getBinderExceptionCode());
+        assertEquals("VmRunApp", atomVmCreationRequested.getVmIdentifier());
+        assertEquals(
+                AtomsProto.VmCreationRequested.ConfigType.VIRTUAL_MACHINE_APP_CONFIG,
+                atomVmCreationRequested.getConfigType());
+        assertEquals(NUM_VCPUS, atomVmCreationRequested.getNumCpus());
+        assertEquals(CPU_AFFINITY, atomVmCreationRequested.getCpuAffinity());
+        assertEquals(minMemorySize(), atomVmCreationRequested.getMemoryMib());
+        assertEquals(
+                "com.android.art:com.android.compos:com.android.sdkext",
+                atomVmCreationRequested.getApexes());
+
+        // Boot VM with microdroid
+        adbConnectToMicrodroid(getDevice(), cid);
+        waitForBootComplete();
+
+        // Check VmBooted atom and clear the statsd report
+        data = ReportUtils.getEventMetricDataList(getDevice());
+        assertEquals(1, data.size());
+        assertEquals(
+                AtomsProto.Atom.VM_BOOTED_FIELD_NUMBER,
+                data.get(0).getAtom().getPushedCase().getNumber());
+        AtomsProto.VmBooted atomVmBooted = data.get(0).getAtom().getVmBooted();
+        assertEquals("VmRunApp", atomVmBooted.getVmIdentifier());
+
+        // Shutdown VM with microdroid
+        shutdownMicrodroid(getDevice(), cid);
+        // TODO: make sure the VM is completely shut down while 'vm stop' command running.
+        Thread.sleep(1000);
+
+        // Check VmExited atom and clear the statsd report
+        data = ReportUtils.getEventMetricDataList(getDevice());
+        assertEquals(1, data.size());
+        assertEquals(
+                AtomsProto.Atom.VM_EXITED_FIELD_NUMBER,
+                data.get(0).getAtom().getPushedCase().getNumber());
+        AtomsProto.VmExited atomVmExited = data.get(0).getAtom().getVmExited();
+        assertEquals("VmRunApp", atomVmExited.getVmIdentifier());
+        assertEquals(AtomsProto.VmExited.DeathReason.KILLED, atomVmExited.getDeathReason());
+    }
+
+    @Test
     @CddTest(requirements = {"9.17/C-1-1", "9.17/C-1-2", "9.17/C/1-3"})
     public void testMicrodroidBoots() throws Exception {
         final String configPath = "assets/vm_config.json"; // path inside the APK