/* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include #include #include #include #include #include "Common.h" #include "sysprop.pb.h" namespace { constexpr const char* kDuplicatedField = R"( owner: Vendor module: "com.error.DuplicatedField" prop { api_name: "dup" type: Integer scope: Internal access: Readonly } prop { api_name: "dup" type: Long scope: Public access: ReadWrite } )"; constexpr const char* kEmptyProp = R"( owner: Vendor module: "com.google.EmptyProp" )"; constexpr const char* kInvalidApiName = R"( owner: Odm module: "odm.invalid.prop.name" prop { api_name: "!@#$" type: Integer scope: Public access: ReadWrite } )"; constexpr const char* kInvalidPropName = R"( owner: Vendor module: "vendor.module.name" prop { api_name: "foo" type: Integer scope: Internal access: Readonly prop_name: "foo$bar" } )"; constexpr const char* kEmptyEnumValues = R"( owner: Odm module: "test.manufacturer" prop { api_name: "empty_enum_value" type: Enum scope: Internal access: ReadWrite } )"; constexpr const char* kDuplicatedEnumValue = R"( owner: Vendor module: "vendor.module.name" prop { api_name: "status" type: Enum enum_values: "oN|off|intermediate|On" scope: Public access: ReadWrite } )"; constexpr const char* kInvalidModuleName = R"( owner: Platform module: "" prop { api_name: "integer" type: Integer scope: Public access: ReadWrite } )"; constexpr const char* kInvalidNamespaceForPlatform = R"( owner: Platform module: "android.PlatformProperties" prop { api_name: "vendor_build_utc_long" prop_name: "vendor.build.utc_long" type: Long scope: Public access: ReadWrite } )"; constexpr const char* kRoPrefixForReadWriteProperty = R"( owner: Vendor module: "com.android.VendorProp" prop { api_name: "i_am_readwrite" type: Long scope: Public prop_name: "ro.vendor.i_am_readwrite" access: ReadWrite } )"; constexpr const char* kIntegerAsBoolWithWrongType = R"( owner: Platform module: "android.os.LongProp" prop { api_name: "longprop" type: Long scope: Internal prop_name: "long.prop" access: ReadWrite integer_as_bool: true } )"; constexpr const char* kTypeMismatch = R"( owner: Platform module: "android.os.Type" prop { prop_name: "prop" type: Double scope: Public access: ReadWrite api_name: "prop" } prop { prop_name: "prop2" legacy_prop_name: "prop" type: Enum enum_values: "a|b|c" scope: Public access: Readonly api_name: "prop2" } )"; constexpr const char* kLegacyNotReadonly = R"( owner: Platform module: "android.os.Sysprop" prop { prop_name: "prop" type: String scope: Public access: ReadWrite api_name: "prop" legacy_prop_name: "legacy_prop" } )"; constexpr const char* kTestCasesAndExpectedErrors[][2] = { {kDuplicatedField, "Duplicated API name \"dup\""}, {kEmptyProp, "There is no defined property"}, {kInvalidApiName, "Invalid API name \"!@#$\""}, {kInvalidPropName, "Invalid prop name \"foo$bar\""}, {kEmptyEnumValues, "Invalid enum value \"\" for API \"empty_enum_value\""}, {kDuplicatedEnumValue, "Duplicated enum value \"On\" for API \"status\""}, {kInvalidModuleName, "Invalid module name \"\""}, {kInvalidNamespaceForPlatform, "Prop \"vendor.build.utc_long\" owned by platform cannot have vendor. or " "odm. " "namespace"}, {kRoPrefixForReadWriteProperty, "Prop \"ro.vendor.i_am_readwrite\" is ReadWrite and also have prefix " "\"ro.\""}, {kIntegerAsBoolWithWrongType, "Prop \"long.prop\" has integer_as_bool: true, but not a boolean"}, {kTypeMismatch, "Type error on prop \"prop\": it's Enum but was Double"}, {kLegacyNotReadonly, "Prop \"prop\" which has legacy_prop_name must be Readonly"}, }; } // namespace TEST(SyspropTest, InvalidSyspropTest) { TemporaryFile file; close(file.fd); file.fd = -1; for (auto [test_case, expected_error] : kTestCasesAndExpectedErrors) { ASSERT_TRUE(android::base::WriteStringToFile(test_case, file.path)); auto res = ParseProps(file.path); EXPECT_FALSE(res.ok()); EXPECT_EQ(res.error().message(), expected_error); } }