• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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