xref: /aosp_15_r20/external/perfetto/src/traced/probes/ftrace/vendor_tracepoints_unittest.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
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 "src/traced/probes/ftrace/vendor_tracepoints.h"
18 
19 #include <vector>
20 
21 #include "test/gtest_and_gmock.h"
22 
23 #include "src/base/test/tmp_dir_tree.h"
24 #include "src/traced/probes/ftrace/atrace_hal_wrapper.h"
25 #include "src/traced/probes/ftrace/ftrace_procfs.h"
26 
27 using testing::_;
28 using testing::AnyNumber;
29 using testing::ElementsAre;
30 using testing::HasSubstr;
31 using testing::NiceMock;
32 using testing::Pair;
33 using testing::Return;
34 using testing::Sequence;
35 
36 namespace perfetto {
37 namespace vendor_tracepoints {
38 namespace {
39 
40 class MockHal : public AtraceHalWrapper {
41  public:
MockHal()42   MockHal() : AtraceHalWrapper() {}
43   MOCK_METHOD(std::vector<std::string>, ListCategories, (), (override));
44   MOCK_METHOD(bool,
45               EnableCategories,
46               (const std::vector<std::string>&),
47               (override));
48   MOCK_METHOD(bool, DisableAllCategories, (), (override));
49 };
50 
51 class MockFtraceProcfs : public FtraceProcfs {
52  public:
MockFtraceProcfs()53   MockFtraceProcfs() : FtraceProcfs("/root/") {
54     ON_CALL(*this, NumberOfCpus()).WillByDefault(Return(1));
55     ON_CALL(*this, WriteToFile(_, _)).WillByDefault(Return(true));
56     ON_CALL(*this, ClearFile(_)).WillByDefault(Return(true));
57     EXPECT_CALL(*this, NumberOfCpus()).Times(AnyNumber());
58   }
59 
60   MOCK_METHOD(bool,
61               WriteToFile,
62               (const std::string& path, const std::string& str),
63               (override));
64   MOCK_METHOD(bool,
65               AppendToFile,
66               (const std::string& path, const std::string& str),
67               (override));
68   MOCK_METHOD(char, ReadOneCharFromFile, (const std::string& path), (override));
69   MOCK_METHOD(bool, ClearFile, (const std::string& path), (override));
70   MOCK_METHOD(bool, IsFileWriteable, (const std::string& path), (override));
71   MOCK_METHOD(std::string,
72               ReadFileIntoString,
73               (const std::string& path),
74               (const, override));
75   MOCK_METHOD(std::vector<std::string>, ReadEnabledEvents, (), (override));
76   MOCK_METHOD(size_t, NumberOfCpus, (), (const, override));
77   MOCK_METHOD(const std::set<std::string>,
78               GetEventNamesForGroup,
79               (const std::string& path),
80               (const, override));
81 };
82 
TEST(DiscoverVendorTracepointsTest,DiscoverVendorTracepointsWithHal)83 TEST(DiscoverVendorTracepointsTest, DiscoverVendorTracepointsWithHal) {
84   MockHal hal;
85   MockFtraceProcfs ftrace;
86   Sequence s;
87 
88   EXPECT_CALL(hal, ListCategories())
89       .InSequence(s)
90       .WillOnce(Return(std::vector<std::string>({"gfx"})));
91   EXPECT_CALL(ftrace, WriteToFile("/root/events/enable", "0"))
92       .InSequence(s)
93       .WillOnce(Return(true));
94   EXPECT_CALL(hal, EnableCategories(ElementsAre("gfx")))
95       .InSequence(s)
96       .WillOnce(Return(true));
97   EXPECT_CALL(ftrace, ReadEnabledEvents())
98       .InSequence(s)
99       .WillOnce(Return(std::vector<std::string>({"foo/bar", "a/b"})));
100   EXPECT_CALL(hal, DisableAllCategories()).InSequence(s).WillOnce(Return(true));
101   EXPECT_CALL(ftrace, WriteToFile("/root/events/enable", "0"))
102       .InSequence(s)
103       .WillOnce(Return(true));
104 
105   EXPECT_THAT(DiscoverVendorTracepointsWithHal(&hal, &ftrace),
106               ElementsAre(Pair("gfx", ElementsAre(GroupAndName("foo", "bar"),
107                                                   GroupAndName("a", "b")))));
108 }
109 
TEST(DiscoverVendorTracepointsTest,DiscoverVendorTracepointsWithFileOk)110 TEST(DiscoverVendorTracepointsTest, DiscoverVendorTracepointsWithFileOk) {
111   base::TmpDirTree tree;
112   std::string contents =
113       "gfx\n"
114       " foo/bar\n"
115       " g/a\n"
116       " g/b\n"
117       "memory\n"
118       " grp/evt\n";
119   tree.AddFile("vendor_atrace.txt", contents);
120 
121   std::map<std::string, std::vector<GroupAndName>> result;
122   base::Status status = DiscoverVendorTracepointsWithFile(
123       tree.AbsolutePath("vendor_atrace.txt"), &result);
124 
125   ASSERT_TRUE(status.ok()) << status.message();
126   EXPECT_THAT(
127       result,
128       ElementsAre(Pair("gfx", ElementsAre(GroupAndName("foo", "bar"),
129                                           GroupAndName("g", "a"),
130                                           GroupAndName("g", "b"))),
131                   Pair("memory", ElementsAre(GroupAndName("grp", "evt")))));
132 }
133 
TEST(DiscoverVendorTracepointsTest,DiscoverVendorTracepointsWithFileEmptyLines)134 TEST(DiscoverVendorTracepointsTest,
135      DiscoverVendorTracepointsWithFileEmptyLines) {
136   base::TmpDirTree tree;
137   std::string contents =
138       "\n"
139       "gfx\n"
140       "   \n"
141       " foo/bar\n"
142       "\n";
143   tree.AddFile("vendor_atrace.txt", contents);
144 
145   std::map<std::string, std::vector<GroupAndName>> result;
146   base::Status status = DiscoverVendorTracepointsWithFile(
147       tree.AbsolutePath("vendor_atrace.txt"), &result);
148 
149   ASSERT_TRUE(status.ok()) << status.message();
150   EXPECT_THAT(result, ElementsAre(Pair(
151                           "gfx", ElementsAre(GroupAndName("foo", "bar")))));
152 }
153 
TEST(DiscoverVendorTracepointsTest,DiscoverVendorTracepointsWithFileWhitespaces)154 TEST(DiscoverVendorTracepointsTest,
155      DiscoverVendorTracepointsWithFileWhitespaces) {
156   base::TmpDirTree tree;
157   std::string contents =
158       "gfx\n"
159       " path/1\n"
160       "\tpath/2\n"
161       "  path/3\n"
162       "\t\tpath/4\n";
163   tree.AddFile("vendor_atrace.txt", contents);
164 
165   std::map<std::string, std::vector<GroupAndName>> result;
166   base::Status status = DiscoverVendorTracepointsWithFile(
167       tree.AbsolutePath("vendor_atrace.txt"), &result);
168 
169   ASSERT_TRUE(status.ok()) << status.message();
170   EXPECT_THAT(result,
171               ElementsAre(Pair("gfx", ElementsAre(GroupAndName("path", "1"),
172                                                   GroupAndName("path", "2"),
173                                                   GroupAndName("path", "3"),
174                                                   GroupAndName("path", "4")))));
175 }
176 
TEST(DiscoverVendorTracepointsTest,DiscoverVendorTracepointsWithFileNoCategory)177 TEST(DiscoverVendorTracepointsTest,
178      DiscoverVendorTracepointsWithFileNoCategory) {
179   base::TmpDirTree tree;
180   std::string contents =
181       " foo/bar\n"
182       " g/a\n"
183       " g/b\n";
184   tree.AddFile("vendor_atrace.txt", contents);
185 
186   std::map<std::string, std::vector<GroupAndName>> result;
187   base::Status status = DiscoverVendorTracepointsWithFile(
188       tree.AbsolutePath("vendor_atrace.txt"), &result);
189 
190   EXPECT_THAT(status.message(), HasSubstr("Ftrace event path before category"));
191 }
192 
TEST(DiscoverVendorTracepointsTest,DiscoverVendorTracepointsWithFileNoSlash)193 TEST(DiscoverVendorTracepointsTest, DiscoverVendorTracepointsWithFileNoSlash) {
194   base::TmpDirTree tree;
195   std::string contents =
196       "gfx\n"
197       " event\n";
198   tree.AddFile("vendor_atrace.txt", contents);
199 
200   std::map<std::string, std::vector<GroupAndName>> result;
201   base::Status status = DiscoverVendorTracepointsWithFile(
202       tree.AbsolutePath("vendor_atrace.txt"), &result);
203 
204   EXPECT_THAT(status.message(),
205               HasSubstr("Ftrace event path not in group/event format"));
206 }
207 
TEST(DiscoverVendorTracepointsTest,DiscoverVendorTracepointsWithFileEmptyGroup)208 TEST(DiscoverVendorTracepointsTest,
209      DiscoverVendorTracepointsWithFileEmptyGroup) {
210   base::TmpDirTree tree;
211   std::string contents =
212       "gfx\n"
213       " /event\n";
214   tree.AddFile("vendor_atrace.txt", contents);
215 
216   std::map<std::string, std::vector<GroupAndName>> result;
217   base::Status status = DiscoverVendorTracepointsWithFile(
218       tree.AbsolutePath("vendor_atrace.txt"), &result);
219 
220   EXPECT_THAT(status.message(), HasSubstr("group is empty"));
221 }
222 
TEST(DiscoverVendorTracepointsTest,DiscoverVendorTracepointsWithFileTooManySlash)223 TEST(DiscoverVendorTracepointsTest,
224      DiscoverVendorTracepointsWithFileTooManySlash) {
225   base::TmpDirTree tree;
226   std::string contents =
227       "gfx\n"
228       " group/dir/event\n";
229   tree.AddFile("vendor_atrace.txt", contents);
230 
231   std::map<std::string, std::vector<GroupAndName>> result;
232   base::Status status = DiscoverVendorTracepointsWithFile(
233       tree.AbsolutePath("vendor_atrace.txt"), &result);
234 
235   EXPECT_THAT(status.message(), HasSubstr("extra /"));
236 }
237 
TEST(DiscoverVendorTracepointsTest,DiscoverVendorTracepointsWithFileNameEmpty)238 TEST(DiscoverVendorTracepointsTest,
239      DiscoverVendorTracepointsWithFileNameEmpty) {
240   base::TmpDirTree tree;
241   std::string contents =
242       "gfx\n"
243       " group/\n";
244   tree.AddFile("vendor_atrace.txt", contents);
245 
246   std::map<std::string, std::vector<GroupAndName>> result;
247   base::Status status = DiscoverVendorTracepointsWithFile(
248       tree.AbsolutePath("vendor_atrace.txt"), &result);
249 
250   EXPECT_THAT(status.message(), HasSubstr("name empty"));
251 }
252 
TEST(DiscoverVendorTracepointsTest,DiscoverAccessibleVendorTracepointsWithFile)253 TEST(DiscoverVendorTracepointsTest,
254      DiscoverAccessibleVendorTracepointsWithFile) {
255   base::TmpDirTree tree;
256   std::string contents =
257       "gfx\n"
258       " g/a\n"
259       " g/b\n"
260       "memory\n"
261       " g/c\n";
262   tree.AddFile("vendor_atrace.txt", contents);
263   MockFtraceProcfs ftrace;
264 
265   EXPECT_CALL(ftrace, IsFileWriteable("/root/events/g/a/enable"))
266       .WillOnce(Return(false));
267   EXPECT_CALL(ftrace, IsFileWriteable("/root/events/g/b/enable"))
268       .WillOnce(Return(true));
269   EXPECT_CALL(ftrace, IsFileWriteable("/root/events/g/c/enable"))
270       .WillOnce(Return(false));
271 
272   std::map<std::string, std::vector<GroupAndName>> result;
273   base::Status status = DiscoverAccessibleVendorTracepointsWithFile(
274       tree.AbsolutePath("vendor_atrace.txt"), &result, &ftrace);
275 
276   ASSERT_TRUE(status.ok()) << status.message();
277   EXPECT_THAT(result,
278               ElementsAre(Pair("gfx", ElementsAre(GroupAndName("g", "b"))),
279                           Pair("memory", ElementsAre())));
280 }
281 
282 }  // namespace
283 }  // namespace vendor_tracepoints
284 }  // namespace perfetto
285