blob: 02a0e8d4f07492c2e60be1dd1a30b57fb21027a5 [file] [log] [blame]
/*
* Copyright (C) 2019 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "src/profiling/deobfuscator.h"
#include "test/gtest_and_gmock.h"
namespace perfetto {
namespace profiling {
bool operator==(const ObfuscatedClass& a, const ObfuscatedClass& b);
bool operator==(const ObfuscatedClass& a, const ObfuscatedClass& b) {
return a.deobfuscated_name() == b.deobfuscated_name() &&
a.deobfuscated_fields() == b.deobfuscated_fields() &&
a.deobfuscated_methods() == b.deobfuscated_methods();
}
namespace {
using ::testing::_;
using ::testing::ElementsAre;
using ::testing::Eq;
using ::testing::Pair;
TEST(ProguardParserTest, ReadClass) {
ProguardParser p;
ASSERT_TRUE(
p.AddLine(
"android.arch.core.executor.ArchTaskExecutor -> android.arch.a.a.a:")
.ok());
ASSERT_THAT(p.ConsumeMapping(),
ElementsAre(std::pair<std::string, ObfuscatedClass>(
"android.arch.a.a.a",
"android.arch.core.executor.ArchTaskExecutor")));
}
TEST(ProguardParserTest, MissingColon) {
ProguardParser p;
ASSERT_FALSE(
p.AddLine(
"android.arch.core.executor.ArchTaskExecutor -> android.arch.a.a.a")
.ok());
}
TEST(ProguardParserTest, UnexpectedMember) {
ProguardParser p;
ASSERT_FALSE(
p.AddLine(" android.arch.core.executor.TaskExecutor mDelegate -> b")
.ok());
}
TEST(ProguardParserTest, Member) {
ProguardParser p;
ASSERT_TRUE(
p.AddLine(
"android.arch.core.executor.ArchTaskExecutor -> android.arch.a.a.a:")
.ok());
ASSERT_TRUE(
p.AddLine(" android.arch.core.executor.TaskExecutor mDelegate -> b")
.ok());
std::map<std::string, std::string> deobfuscated_fields{{"b", "mDelegate"}};
ASSERT_THAT(
p.ConsumeMapping(),
ElementsAre(std::pair<std::string, ObfuscatedClass>(
"android.arch.a.a.a", {"android.arch.core.executor.ArchTaskExecutor",
std::move(deobfuscated_fields),
{}})));
}
TEST(ProguardParserTest, Method) {
ProguardParser p;
ASSERT_TRUE(
p.AddLine(
"android.arch.core.executor.ArchTaskExecutor -> android.arch.a.a.a:")
.ok());
ASSERT_TRUE(p.AddLine(" 15:15:boolean isMainThread():116:116 -> b").ok());
auto mapping = p.ConsumeMapping();
ASSERT_THAT(mapping, ElementsAre(Pair("android.arch.a.a.a", _)));
EXPECT_THAT(
mapping.find("android.arch.a.a.a")->second.deobfuscated_methods(),
ElementsAre(Pair(
"b", "android.arch.core.executor.ArchTaskExecutor.isMainThread")));
}
TEST(ProguardParserTest, AmbiguousMethodSameCls) {
ProguardParser p;
ASSERT_TRUE(
p.AddLine(
"android.arch.core.executor.ArchTaskExecutor -> android.arch.a.a.a:")
.ok());
ASSERT_TRUE(p.AddLine(" 15:15:boolean isMainThread():116:116 -> b").ok());
ASSERT_TRUE(
p.AddLine(" 15:15:boolean somethingDifferent(int):116:116 -> b").ok());
auto mapping = p.ConsumeMapping();
ASSERT_THAT(mapping, ElementsAre(Pair("android.arch.a.a.a", _)));
EXPECT_THAT(
mapping.find("android.arch.a.a.a")->second.deobfuscated_methods(),
ElementsAre(Pair(
"b", "android.arch.core.executor.ArchTaskExecutor.[ambiguous]")));
}
TEST(ProguardParserTest, AmbiguousMethodDifferentCls) {
ProguardParser p;
ASSERT_TRUE(
p.AddLine(
"android.arch.core.executor.ArchTaskExecutor -> android.arch.a.a.a:")
.ok());
ASSERT_TRUE(p.AddLine(" 15:15:boolean isMainThread():116:116 -> b").ok());
ASSERT_TRUE(
p.AddLine(" 15:15:boolean Foo.somethingDifferent(int):116:116 -> b")
.ok());
auto mapping = p.ConsumeMapping();
ASSERT_THAT(mapping, ElementsAre(Pair("android.arch.a.a.a", _)));
EXPECT_THAT(mapping.find("android.arch.a.a.a")->second.deobfuscated_methods(),
ElementsAre(Pair(
"b",
"Foo.somethingDifferent | "
"android.arch.core.executor.ArchTaskExecutor.isMainThread")));
}
TEST(ProguardParserTest, AmbiguousMethodSameAndDifferentCls) {
ProguardParser p;
ASSERT_TRUE(
p.AddLine(
"android.arch.core.executor.ArchTaskExecutor -> android.arch.a.a.a:")
.ok());
ASSERT_TRUE(p.AddLine(" 15:15:boolean isMainThread():116:116 -> b").ok());
ASSERT_TRUE(p.AddLine(" 15:15:boolean what(String):116:116 -> b").ok());
ASSERT_TRUE(
p.AddLine(" 15:15:boolean Foo.somethingDifferent(int):116:116 -> b")
.ok());
auto mapping = p.ConsumeMapping();
ASSERT_THAT(mapping, ElementsAre(Pair("android.arch.a.a.a", _)));
EXPECT_THAT(mapping.find("android.arch.a.a.a")->second.deobfuscated_methods(),
ElementsAre(Pair(
"b",
"Foo.somethingDifferent | "
"android.arch.core.executor.ArchTaskExecutor.[ambiguous]")));
}
TEST(ProguardParserTest, AmbiguousMethodSameAndDifferentCls2) {
ProguardParser p;
ASSERT_TRUE(
p.AddLine(
"android.arch.core.executor.ArchTaskExecutor -> android.arch.a.a.a:")
.ok());
ASSERT_TRUE(p.AddLine(" 15:15:boolean isMainThread():116:116 -> b").ok());
ASSERT_TRUE(p.AddLine(" 15:15:boolean what(String):116:116 -> b").ok());
ASSERT_TRUE(
p.AddLine(" 15:15:boolean Foo.somethingDifferent(int):116:116 -> b")
.ok());
ASSERT_TRUE(
p.AddLine(" 15:15:boolean Foo.third(int,int):116:116 -> b").ok());
auto mapping = p.ConsumeMapping();
ASSERT_THAT(mapping, ElementsAre(Pair("android.arch.a.a.a", _)));
EXPECT_THAT(mapping.find("android.arch.a.a.a")->second.deobfuscated_methods(),
ElementsAre(Pair(
"b",
"Foo.[ambiguous] | "
"android.arch.core.executor.ArchTaskExecutor.[ambiguous]")));
}
TEST(ProguardParserTest, DuplicateClass) {
ProguardParser p;
ASSERT_TRUE(
p.AddLine(
"android.arch.core.executor.ArchTaskExecutor -> android.arch.a.a.a:")
.ok());
ASSERT_FALSE(p.AddLine("android.arch.core.executor.ArchTaskExecutor2 -> "
"android.arch.a.a.a:")
.ok());
}
TEST(ProguardParserTest, DuplicateField) {
ProguardParser p;
ASSERT_TRUE(
p.AddLine(
"android.arch.core.executor.ArchTaskExecutor -> android.arch.a.a.a:")
.ok());
ASSERT_TRUE(
p.AddLine(" android.arch.core.executor.TaskExecutor mDelegate -> b")
.ok());
ASSERT_FALSE(
p.AddLine(" android.arch.core.executor.TaskExecutor mDelegate2 -> b")
.ok());
}
TEST(ProguardParserTest, DuplicateMethod) {
ProguardParser p;
ASSERT_TRUE(
p.AddLine(
"android.arch.core.executor.ArchTaskExecutor -> android.arch.a.a.a:")
.ok());
ASSERT_TRUE(p.AddLine(" 15:15:boolean isMainThread():116:116 -> b").ok());
ASSERT_TRUE(
p.AddLine(" 15:15:boolean doSomething(boolean):116:116 -> b").ok());
}
TEST(ProguardParserTest, DuplicateFieldSame) {
ProguardParser p;
ASSERT_TRUE(
p.AddLine(
"android.arch.core.executor.ArchTaskExecutor -> android.arch.a.a.a:")
.ok());
ASSERT_TRUE(
p.AddLine(" android.arch.core.executor.TaskExecutor mDelegate -> b")
.ok());
ASSERT_TRUE(
p.AddLine(
" 1:1:android.arch.core.executor.TaskExecutor mDelegate -> b")
.ok());
}
} // namespace
} // namespace profiling
} // namespace perfetto