Speed up AuthFsHostTest by reusing the VM
This is basically 7fc99e6c5e03bccc7d461a86c46b1a03b34a547b without
merging AuthFsHostTest into MicrodroidHostTestCases.
Also, add the test to presubmit.
Bug: 191056545
Bug: 193749869
Test: atest AuthFsHostTest
Change-Id: I866c4bbd6dbfc6d47719ad68dd91dafa8096b2c3
diff --git a/authfs/TEST_MAPPING b/authfs/TEST_MAPPING
index d0c0b09..14f1824 100644
--- a/authfs/TEST_MAPPING
+++ b/authfs/TEST_MAPPING
@@ -2,6 +2,9 @@
"presubmit": [
{
"name": "authfs_device_test_src_lib"
+ },
+ {
+ "name": "AuthFsHostTest"
}
]
}
diff --git a/authfs/tests/AndroidTest.xml b/authfs/tests/AndroidTest.xml
index 8f940f6..6100ab9 100644
--- a/authfs/tests/AndroidTest.xml
+++ b/authfs/tests/AndroidTest.xml
@@ -18,18 +18,11 @@
<!-- Need root to start virtualizationservice -->
<target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
- <!-- virtualizationservice doesn't have access to shell_data_file. Instead of giving it
- a test-only permission, run it without selinux -->
+ <!-- Still need to define SELinux policy for authfs and fd_server properly. -->
<target_preparer class="com.android.tradefed.targetprep.DisableSELinuxTargetPreparer"/>
- <!-- 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" />
- <!-- Make sure kernel has FUSE enabled. -->
- <option name="run-command" value="ls /dev/fuse" />
- <!-- Make sure necessary executables are installed. -->
- <option name="run-command" value="ls /apex/com.android.virt/bin/fd_server" />
- <option name="run-command" value="ls /apex/com.android.virt/bin/authfs" />
<!-- Prepare test directory. -->
<option name="run-command" value="mkdir -p /data/local/tmp/authfs/mnt" />
<option name="teardown-command" value="rm -rf /data/local/tmp/authfs" />
diff --git a/authfs/tests/java/src/com/android/fs/AuthFsHostTest.java b/authfs/tests/java/src/com/android/fs/AuthFsHostTest.java
index 426b333..6e1c890 100644
--- a/authfs/tests/java/src/com/android/fs/AuthFsHostTest.java
+++ b/authfs/tests/java/src/com/android/fs/AuthFsHostTest.java
@@ -18,18 +18,26 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
+import static org.junit.Assume.assumeFalse;
import android.platform.test.annotations.RootPermissionTest;
+import android.virt.test.CommandRunner;
import android.virt.test.VirtualizationTestCaseBase;
import com.android.compatibility.common.util.PollingCheck;
import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.device.ITestDevice;
+import com.android.tradefed.invoker.TestInformation;
import com.android.tradefed.log.LogUtil.CLog;
import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.tradefed.testtype.junit4.AfterClassWithInfo;
+import com.android.tradefed.testtype.junit4.BeforeClassWithInfo;
import com.android.tradefed.util.CommandResult;
import org.junit.After;
+import org.junit.AssumptionViolatedException;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -37,7 +45,6 @@
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
-// TODO move to Virtualization/tests/hostside/
@RootPermissionTest
@RunWith(DeviceJUnit4ClassRunner.class)
public final class AuthFsHostTest extends VirtualizationTestCaseBase {
@@ -55,50 +62,87 @@
private static final String AUTHFS_BIN = "/system/bin/authfs";
/** Plenty of time for authfs to get ready */
- private static final int AUTHFS_INIT_TIMEOUT_MS = 1500;
+ private static final int AUTHFS_INIT_TIMEOUT_MS = 3000;
/** FUSE's magic from statfs(2) */
private static final String FUSE_SUPER_MAGIC_HEX = "65735546";
- private ExecutorService mThreadPool;
- private String mCid;
+ private static CommandRunner sAndroid;
+ private static String sCid;
+ private static boolean sAssumptionFailed;
- @Before
- public void setUp() throws DeviceNotAvailableException {
- testIfDeviceIsCapable();
+ private ExecutorService mThreadPool = Executors.newCachedThreadPool();
- cleanUpTestFiles();
+ @BeforeClassWithInfo
+ public static void beforeClassWithDevice(TestInformation testInfo)
+ throws DeviceNotAvailableException {
+ assertNotNull(testInfo.getDevice());
+ ITestDevice androidDevice = testInfo.getDevice();
+ sAndroid = new CommandRunner(androidDevice);
- prepareVirtualizationTestSetup();
+ try {
+ testIfDeviceIsCapable(androidDevice);
+ } catch (AssumptionViolatedException e) {
+ // NB: The assumption exception is NOT handled by the test infra when it is thrown from
+ // a class method (see b/37502066). This has not only caused the loss of log, but also
+ // prevented the test cases to be reported at all and thus confused the test infra.
+ //
+ // Since we want to avoid the big overhead to start the VM repeatedly on CF, let's catch
+ // AssumptionViolatedException and emulate it artifitially.
+ CLog.e("Assumption failed: " + e);
+ sAssumptionFailed = true;
+ return;
+ }
- mThreadPool = Executors.newCachedThreadPool();
+ prepareVirtualizationTestSetup(androidDevice);
// For each test case, boot and adb connect to a new Microdroid
+ CLog.i("Starting the shared VM");
final String apkName = "MicrodroidTestApp.apk";
final String packageName = "com.android.microdroid.test";
final String configPath = "assets/vm_config.json"; // path inside the APK
- mCid = startMicrodroid(apkName, packageName, configPath, /* debug */ false);
- adbConnectToMicrodroid(mCid);
+ sCid =
+ startMicrodroid(
+ androidDevice,
+ testInfo.getBuildInfo(),
+ apkName,
+ packageName,
+ configPath,
+ /* debug */ false);
+ adbConnectToMicrodroid(androidDevice, sCid);
// Root because authfs (started from shell in this test) currently require root to open
// /dev/fuse and mount the FUSE.
rootMicrodroid();
}
- @After
- public void tearDown() throws DeviceNotAvailableException {
- if (mCid != null) {
- shutdownMicrodroid(mCid);
- mCid = null;
+ @AfterClassWithInfo
+ public static void afterClassWithDevice(TestInformation testInfo)
+ throws DeviceNotAvailableException {
+ assertNotNull(sAndroid);
+
+ if (sCid != null) {
+ CLog.i("Shutting down shared VM");
+ shutdownMicrodroid(sAndroid.getDevice(), sCid);
+ sCid = null;
}
- tryRunOnAndroid("killall fd_server");
- cleanUpTestFiles();
- cleanUpVirtualizationTestSetup();
+ cleanUpVirtualizationTestSetup(sAndroid.getDevice());
+ sAndroid = null;
}
- private void cleanUpTestFiles() throws DeviceNotAvailableException {
- tryRunOnAndroid("rm -f " + TEST_DIR + "/output");
+ @Before
+ public void setUp() {
+ assumeFalse(sAssumptionFailed);
+ }
+
+ @After
+ public void tearDown() throws DeviceNotAvailableException {
+ sAndroid.tryRun("killall fd_server");
+ sAndroid.tryRun("rm -f " + TEST_DIR + "/output");
+
+ tryRunOnMicrodroid("killall authfs");
+ tryRunOnMicrodroid("umount " + MOUNT_DIR);
}
@Test
@@ -194,7 +238,7 @@
// Action
// Tampering with the first 2 4K block of the backing file.
- runOnAndroid("dd if=/dev/zero of=" + backendPath + " bs=1 count=8192");
+ sAndroid.run("dd if=/dev/zero of=" + backendPath + " bs=1 count=8192");
// Verify
// Write to a block partially requires a read back to calculate the new hash. It should fail
@@ -274,7 +318,7 @@
}
private String computeFileHashOnAndroid(String path) throws DeviceNotAvailableException {
- String result = runOnAndroid("sha256sum " + path);
+ String result = sAndroid.run("sha256sum " + path);
String[] tokens = result.split("\\s");
if (tokens.length > 0) {
return tokens[0];
@@ -320,7 +364,7 @@
() -> {
try {
CLog.i("Starting fd_server");
- CommandResult result = getDevice().executeShellV2Command(cmd);
+ CommandResult result = sAndroid.runForResult(cmd);
CLog.w("fd_server has stopped: " + result);
} catch (DeviceNotAvailableException e) {
CLog.e("Error running fd_server", e);