| /* |
| * 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 <android-base/logging.h> |
| #include <gtest/gtest.h> |
| #include <vintf/AssembleVintf.h> |
| #include <vintf/parse_string.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<AssembleVintf>& getInstance() { return mInstance; } |
| |
| std::string getOutput() { return mOutputStream->str(); } |
| |
| void resetOutput() { mOutputStream->str(""); } |
| |
| void setFakeEnvs(const std::map<std::string, std::string>& 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<std::stringstream> makeStream(const std::string& s) { |
| return std::make_unique<std::stringstream>(s); |
| } |
| |
| std::unique_ptr<AssembleVintf> mInstance; |
| // do not own this object. |
| std::stringstream* mOutputStream; |
| }; |
| |
| TEST_F(AssembleVintfTest, FrameworkMatrixEmpty) { |
| std::string xmlEmpty = "<compatibility-matrix version=\"1.0\" type=\"framework\" />"; |
| 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.cfg", |
| makeStream(kernel318)); |
| getInstance()->addKernelConfigInputStream({3, 18, 0}, "android-base-arm64.cfg", |
| makeStream(kernel318_64)); |
| getInstance()->addKernelConfigInputStream({4, 4, 0}, "android-base.cfg", makeStream(kernel44)); |
| getInstance()->addKernelConfigInputStream({4, 4, 0}, "android-base-arm64.cfg", |
| makeStream(kernel44_64)); |
| |
| EXPECT_TRUE(getInstance()->assemble()); |
| |
| EXPECT_IN( |
| "<compatibility-matrix version=\"1.0\" type=\"framework\">\n" |
| " <kernel version=\"3.18.0\">\n" |
| " <config>\n" |
| " <key>CONFIG_FOO</key>\n" |
| " <value type=\"tristate\">y</value>\n" |
| " </config>\n" |
| " </kernel>\n" |
| " <kernel version=\"3.18.0\">\n" |
| " <conditions>\n" |
| " <config>\n" |
| " <key>CONFIG_ARM64</key>\n" |
| " <value type=\"tristate\">y</value>\n" |
| " </config>\n" |
| " </conditions>\n" |
| " <config>\n" |
| " <key>CONFIG_BAR</key>\n" |
| " <value type=\"tristate\">y</value>\n" |
| " </config>\n" |
| " </kernel>\n" |
| " <kernel version=\"4.4.0\">\n" |
| " <config>\n" |
| " <key>CONFIG_FOO</key>\n" |
| " <value type=\"tristate\">n</value>\n" |
| " </config>\n" |
| " </kernel>\n" |
| " <kernel version=\"4.4.0\">\n" |
| " <conditions>\n" |
| " <config>\n" |
| " <key>CONFIG_ARM64</key>\n" |
| " <value type=\"tristate\">y</value>\n" |
| " </config>\n" |
| " </conditions>\n" |
| " <config>\n" |
| " <key>CONFIG_BAR</key>\n" |
| " <value type=\"tristate\">y</value>\n" |
| " </config>\n" |
| " </kernel>\n" |
| " <sepolicy>\n" |
| " <kernel-sepolicy-version>30</kernel-sepolicy-version>\n" |
| " <sepolicy-version>10000.0</sepolicy-version>\n" |
| " </sepolicy>\n" |
| " <avb>\n" |
| " <vbmeta-version>1.0</vbmeta-version>\n" |
| " </avb>\n" |
| "</compatibility-matrix>\n", |
| getOutput()); |
| } |
| |
| TEST_F(AssembleVintfTest, FrameworkMatrix) { |
| std::string tail = |
| " <kernel version=\"3.18.0\">\n" |
| " <config>\n" |
| " <key>CONFIG_FOO</key>\n" |
| " <value type=\"tristate\">y</value>\n" |
| " </config>\n" |
| " </kernel>\n" |
| " <sepolicy>\n" |
| " <kernel-sepolicy-version>30</kernel-sepolicy-version>\n" |
| " <sepolicy-version>10000.0</sepolicy-version>\n" |
| " </sepolicy>\n" |
| " <avb>\n" |
| " <vbmeta-version>1.0</vbmeta-version>\n" |
| " </avb>\n" |
| "</compatibility-matrix>\n"; |
| |
| std::string xmlEmpty = "<compatibility-matrix version=\"1.0\" type=\"framework\">\n" + tail; |
| |
| std::string xml1 = |
| "<compatibility-matrix version=\"1.0\" type=\"framework\" level=\"1\">\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"; |
| |
| std::string xml2 = |
| "<compatibility-matrix version=\"1.0\" type=\"framework\" level=\"2\">\n" |
| " <hal format=\"hidl\" optional=\"true\">\n" |
| " <name>android.hardware.foo</name>\n" |
| " <version>1.0-1</version>\n" |
| " <interface>\n" |
| " <name>IFoo</name>\n" |
| " <instance>default</instance>\n" |
| " </interface>\n" |
| " </hal>\n" |
| "</compatibility-matrix>\n"; |
| |
| std::string xml3 = |
| "<compatibility-matrix version=\"1.0\" type=\"framework\" level=\"3\">\n" |
| " <hal format=\"hidl\" optional=\"false\">\n" |
| " <name>android.hardware.foo</name>\n" |
| " <version>2.0</version>\n" |
| " <interface>\n" |
| " <name>IFoo</name>\n" |
| " <instance>default</instance>\n" |
| " </interface>\n" |
| " </hal>\n" |
| "</compatibility-matrix>\n"; |
| |
| auto manifest = [](size_t level) { |
| return "<manifest version=\"1.0\" type=\"device\" target-level=\"" + std::to_string(level) + |
| "\">\n" + |
| " <hal format=\"hidl\">\n" |
| " <name>android.hardware.foo</name>\n" |
| " <version>1.1</version>\n" |
| " <transport>hwbinder</transport>\n" |
| " <interface>\n" |
| " <name>IFoo</name>\n" |
| " <instance>default</instance>\n" |
| " </interface>\n" |
| " </hal>\n" |
| " <hal format=\"hidl\">\n" |
| " <name>android.hardware.foo</name>\n" |
| " <version>2.0</version>\n" |
| " <transport>hwbinder</transport>\n" |
| " <interface>\n" |
| " <name>IFoo</name>\n" |
| " <instance>default</instance>\n" |
| " </interface>\n" |
| " </hal>\n" |
| " <sepolicy>\n" |
| " <version>10000.0</version>\n" |
| " </sepolicy>\n" |
| "</manifest>\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(makeStream(manifest(1))); |
| EXPECT_TRUE(getInstance()->assemble()); |
| EXPECT_IN( |
| "<compatibility-matrix version=\"1.0\" type=\"framework\" level=\"1\">\n" |
| " <hal format=\"hidl\" optional=\"true\">\n" |
| " <name>android.hardware.foo</name>\n" |
| " <version>1.0-1</version>\n" |
| " <version>2.0</version>\n" |
| " <interface>\n" |
| " <name>IFoo</name>\n" |
| " <instance>default</instance>\n" |
| " </interface>\n" |
| " </hal>\n" + |
| tail, |
| getOutput()); |
| |
| resetOutput(); |
| getInstance()->setCheckInputStream(makeStream(manifest(2))); |
| EXPECT_TRUE(getInstance()->assemble()); |
| EXPECT_IN( |
| "<compatibility-matrix version=\"1.0\" type=\"framework\" level=\"2\">\n" |
| " <hal format=\"hidl\" optional=\"true\">\n" |
| " <name>android.hardware.foo</name>\n" |
| " <version>1.0-1</version>\n" |
| " <version>2.0</version>\n" |
| " <interface>\n" |
| " <name>IFoo</name>\n" |
| " <instance>default</instance>\n" |
| " </interface>\n" |
| " </hal>\n" + |
| tail, |
| getOutput()); |
| |
| resetOutput(); |
| getInstance()->setCheckInputStream(makeStream(manifest(3))); |
| EXPECT_TRUE(getInstance()->assemble()); |
| EXPECT_IN( |
| "<compatibility-matrix version=\"1.0\" type=\"framework\" level=\"3\">\n" |
| " <hal format=\"hidl\" optional=\"false\">\n" |
| " <name>android.hardware.foo</name>\n" |
| " <version>2.0</version>\n" |
| " <interface>\n" |
| " <name>IFoo</name>\n" |
| " <instance>default</instance>\n" |
| " </interface>\n" |
| " </hal>\n" + |
| tail, |
| getOutput()); |
| } |
| |
| TEST_F(AssembleVintfTest, MatrixVendorNdk) { |
| addInput("compatibility_matrix.xml", |
| "<compatibility-matrix version=\"1.0\" type=\"device\"/>\n"); |
| getInstance()->setFakeEnv("REQUIRED_VNDK_VERSION", "P"); |
| EXPECT_TRUE(getInstance()->assemble()); |
| EXPECT_IN( |
| "<compatibility-matrix version=\"1.0\" type=\"device\">\n" |
| " <vendor-ndk>\n" |
| " <version>P</version>\n" |
| " </vendor-ndk>\n" |
| "</compatibility-matrix>\n", |
| getOutput()); |
| } |
| |
| TEST_F(AssembleVintfTest, ManifestVendorNdk) { |
| addInput("manifest.xml", "<manifest version=\"1.0\" type=\"framework\"/>\n"); |
| getInstance()->setFakeEnv("PROVIDED_VNDK_VERSIONS", "P 26 27 "); |
| EXPECT_TRUE(getInstance()->assemble()); |
| EXPECT_IN( |
| "<manifest version=\"1.0\" type=\"framework\">\n" |
| " <vendor-ndk>\n" |
| " <version>P</version>\n" |
| " </vendor-ndk>\n" |
| " <vendor-ndk>\n" |
| " <version>26</version>\n" |
| " </vendor-ndk>\n" |
| " <vendor-ndk>\n" |
| " <version>27</version>\n" |
| " </vendor-ndk>\n" |
| "</manifest>\n", |
| getOutput()); |
| } |
| |
| TEST_F(AssembleVintfTest, VendorNdkCheckEmpty) { |
| addInput("manifest.xml", "<manifest version=\"1.0\" type=\"framework\"/>\n"); |
| getInstance()->setFakeEnv("PROVIDED_VNDK_VERSIONS", "P 26 27 "); |
| |
| std::string matrix = "<compatibility-matrix version=\"1.0\" type=\"device\"/>\n"; |
| getInstance()->setCheckInputStream(makeStream(matrix)); |
| EXPECT_TRUE(getInstance()->assemble()); |
| } |
| |
| TEST_F(AssembleVintfTest, VendorNdkCheckIncompat) { |
| addInput("manifest.xml", "<manifest version=\"1.0\" type=\"framework\"/>\n"); |
| getInstance()->setFakeEnv("PROVIDED_VNDK_VERSIONS", "P 26 27 "); |
| std::string matrix = |
| "<compatibility-matrix version=\"1.0\" type=\"device\">\n" |
| " <vendor-ndk>\n" |
| " <version>O</version>\n" |
| " </vendor-ndk>\n" |
| "</compatibility-matrix>\n"; |
| getInstance()->setCheckInputStream(makeStream(matrix)); |
| EXPECT_FALSE(getInstance()->assemble()); |
| } |
| |
| TEST_F(AssembleVintfTest, VendorNdkCheckCompat) { |
| addInput("manifest.xml", "<manifest version=\"1.0\" type=\"framework\"/>\n"); |
| getInstance()->setFakeEnv("PROVIDED_VNDK_VERSIONS", "P 26 27 "); |
| std::string matrix = |
| "<compatibility-matrix version=\"1.0\" type=\"device\">\n" |
| " <vendor-ndk>\n" |
| " <version>27</version>\n" |
| " </vendor-ndk>\n" |
| "</compatibility-matrix>\n"; |
| getInstance()->setCheckInputStream(makeStream(matrix)); |
| EXPECT_TRUE(getInstance()->assemble()); |
| } |
| |
| TEST_F(AssembleVintfTest, MatrixSystemSdk) { |
| addInput("compatibility_matrix.xml", |
| "<compatibility-matrix version=\"1.0\" type=\"device\"/>\n"); |
| getInstance()->setFakeEnv("BOARD_SYSTEMSDK_VERSIONS", "P 1 2 "); |
| EXPECT_TRUE(getInstance()->assemble()); |
| EXPECT_IN( |
| "<compatibility-matrix version=\"1.0\" type=\"device\">\n" |
| " <system-sdk>\n" |
| " <version>1</version>\n" |
| " <version>2</version>\n" |
| " <version>P</version>\n" |
| " </system-sdk>\n" |
| "</compatibility-matrix>\n", |
| getOutput()); |
| } |
| |
| TEST_F(AssembleVintfTest, ManifestSystemSdk) { |
| addInput("manifest.xml", "<manifest version=\"1.0\" type=\"framework\"/>\n"); |
| getInstance()->setFakeEnv("PLATFORM_SYSTEMSDK_VERSIONS", "P 1 2 "); |
| EXPECT_TRUE(getInstance()->assemble()); |
| EXPECT_IN( |
| "<manifest version=\"1.0\" type=\"framework\">\n" |
| " <system-sdk>\n" |
| " <version>1</version>\n" |
| " <version>2</version>\n" |
| " <version>P</version>\n" |
| " </system-sdk>\n" |
| "</manifest>\n", |
| getOutput()); |
| } |
| |
| const std::string gEmptyOutManifest = |
| "<manifest version=\"1.0\" type=\"device\">\n" |
| " <sepolicy>\n" |
| " <version>10000.0</version>\n" |
| " </sepolicy>\n" |
| "</manifest>\n"; |
| |
| TEST_F(AssembleVintfTest, EmptyManifest) { |
| const std::string emptyManifest = "<manifest version=\"1.0\" type=\"device\" />"; |
| 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(makeStream(gEmptyOutManifest)); |
| |
| addInput("compatibility_matrix.empty.xml", |
| "<compatibility-matrix version=\"1.0\" type=\"framework\">\n" |
| " <hal format=\"hidl\" optional=\"true\">\n" |
| " <name>vendor.foo.bar</name>\n" |
| " <version>1.0</version>\n" |
| " <interface>\n" |
| " <name>IFoo</name>\n" |
| " <instance>default</instance>\n" |
| " </interface>\n" |
| " </hal>\n" |
| "</compatibility-matrix>"); |
| |
| EXPECT_TRUE(getInstance()->assemble()); |
| EXPECT_IN( |
| "<compatibility-matrix version=\"1.0\" type=\"framework\">\n" |
| " <hal format=\"hidl\" optional=\"true\">\n" |
| " <name>vendor.foo.bar</name>\n" |
| " <version>1.0</version>\n" |
| " <interface>\n" |
| " <name>IFoo</name>\n" |
| " <instance>default</instance>\n" |
| " </interface>\n" |
| " </hal>\n" |
| " <sepolicy>\n" |
| " <kernel-sepolicy-version>30</kernel-sepolicy-version>\n" |
| " <sepolicy-version>26.0</sepolicy-version>\n" |
| " <sepolicy-version>27.0</sepolicy-version>\n" |
| " <sepolicy-version>10000.0</sepolicy-version>\n" |
| " </sepolicy>\n" |
| " <avb>\n" |
| " <vbmeta-version>1.0</vbmeta-version>\n" |
| " </avb>\n" |
| "</compatibility-matrix>", |
| 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(makeStream(gEmptyOutManifest)); |
| |
| addInput("compatibility_matrix.empty.xml", |
| "<compatibility-matrix version=\"1.0\" type=\"framework\">\n" |
| " <hal format=\"hidl\" optional=\"false\">\n" |
| " <name>vendor.foo.bar</name>\n" |
| " <version>1.0</version>\n" |
| " <interface>\n" |
| " <name>IFoo</name>\n" |
| " <instance>default</instance>\n" |
| " </interface>\n" |
| " </hal>\n" |
| "</compatibility-matrix>"); |
| |
| EXPECT_FALSE(getInstance()->assemble()); |
| } |
| |
| } // namespace vintf |
| } // namespace android |