/* * 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. */ #define LOG_TAG "AssembleVintfTest" #include #include #include #include #include "test_constants.h" namespace android { namespace vintf { static bool In(const std::string& sub, const std::string& str) { return str.find(sub) != std::string::npos; } #define EXPECT_IN(sub, str) EXPECT_TRUE(In((sub), (str))) << (str); class AssembleVintfTest : public ::testing::Test { public: virtual void SetUp() override { mInstance = AssembleVintf::newInstance(); auto s = makeStream(""); mOutputStream = s.get(); mInstance->setOutputStream(std::move(s)); getInstance()->setFakeEnv("PRODUCT_ENFORCE_VINTF_MANIFEST", "true"); } virtual void TearDown() override { mInstance = nullptr; } const std::unique_ptr& getInstance() { return mInstance; } std::string getOutput() { return mOutputStream->str(); } void resetOutput() { mOutputStream->str(""); } void setFakeEnvs(const std::map& envs) { for (const auto& pair : envs) { getInstance()->setFakeEnv(pair.first, pair.second); } } void addInput(const std::string& name, const std::string& s) { getInstance()->addInputStream(name, makeStream(s)); } std::unique_ptr makeStream(const std::string& s) { return std::make_unique(s); } std::unique_ptr mInstance; // do not own this object. std::stringstream* mOutputStream; }; // clang-format off TEST_F(AssembleVintfTest, FrameworkMatrixEmpty) { std::string xmlEmpty = ""; std::string kernel318 = "CONFIG_FOO=y\n"; std::string kernel318_64 = "CONFIG_BAR=y\n"; std::string kernel44 = "# CONFIG_FOO is not set\n"; std::string kernel44_64 = "CONFIG_BAR=y\n"; addInput("compatibility_matrix.empty.xml", xmlEmpty); setFakeEnvs({ {"POLICYVERS", "30"}, {"PLATFORM_SEPOLICY_VERSION", "10000.0"}, {"FRAMEWORK_VBMETA_VERSION", "1.0"}, }); getInstance()->addKernelConfigInputStream({3, 18, 0}, "android-base.config", makeStream(kernel318)); getInstance()->addKernelConfigInputStream({3, 18, 0}, "android-base-arm64.config", makeStream(kernel318_64)); getInstance()->addKernelConfigInputStream({4, 4, 0}, "android-base.config", makeStream(kernel44)); getInstance()->addKernelConfigInputStream({4, 4, 0}, "android-base-arm64.config", makeStream(kernel44_64)); EXPECT_TRUE(getInstance()->assemble()); EXPECT_IN( "\n" " \n" " \n" " CONFIG_FOO\n" " y\n" " \n" " \n" " \n" " \n" " \n" " CONFIG_ARM64\n" " y\n" " \n" " \n" " \n" " CONFIG_BAR\n" " y\n" " \n" " \n" " \n" " \n" " CONFIG_FOO\n" " n\n" " \n" " \n" " \n" " \n" " \n" " CONFIG_ARM64\n" " y\n" " \n" " \n" " \n" " CONFIG_BAR\n" " y\n" " \n" " \n" " \n" " 30\n" " 10000.0\n" " \n" " \n" " 1.0\n" " \n" "\n", getOutput()); } TEST_F(AssembleVintfTest, FrameworkMatrix) { std::string tail = " \n" " CONFIG_FOO\n" " y\n" " \n" " \n" " \n" " 30\n" " 10000.0\n" " \n" " \n" " 1.0\n" " \n" "\n"; std::string xmlEmpty = "\n" " \n" + tail; std::string xml1 = "\n" " \n" " android.hardware.foo\n" " 1.0\n" " \n" " IFoo\n" " default\n" " \n" " \n" "\n"; std::string xml2 = "\n" " \n" " android.hardware.foo\n" " 1.0-1\n" " \n" " IFoo\n" " default\n" " \n" " \n" "\n"; std::string xml3 = "\n" " \n" " android.hardware.foo\n" " 2.0\n" " \n" " IFoo\n" " default\n" " \n" " \n" "\n"; auto manifest = [](size_t level) { return "\n" + " \n" " android.hardware.foo\n" " 1.1\n" " hwbinder\n" " \n" " IFoo\n" " default\n" " \n" " \n" " \n" " android.hardware.foo\n" " 2.0\n" " hwbinder\n" " \n" " IFoo\n" " default\n" " \n" " \n" " \n" " 10000.0\n" " \n" "\n"; }; addInput("compatibility_matrix.1.xml", xml1); addInput("compatibility_matrix.2.xml", xml2); addInput("compatibility_matrix.3.xml", xml3); addInput("compatibility_matrix.empty.xml", xmlEmpty); getInstance()->setFakeEnv("PRODUCT_ENFORCE_VINTF_MANIFEST", "true"); resetOutput(); getInstance()->setCheckInputStream("check.xml", makeStream(manifest(1))); EXPECT_TRUE(getInstance()->assemble()); EXPECT_IN( "\n" " \n" " android.hardware.foo\n" " 1.0-1\n" " 2.0\n" " \n" " IFoo\n" " default\n" " \n" " \n" " \n" + tail, getOutput()); resetOutput(); getInstance()->setCheckInputStream("check.xml", makeStream(manifest(2))); EXPECT_TRUE(getInstance()->assemble()); EXPECT_IN( "\n" " \n" " android.hardware.foo\n" " 1.0-1\n" " 2.0\n" " \n" " IFoo\n" " default\n" " \n" " \n" " \n" + tail, getOutput()); resetOutput(); getInstance()->setCheckInputStream("check.xml", makeStream(manifest(3))); EXPECT_TRUE(getInstance()->assemble()); EXPECT_IN( "\n" " \n" " android.hardware.foo\n" " 2.0\n" " \n" " IFoo\n" " default\n" " \n" " \n" " \n" + tail, getOutput()); } TEST_F(AssembleVintfTest, MatrixVendorNdk) { addInput("compatibility_matrix.xml", "\n"); getInstance()->setFakeEnv("REQUIRED_VNDK_VERSION", "P"); EXPECT_TRUE(getInstance()->assemble()); EXPECT_IN( "\n" " \n" " P\n" " \n" "\n", getOutput()); } TEST_F(AssembleVintfTest, ManifestVendorNdk) { addInput("manifest.xml", "\n"); getInstance()->setFakeEnv("PROVIDED_VNDK_VERSIONS", "P 26 27 "); EXPECT_TRUE(getInstance()->assemble()); EXPECT_IN( "\n" " \n" " P\n" " \n" " \n" " 26\n" " \n" " \n" " 27\n" " \n" "\n", getOutput()); } TEST_F(AssembleVintfTest, VendorNdkCheckEmpty) { addInput("manifest.xml", "\n"); getInstance()->setFakeEnv("PROVIDED_VNDK_VERSIONS", "P 26 27 "); std::string matrix = "\n"; getInstance()->setCheckInputStream("check.xml", makeStream(matrix)); EXPECT_TRUE(getInstance()->assemble()); } TEST_F(AssembleVintfTest, VendorNdkCheckIncompat) { addInput("manifest.xml", "\n"); getInstance()->setFakeEnv("PROVIDED_VNDK_VERSIONS", "P 26 27 "); std::string matrix = "\n" " \n" " O\n" " \n" "\n"; getInstance()->setCheckInputStream("check.xml", makeStream(matrix)); EXPECT_FALSE(getInstance()->assemble()); } TEST_F(AssembleVintfTest, VendorNdkCheckCompat) { addInput("manifest.xml", "\n"); getInstance()->setFakeEnv("PROVIDED_VNDK_VERSIONS", "P 26 27 "); std::string matrix = "\n" " \n" " 27\n" " \n" "\n"; getInstance()->setCheckInputStream("check.xml", makeStream(matrix)); EXPECT_TRUE(getInstance()->assemble()); } TEST_F(AssembleVintfTest, MatrixSystemSdk) { addInput("compatibility_matrix.xml", "\n"); getInstance()->setFakeEnv("BOARD_SYSTEMSDK_VERSIONS", "P 1 2 "); EXPECT_TRUE(getInstance()->assemble()); EXPECT_IN( "\n" " \n" " 1\n" " 2\n" " P\n" " \n" "\n", getOutput()); } TEST_F(AssembleVintfTest, ManifestSystemSdk) { addInput("manifest.xml", "\n"); getInstance()->setFakeEnv("PLATFORM_SYSTEMSDK_VERSIONS", "P 1 2 "); EXPECT_TRUE(getInstance()->assemble()); EXPECT_IN( "\n" " \n" " 1\n" " 2\n" " P\n" " \n" "\n", getOutput()); } const std::string gEmptyOutManifest = "\n" " \n" " 10000.0\n" " \n" "\n"; TEST_F(AssembleVintfTest, EmptyManifest) { const std::string emptyManifest = ""; setFakeEnvs({{"BOARD_SEPOLICY_VERS", "10000.0"}, {"IGNORE_TARGET_FCM_VERSION", "true"}}); addInput("manifest.empty.xml", emptyManifest); EXPECT_TRUE(getInstance()->assemble()); EXPECT_IN(gEmptyOutManifest, getOutput()); } TEST_F(AssembleVintfTest, DeviceFrameworkMatrixOptional) { setFakeEnvs({{"POLICYVERS", "30"}, {"PLATFORM_SEPOLICY_VERSION", "10000.0"}, {"PLATFORM_SEPOLICY_COMPAT_VERSIONS", "26.0 27.0"}, {"FRAMEWORK_VBMETA_VERSION", "1.0"}, {"PRODUCT_ENFORCE_VINTF_MANIFEST", "true"}}); getInstance()->setCheckInputStream("check.xml", makeStream(gEmptyOutManifest)); addInput("compatibility_matrix.empty.xml", "\n" " \n" " vendor.foo.bar\n" " 1.0\n" " \n" " IFoo\n" " default\n" " \n" " \n" ""); EXPECT_TRUE(getInstance()->assemble()); EXPECT_IN( "\n" " \n" " vendor.foo.bar\n" " 1.0\n" " \n" " IFoo\n" " default\n" " \n" " \n" " \n" " 30\n" " 26.0\n" " 27.0\n" " 10000.0\n" " \n" " \n" " 1.0\n" " \n" "", getOutput()); } TEST_F(AssembleVintfTest, DeviceFrameworkMatrixRequired) { setFakeEnvs({{"POLICYVERS", "30"}, {"PLATFORM_SEPOLICY_VERSION", "10000.0"}, {"PLATFORM_SEPOLICY_COMPAT_VERSIONS", "26.0 27.0"}, {"FRAMEWORK_VBMETA_VERSION", "1.0"}, {"PRODUCT_ENFORCE_VINTF_MANIFEST", "true"}}); getInstance()->setCheckInputStream("check.xml", makeStream(gEmptyOutManifest)); addInput("compatibility_matrix.empty.xml", "\n" " \n" " vendor.foo.bar\n" " 1.0\n" " \n" " IFoo\n" " default\n" " \n" " \n" ""); EXPECT_FALSE(getInstance()->assemble()); } TEST_F(AssembleVintfTest, DeviceFrameworkMatrixMultiple) { setFakeEnvs({{"POLICYVERS", "30"}, {"PLATFORM_SEPOLICY_VERSION", "10000.0"}, {"PLATFORM_SEPOLICY_COMPAT_VERSIONS", "26.0 27.0"}, {"FRAMEWORK_VBMETA_VERSION", "1.0"}, {"PRODUCT_ENFORCE_VINTF_MANIFEST", "true"}}); getInstance()->setCheckInputStream("check.xml", makeStream(gEmptyOutManifest)); addInput("compatibility_matrix.foobar.xml", "\n" " \n" " vendor.foo.bar\n" " 1.0\n" " \n" " IFoo\n" " default\n" " \n" " \n" ""); addInput("compatibility_matrix.bazquux.xml", "\n" " \n" " vendor.baz.quux\n" " 1.0\n" " \n" " IBaz\n" " default\n" " \n" " \n" ""); EXPECT_TRUE(getInstance()->assemble()); EXPECT_IN( "\n" " \n" " vendor.baz.quux\n" " 1.0\n" " \n" " IBaz\n" " default\n" " \n" " \n" " \n" " vendor.foo.bar\n" " 1.0\n" " \n" " IFoo\n" " default\n" " \n" " \n" " \n" " 30\n" " 26.0\n" " 27.0\n" " 10000.0\n" " \n" " \n" " 1.0\n" " \n" "", getOutput()); } TEST_F(AssembleVintfTest, OutputFileMatrixTest) { const std::string kFile = "file_name_1.xml"; const std::string kMatrix = ""; addInput(kFile, kMatrix); EXPECT_TRUE(getInstance()->assemble()); EXPECT_IN(kFile, getOutput()); } TEST_F(AssembleVintfTest, OutputFileManifestTest) { const std::string kFile = "file_name_1.xml"; std::string kManifest = ""; addInput(kFile, kManifest); EXPECT_TRUE(getInstance()->assemble()); EXPECT_IN(kFile, getOutput()); } TEST_F(AssembleVintfTest, AidlAndHidlNames) { addInput("manifest1.xml", "\n" " \n" " android.system.foo\n" " IFoo/default\n" " \n" "\n"); addInput("manifest2.xml", "\n" " \n" " android.system.foo\n" " hwbinder\n" " @1.0::IFoo/default\n" " \n" "\n"); EXPECT_TRUE(getInstance()->assemble()); EXPECT_IN( " \n" " android.system.foo\n" " IFoo/default\n" " \n", getOutput()); EXPECT_IN( " \n" " android.system.foo\n" " hwbinder\n" " @1.0::IFoo/default\n" " \n", getOutput()); } // Merge kernel FCM from manually written device manifest and from // parsing kernel prebuilt. TEST_F(AssembleVintfTest, MergeKernelFcmAndConfigs) { addInput("manifest.xml", "\n" " \n" "\n"); getInstance()->addKernelConfigInputStream({3, 18, 10}, "android-base.config", makeStream("CONFIG_FOO=y")); EXPECT_TRUE(getInstance()->assemble()); EXPECT_IN("", getOutput()); } TEST_F(AssembleVintfTest, NoAutoSetKernelFcm) { addInput("manifest.xml", "\n" " \n" "\n"); EXPECT_TRUE(getInstance()->assemble()); EXPECT_IN("", getOutput()); } TEST_F(AssembleVintfTest, AutoSetKernelFcm) { addInput("manifest.xml", "\n" " \n" "\n"); EXPECT_TRUE(getInstance()->assemble()); EXPECT_IN("", getOutput()); } TEST_F(AssembleVintfTest, NoAutoSetKernelFcmWithConfig) { addInput("manifest.xml", "\n"); getInstance()->addKernelConfigInputStream({3, 18, 10}, "android-base.config", makeStream("CONFIG_FOO=y")); EXPECT_TRUE(getInstance()->assemble()); EXPECT_IN("", getOutput()); } TEST_F(AssembleVintfTest, AutoSetKernelFcmWithConfig) { addInput("manifest.xml", "\n"); getInstance()->addKernelConfigInputStream({5, 4, 10}, "android-base.config", makeStream("CONFIG_FOO=y")); EXPECT_TRUE(getInstance()->assemble()); EXPECT_IN("", getOutput()); } // Automatically add kernel FCM when parsing framework matrix for a single FCM version. TEST_F(AssembleVintfTest, AutoSetMatrixKernelFcm) { addInput("compatibility_matrix.xml", "\n" ); getInstance()->addKernelConfigInputStream({3, 18, 10}, "android-base.config", makeStream("")); EXPECT_TRUE(getInstance()->assemble()); EXPECT_IN("", getOutput()); } TEST_F(AssembleVintfTest, WithKernelRequirements) { setFakeEnvs({{"POLICYVERS", "30"}, {"PLATFORM_SEPOLICY_VERSION", "10000.0"}, {"PRODUCT_ENFORCE_VINTF_MANIFEST", "true"}}); addInput("compatibility_matrix.xml", "\n" " \n" " \n" " CONFIG_FOO\n" " y\n" " \n" " \n" "\n"); getInstance()->setCheckInputStream("check.xml", makeStream( "\n" " \n" " \n" " 10000.0\n" " \n" "\n")); EXPECT_FALSE(getInstance()->assemble()); } TEST_F(AssembleVintfTest, NoKernelRequirements) { setFakeEnvs({{"POLICYVERS", "30"}, {"PLATFORM_SEPOLICY_VERSION", "10000.0"}, {"PRODUCT_ENFORCE_VINTF_MANIFEST", "true"}}); addInput("compatibility_matrix.xml", "\n" " \n" "\n"); getInstance()->setCheckInputStream("check.xml", makeStream( "\n" " \n" " \n" " 10000.0\n" " \n" "\n")); EXPECT_TRUE(getInstance()->setNoKernelRequirements()); EXPECT_TRUE(getInstance()->assemble()); } // clang-format on } // namespace vintf } // namespace android