Merge "Clean up on test failure" into main
diff --git a/tests/hostside/java/com/android/microdroid/test/MicrodroidHostTests.java b/tests/hostside/java/com/android/microdroid/test/MicrodroidHostTests.java
index deaf08a..092325e 100644
--- a/tests/hostside/java/com/android/microdroid/test/MicrodroidHostTests.java
+++ b/tests/hostside/java/com/android/microdroid/test/MicrodroidHostTests.java
@@ -42,7 +42,6 @@
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.testtype.DeviceJUnit4ClassRunner.TestMetrics;
import com.android.tradefed.util.CommandResult;
@@ -62,12 +61,8 @@
import org.xml.sax.Attributes;
import org.xml.sax.helpers.DefaultHandler;
-import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.util.ArrayList;
@@ -75,7 +70,6 @@
import java.util.Collections;
import java.util.List;
import java.util.Map;
-import java.util.Optional;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
@@ -95,15 +89,11 @@
private static final int BOOT_COMPLETE_TIMEOUT = 30000; // 30 seconds
- private static final Pattern sCIDPattern = Pattern.compile("with CID (\\d+)");
-
private static class VmInfo {
final Process mProcess;
- final String mCid;
- VmInfo(Process process, String cid) {
+ VmInfo(Process process) {
mProcess = process;
- mCid = cid;
}
}
@@ -376,44 +366,14 @@
PipedInputStream pis = new PipedInputStream();
Process process = RunUtil.getDefault().runCmdInBackground(args, new PipedOutputStream(pis));
- return new VmInfo(process, extractCidFrom(pis));
- }
-
- private static Optional<String> tryExtractCidFrom(String str) {
- Matcher matcher = sCIDPattern.matcher(str);
- if (matcher.find()) {
- return Optional.of(matcher.group(1));
- }
- return Optional.empty();
- }
-
- private static String extractCidFrom(InputStream input) throws IOException {
- String cid = null;
- String line;
- try (BufferedReader out = new BufferedReader(new InputStreamReader(input))) {
- while ((line = out.readLine()) != null) {
- CLog.i("VM output: " + line);
- Optional<String> result = tryExtractCidFrom(line);
- if (result.isPresent()) {
- cid = result.get();
- break;
- }
- }
- }
- assertWithMessage("The output does not contain the expected pattern for CID.")
- .that(cid)
- .isNotNull();
- return cid;
+ return new VmInfo(process);
}
@Test
@CddTest(requirements = {"9.17/C-2-1", "9.17/C-2-2", "9.17/C-2-6"})
public void protectedVmRunsPvmfw() throws Exception {
// Arrange
- boolean protectedVm = true;
- assumeTrue(
- "Skip if protected VMs are not supported",
- getAndroidDevice().supportsMicrodroid(protectedVm));
+ assumeProtectedVmSupported();
final String configPath = "assets/vm_config_apex.json";
// Act
@@ -422,7 +382,7 @@
.debugLevel("full")
.memoryMib(minMemorySize())
.cpuTopology("match_host")
- .protectedVm(protectedVm)
+ .protectedVm(true)
.build(getAndroidDevice());
// Assert
@@ -441,16 +401,16 @@
@CddTest(requirements = {"9.17/C-2-1", "9.17/C-2-2", "9.17/C-2-6"})
public void protectedVmWithImageSignedWithDifferentKeyRunsPvmfw() throws Exception {
// Arrange
- boolean protectedVm = true;
- assumeTrue(
- "Skip if protected VMs are not supported",
- getAndroidDevice().supportsMicrodroid(protectedVm));
+ assumeProtectedVmSupported();
File key = findTestFile("test.com.android.virt.pem");
// Act
VmInfo vmInfo =
runMicrodroidWithResignedImages(
- key, /*keyOverrides=*/ Map.of(), protectedVm, /*updateBootconfigs=*/ true);
+ key,
+ /*keyOverrides=*/ Map.of(),
+ /*isProtected=*/ true,
+ /*updateBootconfigs=*/ true);
// Assert
vmInfo.mProcess.waitFor(5L, TimeUnit.SECONDS);
@@ -465,6 +425,7 @@
@CddTest(requirements = {"9.17/C-2-2", "9.17/C-2-6"})
public void testBootSucceedsWhenNonProtectedVmStartsWithImagesSignedWithDifferentKey()
throws Exception {
+ assumeNonProtectedVmSupported();
File key = findTestFile("test.com.android.virt.pem");
Map<String, File> keyOverrides = Map.of();
VmInfo vmInfo =
@@ -481,6 +442,8 @@
@Test
@CddTest(requirements = {"9.17/C-2-2", "9.17/C-2-6"})
public void testBootFailsWhenVbMetaDigestDoesNotMatchBootconfig() throws Exception {
+ // protectedVmWithImageSignedWithDifferentKeyRunsPvmfw() is the protected case.
+ assumeNonProtectedVmSupported();
// Sign everything with key1 except vbmeta
File key = findTestFile("test.com.android.virt.pem");
// To be able to stop it, it should be a daemon.
@@ -558,10 +521,22 @@
}
@Test
- public void testTombstonesAreGeneratedUponUserspaceCrash() throws Exception {
+ public void testTombstonesAreGeneratedUponUserspaceCrashOnNonPvm() throws Exception {
+ assumeNonProtectedVmSupported();
+ testTombstonesAreGeneratedUponUserspaceCrash(false);
+ }
+
+ @Test
+ public void testTombstonesAreGeneratedUponUserspaceCrashOnPvm() throws Exception {
+ assumeProtectedVmSupported();
+ testTombstonesAreGeneratedUponUserspaceCrash(true);
+ }
+
+ private void testTombstonesAreGeneratedUponUserspaceCrash(boolean protectedVm)
+ throws Exception {
assertThat(
isTombstoneGeneratedWithCmd(
- false,
+ protectedVm,
"assets/vm_config.json",
"kill",
"-SIGSEGV",
@@ -570,10 +545,24 @@
}
@Test
- public void testTombstonesAreNotGeneratedIfNotExportedUponUserspaceCrash() throws Exception {
+ public void testTombstonesAreNotGeneratedIfNotExportedUponUserspaceCrashOnNonPvm()
+ throws Exception {
+ assumeNonProtectedVmSupported();
+ testTombstonesAreNotGeneratedIfNotExportedUponUserspaceCrash(false);
+ }
+
+ @Test
+ public void testTombstonesAreNotGeneratedIfNotExportedUponUserspaceCrashOnPvm()
+ throws Exception {
+ assumeProtectedVmSupported();
+ testTombstonesAreNotGeneratedIfNotExportedUponUserspaceCrash(true);
+ }
+
+ private void testTombstonesAreNotGeneratedIfNotExportedUponUserspaceCrash(boolean protectedVm)
+ throws Exception {
assertThat(
isTombstoneGeneratedWithCmd(
- false,
+ protectedVm,
"assets/vm_config_no_tombstone.json",
"kill",
"-SIGSEGV",
@@ -597,19 +586,18 @@
@Test
public void testTombstonesAreGeneratedUponKernelCrashOnNonPvm() throws Exception {
- testTombstonesAreGeneratedUponKernelCrash(false);
+ assumeNonProtectedVmSupported();
+ testTombstonesAreGeneratedUponKernelCrash(/* protectedVm=*/ false);
}
@Test
public void testTombstonesAreGeneratedUponKernelCrashOnPvm() throws Exception {
- assumeTrue(
- "Protected VMs are not supported",
- getAndroidDevice().supportsMicrodroid(/*protectedVm=*/ true));
- testTombstonesAreGeneratedUponKernelCrash(true);
+ assumeProtectedVmSupported();
+ testTombstonesAreGeneratedUponKernelCrash(/* protectedVm=*/ true);
}
- private boolean isTombstoneGeneratedWithVmRunApp(boolean debuggable, String... additionalArgs)
- throws Exception {
+ private boolean isTombstoneGeneratedWithVmRunApp(
+ boolean protectedVm, boolean debuggable, String... additionalArgs) throws Exception {
// we can't use microdroid builder as it wants ADB connection (debuggable)
CommandRunner android = new CommandRunner(getDevice());
String testStartTime = android.runWithTimeout(1000, "date", "'+%Y-%m-%d %H:%M:%S.%N'");
@@ -630,44 +618,114 @@
apkPath,
idsigPath,
instanceImgPath));
+ if (protectedVm) {
+ cmd.add("--protected");
+ }
Collections.addAll(cmd, additionalArgs);
android.run(cmd.toArray(new String[0]));
return isTombstoneReceivedFromHostLogcat(testStartTime);
}
- private boolean isTombstoneGeneratedWithCrashPayload(boolean debuggable) throws Exception {
+ private boolean isTombstoneGeneratedWithCrashPayload(boolean protectedVm, boolean debuggable)
+ throws Exception {
return isTombstoneGeneratedWithVmRunApp(
- debuggable, "--payload-binary-name", "MicrodroidCrashNativeLib.so");
+ protectedVm, debuggable, "--payload-binary-name", "MicrodroidCrashNativeLib.so");
}
@Test
- public void testTombstonesAreGeneratedWithCrashPayload() throws Exception {
- assertThat(isTombstoneGeneratedWithCrashPayload(true /* debuggable */)).isTrue();
+ public void testTombstonesAreGeneratedWithCrashPayloadOnPvm() throws Exception {
+ assumeProtectedVmSupported();
+ assertThat(
+ isTombstoneGeneratedWithCrashPayload(
+ /*protectedVm=*/ true, /*debuggable=*/ true))
+ .isTrue();
}
@Test
- public void testTombstonesAreNotGeneratedWithCrashPayloadWhenNonDebuggable() throws Exception {
- assertThat(isTombstoneGeneratedWithCrashPayload(false /* debuggable */)).isFalse();
+ public void testTombstonesAreGeneratedWithCrashPayloadOnNonPvm() throws Exception {
+ assumeNonProtectedVmSupported();
+ assertThat(
+ isTombstoneGeneratedWithCrashPayload(
+ /*protectedVm=*/ false, /*debuggable=*/ true))
+ .isTrue();
}
- private boolean isTombstoneGeneratedWithCrashConfig(boolean debuggable) throws Exception {
+ @Test
+ public void testTombstonesAreNotGeneratedWithCrashPayloadWhenNonDebuggableOnPvm()
+ throws Exception {
+ assumeProtectedVmSupported();
+ assertThat(
+ isTombstoneGeneratedWithCrashPayload(
+ /*protectedVm=*/ true, /*debuggable=*/ false))
+ .isFalse();
+ }
+
+ @Test
+ public void testTombstonesAreNotGeneratedWithCrashPayloadWhenNonDebuggableOnNonPvm()
+ throws Exception {
+ assumeNonProtectedVmSupported();
+ assertThat(
+ isTombstoneGeneratedWithCrashPayload(
+ /*protectedVm=*/ false, /*debuggable=*/ false))
+ .isFalse();
+ }
+
+ private boolean isTombstoneGeneratedWithCrashConfig(boolean protectedVm, boolean debuggable)
+ throws Exception {
return isTombstoneGeneratedWithVmRunApp(
- debuggable, "--config-path", "assets/vm_config_crash.json");
+ protectedVm, debuggable, "--config-path", "assets/vm_config_crash.json");
}
@Test
- public void testTombstonesAreGeneratedWithCrashConfig() throws Exception {
- assertThat(isTombstoneGeneratedWithCrashConfig(true /* debuggable */)).isTrue();
+ public void testTombstonesAreGeneratedWithCrashConfigOnPvm() throws Exception {
+ assumeProtectedVmSupported();
+ assertThat(isTombstoneGeneratedWithCrashConfig(/*protectedVm=*/ true, /*debuggable=*/ true))
+ .isTrue();
}
@Test
- public void testTombstonesAreNotGeneratedWithCrashConfigWhenNonDebuggable() throws Exception {
- assertThat(isTombstoneGeneratedWithCrashConfig(false /* debuggable */)).isFalse();
+ public void testTombstonesAreGeneratedWithCrashConfigOnNonPvm() throws Exception {
+ assumeNonProtectedVmSupported();
+ assertThat(
+ isTombstoneGeneratedWithCrashConfig(
+ /*protectedVm=*/ false, /*debuggable=*/ true))
+ .isTrue();
}
@Test
- public void testTelemetryPushedAtoms() throws Exception {
+ public void testTombstonesAreNotGeneratedWithCrashConfigWhenNonDebuggableOnPvm()
+ throws Exception {
+ assumeProtectedVmSupported();
+ assertThat(
+ isTombstoneGeneratedWithCrashConfig(
+ /*protectedVm=*/ true, /*debuggable=*/ false))
+ .isFalse();
+ }
+
+ @Test
+ public void testTombstonesAreNotGeneratedWithCrashConfigWhenNonDebuggableOnNonPvm()
+ throws Exception {
+ assumeNonProtectedVmSupported();
+ assertThat(
+ isTombstoneGeneratedWithCrashConfig(
+ /*protectedVm=*/ false, /*debuggable=*/ false))
+ .isFalse();
+ }
+
+ @Test
+ public void testTelemetryPushedAtomsOnNonPvm() throws Exception {
+ assumeNonProtectedVmSupported();
+ testTelemetryPushedAtoms(false);
+ }
+
+ @Test
+ public void testTelemetryPushedAtomsOnPvm() throws Exception {
+ assumeProtectedVmSupported();
+ testTelemetryPushedAtoms(true);
+ }
+
+ private void testTelemetryPushedAtoms(boolean protectedVm) throws Exception {
// Reset statsd config and report before the test
ConfigUtils.removeConfig(getDevice());
ReportUtils.clearReports(getDevice());
@@ -688,6 +746,7 @@
.debugLevel("full")
.memoryMib(minMemorySize())
.cpuTopology("match_host")
+ .protectedVm(protectedVm)
.build(device);
microdroid.waitForBootComplete(BOOT_COMPLETE_TIMEOUT);
device.shutdownMicrodroid(microdroid);
@@ -714,7 +773,7 @@
data.get(0).getAtom().getVmCreationRequested();
assertThat(atomVmCreationRequested.getHypervisor())
.isEqualTo(AtomsProto.VmCreationRequested.Hypervisor.PKVM);
- assertThat(atomVmCreationRequested.getIsProtected()).isFalse();
+ assertThat(atomVmCreationRequested.getIsProtected()).isEqualTo(protectedVm);
assertThat(atomVmCreationRequested.getCreationSucceeded()).isTrue();
assertThat(atomVmCreationRequested.getBinderExceptionCode()).isEqualTo(0);
assertThat(atomVmCreationRequested.getVmIdentifier()).isEqualTo("VmRunApp");
@@ -743,7 +802,19 @@
@Test
@CddTest(requirements = {"9.17/C-1-1", "9.17/C-1-2", "9.17/C/1-3"})
- public void testMicrodroidBoots() throws Exception {
+ public void testMicrodroidBootsOnPvm() throws Exception {
+ assumeProtectedVmSupported();
+ testMicrodroidBoots(true);
+ }
+
+ @Test
+ @CddTest(requirements = {"9.17/C-1-1", "9.17/C-1-2", "9.17/C/1-3"})
+ public void testMicrodroidBootsOnNonPvm() throws Exception {
+ assumeNonProtectedVmSupported();
+ testMicrodroidBoots(false);
+ }
+
+ private void testMicrodroidBoots(boolean protectedVm) throws Exception {
CommandRunner android = new CommandRunner(getDevice());
final String configPath = "assets/vm_config.json"; // path inside the APK
@@ -752,6 +823,7 @@
.debugLevel("full")
.memoryMib(minMemorySize())
.cpuTopology("match_host")
+ .protectedVm(protectedVm)
.build(getAndroidDevice());
mMicrodroidDevice.waitForBootComplete(BOOT_COMPLETE_TIMEOUT);
CommandRunner microdroid = new CommandRunner(mMicrodroidDevice);
@@ -810,13 +882,25 @@
}
@Test
- public void testMicrodroidRamUsage() throws Exception {
+ public void testMicrodroidRamUsageOnPvm() throws Exception {
+ assumeProtectedVmSupported();
+ testMicrodroidRamUsage(true);
+ }
+
+ @Test
+ public void testMicrodroidRamUsageOnNonPvm() throws Exception {
+ assumeNonProtectedVmSupported();
+ testMicrodroidRamUsage(false);
+ }
+
+ private void testMicrodroidRamUsage(boolean protectedVm) throws Exception {
final String configPath = "assets/vm_config.json";
mMicrodroidDevice =
MicrodroidBuilder.fromDevicePath(getPathForPackage(PACKAGE_NAME), configPath)
.debugLevel("full")
.memoryMib(minMemorySize())
.cpuTopology("match_host")
+ .protectedVm(protectedVm)
.build(getAndroidDevice());
mMicrodroidDevice.waitForBootComplete(BOOT_COMPLETE_TIMEOUT);
mMicrodroidDevice.enableAdbRoot();
@@ -990,6 +1074,18 @@
"android.permission.USE_CUSTOM_VIRTUAL_MACHINE");
}
+ private void assumeProtectedVmSupported() throws Exception {
+ assumeTrue(
+ "Test skipped because protected VMs are not supported",
+ getAndroidDevice().supportsMicrodroid(true));
+ }
+
+ private void assumeNonProtectedVmSupported() throws Exception {
+ assumeTrue(
+ "Test skipped because non-protected VMs are not supported",
+ getAndroidDevice().supportsMicrodroid(false));
+ }
+
private TestDevice getAndroidDevice() {
TestDevice androidDevice = (TestDevice) getDevice();
assertThat(androidDevice).isNotNull();