Add invalid config test

This test ensures that an invalid VM config is correctly reported via
death reason.

Bug: 220071963
Test: atest MicrodroidTests
Change-Id: I3e507828a72b40f51b4f188350ed6a19cf5e5a50
diff --git a/tests/testapk/assets/vm_config_no_task.json b/tests/testapk/assets/vm_config_no_task.json
new file mode 100644
index 0000000..3162bd0
--- /dev/null
+++ b/tests/testapk/assets/vm_config_no_task.json
@@ -0,0 +1,6 @@
+{
+  "os": {
+    "name": "microdroid"
+  },
+  "export_tombstones": true
+}
diff --git a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
index 5c48a41..59f9d17 100644
--- a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
+++ b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
@@ -27,6 +27,7 @@
 import android.os.ParcelFileDescriptor;
 import android.os.SystemProperties;
 import android.sysprop.HypervisorProperties;
+import android.system.virtualizationservice.DeathReason;
 import android.system.virtualmachine.VirtualMachine;
 import android.system.virtualmachine.VirtualMachineCallback;
 import android.system.virtualmachine.VirtualMachineConfig;
@@ -479,10 +480,21 @@
         file.writeByte(b ^ 1);
     }
 
-    private boolean tryBootVm(String vmName)
+    private static class BootResult {
+        public final boolean payloadStarted;
+        public final int deathReason;
+
+        BootResult(boolean payloadStarted, int deathReason) {
+            this.payloadStarted = payloadStarted;
+            this.deathReason = deathReason;
+        }
+    }
+
+    private BootResult tryBootVm(String vmName)
             throws VirtualMachineException, InterruptedException {
         mInner.mVm = mInner.mVmm.get(vmName); // re-load the vm before running tests
         final CompletableFuture<Boolean> payloadStarted = new CompletableFuture<>();
+        final CompletableFuture<Integer> deathReason = new CompletableFuture<>();
         VmEventListener listener =
                 new VmEventListener() {
                     @Override
@@ -490,9 +502,15 @@
                         payloadStarted.complete(true);
                         forceStop(vm);
                     }
+                    @Override
+                    public void onDied(VirtualMachine vm, int reason) {
+                        deathReason.complete(reason);
+                        super.onDied(vm, reason);
+                    }
                 };
         listener.runToFinish(mInner.mVm);
-        return payloadStarted.getNow(false);
+        return new BootResult(
+                payloadStarted.getNow(false), deathReason.getNow(DeathReason.INFRASTRUCTURE_ERROR));
     }
 
     private RandomAccessFile prepareInstanceImage(String vmName)
@@ -506,7 +524,7 @@
         oldVm.delete();
         mInner.mVmm.getOrCreate(vmName, config);
 
-        assertThat(tryBootVm(vmName)).isTrue();
+        assertThat(tryBootVm(vmName).payloadStarted).isTrue();
 
         File vmRoot = new File(mInner.mContext.getFilesDir(), "vm");
         File vmDir = new File(vmRoot, vmName);
@@ -530,7 +548,7 @@
         assertThat(offset.isPresent()).isTrue();
 
         flipBit(instanceFile, offset.getAsLong());
-        assertThat(tryBootVm("test_vm_integrity")).isFalse();
+        assertThat(tryBootVm("test_vm_integrity").payloadStarted).isFalse();
     }
 
     @Test
@@ -571,4 +589,22 @@
             assertThatPartitionIsMissing(PVM_FW_PARTITION_UUID);
         }
     }
+
+    @Test
+    public void bootFailsWhenConfigIsInvalid()
+            throws VirtualMachineException, InterruptedException, IOException {
+        VirtualMachine existingVm = mInner.mVmm.get("test_vm_invalid_config");
+        if (existingVm != null) {
+            existingVm.delete();
+        }
+
+        VirtualMachineConfig.Builder builder =
+                mInner.newVmConfigBuilder("assets/vm_config_no_task.json");
+        VirtualMachineConfig normalConfig = builder.debugLevel(DebugLevel.NONE).build();
+        mInner.mVmm.create("test_vm_invalid_config", normalConfig);
+
+        BootResult bootResult = tryBootVm("test_vm_invalid_config");
+        assertThat(bootResult.payloadStarted).isFalse();
+        assertThat(bootResult.deathReason).isEqualTo(DeathReason.MICRODROID_INVALID_PAYLOAD_CONFIG);
+    }
 }