MicrodroidHostTestCases: Test VM DT modification by device assignment

Bug: 300266803
Test: atest MicrodroidHostTestCases
Change-Id: I3e26c89b6641d70b645613637bcf37476db5db3e
diff --git a/tests/hostside/Android.bp b/tests/hostside/Android.bp
index e3d9cbe..13a9925 100644
--- a/tests/hostside/Android.bp
+++ b/tests/hostside/Android.bp
@@ -37,6 +37,8 @@
         "lpunpack",
         "sign_virt_apex",
         "simg2img",
+        "dtdiff",
+        "dtc", // for dtdiff
     ],
     // java_test_host doesn't have data_native_libs but jni_libs can be used to put
     // native modules under ./lib directory.
@@ -51,5 +53,6 @@
         "liblp",
         "libsparse",
         "libz",
+        "libfdt", // for dtc
     ],
 }
diff --git a/tests/hostside/java/com/android/microdroid/test/MicrodroidHostTests.java b/tests/hostside/java/com/android/microdroid/test/MicrodroidHostTests.java
index 2cd4577..20b5a50 100644
--- a/tests/hostside/java/com/android/microdroid/test/MicrodroidHostTests.java
+++ b/tests/hostside/java/com/android/microdroid/test/MicrodroidHostTests.java
@@ -47,6 +47,7 @@
 import com.android.tradefed.device.TestDevice;
 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner.TestMetrics;
 import com.android.tradefed.util.CommandResult;
+import com.android.tradefed.util.CommandStatus;
 import com.android.tradefed.util.FileUtil;
 import com.android.tradefed.util.RunUtil;
 import com.android.tradefed.util.xml.AbstractXmlParser;
@@ -985,23 +986,71 @@
 
     @Test
     public void testDeviceAssignment() throws Exception {
-        assumeProtectedVm();
+        // Check for preconditions
         assumeVfioPlatformSupported();
 
         List<String> devices = getAssignableDevices();
         assumeFalse("no assignable devices", devices.isEmpty());
 
+        String vmFdtPath = "/sys/firmware/fdt";
+        File testDir = FileUtil.createTempDir("device_assignment_test");
+        File baseFdtFile = new File(testDir, "base_fdt.dtb");
+        File fdtFile = new File(testDir, "fdt.dtb");
+
+        // Generates baseline DT
+        launchWithDeviceAssignment(/* device= */ null);
+        assertThat(mMicrodroidDevice.pullFile(vmFdtPath, baseFdtFile)).isTrue();
+        getAndroidDevice().shutdownMicrodroid(mMicrodroidDevice);
+
+        // Prepares to run dtdiff. It requires dtc.
+        File dtdiff = findTestFile("dtdiff");
+        RunUtil runner = new RunUtil();
+        String separator = System.getProperty("path.separator");
+        String path = dtdiff.getParent() + separator + System.getenv("PATH");
+        runner.setEnvVariable("PATH", path);
+
+        // Try assign devices one by one
+        for (String device : devices) {
+            assertThat(device).isNotNull();
+            launchWithDeviceAssignment(device);
+            assertThat(mMicrodroidDevice.pullFile(vmFdtPath, fdtFile)).isTrue();
+            getAndroidDevice().shutdownMicrodroid(mMicrodroidDevice);
+
+            CommandResult result =
+                    runner.runTimedCmd(
+                            500,
+                            dtdiff.getAbsolutePath(),
+                            baseFdtFile.getPath(),
+                            fdtFile.getPath());
+
+            assertWithMessage(
+                            "VM's device tree hasn't changed when assigning "
+                                    + device
+                                    + ", result="
+                                    + result)
+                    .that(result.getStatus())
+                    .isNotEqualTo(CommandStatus.SUCCESS);
+        }
+
+        mMicrodroidDevice = null;
+    }
+
+    private void launchWithDeviceAssignment(String device) throws Exception {
         final String configPath = "assets/" + mOs + "/vm_config.json";
-        mMicrodroidDevice =
+
+        MicrodroidBuilder builder =
                 MicrodroidBuilder.fromDevicePath(getPathForPackage(PACKAGE_NAME), configPath)
                         .debugLevel("full")
                         .memoryMib(minMemorySize())
                         .cpuTopology("match_host")
-                        .protectedVm(true)
-                        .addAssignableDevice(devices.get(0))
-                        .build(getAndroidDevice());
+                        .protectedVm(mProtectedVm);
+        if (device != null) {
+            builder.addAssignableDevice(device);
+        }
+        mMicrodroidDevice = builder.build(getAndroidDevice());
 
-        mMicrodroidDevice.waitForBootComplete(BOOT_COMPLETE_TIMEOUT);
+        assertThat(mMicrodroidDevice.waitForBootComplete(BOOT_COMPLETE_TIMEOUT)).isTrue();
+        assertThat(mMicrodroidDevice.enableAdbRoot()).isTrue();
     }
 
     @Test