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