1/* 2 * Copyright (c) 2022 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 <gtest/gtest.h> 16#include <map> 17#include <unistd.h> 18#include <vector> 19#include <v1_0/imemory_tracker_interface.h> 20 21#define private public 22#include "executor/memory_dumper.h" 23#undef private 24#include "dump_client_main.h" 25#include "dump_utils.h" 26#include "hdf_base.h" 27#include "executor/memory/memory_filter.h" 28#include "executor/memory/memory_util.h" 29#include "hidumper_test_utils.h" 30#include "util/string_utils.h" 31 32using namespace testing::ext; 33using namespace OHOS::HDI::Memorytracker::V1_0; 34namespace OHOS { 35namespace HiviewDFX { 36class MemoryDumperTest : public testing::Test { 37public: 38 static void SetUpTestCase(void); 39 static void TearDownTestCase(void); 40 void SetUp(); 41 void TearDown(); 42}; 43 44void MemoryDumperTest::SetUpTestCase(void) 45{ 46} 47void MemoryDumperTest::TearDownTestCase(void) 48{ 49} 50void MemoryDumperTest::SetUp(void) 51{ 52} 53void MemoryDumperTest::TearDown(void) 54{ 55} 56 57/** 58 * @tc.name: MemoryDumperTest001 59 * @tc.desc: Test MemoryDumper has correct group. 60 * @tc.type: FUNC 61 * @tc.require: issueI5NWZQ 62 */ 63HWTEST_F(MemoryDumperTest, MemoryDumperTest001, TestSize.Level3) 64{ 65 std::string cmd = "hidumper --mem"; 66 std::string str = "Anonymous Page"; 67 ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str)); 68} 69 70/** 71 * @tc.name: MemoryDumperTest002 72 * @tc.desc: Test MemoryDumper has DMA group. 73 * @tc.type: FUNC 74 * @tc.require: issueI5NX04 75 */ 76HWTEST_F(MemoryDumperTest, MemoryDumperTest002, TestSize.Level3) 77{ 78 std::string cmd = "hidumper --mem"; 79 std::string str = "DMA"; 80 ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str)); 81} 82 83/** 84 * @tc.name: MemoryDumperTest003 85 * @tc.desc: Test MemoryDumper has correct group. 86 * @tc.type: FUNC 87 * @tc.require: issueI5NWZQ 88 */ 89HWTEST_F(MemoryDumperTest, MemoryDumperTest003, TestSize.Level3) 90{ 91 std::string cmd = "hidumper --mem 1"; 92 std::string str = "Total"; 93 ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str)); 94 str = "native heap:"; 95 ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str)); 96 str = "Purgeable:"; 97 ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str)); 98 str = "DMA:"; 99 ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str)); 100} 101 102/** 103 * @tc.name: MemoryDumperTest004 104 * @tc.desc: Test MemoryDumper has GPU group. 105 * @tc.type: FUNC 106 * @tc.require: issueI5NWZQ 107 */ 108HWTEST_F(MemoryDumperTest, MemoryDumperTest004, TestSize.Level3) 109{ 110 std::string cmd = "hidumper --mem"; 111 std::string str = "GPU"; 112 ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str)); 113} 114 115/** 116 * @tc.name: MemoryDumperTest005 117 * @tc.desc: Test MemoryDumper has Purgeable group. 118 * @tc.type: FUNC 119 * @tc.require: issueI5NWZQ 120 */ 121HWTEST_F(MemoryDumperTest, MemoryDumperTest005, TestSize.Level3) 122{ 123 std::string cmd = "hidumper --mem"; 124 std::string str = "Total Purgeable"; 125 ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str)); 126 str = "Total PurgSum"; 127 ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str)); 128 str = "Total PurgPin"; 129 ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str)); 130} 131 132/** 133 * @tc.name: MemoryDumperTest006 134 * @tc.desc: Test MemoryDumper has Dma/PurgSum/PurgPin group. 135 * @tc.type: FUNC 136 * @tc.require: issueI5NWZQ 137 */ 138HWTEST_F(MemoryDumperTest, MemoryDumperTest006, TestSize.Level3) 139{ 140 std::string cmd = "hidumper --mem"; 141 std::string str = "Dma PurgSum PurgPin"; 142 ASSERT_TRUE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str)); 143} 144 145/** 146 * @tc.name: MemoryDumperTest007 147 * @tc.desc: Test zip memory not contain "Total Memory Usage by PID". 148 * @tc.type: FUNC 149 * @tc.require: issueI5NWZQ 150 */ 151HWTEST_F(MemoryDumperTest, MemoryDumperTest007, TestSize.Level3) 152{ 153 std::string cmd = "hidumper --mem --zip"; 154 std::string str = "Total Memory Usage by PID"; 155 ASSERT_FALSE(HidumperTestUtils::GetInstance().IsExistInCmdResult(cmd, str)); 156} 157 158/** 159 * @tc.name: MemoryDumperTest008 160 * @tc.desc: Test dma is equal graph. 161 * @tc.type: FUNC 162 * @tc.require: issueI5NWZQ 163 */ 164HWTEST_F(MemoryDumperTest, MemoryDumperTest008, TestSize.Level3) 165{ 166 auto rsPid = static_cast<int32_t>(HidumperTestUtils::GetInstance().GetPidByName("render_service")); 167 int pid = rsPid > 0 ? rsPid : 1; 168 ASSERT_GT(pid, 0); 169 std::string cmd = "hidumper --mem " + std::to_string(pid); 170 std::string str = "Graph"; 171 std::string result = ""; 172 ASSERT_TRUE(HidumperTestUtils::GetInstance().GetSpecialLine(cmd, str, result)); 173 std::string graphPss = HidumperTestUtils::GetInstance().GetValueInLine(result, 1); 174 ASSERT_TRUE(IsNumericStr(graphPss)); 175 str = "Dma"; 176 result = ""; 177 ASSERT_TRUE(HidumperTestUtils::GetInstance().GetSpecialLine(cmd, str, result)); 178 vector<string> values; 179 StringUtils::GetInstance().StringSplit(result, ":", values); // Dma:0 kB 180 std::string dmaStr = ""; 181 if (!values.empty() && values.size() >= 2) { // 2: Dma, 0 kB 182 dmaStr = values[1]; 183 if (dmaStr.size() >= 3) { 184 dmaStr = dmaStr.substr(0, dmaStr.size() - 4); // 4: ' kB' + 1(index from to 0,1,2...) 185 ASSERT_TRUE(IsNumericStr(dmaStr)); 186 } 187 } 188 ASSERT_TRUE(graphPss == dmaStr); 189} 190 191/** 192 * @tc.name: MemoryDumperTest009 193 * @tc.desc: Test GL not out of bounds. 194 * @tc.type: FUNC 195 * @tc.require: issueI5NWZQ 196 */ 197HWTEST_F(MemoryDumperTest, MemoryDumperTest009, TestSize.Level3) 198{ 199 auto rsPid = static_cast<int32_t>(HidumperTestUtils::GetInstance().GetPidByName("render_service")); 200 int pid = rsPid > 0 ? rsPid : 1; 201 ASSERT_GT(pid, 0); 202 std::string cmd = "hidumper --mem " + std::to_string(pid); 203 std::string str = "GL"; 204 std::string result = ""; 205 ASSERT_TRUE(HidumperTestUtils::GetInstance().GetSpecialLine(cmd, str, result)); 206 std::string glPss = HidumperTestUtils::GetInstance().GetValueInLine(result, 1); 207 ASSERT_TRUE(IsNumericStr(glPss)); 208 uint64_t gl = static_cast<uint64_t>(std::stoi(glPss)); 209 ASSERT_FALSE(gl < 0 || gl > UINT64_MAX); 210} 211 212/** 213 * @tc.name: MemoryDumperTest010 214 * @tc.desc: Test HeapSize for "hidumper --mem `pidof com.ohos.sceneboard`"". 215 * @tc.type: FUNC 216 * @tc.require: issueI5NWZQ 217 */ 218HWTEST_F(MemoryDumperTest, MemoryDumperTest010, TestSize.Level3) 219{ 220 auto sceneboardPid = static_cast<int32_t>(HidumperTestUtils::GetInstance().GetPidByName("com.ohos.sceneboard")); 221 int pid = sceneboardPid > 0 ? sceneboardPid : 1; 222 ASSERT_GT(pid, 0); 223 std::string cmd = "hidumper --mem " + std::to_string(pid); 224 std::string str = "native heap"; 225 std::string result = ""; 226 ASSERT_TRUE(HidumperTestUtils::GetInstance().GetSpecialLine(cmd, str, result)); 227 // 9: HeapSize index 228 std::string nativeHeapSizeStr = HidumperTestUtils::GetInstance().GetValueInLine(result, 9); 229 ASSERT_TRUE(IsNumericStr(nativeHeapSizeStr)); 230 if (DumpUtils::IsHmKernel()) { 231 uint64_t nativeHeapSize = static_cast<uint64_t>(std::stoi(nativeHeapSizeStr)); 232 ASSERT_TRUE(nativeHeapSize > 0); 233 } 234} 235 236/** 237 * @tc.name: MemoryUtilTest001 238 * @tc.desc: Test IsNameLine has correct ret. 239 * @tc.type: FUNC 240 */ 241HWTEST_F(MemoryDumperTest, MemoryUtilTest001, TestSize.Level1) 242{ 243 const std::string valueLine = "Rss: 24 kB"; 244 std::string name; 245 uint64_t iNode = 0; 246 ASSERT_FALSE(MemoryUtil::GetInstance().IsNameLine(valueLine, name, iNode)); 247 ASSERT_EQ(name, ""); 248 const std::string nameLine = "ffb84000-ffba5000 rw-p 00000000 00:00 0 [stack]"; 249 ASSERT_TRUE(MemoryUtil::GetInstance().IsNameLine(nameLine, name, iNode)); 250 ASSERT_EQ(name, "[stack]"); 251} 252 253/** 254 * @tc.name: MemoryUtilTest002 255 * @tc.desc: Test GetTypeAndValue has correct ret. 256 * @tc.type: FUNC 257 */ 258HWTEST_F(MemoryDumperTest, MemoryUtilTest002, TestSize.Level1) 259{ 260 std::string type; 261 uint64_t value = 0; 262 const std::string illegalStr = "aaaaaa"; 263 ASSERT_FALSE(MemoryUtil::GetInstance().GetTypeAndValue(illegalStr, type, value)); 264 const std::string valueStr = "MemTotal: 2010244 kB"; 265 ASSERT_TRUE(MemoryUtil::GetInstance().GetTypeAndValue(valueStr, type, value)); 266 ASSERT_EQ(type, "MemTotal"); 267 ASSERT_EQ(value, 2010244); 268} 269 270/** 271 * @tc.name: MemoryUtilTest003 272 * @tc.desc: Test RunCMD has correct ret. 273 * @tc.type: FUNC 274 */ 275HWTEST_F(MemoryDumperTest, MemoryUtilTest003, TestSize.Level1) 276{ 277 const std::string cmd = "ps -ef"; 278 std::vector<std::string> vec; 279 ASSERT_TRUE(MemoryUtil::GetInstance().RunCMD(cmd, vec)); 280 ASSERT_GT(vec.size(), 0); 281} 282 283/** 284 * @tc.name: MemoryUtilTest004 285 * @tc.desc: Test hidumper some cmd. 286 * @tc.type: FUNC 287 */ 288HWTEST_F(MemoryDumperTest, MemoryUtilTest004, TestSize.Level1) 289{ 290 std::string cmd = "hidumper --mem-smaps 1"; 291 std::vector<std::string> vec; 292 ASSERT_TRUE(MemoryUtil::GetInstance().RunCMD(cmd, vec)); 293 cmd = "hidumper --mem-smaps 1 -v"; 294 ASSERT_TRUE(MemoryUtil::GetInstance().RunCMD(cmd, vec)); 295 cmd = "hidumper --net 1"; 296 ASSERT_TRUE(MemoryUtil::GetInstance().RunCMD(cmd, vec)); 297 cmd = "hidumper --storage 1"; 298 ASSERT_TRUE(MemoryUtil::GetInstance().RunCMD(cmd, vec)); 299} 300 301/** 302 * @tc.name: MemoryUtilTest005 303 * @tc.desc: Test no such pid. 304 * @tc.type: FUNC 305 */ 306HWTEST_F(MemoryDumperTest, MemoryUtilTest005, TestSize.Level1) 307{ 308 std::string cmd = "hidumper --mem-smaps 100000"; 309 std::vector<std::string> vec; 310 ASSERT_TRUE(MemoryUtil::GetInstance().RunCMD(cmd, vec)); 311 cmd = "hidumper --mem-smaps 100000 -v"; 312 ASSERT_TRUE(MemoryUtil::GetInstance().RunCMD(cmd, vec)); 313 cmd = "hidumper --cpuusage 100000"; 314 ASSERT_TRUE(MemoryUtil::GetInstance().RunCMD(cmd, vec)); 315 cmd = "hidumper --mem 100000"; 316 ASSERT_TRUE(MemoryUtil::GetInstance().RunCMD(cmd, vec)); 317 cmd = "hidumper -p 100000"; 318 ASSERT_TRUE(MemoryUtil::GetInstance().RunCMD(cmd, vec)); 319 cmd = "hidumper --storage 100000"; 320 ASSERT_TRUE(MemoryUtil::GetInstance().RunCMD(cmd, vec)); 321 cmd = "hidumper --net 100000"; 322 ASSERT_TRUE(MemoryUtil::GetInstance().RunCMD(cmd, vec)); 323 cmd = "hidumper --mem-jsheap 100000"; 324 ASSERT_TRUE(MemoryUtil::GetInstance().RunCMD(cmd, vec)); 325 cmd = "hidumper --mem-jsheap 0"; 326 ASSERT_TRUE(MemoryUtil::GetInstance().RunCMD(cmd, vec)); 327 cmd = "hidumper --ipc --stat 100000"; 328 ASSERT_TRUE(MemoryUtil::GetInstance().RunCMD(cmd, vec)); 329} 330} // namespace HiviewDFX 331} // namespace OHOS