Add more vintf_object_test

* Fix duplicated Compat2 test in libvintf_test
The test is duplicated in libvintf_test and vintf_object_test;
it also fails because details::CheckCompatibility doesn't take
GetXCompatibilityMatrix functions.

* Add PartitionMounter that allows mocking on mount
procedures

* Fix duplicated mount and unmount in checkCompatibility

Test: libvintf_test
Test: vintf_object_test

Change-Id: I07be537696efe64f084fdbed77a781b26e971784
Merged-In: I07be537696efe64f084fdbed77a781b26e971784
diff --git a/VintfObject.cpp b/VintfObject.cpp
index 4558708..4f757bd 100644
--- a/VintfObject.cpp
+++ b/VintfObject.cpp
@@ -18,6 +18,7 @@
 
 #include "CompatibilityMatrix.h"
 #include "parse_xml.h"
+#include "utils.h"
 
 #include <functional>
 #include <memory>
@@ -90,10 +91,6 @@
 
 namespace details {
 
-static status_t fakeMountUmount() {
-    return OK;
-}
-
 enum class ParseStatus {
     OK,
     PARSE_ERROR,
@@ -135,7 +132,6 @@
 template<typename T, typename GetFunction>
 static status_t getMissing(const T *pkg, bool mount,
         std::function<status_t(void)> mountFunction,
-        std::function<status_t(void)> umountFunction,
         const T **updated,
         GetFunction getFunction) {
     if (pkg != nullptr) {
@@ -145,9 +141,6 @@
             (void)mountFunction(); // ignore mount errors
         }
         *updated = getFunction();
-        if (mount) {
-            (void)umountFunction(); // ignore umount errors
-        }
     }
     return OK;
 }
@@ -180,14 +173,7 @@
 // compatability info is given then the device info will be checked against
 // itself.
 int32_t checkCompatibility(const std::vector<std::string> &xmls, bool mount,
-        std::function<status_t(void)> mountSystem,
-        std::function<status_t(void)> umountSystem,
-        std::function<status_t(void)> mountVendor,
-        std::function<status_t(void)> umountVendor,
-        std::function<const HalManifest *(bool)> GetFrameworkHalManifest,
-        std::function<const HalManifest *(bool)> GetDeviceHalManifest,
-        std::function<const RuntimeInfo *(bool)> GetRuntimeInfo,
-        std::string *error) {
+        const PartitionMounter &mounter, std::string *error) {
 
     status_t status;
     ParseStatus parseStatus;
@@ -217,28 +203,37 @@
     }
 
     // get missing info from device
-    if ((status = getMissing(pkg.fwk.manifest.get(), mount, mountSystem, umountSystem,
-            &updated.fwk.manifest,
-            std::bind(GetFrameworkHalManifest, true /* skipCache */))) != OK) {
-        return status;
-    }
-    if ((status = getMissing(pkg.dev.manifest.get(), mount, mountVendor, umountVendor,
-            &updated.dev.manifest,
-            std::bind(GetDeviceHalManifest, true /* skipCache */))) != OK) {
+    // use functions instead of std::bind because std::bind doesn't work well with mock objects
+    auto mountSystem = [&mounter] { return mounter.mountSystem(); };
+    auto mountVendor = [&mounter] { return mounter.mountVendor(); };
+    if ((status = getMissing(
+             pkg.fwk.manifest.get(), mount, mountSystem, &updated.fwk.manifest,
+             std::bind(VintfObject::GetFrameworkHalManifest, true /* skipCache */))) != OK) {
         return status;
     }
     if ((status = getMissing(
-             pkg.fwk.matrix.get(), mount, mountSystem, umountSystem, &updated.fwk.matrix,
+             pkg.dev.manifest.get(), mount, mountVendor, &updated.dev.manifest,
+             std::bind(VintfObject::GetDeviceHalManifest, true /* skipCache */))) != OK) {
+        return status;
+    }
+    if ((status = getMissing(
+             pkg.fwk.matrix.get(), mount, mountSystem, &updated.fwk.matrix,
              std::bind(VintfObject::GetFrameworkCompatibilityMatrix, true /* skipCache */))) !=
         OK) {
         return status;
     }
     if ((status = getMissing(
-             pkg.dev.matrix.get(), mount, mountVendor, umountVendor, &updated.dev.matrix,
+             pkg.dev.matrix.get(), mount, mountVendor, &updated.dev.matrix,
              std::bind(VintfObject::GetDeviceCompatibilityMatrix, true /* skipCache */))) != OK) {
         return status;
     }
-    updated.runtimeInfo = GetRuntimeInfo(true /* skipCache */);
+
+    if (mount) {
+        (void)mounter.umountSystem(); // ignore errors
+        (void)mounter.umountVendor(); // ignore errors
+    }
+
+    updated.runtimeInfo = VintfObject::GetRuntimeInfo(true /* skipCache */);
 
     // null checks for files and runtime info after the update
     // TODO(b/37321309) if a compat mat is missing, it is not matched and considered compatible.
@@ -301,11 +296,7 @@
 int32_t VintfObject::CheckCompatibility(
         const std::vector<std::string> &xmls, std::string *error) {
     return details::checkCompatibility(xmls, false /* mount */,
-            &details::fakeMountUmount, &details::fakeMountUmount,
-            &details::fakeMountUmount, &details::fakeMountUmount,
-            &VintfObject::GetFrameworkHalManifest,
-            &VintfObject::GetDeviceHalManifest,
-            &VintfObject::GetRuntimeInfo,
+            *details::gPartitionMounter,
             error);
 }
 
diff --git a/VintfObjectRecovery.cpp b/VintfObjectRecovery.cpp
index ccae798..59fe6da 100644
--- a/VintfObjectRecovery.cpp
+++ b/VintfObjectRecovery.cpp
@@ -18,8 +18,9 @@
 
 #include <android-base/properties.h>
 #include <sys/mount.h>
+#include <fs_mgr.h>
 
-#include "fs_mgr.h"
+#include "utils.h"
 
 namespace android {
 namespace vintf {
@@ -36,54 +37,52 @@
     return result == 0 ? OK : -errno;
 }
 
-FstabMgr defaultFstabMgr() {
+static FstabMgr defaultFstabMgr() {
     return FstabMgr{fs_mgr_read_fstab_default(), &fs_mgr_free_fstab};
 }
 
-status_t mountSystem() {
-    FstabMgr fstab = defaultFstabMgr();
-    if (fstab == NULL) {
-        return UNKNOWN_ERROR;
+class RecoveryPartitionMounter : public PartitionMounter {
+   public:
+    status_t mountSystem() const override {
+        FstabMgr fstab = defaultFstabMgr();
+        if (fstab == NULL) {
+            return UNKNOWN_ERROR;
+        }
+        if (android::base::GetBoolProperty("ro.build.system_root_image", false)) {
+            return mountAt(fstab, "/", "/system_root");
+        } else {
+            return mountAt(fstab, "/system", "/system");
+        }
     }
-    if (android::base::GetBoolProperty("ro.build.system_root_image", false)) {
-        return mountAt(fstab, "/", "/system_root");
-    } else {
-        return mountAt(fstab, "/system", "/system");
-    }
-}
 
-status_t mountVendor() {
-    FstabMgr fstab = defaultFstabMgr();
-    if (fstab == NULL) {
-        return UNKNOWN_ERROR;
+    status_t mountVendor() const override {
+        FstabMgr fstab = defaultFstabMgr();
+        if (fstab == NULL) {
+            return UNKNOWN_ERROR;
+        }
+        return mountAt(fstab, "/vendor", "/vendor");
     }
-    return mountAt(fstab, "/vendor", "/vendor");
-}
 
-status_t umountSystem() {
-    if (android::base::GetBoolProperty("ro.build.system_root_image", false)) {
-        return umount("/system_root");
-    } else {
-        return umount("/system");
+    status_t umountSystem() const override {
+        if (android::base::GetBoolProperty("ro.build.system_root_image", false)) {
+            return umount("/system_root");
+        } else {
+            return umount("/system");
+        }
     }
-}
 
-status_t umountVendor() {
-    return umount("/vendor");
-}
+    status_t umountVendor() const override {
+        return umount("/vendor");
+    }
+};
 
 } // namespace details
 
 // static
 int32_t VintfObjectRecovery::CheckCompatibility(
         const std::vector<std::string> &xmls, std::string *error) {
-    return details::checkCompatibility(xmls, true /* mount */,
-            &details::mountSystem, &details::umountSystem,
-            &details::mountVendor, &details::umountVendor,
-            &VintfObject::GetFrameworkHalManifest,
-            &VintfObject::GetDeviceHalManifest,
-            &VintfObject::GetRuntimeInfo,
-            error);
+    static details::RecoveryPartitionMounter mounter;
+    return details::checkCompatibility(xmls, true /* mount */, mounter, error);
 }
 
 
diff --git a/include/vintf/VintfObject.h b/include/vintf/VintfObject.h
index 4f84a51..9d5cc6f 100644
--- a/include/vintf/VintfObject.h
+++ b/include/vintf/VintfObject.h
@@ -101,14 +101,9 @@
 
 // exposed for testing and VintfObjectRecovery.
 namespace details {
+class PartitionMounter;
 int32_t checkCompatibility(const std::vector<std::string> &xmls, bool mount,
-        std::function<status_t(void)> mountSystem,
-        std::function<status_t(void)> umountSystem,
-        std::function<status_t(void)> mountVendor,
-        std::function<status_t(void)> umountVendor,
-        std::function<const HalManifest *(bool)> GetFrameworkHalManifest,
-        std::function<const HalManifest *(bool)> GetDeviceHalManifest,
-        std::function<const RuntimeInfo *(bool)> GetRuntimeInfo,
+        const PartitionMounter& partitionMounter,
         std::string *error);
 } // namespace details
 
diff --git a/include/vintf/VintfObjectRecovery.h b/include/vintf/VintfObjectRecovery.h
index 3c54671..c3288f1 100644
--- a/include/vintf/VintfObjectRecovery.h
+++ b/include/vintf/VintfObjectRecovery.h
@@ -47,14 +47,6 @@
 
 };
 
-// exposed for testing purposes.
-namespace details {
-status_t mountSystem();
-status_t mountVendor();
-status_t umountSystem();
-status_t umountVendor();
-}
-
 } // namespace vintf
 } // namespace android
 
diff --git a/test/main.cpp b/test/main.cpp
index 0903f7d..fce4d6d 100644
--- a/test/main.cpp
+++ b/test/main.cpp
@@ -751,179 +751,6 @@
     EXPECT_TRUE(manifest.checkCompatibility(matrix, &error)) << error;
 }
 
-TEST_F(LibVintfTest, Compat2) {
-    std::string deviceManifestXml =
-        "<manifest version=\"1.0\" type=\"device\">\n"
-        "    <sepolicy>\n"
-        "        <version>25.5</version>\n"
-        "    </sepolicy>\n"
-        "</manifest>\n";
-    std::string frameworkManifestXml =
-        "<manifest version=\"1.0\" type=\"framework\">\n"
-        "    <vndk>\n"
-        "        <version>25.0.5</version>\n"
-        "    </vndk>\n"
-        "</manifest>\n";
-    std::string deviceMatrixXml =
-        "<compatibility-matrix version=\"1.0\" type=\"device\">\n"
-        "    <vndk>\n"
-        "        <version>25.0.5</version>\n"
-        "    </vndk>\n"
-        "</compatibility-matrix>\n";
-    std::string frameworkMatrixXml =
-        "<compatibility-matrix version=\"1.0\" type=\"framework\">\n"
-        "    <kernel version=\"3.18.31\"></kernel>"
-        "    <sepolicy>\n"
-        "        <kernel-sepolicy-version>30</kernel-sepolicy-version>\n"
-        "        <sepolicy-version>25.5</sepolicy-version>\n"
-        "    </sepolicy>\n"
-        "    <avb>\n"
-        "        <vbmeta-version>2.1</vbmeta-version>\n"
-        "    </avb>\n"
-        "</compatibility-matrix>\n";
-    RuntimeInfo runtimeInfo = testRuntimeInfo();
-    HalManifest devManifest;
-    HalManifest fwkManifest;
-    CompatibilityMatrix devMatrix;
-    CompatibilityMatrix fwkMatrix;
-    EXPECT_TRUE(gHalManifestConverter(&devManifest, deviceManifestXml));
-    EXPECT_TRUE(gHalManifestConverter(&fwkManifest, frameworkManifestXml));
-    EXPECT_TRUE(gCompatibilityMatrixConverter(&devMatrix, deviceMatrixXml));
-    EXPECT_TRUE(gCompatibilityMatrixConverter(&fwkMatrix, frameworkMatrixXml));
-    std::string error;
-    EXPECT_TRUE(devManifest.checkCompatibility(fwkMatrix, &error)) << error;
-    EXPECT_TRUE(fwkManifest.checkCompatibility(devMatrix, &error)) << error;
-    EXPECT_TRUE(runtimeInfo.checkCompatibility(fwkMatrix, &error)) << error;
-
-    bool systemMounted = false;
-    bool vendorMounted = false;
-    bool systemUmounted = false;
-    bool vendorUmounted = false;
-    auto mountSystem  = [&systemMounted]  () { systemMounted = true;  return OK; };
-    auto mountVendor  = [&vendorMounted]  () { vendorMounted = true;  return OK; };
-    auto umountSystem = [&systemUmounted] () { systemUmounted = true; return OK; };
-    auto umountVendor = [&vendorUmounted] () { vendorUmounted = true; return OK; };
-    auto nullManifestFunc = [](bool) -> const HalManifest * { return nullptr; };
-    auto runtimeInfoFunc = [&](bool) { return &runtimeInfo; };
-    // full OTA
-    EXPECT_EQ(COMPATIBLE, details::checkCompatibility(
-            {deviceManifestXml, deviceMatrixXml, frameworkManifestXml, frameworkMatrixXml},
-            false /* mount */, mountSystem, umountSystem, mountVendor, umountVendor,
-            nullManifestFunc,
-            nullManifestFunc,
-            runtimeInfoFunc,
-            &error)) << error;
-    EXPECT_FALSE(systemMounted);
-    EXPECT_FALSE(vendorMounted);
-    EXPECT_FALSE(systemUmounted);
-    EXPECT_FALSE(vendorUmounted);
-    EXPECT_EQ(COMPATIBLE, details::checkCompatibility(
-            {deviceManifestXml, deviceMatrixXml, frameworkManifestXml, frameworkMatrixXml},
-            true /* mount */, mountSystem, umountSystem, mountVendor, umountVendor,
-            nullManifestFunc,
-            nullManifestFunc,
-            runtimeInfoFunc,
-            &error)) << error;
-    EXPECT_FALSE(systemMounted);
-    EXPECT_FALSE(vendorMounted);
-    EXPECT_FALSE(systemUmounted);
-    EXPECT_FALSE(vendorUmounted);
-
-    // framework only OTA
-    EXPECT_GT(0, details::checkCompatibility(
-            {frameworkManifestXml, frameworkMatrixXml},
-            false /* mount */, mountSystem, umountSystem, mountVendor, umountVendor,
-            nullManifestFunc,
-            nullManifestFunc,
-            runtimeInfoFunc,
-            &error)) << "should not mount, thus info should be missing";
-    EXPECT_FALSE(systemMounted);
-    EXPECT_FALSE(vendorMounted);
-    EXPECT_FALSE(systemUmounted);
-    EXPECT_FALSE(vendorUmounted);
-    EXPECT_EQ(COMPATIBLE, details::checkCompatibility(
-            {frameworkManifestXml, frameworkMatrixXml},
-            true /* mount */, mountSystem, umountSystem, mountVendor, umountVendor,
-            nullManifestFunc,
-            [&](auto) { return &devManifest; },
-            runtimeInfoFunc,
-            &error)) << error;
-    EXPECT_FALSE(systemMounted);
-    EXPECT_TRUE(vendorMounted);
-    EXPECT_FALSE(systemUmounted);
-    EXPECT_TRUE(vendorUmounted);
-
-    CompatibilityMatrix failedFwkMatrix;
-    std::string failedFrameworkMatrixXml;
-
-    // Failed framework only OTA example 1: runtime info doesn't work (avb version)
-    failedFwkMatrix = {};
-    systemMounted = false;
-    vendorMounted = false;
-    failedFrameworkMatrixXml =
-        "<compatibility-matrix version=\"1.0\" type=\"framework\">\n"
-        "    <kernel version=\"3.18.31\"></kernel>"
-        "    <sepolicy>\n"
-        "        <kernel-sepolicy-version>30</kernel-sepolicy-version>\n"
-        "        <sepolicy-version>25.5</sepolicy-version>\n"
-        "    </sepolicy>\n"
-        "    <avb>\n"
-        "        <vbmeta-version>2.2</vbmeta-version>\n"
-        "    </avb>\n"
-        "</compatibility-matrix>\n";
-    EXPECT_TRUE(gCompatibilityMatrixConverter(&failedFwkMatrix, failedFrameworkMatrixXml));
-    EXPECT_TRUE(devManifest.checkCompatibility(failedFwkMatrix, &error)) << error;
-    EXPECT_FALSE(runtimeInfo.checkCompatibility(failedFwkMatrix, &error)) << error;
-    EXPECT_EQ(INCOMPATIBLE, details::checkCompatibility(
-            {frameworkManifestXml, failedFrameworkMatrixXml},
-            true /* mount */, mountSystem, umountSystem, mountVendor, umountVendor,
-            nullManifestFunc,
-            [&](auto) { return &devManifest; },
-            runtimeInfoFunc,
-            &error)) << error;
-    EXPECT_STREQ(error.c_str(),
-                 "Runtime info and framework compatibility matrix are incompatible: "
-                 "AVB version 2.1 does not match framework matrix 2.2");
-    EXPECT_FALSE(systemMounted);
-    EXPECT_TRUE(vendorMounted);
-    EXPECT_FALSE(systemUmounted);
-    EXPECT_TRUE(vendorUmounted);
-
-    // Failed framework only OTA example 2: unsupported HAL
-    failedFwkMatrix = {};
-    systemMounted = false;
-    vendorMounted = false;
-    failedFrameworkMatrixXml =
-        "<compatibility-matrix version=\"1.0\" type=\"framework\">\n"
-        "    <hal format=\"hidl\" optional=\"false\">\n"
-        "        <name>android.hardware.camera</name>\n"
-        "        <version>2.0-5</version>\n"
-        "    </hal>\n"
-        "    <kernel version=\"3.18.31\"></kernel>"
-        "    <sepolicy>\n"
-        "        <kernel-sepolicy-version>30</kernel-sepolicy-version>\n"
-        "        <sepolicy-version>25.5</sepolicy-version>\n"
-        "    </sepolicy>\n"
-        "    <avb>\n"
-        "        <vbmeta-version>2.1</vbmeta-version>\n"
-        "    </avb>\n"
-        "</compatibility-matrix>\n";
-    EXPECT_TRUE(gCompatibilityMatrixConverter(&failedFwkMatrix, failedFrameworkMatrixXml));
-    EXPECT_FALSE(devManifest.checkCompatibility(failedFwkMatrix, &error)) << error;
-    EXPECT_TRUE(runtimeInfo.checkCompatibility(failedFwkMatrix, &error)) << error;
-    EXPECT_EQ(INCOMPATIBLE, details::checkCompatibility(
-            {frameworkManifestXml, failedFrameworkMatrixXml},
-            true /* mount */, mountSystem, umountSystem, mountVendor, umountVendor,
-            nullManifestFunc,
-            [&](auto) { return &devManifest; },
-            runtimeInfoFunc,
-            &error)) << error;
-    EXPECT_FALSE(systemMounted);
-    EXPECT_TRUE(vendorMounted);
-    EXPECT_FALSE(systemUmounted);
-    EXPECT_TRUE(vendorUmounted);
-}
-
 } // namespace vintf
 } // namespace android
 
diff --git a/test/utils-fake.cpp b/test/utils-fake.cpp
index 586017e..3f4f3c1 100644
--- a/test/utils-fake.cpp
+++ b/test/utils-fake.cpp
@@ -20,10 +20,12 @@
 namespace vintf {
 namespace details {
 
-// Do not create the MockFileFetcher here as InitGoogleMock must be called
+// Do not create the mock objects here as InitGoogleMock must be called
 // first.
 FileFetcher* gFetcher = nullptr;
 
+PartitionMounter* gPartitionMounter = nullptr;
+
 }  // namespace details
 }  // namespace vintf
 }  // namespace android
diff --git a/test/utils-fake.h b/test/utils-fake.h
index d0c687e..cca5dc6 100644
--- a/test/utils-fake.h
+++ b/test/utils-fake.h
@@ -21,6 +21,7 @@
 using ::testing::_;
 using ::testing::AtLeast;
 using ::testing::Invoke;
+using ::testing::Return;
 
 namespace android {
 namespace vintf {
@@ -39,6 +40,39 @@
     FileFetcher real_;
 };
 
+class MockPartitionMounter : public PartitionMounter {
+   public:
+    MockPartitionMounter() {
+        ON_CALL(*this, mountSystem()).WillByDefault(Invoke([&] {
+            systemMounted_ = true;
+            return OK;
+        }));
+        ON_CALL(*this, umountSystem()).WillByDefault(Invoke([&] {
+            systemMounted_ = false;
+            return OK;
+        }));
+        ON_CALL(*this, mountVendor()).WillByDefault(Invoke([&] {
+            vendorMounted_ = true;
+            return OK;
+        }));
+        ON_CALL(*this, umountVendor()).WillByDefault(Invoke([&] {
+            vendorMounted_ = false;
+            return OK;
+        }));
+    }
+    MOCK_CONST_METHOD0(mountSystem, status_t());
+    MOCK_CONST_METHOD0(umountSystem, status_t());
+    MOCK_CONST_METHOD0(mountVendor, status_t());
+    MOCK_CONST_METHOD0(umountVendor, status_t());
+
+    bool systemMounted() const { return systemMounted_; }
+    bool vendorMounted() const { return vendorMounted_; }
+
+   private:
+     bool systemMounted_;
+     bool vendorMounted_;
+};
+
 }  // namespace details
 }  // namespace vintf
 }  // namespace android
diff --git a/test/vintf_object_tests.cpp b/test/vintf_object_tests.cpp
index 27b3f0a..d176d1b 100644
--- a/test/vintf_object_tests.cpp
+++ b/test/vintf_object_tests.cpp
@@ -14,6 +14,8 @@
  * limitations under the License.
  */
 
+#include <android-base/logging.h>
+
 #include <gmock/gmock.h>
 #include <gtest/gtest.h>
 #include <stdio.h>
@@ -193,6 +195,13 @@
         }));
 }
 
+static MockPartitionMounter &mounter() {
+    return *static_cast<MockPartitionMounter *>(gPartitionMounter);
+}
+static MockFileFetcher &fetcher() {
+    return *static_cast<MockFileFetcher*>(gFetcher);
+}
+
 // Test fixture that provides compatible metadata from the mock device.
 class VintfObjectCompatibleTest : public testing::Test {
    protected:
@@ -200,6 +209,11 @@
         setupMockFetcher(vendorManifestXml1, systemMatrixXml1, systemManifestXml1,
                          vendorMatrixXml1);
     }
+    virtual void TearDown() {
+        Mock::VerifyAndClear(&mounter());
+        Mock::VerifyAndClear(&fetcher());
+    }
+
 };
 
 // Tests that local info is checked.
@@ -207,11 +221,38 @@
     std::string error;
     std::vector<std::string> packageInfo;
 
+    EXPECT_CALL(fetcher(), fetch(StrEq("/vendor/manifest.xml"), _));
+    EXPECT_CALL(fetcher(), fetch(StrEq("/system/manifest.xml"), _));
+    EXPECT_CALL(fetcher(), fetch(StrEq("/vendor/compatibility_matrix.xml"), _));
+    EXPECT_CALL(fetcher(), fetch(StrEq("/system/compatibility_matrix.xml"), _));
+    EXPECT_CALL(mounter(), mountSystem()).Times(0);
+    EXPECT_CALL(mounter(), umountSystem()).Times(0);
+    EXPECT_CALL(mounter(), mountVendor()).Times(0);
+    EXPECT_CALL(mounter(), umountVendor()).Times(0);
+
     int result = VintfObject::CheckCompatibility(packageInfo, &error);
 
     ASSERT_EQ(result, 0) << "Fail message:" << error.c_str();
     // Check that nothing was ignored.
     ASSERT_STREQ(error.c_str(), "");
+    EXPECT_FALSE(mounter().systemMounted());
+    EXPECT_FALSE(mounter().vendorMounted());
+}
+
+TEST_F(VintfObjectCompatibleTest, TestDeviceCompatibilityMount) {
+    std::string error;
+    std::vector<std::string> packageInfo;
+
+    EXPECT_CALL(mounter(), mountSystem()).Times(2);
+    EXPECT_CALL(mounter(), umountSystem()).Times(1); // Should only umount once
+    EXPECT_CALL(mounter(), mountVendor()).Times(2);
+    EXPECT_CALL(mounter(), umountVendor()).Times(1);
+
+    int result = details::checkCompatibility(packageInfo, true /* mount */, mounter(), &error);
+
+    ASSERT_EQ(result, 0) << "Fail message:" << error.c_str();
+    EXPECT_FALSE(mounter().systemMounted());
+    EXPECT_FALSE(mounter().vendorMounted());
 }
 
 // Tests that input info is checked against device and passes.
@@ -219,10 +260,37 @@
     std::string error;
     std::vector<std::string> packageInfo = {systemMatrixXml1};
 
+    EXPECT_CALL(fetcher(), fetch(StrEq("/vendor/manifest.xml"), _));
+    EXPECT_CALL(fetcher(), fetch(StrEq("/system/manifest.xml"), _));
+    EXPECT_CALL(fetcher(), fetch(StrEq("/vendor/compatibility_matrix.xml"), _));
+    EXPECT_CALL(fetcher(), fetch(StrEq("/system/compatibility_matrix.xml"), _)).Times(0);
+    EXPECT_CALL(mounter(), mountSystem()).Times(0);
+    EXPECT_CALL(mounter(), umountSystem()).Times(0);
+    EXPECT_CALL(mounter(), mountVendor()).Times(0);
+    EXPECT_CALL(mounter(), umountVendor()).Times(0);
+
     int result = VintfObject::CheckCompatibility(packageInfo, &error);
 
     ASSERT_EQ(result, 0) << "Fail message:" << error.c_str();
     ASSERT_STREQ(error.c_str(), "");
+    EXPECT_FALSE(mounter().systemMounted());
+    EXPECT_FALSE(mounter().vendorMounted());
+}
+
+TEST_F(VintfObjectCompatibleTest, TestInputVsDeviceSuccessMount) {
+    std::string error;
+    std::vector<std::string> packageInfo = {systemMatrixXml1};
+
+    EXPECT_CALL(mounter(), mountSystem()).Times(1); // Should only mount once for manifest
+    EXPECT_CALL(mounter(), umountSystem()).Times(1);
+    EXPECT_CALL(mounter(), mountVendor()).Times(2);
+    EXPECT_CALL(mounter(), umountVendor()).Times(1);
+
+    int result = details::checkCompatibility(packageInfo, true /* mount */, mounter(), &error);
+
+    ASSERT_EQ(result, 0) << "Fail message:" << error.c_str();
+    EXPECT_FALSE(mounter().systemMounted());
+    EXPECT_FALSE(mounter().vendorMounted());
 }
 
 // Tests that input info is checked against device and fails.
@@ -249,6 +317,82 @@
     ASSERT_STREQ(error.c_str(), "");
 }
 
+TEST_F(VintfObjectCompatibleTest, TestFrameworkOnlyOta) {
+    std::string error;
+    std::vector<std::string> packageInfo = {systemMatrixXml1, systemManifestXml1};
+
+    EXPECT_CALL(fetcher(), fetch(StrEq("/vendor/manifest.xml"), _));
+    EXPECT_CALL(fetcher(), fetch(StrEq("/system/manifest.xml"), _)).Times(0);
+    EXPECT_CALL(fetcher(), fetch(StrEq("/vendor/compatibility_matrix.xml"), _));
+    EXPECT_CALL(fetcher(), fetch(StrEq("/system/compatibility_matrix.xml"), _)).Times(0);
+    EXPECT_CALL(mounter(), mountSystem()).Times(0);
+    EXPECT_CALL(mounter(), umountSystem()).Times(0);
+    EXPECT_CALL(mounter(), mountVendor()).Times(0);
+    EXPECT_CALL(mounter(), umountVendor()).Times(0);
+
+    int result = VintfObject::CheckCompatibility(packageInfo, &error);
+
+    ASSERT_EQ(result, 0) << "Fail message:" << error.c_str();
+    ASSERT_STREQ(error.c_str(), "");
+    EXPECT_FALSE(mounter().systemMounted());
+    EXPECT_FALSE(mounter().vendorMounted());
+}
+
+TEST_F(VintfObjectCompatibleTest, TestFrameworkOnlyOtaMount) {
+    std::string error;
+    std::vector<std::string> packageInfo = {systemMatrixXml1, systemManifestXml1};
+
+    EXPECT_CALL(mounter(), mountSystem()).Times(0);
+    EXPECT_CALL(mounter(), umountSystem()).Times(1);
+    EXPECT_CALL(mounter(), mountVendor()).Times(2);
+    EXPECT_CALL(mounter(), umountVendor()).Times(1);
+
+    int result = details::checkCompatibility(packageInfo, true /* mount */, mounter(), &error);
+
+    ASSERT_EQ(result, 0) << "Fail message:" << error.c_str();
+    EXPECT_FALSE(mounter().systemMounted());
+    EXPECT_FALSE(mounter().vendorMounted());
+}
+
+TEST_F(VintfObjectCompatibleTest, TestFullOta) {
+    std::string error;
+    std::vector<std::string> packageInfo = {systemMatrixXml1, systemManifestXml1,
+            vendorMatrixXml1, vendorManifestXml1};
+
+    EXPECT_CALL(fetcher(), fetch(StrEq("/vendor/manifest.xml"), _)).Times(0);
+    EXPECT_CALL(fetcher(), fetch(StrEq("/system/manifest.xml"), _)).Times(0);
+    EXPECT_CALL(fetcher(), fetch(StrEq("/vendor/compatibility_matrix.xml"), _)).Times(0);
+    EXPECT_CALL(fetcher(), fetch(StrEq("/system/compatibility_matrix.xml"), _)).Times(0);
+    EXPECT_CALL(mounter(), mountSystem()).Times(0);
+    EXPECT_CALL(mounter(), umountSystem()).Times(0);
+    EXPECT_CALL(mounter(), mountVendor()).Times(0);
+    EXPECT_CALL(mounter(), umountVendor()).Times(0);
+
+    int result = VintfObject::CheckCompatibility(packageInfo, &error);
+
+    ASSERT_EQ(result, 0) << "Fail message:" << error.c_str();
+    ASSERT_STREQ(error.c_str(), "");
+    EXPECT_FALSE(mounter().systemMounted());
+    EXPECT_FALSE(mounter().vendorMounted());
+}
+
+TEST_F(VintfObjectCompatibleTest, TestFullOnlyOtaMount) {
+    std::string error;
+    std::vector<std::string> packageInfo = {systemMatrixXml1, systemManifestXml1,
+            vendorMatrixXml1, vendorManifestXml1};
+
+    EXPECT_CALL(mounter(), mountSystem()).Times(0);
+    EXPECT_CALL(mounter(), umountSystem()).Times(1);
+    EXPECT_CALL(mounter(), mountVendor()).Times(0);
+    EXPECT_CALL(mounter(), umountVendor()).Times(1);
+
+    int result = details::checkCompatibility(packageInfo, true /* mount */, mounter(), &error);
+
+    ASSERT_EQ(result, 0) << "Fail message:" << error.c_str();
+    EXPECT_FALSE(mounter().systemMounted());
+    EXPECT_FALSE(mounter().vendorMounted());
+}
+
 // Test fixture that provides incompatible metadata from the mock device.
 class VintfObjectIncompatibleTest : public testing::Test {
    protected:
@@ -256,6 +400,10 @@
         setupMockFetcher(vendorManifestXml1, systemMatrixXml2, systemManifestXml1,
                          vendorMatrixXml1);
     }
+    virtual void TearDown() {
+        Mock::VerifyAndClear(&mounter());
+        Mock::VerifyAndClear(&fetcher());
+    }
 };
 
 // Fetch all metadata from device and ensure that it fails.
@@ -263,11 +411,10 @@
     std::string error;
     std::vector<std::string> packageInfo;
 
-    MockFileFetcher* fetcher = static_cast<MockFileFetcher*>(gFetcher);
-    EXPECT_CALL(*fetcher, fetch(StrEq("/vendor/manifest.xml"), _));
-    EXPECT_CALL(*fetcher, fetch(StrEq("/system/manifest.xml"), _));
-    EXPECT_CALL(*fetcher, fetch(StrEq("/vendor/compatibility_matrix.xml"), _));
-    EXPECT_CALL(*fetcher, fetch(StrEq("/system/compatibility_matrix.xml"), _));
+    EXPECT_CALL(fetcher(), fetch(StrEq("/vendor/manifest.xml"), _));
+    EXPECT_CALL(fetcher(), fetch(StrEq("/system/manifest.xml"), _));
+    EXPECT_CALL(fetcher(), fetch(StrEq("/vendor/compatibility_matrix.xml"), _));
+    EXPECT_CALL(fetcher(), fetch(StrEq("/system/compatibility_matrix.xml"), _));
 
     int result = VintfObject::CheckCompatibility(packageInfo, &error);
 
@@ -279,11 +426,10 @@
     std::string error;
     std::vector<std::string> packageInfo = {systemMatrixXml1};
 
-    MockFileFetcher* fetcher = static_cast<MockFileFetcher*>(gFetcher);
-    EXPECT_CALL(*fetcher, fetch(StrEq("/vendor/manifest.xml"), _));
-    EXPECT_CALL(*fetcher, fetch(StrEq("/system/manifest.xml"), _));
-    EXPECT_CALL(*fetcher, fetch(StrEq("/vendor/compatibility_matrix.xml"), _));
-    EXPECT_CALL(*fetcher, fetch(StrEq("/system/compatibility_matrix.xml"), _)).Times(0);
+    EXPECT_CALL(fetcher(), fetch(StrEq("/vendor/manifest.xml"), _));
+    EXPECT_CALL(fetcher(), fetch(StrEq("/system/manifest.xml"), _));
+    EXPECT_CALL(fetcher(), fetch(StrEq("/vendor/compatibility_matrix.xml"), _));
+    EXPECT_CALL(fetcher(), fetch(StrEq("/system/compatibility_matrix.xml"), _)).Times(0);
 
     int result = VintfObject::CheckCompatibility(packageInfo, &error);
 
@@ -295,7 +441,10 @@
     ::testing::InitGoogleMock(&argc, argv);
 
     NiceMock<MockFileFetcher> fetcher;
-    gFetcher = static_cast<FileFetcher*>(&fetcher);
+    gFetcher = &fetcher;
+
+    NiceMock<MockPartitionMounter> mounter;
+    gPartitionMounter = &mounter;
 
     return RUN_ALL_TESTS();
 }
diff --git a/utils.cpp b/utils.cpp
index 3c4d2e7..9b20b01 100644
--- a/utils.cpp
+++ b/utils.cpp
@@ -20,9 +20,11 @@
 namespace vintf {
 namespace details {
 
-FileFetcher fetcher;
+static FileFetcher fetcher;
 FileFetcher* gFetcher = &fetcher;
 
+static PartitionMounter partitionMounter;
+PartitionMounter* gPartitionMounter = &partitionMounter;
 }  // namespace details
 }  // namespace vintf
 }  // namespace android
diff --git a/utils.h b/utils.h
index 2c5f813..9208b6a 100644
--- a/utils.h
+++ b/utils.h
@@ -55,6 +55,17 @@
 
 extern FileFetcher* gFetcher;
 
+class PartitionMounter {
+   public:
+    virtual ~PartitionMounter() {}
+    virtual status_t mountSystem() const { return OK; }
+    virtual status_t mountVendor() const { return OK; }
+    virtual status_t umountSystem() const { return OK; }
+    virtual status_t umountVendor() const { return OK; }
+};
+
+extern PartitionMounter* gPartitionMounter;
+
 template <typename T>
 status_t fetchAllInformation(const std::string& path, const XmlConverter<T>& converter,
                              T* outObject) {