Add some unit tests
There are a bunch of getters and helper methods that we don't exercise
in our tests, so I'm adding some tests to fix that. These are "unit
tests" in a loose sense - no VM is ever created, but they do involve
running code in an APK, touching the filesystem etc.
Also rearranged the ordering of members in the classes so e.g. all the
instance variables are together, which makes it easier to check this.
Bug: 244561836
Test: atest MicrodroidTests
Change-Id: I6887b203c18a021eb2415f2624900012040310e1
diff --git a/javalib/src/android/system/virtualmachine/VirtualMachine.java b/javalib/src/android/system/virtualmachine/VirtualMachine.java
index dec873f..d774cec 100644
--- a/javalib/src/android/system/virtualmachine/VirtualMachine.java
+++ b/javalib/src/android/system/virtualmachine/VirtualMachine.java
@@ -106,26 +106,6 @@
*/
@SystemApi
public class VirtualMachine implements AutoCloseable {
- private static final String TAG = "VirtualMachine";
-
- /** Name of the directory under the files directory where all VMs created for the app exist. */
- private static final String VM_DIR = "vm";
-
- /** Name of the persisted config file for a VM. */
- private static final String CONFIG_FILE = "config.xml";
-
- /** Name of the instance image file for a VM. (Not implemented) */
- private static final String INSTANCE_IMAGE_FILE = "instance.img";
-
- /** Name of the idsig file for a VM */
- private static final String IDSIG_FILE = "idsig";
-
- /** Name of the idsig files for extra APKs. */
- private static final String EXTRA_IDSIG_FILE_PREFIX = "extra_idsig_";
-
- /** Name of the virtualization service. */
- private static final String SERVICE_NAME = "android.system.virtualizationservice";
-
/** The permission needed to create or run a virtual machine. */
public static final String MANAGE_VIRTUAL_MACHINE_PERMISSION =
"android.permission.MANAGE_VIRTUAL_MACHINE";
@@ -162,6 +142,29 @@
*/
public static final int STATUS_DELETED = 2;
+ private static final String TAG = "VirtualMachine";
+
+ /** Name of the directory under the files directory where all VMs created for the app exist. */
+ private static final String VM_DIR = "vm";
+
+ /** Name of the persisted config file for a VM. */
+ private static final String CONFIG_FILE = "config.xml";
+
+ /** Name of the instance image file for a VM. (Not implemented) */
+ private static final String INSTANCE_IMAGE_FILE = "instance.img";
+
+ /** Name of the idsig file for a VM */
+ private static final String IDSIG_FILE = "idsig";
+
+ /** Name of the idsig files for extra APKs. */
+ private static final String EXTRA_IDSIG_FILE_PREFIX = "extra_idsig_";
+
+ /** Name of the virtualization service. */
+ private static final String SERVICE_NAME = "android.system.virtualizationservice";
+
+ /** Size of the instance image. 10 MB. */
+ private static final long INSTANCE_FILE_SIZE = 10 * 1024 * 1024;
+
/** The package which owns this VM. */
@NonNull private final String mPackageName;
@@ -184,25 +187,12 @@
/** Path to the idsig file for this VM. */
@NonNull private final File mIdsigFilePath;
- private static class ExtraApkSpec {
- public final File apk;
- public final File idsig;
-
- ExtraApkSpec(File apk, File idsig) {
- this.apk = apk;
- this.idsig = idsig;
- }
- }
-
/**
* Unmodifiable list of extra apks. Apks are specified by the vm config, and corresponding
* idsigs are to be generated.
*/
@NonNull private final List<ExtraApkSpec> mExtraApks;
- /** Size of the instance image. 10 MB. */
- private static final long INSTANCE_FILE_SIZE = 10 * 1024 * 1024;
-
// A note on lock ordering:
// You can take mLock while holding VirtualMachineManager.sCreateLock, but not vice versa.
// We never take any other lock while holding mCallbackLock; therefore you can
@@ -251,6 +241,16 @@
@Nullable
private Executor mCallbackExecutor;
+ private static class ExtraApkSpec {
+ public final File apk;
+ public final File idsig;
+
+ ExtraApkSpec(File apk, File idsig) {
+ this.apk = apk;
+ this.idsig = idsig;
+ }
+ }
+
static {
System.loadLibrary("virtualmachine_jni");
}
diff --git a/javalib/src/android/system/virtualmachine/VirtualMachineConfig.java b/javalib/src/android/system/virtualmachine/VirtualMachineConfig.java
index 8678b99..b432bde 100644
--- a/javalib/src/android/system/virtualmachine/VirtualMachineConfig.java
+++ b/javalib/src/android/system/virtualmachine/VirtualMachineConfig.java
@@ -65,9 +65,6 @@
private static final String KEY_MEMORY_MIB = "memoryMib";
private static final String KEY_NUM_CPUS = "numCpus";
- // Absolute path to the APK file containing the VM payload.
- @NonNull private final String mApkPath;
-
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef(prefix = "DEBUG_LEVEL_", value = {
@@ -101,6 +98,9 @@
*/
@SystemApi public static final int DEBUG_LEVEL_FULL = 2;
+ /** Absolute path to the APK file containing the VM payload. */
+ @NonNull private final String mApkPath;
+
@DebugLevel private final int mDebugLevel;
/**
diff --git a/tests/helper/src/java/com/android/microdroid/test/device/MicrodroidDeviceTestBase.java b/tests/helper/src/java/com/android/microdroid/test/device/MicrodroidDeviceTestBase.java
index c266b96..bd5b180 100644
--- a/tests/helper/src/java/com/android/microdroid/test/device/MicrodroidDeviceTestBase.java
+++ b/tests/helper/src/java/com/android/microdroid/test/device/MicrodroidDeviceTestBase.java
@@ -88,6 +88,10 @@
return new VirtualMachineConfig.Builder(mCtx).setProtectedVm(mProtectedVm);
}
+ protected final boolean isProtectedVm() {
+ return mProtectedVm;
+ }
+
/**
* Creates a new virtual machine, potentially removing an existing virtual machine with given
* name.
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 abee36c..899e47e 100644
--- a/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
+++ b/tests/testapk/src/java/com/android/microdroid/test/MicrodroidTests.java
@@ -126,12 +126,13 @@
}
@Test
- @CddTest(requirements = {
- "9.17/C-1-1",
- "9.17/C-1-2",
- "9.17/C-1-4",
- })
- public void createVmRequiresPermission() throws Exception {
+ @CddTest(
+ requirements = {
+ "9.17/C-1-1",
+ "9.17/C-1-2",
+ "9.17/C-1-4",
+ })
+ public void createVmRequiresPermission() {
assumeSupportedKernel();
revokePermission(VirtualMachine.MANAGE_VIRTUAL_MACHINE_PERMISSION);
@@ -181,6 +182,68 @@
}
@Test
+ @CddTest(requirements = {"9.17/C-1-1"})
+ public void vmConfigUnitTests() {
+ VirtualMachineConfig minimal =
+ newVmConfigBuilder().setPayloadBinaryPath("binary/path").build();
+
+ assertThat(minimal.getApkPath()).isEqualTo(getContext().getPackageCodePath());
+ assertThat(minimal.getDebugLevel()).isEqualTo(DEBUG_LEVEL_NONE);
+ assertThat(minimal.getMemoryMib()).isEqualTo(0);
+ assertThat(minimal.getNumCpus()).isEqualTo(1);
+ assertThat(minimal.getPayloadBinaryPath()).isEqualTo("binary/path");
+ assertThat(minimal.getPayloadConfigPath()).isNull();
+ assertThat(minimal.isProtectedVm()).isEqualTo(isProtectedVm());
+
+ int maxCpus = Runtime.getRuntime().availableProcessors();
+ VirtualMachineConfig.Builder maximalBuilder =
+ newVmConfigBuilder()
+ .setPayloadConfigPath("config/path")
+ .setApkPath("/apk/path")
+ .setNumCpus(maxCpus)
+ .setDebugLevel(DEBUG_LEVEL_FULL)
+ .setMemoryMib(42);
+ VirtualMachineConfig maximal = maximalBuilder.build();
+
+ assertThat(maximal.getApkPath()).isEqualTo("/apk/path");
+ assertThat(maximal.getDebugLevel()).isEqualTo(DEBUG_LEVEL_FULL);
+ assertThat(maximal.getMemoryMib()).isEqualTo(42);
+ assertThat(maximal.getNumCpus()).isEqualTo(maxCpus);
+ assertThat(maximal.getPayloadBinaryPath()).isNull();
+ assertThat(maximal.getPayloadConfigPath()).isEqualTo("config/path");
+ assertThat(maximal.isProtectedVm()).isEqualTo(isProtectedVm());
+
+ assertThat(minimal.isCompatibleWith(maximal)).isFalse();
+ assertThat(minimal.isCompatibleWith(minimal)).isTrue();
+ assertThat(maximal.isCompatibleWith(maximal)).isTrue();
+
+ VirtualMachineConfig compatible = maximalBuilder.setNumCpus(1).setMemoryMib(99).build();
+ assertThat(compatible.isCompatibleWith(maximal)).isTrue();
+ }
+
+ @Test
+ @CddTest(requirements = {"9.17/C-1-1"})
+ public void vmUnitTests() throws Exception {
+ VirtualMachineConfig.Builder builder =
+ newVmConfigBuilder().setPayloadBinaryPath("binary/path");
+ VirtualMachineConfig config = builder.build();
+ VirtualMachine vm = forceCreateNewVirtualMachine("vm_name", config);
+
+ assertThat(vm.getName()).isEqualTo("vm_name");
+ assertThat(vm.getConfig().getPayloadBinaryPath()).isEqualTo("binary/path");
+ assertThat(vm.getConfig().getMemoryMib()).isEqualTo(0);
+
+ VirtualMachineConfig compatibleConfig = builder.setMemoryMib(42).build();
+ vm.setConfig(compatibleConfig);
+
+ assertThat(vm.getName()).isEqualTo("vm_name");
+ assertThat(vm.getConfig().getPayloadBinaryPath()).isEqualTo("binary/path");
+ assertThat(vm.getConfig().getMemoryMib()).isEqualTo(42);
+
+ assertThat(getVirtualMachineManager().get("vm_name")).isSameInstanceAs(vm);
+ }
+
+ @Test
@CddTest(requirements = {
"9.17/C-1-1",
"9.17/C-1-2",