Merge "Add tests for get, create, getOrCreate"
diff --git a/javalib/src/android/system/virtualmachine/VirtualMachineManager.java b/javalib/src/android/system/virtualmachine/VirtualMachineManager.java
index ea0a305..5b30617 100644
--- a/javalib/src/android/system/virtualmachine/VirtualMachineManager.java
+++ b/javalib/src/android/system/virtualmachine/VirtualMachineManager.java
@@ -150,6 +150,11 @@
* Returns an existing {@link VirtualMachine} with the given name. Returns null if there is no
* such virtual machine.
*
+ * <p>There is at most one {@code VirtualMachine} object corresponding to a given virtual
+ * machine instance. Multiple calls to get() passing the same name will get the same object
+ * returned, until the virtual machine is deleted (via {@link #delete}) and then recreated.
+ *
+ * @see #getOrCreate
* @throws VirtualMachineException if the virtual machine exists but could not be successfully
* retrieved.
* @hide
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 5f24c4b..eb756d8 100644
--- a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
+++ b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
@@ -258,14 +258,7 @@
assertThrowsVmExceptionContaining(() -> vm.toDescriptor(), "deleted");
// This is indistinguishable from the VM having never existed, so the message
// is non-specific.
- assertThrows(
- VirtualMachineException.class, () -> getVirtualMachineManager().delete("test_vm"));
- }
-
- private void assertThrowsVmExceptionContaining(
- ThrowingRunnable runnable, String expectedContents) {
- Exception e = assertThrows(VirtualMachineException.class, runnable);
- assertThat(e).hasMessageThat().contains(expectedContents);
+ assertThrowsVmException(() -> getVirtualMachineManager().delete("test_vm"));
}
@Test
@@ -423,6 +416,48 @@
@Test
@CddTest(requirements = {"9.17/C-1-1"})
+ public void vmmGetAndCreate() throws Exception {
+ assumeSupportedKernel();
+
+ VirtualMachineConfig config =
+ newVmConfigBuilder()
+ .setPayloadBinaryPath("MicrodroidTestNativeLib.so")
+ .setMemoryMib(minMemoryRequired())
+ .setDebugLevel(DEBUG_LEVEL_FULL)
+ .build();
+
+ VirtualMachineManager vmm = getVirtualMachineManager();
+ String vmName = "vmName";
+
+ // VM does not yet exist
+ assertThat(vmm.get(vmName)).isNull();
+
+ VirtualMachine vm1 = vmm.create(vmName, config);
+
+ // Now it does, and we should get the same instance back
+ assertThat(vmm.get(vmName)).isSameInstanceAs(vm1);
+ assertThat(vmm.getOrCreate(vmName, config)).isSameInstanceAs(vm1);
+
+ // Can't recreate it though
+ assertThrowsVmException(() -> vmm.create(vmName, config));
+
+ vmm.delete(vmName);
+ assertThat(vmm.get(vmName)).isNull();
+
+ // Now that we deleted the old one, this should create rather than get, and it should be a
+ // new instance.
+ VirtualMachine vm2 = vmm.getOrCreate(vmName, config);
+ assertThat(vm2).isNotSameInstanceAs(vm1);
+
+ // Subsequent gets should return this new one.
+ assertThat(vmm.get(vmName)).isSameInstanceAs(vm2);
+ assertThat(vmm.getOrCreate(vmName, config)).isSameInstanceAs(vm2);
+
+ vmm.delete(vmName);
+ }
+
+ @Test
+ @CddTest(requirements = {"9.17/C-1-1"})
public void vmFilesStoredInDeDirWhenCreatedFromDEContext() throws Exception {
final Context ctx = getContext().createDeviceProtectedStorageContext();
final int userId = ctx.getUserId();
@@ -511,10 +546,10 @@
assertThat(vmm.get("test_vm_delete")).isNull();
// Can't start the VM even with an existing reference
- assertThrows(VirtualMachineException.class, vm::run);
+ assertThrowsVmException(vm::run);
// Can't delete the VM since it no longer exists
- assertThrows(VirtualMachineException.class, () -> vmm.delete("test_vm_delete"));
+ assertThrowsVmException(() -> vmm.delete("test_vm_delete"));
}
@Test
@@ -1098,6 +1133,16 @@
return filePath.toFile();
}
+ private void assertThrowsVmException(ThrowingRunnable runnable) {
+ assertThrows(VirtualMachineException.class, runnable);
+ }
+
+ private void assertThrowsVmExceptionContaining(
+ ThrowingRunnable runnable, String expectedContents) {
+ Exception e = assertThrows(VirtualMachineException.class, runnable);
+ assertThat(e).hasMessageThat().contains(expectedContents);
+ }
+
private int minMemoryRequired() {
if (Build.SUPPORTED_ABIS.length > 0) {
String primaryAbi = Build.SUPPORTED_ABIS[0];