Add option to throw exception when module to install does not have

preloaded version on device.

Bug: 154167087
Test: atest apex_targetprep_tests
      mma && ./run_tradefed_func_tests.sh --class com.android.tradefed.targetprep.InstallApexModuleTargetPreparerTest
Change-Id: I69f8688d03aa60d2dbf8251eba9745c6cdfae3b4
diff --git a/test_framework/com/android/tradefed/targetprep/InstallApexModuleTargetPreparer.java b/test_framework/com/android/tradefed/targetprep/InstallApexModuleTargetPreparer.java
index 8e3ef8c..efc01a9 100644
--- a/test_framework/com/android/tradefed/targetprep/InstallApexModuleTargetPreparer.java
+++ b/test_framework/com/android/tradefed/targetprep/InstallApexModuleTargetPreparer.java
@@ -74,6 +74,13 @@
     )
     private long mApexStagingWaitTime = 1 * 60 * 1000;
 
+    @Option(
+            name = "ignore-if-module-not-preloaded",
+            description =
+                    "Skip installing the module(s) when the module(s) that are not "
+                            + "preloaded on device. Otherwise an exception will be thrown.")
+    private boolean mIgnoreIfNotPreloaded = false;
+
     @Override
     public void setUp(TestInformation testInfo)
             throws TargetSetupError, BuildError, DeviceNotAvailableException {
@@ -288,6 +295,19 @@
                 moduleNamesToInstall.add(moduleFileName);
                 installedPackages.remove(modulePackageName);
             } else {
+                if (!mIgnoreIfNotPreloaded) {
+                    if (!installedPackages.isEmpty()) {
+                        CLog.i(
+                                "The following modules are preloaded on the device %s",
+                                installedPackages);
+                    }
+                    throw new TargetSetupError(
+                            String.format(
+                                    "Mainline module %s is not preloaded on the device "
+                                            + "but is in the input lists.",
+                                    modulePackageName),
+                            device.getDeviceDescriptor());
+                }
                 CLog.i(
                         "The module package %s is not preloaded on the device but is included in "
                                 + "the train.",
diff --git a/tests/src/com/android/tradefed/targetprep/InstallApexModuleTargetPreparerTest.java b/tests/src/com/android/tradefed/targetprep/InstallApexModuleTargetPreparerTest.java
index 83cd35b..ef5f264 100644
--- a/tests/src/com/android/tradefed/targetprep/InstallApexModuleTargetPreparerTest.java
+++ b/tests/src/com/android/tradefed/targetprep/InstallApexModuleTargetPreparerTest.java
@@ -291,6 +291,32 @@
         EasyMock.verify(mMockBuildInfo, mMockDevice);
     }
 
+    @Test(expected = TargetSetupError.class)
+    public void testSetupFail_getActivatedPackageSuccessThrowModuleNotPreloaded() throws Exception {
+        mInstallApexModuleTargetPreparer.addTestFileName(APK_NAME);
+        mMockDevice.deleteFile(APEX_DATA_DIR + "*");
+        EasyMock.expectLastCall().times(1);
+        mMockDevice.deleteFile(SESSION_DATA_DIR + "*");
+        EasyMock.expectLastCall().times(1);
+        mMockDevice.deleteFile(STAGING_DATA_DIR + "*");
+        EasyMock.expectLastCall().times(1);
+        CommandResult res = new CommandResult();
+        res.setStdout("test.apex");
+        EasyMock.expect(mMockDevice.executeShellV2Command("ls " + APEX_DATA_DIR)).andReturn(res);
+        EasyMock.expect(mMockDevice.executeShellV2Command("ls " + SESSION_DATA_DIR)).andReturn(res);
+        EasyMock.expect(mMockDevice.executeShellV2Command("ls " + STAGING_DATA_DIR)).andReturn(res);
+        mMockDevice.reboot();
+        EasyMock.expectLastCall();
+        Set<ApexInfo> activatedApex = new HashSet<ApexInfo>();
+        activatedApex.add(new ApexInfo("com.android.FAKE_APEX_PACKAGE_NAME", 1));
+        EasyMock.expect(mMockDevice.getActiveApexes()).andReturn(activatedApex).times(2);
+        EasyMock.expect(mMockDevice.getInstalledPackageNames()).andReturn(new HashSet<>());
+
+        EasyMock.replay(mMockBuildInfo, mMockDevice);
+        mInstallApexModuleTargetPreparer.setUp(mTestInfo);
+        EasyMock.verify(mMockBuildInfo, mMockDevice);
+    }
+
     @Test
     public void testSetupFail_getActivatedPackageFail() throws Exception {
         mInstallApexModuleTargetPreparer.addTestFileName(APEX_NAME);
@@ -792,6 +818,7 @@
 
     @Test
     public void testInstallUsingBundletool_skipModuleNotPreloaded() throws Exception {
+        mSetter.setOptionValue("ignore-if-module-not-preloaded", "true");
         mInstallApexModuleTargetPreparer.addTestFileName(SPLIT_APEX_APKS_NAME);
         mInstallApexModuleTargetPreparer.addTestFileName(SPLIT_APK__APKS_NAME);
         mFakeApexApks = File.createTempFile("fakeApex", ".apks");
@@ -938,6 +965,7 @@
 
     @Test
     public void testSetupAndTearDown_noModulesPreloaded() throws Exception {
+        mSetter.setOptionValue("ignore-if-module-not-preloaded", "true");
         mInstallApexModuleTargetPreparer.addTestFileName(APEX_NAME);
         mInstallApexModuleTargetPreparer.addTestFileName(APK_NAME);
         mMockDevice.deleteFile(APEX_DATA_DIR + "*");
@@ -965,6 +993,7 @@
 
     @Test
     public void testSetupAndTearDown_skipModulesNotPreloaded() throws Exception {
+        mSetter.setOptionValue("ignore-if-module-not-preloaded", "true");
         mInstallApexModuleTargetPreparer.addTestFileName(APEX_NAME);
         mInstallApexModuleTargetPreparer.addTestFileName(APK_NAME);
         mInstallApexModuleTargetPreparer.addTestFileName(APK2_NAME);
@@ -1001,6 +1030,43 @@
         EasyMock.verify(mMockBuildInfo, mMockDevice);
     }
 
+    @Test(expected = TargetSetupError.class)
+    public void testSetupAndTearDown_throwExceptionModulesNotPreloaded() throws Exception {
+        mInstallApexModuleTargetPreparer.addTestFileName(APEX_NAME);
+        mInstallApexModuleTargetPreparer.addTestFileName(APK_NAME);
+        mInstallApexModuleTargetPreparer.addTestFileName(APK2_NAME);
+        mMockDevice.deleteFile(APEX_DATA_DIR + "*");
+        EasyMock.expectLastCall().times(2);
+        mMockDevice.deleteFile(SESSION_DATA_DIR + "*");
+        EasyMock.expectLastCall().times(2);
+        mMockDevice.deleteFile(STAGING_DATA_DIR + "*");
+        EasyMock.expectLastCall().times(2);
+        CommandResult res = new CommandResult();
+        res.setStdout("test.apex");
+        EasyMock.expect(mMockDevice.executeShellV2Command("ls " + APEX_DATA_DIR)).andReturn(res);
+        EasyMock.expect(mMockDevice.executeShellV2Command("ls " + SESSION_DATA_DIR)).andReturn(res);
+        EasyMock.expect(mMockDevice.executeShellV2Command("ls " + STAGING_DATA_DIR)).andReturn(res);
+        mMockDevice.reboot();
+        EasyMock.expectLastCall();
+        Set<ApexInfo> activatedApex = new HashSet<ApexInfo>();
+        activatedApex.add(new ApexInfo("com.android.FAKE_APEX_PACKAGE_NAME", 1));
+        EasyMock.expect(mMockDevice.getActiveApexes()).andReturn(activatedApex).times(3);
+        EasyMock.expect(mMockDevice.uninstallPackage(APK_PACKAGE_NAME)).andReturn(null).once();
+        mMockDevice.reboot();
+        EasyMock.expectLastCall();
+        Set<String> installableModules = new HashSet<>();
+        installableModules.add(APEX_PACKAGE_NAME);
+        installableModules.add(APK_PACKAGE_NAME);
+        EasyMock.expect(mMockDevice.getInstalledPackageNames())
+                .andReturn(installableModules)
+                .once();
+
+        EasyMock.replay(mMockBuildInfo, mMockDevice);
+        mInstallApexModuleTargetPreparer.setUp(mTestInfo);
+        mInstallApexModuleTargetPreparer.tearDown(mTestInfo, null);
+        EasyMock.verify(mMockBuildInfo, mMockDevice);
+    }
+
     @Test
     public void testSetupAndTearDown_skipModulesThatFailToExtract() throws Exception {
         mInstallApexModuleTargetPreparer.addTestFileName(APK_NAME);