blob: a878da773714d33ef8eb79d5f7c22a25a749bd48 [file] [log] [blame]
//===-- PlatformAndroidTest.cpp -------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#include "Plugins/Platform/Android/PlatformAndroid.h"
#include "Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h"
#include "TestingSupport/SubsystemRAII.h"
#include "TestingSupport/TestUtilities.h"
#include "lldb/Utility/Connection.h"
#include "gmock/gmock.h"
using namespace lldb;
using namespace lldb_private;
using namespace lldb_private::platform_android;
using namespace testing;
namespace {
class MockSyncService : public AdbClient::SyncService {
public:
MockSyncService() : SyncService(std::unique_ptr<Connection>()) {}
MOCK_METHOD2(PullFile,
Status(const FileSpec &remote_file, const FileSpec &local_file));
MOCK_METHOD4(Stat, Status(const FileSpec &remote_file, uint32_t &mode,
uint32_t &size, uint32_t &mtime));
};
typedef std::unique_ptr<AdbClient::SyncService> SyncServiceUP;
class MockAdbClient : public AdbClient {
public:
explicit MockAdbClient() : AdbClient("mock") {}
MOCK_METHOD3(ShellToFile,
Status(const char *command, std::chrono::milliseconds timeout,
const FileSpec &output_file_spec));
MOCK_METHOD1(GetSyncService, SyncServiceUP(Status &error));
};
class PlatformAndroidTest : public PlatformAndroid, public ::testing::Test {
public:
PlatformAndroidTest() : PlatformAndroid(false) {
m_remote_platform_sp = PlatformSP(new PlatformAndroidRemoteGDBServer());
}
MOCK_METHOD1(GetAdbClient, AdbClientUP(Status &error));
MOCK_METHOD0(GetPropertyPackageName, llvm::StringRef());
};
} // namespace
TEST_F(PlatformAndroidTest, DownloadModuleSliceWithAdbClientError) {
EXPECT_CALL(*this, GetAdbClient(_))
.Times(1)
.WillOnce(DoAll(WithArg<0>([](auto &arg) {
arg = Status("Failed to create AdbClient");
}),
Return(ByMove(AdbClientUP()))));
EXPECT_TRUE(
DownloadModuleSlice(
FileSpec("/system/app/Test/Test.apk!/lib/arm64-v8a/libtest.so"), 4096,
3600, FileSpec())
.Fail());
}
TEST_F(PlatformAndroidTest, DownloadModuleSliceWithNormalFile) {
auto sync_service = new MockSyncService();
EXPECT_CALL(*sync_service, Stat(FileSpec("/system/lib64/libc.so"), _, _, _))
.Times(1)
.WillOnce(DoAll(SetArgReferee<1>(1), Return(Status())));
EXPECT_CALL(*sync_service, PullFile(FileSpec("/system/lib64/libc.so"), _))
.Times(1)
.WillOnce(Return(Status()));
auto adb_client = new MockAdbClient();
EXPECT_CALL(*adb_client, GetSyncService(_))
.Times(1)
.WillOnce(Return(ByMove(SyncServiceUP(sync_service))));
EXPECT_CALL(*this, GetAdbClient(_))
.Times(1)
.WillOnce(Return(ByMove(AdbClientUP(adb_client))));
EXPECT_TRUE(
DownloadModuleSlice(FileSpec("/system/lib64/libc.so"), 0, 0, FileSpec())
.Success());
}
TEST_F(PlatformAndroidTest, DownloadModuleSliceWithZipFile) {
auto adb_client = new MockAdbClient();
EXPECT_CALL(*adb_client,
ShellToFile(StrEq("dd if='/system/app/Test/Test.apk' "
"iflag=skip_bytes,count_bytes "
"skip=4096 count=3600 status=none"),
_, _))
.Times(1)
.WillOnce(Return(Status()));
EXPECT_CALL(*this, GetAdbClient(_))
.Times(1)
.WillOnce(Return(ByMove(AdbClientUP(adb_client))));
EXPECT_TRUE(
DownloadModuleSlice(
FileSpec("/system/app/Test/Test.apk!/lib/arm64-v8a/libtest.so"), 4096,
3600, FileSpec())
.Success());
}
TEST_F(PlatformAndroidTest, DownloadModuleSliceWithZipFileAndRunAs) {
auto adb_client = new MockAdbClient();
EXPECT_CALL(*adb_client,
ShellToFile(StrEq("run-as 'com.example.test' "
"dd if='/system/app/Test/Test.apk' "
"iflag=skip_bytes,count_bytes "
"skip=4096 count=3600 status=none"),
_, _))
.Times(1)
.WillOnce(Return(Status()));
EXPECT_CALL(*this, GetPropertyPackageName())
.Times(1)
.WillOnce(Return(llvm::StringRef("com.example.test")));
EXPECT_CALL(*this, GetAdbClient(_))
.Times(1)
.WillOnce(Return(ByMove(AdbClientUP(adb_client))));
EXPECT_TRUE(
DownloadModuleSlice(
FileSpec("/system/app/Test/Test.apk!/lib/arm64-v8a/libtest.so"), 4096,
3600, FileSpec())
.Success());
}
TEST_F(PlatformAndroidTest, GetFileWithNormalFile) {
auto sync_service = new MockSyncService();
EXPECT_CALL(*sync_service, Stat(FileSpec("/data/local/tmp/test"), _, _, _))
.Times(1)
.WillOnce(DoAll(SetArgReferee<1>(1), Return(Status())));
EXPECT_CALL(*sync_service, PullFile(FileSpec("/data/local/tmp/test"), _))
.Times(1)
.WillOnce(Return(Status()));
auto adb_client = new MockAdbClient();
EXPECT_CALL(*adb_client, GetSyncService(_))
.Times(1)
.WillOnce(Return(ByMove(SyncServiceUP(sync_service))));
EXPECT_CALL(*this, GetAdbClient(_))
.Times(1)
.WillOnce(Return(ByMove(AdbClientUP(adb_client))));
EXPECT_TRUE(GetFile(FileSpec("/data/local/tmp/test"), FileSpec()).Success());
}
TEST_F(PlatformAndroidTest, GetFileWithCatFallback) {
auto sync_service = new MockSyncService();
EXPECT_CALL(
*sync_service,
Stat(FileSpec("/data/data/com.example.app/lib-main/libtest.so"), _, _, _))
.Times(1)
.WillOnce(DoAll(SetArgReferee<1>(0), Return(Status())));
auto adb_client0 = new MockAdbClient();
EXPECT_CALL(*adb_client0, GetSyncService(_))
.Times(1)
.WillOnce(Return(ByMove(SyncServiceUP(sync_service))));
auto adb_client1 = new MockAdbClient();
EXPECT_CALL(
*adb_client1,
ShellToFile(StrEq("cat '/data/data/com.example.app/lib-main/libtest.so'"),
_, _))
.Times(1)
.WillOnce(Return(Status()));
EXPECT_CALL(*this, GetAdbClient(_))
.Times(2)
.WillOnce(Return(ByMove(AdbClientUP(adb_client0))))
.WillOnce(Return(ByMove(AdbClientUP(adb_client1))));
EXPECT_TRUE(
GetFile(FileSpec("/data/data/com.example.app/lib-main/libtest.so"),
FileSpec())
.Success());
}
TEST_F(PlatformAndroidTest, GetFileWithCatFallbackAndRunAs) {
auto sync_service = new MockSyncService();
EXPECT_CALL(
*sync_service,
Stat(FileSpec("/data/data/com.example.app/lib-main/libtest.so"), _, _, _))
.Times(1)
.WillOnce(DoAll(SetArgReferee<1>(0), Return(Status())));
auto adb_client0 = new MockAdbClient();
EXPECT_CALL(*adb_client0, GetSyncService(_))
.Times(1)
.WillOnce(Return(ByMove(SyncServiceUP(sync_service))));
auto adb_client1 = new MockAdbClient();
EXPECT_CALL(
*adb_client1,
ShellToFile(StrEq("run-as 'com.example.app' "
"cat '/data/data/com.example.app/lib-main/libtest.so'"),
_, _))
.Times(1)
.WillOnce(Return(Status()));
EXPECT_CALL(*this, GetPropertyPackageName())
.Times(1)
.WillOnce(Return(llvm::StringRef("com.example.app")));
EXPECT_CALL(*this, GetAdbClient(_))
.Times(2)
.WillOnce(Return(ByMove(AdbClientUP(adb_client0))))
.WillOnce(Return(ByMove(AdbClientUP(adb_client1))));
EXPECT_TRUE(
GetFile(FileSpec("/data/data/com.example.app/lib-main/libtest.so"),
FileSpec())
.Success());
}