1 //===-- PlatformAndroidTest.cpp -------------------------------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "Plugins/Platform/Android/PlatformAndroid.h" 10 #include "Plugins/Platform/Android/PlatformAndroidRemoteGDBServer.h" 11 #include "TestingSupport/SubsystemRAII.h" 12 #include "TestingSupport/TestUtilities.h" 13 #include "lldb/Utility/Connection.h" 14 #include "gmock/gmock.h" 15 16 using namespace lldb; 17 using namespace lldb_private; 18 using namespace lldb_private::platform_android; 19 using namespace testing; 20 21 namespace { 22 23 class MockSyncService : public AdbClient::SyncService { 24 public: 25 MockSyncService() : SyncService(std::unique_ptr<Connection>()) {} 26 27 MOCK_METHOD2(PullFile, 28 Status(const FileSpec &remote_file, const FileSpec &local_file)); 29 MOCK_METHOD4(Stat, Status(const FileSpec &remote_file, uint32_t &mode, 30 uint32_t &size, uint32_t &mtime)); 31 }; 32 33 typedef std::unique_ptr<AdbClient::SyncService> SyncServiceUP; 34 35 class MockAdbClient : public AdbClient { 36 public: 37 explicit MockAdbClient() : AdbClient("mock") {} 38 39 MOCK_METHOD3(ShellToFile, 40 Status(const char *command, std::chrono::milliseconds timeout, 41 const FileSpec &output_file_spec)); 42 MOCK_METHOD1(GetSyncService, SyncServiceUP(Status &error)); 43 }; 44 45 class PlatformAndroidTest : public PlatformAndroid, public ::testing::Test { 46 public: 47 PlatformAndroidTest() : PlatformAndroid(false) { 48 m_remote_platform_sp = PlatformSP(new PlatformAndroidRemoteGDBServer()); 49 } 50 51 MOCK_METHOD1(GetAdbClient, AdbClientUP(Status &error)); 52 MOCK_METHOD0(GetPropertyPackageName, llvm::StringRef()); 53 }; 54 55 } // namespace 56 57 TEST_F(PlatformAndroidTest, DownloadModuleSliceWithAdbClientError) { 58 EXPECT_CALL(*this, GetAdbClient(_)) 59 .Times(1) 60 .WillOnce(DoAll(WithArg<0>([](auto &arg) { 61 arg = Status::FromErrorString( 62 "Failed to create AdbClient"); 63 }), 64 Return(ByMove(AdbClientUP())))); 65 66 EXPECT_TRUE( 67 DownloadModuleSlice( 68 FileSpec("/system/app/Test/Test.apk!/lib/arm64-v8a/libtest.so"), 4096, 69 3600, FileSpec()) 70 .Fail()); 71 } 72 73 TEST_F(PlatformAndroidTest, DownloadModuleSliceWithNormalFile) { 74 auto sync_service = new MockSyncService(); 75 EXPECT_CALL(*sync_service, Stat(FileSpec("/system/lib64/libc.so"), _, _, _)) 76 .Times(1) 77 .WillOnce(DoAll(SetArgReferee<1>(1), Return(Status()))); 78 EXPECT_CALL(*sync_service, PullFile(FileSpec("/system/lib64/libc.so"), _)) 79 .Times(1) 80 .WillOnce(Return(Status())); 81 82 auto adb_client = new MockAdbClient(); 83 EXPECT_CALL(*adb_client, GetSyncService(_)) 84 .Times(1) 85 .WillOnce(Return(ByMove(SyncServiceUP(sync_service)))); 86 87 EXPECT_CALL(*this, GetAdbClient(_)) 88 .Times(1) 89 .WillOnce(Return(ByMove(AdbClientUP(adb_client)))); 90 91 EXPECT_TRUE( 92 DownloadModuleSlice(FileSpec("/system/lib64/libc.so"), 0, 0, FileSpec()) 93 .Success()); 94 } 95 96 TEST_F(PlatformAndroidTest, DownloadModuleSliceWithZipFile) { 97 auto adb_client = new MockAdbClient(); 98 EXPECT_CALL(*adb_client, 99 ShellToFile(StrEq("dd if='/system/app/Test/Test.apk' " 100 "iflag=skip_bytes,count_bytes " 101 "skip=4096 count=3600 status=none"), 102 _, _)) 103 .Times(1) 104 .WillOnce(Return(Status())); 105 106 EXPECT_CALL(*this, GetAdbClient(_)) 107 .Times(1) 108 .WillOnce(Return(ByMove(AdbClientUP(adb_client)))); 109 110 EXPECT_TRUE( 111 DownloadModuleSlice( 112 FileSpec("/system/app/Test/Test.apk!/lib/arm64-v8a/libtest.so"), 4096, 113 3600, FileSpec()) 114 .Success()); 115 } 116 117 TEST_F(PlatformAndroidTest, DownloadModuleSliceWithZipFileAndRunAs) { 118 auto adb_client = new MockAdbClient(); 119 EXPECT_CALL(*adb_client, 120 ShellToFile(StrEq("run-as 'com.example.test' " 121 "dd if='/system/app/Test/Test.apk' " 122 "iflag=skip_bytes,count_bytes " 123 "skip=4096 count=3600 status=none"), 124 _, _)) 125 .Times(1) 126 .WillOnce(Return(Status())); 127 128 EXPECT_CALL(*this, GetPropertyPackageName()) 129 .Times(1) 130 .WillOnce(Return(llvm::StringRef("com.example.test"))); 131 132 EXPECT_CALL(*this, GetAdbClient(_)) 133 .Times(1) 134 .WillOnce(Return(ByMove(AdbClientUP(adb_client)))); 135 136 EXPECT_TRUE( 137 DownloadModuleSlice( 138 FileSpec("/system/app/Test/Test.apk!/lib/arm64-v8a/libtest.so"), 4096, 139 3600, FileSpec()) 140 .Success()); 141 } 142 143 TEST_F(PlatformAndroidTest, GetFileWithNormalFile) { 144 auto sync_service = new MockSyncService(); 145 EXPECT_CALL(*sync_service, Stat(FileSpec("/data/local/tmp/test"), _, _, _)) 146 .Times(1) 147 .WillOnce(DoAll(SetArgReferee<1>(1), Return(Status()))); 148 EXPECT_CALL(*sync_service, PullFile(FileSpec("/data/local/tmp/test"), _)) 149 .Times(1) 150 .WillOnce(Return(Status())); 151 152 auto adb_client = new MockAdbClient(); 153 EXPECT_CALL(*adb_client, GetSyncService(_)) 154 .Times(1) 155 .WillOnce(Return(ByMove(SyncServiceUP(sync_service)))); 156 157 EXPECT_CALL(*this, GetAdbClient(_)) 158 .Times(1) 159 .WillOnce(Return(ByMove(AdbClientUP(adb_client)))); 160 161 EXPECT_TRUE(GetFile(FileSpec("/data/local/tmp/test"), FileSpec()).Success()); 162 } 163 164 TEST_F(PlatformAndroidTest, GetFileWithCatFallback) { 165 auto sync_service = new MockSyncService(); 166 EXPECT_CALL( 167 *sync_service, 168 Stat(FileSpec("/data/data/com.example.app/lib-main/libtest.so"), _, _, _)) 169 .Times(1) 170 .WillOnce(DoAll(SetArgReferee<1>(0), Return(Status()))); 171 172 auto adb_client0 = new MockAdbClient(); 173 EXPECT_CALL(*adb_client0, GetSyncService(_)) 174 .Times(1) 175 .WillOnce(Return(ByMove(SyncServiceUP(sync_service)))); 176 177 auto adb_client1 = new MockAdbClient(); 178 EXPECT_CALL( 179 *adb_client1, 180 ShellToFile(StrEq("cat '/data/data/com.example.app/lib-main/libtest.so'"), 181 _, _)) 182 .Times(1) 183 .WillOnce(Return(Status())); 184 185 EXPECT_CALL(*this, GetAdbClient(_)) 186 .Times(2) 187 .WillOnce(Return(ByMove(AdbClientUP(adb_client0)))) 188 .WillOnce(Return(ByMove(AdbClientUP(adb_client1)))); 189 190 EXPECT_TRUE( 191 GetFile(FileSpec("/data/data/com.example.app/lib-main/libtest.so"), 192 FileSpec()) 193 .Success()); 194 } 195 196 TEST_F(PlatformAndroidTest, GetFileWithCatFallbackAndRunAs) { 197 auto sync_service = new MockSyncService(); 198 EXPECT_CALL( 199 *sync_service, 200 Stat(FileSpec("/data/data/com.example.app/lib-main/libtest.so"), _, _, _)) 201 .Times(1) 202 .WillOnce(DoAll(SetArgReferee<1>(0), Return(Status()))); 203 204 auto adb_client0 = new MockAdbClient(); 205 EXPECT_CALL(*adb_client0, GetSyncService(_)) 206 .Times(1) 207 .WillOnce(Return(ByMove(SyncServiceUP(sync_service)))); 208 209 auto adb_client1 = new MockAdbClient(); 210 EXPECT_CALL( 211 *adb_client1, 212 ShellToFile(StrEq("run-as 'com.example.app' " 213 "cat '/data/data/com.example.app/lib-main/libtest.so'"), 214 _, _)) 215 .Times(1) 216 .WillOnce(Return(Status())); 217 218 EXPECT_CALL(*this, GetPropertyPackageName()) 219 .Times(1) 220 .WillOnce(Return(llvm::StringRef("com.example.app"))); 221 222 EXPECT_CALL(*this, GetAdbClient(_)) 223 .Times(2) 224 .WillOnce(Return(ByMove(AdbClientUP(adb_client0)))) 225 .WillOnce(Return(ByMove(AdbClientUP(adb_client1)))); 226 227 EXPECT_TRUE( 228 GetFile(FileSpec("/data/data/com.example.app/lib-main/libtest.so"), 229 FileSpec()) 230 .Success()); 231 } 232