Java framework for host-side virtualization tests
Add base class VirtTestCase for host-side Java virtualization tests.
It provides common methods for pushing necessary files to the device and
spawning a VM using CrosVM.
Test: VirtualizationHostTestCases
Change-Id: Ieeb129b7af772f8ab70205819766c946ae70ed11
diff --git a/tests/hostside/Android.bp b/tests/hostside/Android.bp
index d8c9871..0c894ac 100644
--- a/tests/hostside/Android.bp
+++ b/tests/hostside/Android.bp
@@ -17,6 +17,34 @@
kernel_target_stem = ":kernel_prebuilts-" + kernel_version
vendor_ramdisk_target_stem = ":cf_prebuilts_initramfs-" + kernel_version
+// JAR containing all virtualization host-side tests.
+java_test_host {
+ name: "VirtualizationHostTestCases",
+ srcs: ["java/**/*.java"],
+ test_suites: ["device-tests"],
+ libs: ["tradefed"],
+ data: [
+ ":virt_hostside_tests_kernel",
+ ":virt_hostside_tests_initramfs-arm64",
+ ":virt_hostside_tests_initramfs-x86_64",
+ ],
+}
+
+// Give kernel images unique file names.
+genrule {
+ name: "virt_hostside_tests_kernel",
+ srcs: [
+ kernel_target_stem + "-arm64",
+ kernel_target_stem + "-x86_64",
+ ],
+ out: [
+ "virt_hostside_tests_kernel-arm64",
+ "virt_hostside_tests_kernel-x86_64",
+ ],
+ tool_files: ["scripts/place_files.sh"],
+ cmd: "$(location scripts/place_files.sh) $(in) -- $(out)",
+}
+
// Ramdisk containing /init and test binaries/resources needed inside guest.
genrule {
name: "virt_hostside_tests_initramfs_base",
diff --git a/tests/hostside/AndroidTest.xml b/tests/hostside/AndroidTest.xml
new file mode 100644
index 0000000..ab77b45
--- /dev/null
+++ b/tests/hostside/AndroidTest.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 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.
+-->
+
+<configuration description="Config for Virtualization host tests">
+
+ <!-- Basic checks that the device has all the prerequisites. -->
+ <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer">
+ <option name="throw-if-cmd-fail" value="true" />
+ <!-- Kernel has KVM enabled. -->
+ <option name="run-command" value="ls /dev/kvm" />
+ <!-- Kernel has vhost-vsock enabled. -->
+ <option name="run-command" value="ls /dev/vhost-vsock" />
+ <!-- CrosVM is installed. -->
+ <option name="run-command" value="which crosvm" />
+ </target_preparer>
+
+ <!-- Push test binaries to the device. -->
+ <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+ <option name="cleanup" value="true" />
+ <option name="abort-on-push-failure" value="true" />
+ <option name="push-file" key="virt_hostside_tests_kernel-arm64" value="/data/local/tmp/virt-test/arm64/kernel" />
+ <option name="push-file" key="virt_hostside_tests_initramfs-arm64" value="/data/local/tmp/virt-test/arm64/initramfs" />
+ <option name="push-file" key="virt_hostside_tests_kernel-x86_64" value="/data/local/tmp/virt-test/x86_64/kernel" />
+ <option name="push-file" key="virt_hostside_tests_initramfs-x86_64" value="/data/local/tmp/virt-test/x86_64/initramfs" />
+ </target_preparer>
+
+ <!-- Root currently needed to run CrosVM.
+ TODO: Give sufficient permissions to the adb shell user (b/171240450). -->
+ <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
+
+ <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
+ <option name="jar" value="VirtualizationHostTestCases.jar" />
+ <option name="runtime-hint" value="2m" />
+ </test>
+</configuration>
diff --git a/tests/hostside/java/android/virt/test/VirtTestCase.java b/tests/hostside/java/android/virt/test/VirtTestCase.java
new file mode 100644
index 0000000..7ba6409
--- /dev/null
+++ b/tests/hostside/java/android/virt/test/VirtTestCase.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2020 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.
+ */
+
+package android.virt.test;
+
+import static org.junit.Assert.*;
+
+import com.android.tradefed.testtype.DeviceTestCase;
+import com.android.tradefed.testtype.IAbi;
+import com.android.tradefed.testtype.IAbiReceiver;
+
+import org.junit.Before;
+
+import java.util.ArrayList;
+
+public abstract class VirtTestCase extends DeviceTestCase implements IAbiReceiver {
+
+ private static final String DEVICE_DIR = "/data/local/tmp/virt-test";
+
+ private static final int CID_RESERVED = 2;
+
+ private IAbi mAbi;
+
+ @Before
+ public void setUp() throws Exception {
+ getDevice().waitForDeviceAvailable();
+ }
+
+ private String getAbiName() {
+ String name = mAbi.getName();
+ if ("arm64-v8a".equals(name)) {
+ name = "arm64";
+ }
+ return name;
+ }
+
+ protected String getDevicePathForTestBinary(String targetName) throws Exception {
+ String path = String.format("%s/%s/%s", DEVICE_DIR, getAbiName(), targetName);
+ if (!getDevice().doesFileExist(path)) {
+ throw new IllegalArgumentException(String.format(
+ "Binary for target %s not found on device at \"%s\"", targetName, path));
+ }
+ return path;
+ }
+
+ protected static String createCommand(String prog, Object... args) {
+ ArrayList<String> strings = new ArrayList<>();
+ strings.add(prog);
+ for (Object arg : args) {
+ strings.add(arg.toString());
+ }
+ for (String str : strings) {
+ if (str.indexOf(' ') != -1) {
+ throw new IllegalArgumentException("TODO: implement quotes around arguments");
+ } else if (str.indexOf('\'') != -1) {
+ throw new IllegalArgumentException("TODO: implement escaping arguments");
+ }
+ }
+ return String.join(" ", strings);
+ }
+
+ protected String getVmCommand(String guestCmd, Integer cid) throws Exception {
+ ArrayList<String> cmd = new ArrayList<>();
+
+ cmd.add("crosvm");
+ cmd.add("run");
+
+ cmd.add("--disable-sandbox");
+
+ if (cid != null) {
+ if (cid > CID_RESERVED) {
+ cmd.add("--cid");
+ cmd.add(cid.toString());
+ } else {
+ throw new IllegalArgumentException("Invalid CID " + cid);
+ }
+ }
+
+ cmd.add("--initrd");
+ cmd.add(getDevicePathForTestBinary("initramfs"));
+
+ cmd.add("--params");
+ cmd.add(String.format("'%s'", guestCmd));
+
+ cmd.add(getDevicePathForTestBinary("kernel"));
+
+ return String.join(" ", cmd);
+ }
+
+ @Override
+ public void setAbi(IAbi abi) {
+ mAbi = abi;
+ }
+}