/* * Copyright (C) 2017 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. */ #include #include #include #include #include #include "utils-fake.h" #include "vintf/VintfObject.h" using namespace ::testing; using namespace ::android::vintf; using namespace ::android::vintf::details; // // Set of Xml1 metadata compatible with each other. // const std::string systemMatrixXml1 = "\n" " \n" " android.hardware.camera\n" " 2.0-5\n" " 3.4-16\n" " \n" " \n" " android.hardware.nfc\n" " 1.0\n" " 2.0\n" " \n" " \n" " android.hardware.foo\n" " 1.0\n" " \n" " \n" " \n" " 30\n" " 25.5\n" " 26.0-3\n" " \n" " \n" " 0.0\n" " \n" "\n"; const std::string vendorManifestXml1 = "\n" " \n" " android.hardware.camera\n" " hwbinder\n" " 3.5\n" " \n" " IBetterCamera\n" " camera\n" " \n" " \n" " ICamera\n" " default\n" " legacy/0\n" " \n" " \n" " \n" " android.hardware.nfc\n" " hwbinder\n" " 1.0\n" " 2.0\n" " \n" " INfc\n" " nfc_nci\n" " \n" " \n" " \n" " android.hardware.nfc\n" " hwbinder\n" " 2.0\n" " \n" " INfc\n" " default\n" " \n" " \n" " \n" " 25.5\n" " \n" "\n"; const std::string systemManifestXml1 = "\n" " \n" " android.hidl.manager\n" " hwbinder\n" " 1.0\n" " \n" " IServiceManager\n" " default\n" " \n" " \n" " \n" " 25.0.5\n" " libbase.so\n" " libjpeg.so\n" " \n" "\n"; const std::string vendorMatrixXml1 = "\n" " \n" " android.hidl.manager\n" " 1.0\n" " \n" " \n" " 25.0.1-5\n" " libbase.so\n" " libjpeg.so\n" " \n" "\n"; // // Set of Xml2 metadata compatible with each other. // const std::string systemMatrixXml2 = "\n" " \n" " android.hardware.foo\n" " 1.0\n" " \n" " \n" " \n" " 30\n" " 25.5\n" " 26.0-3\n" " \n" " \n" " 0.0\n" " \n" "\n"; const std::string vendorManifestXml2 = "" " " " android.hardware.foo" " hwbinder" " 1.0" " " " \n" " 25.5\n" " \n" ""; // Setup the MockFileFetcher used by the fetchAllInformation template // so it returns the given metadata info instead of fetching from device. void setupMockFetcher(const std::string& vendorManifestXml, const std::string& systemMatrixXml, const std::string& systemManifestXml, const std::string& vendorMatrixXml) { MockFileFetcher* fetcher = static_cast(gFetcher); ON_CALL(*fetcher, fetch(StrEq("/vendor/manifest.xml"), _)) .WillByDefault(Invoke([vendorManifestXml](const std::string& path, std::string& fetched) { (void)path; fetched = vendorManifestXml; return 0; })); ON_CALL(*fetcher, fetch(StrEq("/system/manifest.xml"), _)) .WillByDefault(Invoke([systemManifestXml](const std::string& path, std::string& fetched) { (void)path; fetched = systemManifestXml; return 0; })); ON_CALL(*fetcher, fetch(StrEq("/vendor/compatibility_matrix.xml"), _)) .WillByDefault(Invoke([vendorMatrixXml](const std::string& path, std::string& fetched) { (void)path; fetched = vendorMatrixXml; return 0; })); ON_CALL(*fetcher, fetch(StrEq("/system/compatibility_matrix.xml"), _)) .WillByDefault(Invoke([systemMatrixXml](const std::string& path, std::string& fetched) { (void)path; fetched = systemMatrixXml; return 0; })); } static MockPartitionMounter &mounter() { return *static_cast(gPartitionMounter); } static MockFileFetcher &fetcher() { return *static_cast(gFetcher); } // Test fixture that provides compatible metadata from the mock device. class VintfObjectCompatibleTest : public testing::Test { protected: virtual void SetUp() { setupMockFetcher(vendorManifestXml1, systemMatrixXml1, systemManifestXml1, vendorMatrixXml1); } virtual void TearDown() { Mock::VerifyAndClear(&mounter()); Mock::VerifyAndClear(&fetcher()); } }; // Tests that local info is checked. TEST_F(VintfObjectCompatibleTest, TestDeviceCompatibility) { std::string error; std::vector 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 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. TEST_F(VintfObjectCompatibleTest, TestInputVsDeviceSuccess) { std::string error; std::vector 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 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. TEST_F(VintfObjectCompatibleTest, TestInputVsDeviceFail) { std::string error; std::vector packageInfo = {systemMatrixXml2}; int result = VintfObject::CheckCompatibility(packageInfo, &error); ASSERT_EQ(result, 1) << "Should have failed:" << error.c_str(); ASSERT_STREQ(error.c_str(), "Device manifest and framework compatibility matrix are incompatible: HALs " "incompatible. android.hardware.foo"); } // Tests that complementary info is checked against itself. TEST_F(VintfObjectCompatibleTest, TestInputSuccess) { std::string error; std::vector packageInfo = {systemMatrixXml2, vendorManifestXml2}; int result = VintfObject::CheckCompatibility(packageInfo, &error); ASSERT_EQ(result, 0) << "Failed message:" << error.c_str(); ASSERT_STREQ(error.c_str(), ""); } TEST_F(VintfObjectCompatibleTest, TestFrameworkOnlyOta) { std::string error; std::vector 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 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 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 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: virtual void SetUp() { setupMockFetcher(vendorManifestXml1, systemMatrixXml2, systemManifestXml1, vendorMatrixXml1); } virtual void TearDown() { Mock::VerifyAndClear(&mounter()); Mock::VerifyAndClear(&fetcher()); } }; // Fetch all metadata from device and ensure that it fails. TEST_F(VintfObjectIncompatibleTest, TestDeviceCompatibility) { std::string error; std::vector 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"), _)); int result = VintfObject::CheckCompatibility(packageInfo, &error); ASSERT_EQ(result, 1) << "Should have failed:" << error.c_str(); } // Pass in new metadata that fixes the incompatibility. TEST_F(VintfObjectIncompatibleTest, TestInputVsDeviceSuccess) { std::string error; std::vector 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); int result = VintfObject::CheckCompatibility(packageInfo, &error); ASSERT_EQ(result, 0) << "Failed message:" << error.c_str(); ASSERT_STREQ(error.c_str(), ""); } int main(int argc, char** argv) { ::testing::InitGoogleMock(&argc, argv); NiceMock fetcher; gFetcher = &fetcher; NiceMock mounter; gPartitionMounter = &mounter; return RUN_ALL_TESTS(); }