1/* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15#include <fcntl.h> 16#include <vector> 17#include <unistd.h> 18#include <cstdlib> 19#include <gtest/gtest.h> 20#include <string_ex.h> 21#include "inner/dump_service_id.h" 22#include "dump_client_main.h" 23#include "dump_controller.h" 24#include "dump_manager_client.h" 25#include "app_mgr_client.h" 26 27using namespace testing::ext; 28using namespace std; 29using OHOS::HiviewDFX::DumpClientMain; 30using OHOS::AppExecFwk::AppMgrClient; 31using OHOS::AppExecFwk::RunningProcessInfo; 32namespace OHOS { 33namespace HiviewDFX { 34const std::string TOOL_NAME = "hidumper"; 35const int BUFFER_SIZE = 1024; 36class HidumperClientTest : public testing::Test { 37public: 38 static void SetUpTestCase(void); 39 static void TearDownTestCase(void); 40 void SetUp(); 41 void TearDown(); 42}; 43 44void HidumperClientTest::SetUpTestCase(void) 45{ 46} 47 48void HidumperClientTest::TearDownTestCase(void) 49{ 50} 51 52void HidumperClientTest::SetUp(void) 53{ 54} 55 56void HidumperClientTest::TearDown(void) 57{ 58} 59 60/** 61 * @tc.name: ClientMainTest001 62 * @tc.desc: Test too many arguments. 63 * @tc.type: FUNC 64 */ 65HWTEST_F(HidumperClientTest, ClientMainTest001, TestSize.Level0) 66{ 67 char *argv[] = { 68 const_cast<char *>(TOOL_NAME.c_str()), 69 }; 70 int argc = ARG_MAX_COUNT + 1; 71 int ret = DumpClientMain::GetInstance().Main(argc, argv, STDOUT_FILENO); 72 ASSERT_EQ(ret, DumpStatus::DUMP_INVALID_ARG); 73} 74 75/** 76 * @tc.name: ClientMainTest002 77 * @tc.desc: Test empty argument. 78 * @tc.type: FUNC 79 */ 80HWTEST_F(HidumperClientTest, ClientMainTest002, TestSize.Level0) 81{ 82 char *argv[] = { 83 const_cast<char *>(TOOL_NAME.c_str()), 84 const_cast<char *>("--mem"), 85 const_cast<char *>("-1"), 86 const_cast<char *>(""), 87 const_cast<char *>("--mem"), 88 }; 89 int argc = sizeof(argv) / sizeof(argv[0]) - 1; 90 int ret = DumpClientMain::GetInstance().Main(argc, argv, STDOUT_FILENO); 91 ASSERT_EQ(ret, DumpStatus::DUMP_INVALID_ARG); 92} 93 94/** 95 * @tc.name: ClientMainTest003 96 * @tc.desc: Test too long argument . 97 * @tc.type: FUNC 98 */ 99HWTEST_F(HidumperClientTest, ClientMainTest003, TestSize.Level0) 100{ 101 std::string longArg; 102 longArg.assign(SINGLE_ARG_MAXLEN + 1, 'c'); 103 char *argv[] = { 104 const_cast<char *>(TOOL_NAME.c_str()), 105 const_cast<char *>("-h"), 106 const_cast<char *>(longArg.c_str()), 107 }; 108 int argc = sizeof(argv) / sizeof(argv[0]); 109 int ret = DumpClientMain::GetInstance().Main(argc, argv, STDOUT_FILENO); 110 ASSERT_EQ(ret, DumpStatus::DUMP_INVALID_ARG); 111} 112 113/** 114 * @tc.name: ClientMainTest004 115 * @tc.desc: Test null argument. 116 * @tc.type: FUNC 117 */ 118HWTEST_F(HidumperClientTest, ClientMainTest004, TestSize.Level0) 119{ 120 char *argv[] = { 121 const_cast<char *>(TOOL_NAME.c_str()), 122 nullptr, 123 }; 124 int argc = sizeof(argv) / sizeof(argv[0]); 125 int ret = DumpClientMain::GetInstance().Main(argc, argv, STDOUT_FILENO); 126 ASSERT_EQ(ret, DumpStatus::DUMP_INVALID_ARG); 127} 128 129/** 130 * @tc.name: ClientMainTest005 131 * @tc.desc: Test null fd. 132 * @tc.type: FUNC 133 */ 134HWTEST_F(HidumperClientTest, ClientMainTest005, TestSize.Level0) 135{ 136 char *argv[] = { 137 const_cast<char *>("hidumper"), 138 const_cast<char *>("--mem"), 139 const_cast<char *>("1"), 140 }; 141 int argc = sizeof(argv) / sizeof(argv[0]); 142 int fd = open("/dev/null", O_RDWR | O_CREAT | O_TRUNC, 0664); 143 if (fd <= 0) { 144 fd = STDERR_FILENO; 145 } 146 int ret = DumpClientMain::GetInstance().Main(argc, argv, fd); 147 ASSERT_EQ(ret, DumpStatus::DUMP_OK); 148} 149 150/** 151 * @tc.name: ClientMainTest006 152 * @tc.desc: Test null argv. 153 * @tc.type: FUNC 154 */ 155HWTEST_F(HidumperClientTest, ClientMainTest006, TestSize.Level0) 156{ 157 int argc = ARG_MAX_COUNT; 158 int ret = DumpClientMain::GetInstance().Main(argc, nullptr, STDOUT_FILENO); 159 ASSERT_EQ(ret, DumpStatus::DUMP_INVALID_ARG); 160} 161 162/** 163 * @tc.name: ManagerClientTest001 164 * @tc.desc: Test emtpy argument list. 165 * @tc.type: FUNC 166 */ 167HWTEST_F(HidumperClientTest, ManagerClientTest001, TestSize.Level0) 168{ 169 vector<u16string> args{}; 170 int ret = DumpManagerClient::GetInstance().Request(args, STDOUT_FILENO); 171 ASSERT_EQ(ret, DumpStatus::DUMP_FAIL); 172} 173 174/** 175 * @tc.name: ManagerClientTest002 176 * @tc.desc: Test emtpy argument. 177 * @tc.type: FUNC 178 */ 179HWTEST_F(HidumperClientTest, ManagerClientTest002, TestSize.Level0) 180{ 181 vector<u16string> args{ 182 std::u16string(), 183 }; 184 int ret = DumpManagerClient::GetInstance().Request(args, STDOUT_FILENO); 185 ASSERT_EQ(ret, DumpStatus::DUMP_FAIL); 186} 187 188/** 189 * @tc.name: ManagerClientTest003 190 * @tc.desc: Test mamanage client Request. 191 * @tc.type: FUNC 192 */ 193HWTEST_F(HidumperClientTest, ManagerClientTest003, TestSize.Level0) 194{ 195 vector<u16string> args{ 196 std::u16string(u"hidumper"), 197 std::u16string(u"-s"), 198 std::u16string(u"1212"), 199 }; 200 int ret = DumpManagerClient::GetInstance().Request(args, STDOUT_FILENO); 201 ASSERT_EQ(ret, DumpStatus::DUMP_OK); 202} 203 204/** 205 * @tc.name: ManagerClientTest004 206 * @tc.desc: Test mamanage client ScanPidOverLimit. 207 * @tc.type: FUNC 208 */ 209HWTEST_F(HidumperClientTest, ManagerClientTest004, TestSize.Level0) 210{ 211 sptr<IDumpBroker> proxy_ {nullptr}; 212 sptr<ISystemAbilityManager> sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); 213 ASSERT_TRUE(sam != nullptr) << "ManagerClientTest004 fail to get GetSystemAbilityManager"; 214 sptr<IRemoteObject> remoteObject = sam->CheckSystemAbility(DFX_HI_DUMPER_SERVICE_ABILITY_ID); 215 ASSERT_TRUE(remoteObject != nullptr) << "Get SystemAbility failed."; 216 proxy_ = iface_cast<IDumpBroker>(remoteObject); 217 std::string requestType = "fd"; 218 std::vector<int32_t> pidList; 219 int ret = proxy_->ScanPidOverLimit(requestType, LIMIT_SIZE, pidList); 220 ASSERT_EQ(ret, DumpStatus::DUMP_OK); 221} 222 223/** 224 * @tc.name: ManagerClientTest005 225 * @tc.desc: Test mamanage client CountFdNums. 226 * @tc.type: FUNC 227 */ 228HWTEST_F(HidumperClientTest, ManagerClientTest005, TestSize.Level0) 229{ 230 sptr<IDumpBroker> proxy_ {nullptr}; 231 sptr<ISystemAbilityManager> sam = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); 232 ASSERT_TRUE(sam != nullptr) << "ManagerClientTest005 fail to get GetSystemAbilityManager"; 233 sptr<IRemoteObject> remoteObject = sam->CheckSystemAbility(DFX_HI_DUMPER_SERVICE_ABILITY_ID); 234 ASSERT_TRUE(remoteObject != nullptr) << "Get SystemAbility failed."; 235 proxy_ = iface_cast<IDumpBroker>(remoteObject); 236 int32_t pid = 1; 237 uint32_t fdNums = 0; 238 std::string detailFdInfo; 239 std::string topLeakedType; 240 int ret = proxy_->CountFdNums(pid, fdNums, detailFdInfo, topLeakedType); 241 ASSERT_EQ(ret, DumpStatus::DUMP_OK); 242} 243 244/** 245 * @tc.name: ManagerClientTest006 246 * @tc.desc: Test ipc stat dump with pid. 247 * @tc.type: FUNC 248 */ 249HWTEST_F(HidumperClientTest, ManagerClientTest006, TestSize.Level0) 250{ 251 string pid; 252 FILE* file = popen("pidof samgr", "r"); 253 if (file) { 254 char buffer[BUFFER_SIZE]; 255 if (fgets(buffer, sizeof(buffer), file) != nullptr) { 256 pid.assign(buffer); 257 }; 258 pid = pid.substr(0, pid.length() - 1); 259 pclose(file); 260 } else { 261 std::cerr << "Failed to execute command" << std::endl; 262 } 263 vector<u16string> args{ 264 std::u16string(u"hidumper"), 265 std::u16string(u"--ipc"), 266 Str8ToStr16(pid), 267 std::u16string(u"--start-stat"), 268 }; 269 int32_t ret = DumpManagerClient::GetInstance().Request(args, STDOUT_FILENO); 270 ASSERT_EQ(ret, DumpStatus::DUMP_OK); 271} 272 273/** 274 * @tc.name: ManagerClientTest007 275 * @tc.desc: Test ipc stat dump all. 276 * @tc.type: FUNC 277 */ 278HWTEST_F(HidumperClientTest, ManagerClientTest007, TestSize.Level0) 279{ 280 vector<u16string> args{ 281 std::u16string(u"hidumper"), 282 std::u16string(u"--ipc"), 283 std::u16string(u"-a"), 284 std::u16string(u"--start-stat"), 285 }; 286 int ret = DumpManagerClient::GetInstance().Request(args, STDOUT_FILENO); 287 ASSERT_EQ(ret, DumpStatus::DUMP_OK); 288} 289 290/** 291 * @tc.name: ManagerClientTest008 292 * @tc.desc: Test cpuusage of all processes. 293 * @tc.type: FUNC 294 */ 295HWTEST_F(HidumperClientTest, ManagerClientTest008, TestSize.Level0) 296{ 297 vector<u16string> args{ 298 std::u16string(u"hidumper"), 299 std::u16string(u"--cpuusage"), 300 }; 301 int ret = DumpManagerClient::GetInstance().Request(args, STDOUT_FILENO); 302 ASSERT_EQ(ret, DumpStatus::DUMP_OK); 303} 304 305/** 306 * @tc.name: ManagerClientTest009 307 * @tc.desc: Test cpuusage with pid. 308 * @tc.type: FUNC 309 */ 310HWTEST_F(HidumperClientTest, ManagerClientTest009, TestSize.Level0) 311{ 312 vector<u16string> args{ 313 std::u16string(u"hidumper"), 314 std::u16string(u"--cpuusage"), 315 std::u16string(u"1"), 316 }; 317 int ret = DumpManagerClient::GetInstance().Request(args, STDOUT_FILENO); 318 ASSERT_EQ(ret, DumpStatus::DUMP_OK); 319} 320 321/** 322 * @tc.name: ManagerClientTest010 323 * @tc.desc: Test cpufreq. 324 * @tc.type: FUNC 325 */ 326HWTEST_F(HidumperClientTest, ManagerClientTest010, TestSize.Level0) 327{ 328 vector<u16string> args{ 329 std::u16string(u"hidumper"), 330 std::u16string(u"--cpufreq"), 331 }; 332 int ret = DumpManagerClient::GetInstance().Request(args, STDOUT_FILENO); 333 ASSERT_EQ(ret, DumpStatus::DUMP_OK); 334} 335 336/** 337 * @tc.name: ManagerClientTest011 338 * @tc.desc: Test --mem-jsheap. 339 * @tc.type: FUNC 340 */ 341HWTEST_F(HidumperClientTest, ManagerClientTest011, TestSize.Level0) 342{ 343 vector<u16string> args{ 344 std::u16string(u"hidumper"), 345 std::u16string(u"--mem-jsheap"), 346 }; 347 int ret = DumpManagerClient::GetInstance().Request(args, STDOUT_FILENO); 348 ASSERT_EQ(ret, DumpStatus::DUMP_OK); 349} 350 351/** 352 * @tc.name: ManagerClientTest012 353 * @tc.desc: Test --mem-jsheap. 354 * @tc.type: FUNC 355 */ 356HWTEST_F(HidumperClientTest, ManagerClientTest012, TestSize.Level0) 357{ 358 string pid; 359 auto appMgrClient = std::make_unique<AppMgrClient>(); 360 std::vector<RunningProcessInfo> runningProcessInfos; 361 appMgrClient->GetAllRunningProcesses(runningProcessInfos); 362 ASSERT_TRUE(runningProcessInfos.size() > 0); 363 364 pid = to_string(runningProcessInfos[0].pid_); 365 vector<u16string> args{ 366 std::u16string(u"hidumper"), 367 std::u16string(u"--mem-jsheap"), 368 Str8ToStr16(pid) 369 }; 370 int ret = DumpManagerClient::GetInstance().Request(args, STDOUT_FILENO); 371 ASSERT_EQ(ret, DumpStatus::DUMP_OK); 372} 373} // namespace HiviewDFX 374} // namespace OHOS