Merge "Migrate MicrodroidHostTestCases to MicrodroidBuilder"
This commit is contained in:
commit
9b55de3259
|
@ -17,4 +17,7 @@ java_test_host {
|
|||
test_suites: [
|
||||
"general-tests",
|
||||
],
|
||||
data: [
|
||||
":MicrodroidTestApp",
|
||||
],
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
package android.avf.test;
|
||||
|
||||
import static com.android.tradefed.device.TestDevice.MicrodroidBuilder;
|
||||
import static com.android.tradefed.testtype.DeviceJUnit4ClassRunner.TestMetrics;
|
||||
|
||||
import static com.google.common.truth.Truth.assertWithMessage;
|
||||
|
@ -31,6 +32,8 @@ import com.android.microdroid.test.common.MetricsProcessor;
|
|||
import com.android.microdroid.test.host.CommandRunner;
|
||||
import com.android.microdroid.test.host.MicrodroidHostTestCaseBase;
|
||||
import com.android.tradefed.device.DeviceNotAvailableException;
|
||||
import com.android.tradefed.device.ITestDevice;
|
||||
import com.android.tradefed.device.TestDevice;
|
||||
import com.android.tradefed.log.LogUtil.CLog;
|
||||
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
|
||||
import com.android.tradefed.util.CommandResult;
|
||||
|
@ -45,7 +48,6 @@ import java.util.ArrayList;
|
|||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
@ -85,6 +87,9 @@ public final class AVFHostTestCase extends MicrodroidHostTestCaseBase {
|
|||
@Before
|
||||
public void setUp() throws Exception {
|
||||
testIfDeviceIsCapable(getDevice());
|
||||
|
||||
getDevice().installPackage(findTestFile(APK_NAME), /* reinstall */ false);
|
||||
|
||||
mMetricsProcessor = new MetricsProcessor(getMetricPrefix() + "hostside/");
|
||||
}
|
||||
|
||||
|
@ -196,10 +201,6 @@ public final class AVFHostTestCase extends MicrodroidHostTestCaseBase {
|
|||
return null;
|
||||
}
|
||||
|
||||
private void microdroidWaitForBootComplete() {
|
||||
runOnMicrodroidForResult("watch -e \"getprop dev.bootcomplete | grep '^0$'\"");
|
||||
}
|
||||
|
||||
private AmStartupTimeCmdParser getColdRunStartupTimes(CommandRunner android, String pkgName)
|
||||
throws DeviceNotAvailableException, InterruptedException {
|
||||
unlockScreen(android);
|
||||
|
@ -216,9 +217,7 @@ public final class AVFHostTestCase extends MicrodroidHostTestCaseBase {
|
|||
// and the time measured after running the VM.
|
||||
private void getAppStartupTime(String pkgName, StartupTimeMetricCollection metricColector)
|
||||
throws Exception {
|
||||
final String configPath = "assets/vm_config.json";
|
||||
final String cid;
|
||||
final int vm_mem_mb;
|
||||
TestDevice device = (TestDevice) getDevice();
|
||||
|
||||
// 1. Reboot the device to run the test without stage2 fragmentation
|
||||
getDevice().rebootUntilOnline();
|
||||
|
@ -240,30 +239,30 @@ public final class AVFHostTestCase extends MicrodroidHostTestCaseBase {
|
|||
android.tryRun("rm", "-rf", MicrodroidHostTestCaseBase.TEST_ROOT);
|
||||
|
||||
// Donate 80% of the available device memory to the VM
|
||||
vm_mem_mb = getFreeMemoryInfoMb(android) * 80 / 100;
|
||||
cid = startMicrodroid(
|
||||
getDevice(),
|
||||
getBuild(),
|
||||
APK_NAME,
|
||||
PACKAGE_NAME,
|
||||
configPath,
|
||||
true,
|
||||
vm_mem_mb,
|
||||
Optional.of(NUM_VCPUS));
|
||||
adbConnectToMicrodroid(getDevice(), cid);
|
||||
microdroidWaitForBootComplete();
|
||||
final String configPath = "assets/vm_config.json";
|
||||
final int vm_mem_mb = getFreeMemoryInfoMb(android) * 80 / 100;
|
||||
ITestDevice microdroidDevice =
|
||||
MicrodroidBuilder.fromDevicePath(getPathForPackage(PACKAGE_NAME), configPath)
|
||||
.debugLevel("full")
|
||||
.memoryMib(vm_mem_mb)
|
||||
.numCpus(NUM_VCPUS)
|
||||
.build(device);
|
||||
microdroidDevice.waitForBootComplete(30000);
|
||||
microdroidDevice.enableAdbRoot();
|
||||
|
||||
rootMicrodroid();
|
||||
CommandRunner microdroid = new CommandRunner(microdroidDevice);
|
||||
|
||||
runOnMicrodroid("mkdir -p /mnt/ramdisk && chmod 777 /mnt/ramdisk");
|
||||
runOnMicrodroid("mount -t tmpfs -o size=32G tmpfs /mnt/ramdisk");
|
||||
microdroid.run("mkdir -p /mnt/ramdisk && chmod 777 /mnt/ramdisk");
|
||||
microdroid.run("mount -t tmpfs -o size=32G tmpfs /mnt/ramdisk");
|
||||
|
||||
// Allocate memory for the VM until it fails and make sure that we touch
|
||||
// the allocated memory in the guest to be able to create stage2 fragmentation.
|
||||
try {
|
||||
runOnMicrodroidForResult(String.format("cd /mnt/ramdisk && truncate -s %dM sprayMemory"
|
||||
+ " && dd if=/dev/zero of=sprayMemory bs=1MB count=%d",
|
||||
vm_mem_mb , vm_mem_mb));
|
||||
microdroid.tryRun(
|
||||
String.format(
|
||||
"cd /mnt/ramdisk && truncate -s %dM sprayMemory"
|
||||
+ " && dd if=/dev/zero of=sprayMemory bs=1MB count=%d",
|
||||
vm_mem_mb, vm_mem_mb));
|
||||
} catch (Exception ex) {
|
||||
}
|
||||
|
||||
|
@ -273,7 +272,7 @@ public final class AVFHostTestCase extends MicrodroidHostTestCaseBase {
|
|||
metricColector.addStartupTimeMetricDuringVmRun(duringVmStartApp);
|
||||
}
|
||||
|
||||
shutdownMicrodroid(getDevice(), cid);
|
||||
device.shutdownMicrodroid(microdroidDevice);
|
||||
|
||||
// Run the app after the VM run and collect cold startup time.
|
||||
for (int i = 0; i < ROUND_COUNT; i++) {
|
||||
|
|
|
@ -38,13 +38,7 @@ import com.android.virt.VirtualizationTestHelper;
|
|||
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public abstract class MicrodroidHostTestCaseBase extends BaseHostJUnit4Test {
|
||||
protected static final String TEST_ROOT = "/data/local/tmp/virt/";
|
||||
|
@ -160,53 +154,12 @@ public abstract class MicrodroidHostTestCaseBase extends BaseHostJUnit4Test {
|
|||
return result.getStdout().trim();
|
||||
}
|
||||
|
||||
// Same as runOnMicrodroid, but keeps retrying on error for maximum attempts times
|
||||
// Each attempt with timeoutMs
|
||||
public static String runOnMicrodroidRetryingOnFailure(
|
||||
long timeoutMs, int attempts, String... cmd) {
|
||||
CommandResult result = RunUtil.getDefault()
|
||||
.runTimedCmdRetry(timeoutMs, MICRODROID_COMMAND_RETRY_INTERVAL_MILLIS, attempts,
|
||||
"adb", "-s", MICRODROID_SERIAL, "shell", join(cmd));
|
||||
assertWithMessage("Command `" + Arrays.toString(cmd) + "` has failed")
|
||||
.about(command_results())
|
||||
.that(result)
|
||||
.isSuccess();
|
||||
return result.getStdout().trim();
|
||||
}
|
||||
|
||||
public static CommandResult runOnMicrodroidForResult(String... cmd) {
|
||||
final long timeoutMs = 30000; // 30 sec. Microdroid is extremely slow on GCE-on-CF.
|
||||
return RunUtil.getDefault()
|
||||
.runTimedCmd(timeoutMs, "adb", "-s", MICRODROID_SERIAL, "shell", join(cmd));
|
||||
}
|
||||
|
||||
public static void pullMicrodroidFile(String path, File target) {
|
||||
final long timeoutMs = 30000; // 30 sec. Microdroid is extremely slow on GCE-on-CF.
|
||||
CommandResult result =
|
||||
RunUtil.getDefault()
|
||||
.runTimedCmd(
|
||||
timeoutMs,
|
||||
"adb",
|
||||
"-s",
|
||||
MICRODROID_SERIAL,
|
||||
"pull",
|
||||
path,
|
||||
target.getPath());
|
||||
assertWithMessage("pulling " + path + " from microdroid")
|
||||
.about(command_results())
|
||||
.that(result)
|
||||
.isSuccess();
|
||||
}
|
||||
|
||||
// Asserts the command will fail on Microdroid.
|
||||
public static void assertFailedOnMicrodroid(String... cmd) {
|
||||
CommandResult result = runOnMicrodroidForResult(cmd);
|
||||
assertWithMessage("Microdroid command `" + join(cmd) + "` did not fail expectedly")
|
||||
.about(command_results())
|
||||
.that(result)
|
||||
.isFailed();
|
||||
}
|
||||
|
||||
private static String join(String... strs) {
|
||||
return String.join(" ", Arrays.asList(strs));
|
||||
}
|
||||
|
@ -240,36 +193,6 @@ public abstract class MicrodroidHostTestCaseBase extends BaseHostJUnit4Test {
|
|||
return pathLine.substring("package:".length());
|
||||
}
|
||||
|
||||
public static String startMicrodroid(
|
||||
ITestDevice androidDevice,
|
||||
IBuildInfo buildInfo,
|
||||
String apkName,
|
||||
String packageName,
|
||||
String configPath,
|
||||
boolean debug,
|
||||
int memoryMib,
|
||||
Optional<Integer> numCpus)
|
||||
throws DeviceNotAvailableException {
|
||||
return startMicrodroid(androidDevice, buildInfo, apkName, packageName, null, configPath,
|
||||
debug, memoryMib, numCpus);
|
||||
}
|
||||
|
||||
public static String startMicrodroid(
|
||||
ITestDevice androidDevice,
|
||||
IBuildInfo buildInfo,
|
||||
String apkName,
|
||||
String packageName,
|
||||
String[] extraIdsigPaths,
|
||||
String configPath,
|
||||
boolean debug,
|
||||
int memoryMib,
|
||||
Optional<Integer> numCpus)
|
||||
throws DeviceNotAvailableException {
|
||||
return startMicrodroid(androidDevice, buildInfo, apkName, null, packageName,
|
||||
extraIdsigPaths, configPath, debug,
|
||||
memoryMib, numCpus);
|
||||
}
|
||||
|
||||
private static void forwardFileToLog(CommandRunner android, String path, String tag)
|
||||
throws DeviceNotAvailableException {
|
||||
android.runWithTimeout(
|
||||
|
@ -281,93 +204,6 @@ public abstract class MicrodroidHostTestCaseBase extends BaseHostJUnit4Test {
|
|||
+ " | sed \\'s/^/" + tag + ": /g\\''\""); // add tags in front of lines
|
||||
}
|
||||
|
||||
public static String startMicrodroid(
|
||||
ITestDevice androidDevice,
|
||||
IBuildInfo buildInfo,
|
||||
String apkName,
|
||||
String apkPath,
|
||||
String packageName,
|
||||
String[] extraIdsigPaths,
|
||||
String configPath,
|
||||
boolean debug,
|
||||
int memoryMib,
|
||||
Optional<Integer> numCpus)
|
||||
throws DeviceNotAvailableException {
|
||||
CommandRunner android = new CommandRunner(androidDevice);
|
||||
|
||||
// Install APK if necessary
|
||||
if (apkName != null) {
|
||||
File apkFile = findTestFile(buildInfo, apkName);
|
||||
androidDevice.installPackage(apkFile, /* reinstall */ true);
|
||||
}
|
||||
|
||||
if (apkPath == null) {
|
||||
apkPath = getPathForPackage(androidDevice, packageName);
|
||||
}
|
||||
|
||||
android.run("mkdir", "-p", TEST_ROOT);
|
||||
|
||||
// This file is not what we provide. It will be created by the vm tool.
|
||||
final String outApkIdsigPath = TEST_ROOT + apkName + ".idsig";
|
||||
|
||||
final String instanceImg = TEST_ROOT + INSTANCE_IMG;
|
||||
final String logPath = LOG_PATH;
|
||||
final String consolePath = CONSOLE_PATH;
|
||||
final String debugFlag = debug ? "--debug full" : "";
|
||||
|
||||
// Run the VM
|
||||
ArrayList<String> args = new ArrayList<>(Arrays.asList(
|
||||
VIRT_APEX + "bin/vm",
|
||||
"run-app",
|
||||
"--daemonize",
|
||||
"--log " + logPath,
|
||||
"--console " + consolePath,
|
||||
"--mem " + memoryMib,
|
||||
numCpus.isPresent() ? "--cpus " + numCpus.get() : "",
|
||||
debugFlag,
|
||||
apkPath,
|
||||
outApkIdsigPath,
|
||||
instanceImg,
|
||||
configPath));
|
||||
if (extraIdsigPaths != null) {
|
||||
for (String path : extraIdsigPaths) {
|
||||
args.add("--extra-idsig");
|
||||
args.add(path);
|
||||
}
|
||||
}
|
||||
String ret = android.run(args.toArray(new String[0]));
|
||||
|
||||
// Redirect log.txt and console.txt to logd using logwrapper
|
||||
// Keep redirecting as long as the expecting maximum test time. When an adb
|
||||
// command times out, it may trigger the device recovery process, which
|
||||
// disconnect adb, which terminates any live adb commands. See an example at
|
||||
// b/194974010#comment25.
|
||||
ExecutorService executor = Executors.newFixedThreadPool(2);
|
||||
executor.execute(
|
||||
() -> {
|
||||
try {
|
||||
forwardFileToLog(android, logPath, "MicrodroidLog");
|
||||
} catch (Exception e) {
|
||||
// Consume
|
||||
}
|
||||
});
|
||||
|
||||
executor.execute(
|
||||
() -> {
|
||||
try {
|
||||
forwardFileToLog(android, consolePath, "MicrodroidConsole");
|
||||
} catch (Exception e) {
|
||||
// Consume
|
||||
}
|
||||
});
|
||||
|
||||
// Retrieve the CID from the vm tool output
|
||||
Pattern pattern = Pattern.compile("with CID (\\d+)");
|
||||
Matcher matcher = pattern.matcher(ret);
|
||||
assertWithMessage("Failed to find CID").that(matcher.find()).isTrue();
|
||||
return matcher.group(1);
|
||||
}
|
||||
|
||||
public static void shutdownMicrodroid(ITestDevice androidDevice, String cid)
|
||||
throws DeviceNotAvailableException {
|
||||
CommandRunner android = new CommandRunner(androidDevice);
|
||||
|
@ -376,17 +212,6 @@ public abstract class MicrodroidHostTestCaseBase extends BaseHostJUnit4Test {
|
|||
android.run(VIRT_APEX + "bin/vm", "stop", cid);
|
||||
}
|
||||
|
||||
public static void rootMicrodroid() throws InterruptedException {
|
||||
runOnHostRetryingOnFailure(MICRODROID_COMMAND_TIMEOUT_MILLIS,
|
||||
MICRODROID_ADB_CONNECT_MAX_ATTEMPTS, "adb", "-s", MICRODROID_SERIAL, "root");
|
||||
// adbd reboots after root. Some commands (including wait-for-device) following this fails
|
||||
// with error: closed. Hence, we disconnect and re-connect to the device before returning.
|
||||
runOnHostRetryingOnFailure(MICRODROID_COMMAND_TIMEOUT_MILLIS,
|
||||
MICRODROID_ADB_CONNECT_MAX_ATTEMPTS, "adb", "disconnect", MICRODROID_SERIAL);
|
||||
runOnHostRetryingOnFailure(MICRODROID_COMMAND_TIMEOUT_MILLIS,
|
||||
MICRODROID_ADB_CONNECT_MAX_ATTEMPTS, "adb", "connect", MICRODROID_SERIAL);
|
||||
}
|
||||
|
||||
// Establish an adb connection to microdroid by letting Android forward the connection to
|
||||
// microdroid. Wait until the connection is established and microdroid is booted.
|
||||
public static void adbConnectToMicrodroid(ITestDevice androidDevice, String cid) {
|
||||
|
|
|
@ -17,12 +17,14 @@
|
|||
package com.android.microdroid.test;
|
||||
|
||||
import static com.android.microdroid.test.host.CommandResultSubject.command_results;
|
||||
import static com.android.tradefed.device.TestDevice.MicrodroidBuilder;
|
||||
import static com.android.tradefed.testtype.DeviceJUnit4ClassRunner.TestLogData;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
import static com.google.common.truth.Truth.assertWithMessage;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assume.assumeTrue;
|
||||
|
||||
|
@ -38,6 +40,8 @@ import com.android.microdroid.test.host.MicrodroidHostTestCaseBase;
|
|||
import com.android.os.AtomsProto;
|
||||
import com.android.os.StatsLog;
|
||||
import com.android.tradefed.device.DeviceNotAvailableException;
|
||||
import com.android.tradefed.device.ITestDevice;
|
||||
import com.android.tradefed.device.TestDevice;
|
||||
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
|
||||
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner.TestMetrics;
|
||||
import com.android.tradefed.util.CommandResult;
|
||||
|
@ -64,8 +68,8 @@ import java.io.IOException;
|
|||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.Callable;
|
||||
import java.util.function.Function;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
|
@ -81,12 +85,16 @@ public class MicrodroidHostTests extends MicrodroidHostTestCaseBase {
|
|||
// Number of vCPUs for testing purpose
|
||||
private static final int NUM_VCPUS = 3;
|
||||
|
||||
private static final int BOOT_COMPLETE_TIMEOUT = 30000; // 30 seconds
|
||||
|
||||
@Rule public TestLogData mTestLogs = new TestLogData();
|
||||
@Rule public TestName mTestName = new TestName();
|
||||
@Rule public TestMetrics mMetrics = new TestMetrics();
|
||||
|
||||
private String mMetricPrefix;
|
||||
|
||||
private ITestDevice mMicrodroidDevice;
|
||||
|
||||
private int minMemorySize() throws DeviceNotAvailableException {
|
||||
CommandRunner android = new CommandRunner(getDevice());
|
||||
String abi = android.run("getprop", "ro.product.cpu.abi");
|
||||
|
@ -99,10 +107,6 @@ public class MicrodroidHostTests extends MicrodroidHostTestCaseBase {
|
|||
throw new AssertionError("Unsupported ABI: " + abi);
|
||||
}
|
||||
|
||||
private void waitForBootComplete() {
|
||||
runOnMicrodroidForResult("watch -e \"getprop dev.bootcomplete | grep '^0$'\"");
|
||||
}
|
||||
|
||||
private static JSONObject newPartition(String label, String path) {
|
||||
return new JSONObject(Map.of("label", label, "path", path));
|
||||
}
|
||||
|
@ -447,16 +451,18 @@ public class MicrodroidHostTests extends MicrodroidHostTestCaseBase {
|
|||
private boolean isTombstoneGeneratedWithConfig(String configPath) throws Exception {
|
||||
// Note this test relies on logcat values being printed by tombstone_transmit on
|
||||
// and the reeceiver on host (virtualization_service)
|
||||
final String cid =
|
||||
startMicrodroid(
|
||||
getDevice(),
|
||||
getBuild(),
|
||||
APK_NAME,
|
||||
PACKAGE_NAME,
|
||||
configPath,
|
||||
/* debug */ true,
|
||||
minMemorySize(),
|
||||
Optional.of(NUM_VCPUS));
|
||||
mMicrodroidDevice = MicrodroidBuilder
|
||||
.fromDevicePath(getPathForPackage(PACKAGE_NAME), configPath)
|
||||
.debugLevel("full")
|
||||
.memoryMib(minMemorySize())
|
||||
.numCpus(NUM_VCPUS)
|
||||
.build((TestDevice) getDevice());
|
||||
mMicrodroidDevice.waitForBootComplete(BOOT_COMPLETE_TIMEOUT);
|
||||
mMicrodroidDevice.enableAdbRoot();
|
||||
|
||||
CommandRunner microdroid = new CommandRunner(mMicrodroidDevice);
|
||||
microdroid.run("kill", "-SIGSEGV", "$(pidof microdroid_launcher)");
|
||||
|
||||
// check until microdroid is shut down
|
||||
CommandRunner android = new CommandRunner(getDevice());
|
||||
android.runWithTimeout(15000, "logcat", "-m", "1", "-e", "'crosvm has exited normally'");
|
||||
|
@ -499,22 +505,28 @@ public class MicrodroidHostTests extends MicrodroidHostTestCaseBase {
|
|||
ConfigUtils.uploadConfigForPushedAtoms(getDevice(), PACKAGE_NAME, atomIds);
|
||||
|
||||
// Create VM with microdroid
|
||||
TestDevice device = (TestDevice) getDevice();
|
||||
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));
|
||||
ITestDevice microdroid =
|
||||
MicrodroidBuilder.fromDevicePath(getPathForPackage(PACKAGE_NAME), configPath)
|
||||
.debugLevel("full")
|
||||
.memoryMib(minMemorySize())
|
||||
.numCpus(NUM_VCPUS)
|
||||
.build(device);
|
||||
microdroid.waitForBootComplete(BOOT_COMPLETE_TIMEOUT);
|
||||
device.shutdownMicrodroid(microdroid);
|
||||
|
||||
// Check VmCreationRequested atom and clear the statsd report
|
||||
List<StatsLog.EventMetricData> data;
|
||||
data = ReportUtils.getEventMetricDataList(getDevice());
|
||||
assertThat(data).hasSize(1);
|
||||
List<StatsLog.EventMetricData> data = new ArrayList<>();
|
||||
assertThatEventually(
|
||||
10000,
|
||||
() -> {
|
||||
data.addAll(ReportUtils.getEventMetricDataList(getDevice()));
|
||||
return data.size();
|
||||
},
|
||||
is(3)
|
||||
);
|
||||
|
||||
// Check VmCreationRequested atom
|
||||
assertThat(data.get(0).getAtom().getPushedCase().getNumber()).isEqualTo(
|
||||
AtomsProto.Atom.VM_CREATION_REQUESTED_FIELD_NUMBER);
|
||||
AtomsProto.VmCreationRequested atomVmCreationRequested =
|
||||
|
@ -532,29 +544,16 @@ public class MicrodroidHostTests extends MicrodroidHostTestCaseBase {
|
|||
assertThat(atomVmCreationRequested.getApexes())
|
||||
.isEqualTo("com.android.art:com.android.compos:com.android.sdkext");
|
||||
|
||||
// Boot VM with microdroid
|
||||
adbConnectToMicrodroid(getDevice(), cid);
|
||||
waitForBootComplete();
|
||||
|
||||
// Check VmBooted atom and clear the statsd report
|
||||
data = ReportUtils.getEventMetricDataList(getDevice());
|
||||
assertThat(data).hasSize(1);
|
||||
assertThat(data.get(0).getAtom().getPushedCase().getNumber())
|
||||
// Check VmBooted atom
|
||||
assertThat(data.get(1).getAtom().getPushedCase().getNumber())
|
||||
.isEqualTo(AtomsProto.Atom.VM_BOOTED_FIELD_NUMBER);
|
||||
AtomsProto.VmBooted atomVmBooted = data.get(0).getAtom().getVmBooted();
|
||||
AtomsProto.VmBooted atomVmBooted = data.get(1).getAtom().getVmBooted();
|
||||
assertThat(atomVmBooted.getVmIdentifier()).isEqualTo("VmRunApp");
|
||||
|
||||
// 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());
|
||||
assertThat(data).hasSize(1);
|
||||
assertThat(data.get(0).getAtom().getPushedCase().getNumber())
|
||||
// Check VmExited atom
|
||||
assertThat(data.get(2).getAtom().getPushedCase().getNumber())
|
||||
.isEqualTo(AtomsProto.Atom.VM_EXITED_FIELD_NUMBER);
|
||||
AtomsProto.VmExited atomVmExited = data.get(0).getAtom().getVmExited();
|
||||
AtomsProto.VmExited atomVmExited = data.get(2).getAtom().getVmExited();
|
||||
assertThat(atomVmExited.getVmIdentifier()).isEqualTo("VmRunApp");
|
||||
assertThat(atomVmExited.getDeathReason()).isEqualTo(AtomsProto.VmExited.DeathReason.KILLED);
|
||||
|
||||
|
@ -569,54 +568,49 @@ public class MicrodroidHostTests extends MicrodroidHostTestCaseBase {
|
|||
@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
|
||||
final String cid =
|
||||
startMicrodroid(
|
||||
getDevice(),
|
||||
getBuild(),
|
||||
APK_NAME,
|
||||
PACKAGE_NAME,
|
||||
configPath,
|
||||
/* debug */ true,
|
||||
minMemorySize(),
|
||||
Optional.of(NUM_VCPUS));
|
||||
adbConnectToMicrodroid(getDevice(), cid);
|
||||
waitForBootComplete();
|
||||
mMicrodroidDevice =
|
||||
MicrodroidBuilder.fromDevicePath(getPathForPackage(PACKAGE_NAME), configPath)
|
||||
.debugLevel("full")
|
||||
.memoryMib(minMemorySize())
|
||||
.numCpus(NUM_VCPUS)
|
||||
.build((TestDevice) getDevice());
|
||||
mMicrodroidDevice.waitForBootComplete(BOOT_COMPLETE_TIMEOUT);
|
||||
CommandRunner microdroid = new CommandRunner(mMicrodroidDevice);
|
||||
|
||||
// Test writing to /data partition
|
||||
runOnMicrodroid("echo MicrodroidTest > /data/local/tmp/test.txt");
|
||||
assertThat(runOnMicrodroid("cat /data/local/tmp/test.txt")).isEqualTo("MicrodroidTest");
|
||||
microdroid.run("echo MicrodroidTest > /data/local/tmp/test.txt");
|
||||
assertThat(microdroid.run("cat /data/local/tmp/test.txt")).isEqualTo("MicrodroidTest");
|
||||
|
||||
// Check if the APK & its idsig partitions exist
|
||||
final String apkPartition = "/dev/block/by-name/microdroid-apk";
|
||||
assertThat(runOnMicrodroid("ls", apkPartition)).isEqualTo(apkPartition);
|
||||
assertThat(microdroid.run("ls", apkPartition)).isEqualTo(apkPartition);
|
||||
final String apkIdsigPartition = "/dev/block/by-name/microdroid-apk-idsig";
|
||||
assertThat(runOnMicrodroid("ls", apkIdsigPartition)).isEqualTo(apkIdsigPartition);
|
||||
assertThat(microdroid.run("ls", apkIdsigPartition)).isEqualTo(apkIdsigPartition);
|
||||
// Check the vm-instance partition as well
|
||||
final String vmInstancePartition = "/dev/block/by-name/vm-instance";
|
||||
assertThat(runOnMicrodroid("ls", vmInstancePartition)).isEqualTo(vmInstancePartition);
|
||||
assertThat(microdroid.run("ls", vmInstancePartition)).isEqualTo(vmInstancePartition);
|
||||
|
||||
// Check if the native library in the APK is has correct filesystem info
|
||||
final String[] abis = runOnMicrodroid("getprop", "ro.product.cpu.abilist").split(",");
|
||||
final String[] abis = microdroid.run("getprop", "ro.product.cpu.abilist").split(",");
|
||||
assertThat(abis).hasLength(1);
|
||||
final String testLib = "/mnt/apk/lib/" + abis[0] + "/MicrodroidTestNativeLib.so";
|
||||
final String label = "u:object_r:system_file:s0";
|
||||
assertThat(runOnMicrodroid("ls", "-Z", testLib)).isEqualTo(label + " " + testLib);
|
||||
assertThat(microdroid.run("ls", "-Z", testLib)).isEqualTo(label + " " + testLib);
|
||||
|
||||
// Check that no denials have happened so far
|
||||
CommandRunner android = new CommandRunner(getDevice());
|
||||
assertThat(android.tryRun("egrep", "'avc:[[:space:]]{1,2}denied'", LOG_PATH)).isNull();
|
||||
|
||||
assertThat(runOnMicrodroid("cat /proc/cpuinfo | grep processor | wc -l"))
|
||||
assertThat(microdroid.run("cat /proc/cpuinfo | grep processor | wc -l"))
|
||||
.isEqualTo(Integer.toString(NUM_VCPUS));
|
||||
|
||||
// Check that selinux is enabled
|
||||
assertThat(runOnMicrodroid("getenforce")).isEqualTo("Enforcing");
|
||||
assertThat(microdroid.run("getenforce")).isEqualTo("Enforcing");
|
||||
|
||||
// TODO(b/176805428): adb is broken for nested VM
|
||||
if (!isCuttlefish()) {
|
||||
// Check neverallow rules on microdroid
|
||||
File policyFile = FileUtil.createTempFile("microdroid_sepolicy", "");
|
||||
pullMicrodroidFile("/sys/fs/selinux/policy", policyFile);
|
||||
|
||||
File policyFile = mMicrodroidDevice.pullFile("/sys/fs/selinux/policy");
|
||||
File generalPolicyConfFile = findTestFile("microdroid_general_sepolicy.conf");
|
||||
File sepolicyAnalyzeBin = findTestFile("sepolicy-analyze");
|
||||
|
||||
|
@ -635,38 +629,41 @@ public class MicrodroidHostTests extends MicrodroidHostTestCaseBase {
|
|||
.that(result)
|
||||
.isSuccess();
|
||||
}
|
||||
|
||||
shutdownMicrodroid(getDevice(), cid);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMicrodroidRamUsage() throws Exception {
|
||||
final String configPath = "assets/vm_config.json";
|
||||
final String cid =
|
||||
startMicrodroid(
|
||||
getDevice(),
|
||||
getBuild(),
|
||||
APK_NAME,
|
||||
PACKAGE_NAME,
|
||||
configPath,
|
||||
/* debug */ true,
|
||||
minMemorySize(),
|
||||
Optional.of(NUM_VCPUS));
|
||||
adbConnectToMicrodroid(getDevice(), cid);
|
||||
waitForBootComplete();
|
||||
rootMicrodroid();
|
||||
mMicrodroidDevice = MicrodroidBuilder
|
||||
.fromDevicePath(getPathForPackage(PACKAGE_NAME), configPath)
|
||||
.debugLevel("full")
|
||||
.memoryMib(minMemorySize())
|
||||
.numCpus(NUM_VCPUS)
|
||||
.build((TestDevice) getDevice());
|
||||
mMicrodroidDevice.waitForBootComplete(BOOT_COMPLETE_TIMEOUT);
|
||||
mMicrodroidDevice.enableAdbRoot();
|
||||
|
||||
CommandRunner microdroid = new CommandRunner(mMicrodroidDevice);
|
||||
Function<String, String> microdroidExec =
|
||||
(cmd) -> {
|
||||
try {
|
||||
return microdroid.run(cmd);
|
||||
} catch (Exception ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
};
|
||||
|
||||
for (Map.Entry<String, Long> stat :
|
||||
ProcessUtil.getProcessMemoryMap(cmd -> runOnMicrodroid(cmd)).entrySet()) {
|
||||
ProcessUtil.getProcessMemoryMap(microdroidExec).entrySet()) {
|
||||
mMetrics.addTestMetric(
|
||||
mMetricPrefix + "meminfo/" + stat.getKey().toLowerCase(),
|
||||
stat.getValue().toString());
|
||||
}
|
||||
|
||||
for (Map.Entry<Integer, String> proc :
|
||||
ProcessUtil.getProcessMap(cmd -> runOnMicrodroid(cmd)).entrySet()) {
|
||||
ProcessUtil.getProcessMap(microdroidExec).entrySet()) {
|
||||
for (Map.Entry<String, Long> stat :
|
||||
ProcessUtil.getProcessSmapsRollup(proc.getKey(), cmd -> runOnMicrodroid(cmd))
|
||||
ProcessUtil.getProcessSmapsRollup(proc.getKey(), microdroidExec)
|
||||
.entrySet()) {
|
||||
String name = stat.getKey().toLowerCase();
|
||||
mMetrics.addTestMetric(
|
||||
|
@ -674,8 +671,6 @@ public class MicrodroidHostTests extends MicrodroidHostTestCaseBase {
|
|||
stat.getValue().toString());
|
||||
}
|
||||
}
|
||||
|
||||
shutdownMicrodroid(getDevice(), cid);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -717,6 +712,7 @@ public class MicrodroidHostTests extends MicrodroidHostTestCaseBase {
|
|||
public void setUp() throws Exception {
|
||||
testIfDeviceIsCapable(getDevice());
|
||||
mMetricPrefix = getMetricPrefix() + "microdroid/";
|
||||
mMicrodroidDevice = null;
|
||||
|
||||
prepareVirtualizationTestSetup(getDevice());
|
||||
|
||||
|
@ -728,6 +724,10 @@ public class MicrodroidHostTests extends MicrodroidHostTestCaseBase {
|
|||
|
||||
@After
|
||||
public void shutdown() throws Exception {
|
||||
if (mMicrodroidDevice != null) {
|
||||
((TestDevice) getDevice()).shutdownMicrodroid(mMicrodroidDevice);
|
||||
}
|
||||
|
||||
cleanUpVirtualizationTestSetup(getDevice());
|
||||
|
||||
archiveLogThenDelete(
|
||||
|
|
|
@ -22,7 +22,7 @@ android_test {
|
|||
libs: ["android.system.virtualmachine"],
|
||||
jni_libs: [
|
||||
"MicrodroidTestNativeLib",
|
||||
"MicrodroidTestNativeCrashLib",
|
||||
"MicrodroidIdleNativeLib",
|
||||
],
|
||||
platform_apis: true,
|
||||
use_embedded_native_libs: true,
|
||||
|
@ -50,13 +50,6 @@ cc_library_shared {
|
|||
],
|
||||
}
|
||||
|
||||
cc_library_shared {
|
||||
name: "MicrodroidTestNativeCrashLib",
|
||||
header_libs: ["vm_payload_headers"],
|
||||
srcs: ["src/native/crashbinary.cpp"],
|
||||
stl: "libc++_static",
|
||||
}
|
||||
|
||||
cc_library_shared {
|
||||
name: "MicrodroidTestNativeLibSub",
|
||||
srcs: ["src/native/testlib.cpp"],
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
},
|
||||
"task": {
|
||||
"type": "microdroid_launcher",
|
||||
"command": "MicrodroidTestNativeCrashLib.so"
|
||||
"command": "MicrodroidIdleNativeLib.so"
|
||||
},
|
||||
"export_tombstones": true
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
},
|
||||
"task": {
|
||||
"type": "microdroid_launcher",
|
||||
"command": "MicrodroidTestNativeCrashLib.so"
|
||||
"command": "MicrodroidIdleNativeLib.so"
|
||||
},
|
||||
"export_tombstones": false
|
||||
}
|
||||
|
|
|
@ -1,26 +0,0 @@
|
|||
/*
|
||||
* Copyright 2022 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.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "vm_main.h"
|
||||
|
||||
// A VM payload that crashes as soon as it starts, to allow us to exercise that error path.
|
||||
extern "C" int AVmPayload_main() {
|
||||
printf("test crash!!!!\n");
|
||||
abort();
|
||||
}
|
Loading…
Reference in New Issue