xref: /aosp_15_r20/external/perfetto/src/traced/probes/ftrace/format_parser/format_parser_unittest.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1 /*
2  * Copyright (C) 2017 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 #include "src/traced/probes/ftrace/format_parser/format_parser.h"
17 
18 #include "test/gtest_and_gmock.h"
19 
20 namespace perfetto {
21 namespace {
22 
23 using testing::ElementsAre;
24 using testing::Eq;
25 
TEST(FtraceEventParserTest,HappyPath)26 TEST(FtraceEventParserTest, HappyPath) {
27   const std::string input = R"(name: the_name
28 ID: 42
29 format:
30 	field:unsigned short common_type;	offset:0;	size:2;	signed:0;
31 	field:unsigned char common_flags;	offset:2;	size:1;	signed:0;
32 	field:unsigned char common_preempt_count;	offset:3;	size:1;	signed:0;
33 	field:int common_pid;	offset:4;	size:4;	signed:1;
34 
35 	field:char client_name[64];	offset:8;	size:64;	signed:0;
36 	field:const char * heap_name;	offset:72;	size:4;	signed:1;
37 
38 print fmt: "client_name=%s heap_name=%s len=%zu mask=0x%x flags=0x%x", REC->client_name, REC->heap_name, REC->len, REC->mask, REC->flags
39 )";
40 
41   FtraceEvent output;
42   EXPECT_TRUE(ParseFtraceEvent(input));
43   EXPECT_TRUE(ParseFtraceEvent(input, &output));
44   EXPECT_EQ(output.name, "the_name");
45   EXPECT_EQ(output.id, 42u);
46   EXPECT_THAT(
47       output.fields,
48       ElementsAre(
49           Eq(FtraceEvent::Field{"char client_name[64]", 8, 64, false}),
50           Eq(FtraceEvent::Field{"const char * heap_name", 72, 4, true})));
51   EXPECT_THAT(
52       output.common_fields,
53       ElementsAre(
54           Eq(FtraceEvent::Field{"unsigned short common_type", 0, 2, false}),
55           Eq(FtraceEvent::Field{"unsigned char common_flags", 2, 1, false}),
56           Eq(FtraceEvent::Field{"unsigned char common_preempt_count", 3, 1,
57                                 false}),
58           Eq(FtraceEvent::Field{"int common_pid", 4, 4, true})));
59 }
60 
TEST(FtraceEventParserTest,OnlyCommonFields)61 TEST(FtraceEventParserTest, OnlyCommonFields) {
62   const std::string input = R"(name: another_name
63 ID: 42
64 format:
65 	field:unsigned short common_type;	offset:0;	size:2;	signed:0;
66 
67 print fmt: " ",
68 )";
69 
70   FtraceEvent output;
71   EXPECT_TRUE(ParseFtraceEvent(input));
72   EXPECT_TRUE(ParseFtraceEvent(input, &output));
73   EXPECT_EQ(output.name, "another_name");
74   EXPECT_EQ(output.id, 42u);
75   EXPECT_THAT(output.common_fields,
76               ElementsAre(Eq(FtraceEvent::Field{"unsigned short common_type", 0,
77                                                 2, false})));
78 }
79 
TEST(FtraceEventParserTest,MissingName)80 TEST(FtraceEventParserTest, MissingName) {
81   const std::string input = R"(ID: 42
82 format:
83 	field:unsigned short common_type;	offset:0;	size:2;	signed:0;
84 	field:unsigned char common_flags;	offset:2;	size:1;	signed:0;
85 	field:unsigned char common_preempt_count;	offset:3;	size:1;	signed:0;
86 	field:int common_pid;	offset:4;	size:4;	signed:1;
87 
88 print fmt: "client_name=%s heap_name=%s len=%zu mask=0x%x flags=0x%x", REC->client_name, REC->heap_name, REC->len, REC->mask, REC->flags
89 )";
90 
91   EXPECT_FALSE(ParseFtraceEvent(input));
92 }
93 
TEST(FtraceEventParserTest,MissingID)94 TEST(FtraceEventParserTest, MissingID) {
95   const std::string input = R"(name: the_name
96 format:
97 	field:unsigned short common_type;	offset:0;	size:2;	signed:0;
98 	field:unsigned char common_flags;	offset:2;	size:1;	signed:0;
99 	field:unsigned char common_preempt_count;	offset:3;	size:1;	signed:0;
100 	field:int common_pid;	offset:4;	size:4;	signed:1;
101 
102 print fmt: "client_name=%s heap_name=%s len=%zu mask=0x%x flags=0x%x", REC->client_name, REC->heap_name, REC->len, REC->mask, REC->flags
103 )";
104 
105   EXPECT_FALSE(ParseFtraceEvent(input));
106 }
107 
TEST(FtraceEventParserTest,NoFields)108 TEST(FtraceEventParserTest, NoFields) {
109   const std::string input = R"(name: the_name
110 ID: 10
111 print fmt: "client_name=%s heap_name=%s len=%zu mask=0x%x flags=0x%x", REC->client_name, REC->heap_name, REC->len, REC->mask, REC->flags
112 )";
113 
114   EXPECT_FALSE(ParseFtraceEvent(input));
115 }
116 
TEST(FtraceEventParserTest,BasicFuzzing)117 TEST(FtraceEventParserTest, BasicFuzzing) {
118   const std::string input = R"(name: the_name
119 ID: 42
120 format:
121 	field:unsigned short common_type;	offset:0;	size:2;	signed:0;
122 	field:unsigned char common_flags;	offset:2;	size:1;	signed:0;
123 	field:unsigned char common_preempt_count;	offset:3;	size:1;	signed:0;
124 	field:int common_pid;	offset:4;	size:4;	signed:1;
125 
126 	field:char client_name[64];	offset:8;	size:64;	signed:0;
127 	field:const char * heap_name;	offset:72;	size:4;	signed:0;
128 	field:size_t len;	offset:76;	size:4;	signed:0;
129 	field:unsigned int mask;	offset:80;	size:4;	signed:0;
130 	field:unsigned int flags;	offset:84;	size:4;	signed:0;
131 
132 print fmt: "client_name=%s heap_name=%s len=%zu mask=0x%x flags=0x%x", REC->client_name, REC->heap_name, REC->len, REC->mask, REC->flags
133 )";
134 
135   for (size_t i = 0; i < input.length(); i++) {
136     for (size_t j = 1; j < 10 && i + j < input.length(); j++) {
137       std::string copy = input;
138       copy.erase(i, j);
139       ParseFtraceEvent(copy);
140     }
141   }
142 }
143 
TEST(FtraceEventParserTest,GetNameFromTypeAndName)144 TEST(FtraceEventParserTest, GetNameFromTypeAndName) {
145   EXPECT_EQ(GetNameFromTypeAndName("int foo"), "foo");
146   EXPECT_EQ(GetNameFromTypeAndName("int foo_bar"), "foo_bar");
147   EXPECT_EQ(GetNameFromTypeAndName("const char * foo"), "foo");
148   EXPECT_EQ(GetNameFromTypeAndName("const char foo[64]"), "foo");
149   EXPECT_EQ(GetNameFromTypeAndName("char[] foo[16]"), "foo");
150   EXPECT_EQ(GetNameFromTypeAndName("u8 foo[(int)sizeof(struct blah)]"), "foo");
151 
152   EXPECT_EQ(GetNameFromTypeAndName(""), "");
153   EXPECT_EQ(GetNameFromTypeAndName("]"), "");
154   EXPECT_EQ(GetNameFromTypeAndName("["), "");
155   EXPECT_EQ(GetNameFromTypeAndName(" "), "");
156   EXPECT_EQ(GetNameFromTypeAndName(" []"), "");
157   EXPECT_EQ(GetNameFromTypeAndName(" ]["), "");
158   EXPECT_EQ(GetNameFromTypeAndName("char"), "");
159   EXPECT_EQ(GetNameFromTypeAndName("char *"), "");
160   EXPECT_EQ(GetNameFromTypeAndName("char 42"), "");
161 }
162 
163 }  // namespace
164 }  // namespace perfetto
165