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("Failed to create AdbClient"); 62 }), 63 Return(ByMove(AdbClientUP())))); 64 65 EXPECT_TRUE( 66 DownloadModuleSlice( 67 FileSpec("/system/app/Test/Test.apk!/lib/arm64-v8a/libtest.so"), 4096, 68 3600, FileSpec()) 69 .Fail()); 70 } 71 72 TEST_F(PlatformAndroidTest, DownloadModuleSliceWithNormalFile) { 73 auto sync_service = new MockSyncService(); 74 EXPECT_CALL(*sync_service, Stat(FileSpec("/system/lib64/libc.so"), _, _, _)) 75 .Times(1) 76 .WillOnce(DoAll(SetArgReferee<1>(1), Return(Status()))); 77 EXPECT_CALL(*sync_service, PullFile(FileSpec("/system/lib64/libc.so"), _)) 78 .Times(1) 79 .WillOnce(Return(Status())); 80 81 auto adb_client = new MockAdbClient(); 82 EXPECT_CALL(*adb_client, GetSyncService(_)) 83 .Times(1) 84 .WillOnce(Return(ByMove(SyncServiceUP(sync_service)))); 85 86 EXPECT_CALL(*this, GetAdbClient(_)) 87 .Times(1) 88 .WillOnce(Return(ByMove(AdbClientUP(adb_client)))); 89 90 EXPECT_TRUE( 91 DownloadModuleSlice(FileSpec("/system/lib64/libc.so"), 0, 0, FileSpec()) 92 .Success()); 93 } 94 95 TEST_F(PlatformAndroidTest, DownloadModuleSliceWithZipFile) { 96 auto adb_client = new MockAdbClient(); 97 EXPECT_CALL(*adb_client, 98 ShellToFile(StrEq("dd if='/system/app/Test/Test.apk' " 99 "iflag=skip_bytes,count_bytes " 100 "skip=4096 count=3600 status=none"), 101 _, _)) 102 .Times(1) 103 .WillOnce(Return(Status())); 104 105 EXPECT_CALL(*this, GetAdbClient(_)) 106 .Times(1) 107 .WillOnce(Return(ByMove(AdbClientUP(adb_client)))); 108 109 EXPECT_TRUE( 110 DownloadModuleSlice( 111 FileSpec("/system/app/Test/Test.apk!/lib/arm64-v8a/libtest.so"), 4096, 112 3600, FileSpec()) 113 .Success()); 114 } 115 116 TEST_F(PlatformAndroidTest, DownloadModuleSliceWithZipFileAndRunAs) { 117 auto adb_client = new MockAdbClient(); 118 EXPECT_CALL(*adb_client, 119 ShellToFile(StrEq("run-as 'com.example.test' " 120 "dd if='/system/app/Test/Test.apk' " 121 "iflag=skip_bytes,count_bytes " 122 "skip=4096 count=3600 status=none"), 123 _, _)) 124 .Times(1) 125 .WillOnce(Return(Status())); 126 127 EXPECT_CALL(*this, GetPropertyPackageName()) 128 .Times(1) 129 .WillOnce(Return(llvm::StringRef("com.example.test"))); 130 131 EXPECT_CALL(*this, GetAdbClient(_)) 132 .Times(1) 133 .WillOnce(Return(ByMove(AdbClientUP(adb_client)))); 134 135 EXPECT_TRUE( 136 DownloadModuleSlice( 137 FileSpec("/system/app/Test/Test.apk!/lib/arm64-v8a/libtest.so"), 4096, 138 3600, FileSpec()) 139 .Success()); 140 } 141 142 TEST_F(PlatformAndroidTest, GetFileWithNormalFile) { 143 auto sync_service = new MockSyncService(); 144 EXPECT_CALL(*sync_service, Stat(FileSpec("/data/local/tmp/test"), _, _, _)) 145 .Times(1) 146 .WillOnce(DoAll(SetArgReferee<1>(1), Return(Status()))); 147 EXPECT_CALL(*sync_service, PullFile(FileSpec("/data/local/tmp/test"), _)) 148 .Times(1) 149 .WillOnce(Return(Status())); 150 151 auto adb_client = new MockAdbClient(); 152 EXPECT_CALL(*adb_client, GetSyncService(_)) 153 .Times(1) 154 .WillOnce(Return(ByMove(SyncServiceUP(sync_service)))); 155 156 EXPECT_CALL(*this, GetAdbClient(_)) 157 .Times(1) 158 .WillOnce(Return(ByMove(AdbClientUP(adb_client)))); 159 160 EXPECT_TRUE(GetFile(FileSpec("/data/local/tmp/test"), FileSpec()).Success()); 161 } 162 163 TEST_F(PlatformAndroidTest, GetFileWithCatFallback) { 164 auto sync_service = new MockSyncService(); 165 EXPECT_CALL( 166 *sync_service, 167 Stat(FileSpec("/data/data/com.example.app/lib-main/libtest.so"), _, _, _)) 168 .Times(1) 169 .WillOnce(DoAll(SetArgReferee<1>(0), Return(Status()))); 170 171 auto adb_client0 = new MockAdbClient(); 172 EXPECT_CALL(*adb_client0, GetSyncService(_)) 173 .Times(1) 174 .WillOnce(Return(ByMove(SyncServiceUP(sync_service)))); 175 176 auto adb_client1 = new MockAdbClient(); 177 EXPECT_CALL( 178 *adb_client1, 179 ShellToFile(StrEq("cat '/data/data/com.example.app/lib-main/libtest.so'"), 180 _, _)) 181 .Times(1) 182 .WillOnce(Return(Status())); 183 184 EXPECT_CALL(*this, GetAdbClient(_)) 185 .Times(2) 186 .WillOnce(Return(ByMove(AdbClientUP(adb_client0)))) 187 .WillOnce(Return(ByMove(AdbClientUP(adb_client1)))); 188 189 EXPECT_TRUE( 190 GetFile(FileSpec("/data/data/com.example.app/lib-main/libtest.so"), 191 FileSpec()) 192 .Success()); 193 } 194 195 TEST_F(PlatformAndroidTest, GetFileWithCatFallbackAndRunAs) { 196 auto sync_service = new MockSyncService(); 197 EXPECT_CALL( 198 *sync_service, 199 Stat(FileSpec("/data/data/com.example.app/lib-main/libtest.so"), _, _, _)) 200 .Times(1) 201 .WillOnce(DoAll(SetArgReferee<1>(0), Return(Status()))); 202 203 auto adb_client0 = new MockAdbClient(); 204 EXPECT_CALL(*adb_client0, GetSyncService(_)) 205 .Times(1) 206 .WillOnce(Return(ByMove(SyncServiceUP(sync_service)))); 207 208 auto adb_client1 = new MockAdbClient(); 209 EXPECT_CALL( 210 *adb_client1, 211 ShellToFile(StrEq("run-as 'com.example.app' " 212 "cat '/data/data/com.example.app/lib-main/libtest.so'"), 213 _, _)) 214 .Times(1) 215 .WillOnce(Return(Status())); 216 217 EXPECT_CALL(*this, GetPropertyPackageName()) 218 .Times(1) 219 .WillOnce(Return(llvm::StringRef("com.example.app"))); 220 221 EXPECT_CALL(*this, GetAdbClient(_)) 222 .Times(2) 223 .WillOnce(Return(ByMove(AdbClientUP(adb_client0)))) 224 .WillOnce(Return(ByMove(AdbClientUP(adb_client1)))); 225 226 EXPECT_TRUE( 227 GetFile(FileSpec("/data/data/com.example.app/lib-main/libtest.so"), 228 FileSpec()) 229 .Success()); 230 } 231