summaryrefslogtreecommitdiffstats
path: root/init
diff options
context:
space:
mode:
authorTom Cherry2018-07-17 17:28:16 -0500
committerTom Cherry2018-07-17 17:28:51 -0500
commit5f0198bfbb7b8c7ee65dbadc19b4c7553531687c (patch)
treee3d253f2cf6a91dd720408caefb0d8ef1470ba9d /init
parenta63b3309fffcdbc8074648e539390342b0bd8697 (diff)
downloadplatform-system-core-5f0198bfbb7b8c7ee65dbadc19b4c7553531687c.tar.gz
platform-system-core-5f0198bfbb7b8c7ee65dbadc19b4c7553531687c.tar.xz
platform-system-core-5f0198bfbb7b8c7ee65dbadc19b4c7553531687c.zip
ueventd: add a test for ueventd_parser.cpp
Test: this unit test Change-Id: Ib23f23ea5b362bb458adf8208573e5dc80ad6cf0
Diffstat (limited to 'init')
-rw-r--r--init/Android.bp1
-rw-r--r--init/devices.h27
-rw-r--r--init/ueventd_parser.cpp4
-rw-r--r--init/ueventd_parser_test.cpp224
4 files changed, 244 insertions, 12 deletions
diff --git a/init/Android.bp b/init/Android.bp
index 625fb949a..5bbb7a09c 100644
--- a/init/Android.bp
+++ b/init/Android.bp
@@ -180,6 +180,7 @@ cc_test {
180 "service_test.cpp", 180 "service_test.cpp",
181 "subcontext_test.cpp", 181 "subcontext_test.cpp",
182 "tokenizer_test.cpp", 182 "tokenizer_test.cpp",
183 "ueventd_parser_test.cpp",
183 "ueventd_test.cpp", 184 "ueventd_test.cpp",
184 "util_test.cpp", 185 "util_test.cpp",
185 ], 186 ],
diff --git a/init/devices.h b/init/devices.h
index 9224fcd82..0be660f80 100644
--- a/init/devices.h
+++ b/init/devices.h
@@ -35,6 +35,8 @@ namespace init {
35 35
36class Permissions { 36class Permissions {
37 public: 37 public:
38 friend void TestPermissions(const Permissions& expected, const Permissions& test);
39
38 Permissions(const std::string& name, mode_t perm, uid_t uid, gid_t gid); 40 Permissions(const std::string& name, mode_t perm, uid_t uid, gid_t gid);
39 41
40 bool Match(const std::string& path) const; 42 bool Match(const std::string& path) const;
@@ -57,6 +59,8 @@ class Permissions {
57 59
58class SysfsPermissions : public Permissions { 60class SysfsPermissions : public Permissions {
59 public: 61 public:
62 friend void TestSysfsPermissions(const SysfsPermissions& expected, const SysfsPermissions& test);
63
60 SysfsPermissions(const std::string& name, const std::string& attribute, mode_t perm, uid_t uid, 64 SysfsPermissions(const std::string& name, const std::string& attribute, mode_t perm, uid_t uid,
61 gid_t gid) 65 gid_t gid)
62 : Permissions(name, perm, uid, gid), attribute_(attribute) {} 66 : Permissions(name, perm, uid, gid), attribute_(attribute) {}
@@ -71,16 +75,24 @@ class SysfsPermissions : public Permissions {
71class Subsystem { 75class Subsystem {
72 public: 76 public:
73 friend class SubsystemParser; 77 friend class SubsystemParser;
78 friend void TestSubsystems(const Subsystem& expected, const Subsystem& test);
79
80 enum DevnameSource {
81 DEVNAME_UEVENT_DEVNAME,
82 DEVNAME_UEVENT_DEVPATH,
83 };
74 84
75 Subsystem() {} 85 Subsystem() {}
76 Subsystem(std::string name) : name_(std::move(name)) {} 86 Subsystem(const std::string& name) : name_(name) {}
87 Subsystem(const std::string& name, DevnameSource source, const std::string& dir_name)
88 : name_(name), devname_source_(source), dir_name_(dir_name) {}
77 89
78 // Returns the full path for a uevent of a device that is a member of this subsystem, 90 // Returns the full path for a uevent of a device that is a member of this subsystem,
79 // according to the rules parsed from ueventd.rc 91 // according to the rules parsed from ueventd.rc
80 std::string ParseDevPath(const Uevent& uevent) const { 92 std::string ParseDevPath(const Uevent& uevent) const {
81 std::string devname = devname_source_ == DevnameSource::DEVNAME_UEVENT_DEVNAME 93 std::string devname = devname_source_ == DEVNAME_UEVENT_DEVNAME
82 ? uevent.device_name 94 ? uevent.device_name
83 : android::base::Basename(uevent.path); 95 : android::base::Basename(uevent.path);
84 96
85 return dir_name_ + "/" + devname; 97 return dir_name_ + "/" + devname;
86 } 98 }
@@ -88,14 +100,9 @@ class Subsystem {
88 bool operator==(const std::string& string_name) const { return name_ == string_name; } 100 bool operator==(const std::string& string_name) const { return name_ == string_name; }
89 101
90 private: 102 private:
91 enum class DevnameSource {
92 DEVNAME_UEVENT_DEVNAME,
93 DEVNAME_UEVENT_DEVPATH,
94 };
95
96 std::string name_; 103 std::string name_;
104 DevnameSource devname_source_ = DEVNAME_UEVENT_DEVNAME;
97 std::string dir_name_ = "/dev"; 105 std::string dir_name_ = "/dev";
98 DevnameSource devname_source_;
99}; 106};
100 107
101class DeviceHandler { 108class DeviceHandler {
diff --git a/init/ueventd_parser.cpp b/init/ueventd_parser.cpp
index c114ec704..54b0d16aa 100644
--- a/init/ueventd_parser.cpp
+++ b/init/ueventd_parser.cpp
@@ -117,11 +117,11 @@ Result<Success> SubsystemParser::ParseSection(std::vector<std::string>&& args,
117 117
118Result<Success> SubsystemParser::ParseDevName(std::vector<std::string>&& args) { 118Result<Success> SubsystemParser::ParseDevName(std::vector<std::string>&& args) {
119 if (args[1] == "uevent_devname") { 119 if (args[1] == "uevent_devname") {
120 subsystem_.devname_source_ = Subsystem::DevnameSource::DEVNAME_UEVENT_DEVNAME; 120 subsystem_.devname_source_ = Subsystem::DEVNAME_UEVENT_DEVNAME;
121 return Success(); 121 return Success();
122 } 122 }
123 if (args[1] == "uevent_devpath") { 123 if (args[1] == "uevent_devpath") {
124 subsystem_.devname_source_ = Subsystem::DevnameSource::DEVNAME_UEVENT_DEVPATH; 124 subsystem_.devname_source_ = Subsystem::DEVNAME_UEVENT_DEVPATH;
125 return Success(); 125 return Success();
126 } 126 }
127 127
diff --git a/init/ueventd_parser_test.cpp b/init/ueventd_parser_test.cpp
new file mode 100644
index 000000000..31208b926
--- /dev/null
+++ b/init/ueventd_parser_test.cpp
@@ -0,0 +1,224 @@
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 "ueventd_parser.h"
18
19#include <android-base/test_utils.h>
20#include <gtest/gtest.h>
21#include <private/android_filesystem_config.h>
22
23namespace android {
24namespace init {
25
26void TestSubsystems(const Subsystem& expected, const Subsystem& test) {
27 EXPECT_EQ(expected.name_, test.name_);
28 EXPECT_EQ(expected.devname_source_, test.devname_source_) << expected.name_;
29 EXPECT_EQ(expected.dir_name_, test.dir_name_) << expected.name_;
30}
31
32void TestPermissions(const Permissions& expected, const Permissions& test) {
33 EXPECT_EQ(expected.name_, test.name_);
34 EXPECT_EQ(expected.perm_, test.perm_) << expected.name_;
35 EXPECT_EQ(expected.uid_, test.uid_) << expected.name_;
36 EXPECT_EQ(expected.gid_, test.gid_) << expected.name_;
37 EXPECT_EQ(expected.prefix_, test.prefix_) << expected.name_;
38 EXPECT_EQ(expected.wildcard_, test.wildcard_) << expected.name_;
39}
40
41void TestSysfsPermissions(const SysfsPermissions& expected, const SysfsPermissions& test) {
42 TestPermissions(expected, test);
43 EXPECT_EQ(expected.attribute_, test.attribute_);
44}
45
46template <typename T, typename F>
47void TestVector(const T& expected, const T& test, F function) {
48 ASSERT_EQ(expected.size(), test.size());
49 auto expected_it = expected.begin();
50 auto test_it = test.begin();
51
52 for (; expected_it != expected.end(); ++expected_it, ++test_it) {
53 function(*expected_it, *test_it);
54 }
55}
56
57void TestUeventdFile(const std::string& content, const UeventdConfiguration& expected) {
58 TemporaryFile tf;
59 ASSERT_TRUE(tf.fd != -1);
60 ASSERT_TRUE(android::base::WriteStringToFd(content, tf.fd));
61
62 auto result = ParseConfig({tf.path});
63
64 TestVector(expected.subsystems, result.subsystems, TestSubsystems);
65 TestVector(expected.sysfs_permissions, result.sysfs_permissions, TestSysfsPermissions);
66 TestVector(expected.dev_permissions, result.dev_permissions, TestPermissions);
67 EXPECT_EQ(expected.firmware_directories, result.firmware_directories);
68}
69
70TEST(ueventd_parser, EmptyFile) {
71 TestUeventdFile("", {});
72}
73
74TEST(ueventd_parser, Subsystems) {
75 auto ueventd_file = R"(
76subsystem test_devname
77 devname uevent_devname
78
79subsystem test_devpath_no_dirname
80 devname uevent_devpath
81
82subsystem test_devname2
83 devname uevent_devname
84
85subsystem test_devpath_dirname
86 devname uevent_devpath
87 dirname /dev/graphics
88)";
89
90 auto subsystems = std::vector<Subsystem>{
91 {"test_devname", Subsystem::DEVNAME_UEVENT_DEVNAME, "/dev"},
92 {"test_devpath_no_dirname", Subsystem::DEVNAME_UEVENT_DEVPATH, "/dev"},
93 {"test_devname2", Subsystem::DEVNAME_UEVENT_DEVNAME, "/dev"},
94 {"test_devpath_dirname", Subsystem::DEVNAME_UEVENT_DEVPATH, "/dev/graphics"}};
95
96 TestUeventdFile(ueventd_file, {subsystems, {}, {}, {}});
97}
98
99TEST(ueventd_parser, Permissions) {
100 auto ueventd_file = R"(
101/dev/rtc0 0640 system system
102/dev/graphics/* 0660 root graphics
103/dev/*/test 0660 root system
104
105/sys/devices/platform/trusty.* trusty_version 0440 root log
106/sys/devices/virtual/input/input enable 0660 root input
107/sys/devices/virtual/*/input poll_delay 0660 root input
108)";
109
110 auto permissions = std::vector<Permissions>{
111 {"/dev/rtc0", 0640, AID_SYSTEM, AID_SYSTEM},
112 {"/dev/graphics/*", 0660, AID_ROOT, AID_GRAPHICS},
113 {"/dev/*/test", 0660, AID_ROOT, AID_SYSTEM},
114 };
115
116 auto sysfs_permissions = std::vector<SysfsPermissions>{
117 {"/sys/devices/platform/trusty.*", "trusty_version", 0440, AID_ROOT, AID_LOG},
118 {"/sys/devices/virtual/input/input", "enable", 0660, AID_ROOT, AID_INPUT},
119 {"/sys/devices/virtual/*/input", "poll_delay", 0660, AID_ROOT, AID_INPUT},
120 };
121
122 TestUeventdFile(ueventd_file, {{}, sysfs_permissions, permissions, {}});
123}
124
125TEST(ueventd_parser, FirmwareDirectories) {
126 auto ueventd_file = R"(
127firmware_directories /first/ /second /third
128firmware_directories /more
129)";
130
131 auto firmware_directories = std::vector<std::string>{
132 "/first/",
133 "/second",
134 "/third",
135 "/more",
136 };
137
138 TestUeventdFile(ueventd_file, {{}, {}, {}, firmware_directories});
139}
140
141TEST(ueventd_parser, AllTogether) {
142 auto ueventd_file = R"(
143
144/dev/rtc0 0640 system system
145firmware_directories /first/ /second /third
146/sys/devices/platform/trusty.* trusty_version 0440 root log
147
148subsystem test_devname
149 devname uevent_devname
150
151/dev/graphics/* 0660 root graphics
152
153subsystem test_devpath_no_dirname
154 devname uevent_devpath
155
156/sys/devices/virtual/input/input enable 0660 root input
157
158## this is a comment
159
160subsystem test_devname2
161## another comment
162 devname uevent_devname
163
164subsystem test_devpath_dirname
165 devname uevent_devpath
166 dirname /dev/graphics
167
168/dev/*/test 0660 root system
169/sys/devices/virtual/*/input poll_delay 0660 root input
170firmware_directories /more
171
172#ending comment
173)";
174
175 auto subsystems = std::vector<Subsystem>{
176 {"test_devname", Subsystem::DEVNAME_UEVENT_DEVNAME, "/dev"},
177 {"test_devpath_no_dirname", Subsystem::DEVNAME_UEVENT_DEVPATH, "/dev"},
178 {"test_devname2", Subsystem::DEVNAME_UEVENT_DEVNAME, "/dev"},
179 {"test_devpath_dirname", Subsystem::DEVNAME_UEVENT_DEVPATH, "/dev/graphics"}};
180
181 auto permissions = std::vector<Permissions>{
182 {"/dev/rtc0", 0640, AID_SYSTEM, AID_SYSTEM},
183 {"/dev/graphics/*", 0660, AID_ROOT, AID_GRAPHICS},
184 {"/dev/*/test", 0660, AID_ROOT, AID_SYSTEM},
185 };
186
187 auto sysfs_permissions = std::vector<SysfsPermissions>{
188 {"/sys/devices/platform/trusty.*", "trusty_version", 0440, AID_ROOT, AID_LOG},
189 {"/sys/devices/virtual/input/input", "enable", 0660, AID_ROOT, AID_INPUT},
190 {"/sys/devices/virtual/*/input", "poll_delay", 0660, AID_ROOT, AID_INPUT},
191 };
192
193 auto firmware_directories = std::vector<std::string>{
194 "/first/",
195 "/second",
196 "/third",
197 "/more",
198 };
199
200 TestUeventdFile(ueventd_file,
201 {subsystems, sysfs_permissions, permissions, firmware_directories});
202}
203
204// All of these lines are ill-formed, so test that there is 0 output.
205TEST(ueventd_parser, ParseErrors) {
206 auto ueventd_file = R"(
207
208/dev/rtc0 badmode baduidbad system
209/dev/rtc0 0640 baduidbad system
210/dev/rtc0 0640 system baduidbad
211firmware_directories #no directory listed
212/sys/devices/platform/trusty.* trusty_version badmode root log
213/sys/devices/platform/trusty.* trusty_version 0440 baduidbad log
214/sys/devices/platform/trusty.* trusty_version 0440 root baduidbad
215
216subsystem #no name
217
218)";
219
220 TestUeventdFile(ueventd_file, {});
221}
222
223} // namespace init
224} // namespace android