/*
 * 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 <android-base/logging.h>

#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <stdio.h>
#include <unistd.h>

#include <android-base/strings.h>
#include <hidl-util/FQName.h>

#include <vintf/VintfObject.h>
#include <vintf/parse_string.h>
#include "test_constants.h"
#include "utils-fake.h"

using namespace ::testing;

using android::FqInstance;

static AssertionResult In(const std::string& sub, const std::string& str) {
    return (str.find(sub) != std::string::npos ? AssertionSuccess() : AssertionFailure())
           << "Value is " << str;
}
#define EXPECT_IN(sub, str) EXPECT_TRUE(In((sub), (str)))
#define EXPECT_NOT_IN(sub, str) EXPECT_FALSE(In((sub), (str)))

namespace android {
namespace vintf {
namespace testing {

using namespace ::android::vintf::details;

// clang-format off

//
// Set of Xml1 metadata compatible with each other.
//

const std::string systemMatrixXml1 =
    "<compatibility-matrix " + kMetaVersionStr + " type=\"framework\">\n"
    "    <hal format=\"hidl\" optional=\"false\">\n"
    "        <name>android.hardware.camera</name>\n"
    "        <version>2.0-5</version>\n"
    "        <version>3.4-16</version>\n"
    "    </hal>\n"
    "    <hal format=\"hidl\" optional=\"false\">\n"
    "        <name>android.hardware.nfc</name>\n"
    "        <version>1.0</version>\n"
    "        <version>2.0</version>\n"
    "    </hal>\n"
    "    <hal format=\"hidl\" optional=\"true\">\n"
    "        <name>android.hardware.foo</name>\n"
    "        <version>1.0</version>\n"
    "    </hal>\n"
    "    <kernel version=\"3.18.31\"></kernel>\n"
    "    <sepolicy>\n"
    "        <kernel-sepolicy-version>30</kernel-sepolicy-version>\n"
    "        <sepolicy-version>25.5</sepolicy-version>\n"
    "        <sepolicy-version>26.0-3</sepolicy-version>\n"
    "    </sepolicy>\n"
    "    <avb>\n"
    "        <vbmeta-version>0.0</vbmeta-version>\n"
    "    </avb>\n"
    "</compatibility-matrix>\n";

const std::string vendorManifestXml1 =
    "<manifest " + kMetaVersionStr + " type=\"device\">\n"
    "    <hal format=\"hidl\">\n"
    "        <name>android.hardware.camera</name>\n"
    "        <transport>hwbinder</transport>\n"
    "        <version>3.5</version>\n"
    "        <interface>\n"
    "            <name>IBetterCamera</name>\n"
    "            <instance>camera</instance>\n"
    "        </interface>\n"
    "        <interface>\n"
    "            <name>ICamera</name>\n"
    "            <instance>default</instance>\n"
    "            <instance>legacy/0</instance>\n"
    "        </interface>\n"
    "    </hal>\n"
    "    <hal format=\"hidl\">\n"
    "        <name>android.hardware.nfc</name>\n"
    "        <transport>hwbinder</transport>\n"
    "        <version>1.0</version>\n"
    "        <interface>\n"
    "            <name>INfc</name>\n"
    "            <instance>nfc_nci</instance>\n"
    "        </interface>\n"
    "    </hal>\n"
    "    <hal format=\"hidl\">\n"
    "        <name>android.hardware.nfc</name>\n"
    "        <transport>hwbinder</transport>\n"
    "        <version>2.0</version>\n"
    "        <interface>\n"
    "            <name>INfc</name>\n"
    "            <instance>default</instance>\n"
    "            <instance>nfc_nci</instance>\n"
    "        </interface>\n"
    "    </hal>\n"
    "    <sepolicy>\n"
    "        <version>25.5</version>\n"
    "    </sepolicy>\n"
    "</manifest>\n";

const std::string systemManifestXml1 =
    "<manifest " + kMetaVersionStr + " type=\"framework\">\n"
    "    <hal format=\"hidl\">\n"
    "        <name>android.hidl.manager</name>\n"
    "        <transport>hwbinder</transport>\n"
    "        <version>1.0</version>\n"
    "        <interface>\n"
    "            <name>IServiceManager</name>\n"
    "            <instance>default</instance>\n"
    "        </interface>\n"
    "    </hal>\n"
    "    <vndk>\n"
    "        <version>25.0.5</version>\n"
    "        <library>libbase.so</library>\n"
    "        <library>libjpeg.so</library>\n"
    "    </vndk>\n"
    "</manifest>\n";

const std::string vendorMatrixXml1 =
    "<compatibility-matrix " + kMetaVersionStr + " type=\"device\">\n"
    "    <hal format=\"hidl\" optional=\"false\">\n"
    "        <name>android.hidl.manager</name>\n"
    "        <version>1.0</version>\n"
    "    </hal>\n"
    "    <vndk>\n"
    "        <version>25.0.1-5</version>\n"
    "        <library>libbase.so</library>\n"
    "        <library>libjpeg.so</library>\n"
    "    </vndk>\n"
    "</compatibility-matrix>\n";

//
// Set of Xml2 metadata compatible with each other.
//

const std::string systemMatrixXml2 =
    "<compatibility-matrix " + kMetaVersionStr + " type=\"framework\">\n"
    "    <hal format=\"hidl\">\n"
    "        <name>android.hardware.foo</name>\n"
    "        <version>1.0</version>\n"
    "    </hal>\n"
    "    <kernel version=\"3.18.31\"></kernel>\n"
    "    <sepolicy>\n"
    "        <kernel-sepolicy-version>30</kernel-sepolicy-version>\n"
    "        <sepolicy-version>25.5</sepolicy-version>\n"
    "        <sepolicy-version>26.0-3</sepolicy-version>\n"
    "    </sepolicy>\n"
    "    <avb>\n"
    "        <vbmeta-version>0.0</vbmeta-version>\n"
    "    </avb>\n"
    "</compatibility-matrix>\n";

const std::string vendorManifestXml2 =
    "<manifest " + kMetaVersionStr + " type=\"device\">"
    "    <hal>"
    "        <name>android.hardware.foo</name>"
    "        <transport>hwbinder</transport>"
    "        <version>1.0</version>"
    "    </hal>"
    "    <sepolicy>\n"
    "        <version>25.5</version>\n"
    "    </sepolicy>\n"
    "</manifest>";

//
// Set of framework matrices of different FCM version.
//

const std::string systemMatrixLevel1 =
    "<compatibility-matrix " + kMetaVersionStr + " type=\"framework\" level=\"1\">\n"
    "    <hal format=\"hidl\" optional=\"true\">\n"
    "        <name>android.hardware.major</name>\n"
    "        <version>1.0</version>\n"
    "        <interface>\n"
    "            <name>IMajor</name>\n"
    "            <instance>default</instance>\n"
    "        </interface>\n"
    "    </hal>\n"
    "    <hal format=\"hidl\" optional=\"true\">\n"
    "        <name>android.hardware.removed</name>\n"
    "        <version>1.0</version>\n"
    "        <interface>\n"
    "            <name>IRemoved</name>\n"
    "            <instance>default</instance>\n"
    "        </interface>\n"
    "    </hal>\n"
    "    <hal format=\"hidl\" optional=\"true\">\n"
    "        <name>android.hardware.minor</name>\n"
    "        <version>1.0</version>\n"
    "        <interface>\n"
    "            <name>IMinor</name>\n"
    "            <instance>default</instance>\n"
    "            <instance>legacy</instance>\n"
    "        </interface>\n"
    "    </hal>\n"
    "</compatibility-matrix>\n";

const std::string systemMatrixLevel2 =
    "<compatibility-matrix " + kMetaVersionStr + " type=\"framework\" level=\"2\">\n"
    "    <hal format=\"hidl\" optional=\"true\">\n"
    "        <name>android.hardware.major</name>\n"
    "        <version>2.0</version>\n"
    "        <interface>\n"
    "            <name>IMajor</name>\n"
    "            <instance>default</instance>\n"
    "        </interface>\n"
    "    </hal>\n"
    "    <hal format=\"hidl\" optional=\"true\">\n"
    "        <name>android.hardware.minor</name>\n"
    "        <version>1.1</version>\n"
    "        <interface>\n"
    "            <name>IMinor</name>\n"
    "            <instance>default</instance>\n"
    "        </interface>\n"
    "    </hal>\n"
    "</compatibility-matrix>\n";

//
// Set of framework matrices of different FCM version with regex.
//

const static std::vector<std::string> systemMatrixRegexXmls = {
    // 1.xml
    "<compatibility-matrix " + kMetaVersionStr + " type=\"framework\" level=\"1\">\n"
    "    <hal format=\"hidl\" optional=\"false\">\n"
    "        <name>android.hardware.regex</name>\n"
    "        <version>1.0-1</version>\n"
    "        <interface>\n"
    "            <name>IRegex</name>\n"
    "            <instance>default</instance>\n"
    "            <instance>special/1.0</instance>\n"
    "            <regex-instance>regex/1.0/[0-9]+</regex-instance>\n"
    "            <regex-instance>regex_common/[0-9]+</regex-instance>\n"
    "        </interface>\n"
    "    </hal>\n"
    "</compatibility-matrix>\n",
    // 2.xml
    "<compatibility-matrix " + kMetaVersionStr + " type=\"framework\" level=\"2\">\n"
    "    <hal format=\"hidl\" optional=\"false\">\n"
    "        <name>android.hardware.regex</name>\n"
    "        <version>1.1-2</version>\n"
    "        <interface>\n"
    "            <name>IRegex</name>\n"
    "            <instance>default</instance>\n"
    "            <instance>special/1.1</instance>\n"
    "            <regex-instance>regex/1.1/[0-9]+</regex-instance>\n"
    "            <regex-instance>[a-z]+_[a-z]+/[0-9]+</regex-instance>\n"
    "        </interface>\n"
    "    </hal>\n"
    "</compatibility-matrix>\n",
    // 3.xml
    "<compatibility-matrix " + kMetaVersionStr + " type=\"framework\" level=\"3\">\n"
    "    <hal format=\"hidl\" optional=\"false\">\n"
    "        <name>android.hardware.regex</name>\n"
    "        <version>2.0</version>\n"
    "        <interface>\n"
    "            <name>IRegex</name>\n"
    "            <instance>default</instance>\n"
    "            <instance>special/2.0</instance>\n"
    "            <regex-instance>regex/2.0/[0-9]+</regex-instance>\n"
    "            <regex-instance>regex_[a-z]+/[0-9]+</regex-instance>\n"
    "        </interface>\n"
    "    </hal>\n"
    "</compatibility-matrix>\n"};

//
// Set of metadata at different FCM version that has requirements
//

const std::vector<std::string> systemMatrixRequire = {
    // 1.xml
    "<compatibility-matrix " + kMetaVersionStr + " type=\"framework\" level=\"1\">\n"
    "    <hal format=\"hidl\" optional=\"false\">\n"
    "        <name>android.hardware.foo</name>\n"
    "        <version>1.0</version>\n"
    "        <interface>\n"
    "            <name>IFoo</name>\n"
    "            <instance>default</instance>\n"
    "        </interface>\n"
    "    </hal>\n"
    "</compatibility-matrix>\n",
    // 2.xml
    "<compatibility-matrix " + kMetaVersionStr + " type=\"framework\" level=\"2\">\n"
    "    <hal format=\"hidl\" optional=\"false\">\n"
    "        <name>android.hardware.bar</name>\n"
    "        <version>1.0</version>\n"
    "        <interface>\n"
    "            <name>IBar</name>\n"
    "            <instance>default</instance>\n"
    "        </interface>\n"
    "    </hal>\n"
    "</compatibility-matrix>\n"};

const std::string vendorManifestRequire1 =
    "<manifest " + kMetaVersionStr + " type=\"device\" target-level=\"1\">\n"
    "    <hal format=\"hidl\">\n"
    "        <name>android.hardware.foo</name>\n"
    "        <transport>hwbinder</transport>\n"
    "        <fqname>@1.0::IFoo/default</fqname>\n"
    "    </hal>\n"
    "</manifest>\n";

const std::string vendorManifestRequire2 =
    "<manifest " + kMetaVersionStr + " type=\"device\" target-level=\"2\">\n"
    "    <hal format=\"hidl\">\n"
    "        <name>android.hardware.bar</name>\n"
    "        <transport>hwbinder</transport>\n"
    "        <fqname>@1.0::IBar/default</fqname>\n"
    "    </hal>\n"
    "</manifest>\n";

//
// Set of metadata for kernel requirements
//

const std::string vendorManifestKernel318 =
    "<manifest " + kMetaVersionStr + " type=\"device\">\n"
    "    <kernel version=\"3.18.999\" />\n"
    "    <sepolicy>\n"
    "        <version>25.5</version>\n"
    "    </sepolicy>\n"
    "</manifest>\n";

const std::string systemMatrixKernel318 =
    "<compatibility-matrix " + kMetaVersionStr + " type=\"framework\">\n"
    "    <kernel version=\"3.18.999\"></kernel>\n"
    "    <sepolicy>\n"
    "        <kernel-sepolicy-version>30</kernel-sepolicy-version>\n"
    "        <sepolicy-version>25.5</sepolicy-version>\n"
    "    </sepolicy>\n"
    "</compatibility-matrix>\n";

class VintfObjectTestBase : public ::testing::Test {
   protected:
    MockFileSystem& fetcher() {
        return static_cast<MockFileSystem&>(*vintfObject->getFileSystem());
    }
    MockPropertyFetcher& propertyFetcher() {
        return static_cast<MockPropertyFetcher&>(*vintfObject->getPropertyFetcher());
    }

    // Setup the MockFileSystem 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,
                          const std::string& productModel) {
        ON_CALL(fetcher(), listFiles(StrEq(kVendorManifestFragmentDir), _, _))
            .WillByDefault(Return(::android::OK));
        ON_CALL(fetcher(), listFiles(StrEq(kSystemManifestFragmentDir), _, _))
            .WillByDefault(Return(::android::OK));
        ON_CALL(fetcher(), listFiles(StrEq(kOdmManifestFragmentDir), _, _))
            .WillByDefault(Return(::android::OK));
        ON_CALL(fetcher(), listFiles(StrEq(kProductManifestFragmentDir), _, _))
            .WillByDefault(Return(::android::OK));

        if (!productModel.empty()) {
            ON_CALL(fetcher(),
                    fetch(StrEq(kOdmLegacyVintfDir + "manifest_" + productModel + ".xml"), _))
                .WillByDefault(Return(::android::NAME_NOT_FOUND));
            ON_CALL(fetcher(), fetch(StrEq(kOdmVintfDir + "manifest_" + productModel + ".xml"), _))
                .WillByDefault(Return(::android::NAME_NOT_FOUND));
        }
        ON_CALL(fetcher(), fetch(StrEq(kOdmLegacyManifest), _))
            .WillByDefault(Return(::android::NAME_NOT_FOUND));
        ON_CALL(fetcher(), fetch(StrEq(kOdmManifest), _))
            .WillByDefault(Return(::android::NAME_NOT_FOUND));
        ON_CALL(fetcher(), fetch(StrEq(kVendorManifest), _))
            .WillByDefault(Return(::android::NAME_NOT_FOUND));
        ON_CALL(fetcher(), fetch(StrEq(kVendorLegacyManifest), _))
            .WillByDefault(
                Invoke([vendorManifestXml](const std::string& path, std::string& fetched) {
                    (void)path;
                    fetched = vendorManifestXml;
                    return 0;
                }));
        ON_CALL(fetcher(), fetch(StrEq(kSystemManifest), _))
            .WillByDefault(
                Invoke([systemManifestXml](const std::string& path, std::string& fetched) {
                    (void)path;
                    fetched = systemManifestXml;
                    return 0;
                }));
        ON_CALL(fetcher(), fetch(StrEq(kVendorMatrix), _))
            .WillByDefault(Return(::android::NAME_NOT_FOUND));
        ON_CALL(fetcher(), fetch(StrEq(kVendorLegacyMatrix), _))
            .WillByDefault(Invoke([vendorMatrixXml](const std::string& path, std::string& fetched) {
                (void)path;
                fetched = vendorMatrixXml;
                return 0;
            }));
        ON_CALL(fetcher(), fetch(StrEq(kSystemLegacyMatrix), _))
            .WillByDefault(Invoke([systemMatrixXml](const std::string& path, std::string& fetched) {
                (void)path;
                fetched = systemMatrixXml;
                return 0;
            }));
        // Don't list /system/etc/vintf unless otherwise specified.
        ON_CALL(fetcher(), listFiles(StrEq(kSystemVintfDir), _, _))
            .WillByDefault(Return(::android::OK));
        // Don't fetch product matrix unless otherwise specified.
        ON_CALL(fetcher(), fetch(StrEq(kProductMatrix), _)).WillByDefault(Return(NAME_NOT_FOUND));
        // Don't fetch product manifest unless otherwise specified.
        ON_CALL(fetcher(), fetch(StrEq(kProductManifest), _)).WillByDefault(Return(NAME_NOT_FOUND));
    }

    void setFakeProperties() {
        productModel = "fake_sku";
        ON_CALL(propertyFetcher(), getProperty("ro.boot.product.hardware.sku", _))
            .WillByDefault(Return(productModel));
    }

    virtual void SetUp() {
        vintfObject = VintfObject::Builder()
                          .setFileSystem(std::make_unique<NiceMock<MockFileSystem>>())
                          .setRuntimeInfoFactory(std::make_unique<NiceMock<MockRuntimeInfoFactory>>(
                              std::make_shared<NiceMock<MockRuntimeInfo>>()))
                          .setPropertyFetcher(std::make_unique<NiceMock<MockPropertyFetcher>>())
                          .build();
    }
    virtual void TearDown() {
        Mock::VerifyAndClear(&fetcher());
    }

    void expectVendorManifest(size_t times = 1) {
        EXPECT_CALL(fetcher(), fetch(StrEq(kVendorManifest), _)).Times(times);
        if (!productModel.empty()) {
            EXPECT_CALL(fetcher(),
                        fetch(StrEq(kOdmLegacyVintfDir + "manifest_" + productModel + ".xml"), _))
                .Times(times);
            EXPECT_CALL(fetcher(),
                        fetch(StrEq(kOdmVintfDir + "manifest_" + productModel + ".xml"), _))
                .Times(times);
        }
        EXPECT_CALL(fetcher(), fetch(StrEq(kOdmLegacyManifest), _)).Times(times);
        EXPECT_CALL(fetcher(), fetch(StrEq(kOdmManifest), _)).Times(times);
        EXPECT_CALL(fetcher(), fetch(StrEq(kVendorLegacyManifest), _)).Times(times);
    }

    void expectSystemManifest(size_t times = 1) {
        EXPECT_CALL(fetcher(), fetch(StrEq(kSystemManifest), _)).Times(times);
        EXPECT_CALL(fetcher(), fetch(StrEq(kProductManifest), _)).Times(times);
    }

    void expectVendorMatrix(size_t times = 1) {
        EXPECT_CALL(fetcher(), fetch(StrEq(kVendorMatrix), _)).Times(times);
        EXPECT_CALL(fetcher(), fetch(StrEq(kVendorLegacyMatrix), _)).Times(times);
    }

    void expectSystemMatrix(size_t times = 1) {
        EXPECT_CALL(fetcher(), fetch(StrEq(kProductMatrix), _)).Times(times);
        EXPECT_CALL(fetcher(), fetch(StrEq(kSystemLegacyMatrix), _)).Times(times);
    }

    // Expect that a file exist and should be fetched once.
    void expectFetch(const std::string& path, const std::string& content) {
        EXPECT_CALL(fetcher(), fetch(StrEq(path), _))
            .WillOnce(Invoke([content](const auto&, auto& out) {
                out = content;
                return ::android::OK;
            }));
    }

    // Expect that a file exist and can be fetched 0 or more times.
    void expectFetchRepeatedly(const std::string& path, const std::string& content) {
        EXPECT_CALL(fetcher(), fetch(StrEq(path), _))
            .Times(AnyNumber())
            .WillRepeatedly(Invoke([content](const auto&, auto& out) {
                out = content;
                return ::android::OK;
            }));
    }

    // Expect that the file should never be fetched (whether it exists or not).
    void expectNeverFetch(const std::string& path) {
        EXPECT_CALL(fetcher(), fetch(StrEq(path), _)).Times(0);
    }

    // Expect that the file does not exist, and can be fetched 0 or more times.
    template <typename Matcher>
    void expectFileNotExist(const Matcher& matcher) {
        EXPECT_CALL(fetcher(), fetch(matcher, _))
            .Times(AnyNumber())
            .WillRepeatedly(Return(::android::NAME_NOT_FOUND));
    }

    // Access to private method.
    int checkCompatibility(const std::vector<std::string>& xmls, std::string* error) {
        return vintfObject->checkCompatibility(xmls, error);
    }

    MockRuntimeInfoFactory& runtimeInfoFactory() {
        return static_cast<MockRuntimeInfoFactory&>(*vintfObject->getRuntimeInfoFactory());
    }

    std::string productModel;
    std::unique_ptr<VintfObject> vintfObject;
};

// Test fixture that provides compatible metadata from the mock device.
class VintfObjectCompatibleTest : public VintfObjectTestBase {
   protected:
    virtual void SetUp() {
        VintfObjectTestBase::SetUp();
        setFakeProperties();
        setupMockFetcher(vendorManifestXml1, systemMatrixXml1, systemManifestXml1, vendorMatrixXml1,
                         productModel);
    }
};

// Tests that local info is checked.
TEST_F(VintfObjectCompatibleTest, TestDeviceCompatibility) {
    std::string error;
    std::vector<std::string> packageInfo;

    expectVendorManifest();
    expectSystemManifest();
    expectVendorMatrix();
    expectSystemMatrix();

    int result = checkCompatibility(packageInfo, &error);

    ASSERT_EQ(result, 0) << "Fail message:" << error.c_str();
    // Check that nothing was ignored.
    ASSERT_STREQ(error.c_str(), "");
}

// Tests that input info is checked against device and passes.
TEST_F(VintfObjectCompatibleTest, TestInputVsDeviceSuccess) {
    std::string error;
    std::vector<std::string> packageInfo = {systemMatrixXml1};

    expectVendorManifest();
    expectSystemManifest();
    expectVendorMatrix();
    expectSystemMatrix(0);

    int result = checkCompatibility(packageInfo, &error);

    ASSERT_EQ(result, 0) << "Fail message:" << error.c_str();
    ASSERT_STREQ(error.c_str(), "");
}

// Tests that input info is checked against device and fails.
TEST_F(VintfObjectCompatibleTest, TestInputVsDeviceFail) {
    std::string error;
    std::vector<std::string> packageInfo = {systemMatrixXml2};

    int result = checkCompatibility(packageInfo, &error);

    ASSERT_EQ(result, 1) << "Should have failed:" << error.c_str();
    EXPECT_IN(
        "Device manifest and framework compatibility matrix are incompatible: HALs "
        "incompatible.",
        error);
    EXPECT_IN("android.hardware.foo", error);
}

// Tests that complementary info is checked against itself.
TEST_F(VintfObjectCompatibleTest, TestInputSuccess) {
    std::string error;
    std::vector<std::string> packageInfo = {systemMatrixXml2, vendorManifestXml2};

    int result = 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<std::string> packageInfo = {systemMatrixXml1, systemManifestXml1};

    expectVendorManifest();
    expectSystemManifest(0);
    expectVendorMatrix();
    expectSystemMatrix(0);

    int result = checkCompatibility(packageInfo, &error);

    ASSERT_EQ(result, 0) << "Fail message:" << error.c_str();
    ASSERT_STREQ(error.c_str(), "");
}

TEST_F(VintfObjectCompatibleTest, TestFullOta) {
    std::string error;
    std::vector<std::string> packageInfo = {systemMatrixXml1, systemManifestXml1,
            vendorMatrixXml1, vendorManifestXml1};

    expectVendorManifest(0);
    expectSystemManifest(0);
    expectVendorMatrix(0);
    expectSystemMatrix(0);

    int result = checkCompatibility(packageInfo, &error);

    ASSERT_EQ(result, 0) << "Fail message:" << error.c_str();
    ASSERT_STREQ(error.c_str(), "");
}

// Test that framework-only OTA fails when kernel is not compatible with incoming system.
TEST_F(VintfObjectCompatibleTest, KernelInfoIncompatible) {
    std::string error;
    std::vector<std::string> packageInfo = {systemMatrixKernel318};

    int result = checkCompatibility(packageInfo, &error);

    ASSERT_EQ(result, INCOMPATIBLE) << "Should have failed.";
    EXPECT_IN("Framework is incompatible with kernel version 3.18.31", error);
}

// Test that full OTA is successful when the OTA package provides a compatible kernel.
TEST_F(VintfObjectCompatibleTest, UpdateKernel) {
    std::string error;
    std::vector<std::string> packageInfo = {vendorManifestKernel318, systemMatrixKernel318};

    int result = checkCompatibility(packageInfo, &error);

    ASSERT_EQ(result, COMPATIBLE) << "Fail message:" << error;
    ASSERT_STREQ(error.c_str(), "");
}

// Test fixture that provides incompatible metadata from the mock device.
class VintfObjectIncompatibleTest : public VintfObjectTestBase {
   protected:
    virtual void SetUp() {
        VintfObjectTestBase::SetUp();
        setFakeProperties();
        setupMockFetcher(vendorManifestXml1, systemMatrixXml2, systemManifestXml1, vendorMatrixXml1,
                         productModel);
    }
};

// Fetch all metadata from device and ensure that it fails.
TEST_F(VintfObjectIncompatibleTest, TestDeviceCompatibility) {
    std::string error;
    std::vector<std::string> packageInfo;

    expectVendorManifest();
    expectSystemManifest();
    expectVendorMatrix();
    expectSystemMatrix();

    int result = 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<std::string> packageInfo = {systemMatrixXml1};

    expectVendorManifest();
    expectSystemManifest();
    expectVendorMatrix();
    expectSystemMatrix(0);

    int result = checkCompatibility(packageInfo, &error);

    ASSERT_EQ(result, 0) << "Failed message:" << error.c_str();
    ASSERT_STREQ(error.c_str(), "");
}

// Test fixture that provides compatible metadata from the mock device.
class VintfObjectRuntimeInfoTest : public VintfObjectTestBase {
   protected:
    virtual void SetUp() {
        VintfObjectTestBase::SetUp();
        // clear fetch flags
        runtimeInfoFactory().getInfo()->failNextFetch();
        vintfObject->getRuntimeInfo(true /* skipCache */, RuntimeInfo::FetchFlag::ALL);
    }
    virtual void TearDown() {
        Mock::VerifyAndClear(&runtimeInfoFactory());
        Mock::VerifyAndClear(runtimeInfoFactory().getInfo().get());
    }
};

TEST_F(VintfObjectRuntimeInfoTest, GetRuntimeInfo) {
    InSequence s;

    EXPECT_CALL(*runtimeInfoFactory().getInfo(),
                fetchAllInformation(RuntimeInfo::FetchFlag::CPU_VERSION));
    EXPECT_CALL(*runtimeInfoFactory().getInfo(), fetchAllInformation(RuntimeInfo::FetchFlag::NONE));
    EXPECT_CALL(*runtimeInfoFactory().getInfo(),
                fetchAllInformation(RuntimeInfo::FetchFlag::CPU_VERSION));
    EXPECT_CALL(
        *runtimeInfoFactory().getInfo(),
        fetchAllInformation(RuntimeInfo::FetchFlag::ALL & ~RuntimeInfo::FetchFlag::CPU_VERSION));
    EXPECT_CALL(*runtimeInfoFactory().getInfo(), fetchAllInformation(RuntimeInfo::FetchFlag::ALL));
    EXPECT_CALL(*runtimeInfoFactory().getInfo(), fetchAllInformation(RuntimeInfo::FetchFlag::NONE));

    vintfObject->getRuntimeInfo(false /* skipCache */, RuntimeInfo::FetchFlag::CPU_VERSION);
    vintfObject->getRuntimeInfo(false /* skipCache */, RuntimeInfo::FetchFlag::CPU_VERSION);
    vintfObject->getRuntimeInfo(true /* skipCache */, RuntimeInfo::FetchFlag::CPU_VERSION);
    vintfObject->getRuntimeInfo(false /* skipCache */, RuntimeInfo::FetchFlag::ALL);
    vintfObject->getRuntimeInfo(true /* skipCache */, RuntimeInfo::FetchFlag::ALL);
    vintfObject->getRuntimeInfo(false /* skipCache */, RuntimeInfo::FetchFlag::ALL);
}

// Test fixture that provides incompatible metadata from the mock device.
class VintfObjectTest : public VintfObjectTestBase {
   protected:
    virtual void SetUp() {
        VintfObjectTestBase::SetUp();

        // By default use empty filesystem
        EXPECT_CALL(fetcher(), listFiles(_, _, _))
            .Times(AnyNumber())
            .WillRepeatedly(Return(::android::OK));
        EXPECT_CALL(fetcher(), fetch(_, _))
            .Times(AnyNumber())
            .WillRepeatedly(Return(::android::NAME_NOT_FOUND));
    }
};

// Test framework compatibility matrix is combined at runtime
TEST_F(VintfObjectTest, FrameworkCompatibilityMatrixCombine) {
    EXPECT_CALL(fetcher(), listFiles(StrEq(kSystemVintfDir), _, _))
        .WillOnce(Invoke([](const auto&, auto* out, auto*) {
            *out = {
                "compatibility_matrix.1.xml",
                "compatibility_matrix.empty.xml",
            };
            return ::android::OK;
        }));
    expectFetch(kSystemVintfDir + "compatibility_matrix.1.xml",
                "<compatibility-matrix " + kMetaVersionStr + " type=\"framework\" level=\"1\"/>");
    expectFetch(kSystemVintfDir + "compatibility_matrix.empty.xml",
                "<compatibility-matrix " + kMetaVersionStr + " type=\"framework\"/>");
    expectFileNotExist(StrEq(kProductMatrix));
    expectFetch(kVendorManifest, "<manifest " + kMetaVersionStr + " type=\"device\" />\n");
    expectNeverFetch(kSystemLegacyMatrix);

    EXPECT_NE(nullptr, vintfObject->getFrameworkCompatibilityMatrix(true /* skipCache */));
}

// Test product compatibility matrix is fetched
TEST_F(VintfObjectTest, ProductCompatibilityMatrix) {
    EXPECT_CALL(fetcher(), listFiles(StrEq(kSystemVintfDir), _, _))
        .WillOnce(Invoke([](const auto&, auto* out, auto*) {
            *out = {
                "compatibility_matrix.1.xml",
                "compatibility_matrix.empty.xml",
            };
            return ::android::OK;
        }));
    expectFetch(kSystemVintfDir + "compatibility_matrix.1.xml",
                "<compatibility-matrix " + kMetaVersionStr + " type=\"framework\" level=\"1\"/>");
    expectFetch(kSystemVintfDir + "compatibility_matrix.empty.xml",
                "<compatibility-matrix " + kMetaVersionStr + " type=\"framework\"/>");
    expectFetch(kProductMatrix,
                "<compatibility-matrix " + kMetaVersionStr + " type=\"framework\">\n"
                "    <hal format=\"hidl\" optional=\"true\">\n"
                "        <name>android.hardware.foo</name>\n"
                "        <version>1.0</version>\n"
                "        <interface>\n"
                "            <name>IFoo</name>\n"
                "            <instance>default</instance>\n"
                "        </interface>\n"
                "    </hal>\n"
                "</compatibility-matrix>\n");
    expectFetch(kVendorManifest, "<manifest " + kMetaVersionStr + " type=\"device\" />\n");
    expectNeverFetch(kSystemLegacyMatrix);

    auto fcm = vintfObject->getFrameworkCompatibilityMatrix(true /* skipCache */);
    ASSERT_NE(nullptr, fcm);

    FqInstance expectInstance;
    EXPECT_TRUE(expectInstance.setTo("android.hardware.foo@1.0::IFoo/default"));
    bool found = false;
    fcm->forEachHidlInstance([&found, &expectInstance](const auto& matrixInstance) {
        found |= matrixInstance.isSatisfiedBy(expectInstance);
        return !found;  // continue if not found
    });
    EXPECT_TRUE(found) << "android.hardware.foo@1.0::IFoo/default should be found in matrix:\n"
                       << gCompatibilityMatrixConverter(*fcm);
}

const std::string vendorEtcManifest =
    "<manifest " + kMetaVersionStr + " type=\"device\">\n"
    "    <hal format=\"hidl\">\n"
    "        <name>android.hardware.foo</name>\n"
    "        <transport>hwbinder</transport>\n"
    "        <version>1.0</version>\n"
    "        <version>2.0</version>\n"
    "        <interface>\n"
    "            <name>IVendorEtc</name>\n"
    "            <instance>default</instance>\n"
    "        </interface>\n"
    "    </hal>\n"
    "</manifest>\n";

const std::string vendorManifest =
    "<manifest " + kMetaVersionStr + " type=\"device\">\n"
    "    <hal format=\"hidl\">\n"
    "        <name>android.hardware.foo</name>\n"
    "        <transport>hwbinder</transport>\n"
    "        <version>1.0</version>\n"
    "        <interface>\n"
    "            <name>IVendor</name>\n"
    "            <instance>default</instance>\n"
    "        </interface>\n"
    "    </hal>\n"
    "</manifest>\n";

const std::string odmProductManifest =
    "<manifest " + kMetaVersionStr + " type=\"device\">\n"
    "    <hal format=\"hidl\" override=\"true\">\n"
    "        <name>android.hardware.foo</name>\n"
    "        <transport>hwbinder</transport>\n"
    "        <version>1.1</version>\n"
    "        <interface>\n"
    "            <name>IOdmProduct</name>\n"
    "            <instance>default</instance>\n"
    "        </interface>\n"
    "    </hal>\n"
    "</manifest>\n";

const std::string odmManifest =
    "<manifest " + kMetaVersionStr + " type=\"device\">\n"
    "    <hal format=\"hidl\" override=\"true\">\n"
    "        <name>android.hardware.foo</name>\n"
    "        <transport>hwbinder</transport>\n"
    "        <version>1.1</version>\n"
    "        <interface>\n"
    "            <name>IOdm</name>\n"
    "            <instance>default</instance>\n"
    "        </interface>\n"
    "    </hal>\n"
    "</manifest>\n";

bool containsVendorManifest(const std::shared_ptr<const HalManifest>& p) {
    return !p->getHidlInstances("android.hardware.foo", {1, 0}, "IVendor").empty();
}

bool containsVendorEtcManifest(const std::shared_ptr<const HalManifest>& p) {
    return !p->getHidlInstances("android.hardware.foo", {2, 0}, "IVendorEtc").empty();
}

bool vendorEtcManifestOverridden(const std::shared_ptr<const HalManifest>& p) {
    return p->getHidlInstances("android.hardware.foo", {1, 0}, "IVendorEtc").empty();
}

bool containsOdmManifest(const std::shared_ptr<const HalManifest>& p) {
    return !p->getHidlInstances("android.hardware.foo", {1, 1}, "IOdm").empty();
}

bool containsOdmProductManifest(const std::shared_ptr<const HalManifest>& p) {
    return !p->getHidlInstances("android.hardware.foo", {1, 1}, "IOdmProduct").empty();
}

class DeviceManifestTest : public VintfObjectTestBase {
   protected:
    virtual void SetUp() {
        VintfObjectTestBase::SetUp();
        setFakeProperties();
    }

    // Expect that /vendor/etc/vintf/manifest.xml is fetched.
    void expectVendorManifest() { expectFetch(kVendorManifest, vendorEtcManifest); }
    // /vendor/etc/vintf/manifest.xml does not exist.
    void noVendorManifest() { expectFileNotExist(StrEq(kVendorManifest)); }
    // Expect some ODM manifest is fetched.
    void expectOdmManifest() {
        if (!productModel.empty()) {
            expectFileNotExist(StrEq(kOdmVintfDir + "manifest_" + productModel + ".xml"));
        }
        expectFetch(kOdmManifest, odmManifest);
    }
    void noOdmManifest() { expectFileNotExist(StartsWith("/odm/")); }
    std::shared_ptr<const HalManifest> get() {
        return vintfObject->getDeviceHalManifest(true /* skipCache */);
    }
};

// Test /vendor/etc/vintf/manifest.xml + ODM manifest
TEST_F(DeviceManifestTest, Combine1) {
    expectVendorManifest();
    expectOdmManifest();
    auto p = get();
    ASSERT_NE(nullptr, p);
    EXPECT_TRUE(containsVendorEtcManifest(p));
    EXPECT_TRUE(vendorEtcManifestOverridden(p));
    EXPECT_TRUE(containsOdmManifest(p));
    EXPECT_FALSE(containsVendorManifest(p));
}

// Test /vendor/etc/vintf/manifest.xml
TEST_F(DeviceManifestTest, Combine2) {
    expectVendorManifest();
    noOdmManifest();
    auto p = get();
    ASSERT_NE(nullptr, p);
    EXPECT_TRUE(containsVendorEtcManifest(p));
    EXPECT_FALSE(vendorEtcManifestOverridden(p));
    EXPECT_FALSE(containsOdmManifest(p));
    EXPECT_FALSE(containsVendorManifest(p));
}

// Test ODM manifest
TEST_F(DeviceManifestTest, Combine3) {
    noVendorManifest();
    expectOdmManifest();
    auto p = get();
    ASSERT_NE(nullptr, p);
    EXPECT_FALSE(containsVendorEtcManifest(p));
    EXPECT_TRUE(vendorEtcManifestOverridden(p));
    EXPECT_TRUE(containsOdmManifest(p));
    EXPECT_FALSE(containsVendorManifest(p));
}

// Test /vendor/manifest.xml
TEST_F(DeviceManifestTest, Combine4) {
    noVendorManifest();
    noOdmManifest();
    expectFetch(kVendorLegacyManifest, vendorManifest);
    auto p = get();
    ASSERT_NE(nullptr, p);
    EXPECT_FALSE(containsVendorEtcManifest(p));
    EXPECT_TRUE(vendorEtcManifestOverridden(p));
    EXPECT_FALSE(containsOdmManifest(p));
    EXPECT_TRUE(containsVendorManifest(p));
}

class OdmManifestTest : public VintfObjectTestBase {
   protected:
    virtual void SetUp() override {
        VintfObjectTestBase::SetUp();
        // Assume /vendor/etc/vintf/manifest.xml does not exist to simplify
        // testing logic.
        expectFileNotExist(StrEq(kVendorManifest));
        // Expect that the legacy /vendor/manifest.xml is never fetched.
        expectNeverFetch(kVendorLegacyManifest);
        // Assume no files exist under /odm/ unless otherwise specified.
        expectFileNotExist(StartsWith("/odm/"));
    }
    std::shared_ptr<const HalManifest> get() {
        return vintfObject->getDeviceHalManifest(true /* skipCache */);
    }
};

TEST_F(OdmManifestTest, OdmProductManifest) {
    if (productModel.empty()) return;
    expectFetch(kOdmVintfDir + "manifest_" + productModel + ".xml", odmProductManifest);
    // /odm/etc/vintf/manifest.xml should not be fetched when the product variant exists.
    expectNeverFetch(kOdmManifest);
    auto p = get();
    ASSERT_NE(nullptr, p);
    EXPECT_TRUE(containsOdmProductManifest(p));
}

TEST_F(OdmManifestTest, OdmManifest) {
    expectFetch(kOdmManifest, odmManifest);
    auto p = get();
    ASSERT_NE(nullptr, p);
    EXPECT_TRUE(containsOdmManifest(p));
}

TEST_F(OdmManifestTest, OdmLegacyProductManifest) {
    if (productModel.empty()) return;
    expectFetch(kOdmLegacyVintfDir + "manifest_" + productModel + ".xml", odmProductManifest);
    // /odm/manifest.xml should not be fetched when the product variant exists.
    expectNeverFetch(kOdmLegacyManifest);
    auto p = get();
    ASSERT_NE(nullptr, p);
    EXPECT_TRUE(containsOdmProductManifest(p));
}

TEST_F(OdmManifestTest, OdmLegacyManifest) {
    expectFetch(kOdmLegacyManifest, odmManifest);
    auto p = get();
    ASSERT_NE(nullptr, p);
    EXPECT_TRUE(containsOdmManifest(p));
}

struct CheckedFqInstance : FqInstance {
    CheckedFqInstance(const char* s) : CheckedFqInstance(std::string(s)) {}
    CheckedFqInstance(const std::string& s) { CHECK(setTo(s)) << s; }

    Version getVersion() const { return FqInstance::getVersion(); }
};

static VintfObject::ListInstances getInstanceListFunc(
    const std::vector<CheckedFqInstance>& instances) {
    return [instances](const std::string& package, Version version, const std::string& interface,
                       const auto& /* instanceHint */) {
        std::vector<std::pair<std::string, Version>> ret;
        for (auto&& existing : instances) {
            if (existing.getPackage() == package && existing.getVersion().minorAtLeast(version) &&
                existing.getInterface() == interface) {
                ret.push_back(std::make_pair(existing.getInstance(), existing.getVersion()));
            }
        }

        return ret;
    };
}

class DeprecateTest : public VintfObjectTestBase {
   protected:
    virtual void SetUp() override {
        VintfObjectTestBase::SetUp();
        EXPECT_CALL(fetcher(), listFiles(StrEq(kSystemVintfDir), _, _))
            .WillRepeatedly(Invoke([](const auto&, auto* out, auto*) {
                *out = {
                    "compatibility_matrix.1.xml",
                    "compatibility_matrix.2.xml",
                };
                return ::android::OK;
            }));
        EXPECT_CALL(fetcher(), listFiles(StrEq(kVendorManifestFragmentDir), _, _))
            .WillOnce(Return(::android::OK));
        EXPECT_CALL(fetcher(), listFiles(StrEq(kOdmManifestFragmentDir), _, _))
            .WillOnce(Return(::android::OK));
        expectFetch(kSystemVintfDir + "compatibility_matrix.1.xml", systemMatrixLevel1);
        expectFetch(kSystemVintfDir + "compatibility_matrix.2.xml", systemMatrixLevel2);
        expectFileNotExist(StrEq(kProductMatrix));
        expectNeverFetch(kSystemLegacyMatrix);

        expectFetch(kVendorManifest,
                    "<manifest " + kMetaVersionStr + " type=\"device\" target-level=\"2\"/>");
        expectFileNotExist(StartsWith("/odm/"));

        // Update the device manifest cache because CheckDeprecate does not fetch
        // device manifest again if cache exist.
        vintfObject->getDeviceHalManifest(true /* skipCache */);
    }

};

TEST_F(DeprecateTest, CheckNoDeprecate) {
    auto pred = getInstanceListFunc({
        "android.hardware.minor@1.1::IMinor/default",
        "android.hardware.major@2.0::IMajor/default",
    });
    std::string error;
    EXPECT_EQ(NO_DEPRECATED_HALS, vintfObject->checkDeprecation(pred, &error)) << error;
}

TEST_F(DeprecateTest, CheckRemoved) {
    auto pred = getInstanceListFunc({
        "android.hardware.removed@1.0::IRemoved/default",
        "android.hardware.minor@1.1::IMinor/default",
        "android.hardware.major@2.0::IMajor/default",
    });
    std::string error;
    EXPECT_EQ(DEPRECATED, vintfObject->checkDeprecation(pred, &error))
        << "removed@1.0 should be deprecated. " << error;
}

TEST_F(DeprecateTest, CheckMinor) {
    auto pred = getInstanceListFunc({
        "android.hardware.minor@1.0::IMinor/default",
        "android.hardware.major@2.0::IMajor/default",
    });
    std::string error;
    EXPECT_EQ(DEPRECATED, vintfObject->checkDeprecation(pred, &error))
        << "minor@1.0 should be deprecated. " << error;
}

TEST_F(DeprecateTest, CheckMinorDeprecatedInstance1) {
    auto pred = getInstanceListFunc({
        "android.hardware.minor@1.0::IMinor/legacy",
        "android.hardware.minor@1.1::IMinor/default",
        "android.hardware.major@2.0::IMajor/default",
    });
    std::string error;
    EXPECT_EQ(DEPRECATED, vintfObject->checkDeprecation(pred, &error))
        << "minor@1.0::IMinor/legacy should be deprecated. " << error;
}

TEST_F(DeprecateTest, CheckMinorDeprecatedInstance2) {
    auto pred = getInstanceListFunc({
        "android.hardware.minor@1.1::IMinor/default",
        "android.hardware.minor@1.1::IMinor/legacy",
        "android.hardware.major@2.0::IMajor/default",
    });
    std::string error;
    EXPECT_EQ(DEPRECATED, vintfObject->checkDeprecation(pred, &error))
        << "minor@1.1::IMinor/legacy should be deprecated. " << error;
}

TEST_F(DeprecateTest, CheckMajor1) {
    auto pred = getInstanceListFunc({
        "android.hardware.minor@1.1::IMinor/default",
        "android.hardware.major@1.0::IMajor/default",
        "android.hardware.major@2.0::IMajor/default",
    });
    std::string error;
    EXPECT_EQ(DEPRECATED, vintfObject->checkDeprecation(pred, &error))
        << "major@1.0 should be deprecated. " << error;
}

TEST_F(DeprecateTest, CheckMajor2) {
    auto pred = getInstanceListFunc({
        "android.hardware.minor@1.1::IMinor/default",
        "android.hardware.major@1.0::IMajor/default",
    });
    std::string error;
    EXPECT_EQ(DEPRECATED, vintfObject->checkDeprecation(pred, &error))
        << "major@1.0 should be deprecated. " << error;
}

class MultiMatrixTest : public VintfObjectTestBase {
   protected:
    static std::string getFileName(size_t i) {
        return "compatibility_matrix." + std::to_string(static_cast<Level>(i)) + ".xml";
    }
    void SetUpMockSystemMatrices(const std::vector<std::string>& xmls) {
        EXPECT_CALL(fetcher(), listFiles(_, _, _))
            .Times(AnyNumber())
            .WillRepeatedly(Return(::android::OK));
        EXPECT_CALL(fetcher(), listFiles(StrEq(kSystemVintfDir), _, _))
            .WillRepeatedly(Invoke([=](const auto&, auto* out, auto*) {
                size_t i = 1;
                for (const auto& content : xmls) {
                    (void)content;
                    out->push_back(getFileName(i));
                    ++i;
                }
                return ::android::OK;
            }));
        size_t i = 1;
        for (const auto& content : xmls) {
            expectFetchRepeatedly(kSystemVintfDir + getFileName(i), content);
            ++i;
        }
        expectFileNotExist(kProductMatrix);
        expectNeverFetch(kSystemLegacyMatrix);
        expectFileNotExist(StartsWith("/odm/"));
    }
    void expectTargetFcmVersion(size_t level) {
        expectFetch(kVendorManifest, "<manifest " + kMetaVersionStr + " type=\"device\" target-level=\"" +
                                         to_string(static_cast<Level>(level)) + "\"/>");
        vintfObject->getDeviceHalManifest(true /* skipCache */);
    }
};

class RegexTest : public MultiMatrixTest {
   protected:
    virtual void SetUp() {
        MultiMatrixTest::SetUp();
        SetUpMockSystemMatrices(systemMatrixRegexXmls);
    }
};

TEST_F(RegexTest, CombineLevel1) {
    expectTargetFcmVersion(1);
    auto matrix = vintfObject->getFrameworkCompatibilityMatrix(true /* skipCache */);
    ASSERT_NE(nullptr, matrix);
    std::string xml = gCompatibilityMatrixConverter(*matrix);

    EXPECT_IN(
        "    <hal format=\"hidl\" optional=\"false\">\n"
        "        <name>android.hardware.regex</name>\n"
        "        <version>1.0-2</version>\n"
        "        <version>2.0</version>\n"
        "        <interface>\n"
        "            <name>IRegex</name>\n"
        "            <instance>default</instance>\n"
        "        </interface>\n"
        "    </hal>\n",
        xml);
    EXPECT_IN(
        "    <hal format=\"hidl\" optional=\"false\">\n"
        "        <name>android.hardware.regex</name>\n"
        "        <version>1.0-1</version>\n"
        "        <interface>\n"
        "            <name>IRegex</name>\n"
        "            <instance>special/1.0</instance>\n"
        "            <regex-instance>regex/1.0/[0-9]+</regex-instance>\n"
        "            <regex-instance>regex_common/[0-9]+</regex-instance>\n"
        "        </interface>\n"
        "    </hal>\n",
        xml);
    EXPECT_IN(
        "    <hal format=\"hidl\" optional=\"true\">\n"
        "        <name>android.hardware.regex</name>\n"
        "        <version>1.1-2</version>\n"
        "        <interface>\n"
        "            <name>IRegex</name>\n"
        "            <instance>special/1.1</instance>\n"
        "            <regex-instance>[a-z]+_[a-z]+/[0-9]+</regex-instance>\n"
        "            <regex-instance>regex/1.1/[0-9]+</regex-instance>\n"
        "        </interface>\n"
        "    </hal>\n",
        xml);
    EXPECT_IN(
        "    <hal format=\"hidl\" optional=\"true\">\n"
        "        <name>android.hardware.regex</name>\n"
        "        <version>2.0</version>\n"
        "        <interface>\n"
        "            <name>IRegex</name>\n"
        "            <instance>special/2.0</instance>\n"
        "            <regex-instance>regex/2.0/[0-9]+</regex-instance>\n"
        "            <regex-instance>regex_[a-z]+/[0-9]+</regex-instance>\n"
        "        </interface>\n"
        "    </hal>\n",
        xml);
}

TEST_F(RegexTest, CombineLevel2) {
    expectTargetFcmVersion(2);
    auto matrix = vintfObject->getFrameworkCompatibilityMatrix(true /* skipCache */);
    ASSERT_NE(nullptr, matrix);
    std::string xml = gCompatibilityMatrixConverter(*matrix);

    EXPECT_IN(
        "    <hal format=\"hidl\" optional=\"false\">\n"
        "        <name>android.hardware.regex</name>\n"
        "        <version>1.1-2</version>\n"
        "        <version>2.0</version>\n"
        "        <interface>\n"
        "            <name>IRegex</name>\n"
        "            <instance>default</instance>\n"
        "        </interface>\n"
        "    </hal>\n",
        xml);
    EXPECT_IN(
        "    <hal format=\"hidl\" optional=\"false\">\n"
        "        <name>android.hardware.regex</name>\n"
        "        <version>1.1-2</version>\n"
        "        <interface>\n"
        "            <name>IRegex</name>\n"
        "            <instance>special/1.1</instance>\n"
        "            <regex-instance>[a-z]+_[a-z]+/[0-9]+</regex-instance>\n"
        "            <regex-instance>regex/1.1/[0-9]+</regex-instance>\n"
        "        </interface>\n"
        "    </hal>\n",
        xml);
    EXPECT_IN(
        "    <hal format=\"hidl\" optional=\"true\">\n"
        "        <name>android.hardware.regex</name>\n"
        "        <version>2.0</version>\n"
        "        <interface>\n"
        "            <name>IRegex</name>\n"
        "            <instance>special/2.0</instance>\n"
        "            <regex-instance>regex/2.0/[0-9]+</regex-instance>\n"
        "            <regex-instance>regex_[a-z]+/[0-9]+</regex-instance>\n"
        "        </interface>\n"
        "    </hal>\n",
        xml);
}

TEST_F(RegexTest, DeprecateLevel2) {
    std::string error;
    expectTargetFcmVersion(2);

    auto pred = getInstanceListFunc({
        "android.hardware.regex@1.1::IRegex/default",
        "android.hardware.regex@1.1::IRegex/special/1.1",
        "android.hardware.regex@1.1::IRegex/regex/1.1/1",
        "android.hardware.regex@1.1::IRegex/regex_common/0",
        "android.hardware.regex@2.0::IRegex/default",
    });
    EXPECT_EQ(NO_DEPRECATED_HALS, vintfObject->checkDeprecation(pred, &error)) << error;

    for (const auto& deprecated : {
             "android.hardware.regex@1.0::IRegex/default",
             "android.hardware.regex@1.0::IRegex/special/1.0",
             "android.hardware.regex@1.0::IRegex/regex/1.0/1",
             "android.hardware.regex@1.0::IRegex/regex_common/0",
             "android.hardware.regex@1.1::IRegex/special/1.0",
             "android.hardware.regex@1.1::IRegex/regex/1.0/1",
         }) {
        // 2.0/default ensures compatibility.
        pred = getInstanceListFunc({
            deprecated,
            "android.hardware.regex@2.0::IRegex/default",
        });
        error.clear();
        EXPECT_EQ(DEPRECATED, vintfObject->checkDeprecation(pred, &error))
            << deprecated << " should be deprecated. " << error;
    }
}

TEST_F(RegexTest, DeprecateLevel3) {
    std::string error;
    expectTargetFcmVersion(3);

    auto pred = getInstanceListFunc({
        "android.hardware.regex@2.0::IRegex/special/2.0",
        "android.hardware.regex@2.0::IRegex/regex/2.0/1",
        "android.hardware.regex@2.0::IRegex/default",
    });
    EXPECT_EQ(NO_DEPRECATED_HALS, vintfObject->checkDeprecation(pred, &error)) << error;

    for (const auto& deprecated : {
             "android.hardware.regex@1.0::IRegex/default",
             "android.hardware.regex@1.0::IRegex/special/1.0",
             "android.hardware.regex@1.0::IRegex/regex/1.0/1",
             "android.hardware.regex@1.0::IRegex/regex_common/0",
             "android.hardware.regex@1.1::IRegex/special/1.0",
             "android.hardware.regex@1.1::IRegex/regex/1.0/1",
             "android.hardware.regex@1.1::IRegex/special/1.1",
             "android.hardware.regex@1.1::IRegex/regex/1.1/1",
             "android.hardware.regex@1.1::IRegex/regex_common/0",
         }) {
        // 2.0/default ensures compatibility.
        pred = getInstanceListFunc({
            deprecated,
            "android.hardware.regex@2.0::IRegex/default",
        });

        error.clear();
        EXPECT_EQ(DEPRECATED, vintfObject->checkDeprecation(pred, &error))
            << deprecated << " should be deprecated.";
    }
}

//
// Set of framework matrices of different FCM version with <kernel>.
//

#define FAKE_KERNEL(__version__, __key__)                   \
    "    <kernel version=\"" __version__ "\">\n"            \
    "        <config>\n"                                    \
    "            <key>CONFIG_" __key__ "</key>\n"           \
    "            <value type=\"tristate\">y</value>\n"      \
    "        </config>\n"                                   \
    "    </kernel>\n"

const static std::vector<std::string> systemMatrixKernelXmls = {
    // 1.xml
    "<compatibility-matrix " + kMetaVersionStr + " type=\"framework\" level=\"1\">\n"
    FAKE_KERNEL("1.0.0", "A1")
    FAKE_KERNEL("2.0.0", "B1")
    "</compatibility-matrix>\n",
    // 2.xml
    "<compatibility-matrix " + kMetaVersionStr + " type=\"framework\" level=\"2\">\n"
    FAKE_KERNEL("2.0.0", "B2")
    FAKE_KERNEL("3.0.0", "C2")
    FAKE_KERNEL("4.0.0", "D2")
    "</compatibility-matrix>\n",
    // 3.xml
    "<compatibility-matrix " + kMetaVersionStr + " type=\"framework\" level=\"3\">\n"
    FAKE_KERNEL("4.0.0", "D3")
    FAKE_KERNEL("5.0.0", "E3")
    "</compatibility-matrix>\n",
};

class KernelTest : public MultiMatrixTest {};

// Assume that we are developing level 2. Test that old <kernel> requirements should
// not change and new <kernel> versions are added.
TEST_F(KernelTest, Level1AndLevel2) {
    SetUpMockSystemMatrices({systemMatrixKernelXmls[0], systemMatrixKernelXmls[1]});

    expectTargetFcmVersion(1);
    auto matrix = vintfObject->getFrameworkCompatibilityMatrix(true /* skipCache */);
    ASSERT_NE(nullptr, matrix);
    std::string xml = gCompatibilityMatrixConverter(*matrix);

    EXPECT_IN(FAKE_KERNEL("1.0.0", "A1"), xml) << "\nOld requirements must not change.";
    EXPECT_IN(FAKE_KERNEL("2.0.0", "B1"), xml) << "\nOld requirements must not change.";
    EXPECT_IN(FAKE_KERNEL("3.0.0", "C2"), xml) << "\nShould see <kernel> from new matrices";
    EXPECT_IN(FAKE_KERNEL("4.0.0", "D2"), xml) << "\nShould see <kernel> from new matrices";

    EXPECT_NOT_IN(FAKE_KERNEL("2.0.0", "B2"), xml) << "\nOld requirements must not change";
}

// Assume that we are developing level 3. Test that old <kernel> requirements should
// not change and new <kernel> versions are added.
TEST_F(KernelTest, Level1AndMore) {
    SetUpMockSystemMatrices({systemMatrixKernelXmls});

    expectTargetFcmVersion(1);
    auto matrix = vintfObject->getFrameworkCompatibilityMatrix(true /* skipCache */);
    ASSERT_NE(nullptr, matrix);
    std::string xml = gCompatibilityMatrixConverter(*matrix);

    EXPECT_IN(FAKE_KERNEL("1.0.0", "A1"), xml) << "\nOld requirements must not change.";
    EXPECT_IN(FAKE_KERNEL("2.0.0", "B1"), xml) << "\nOld requirements must not change.";
    EXPECT_IN(FAKE_KERNEL("3.0.0", "C2"), xml) << "\nOld requirements must not change.";
    EXPECT_IN(FAKE_KERNEL("4.0.0", "D2"), xml) << "\nOld requirements must not change.";
    EXPECT_IN(FAKE_KERNEL("5.0.0", "E3"), xml) << "\nShould see <kernel> from new matrices";

    EXPECT_NOT_IN(FAKE_KERNEL("2.0.0", "B2"), xml) << "\nOld requirements must not change";
    EXPECT_NOT_IN(FAKE_KERNEL("4.0.0", "D3"), xml) << "\nOld requirements must not change";
}

class VintfObjectPartialUpdateTest : public MultiMatrixTest {
   protected:
    void SetUp() override {
        MultiMatrixTest::SetUp();
        setFakeProperties();
    }
};

TEST_F(VintfObjectPartialUpdateTest, DeviceCompatibility) {
    setupMockFetcher(vendorManifestRequire1, "", systemManifestXml1, vendorMatrixXml1,
                     productModel);
    SetUpMockSystemMatrices(systemMatrixRequire);

    expectSystemManifest();
    expectVendorMatrix();
    expectVendorManifest();

    std::string error;
    EXPECT_TRUE(checkCompatibility({}, &error)) << error;
}

TEST_F(VintfObjectPartialUpdateTest, VendorOnlyCompatible) {
    setupMockFetcher("", "", systemManifestXml1, vendorMatrixXml1, productModel);
    SetUpMockSystemMatrices(systemMatrixRequire);

    expectSystemManifest();
    expectVendorMatrix();
    // Should not load vendor manifest from device
    expectVendorManifest(0);

    std::string error;
    EXPECT_TRUE(checkCompatibility({vendorManifestRequire2}, &error)) << error;
}

const std::string systemEtcManifest =
    "<manifest " + kMetaVersionStr + " type=\"framework\">\n"
    "    <hal format=\"hidl\">\n"
    "        <name>android.hardware.foo</name>\n"
    "        <transport>hwbinder</transport>\n"
    "        <fqname>@1.0::ISystemEtc/default</fqname>\n"
    "    </hal>\n"
    "</manifest>\n";

const std::string systemEtcManifestFrag =
    "<manifest " + kMetaVersionStr + " type=\"framework\">\n"
    "    <hal format=\"hidl\">\n"
    "        <name>android.hardware.foo</name>\n"
    "        <transport>hwbinder</transport>\n"
    "        <fqname>@1.0::ISystemEtcFragment/default</fqname>\n"
    "    </hal>\n"
    "</manifest>\n";

const std::string productEtcManifest =
    "<manifest " + kMetaVersionStr + " type=\"framework\">\n"
    "    <hal format=\"hidl\">\n"
    "        <name>android.hardware.foo</name>\n"
    "        <transport>hwbinder</transport>\n"
    "        <fqname>@1.0::IProductEtc/default</fqname>\n"
    "    </hal>\n"
    "</manifest>\n";

const std::string productEtcManifestFrag =
    "<manifest " + kMetaVersionStr + " type=\"framework\">\n"
    "    <hal format=\"hidl\">\n"
    "        <name>android.hardware.foo</name>\n"
    "        <transport>hwbinder</transport>\n"
    "        <fqname>@1.0::IProductEtcFragment/default</fqname>\n"
    "    </hal>\n"
    "</manifest>\n";

using FrameworkManifestTestParam =
    std::tuple<bool /* Existence of /system/etc/vintf/manifest.xml */,
               bool /* Existence of /system/etc/vintf/manifest/fragment.xml */,
               bool /* Existence of /product/etc/vintf/manifest.xml */,
               bool /* Existence of /product/etc/vintf/manifest/fragment.xml */>;
class FrameworkManifestTest : public VintfObjectTestBase,
                              public ::testing::WithParamInterface<FrameworkManifestTestParam> {
   protected:
    virtual void SetUp() {
        VintfObjectTestBase::SetUp();
        setFakeProperties();
    }

    // Set the existence of /system/etc/vintf/manifest.xml
    void expectSystemManifest(bool exists) {
        if (exists) {
            expectFetchRepeatedly(kSystemManifest, systemEtcManifest);
        } else {
            expectFileNotExist(StrEq(kSystemManifest));
        }
        expectFileNotExist(StrEq(kSystemLegacyManifest));
    }
    // Set the existence of /system/etc/vintf/manifest/fragment.xml
    void expectSystemManifestFragment(bool exists) {
        if (exists) {
            EXPECT_CALL(fetcher(), listFiles(StrEq(kSystemManifestFragmentDir), _, _))
                .Times(AnyNumber())
                .WillRepeatedly(Invoke([](const auto&, auto* out, auto*) {
                    *out = {"fragment.xml"};
                    return ::android::OK;
                }));
            expectFetchRepeatedly(kSystemManifestFragmentDir + "fragment.xml",
                                  systemEtcManifestFrag);
        } else {
            EXPECT_CALL(fetcher(), listFiles(StrEq(kSystemManifestFragmentDir), _, _))
                .Times(AnyNumber())
                .WillRepeatedly(Return(::android::OK));
            expectFileNotExist(kSystemManifestFragmentDir + "fragment.xml");
        }
    }
    // Set the existence of /product/etc/vintf/manifest.xml
    void expectProductManifest(bool exists) {
        if (exists) {
            expectFetchRepeatedly(kProductManifest, productEtcManifest);
        } else {
            expectFileNotExist(kProductManifest);
        }
    }
    // Set the existence of /product/etc/vintf/manifest/fragment.xml
    void expectProductManifestFragment(bool exists) {
        if (exists) {
            EXPECT_CALL(fetcher(), listFiles(StrEq(kProductManifestFragmentDir), _, _))
                .Times(AnyNumber())
                .WillRepeatedly(Invoke([](const auto&, auto* out, auto*) {
                    *out = {"fragment.xml"};
                    return ::android::OK;
                }));
            expectFetchRepeatedly(kProductManifestFragmentDir + "fragment.xml",
                                  productEtcManifestFrag);
        } else {
            EXPECT_CALL(fetcher(), listFiles(StrEq(kProductManifestFragmentDir), _, _))
                .Times(AnyNumber())
                .WillRepeatedly(Return(::android::OK));
            expectFileNotExist(kProductManifestFragmentDir + "fragment.xml");
        }
    }

    void expectContainsInterface(const std::string& interface, bool contains = true) {
        auto manifest = vintfObject->getFrameworkHalManifest();
        ASSERT_NE(nullptr, manifest);
        EXPECT_NE(manifest->getHidlInstances("android.hardware.foo", {1, 0}, interface).empty(),
                  contains)
            << interface << " is missing.";
    }
};

TEST_P(FrameworkManifestTest, Existence) {
    expectSystemManifest(std::get<0>(GetParam()));
    expectSystemManifestFragment(std::get<1>(GetParam()));
    expectProductManifest(std::get<2>(GetParam()));
    expectProductManifestFragment(std::get<3>(GetParam()));

    if (!std::get<0>(GetParam())) {
        EXPECT_EQ(nullptr, vintfObject->getFrameworkHalManifest())
            << "getFrameworkHalManifest must return nullptr if " << kSystemManifest
            << " does not exist";
    } else {
        expectContainsInterface("ISystemEtc", std::get<0>(GetParam()));
        expectContainsInterface("ISystemEtcFragment", std::get<1>(GetParam()));
        expectContainsInterface("IProductEtc", std::get<2>(GetParam()));
        expectContainsInterface("IProductEtcFragment", std::get<3>(GetParam()));
    }
}
INSTANTIATE_TEST_SUITE_P(, FrameworkManifestTest,
                         ::testing::Combine(Bool(), Bool(), Bool(), Bool()));

class GetCompatibleKernelRequirementTest : public MultiMatrixTest {
   protected:
    void SetUp() override {
        MultiMatrixTest::SetUp();
        SetUpMockSystemMatrices(systemMatrixKernelXmls);
        expectTargetFcmVersion(1);
    }
};

TEST_F(GetCompatibleKernelRequirementTest, Version1) {
    runtimeInfoFactory().getInfo()->setNextFetchKernelInfo({1, 0, 1}, {{"CONFIG_A1", "y"}});
    auto kreq = vintfObject->getCompatibleKernelRequirement();
    ASSERT_TRUE(kreq.has_value());
    EXPECT_EQ(1u, kreq->level());
    EXPECT_EQ(KernelVersion(1, 0, 0), kreq->minLts());
}

TEST_F(GetCompatibleKernelRequirementTest, Version1Incompat) {
    runtimeInfoFactory().getInfo()->setNextFetchKernelInfo({1, 0, 0}, {});
    auto kreq = vintfObject->getCompatibleKernelRequirement();
    EXPECT_FALSE(kreq.has_value())
        << "Should be incompatible because CONFIG_A1 is missing, but get: (" << kreq->level()
        << ", " << kreq->minLts() << ")";
}

TEST_F(GetCompatibleKernelRequirementTest, Version2) {
    runtimeInfoFactory().getInfo()->setNextFetchKernelInfo({2, 0, 1}, {{"CONFIG_B1", "y"}});
    auto kreq = vintfObject->getCompatibleKernelRequirement();
    ASSERT_TRUE(kreq.has_value());
    EXPECT_EQ(1u, kreq->level());
    EXPECT_EQ(KernelVersion(2, 0, 0), kreq->minLts());
}

TEST_F(GetCompatibleKernelRequirementTest, Version2FutureConfigIncompat) {
    runtimeInfoFactory().getInfo()->setNextFetchKernelInfo({2, 0, 0}, {{"CONFIG_B2", "y"}});
    auto kreq = vintfObject->getCompatibleKernelRequirement();
    EXPECT_FALSE(kreq.has_value())
        << "CONFIG_B2 is from 2.xml and should not be compatible, but get: (" << kreq->level()
        << ", " << kreq->minLts() << ")";
}

TEST_F(GetCompatibleKernelRequirementTest, GetKernelReqFromNewerMatrix) {
    runtimeInfoFactory().getInfo()->setNextFetchKernelInfo({3, 0, 1}, {{"CONFIG_C2", "y"}});
    auto kreq = vintfObject->getCompatibleKernelRequirement();
    ASSERT_TRUE(kreq.has_value());
    EXPECT_EQ(2u, kreq->level()) << "Should get 3.0.0 from 2.xml because 1.xml doesn't have 3.0.x";
    EXPECT_EQ(KernelVersion(3, 0, 0), kreq->minLts());
}

TEST_F(GetCompatibleKernelRequirementTest, GetKernelReqFromOldestMatrixPossible) {
    runtimeInfoFactory().getInfo()->setNextFetchKernelInfo({4, 0, 1}, {{"CONFIG_D2", "y"}});
    auto kreq = vintfObject->getCompatibleKernelRequirement();
    ASSERT_TRUE(kreq.has_value());
    EXPECT_EQ(2u, kreq->level()) << "Should get 4.0.0 from 2.xml even though it exists in 3.xml";
    EXPECT_EQ(KernelVersion(4, 0, 0), kreq->minLts());
}

TEST_F(GetCompatibleKernelRequirementTest, GetKernelReqFromNewerMatrixIncompat) {
    runtimeInfoFactory().getInfo()->setNextFetchKernelInfo({4, 0, 0}, {{"CONFIG_D3", "y"}});
    auto kreq = vintfObject->getCompatibleKernelRequirement();
    ASSERT_FALSE(kreq.has_value())
        << "CONFIG_D3 is from 3.xml and should not be compatible, but get: (" << kreq->level()
        << ", " << kreq->minLts() << ")";
}

TEST_F(GetCompatibleKernelRequirementTest, GetKernelReqFromEvenNewerMatrix) {
    runtimeInfoFactory().getInfo()->setNextFetchKernelInfo({5, 0, 1}, {{"CONFIG_E3", "y"}});
    auto kreq = vintfObject->getCompatibleKernelRequirement();
    ASSERT_TRUE(kreq.has_value());
    EXPECT_EQ(3u, kreq->level())
        << "Should get 5.0.0 from 3.xml because neither 1.xml nor 2.xml has 5.0.x";
    EXPECT_EQ(KernelVersion(5, 0, 0), kreq->minLts());
}

// clang-format on

}  // namespace testing
}  // namespace vintf
}  // namespace android

int main(int argc, char** argv) {
    ::testing::InitGoogleMock(&argc, argv);
    return RUN_ALL_TESTS();
}
