diff --git a/authfs/tests/Android.bp b/authfs/tests/Android.bp
new file mode 100644
index 0000000..8061c56
--- /dev/null
+++ b/authfs/tests/Android.bp
@@ -0,0 +1,21 @@
+package {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+java_test_host {
+    name: "AuthFsHostTest",
+    srcs: ["java/**/*.java"],
+    libs: [
+        "tradefed",
+        "compatibility-tradefed",
+        "compatibility-host-util",
+    ],
+    static_libs: [
+        "VirtualizationTestHelper",
+    ],
+    test_suites: ["general-tests"],
+    data: [
+        ":authfs_test_files",
+        ":MicrodroidTestApp.signed",
+    ],
+}
diff --git a/authfs/tests/AndroidTest.xml b/authfs/tests/AndroidTest.xml
new file mode 100644
index 0000000..8f940f6
--- /dev/null
+++ b/authfs/tests/AndroidTest.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2021 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 authfs tests">
+    <!-- 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 -->
+    <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" />
+    </target_preparer>
+
+    <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="cert.der" value="/data/local/tmp/authfs/cert.der" />
+        <option name="push-file" key="input.4m" value="/data/local/tmp/authfs/input.4m" />
+        <option name="push-file" key="input.4k1" value="/data/local/tmp/authfs/input.4k1" />
+        <option name="push-file" key="input.4k" value="/data/local/tmp/authfs/input.4k" />
+        <option name="push-file" key="input.4m.fsv_sig"
+            value="/data/local/tmp/authfs/input.4m.fsv_sig" />
+        <option name="push-file" key="input.4k1.fsv_sig"
+            value="/data/local/tmp/authfs/input.4k1.fsv_sig" />
+        <option name="push-file" key="input.4k.fsv_sig"
+            value="/data/local/tmp/authfs/input.4k.fsv_sig" />
+        <option name="push-file" key="input.4m.merkle_dump"
+            value="/data/local/tmp/authfs/input.4m.merkle_dump" />
+        <option name="push-file" key="input.4m.merkle_dump.bad"
+            value="/data/local/tmp/authfs/input.4m.merkle_dump.bad" />
+        <option name="push-file" key="input.4k1.merkle_dump"
+            value="/data/local/tmp/authfs/input.4k1.merkle_dump" />
+        <option name="push-file" key="input.4k.merkle_dump"
+            value="/data/local/tmp/authfs/input.4k.merkle_dump" />
+    </target_preparer>
+
+    <test class="com.android.compatibility.common.tradefed.testtype.JarHostTest" >
+        <option name="jar" value="AuthFsHostTest.jar" />
+    </test>
+</configuration>
diff --git a/authfs/tests/java/src/com/android/fs/AuthFsHostTest.java b/authfs/tests/java/src/com/android/fs/AuthFsHostTest.java
new file mode 100644
index 0000000..426b333
--- /dev/null
+++ b/authfs/tests/java/src/com/android/fs/AuthFsHostTest.java
@@ -0,0 +1,336 @@
+/*
+ * Copyright (C) 2021 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 com.android.virt.fs;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import android.platform.test.annotations.RootPermissionTest;
+import android.virt.test.VirtualizationTestCaseBase;
+
+import com.android.compatibility.common.util.PollingCheck;
+import com.android.tradefed.device.DeviceNotAvailableException;
+import com.android.tradefed.log.LogUtil.CLog;
+import com.android.tradefed.testtype.DeviceJUnit4ClassRunner;
+import com.android.tradefed.util.CommandResult;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+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 {
+
+    /** Test directory on Android where data are located */
+    private static final String TEST_DIR = "/data/local/tmp/authfs";
+
+    /** Mount point of authfs on Microdroid during the test */
+    private static final String MOUNT_DIR = "/data/local/tmp";
+
+    /** Path to fd_server on Android */
+    private static final String FD_SERVER_BIN = "/apex/com.android.virt/bin/fd_server";
+
+    /** Path to authfs on Microdroid */
+    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;
+
+    /** FUSE's magic from statfs(2) */
+    private static final String FUSE_SUPER_MAGIC_HEX = "65735546";
+
+    private ExecutorService mThreadPool;
+    private String mCid;
+
+    @Before
+    public void setUp() throws DeviceNotAvailableException {
+        testIfDeviceIsCapable();
+
+        cleanUpTestFiles();
+
+        prepareVirtualizationTestSetup();
+
+        mThreadPool = Executors.newCachedThreadPool();
+
+        // For each test case, boot and adb connect to a new Microdroid
+        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);
+
+        // 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;
+        }
+
+        tryRunOnAndroid("killall fd_server");
+        cleanUpTestFiles();
+        cleanUpVirtualizationTestSetup();
+    }
+
+    private void cleanUpTestFiles() throws DeviceNotAvailableException {
+        tryRunOnAndroid("rm -f " + TEST_DIR + "/output");
+    }
+
+    @Test
+    public void testReadWithFsverityVerification_RemoteFile()
+            throws DeviceNotAvailableException, InterruptedException {
+        // Setup
+        runFdServerOnAndroid(
+                "3<input.4m 4<input.4m.merkle_dump 5<input.4m.fsv_sig 6<input.4m",
+                "--ro-fds 3:4:5 --ro-fds 6 --rpc-binder");
+
+        runAuthFsOnMicrodroid(
+                "--remote-ro-file-unverified 10:6:4194304 --remote-ro-file 11:3:4194304:cert.der"
+                        + " --cid 2");
+
+        // Action
+        String actualHashUnverified4m = computeFileHashOnMicrodroid(MOUNT_DIR + "/10");
+        String actualHash4m = computeFileHashOnMicrodroid(MOUNT_DIR + "/11");
+
+        // Verify
+        String expectedHash4m = computeFileHashOnAndroid(TEST_DIR + "/input.4m");
+
+        assertEquals("Inconsistent hash from /authfs/10: ", expectedHash4m, actualHashUnverified4m);
+        assertEquals("Inconsistent hash from /authfs/11: ", expectedHash4m, actualHash4m);
+    }
+
+    // Separate the test from the above simply because exec in shell does not allow open too many
+    // files.
+    @Test
+    public void testReadWithFsverityVerification_RemoteSmallerFile()
+            throws DeviceNotAvailableException, InterruptedException {
+        // Setup
+        runFdServerOnAndroid(
+                "3<input.4k 4<input.4k.merkle_dump 5<input.4k.fsv_sig"
+                        + " 6<input.4k1 7<input.4k1.merkle_dump 8<input.4k1.fsv_sig",
+                "--ro-fds 3:4:5 --ro-fds 6:7:8 --rpc-binder");
+        runAuthFsOnMicrodroid(
+                "--remote-ro-file 10:3:4096:cert.der --remote-ro-file 11:6:4097:cert.der --cid 2");
+
+        // Action
+        String actualHash4k = computeFileHashOnMicrodroid(MOUNT_DIR + "/10");
+        String actualHash4k1 = computeFileHashOnMicrodroid(MOUNT_DIR + "/11");
+
+        // Verify
+        String expectedHash4k = computeFileHashOnAndroid(TEST_DIR + "/input.4k");
+        String expectedHash4k1 = computeFileHashOnAndroid(TEST_DIR + "/input.4k1");
+
+        assertEquals("Inconsistent hash from /authfs/10: ", expectedHash4k, actualHash4k);
+        assertEquals("Inconsistent hash from /authfs/11: ", expectedHash4k1, actualHash4k1);
+    }
+
+    @Test
+    public void testReadWithFsverityVerification_TamperedMerkleTree()
+            throws DeviceNotAvailableException, InterruptedException {
+        // Setup
+        runFdServerOnAndroid(
+                "3<input.4m 4<input.4m.merkle_dump.bad 5<input.4m.fsv_sig",
+                "--ro-fds 3:4:5 --rpc-binder");
+        runAuthFsOnMicrodroid("--remote-ro-file 10:3:4096:cert.der --cid 2");
+
+        // Verify
+        assertFalse(copyFileOnMicrodroid(MOUNT_DIR + "/10", "/dev/null"));
+    }
+
+    @Test
+    public void testWriteThroughCorrectly()
+            throws DeviceNotAvailableException, InterruptedException {
+        // Setup
+        runFdServerOnAndroid("3<>output", "--rw-fds 3 --rpc-binder");
+        runAuthFsOnMicrodroid("--remote-new-rw-file 20:3 --cid 2");
+
+        // Action
+        String srcPath = "/system/bin/linker64";
+        String destPath = MOUNT_DIR + "/20";
+        String backendPath = TEST_DIR + "/output";
+        assertTrue(copyFileOnMicrodroid(srcPath, destPath));
+
+        // Verify
+        String expectedHash = computeFileHashOnMicrodroid(srcPath);
+        expectBackingFileConsistency(destPath, backendPath, expectedHash);
+    }
+
+    @Test
+    public void testWriteFailedIfDetectsTampering()
+            throws DeviceNotAvailableException, InterruptedException {
+        // Setup
+        runFdServerOnAndroid("3<>output", "--rw-fds 3 --rpc-binder");
+        runAuthFsOnMicrodroid("--remote-new-rw-file 20:3 --cid 2");
+
+        String srcPath = "/system/bin/linker64";
+        String destPath = MOUNT_DIR + "/20";
+        String backendPath = TEST_DIR + "/output";
+        assertTrue(copyFileOnMicrodroid(srcPath, destPath));
+
+        // Action
+        // Tampering with the first 2 4K block of the backing file.
+        runOnAndroid("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
+        // when the content is inconsistent to the known hash. Use direct I/O to avoid simply
+        // writing to the filesystem cache.
+        assertEquals(
+                tryRunOnMicrodroid("dd if=/dev/zero of=" + destPath + " bs=1 count=1024 direct"),
+                null);
+
+        // A full 4K write does not require to read back, so write can succeed even if the backing
+        // block has already been tampered.
+        runOnMicrodroid("dd if=/dev/zero of=" + destPath + " bs=1 count=4096 skip=4096");
+
+        // Otherwise, a partial write with correct backing file should still succeed.
+        runOnMicrodroid("dd if=/dev/zero of=" + destPath + " bs=1 count=1024 skip=8192");
+    }
+
+    @Test
+    public void testFileResize() throws DeviceNotAvailableException, InterruptedException {
+        // Setup
+        runFdServerOnAndroid("3<>output", "--rw-fds 3 --rpc-binder");
+        runAuthFsOnMicrodroid("--remote-new-rw-file 20:3 --cid 2");
+        String outputPath = MOUNT_DIR + "/20";
+        String backendPath = TEST_DIR + "/output";
+
+        // Action & Verify
+        runOnMicrodroid("yes $'\\x01' | tr -d '\\n' | dd bs=1 count=10000 of=" + outputPath);
+        assertEquals(getFileSizeInBytesOnMicrodroid(outputPath), 10000);
+        expectBackingFileConsistency(
+                outputPath,
+                backendPath,
+                "684ad25fdc2bbb80cbc910dd1bde6d5499ccf860ca6ee44704b77ec445271353");
+
+        resizeFileOnMicrodroid(outputPath, 15000);
+        assertEquals(getFileSizeInBytesOnMicrodroid(outputPath), 15000);
+        expectBackingFileConsistency(
+                outputPath,
+                backendPath,
+                "567c89f62586e0d33369157afdfe99a2fa36cdffb01e91dcdc0b7355262d610d");
+
+        resizeFileOnMicrodroid(outputPath, 5000);
+        assertEquals(getFileSizeInBytesOnMicrodroid(outputPath), 5000);
+        expectBackingFileConsistency(
+                outputPath,
+                backendPath,
+                "e53130831c13dabff71d5d1797e3aaa467b4b7d32b3b8782c4ff03d76976f2aa");
+    }
+
+    private void expectBackingFileConsistency(
+            String authFsPath, String backendPath, String expectedHash)
+            throws DeviceNotAvailableException {
+        String hashOnAuthFs = computeFileHashOnMicrodroid(authFsPath);
+        assertEquals("File hash is different to expectation", expectedHash, hashOnAuthFs);
+
+        String hashOfBackingFile = computeFileHashOnAndroid(backendPath);
+        assertEquals(
+                "Inconsistent file hash on the backend storage", hashOnAuthFs, hashOfBackingFile);
+    }
+
+    private String computeFileHashOnMicrodroid(String path) {
+        String result = runOnMicrodroid("sha256sum " + path);
+        String[] tokens = result.split("\\s");
+        if (tokens.length > 0) {
+            return tokens[0];
+        } else {
+            CLog.e("Unrecognized output by sha256sum: " + result);
+            return "";
+        }
+    }
+
+    private boolean copyFileOnMicrodroid(String src, String dest)
+            throws DeviceNotAvailableException {
+        // TODO(b/182576497): cp returns error because close(2) returns ENOSYS in the current authfs
+        // implementation. We should probably fix that since programs can expect close(2) return 0.
+        String cmd = "cat " + src + " > " + dest;
+        return tryRunOnMicrodroid(cmd) != null;
+    }
+
+    private String computeFileHashOnAndroid(String path) throws DeviceNotAvailableException {
+        String result = runOnAndroid("sha256sum " + path);
+        String[] tokens = result.split("\\s");
+        if (tokens.length > 0) {
+            return tokens[0];
+        } else {
+            CLog.e("Unrecognized output by sha256sum: " + result);
+            return "";
+        }
+    }
+
+    private void resizeFileOnMicrodroid(String path, long size) {
+        runOnMicrodroid("truncate -c -s " + size + " " + path);
+    }
+
+    private long getFileSizeInBytesOnMicrodroid(String path) {
+        return Long.parseLong(runOnMicrodroid("stat -c '%s' " + path));
+    }
+
+    private void runAuthFsOnMicrodroid(String flags) {
+        String cmd = AUTHFS_BIN + " " + MOUNT_DIR + " " + flags;
+
+        mThreadPool.submit(
+                () -> {
+                    CLog.i("Starting authfs");
+                    CommandResult result = runOnMicrodroidForResult(cmd);
+                    CLog.w("authfs has stopped: " + result);
+                });
+        try {
+            PollingCheck.waitFor(
+                    AUTHFS_INIT_TIMEOUT_MS, () -> isMicrodroidDirectoryOnFuse(MOUNT_DIR));
+        } catch (Exception e) {
+            // Convert the broad Exception into an unchecked exception to avoid polluting all other
+            // methods. waitFor throws Exception because the callback, Callable#call(), has a
+            // signature to throw an Exception.
+            throw new RuntimeException(e);
+        }
+    }
+
+    private void runFdServerOnAndroid(String execParamsForOpeningFds, String flags)
+            throws DeviceNotAvailableException {
+        String cmd = "cd " + TEST_DIR + " && exec " + execParamsForOpeningFds + " " + FD_SERVER_BIN
+                + " " + flags;
+        mThreadPool.submit(
+                () -> {
+                    try {
+                        CLog.i("Starting fd_server");
+                        CommandResult result = getDevice().executeShellV2Command(cmd);
+                        CLog.w("fd_server has stopped: " + result);
+                    } catch (DeviceNotAvailableException e) {
+                        CLog.e("Error running fd_server", e);
+                        throw new RuntimeException(e);
+                    }
+                });
+    }
+
+    private boolean isMicrodroidDirectoryOnFuse(String path) {
+        String fs_type = tryRunOnMicrodroid("stat -f -c '%t' " + path);
+        return FUSE_SUPER_MAGIC_HEX.equals(fs_type);
+    }
+}
