• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <cstdio>
18 #include <string>
19 
20 #include <android-base/file.h>
21 #include <android-base/test_utils.h>
22 #include <gtest/gtest.h>
23 
24 #include "Common.h"
25 #include "sysprop.pb.h"
26 
27 namespace {
28 
29 constexpr const char* kDuplicatedField =
30     R"(
31 owner: Vendor
32 module: "com.error.DuplicatedField"
33 prop {
34     api_name: "dup"
35     type: Integer
36     scope: Internal
37     access: Readonly
38 }
39 prop {
40     api_name: "dup"
41     type: Long
42     scope: Public
43     access: ReadWrite
44 }
45 )";
46 
47 constexpr const char* kEmptyProp =
48     R"(
49 owner: Vendor
50 module: "com.google.EmptyProp"
51 )";
52 
53 constexpr const char* kInvalidApiName =
54     R"(
55 owner: Odm
56 module: "odm.invalid.prop.name"
57 prop {
58     api_name: "!@#$"
59     type: Integer
60     scope: Public
61     access: ReadWrite
62 }
63 )";
64 
65 constexpr const char* kInvalidPropName =
66     R"(
67 owner: Vendor
68 module: "vendor.module.name"
69 prop {
70     api_name: "foo"
71     type: Integer
72     scope: Internal
73     access: Readonly
74     prop_name: "foo$bar"
75 }
76 )";
77 
78 constexpr const char* kEmptyEnumValues =
79     R"(
80 owner: Odm
81 module: "test.manufacturer"
82 prop {
83     api_name: "empty_enum_value"
84     type: Enum
85     scope: Internal
86     access: ReadWrite
87 }
88 )";
89 
90 constexpr const char* kDuplicatedEnumValue =
91     R"(
92 owner: Vendor
93 module: "vendor.module.name"
94 prop {
95     api_name: "status"
96     type: Enum
97     enum_values: "oN|off|intermediate|On"
98     scope: Public
99     access: ReadWrite
100 }
101 )";
102 
103 constexpr const char* kInvalidModuleName =
104     R"(
105 owner: Platform
106 module: ""
107 prop {
108     api_name: "integer"
109     type: Integer
110     scope: Public
111     access: ReadWrite
112 }
113 )";
114 
115 constexpr const char* kInvalidNamespaceForPlatform =
116     R"(
117 owner: Platform
118 module: "android.PlatformProperties"
119 prop {
120     api_name: "vendor_build_utc_long"
121     prop_name: "vendor.build.utc_long"
122     type: Long
123     scope: Public
124     access: ReadWrite
125 }
126 )";
127 
128 constexpr const char* kRoPrefixForReadWriteProperty =
129     R"(
130 owner: Vendor
131 module: "com.android.VendorProp"
132 prop {
133     api_name: "i_am_readwrite"
134     type: Long
135     scope: Public
136     prop_name: "ro.vendor.i_am_readwrite"
137     access: ReadWrite
138 }
139 )";
140 
141 constexpr const char* kIntegerAsBoolWithWrongType =
142     R"(
143 owner: Platform
144 module: "android.os.LongProp"
145 prop {
146     api_name: "longprop"
147     type: Long
148     scope: Internal
149     prop_name: "long.prop"
150     access: ReadWrite
151     integer_as_bool: true
152 }
153 )";
154 
155 constexpr const char* kTypeMismatch =
156     R"(
157 owner: Platform
158 module: "android.os.Type"
159 prop {
160     prop_name: "prop"
161     type: Double
162     scope: Public
163     access: ReadWrite
164     api_name: "prop"
165 }
166 prop {
167     prop_name: "prop2"
168     legacy_prop_name: "prop"
169     type: Enum
170     enum_values: "a|b|c"
171     scope: Public
172     access: Readonly
173     api_name: "prop2"
174 }
175 )";
176 
177 constexpr const char* kLegacyNotReadonly =
178     R"(
179 owner: Platform
180 module: "android.os.Sysprop"
181 prop {
182     prop_name: "prop"
183     type: String
184     scope: Public
185     access: ReadWrite
186     api_name: "prop"
187     legacy_prop_name: "legacy_prop"
188 }
189 )";
190 
191 constexpr const char* kTestCasesAndExpectedErrors[][2] = {
192     {kDuplicatedField, "Duplicated API name \"dup\""},
193     {kEmptyProp, "There is no defined property"},
194     {kInvalidApiName, "Invalid API name \"!@#$\""},
195     {kInvalidPropName, "Invalid prop name \"foo$bar\""},
196     {kEmptyEnumValues, "Invalid enum value \"\" for API \"empty_enum_value\""},
197     {kDuplicatedEnumValue, "Duplicated enum value \"On\" for API \"status\""},
198     {kInvalidModuleName, "Invalid module name \"\""},
199     {kInvalidNamespaceForPlatform,
200      "Prop \"vendor.build.utc_long\" owned by platform cannot have vendor. or "
201      "odm. "
202      "namespace"},
203     {kRoPrefixForReadWriteProperty,
204      "Prop \"ro.vendor.i_am_readwrite\" is ReadWrite and also have prefix "
205      "\"ro.\""},
206     {kIntegerAsBoolWithWrongType,
207      "Prop \"long.prop\" has integer_as_bool: true, but not a boolean"},
208     {kTypeMismatch, "Type error on prop \"prop\": it's Enum but was Double"},
209     {kLegacyNotReadonly,
210      "Prop \"prop\" which has legacy_prop_name must be Readonly"},
211 };
212 
213 }  // namespace
214 
TEST(SyspropTest,InvalidSyspropTest)215 TEST(SyspropTest, InvalidSyspropTest) {
216   TemporaryFile file;
217   close(file.fd);
218   file.fd = -1;
219 
220   for (auto [test_case, expected_error] : kTestCasesAndExpectedErrors) {
221     ASSERT_TRUE(android::base::WriteStringToFile(test_case, file.path));
222     auto res = ParseProps(file.path);
223     EXPECT_FALSE(res.ok());
224     EXPECT_EQ(res.error().message(), expected_error);
225   }
226 }
227