1 /*
2 * Copyright (C) 2020 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 <string>
18
19 #include <android-base/test_utils.h>
20 #include <gtest/gtest.h>
21
22 #include "Common.h"
23 #include "TypeChecker.h"
24
25 using android::properties::ParsePropertyInfoFile;
26 using android::properties::PropertyInfoEntry;
27
28 namespace {
29
30 constexpr const char* kApi =
31 R"(
32 props {
33 owner: Platform
34 module: "android.platprop"
35 prop {
36 api_name: "prop1"
37 type: Long
38 scope: Public
39 access: ReadWrite
40 prop_name: "prop1"
41 }
42 prop {
43 api_name: "prop2"
44 type: Enum
45 scope: Public
46 access: Writeonce
47 enum_values: "a|b|c"
48 prop_name: "ro.public.prop2"
49 }
50 prop {
51 api_name: "prop3"
52 type: Boolean
53 scope: Public
54 access: ReadWrite
55 prop_name: "ctl.start$prop3"
56 }
57 prop {
58 api_name: "prop4"
59 type: String
60 scope: Public
61 access: Readonly
62 prop_name: "ro.prop4"
63 legacy_prop_name: "ro.legacy.prop4"
64 deprecated: true
65 }
66
67 }
68 )";
69
70 constexpr const char* kContexts =
71 R"(
72 prop1 u:object_r:default_prop:s0 exact int
73 ro.public.prop2 u:object_r:foo_prop:s0 exact enum c b a
74 ctl.start$prop3 u:object_r:ctl_prop:s0 exact bool
75 ro.prop4 u:object_r:bar_prop:s0 exact string
76 ro.legacy.prop4 u:object_r:baz_prop:s0 exact string
77 )";
78
79 constexpr const char* kBadContexts =
80 R"(
81 prop1 u:object_r:default_prop:s0 exact double
82 ro.public.prop2 u:object_r:foo_prop:s0 exact enum a c
83 ctl.start$prop3 u:object_r:ctl_prop:s0 exact string
84 ro.prop4 u:object_r:bar_prop:s0 exact int
85 ro.legacy.prop4 u:object_r:baz_prop:s0 exact bool
86 )";
87
88 } // namespace
89
TEST(SyspropTest,TypeCheckerTest)90 TEST(SyspropTest, TypeCheckerTest) {
91 TemporaryFile api_file;
92 close(api_file.fd);
93 api_file.fd = -1;
94 ASSERT_TRUE(android::base::WriteStringToFile(kApi, api_file.path));
95
96 std::string err;
97 auto api = ParseApiFile(api_file.path);
98 ASSERT_RESULT_OK(api);
99
100 // Good property_contexts tests
101 std::vector<PropertyInfoEntry> entries;
102 std::vector<std::string> errors;
103 ParsePropertyInfoFile(kContexts, true, &entries, &errors);
104 ASSERT_TRUE(errors.empty());
105
106 auto res = CheckPropertyTypes(*api, entries);
107 EXPECT_TRUE(res.ok());
108
109 // Bad property_contexts tests
110 std::vector<PropertyInfoEntry> bad_entries;
111 ParsePropertyInfoFile(kBadContexts, true, &bad_entries, &errors);
112 ASSERT_TRUE(errors.empty());
113
114 auto bad_res = CheckPropertyTypes(*api, bad_entries);
115 EXPECT_FALSE(bad_res.ok());
116
117 EXPECT_EQ(
118 bad_res.error().message(),
119 "Type of prop 'prop1' is incompatible with property_contexts\n"
120 "In sysprop_library: Long\n"
121 "In property_contexts: double (should be 'int')\n"
122 "\n"
123 "Type of prop 'ro.public.prop2' is incompatible with property_contexts\n"
124 "In sysprop_library: Enum a|b|c\n"
125 "In property_contexts: enum a c (should be 'enum a b c')\n"
126 "\n"
127 "Type of prop 'ctl.start$prop3' is incompatible with property_contexts\n"
128 "In sysprop_library: Boolean\n"
129 "In property_contexts: string (should be 'bool')\n"
130 "\n"
131 "Type of prop 'ro.prop4' is incompatible with property_contexts\n"
132 "In sysprop_library: String\n"
133 "In property_contexts: int (should be 'string')\n"
134 "\n"
135 "Type of prop 'ro.legacy.prop4' is incompatible with property_contexts\n"
136 "In sysprop_library: String\n"
137 "In property_contexts: bool (should be 'string')\n");
138 }
139