1 /*
2 * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
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
16 #include <dlfcn.h>
17 #include <gtest/gtest.h>
18 #include <sys/types.h>
19
20 #include "memory_data_plugin.h"
21 #include "plugin_module_api.h"
22
23 using namespace testing::ext;
24
25 namespace {
26 const std::string DEFAULT_TEST_PATH("/data/local/tmp/");
27 const std::string DEFAULT_BIN_PATH("/data/local/tmp/memorytest");
28 constexpr uint32_t BUF_SIZE = 4 * 1024 * 1024;
29 const int US_PER_S = 1000000;
30 constexpr uint32_t PAGE_SIZE = 4 * 1024;
31 constexpr int LINE_SIZE = 1000;
32
33 std::string g_path;
34
35 struct TestElement {
36 int32_t pid;
37 std::string name;
38 // data from /proc/$pid/stat
39 uint64_t vm_size_kb;
40 uint64_t vm_rss_kb;
41 uint64_t rss_anon_kb;
42 uint64_t rss_file_kb;
43 uint64_t rss_shmem_kb;
44 uint64_t vm_swap_kb;
45 uint64_t vm_locked_kb;
46 uint64_t vm_hwm_kb;
47 int64_t oom_score_adj;
48
49 uint64_t java_heap;
50 uint64_t native_heap;
51 uint64_t code;
52 uint64_t stack;
53 uint64_t graphics;
54 uint64_t private_other;
55 uint64_t purg_sum_kb;
56 uint64_t purg_pin_kb;
57 };
58
59 TestElement g_pidtarget[] = {
60 {1, "systemd", 226208, 9388, 2984, 6404, 0, 0, 0, 9616, -1, 3036, 4256, 288, 748, 0, 1388, 10232, 400},
61 {2, "kthreadd", 0, 0, 0, 0, 0, 0, 0, 0, -100, 3036, 4260, 336, 760, 0, 4204, 0, 0},
62 {11, "rcu_sched", 0, 0, 0, 0, 0, 0, 0, 0, 0, 3036, 4272, 400, 772, 0, 7160, 103, 0},
63 };
64
65 unsigned long g_meminfo[] = {
66 16168696, 1168452, 12363564, 2726188, 7370484, 29260, 8450388, 4807668,
67 2535372, 658832, 4148836, 10, 5678, 116790, 132, 0, 63999996, 62211580, 0
68 };
69
70 unsigned long g_vmeminfo[] = {
71 112823, 0, 587, 1848, 101, 9074, 8426, 18314,
72 0, 2416, 2348, 9073, 1876, 26863, 1, 0
73 };
74
75 struct AshMemInfo {
76 std::string name;
77 int32_t pid;
78 int32_t fd;
79 int32_t adj;
80 std::string ashmem_name;
81 uint64_t size;
82 int32_t id;
83 uint64_t time;
84 uint64_t ref_count;
85 uint64_t purged;
86 };
87
88 AshMemInfo g_ashMemInfo[] = {
89 {"com.ohos.settin", 1474, 46, 1, "dev/ashmem/SharedBlock:/data/storage/el2/database/entry/rdb/settingsdata.db",
90 2097152, 1, 1282999603, 1, 1},
91 {"com.ohos.launch", 1515, 54, 1, "dev/ashmem/hooknativesmb", 67108864, 10, 1282945782, 1, 0},
92 {"hiprofilerd", 6746, 27, 1, "dev/ashmem/memory-plugin", 67108864, 12, 1287845167, 0, 0},
93 {"hiprofiler_plug", 6756, 7, 1, "dev/ashmem/memory-plugin", 67108864, 15, 1358999004, 0, 0},
94 };
95
96 struct ProcessGpuInfo {
97 std::string addr;
98 int32_t pid;
99 int32_t tid;
100 uint64_t used_gpu_size;
101 };
102
103 struct GpuMemInfo {
104 std::string gpu_name;
105 uint64_t all_gpu_size;
106 ProcessGpuInfo gpuInfo[3];
107 };
108
109 GpuMemInfo g_gpuMemInfo = {
110 "mali0",
111 30217,
112 {
113 {"kctx-0xffffffc0108f5000", 1149, 1226, 30212},
114 {"kctx-0xffffffc0108f6000", 1049, 1216, 1},
115 {"kctx-0xffffffc0108f7000", 1206, 1206, 4}
116 }
117 };
118
119 struct DmaMemInfo {
120 std::string name;
121 int32_t pid;
122 int32_t fd;
123 uint64_t size;
124 int32_t ino;
125 int32_t expPid;
126 std::string exp_task_comm;
127 std::string buf_name;
128 std::string exp_name;
129 };
130
131 DmaMemInfo g_dmaMemInfo[] = {
132 {"ispserver", 433, 18, 12288, 3041, 433, "ispserver", "NULL", "videobuf2_vmalloc"},
133 {"ispserver", 433, 19, 12288, 3042, 433, "ispserver", "ispserver1", "videobuf2_vmalloc"},
134 {"ispserver", 433, 20, 12288, 3043, 433, "ispserver", "ispserver4", "videobuf2_vmalloc"},
135 {"ispserver", 433, 21, 12288, 3044, 433, "ispserver", "NULL", "videobuf2_vmalloc"},
136 {"render_service", 624, 9, 3686400, 28914, 624, "render_service", "NULL", "rockchipdrm"},
137 {"render_service", 624, 30, 3686400, 30144, 539, "disp_gralloc_ho", "1", "rockchipdrm"},
138 {"render_service", 624, 32, 3686400, 31026, 539, "disp_gralloc_ho", "5", "rockchipdrm"},
139 {"render_service", 624, 34, 3686400, 29650, 539, "disp_gralloc_ho", "disp_gralloc_ho78", "rockchipdrm"},
140 {"render_service", 624, 37, 3686400, 32896, 539, "disp_gralloc_ho", "0", "rockchipdrm"},
141 {"render_service", 624, 38, 3686400, 30860, 539, "disp_gralloc_ho", "NULL", "rockchipdrm"},
142 {"render_service", 624, 39, 3686400, 30860, 539, "disp_gralloc_ho", "NULL", "rockchipdrm"},
143 {"render_service", 624, 58, 3686400, 30145, 539, "disp_gralloc_ho", "NULL", "rockchipdrm"},
144 {"render_service", 624, 59, 208896, 32895, 539, "disp_gralloc_ho", "NULL", "rockchipdrm"},
145 {"render_service", 624, 66, 3686400, 32896, 539, "disp_gralloc_ho", "NULL", "rockchipdrm"},
146 {"com.ohos.system", 1298, 56, 3686400, 32896, 539, "disp_gralloc_ho", "NULL", "rockchipdrm"},
147 {"com.ohos.system", 1298, 60, 3686400, 32899, 539, "disp_gralloc_ho", "NULL", "rockchipdrm"},
148 {"com.ohos.system", 1298, 62, 3686400, 32901, 539, "disp_gralloc_ho", "NULL", "rockchipdrm"},
149 };
150
151 struct GpuSubTestInfo {
152 std::string category_name;
153 std::string size;
154 std::string type;
155 int32_t entryNum;
156 };
157
158 struct GpuDetailTestInfo {
159 std::string module_name;
160 GpuSubTestInfo gpu_sub_info[4];
161 };
162
163 struct GpuDumpTestInfo {
164 std::string window_name;
165 uint64_t id;
166 GpuDetailTestInfo gpu_detail_info[5];
167 std::string gpu_purgeable_size;
168 std::string type;
169 };
170
171 GpuDumpTestInfo g_gpudumpAllInfo = {
172 "",
173 0,
174 {
175 {
176 "skia/gr_text_blob_cache",
177 {
178 {"Other", "3.33", "KB", 1}
179 }
180 },
181 {
182 "SW Path Mask",
183 {
184 {"Texture", "352.34", "KB", 12}
185 }
186 },
187 {
188 "Other",
189 {
190 {"Buffer Object", "914.00", "bytes", 4},
191 {"StencilAttachment", "4.50", "MB", 2}
192 }
193 },
194 {
195 "Image",
196 {
197 {"Texture", "7.98", "MB", 1}
198 }
199 },
200 {
201 "Scratch",
202 {
203 {"Texture", "1.00", "MB", 1},
204 {"Buffer Object", "78.00", "KB", 2},
205 {"RenderTarget", "29.42", "MB", 3},
206 {"StencilAttachment", "14.21", "MB", 1}
207 }
208 }
209 },
210 "23.69",
211 "MB",
212 };
213
214 GpuDumpTestInfo g_gpudumpInfo1 = {
215 "SysUI_Volume",
216 10007273799686,
217 {
218 {
219 "SW Path Mask",
220 {
221 {"Texture", "352.34", "KB", 12}
222 }
223 },
224 {
225 "skia/gr_text_blob_cache",
226 {
227 {"Other", "3.33", "KB", 1}
228 }
229 }
230 },
231 "0.00",
232 "bytes",
233 };
234
235 GpuDumpTestInfo g_gpudumpInfo2 = {
236 "capture",
237 0,
238 {
239 {
240 "skia/gr_text_blob_cache",
241 {
242 {"Other", "3.33", "KB", 1}
243 }
244 }
245 },
246 "0.00",
247 "bytes",
248 };
249
250 struct RSImageDumpInfo {
251 uint64_t size; // bytes
252 std::string type;
253 int32_t pid;
254 std::string name;
255 };
256
257 RSImageDumpInfo g_rSImageDumpInfo[] = {
258 {12441600, "pixelmap", 2230, "SCBScreenLock12"}, {331776, "pixelmap", 2230, "NONE"},
259 {331776, "pixelmap", 2230, "NONE"}, {331776, "pixelmap", 2230, "NONE"},
260 {331776, "pixelmap", 2230, "NONE"}, {147456, "pixelmap", 2230, "NONE"},
261 {82944, "pixelmap", 2230, "NONE"}, {200704, "pixelmap", 2230, "NONE"},
262 {1106000, "pixelmap", 2230, "SCBNegativeScreen3"}, {147456, "pixelmap", 2230, "NONE"},
263 {147456, "pixelmap", 2230, "NONE"}, {147456, "pixelmap", 2230, "NONE"},
264 {147456, "pixelmap", 2230, "NONE"}, {173056, "pixelmap", 25177, "music0"},
265 {3349548, "skimage", 2230, "NONE"}, {186624, "pixelmap", 2230, "NONE"},
266 {147456, "pixelmap", 2230, "NONE"}, {518400, "pixelmap", 2230, "NONE"},
267 {331776, "pixelmap", 2230, "NONE"}, {331776, "pixelmap", 2230, "NONE"},
268 {331776, "pixelmap", 2230, "NONE"}, {331776, "pixelmap", 2230, "NONE"},
269 {19600, "pixelmap", 3485, "ArkTSCardNode"}, {147456, "pixelmap", 2230, "NONE"},
270 {331776, "pixelmap", 2230, "NONE"}, {331776, "pixelmap", 2230, "NONE"},
271 {254016, "pixelmap", 2230, "NONE"}, {331776, "pixelmap", 2230, "NONE"},
272 {147456, "pixelmap", 2230, "NONE"}, {147456, "pixelmap", 2230, "NONE"},
273 {331776, "pixelmap", 2230, "NONE"}, {331776, "pixelmap", 2230, "NONE"},
274 {331776, "pixelmap", 2230, "NONE"}, {331776, "pixelmap", 2230, "NONE"},
275 {147456, "pixelmap", 2230, "NONE"}, {589824, "pixelmap", 3485, "ArkTSCardNode"},
276 {147456, "pixelmap", 2230, "NONE"}, {331776, "pixelmap", 2230, "NONE"},
277 {1788696, "skimage", 2230, "SCBNegativeScreen3"}, {147456, "pixelmap", 2230, "NONE"},
278 {929600, "pixelmap", 3485, "ArkTSCardNode"}, {12441600, "pixelmap", 2230, "SCBWallpaper1"},
279 {331776, "pixelmap", 2230, "NONE"}, {147456, "pixelmap", 2230, "NONE"},
280 {147456, "pixelmap", 2230, "NONE"}, {147456, "pixelmap", 2230, "NONE"},
281 {160000, "pixelmap", 0, "NONE"}, {147456, "pixelmap", 2230, "NONE"},
282 {331776, "pixelmap", 2230, "NONE"}, {65536, "pixelmap", 2230, "NONE"},
283 {147456, "pixelmap", 2230, "NONE"}, {331776, "pixelmap", 2230, "NONE"},
284 {331776, "pixelmap", 2230, "NONE"}, {331776, "pixelmap", 2230, "NONE"},
285 {147456, "pixelmap", 2230, "NONE"}, {147456, "pixelmap", 2230, "NONE"},
286 {331776, "pixelmap", 2230, "NONE"}, {262144, "pixelmap", 2230, "NONE"},
287 {147456, "pixelmap", 2230, "NONE"}, {147456, "pixelmap", 2230, "NONE"},
288 {147456, "pixelmap", 2230, "NONE"}, {3538944, "pixelmap", 25111, "NONE"},
289 {331776, "pixelmap", 2230, "NONE"}, {147456, "pixelmap", 2230, "NONE"},
290 {331776, "pixelmap", 2230, "NONE"}, {147456, "pixelmap", 2230, "NONE"}
291 };
292
293 struct WinMgrSvcInfo {
294 std::string name;
295 int32_t pid;
296 };
297
298 WinMgrSvcInfo g_winMgrSvcInfo[] = {
299 {"SCBWallpaper1", 2230}, {"SCBDesktop2", 2230}, {"SCBStatusBar7", 2230}, {"SCBGestureBack10", 2230},
300 {"SCBScreenLock12", 2230}, {"SCBNegativeScreen3", 2230}, {"SCBGlobalSearch4", 2230}, {"BlurComponent5", 2230},
301 {"SCBBannerNotificatio", 2230}, {"SCBDropdownPanel8", 2230}, {"SCBVolumePanel9", 2230},
302 {"SCBSysDialogDefault1", 2230}, {"SCBSysDialogUpper13", 2230}, {"imeWindow", 3109}, {"hmscore0", 24704},
303 {"himovie0", 24901}, {"music0", 25177}
304 };
305
306 struct ProfileInfo {
307 std::string channel;
308 uint64_t size;
309 };
310
311 ProfileInfo g_profileInfo[] = {
312 {"Unnamed", 630784}, {"Default Heap", 13281584}, {"Framepool", 0}, {"Frame Internal", 0}, {"GPU Program", 368640},
313 {"EGL Color Plane", 0}, {"GLES Vertex Array Object", 0}, {"Image Descriptor", 3360}, {"Texture", 80546816},
314 {"Buffer", 273814}, {"CRC Buffer", 538960}, {"CPOM Host Memory", 4404512}, {"CPOM Render State", 0},
315 {"CPOM Compute Shader", 0}, {"CPOM Static Data", 0}, {"CFRAME Host Memory", 0}, {"CFRAME Sample Position", 0},
316 {"CFRAME Discardable FBD", 0}, {"CFRAME Tessellation/Geometry", 0}, {"COBJ Host Memory", 782360},
317 {"CMAR Host Memory", 52932608}, {"CMAR Profiling/Dumping", 0}, {"CBLEND Host Memory", 0},
318 {"GLES Host Memory", 12828704}, {"GLES Query/XFB/Unroll", 0}, {"GLES Multiview", 0}, {"CDEPS Host Memory", 720896},
319 {"CMEM Sub-allocators", 30341768}, {"CMEM Hoard", 2897728}, {"CMEM Registry", 0}, {"CL Command Payloads", 0},
320 {"CL Workgroup/Thread", 0}, {"CL Host Memory", 0}, {"CL Shared Virtual Memory", 0}, {"CINSTR Memory", 0},
321 {"GFX Device Memory CPU Uncached", 0}, {"GFX Device Memory CPU Cached", 0}, {"GFX Device Memory Transient", 0},
322 {"GFX Device Memory Protected", 0}, {"GFX Device External Memory", 0}, {"GFX Device External Swapchain Memory", 0},
323 {"GFX Device Internal Memory", 3678208}, {"GFX Device Internal Host Memory", 22879792},
324 {"GFX Device Internal Protected Memory", 0}, {"GFX Descriptor Pool Memory", 0}, {"GFX Command Allocator Memory", 0},
325 {"GFX Command Allocator Host Memory", 0}, {"GFX Command Allocator Protected Memory", 0},
326 {"Vulkan Bound Buffer Memory", 0}, {"Vulkan Bound Image Memory", 0}, {"CMAR Signal Memory", 8192},
327 {"CMAR Flush Chain Memory", 0}, {"CMAR Metadata List Memory", 8192}
328 };
329
330 std::string GetFullPath(std::string path);
331
332 class MemoryDataPluginTest : public ::testing::Test {
333 public:
334 static void SetUpTestCase();
335
TearDownTestCase()336 static void TearDownTestCase() {}
SetUp()337 void SetUp() {}
TearDown()338 void TearDown() {}
339 };
340
Getexepath()341 string Getexepath()
342 {
343 char buf[PATH_MAX] = "";
344 std::string path = "/proc/self/exe";
345 size_t rslt = readlink(path.c_str(), buf, sizeof(buf));
346 if (rslt < 0 || (rslt >= sizeof(buf))) {
347 return "";
348 }
349 buf[rslt] = '\0';
350 for (int i = rslt; i >= 0; i--) {
351 if (buf[i] == '/') {
352 buf[i + 1] = '\0';
353 break;
354 }
355 }
356 return buf;
357 }
358
GetPid(const std::string processName)359 int GetPid(const std::string processName)
360 {
361 int pid = -1;
362 std::string findpid = "pidof " + processName;
363 PROFILER_LOG_INFO(LOG_CORE, "find pid command : %s", findpid.c_str());
364 std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(findpid.c_str(), "r"), pclose);
365
366 char line[LINE_SIZE];
367 do {
368 if (fgets(line, sizeof(line), pipe.get()) == nullptr) {
369 PROFILER_LOG_INFO(LOG_CORE, "not find processName : %s", processName.c_str());
370 return pid;
371 } else if (strlen(line) > 0 && isdigit(static_cast<unsigned char>(line[0]))) {
372 pid = atoi(line);
373 PROFILER_LOG_INFO(LOG_CORE, "find processName : %s, pid: %d", processName.c_str(), pid);
374 break;
375 }
376 } while (1);
377
378 return pid;
379 }
380
SetPluginProcessConfig(std::vector<int> processList,MemoryConfig & protoConfig)381 void SetPluginProcessConfig(std::vector<int> processList, MemoryConfig& protoConfig)
382 {
383 if (processList.size() != 0) {
384 // 具体进程
385 protoConfig.set_report_process_mem_info(true);
386 protoConfig.set_report_app_mem_info(true);
387 for (size_t i = 0; i < processList.size(); i++) {
388 protoConfig.add_pid(processList.at(i));
389 }
390 } else {
391 // 进程树
392 protoConfig.set_report_process_tree(true);
393 }
394 }
395
SetPluginSysMemConfig(MemoryConfig & protoConfig)396 void SetPluginSysMemConfig(MemoryConfig &protoConfig)
397 {
398 protoConfig.set_report_sysmem_mem_info(true);
399
400 protoConfig.add_sys_meminfo_counters(SysMeminfoType::PMEM_MEM_TOTAL);
401 protoConfig.add_sys_meminfo_counters(SysMeminfoType::PMEM_MEM_FREE);
402 protoConfig.add_sys_meminfo_counters(SysMeminfoType::PMEM_MEM_AVAILABLE);
403 protoConfig.add_sys_meminfo_counters(SysMeminfoType::PMEM_BUFFERS);
404 protoConfig.add_sys_meminfo_counters(SysMeminfoType::PMEM_CACHED);
405 protoConfig.add_sys_meminfo_counters(SysMeminfoType::PMEM_SWAP_CACHED);
406 protoConfig.add_sys_meminfo_counters(SysMeminfoType::PMEM_ACTIVE);
407 protoConfig.add_sys_meminfo_counters(SysMeminfoType::PMEM_INACTIVE);
408
409 protoConfig.add_sys_meminfo_counters(SysMeminfoType::PMEM_ACTIVE_ANON);
410 protoConfig.add_sys_meminfo_counters(SysMeminfoType::PMEM_INACTIVE_ANON);
411 protoConfig.add_sys_meminfo_counters(SysMeminfoType::PMEM_INACTIVE_FILE);
412 protoConfig.add_sys_meminfo_counters(SysMeminfoType::PMEM_UNEVICTABLE);
413 protoConfig.add_sys_meminfo_counters(SysMeminfoType::PMEM_MLOCKED);
414 protoConfig.add_sys_meminfo_counters(SysMeminfoType::PMEM_SWAP_TOTAL);
415 protoConfig.add_sys_meminfo_counters(SysMeminfoType::PMEM_SWAP_FREE);
416 protoConfig.add_sys_meminfo_counters(SysMeminfoType::PMEM_DIRTY);
417 protoConfig.add_sys_meminfo_counters(SysMeminfoType::PMEM_ACTIVE_PURG);
418 protoConfig.add_sys_meminfo_counters(SysMeminfoType::PMEM_INACTIVE_PURG);
419 protoConfig.add_sys_meminfo_counters(SysMeminfoType::PMEM_PINED_PURG);
420
421 protoConfig.set_report_sysmem_vmem_info(true);
422
423 protoConfig.add_sys_vmeminfo_counters(SysVMeminfoType::VMEMINFO_NR_FREE_PAGES);
424 protoConfig.add_sys_vmeminfo_counters(SysVMeminfoType::VMEMINFO_NR_INACTIVE_ANON);
425 protoConfig.add_sys_vmeminfo_counters(SysVMeminfoType::VMEMINFO_NR_ACTIVE_ANON);
426 protoConfig.add_sys_vmeminfo_counters(SysVMeminfoType::VMEMINFO_NR_INACTIVE_FILE);
427
428 protoConfig.add_sys_vmeminfo_counters(SysVMeminfoType::VMEMINFO_NR_ACTIVE_FILE);
429 protoConfig.add_sys_vmeminfo_counters(SysVMeminfoType::VMEMINFO_NR_UNEVICTABLE);
430 protoConfig.add_sys_vmeminfo_counters(SysVMeminfoType::VMEMINFO_NR_MLOCK);
431 protoConfig.add_sys_vmeminfo_counters(SysVMeminfoType::VMEMINFO_NR_ANON_PAGES);
432
433 protoConfig.add_sys_vmeminfo_counters(SysVMeminfoType::VMEMINFO_NR_MAPPED);
434 protoConfig.add_sys_vmeminfo_counters(SysVMeminfoType::VMEMINFO_NR_FILE_PAGES);
435 protoConfig.add_sys_vmeminfo_counters(SysVMeminfoType::VMEMINFO_NR_DIRTY);
436 protoConfig.add_sys_vmeminfo_counters(SysVMeminfoType::VMEMINFO_NR_SLAB_RECLAIMABLE);
437
438 protoConfig.add_sys_vmeminfo_counters(SysVMeminfoType::VMEMINFO_NR_SLAB_UNRECLAIMABLE);
439 protoConfig.add_sys_vmeminfo_counters(SysVMeminfoType::VMEMINFO_NR_PAGE_TABLE_PAGES);
440 protoConfig.add_sys_vmeminfo_counters(SysVMeminfoType::VMEMINFO_NR_KERNEL_STACK);
441 protoConfig.add_sys_vmeminfo_counters(SysVMeminfoType::VMEMINFO_NR_UNSTABLE);
442 }
443
SetPluginMemoryServiceConfig(MemoryConfig & protoConfig)444 void SetPluginMemoryServiceConfig(MemoryConfig& protoConfig)
445 {
446 protoConfig.set_report_process_mem_info(true);
447 protoConfig.set_report_app_mem_info(true);
448 protoConfig.add_pid(1);
449 protoConfig.set_report_app_mem_by_memory_service(true);
450 }
451
PluginStub(MemoryDataPlugin & memoryPlugin,MemoryConfig & protoConfig,MemoryData & memoryData)452 bool PluginStub(MemoryDataPlugin& memoryPlugin, MemoryConfig& protoConfig, MemoryData& memoryData)
453 {
454 // serialize
455 int configSize = protoConfig.ByteSizeLong();
456 std::vector<uint8_t> configData(configSize);
457 int ret = protoConfig.SerializeToArray(configData.data(), configData.size());
458 CHECK_TRUE(ret > 0, false, "PluginStub::SerializeToArray fail!!!");
459
460 // start
461 ret = memoryPlugin.Start(configData.data(), configData.size());
462 CHECK_TRUE(ret == 0, false, "PluginStub::start plugin fail!!!");
463
464 // report
465 std::vector<uint8_t> bufferData(BUF_SIZE);
466 ret = memoryPlugin.Report(bufferData.data(), bufferData.size());
467 if (ret >= 0) {
468 memoryData.ParseFromArray(bufferData.data(), ret);
469 return true;
470 }
471
472 return false;
473 }
474
GetFullPath(std::string path)475 std::string GetFullPath(std::string path)
476 {
477 if (path.size() > 0 && path[0] != '/') {
478 return Getexepath() + path;
479 }
480 return path;
481 }
482
SetUpTestCase()483 void MemoryDataPluginTest::SetUpTestCase()
484 {
485 g_path = GetFullPath(DEFAULT_TEST_PATH);
486 EXPECT_NE("", g_path);
487 g_path += "utresources/proc";
488 }
489
490 /**
491 * @tc.name: memory plugin
492 * @tc.desc: Test whether the path exists.
493 * @tc.type: FUNC
494 */
495 HWTEST_F(MemoryDataPluginTest, TestUtpath, TestSize.Level1)
496 {
497 EXPECT_NE(g_path, "");
498 }
499
500 /**
501 * @tc.name: memory plugin
502 * @tc.desc: Pid list test in a specific directory.
503 * @tc.type: FUNC
504 */
505 HWTEST_F(MemoryDataPluginTest, Testpidlist, TestSize.Level1)
506 {
507 MemoryDataPlugin* memoryPlugin = new MemoryDataPlugin();
508 const std::vector<int> expectPidList = {1, 2, 11};
509
510 DIR* dir = memoryPlugin->OpenDestDir(g_path.c_str());
511 EXPECT_NE(nullptr, dir);
512
513 std::vector<int> cmpPidList;
514 while (int32_t pid = memoryPlugin->GetValidPid(dir)) {
515 cmpPidList.push_back(pid);
516 }
517 sort(cmpPidList.begin(), cmpPidList.end());
518 closedir(dir);
519 EXPECT_EQ(cmpPidList, expectPidList);
520 delete memoryPlugin;
521 }
522
523 /**
524 * @tc.name: memory plugin
525 * @tc.desc: Mem information test for specific pid.
526 * @tc.type: FUNC
527 */
528 HWTEST_F(MemoryDataPluginTest, Testpluginformeminfo, TestSize.Level1)
529 {
530 MemoryDataPlugin memoryPlugin;
531 MemoryData memoryData;
532 MemoryConfig protoConfig;
533
534 memoryPlugin.SetPath(const_cast<char*>(g_path.c_str()));
535 SetPluginSysMemConfig(protoConfig);
536 EXPECT_TRUE(PluginStub(memoryPlugin, protoConfig, memoryData));
537
538 EXPECT_EQ(19, memoryData.meminfo().size());
539 int index = memoryData.meminfo_size();
540 for (int i = 0; i < index; ++i) {
541 EXPECT_EQ(g_meminfo[i], memoryData.meminfo(i).value());
542 }
543
544 EXPECT_EQ(16, memoryData.vmeminfo().size());
545 index = memoryData.vmeminfo_size();
546 for (int i = 0; i < index; ++i) {
547 EXPECT_EQ(g_vmeminfo[i], memoryData.vmeminfo(i).value());
548 }
549 memoryPlugin.Stop();
550 }
551
552 /**
553 * @tc.name: memory plugin
554 * @tc.desc: pid list information test for process tree.
555 * @tc.type: FUNC
556 */
557 HWTEST_F(MemoryDataPluginTest, Testpluginforlist, TestSize.Level1)
558 {
559 MemoryDataPlugin memoryPlugin;
560 MemoryData memoryData;
561 MemoryConfig protoConfig;
562
563 std::vector<int> cmpPidList;
564 EXPECT_EQ((size_t)0, cmpPidList.size());
565
566 memoryPlugin.SetPath(const_cast<char*>(g_path.c_str()));
567
568 SetPluginProcessConfig(cmpPidList, protoConfig);
569 EXPECT_TRUE(PluginStub(memoryPlugin, protoConfig, memoryData));
570
571 int index = memoryData.processesinfo_size();
572 EXPECT_EQ(3, index);
573 for (int i = 0; i < index; ++i) {
574 ProcessMemoryInfo it = memoryData.processesinfo(i);
575 EXPECT_EQ(g_pidtarget[i].pid, it.pid());
576 EXPECT_EQ(g_pidtarget[i].name, it.name());
577 EXPECT_EQ(g_pidtarget[i].vm_size_kb, it.vm_size_kb());
578 EXPECT_EQ(g_pidtarget[i].vm_rss_kb, it.vm_rss_kb());
579 EXPECT_EQ(g_pidtarget[i].rss_anon_kb, it.rss_anon_kb());
580 EXPECT_EQ(g_pidtarget[i].rss_file_kb, it.rss_file_kb());
581 EXPECT_EQ(g_pidtarget[i].rss_shmem_kb, it.rss_shmem_kb());
582 EXPECT_EQ(g_pidtarget[i].vm_locked_kb, it.vm_locked_kb());
583 EXPECT_EQ(g_pidtarget[i].vm_hwm_kb, it.vm_hwm_kb());
584 EXPECT_EQ(g_pidtarget[i].purg_sum_kb, it.purg_sum_kb());
585 EXPECT_EQ(g_pidtarget[i].purg_pin_kb, it.purg_pin_kb());
586
587 EXPECT_EQ(g_pidtarget[i].oom_score_adj, it.oom_score_adj());
588
589 EXPECT_FALSE(it.has_memsummary());
590 }
591
592 memoryPlugin.Stop();
593 }
594
595 /**
596 * @tc.name: memory plugin
597 * @tc.desc: pid list information test for specific pid.
598 * @tc.type: FUNC
599 */
600 HWTEST_F(MemoryDataPluginTest, Testpluginforsinglepid, TestSize.Level1)
601 {
602 MemoryDataPlugin memoryPlugin;
603 MemoryData memoryData;
604 MemoryConfig protoConfig;
605
606 std::vector<int> pid = {5};
607 TestElement singlepid = {};
608
609 memoryPlugin.SetPath(const_cast<char*>(g_path.c_str()));
610
611 SetPluginProcessConfig(pid, protoConfig);
612 EXPECT_TRUE(PluginStub(memoryPlugin, protoConfig, memoryData));
613
614 int index = memoryData.processesinfo_size();
615 EXPECT_EQ(2, index); // 2: the size of processinfo
616
617 ProcessMemoryInfo it = memoryData.processesinfo(0);
618 EXPECT_EQ(singlepid.pid, it.pid());
619 EXPECT_EQ(singlepid.name, it.name());
620 EXPECT_EQ(singlepid.vm_size_kb, it.vm_size_kb());
621 EXPECT_EQ(singlepid.vm_rss_kb, it.vm_rss_kb());
622 EXPECT_EQ(singlepid.rss_anon_kb, it.rss_anon_kb());
623 EXPECT_EQ(singlepid.rss_file_kb, it.rss_file_kb());
624 EXPECT_EQ(singlepid.rss_shmem_kb, it.rss_shmem_kb());
625 EXPECT_EQ(singlepid.vm_locked_kb, it.vm_locked_kb());
626 EXPECT_EQ(singlepid.vm_hwm_kb, it.vm_hwm_kb());
627 EXPECT_EQ(singlepid.purg_sum_kb, it.purg_sum_kb());
628 EXPECT_EQ(singlepid.purg_pin_kb, it.purg_pin_kb());
629
630 EXPECT_EQ(singlepid.oom_score_adj, it.oom_score_adj());
631
632 EXPECT_TRUE(it.has_memsummary());
633 AppSummary app = it.memsummary();
634 EXPECT_EQ(singlepid.java_heap, app.java_heap());
635 EXPECT_EQ(singlepid.native_heap, app.native_heap());
636 EXPECT_EQ(singlepid.code, app.code());
637 EXPECT_EQ(singlepid.stack, app.stack());
638 EXPECT_EQ(singlepid.graphics, app.graphics());
639
640 memoryPlugin.Stop();
641 }
642
643 /**
644 * @tc.name: memory plugin
645 * @tc.desc: pid list information test for specific pids.
646 * @tc.type: FUNC
647 */
648 HWTEST_F(MemoryDataPluginTest, Testpluginforpids, TestSize.Level1)
649 {
650 MemoryDataPlugin memoryPlugin;
651 MemoryData memoryData;
652 MemoryConfig protoConfig;
653
654 std::vector<int> cmpPidList = {1, 2, 11};
655 EXPECT_NE((size_t)0, cmpPidList.size());
656
657 memoryPlugin.SetPath(const_cast<char*>(g_path.c_str()));
658
659 SetPluginProcessConfig(cmpPidList, protoConfig);
660 EXPECT_TRUE(PluginStub(memoryPlugin, protoConfig, memoryData));
661
662 int index = memoryData.processesinfo_size();
663 EXPECT_EQ(6, index); // 3: the size of processinfo
664 for (int i = 0; i < 3; ++i) {
665 ProcessMemoryInfo it = memoryData.processesinfo(i);
666 EXPECT_EQ(g_pidtarget[i].pid, it.pid());
667 EXPECT_EQ(g_pidtarget[i].name, it.name());
668 EXPECT_EQ(g_pidtarget[i].vm_size_kb, it.vm_size_kb());
669 EXPECT_EQ(g_pidtarget[i].vm_rss_kb, it.vm_rss_kb());
670 EXPECT_EQ(g_pidtarget[i].rss_anon_kb, it.rss_anon_kb());
671 EXPECT_EQ(g_pidtarget[i].rss_file_kb, it.rss_file_kb());
672 EXPECT_EQ(g_pidtarget[i].rss_shmem_kb, it.rss_shmem_kb());
673 EXPECT_EQ(g_pidtarget[i].vm_locked_kb, it.vm_locked_kb());
674 EXPECT_EQ(g_pidtarget[i].vm_hwm_kb, it.vm_hwm_kb());
675 EXPECT_EQ(g_pidtarget[i].purg_sum_kb, it.purg_sum_kb());
676 EXPECT_EQ(g_pidtarget[i].purg_pin_kb, it.purg_pin_kb());
677
678 EXPECT_EQ(g_pidtarget[i].oom_score_adj, it.oom_score_adj());
679
680 if (i == 0) {
681 EXPECT_TRUE(it.has_memsummary());
682 }
683 }
684
685 memoryPlugin.Stop();
686 }
687
688 /**
689 * @tc.name: memory plugin
690 * @tc.desc: Smaps stats info test for specific pids.
691 * @tc.type: FUNC
692 */
693 HWTEST_F(MemoryDataPluginTest, TestSmapsStatsInfo, TestSize.Level1)
694 {
695 const std::vector<int> expectPidList = {1, 2, 11};
696
697 SmapsStats smap(std::string(g_path + "/"));
698 for (size_t i = 0; i < expectPidList.size(); i++) {
699 ProcessMemoryInfo processMemoryInfo;
700 SmapsInfo* smapsInfo = nullptr;
701 EXPECT_TRUE(smap.ParseMaps(expectPidList[i], processMemoryInfo, smapsInfo, true, false, false));
702 EXPECT_EQ(g_pidtarget[i].java_heap, (uint64_t)(smap.GetProcessJavaHeap()));
703 EXPECT_EQ(g_pidtarget[i].native_heap, (uint64_t)(smap.GetProcessNativeHeap()));
704 EXPECT_EQ(g_pidtarget[i].code, (uint64_t)(smap.GetProcessCode()));
705 EXPECT_EQ(g_pidtarget[i].stack, (uint64_t)(smap.GetProcessStack()));
706 EXPECT_EQ(g_pidtarget[i].graphics, (uint64_t)(smap.GetProcessGraphics()));
707 EXPECT_EQ(g_pidtarget[i].private_other, (uint64_t)(smap.GetProcessPrivateOther()));
708 }
709 }
710
711 /**
712 * @tc.name: memory plugin
713 * @tc.desc: Vmstat info test for specific pids.
714 * @tc.type: FUNC
715 */
716 HWTEST_F(MemoryDataPluginTest, TestpluginWriteVmstat, TestSize.Level1)
717 {
718 MemoryDataPlugin memoryPlugin;
719 MemoryData memoryData;
720 MemoryConfig protoConfig;
721
722 protoConfig.set_report_sysmem_vmem_info(true);
723 EXPECT_TRUE(PluginStub(memoryPlugin, protoConfig, memoryData));
724
725 memoryPlugin.Stop();
726 }
727
728 /**
729 * @tc.name: memory plugin
730 * @tc.desc: Get information through MemoryService.
731 * @tc.type: FUNC
732 */
733 HWTEST_F(MemoryDataPluginTest, TestpluginMemoryService, TestSize.Level1)
734 {
735 MemoryDataPlugin memoryPlugin;
736 MemoryData memoryData;
737 MemoryConfig protoConfig;
738
739 SetPluginMemoryServiceConfig(protoConfig);
740 EXPECT_TRUE(PluginStub(memoryPlugin, protoConfig, memoryData));
741 std::string line = "01234567890";
742 memoryPlugin.ParseNumber(line);
743
744 ProcessMemoryInfo it = memoryData.processesinfo(0);
745 EXPECT_FALSE(it.has_memsummary());
746 AppSummary app = it.memsummary();
747 EXPECT_EQ((uint64_t)0, app.java_heap());
748 EXPECT_EQ((uint64_t)0, app.native_heap());
749 EXPECT_EQ((uint64_t)0, app.code());
750 EXPECT_EQ((uint64_t)0, app.stack());
751 EXPECT_EQ((uint64_t)0, app.graphics());
752 EXPECT_EQ((uint64_t)0, app.private_other());
753
754 memoryPlugin.Stop();
755 }
756
WriteFunc(WriterStruct * writer,const void * data,size_t size)757 long WriteFunc(WriterStruct* writer, const void* data, size_t size)
758 {
759 if (writer == nullptr || data == nullptr || size <= 0) {
760 return -1;
761 }
762 return 0;
763 }
764
FlushFunc(WriterStruct * writer)765 bool FlushFunc(WriterStruct* writer)
766 {
767 if (writer == nullptr) {
768 return false;
769 }
770 return true;
771 }
772
773 /**
774 * @tc.name: mem plugin
775 * @tc.desc: test register
776 * @tc.type: FUNC
777 */
778 HWTEST_F(MemoryDataPluginTest, TestRegister, TestSize.Level1)
779 {
780 std::string path = std::string("libmemdataplugin.z.so");
781 void* handle = dlopen(path.c_str(), RTLD_LAZY);
782 EXPECT_NE(handle, nullptr);
783 PluginModuleStruct* plugin = reinterpret_cast<PluginModuleStruct*>(dlsym(handle, "g_pluginModule"));
784 EXPECT_NE(plugin, nullptr);
785 EXPECT_STREQ(plugin->name, "memory-plugin");
786
787 // set config
788 MemoryConfig config;
789 config.set_report_process_mem_info(true);
790 int size = config.ByteSizeLong();
791 ASSERT_GT(size, 0);
792 std::vector<uint8_t> configData(size);
793 ASSERT_GT(config.SerializeToArray(configData.data(), configData.size()), 0);
794
795 // test framework process
796 WriterStruct writer = {WriteFunc, FlushFunc};
797 std::vector<uint8_t> dataBuffer(plugin->resultBufferSizeHint);
798 EXPECT_EQ(plugin->callbacks->onRegisterWriterStruct(&writer), 0);
799 }
800
801 /**
802 * @tc.name: mem plugin
803 * @tc.desc: start fail test
804 * @tc.type: FUNC
805 */
806 HWTEST_F(MemoryDataPluginTest, TestStartFail, TestSize.Level1)
807 {
808 MemoryConfig config;
809 MemoryDataPlugin plugin;
810
811 // set config
812 config.set_report_process_mem_info(true);
813
814 // serialize
815 int size = config.ByteSizeLong();
816 ASSERT_GT(size, 0);
817 std::vector<uint8_t> configData(size);
818 ASSERT_GT(config.SerializeToArray(configData.data(), configData.size()), 0);
819
820 // start
821 EXPECT_NE(plugin.Start(configData.data(), size - 1), 0);
822 }
823
824 /**
825 * @tc.name: mem plugin
826 * @tc.desc: Framework test
827 * @tc.type: FUNC
828 */
829 HWTEST_F(MemoryDataPluginTest, TestFramework, TestSize.Level1)
830 {
831 std::string path = std::string("libmemdataplugin.z.so");
832 void* handle = dlopen(path.c_str(), RTLD_LAZY);
833 EXPECT_NE(handle, nullptr);
834 PluginModuleStruct* plugin = reinterpret_cast<PluginModuleStruct*>(dlsym(handle, "g_pluginModule"));
835 EXPECT_NE(plugin, nullptr);
836 EXPECT_STREQ(plugin->name, "memory-plugin");
837
838 // set config
839 MemoryConfig config;
840 config.set_report_process_mem_info(true);
841 int size = config.ByteSizeLong();
842 ASSERT_GT(size, 0);
843 std::vector<uint8_t> configData(size);
844 ASSERT_GT(config.SerializeToArray(configData.data(), configData.size()), 0);
845
846 // test framework process
847 std::vector<uint8_t> dataBuffer(plugin->resultBufferSizeHint);
848 EXPECT_EQ(plugin->callbacks->onPluginSessionStart(configData.data(), configData.size()), 0);
849 EXPECT_EQ(plugin->callbacks->onPluginReportResult(dataBuffer.data(), dataBuffer.size()), 0);
850 EXPECT_EQ(plugin->callbacks->onPluginSessionStop(), 0);
851 }
852
OutputData(uint8_t * data,uint32_t size)853 void OutputData(uint8_t* data, uint32_t size)
854 {
855 MemoryData memoryData;
856 int ret = memoryData.ParseFromArray(data, size);
857 if (ret <= 0) {
858 PROFILER_LOG_ERROR(LOG_CORE, "MemoryDataPluginTest, %s:parseFromArray failed!", __func__);
859 return;
860 }
861
862 return;
863 }
864
865 /**
866 * @tc.name: mem plugin
867 * @tc.desc: ProcessTree test
868 * @tc.type: FUNC
869 */
870 HWTEST_F(MemoryDataPluginTest, TestProcessTreeRunTime, TestSize.Level1)
871 {
872 std::string path = std::string("libmemdataplugin.z.so");
873 void* handle = dlopen(path.c_str(), RTLD_LAZY);
874 EXPECT_NE(handle, nullptr);
875 PluginModuleStruct* plugin = reinterpret_cast<PluginModuleStruct*>(dlsym(handle, "g_pluginModule"));
876 EXPECT_NE(plugin, nullptr);
877 EXPECT_STREQ(plugin->name, "memory-plugin");
878
879 // set config
880 MemoryConfig config;
881 config.set_report_process_tree(true);
882 int size = config.ByteSizeLong();
883 ASSERT_GT(size, 0);
884 std::vector<uint8_t> configData(size);
885 ASSERT_GT(config.SerializeToArray(configData.data(), configData.size()), 0);
886
887 // test framework process
888 int testCount = 10;
889 struct timeval start, end;
890 std::vector<uint8_t> dataBuffer(plugin->resultBufferSizeHint);
891 EXPECT_EQ(plugin->callbacks->onPluginSessionStart(configData.data(), configData.size()), 0);
892 clock_t clockstart = clock();
893 gettimeofday(&start, nullptr);
894 while (testCount--) {
895 int ret = plugin->callbacks->onPluginReportResult(dataBuffer.data(), dataBuffer.size());
896 ASSERT_GT(ret, 0);
897 OutputData(dataBuffer.data(), (uint32_t)ret);
898 }
899 gettimeofday(&end, nullptr);
900 clock_t clockend = clock();
901 int timeuse = US_PER_S * (end.tv_sec - start.tv_sec) + end.tv_usec - start.tv_usec;
902 PROFILER_LOG_INFO(LOG_CORE, "clock time=%.3fs, timeofday=%.3fs", (double)(clockend - clockstart) / CLOCKS_PER_SEC,
903 (double)timeuse / US_PER_S);
904 EXPECT_EQ(plugin->callbacks->onPluginSessionStop(), 0);
905 }
906
907 namespace {
908 const char* DUMP_FORMAT = R"(Applications Memory Usage (in Kilobytes):
909 Uptime: 559174 Realtime: 559174
910 App Summary
911 Pss(KB)
912 ------
913 Java Heap: 0
914 Native Heap: 2932
915 Code: 640
916 Stack: 60
917 Graphics: 0
918 Private Other: 1056
919 System: 1092
920 TOTAL: 5780 TOTAL SWAP (KB): 0)";
921 }
922
923 /**
924 * @tc.name: mem plugin
925 * @tc.desc: test ParseMemInfo
926 * @tc.type: FUNC
927 */
928 HWTEST_F(MemoryDataPluginTest, TestParseMemInfo, TestSize.Level1)
929 {
930 MemoryDataPlugin plugin;
931 ProcessMemoryInfo memoryInfo;
932 uint64_t javaHeap = 0;
933 uint64_t nativeHeap = 2932;
934 uint64_t code = 640;
935 uint64_t stack = 60;
936 uint64_t graphics = 0;
937 uint64_t other = 1056;
938 uint64_t system = 1092;
939
940 ASSERT_TRUE(plugin.ParseMemInfo(DUMP_FORMAT, memoryInfo));
941 // test result
942 EXPECT_EQ(memoryInfo.mutable_memsummary()->java_heap(), javaHeap);
943 EXPECT_EQ(memoryInfo.mutable_memsummary()->native_heap(), nativeHeap);
944 EXPECT_EQ(memoryInfo.mutable_memsummary()->code(), code);
945 EXPECT_EQ(memoryInfo.mutable_memsummary()->stack(), stack);
946 EXPECT_EQ(memoryInfo.mutable_memsummary()->graphics(), graphics);
947 EXPECT_EQ(memoryInfo.mutable_memsummary()->private_other(), other);
948 EXPECT_EQ(memoryInfo.mutable_memsummary()->system(), system);
949 }
950
ExecuteBin(const std::string & bin,const std::vector<std::string> & args)951 bool ExecuteBin(const std::string& bin, const std::vector<std::string>& args)
952 {
953 std::vector<char*> argv;
954 for (size_t i = 0; i < args.size(); i++) {
955 argv.push_back(const_cast<char*>(args[i].c_str()));
956 }
957 argv.push_back(nullptr); // last item in argv must be NULL
958
959 int retval = execvp(bin.c_str(), argv.data());
960 CHECK_TRUE(retval != -1, false, "execv %s failed, %d!", bin.c_str(), errno);
961 _exit(EXIT_FAILURE);
962 abort(); // never should be here.
963 return true;
964 }
965
966 /**
967 * @tc.name: mem plugin
968 * @tc.desc: test ParseMemInfo
969 * @tc.type: FUNC
970 */
971 HWTEST_F(MemoryDataPluginTest, TestPid, TestSize.Level1)
972 {
973 MemoryDataPlugin plugin;
974 MemoryData memoryData;
975 MemoryConfig config;
976
977 std::string cmd = "chmod 777 " + DEFAULT_BIN_PATH;
978 system(cmd.c_str());
979 pid_t pid1 = fork();
980 if (pid1 == 0) {
981 std::vector<std::string> argv = {"childpidtest1", "10"};
982 ASSERT_TRUE(ExecuteBin(DEFAULT_BIN_PATH, argv));
983 }
984 pid_t pid2 = fork();
985 if (pid2 == 0) {
986 std::vector<std::string> argv = {"childpidtest2", "1"};
987 ASSERT_TRUE(ExecuteBin(DEFAULT_BIN_PATH, argv));
988 }
989 sleep(1);
990
991 // set config
992 config.set_report_process_mem_info(true);
993 config.set_report_app_mem_info(true);
994 config.add_pid(pid1);
995 config.add_pid(pid2);
996 // check result
997 EXPECT_TRUE(PluginStub(plugin, config, memoryData));
998 EXPECT_GT(memoryData.processesinfo(0).vm_size_kb(), memoryData.processesinfo(1).vm_size_kb());
999
1000 while (waitpid(-1, nullptr, WNOHANG) == 0) {
1001 kill(pid1, SIGKILL);
1002 kill(pid2, SIGKILL);
1003 }
1004 plugin.Stop();
1005 }
1006
1007 /**
1008 * @tc.name: mem plugin
1009 * @tc.desc: test WriteAshmemInfo
1010 * @tc.type: FUNC
1011 */
1012 HWTEST_F(MemoryDataPluginTest, TestWriteAshmemInfo, TestSize.Level1)
1013 {
1014 MemoryDataPlugin plugin;
1015 MemoryData memoryData;
1016 plugin.SetPath(const_cast<char*>(g_path.c_str()));
1017 plugin.WriteAshmemInfo(memoryData);
1018
1019 const int size = 4;
1020 ASSERT_EQ(memoryData.ashmeminfo().size(), size);
1021 for (int i = 0; i < size; i++) {
1022 auto ashmemInfo = memoryData.ashmeminfo(i);
1023 EXPECT_STREQ(ashmemInfo.name().c_str(), g_ashMemInfo[i].name.c_str());
1024 EXPECT_EQ(ashmemInfo.pid(), g_ashMemInfo[i].pid);
1025 EXPECT_EQ(ashmemInfo.adj(), g_ashMemInfo[i].adj);
1026 EXPECT_EQ(ashmemInfo.fd(), g_ashMemInfo[i].fd);
1027 EXPECT_STREQ(ashmemInfo.ashmem_name().c_str(), g_ashMemInfo[i].ashmem_name.c_str());
1028 EXPECT_EQ(ashmemInfo.size(), g_ashMemInfo[i].size);
1029 EXPECT_EQ(ashmemInfo.id(), g_ashMemInfo[i].id);
1030 EXPECT_EQ(ashmemInfo.time(), g_ashMemInfo[i].time);
1031 EXPECT_EQ(ashmemInfo.ref_count(), g_ashMemInfo[i].ref_count);
1032 EXPECT_EQ(ashmemInfo.purged(), g_ashMemInfo[i].purged);
1033 }
1034 }
1035
1036 /**
1037 * @tc.name: mem plugin
1038 * @tc.desc: test WriteDmaInfo
1039 * @tc.type: FUNC
1040 */
1041 HWTEST_F(MemoryDataPluginTest, TestWriteDmaInfo, TestSize.Level1)
1042 {
1043 MemoryDataPlugin plugin;
1044 MemoryData memoryData;
1045 plugin.SetPath(const_cast<char*>(g_path.c_str()));
1046 plugin.WriteDmaInfo(memoryData);
1047
1048 const int size = 17;
1049 ASSERT_EQ(memoryData.dmainfo().size(), size);
1050 for (int i = 0; i < size; i++) {
1051 auto dmaInfo = memoryData.dmainfo(i);
1052 EXPECT_STREQ(dmaInfo.name().c_str(), g_dmaMemInfo[i].name.c_str());
1053 EXPECT_EQ(dmaInfo.pid(), g_dmaMemInfo[i].pid);
1054 EXPECT_EQ(dmaInfo.fd(), g_dmaMemInfo[i].fd);
1055 EXPECT_EQ(dmaInfo.size(), g_dmaMemInfo[i].size);
1056 EXPECT_EQ(dmaInfo.ino(), g_dmaMemInfo[i].ino);
1057 EXPECT_EQ(dmaInfo.exp_pid(), g_dmaMemInfo[i].expPid);
1058 EXPECT_STREQ(dmaInfo.exp_task_comm().c_str(), g_dmaMemInfo[i].exp_task_comm.c_str());
1059 EXPECT_STREQ(dmaInfo.buf_name().c_str(), g_dmaMemInfo[i].buf_name.c_str());
1060 EXPECT_STREQ(dmaInfo.exp_name().c_str(), g_dmaMemInfo[i].exp_name.c_str());
1061 }
1062 }
1063
1064 /**
1065 * @tc.name: mem plugin
1066 * @tc.desc: test WriteGpuMemInfo
1067 * @tc.type: FUNC
1068 */
1069 HWTEST_F(MemoryDataPluginTest, TestWriteGpuMemInfo, TestSize.Level1)
1070 {
1071 MemoryDataPlugin plugin;
1072 MemoryData memoryData;
1073 plugin.SetPath(const_cast<char*>(g_path.c_str()));
1074 plugin.WriteGpuMemInfo(memoryData);
1075 ASSERT_EQ(memoryData.gpumemoryinfo().size(), 1);
1076
1077 auto gpuMemoryInfo = memoryData.gpumemoryinfo(0);
1078 EXPECT_STREQ(gpuMemoryInfo.gpu_name().c_str(), g_gpuMemInfo.gpu_name.c_str());
1079 EXPECT_EQ(gpuMemoryInfo.all_gpu_size(), g_gpuMemInfo.all_gpu_size * PAGE_SIZE);
1080
1081 const int size = 3;
1082 ASSERT_EQ(gpuMemoryInfo.gpu_process_info().size(), size);
1083 for (int i = 0; i < size; i++) {
1084 auto gpuProcessInfo = gpuMemoryInfo.gpu_process_info(i);
1085 EXPECT_STREQ(gpuProcessInfo.addr().c_str(), g_gpuMemInfo.gpuInfo[i].addr.c_str());
1086 EXPECT_EQ(gpuProcessInfo.pid(), g_gpuMemInfo.gpuInfo[i].pid);
1087 EXPECT_EQ(gpuProcessInfo.tid(), g_gpuMemInfo.gpuInfo[i].tid);
1088 EXPECT_EQ(gpuProcessInfo.used_gpu_size(), g_gpuMemInfo.gpuInfo[i].used_gpu_size * PAGE_SIZE);
1089 }
1090 }
1091
1092 /**
1093 * @tc.name: mem plugin
1094 * @tc.desc: test WriteGpuDumpInfo
1095 * @tc.type: FUNC
1096 */
1097 HWTEST_F(MemoryDataPluginTest, TestWriteGpuDumpInfo, TestSize.Level1)
1098 {
1099 MemoryDataPlugin plugin;
1100 MemoryData memoryData;
1101 plugin.SetPath(const_cast<char*>(g_path.c_str()));
1102 plugin.WriteGpuDumpInfo(memoryData);
1103
1104 const int size = 22;
1105 ASSERT_EQ(memoryData.gpudumpinfo().size(), size);
1106
1107 auto gpuDumpAllInfo = memoryData.gpudumpinfo(0);
1108 EXPECT_STREQ(gpuDumpAllInfo.window_name().c_str(), g_gpudumpAllInfo.window_name.c_str());
1109 EXPECT_EQ(gpuDumpAllInfo.id(), g_gpudumpAllInfo.id);
1110 const int detailAllSize = 5;
1111 ASSERT_EQ(gpuDumpAllInfo.gpu_detail_info().size(), detailAllSize);
1112 for (int i = 0; i < detailAllSize; i++) {
1113 auto detailInfo = gpuDumpAllInfo.gpu_detail_info(i);
1114 auto detailInfoTest = g_gpudumpAllInfo.gpu_detail_info[i];
1115 EXPECT_STREQ(detailInfo.module_name().c_str(), detailInfoTest.module_name.c_str());
1116 if (i == 0 || i == 1 || i == 3) {
1117 ASSERT_EQ(detailInfo.gpu_sub_info().size(), 1);
1118 auto subInfo = detailInfo.gpu_sub_info(0);
1119 auto subInfoTest = detailInfoTest.gpu_sub_info[0];
1120 EXPECT_STREQ(subInfo.category_name().c_str(), subInfoTest.category_name.c_str());
1121 EXPECT_EQ(subInfo.size(), plugin.SizeToBytes(subInfoTest.size, subInfoTest.type));
1122 EXPECT_EQ(subInfo.entry_num(), subInfoTest.entryNum);
1123 } else if (i == 2) {
1124 const int subSize = 2;
1125 ASSERT_EQ(detailInfo.gpu_sub_info().size(), subSize);
1126 for (int j = 0; j < subSize; j++) {
1127 auto subInfo = detailInfo.gpu_sub_info(j);
1128 auto subInfoTest = detailInfoTest.gpu_sub_info[j];
1129 EXPECT_STREQ(subInfo.category_name().c_str(), subInfoTest.category_name.c_str());
1130 EXPECT_EQ(subInfo.size(), plugin.SizeToBytes(subInfoTest.size, subInfoTest.type));
1131 EXPECT_EQ(subInfo.entry_num(), subInfoTest.entryNum);
1132 }
1133 } else if (i == 4) {
1134 const int subSize = 4;
1135 ASSERT_EQ(detailInfo.gpu_sub_info().size(), subSize);
1136 for (int j = 0; j < subSize; j++) {
1137 auto subInfo = detailInfo.gpu_sub_info(j);
1138 auto subInfoTest = detailInfoTest.gpu_sub_info[j];
1139 EXPECT_STREQ(subInfo.category_name().c_str(), subInfoTest.category_name.c_str());
1140 EXPECT_EQ(subInfo.size(), plugin.SizeToBytes(subInfoTest.size, subInfoTest.type));
1141 EXPECT_EQ(subInfo.entry_num(), subInfoTest.entryNum);
1142 }
1143 }
1144 }
1145 EXPECT_EQ(gpuDumpAllInfo.gpu_purgeable_size(), plugin.SizeToBytes(g_gpudumpAllInfo.gpu_purgeable_size,
1146 g_gpudumpAllInfo.type));
1147
1148 auto gpuDumpInfo1 = memoryData.gpudumpinfo(1);
1149 EXPECT_STREQ(gpuDumpInfo1.window_name().c_str(), g_gpudumpInfo1.window_name.c_str());
1150 EXPECT_EQ(gpuDumpInfo1.id(), g_gpudumpInfo1.id);
1151 const int detailSize = 2;
1152 ASSERT_EQ(gpuDumpInfo1.gpu_detail_info().size(), detailSize);
1153 for (int i = 0; i < detailSize; i++) {
1154 auto detailInfo = gpuDumpInfo1.gpu_detail_info(i);
1155 auto detailInfoTest = g_gpudumpInfo1.gpu_detail_info[i];
1156 EXPECT_STREQ(detailInfo.module_name().c_str(), detailInfoTest.module_name.c_str());
1157 ASSERT_EQ(detailInfo.gpu_sub_info().size(), 1);
1158 auto subInfo = detailInfo.gpu_sub_info(0);
1159 auto subInfoTest = detailInfoTest.gpu_sub_info[0];
1160 EXPECT_STREQ(subInfo.category_name().c_str(), subInfoTest.category_name.c_str());
1161 EXPECT_EQ(subInfo.size(), plugin.SizeToBytes(subInfoTest.size, subInfoTest.type));
1162 EXPECT_EQ(subInfo.entry_num(), subInfoTest.entryNum);
1163 }
1164 EXPECT_EQ(gpuDumpInfo1.gpu_purgeable_size(), plugin.SizeToBytes(g_gpudumpInfo1.gpu_purgeable_size,
1165 g_gpudumpInfo1.type));
1166
1167 const int rSDumpSize = 66;
1168 ASSERT_EQ(memoryData.rsdumpinfo().size(), rSDumpSize);
1169 for (int i = 0; i < rSDumpSize; i++) {
1170 auto rsDumpInfo = memoryData.rsdumpinfo(i);
1171 EXPECT_EQ(rsDumpInfo.size(), g_rSImageDumpInfo[i].size);
1172 EXPECT_STREQ(rsDumpInfo.type().c_str(), g_rSImageDumpInfo[i].type.c_str());
1173 EXPECT_EQ(rsDumpInfo.pid(), g_rSImageDumpInfo[i].pid);
1174 EXPECT_STREQ(rsDumpInfo.surface_name().c_str(), g_rSImageDumpInfo[i].name.c_str());
1175 }
1176
1177 auto gpuDumpInfo2 = memoryData.gpudumpinfo(size - 1);
1178 EXPECT_STREQ(gpuDumpInfo2.window_name().c_str(), g_gpudumpInfo2.window_name.c_str());
1179 EXPECT_EQ(gpuDumpInfo2.id(), g_gpudumpInfo2.id);
1180 ASSERT_EQ(gpuDumpInfo2.gpu_detail_info().size(), 1);
1181 auto detailInfo = gpuDumpInfo2.gpu_detail_info(0);
1182 auto detailInfoTest = g_gpudumpInfo2.gpu_detail_info[0];
1183 EXPECT_STREQ(detailInfo.module_name().c_str(), detailInfoTest.module_name.c_str());
1184 ASSERT_EQ(detailInfo.gpu_sub_info().size(), 1);
1185 auto subInfo = detailInfo.gpu_sub_info(0);
1186 auto subInfoTest = detailInfoTest.gpu_sub_info[0];
1187 EXPECT_STREQ(subInfo.category_name().c_str(), subInfoTest.category_name.c_str());
1188 EXPECT_EQ(subInfo.size(), plugin.SizeToBytes(subInfoTest.size, subInfoTest.type));
1189 EXPECT_EQ(subInfo.entry_num(), subInfoTest.entryNum);
1190 EXPECT_EQ(gpuDumpInfo2.gpu_purgeable_size(), plugin.SizeToBytes(g_gpudumpInfo2.gpu_purgeable_size,
1191 g_gpudumpInfo2.type));
1192
1193 const uint64_t gpuLimitSize = 301989888;
1194 const uint64_t usedSize = 45064738;
1195 EXPECT_EQ(memoryData.gpu_limit_size(), gpuLimitSize);
1196 EXPECT_EQ(memoryData.gpu_used_size(), usedSize);
1197 }
1198
1199 /**
1200 * @tc.name: mem plugin
1201 * @tc.desc: test WriteDumpProcessInfo
1202 * @tc.type: FUNC
1203 */
1204 HWTEST_F(MemoryDataPluginTest, TestWriteDumpProcessInfo, TestSize.Level1)
1205 {
1206 MemoryDataPlugin plugin;
1207 MemoryData memoryData;
1208 MemoryConfig protoConfig;
1209 protoConfig.add_pid(1);
1210 protoConfig.set_report_process_mem_info(true);
1211 protoConfig.set_report_gpu_dump_info(true);
1212 EXPECT_TRUE(PluginStub(plugin, protoConfig, memoryData));
1213 plugin.Stop();
1214 const int size = 2;
1215 ASSERT_EQ(memoryData.processesinfo().size(), size);
1216 EXPECT_EQ(memoryData.processesinfo(1).pid(), 1);
1217 EXPECT_GE(memoryData.processesinfo(1).gl_pss_kb(), 0);
1218 EXPECT_GE(memoryData.processesinfo(1).graph_pss_kb(), 0);
1219
1220 int pid = GetPid("render_service");
1221 if (pid > 0) {
1222 protoConfig.add_pid(pid);
1223 EXPECT_TRUE(PluginStub(plugin, protoConfig, memoryData));
1224 plugin.Stop();
1225 const int size = 4;
1226 ASSERT_EQ(memoryData.processesinfo().size(), size);
1227 EXPECT_EQ(memoryData.processesinfo(size - 1).pid(), pid);
1228 EXPECT_GE(memoryData.processesinfo(size - 1).gl_pss_kb(), 0);
1229 EXPECT_GE(memoryData.processesinfo(size - 1).graph_pss_kb(), 0);
1230 }
1231 }
1232
1233 /**
1234 * @tc.name: mem plugin
1235 * @tc.desc: test WriteManagerServiceInfo
1236 * @tc.type: FUNC
1237 */
1238 HWTEST_F(MemoryDataPluginTest, TestWriteManagerServiceInfo, TestSize.Level1)
1239 {
1240 MemoryDataPlugin plugin;
1241 MemoryData memoryData;
1242 MemoryConfig protoConfig;
1243 plugin.SetPath(const_cast<char*>(g_path.c_str()));
1244 plugin.WriteManagerServiceInfo(memoryData);
1245
1246 const int winMgrSvcSize = 17;
1247 ASSERT_EQ(memoryData.windowinfo().size(), winMgrSvcSize);
1248 for (int i = 0; i < winMgrSvcSize; i++) {
1249 auto windowInfo = memoryData.windowinfo(i);
1250 EXPECT_STREQ(windowInfo.window_name().c_str(), g_winMgrSvcInfo[i].name.c_str());
1251 EXPECT_EQ(windowInfo.pid(), g_winMgrSvcInfo[i].pid);
1252 }
1253 }
1254
1255 /**
1256 * @tc.name: mem plugin
1257 * @tc.desc: test WriteProfileMemInfo
1258 * @tc.type: FUNC
1259 */
1260 HWTEST_F(MemoryDataPluginTest, TestWriteProfileMemInfo, TestSize.Level1)
1261 {
1262 MemoryDataPlugin plugin;
1263 MemoryData memoryData;
1264 MemoryConfig protoConfig;
1265 protoConfig.add_pid(1);
1266 plugin.SetPath(const_cast<char*>(g_path.c_str()));
1267 plugin.SetProtoConfig(protoConfig);
1268 plugin.WriteProfileMemInfo(memoryData);
1269
1270 const int profileMemSize = 53;
1271 ASSERT_EQ(memoryData.profilememinfo().size(), profileMemSize);
1272 for (int i = 0; i < profileMemSize; i++) {
1273 auto profileMemInfo = memoryData.profilememinfo(i);
1274 EXPECT_STREQ(profileMemInfo.channel().c_str(), g_profileInfo[i].channel.c_str());
1275 EXPECT_EQ(profileMemInfo.total_memory_size(), g_profileInfo[i].size);
1276 }
1277 }
1278
1279 /**
1280 * @tc.name: mem plugin
1281 * @tc.desc: test GpuData
1282 * @tc.type: FUNC
1283 */
1284 HWTEST_F(MemoryDataPluginTest, TestGpuData, TestSize.Level1)
1285 {
1286 MemoryDataPlugin plugin;
1287 MemoryData memoryData;
1288 MemoryConfig protoConfig;
1289 protoConfig.add_pid(1);
1290 protoConfig.set_report_process_mem_info(true);
1291 protoConfig.set_report_purgeable_ashmem_info(true);
1292 protoConfig.set_report_dma_mem_info(true);
1293 protoConfig.set_report_gpu_mem_info(true);
1294 protoConfig.set_report_gpu_dump_info(true);
1295 plugin.SetPath(const_cast<char*>(g_path.c_str()));
1296 EXPECT_TRUE(PluginStub(plugin, protoConfig, memoryData));
1297 plugin.Stop();
1298
1299 const int processesSize = 2;
1300 const int ashmemSize = 4;
1301 const int dmaSize = 17;
1302 const int dumpSize = 22;
1303 const uint64_t gpuLimitSize = 301989888;
1304 const uint64_t usedSize = 45064738;
1305 EXPECT_EQ(memoryData.processesinfo().size(), processesSize);
1306 EXPECT_EQ(memoryData.ashmeminfo().size(), ashmemSize);
1307 EXPECT_EQ(memoryData.dmainfo().size(), dmaSize);
1308 EXPECT_EQ(memoryData.gpumemoryinfo().size(), 1);
1309 EXPECT_EQ(memoryData.gpudumpinfo().size(), dumpSize);
1310 EXPECT_EQ(memoryData.gpu_limit_size(), gpuLimitSize);
1311 EXPECT_EQ(memoryData.gpu_used_size(), usedSize);
1312 }
1313 } // namespace
1314