xref: /aosp_15_r20/external/perfetto/src/profiling/deobfuscator_unittest.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1 /*
2  * Copyright (C) 2019 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/profiling/deobfuscator.h"
18 
19 #include "test/gtest_and_gmock.h"
20 
21 namespace perfetto {
22 namespace profiling {
23 
24 bool operator==(const ObfuscatedClass& a, const ObfuscatedClass& b);
operator ==(const ObfuscatedClass & a,const ObfuscatedClass & b)25 bool operator==(const ObfuscatedClass& a, const ObfuscatedClass& b) {
26   return a.deobfuscated_name() == b.deobfuscated_name() &&
27          a.deobfuscated_fields() == b.deobfuscated_fields() &&
28          a.deobfuscated_methods() == b.deobfuscated_methods();
29 }
30 
31 namespace {
32 
33 using ::testing::_;
34 using ::testing::ElementsAre;
35 using ::testing::Eq;
36 using ::testing::Pair;
37 
TEST(ProguardParserTest,ReadClass)38 TEST(ProguardParserTest, ReadClass) {
39   ProguardParser p;
40   ASSERT_TRUE(
41       p.AddLine(
42            "android.arch.core.executor.ArchTaskExecutor -> android.arch.a.a.a:")
43           .ok());
44   ASSERT_THAT(p.ConsumeMapping(),
45               ElementsAre(std::pair<std::string, ObfuscatedClass>(
46                   "android.arch.a.a.a",
47                   "android.arch.core.executor.ArchTaskExecutor")));
48 }
49 
TEST(ProguardParserTest,MissingColon)50 TEST(ProguardParserTest, MissingColon) {
51   ProguardParser p;
52   ASSERT_FALSE(
53       p.AddLine(
54            "android.arch.core.executor.ArchTaskExecutor -> android.arch.a.a.a")
55           .ok());
56 }
57 
TEST(ProguardParserTest,UnexpectedMember)58 TEST(ProguardParserTest, UnexpectedMember) {
59   ProguardParser p;
60   ASSERT_FALSE(
61       p.AddLine("    android.arch.core.executor.TaskExecutor mDelegate -> b")
62           .ok());
63 }
64 
TEST(ProguardParserTest,Member)65 TEST(ProguardParserTest, Member) {
66   ProguardParser p;
67   ASSERT_TRUE(
68       p.AddLine(
69            "android.arch.core.executor.ArchTaskExecutor -> android.arch.a.a.a:")
70           .ok());
71   ASSERT_TRUE(
72       p.AddLine("    android.arch.core.executor.TaskExecutor mDelegate -> b")
73           .ok());
74   EXPECT_THAT(
75       p.ConsumeMapping(),
76       ElementsAre(std::pair<std::string, ObfuscatedClass>(
77           "android.arch.a.a.a", {"android.arch.core.executor.ArchTaskExecutor",
78                                  {{"b", "mDelegate"}},
79                                  {}})));
80 }
81 
TEST(ProguardParserTest,Method)82 TEST(ProguardParserTest, Method) {
83   ProguardParser p;
84   ASSERT_TRUE(
85       p.AddLine(
86            "android.arch.core.executor.ArchTaskExecutor -> android.arch.a.a.a:")
87           .ok());
88   ASSERT_TRUE(p.AddLine("    15:15:boolean isMainThread():116:116 -> b").ok());
89   auto mapping = p.ConsumeMapping();
90   ASSERT_THAT(mapping, ElementsAre(Pair("android.arch.a.a.a", _)));
91   EXPECT_THAT(
92       mapping.find("android.arch.a.a.a")->second.deobfuscated_methods(),
93       ElementsAre(Pair(
94           "b", "android.arch.core.executor.ArchTaskExecutor.isMainThread")));
95 }
96 
TEST(ProguardParserTest,AmbiguousMethodSameCls)97 TEST(ProguardParserTest, AmbiguousMethodSameCls) {
98   ProguardParser p;
99   ASSERT_TRUE(
100       p.AddLine(
101            "android.arch.core.executor.ArchTaskExecutor -> android.arch.a.a.a:")
102           .ok());
103   ASSERT_TRUE(p.AddLine("    15:15:boolean isMainThread():116:116 -> b").ok());
104   ASSERT_TRUE(
105       p.AddLine("    15:15:boolean somethingDifferent(int):116:116 -> b").ok());
106   auto mapping = p.ConsumeMapping();
107   ASSERT_THAT(mapping, ElementsAre(Pair("android.arch.a.a.a", _)));
108   EXPECT_THAT(
109       mapping.find("android.arch.a.a.a")->second.deobfuscated_methods(),
110       ElementsAre(Pair(
111           "b", "android.arch.core.executor.ArchTaskExecutor.[ambiguous]")));
112 }
113 
TEST(ProguardParserTest,AmbiguousMethodDifferentCls)114 TEST(ProguardParserTest, AmbiguousMethodDifferentCls) {
115   ProguardParser p;
116   ASSERT_TRUE(
117       p.AddLine(
118            "android.arch.core.executor.ArchTaskExecutor -> android.arch.a.a.a:")
119           .ok());
120   ASSERT_TRUE(p.AddLine("    15:15:boolean isMainThread():116:116 -> b").ok());
121   ASSERT_TRUE(
122       p.AddLine("    15:15:boolean Foo.somethingDifferent(int):116:116 -> b")
123           .ok());
124   auto mapping = p.ConsumeMapping();
125   ASSERT_THAT(mapping, ElementsAre(Pair("android.arch.a.a.a", _)));
126   EXPECT_THAT(mapping.find("android.arch.a.a.a")->second.deobfuscated_methods(),
127               ElementsAre(Pair(
128                   "b",
129                   "Foo.somethingDifferent | "
130                   "android.arch.core.executor.ArchTaskExecutor.isMainThread")));
131 }
132 
TEST(ProguardParserTest,AmbiguousMethodSameAndDifferentCls)133 TEST(ProguardParserTest, AmbiguousMethodSameAndDifferentCls) {
134   ProguardParser p;
135   ASSERT_TRUE(
136       p.AddLine(
137            "android.arch.core.executor.ArchTaskExecutor -> android.arch.a.a.a:")
138           .ok());
139   ASSERT_TRUE(p.AddLine("    15:15:boolean isMainThread():116:116 -> b").ok());
140   ASSERT_TRUE(p.AddLine("    15:15:boolean what(String):116:116 -> b").ok());
141   ASSERT_TRUE(
142       p.AddLine("    15:15:boolean Foo.somethingDifferent(int):116:116 -> b")
143           .ok());
144   auto mapping = p.ConsumeMapping();
145   ASSERT_THAT(mapping, ElementsAre(Pair("android.arch.a.a.a", _)));
146   EXPECT_THAT(mapping.find("android.arch.a.a.a")->second.deobfuscated_methods(),
147               ElementsAre(Pair(
148                   "b",
149                   "Foo.somethingDifferent | "
150                   "android.arch.core.executor.ArchTaskExecutor.[ambiguous]")));
151 }
152 
TEST(ProguardParserTest,AmbiguousMethodSameAndDifferentCls2)153 TEST(ProguardParserTest, AmbiguousMethodSameAndDifferentCls2) {
154   ProguardParser p;
155   ASSERT_TRUE(
156       p.AddLine(
157            "android.arch.core.executor.ArchTaskExecutor -> android.arch.a.a.a:")
158           .ok());
159   ASSERT_TRUE(p.AddLine("    15:15:boolean isMainThread():116:116 -> b").ok());
160   ASSERT_TRUE(p.AddLine("    15:15:boolean what(String):116:116 -> b").ok());
161   ASSERT_TRUE(
162       p.AddLine("    15:15:boolean Foo.somethingDifferent(int):116:116 -> b")
163           .ok());
164   ASSERT_TRUE(
165       p.AddLine("    15:15:boolean Foo.third(int,int):116:116 -> b").ok());
166   auto mapping = p.ConsumeMapping();
167   ASSERT_THAT(mapping, ElementsAre(Pair("android.arch.a.a.a", _)));
168   EXPECT_THAT(mapping.find("android.arch.a.a.a")->second.deobfuscated_methods(),
169               ElementsAre(Pair(
170                   "b",
171                   "Foo.[ambiguous] | "
172                   "android.arch.core.executor.ArchTaskExecutor.[ambiguous]")));
173 }
174 
TEST(ProguardParserTest,DuplicateClass)175 TEST(ProguardParserTest, DuplicateClass) {
176   ProguardParser p;
177   ASSERT_TRUE(
178       p.AddLine(
179            "android.arch.core.executor.ArchTaskExecutor -> android.arch.a.a.a:")
180           .ok());
181   ASSERT_FALSE(p.AddLine("android.arch.core.executor.ArchTaskExecutor2 -> "
182                          "android.arch.a.a.a:")
183                    .ok());
184 }
185 
TEST(ProguardParserTest,DuplicateField)186 TEST(ProguardParserTest, DuplicateField) {
187   ProguardParser p;
188   ASSERT_TRUE(
189       p.AddLine(
190            "android.arch.core.executor.ArchTaskExecutor -> android.arch.a.a.a:")
191           .ok());
192   ASSERT_TRUE(
193       p.AddLine("    android.arch.core.executor.TaskExecutor mDelegate -> b")
194           .ok());
195   ASSERT_FALSE(
196       p.AddLine("    android.arch.core.executor.TaskExecutor mDelegate2 -> b")
197           .ok());
198 }
199 
TEST(ProguardParserTest,DuplicateMethod)200 TEST(ProguardParserTest, DuplicateMethod) {
201   ProguardParser p;
202   ASSERT_TRUE(
203       p.AddLine(
204            "android.arch.core.executor.ArchTaskExecutor -> android.arch.a.a.a:")
205           .ok());
206   ASSERT_TRUE(p.AddLine("    15:15:boolean isMainThread():116:116 -> b").ok());
207   ASSERT_TRUE(
208       p.AddLine("    15:15:boolean doSomething(boolean):116:116 -> b").ok());
209 }
210 
TEST(ProguardParserTest,DuplicateFieldSame)211 TEST(ProguardParserTest, DuplicateFieldSame) {
212   ProguardParser p;
213   ASSERT_TRUE(
214       p.AddLine(
215            "android.arch.core.executor.ArchTaskExecutor -> android.arch.a.a.a:")
216           .ok());
217   ASSERT_TRUE(
218       p.AddLine("    android.arch.core.executor.TaskExecutor mDelegate -> b")
219           .ok());
220   ASSERT_TRUE(
221       p.AddLine(
222            "    1:1:android.arch.core.executor.TaskExecutor mDelegate -> b")
223           .ok());
224 }
225 
TEST(ProguardParserTest,EmptyLinesAndComments)226 TEST(ProguardParserTest, EmptyLinesAndComments) {
227   ProguardParser p;
228   const char input[] = R"(
229 # comment
230 
231 Example$$Class -> C:
232 
233     int first -> q
234     # indented comment
235     long second -> o
236 )";
237 
238   ASSERT_TRUE(p.AddLines(std::string(input)));
239   EXPECT_THAT(
240       p.ConsumeMapping(),
241       ElementsAre(std::pair<std::string, ObfuscatedClass>(
242           "C", {"Example$$Class", {{"q", "first"}, {"o", "second"}}, {}})));
243 }
244 
245 }  // namespace
246 }  // namespace profiling
247 }  // namespace perfetto
248