1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3# Copyright (C) 2024 Huawei Device Co., Ltd. 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15 16import pytest 17import subprocess 18import re 19import time 20import threading 21import sqlite3 22from string import Template 23import os 24 25 26def get_file_size(file_path): 27 size = os.path.getsize(file_path) 28 return size 29 30 31def task(): 32 subprocess.check_output(f'hdc shell "hiprofiler_cmd -c /data/local/tmp/config_memory_plugin.txt -o /data/local/tmp/test_memory_kernel.htrace -t 60 -s -k"') 33 34 35 36def task_vminfo(): 37 subprocess.check_output(f'hdc shell "hiprofiler_cmd -c /data/local/tmp/config_memory_vmeminfo.txt -o /data/local/tmp/test_memory_vmeminfo.htrace -t 60 -s -k"') 38 39 40def task_vmtracker(): 41 subprocess.check_output(f'hdc shell "hiprofiler_cmd -c /data/local/tmp/config_memory_vmtracker.txt -o /data/local/tmp/test_memory_vmtracker.htrace -t 60 -s -k"') 42 43 44def write_str_file(file_path, large_string): 45 lines = large_string.split('\n') 46 with open(file_path, 'w') as file: 47 for line in lines: 48 file.write(line + '\n') 49 50 51class TestHiprofilerMemoryPlugin: 52 # 检查内核的 memory info 53 @pytest.mark.L0 54 def test_memory_plugin_kernel(self): 55 subprocess.check_output(f"hdc file send ..\inputfiles\memory_plugin\config_memory_plugin.txt /data/local/tmp/", shell=False, 56 text=True, encoding="utf-8") 57 task_thread = threading.Thread(target=task, args=()) 58 task_thread.start() 59 60 task_thread.join() 61 subprocess.run(f'hdc file recv /data/local/tmp/test_memory_kernel.htrace ../outputfiles/', shell=False, 62 text=True, encoding="utf-8") 63 # 检查文件大小 64 file_size = get_file_size(f"../outputfiles/test_memory_kernel.htrace") 65 assert (file_size > 1024) 66 subprocess.check_output( 67 r"../inputfiles/trace_streamer_db.exe ../outputfiles/test_memory_kernel.htrace -e ../outputfiles/test_memory_kernel.db") 68 # 连接数据库文件 69 conn = sqlite3.connect(r'../outputfiles/test_memory_kernel.db') 70 # # 创建游标对象 71 cursor = conn.cursor() 72 cursor.execute("select * from sys_mem_measure,sys_event_filter where filter_id = id and name ='sys.mem.mapped'") 73 result = cursor.fetchall() 74 row_count = len(result) 75 #检查获得sys_mem 数据是否正确 76 assert(row_count > 0) 77 #检查是否存在map 的事件 78 for row in result: 79 assert(row[3] >= 0) 80 #检查是否存在sys_mem_total 事件 81 cursor = conn.cursor() 82 cursor.execute("select * from sys_mem_measure,sys_event_filter where filter_id = id and name ='sys.mem.total'") 83 result = cursor.fetchall() 84 row_count = len(result) 85 assert(row_count > 0) 86 for row in result: 87 assert(row[3] >= 0) 88 cursor.close() 89 conn.close() 90 91 # 检查内核的 virture memory info stats 92 @pytest.mark.L0 93 def test_memory_plugin_vmeminfo(self): 94 subprocess.check_output(f"hdc file send ..\inputfiles\memory_plugin\config_memory_vmeminfo.txt /data/local/tmp/", shell=False, 95 text=True, encoding="utf-8") 96 task_thread = threading.Thread(target=task_vminfo, args=()) 97 task_thread.start() 98 99 task_thread.join() 100 subprocess.run(f'hdc file recv /data/local/tmp/test_memory_vmeminfo.htrace ../outputfiles/', shell=False, 101 text=True, encoding="utf-8") 102 # 检查文件大小 103 file_size = get_file_size(f"../outputfiles/test_memory_vmeminfo.htrace") 104 assert (file_size > 1024) 105 subprocess.check_output( 106 r"../inputfiles/trace_streamer_db.exe ../outputfiles/test_memory_vmeminfo.htrace -e ../outputfiles/test_memory_vmeminfo.db") 107 # 连接数据库文件 108 conn = sqlite3.connect(r'../outputfiles/test_memory_vmeminfo.db') 109 # # 创建游标对象 110 cursor = conn.cursor() 111 cursor.execute("select * from sys_mem_measure,sys_event_filter where filter_id = id and name ='sys.virtual.mem.nr.free.pages'") 112 result = cursor.fetchall() 113 row_count = len(result) 114 #检查获得free pages 数据是否正确 115 assert(row_count > 0) 116 #检查是否存在 free pages 的事件 117 for row in result: 118 assert(row[3] >= 0) 119 #检查是否存在active file 事件 120 cursor = conn.cursor() 121 cursor.execute("select * from sys_mem_measure,sys_event_filter where filter_id = id and name ='sys.virtual.mem.nr.active_file'") 122 result = cursor.fetchall() 123 row_count = len(result) 124 assert(row_count > 0) 125 for row in result: 126 assert(row[3] >= 0) 127 cursor.close() 128 conn.close() 129 130 # 检查某一个进程的vm ,观测点,DMA 数据,smaps 数据。 131 @pytest.mark.L0 132 def test_memory_plugin_vmtracker(self): 133 #获得32位还是64位 134 sys_bit = subprocess.run(f"hdc shell getconf LONG_BIT", stdout=subprocess.PIPE, text=True, check=True) 135 sysinfo = sys_bit.stdout 136 if sysinfo.strip() == "32": 137 subprocess.check_output(f"hdc shell aa start -a com.ohos.settings.MainAbility -b com.ohos.settings", shell=False, text=True, encoding="utf-8") 138 time.sleep(2) 139 pid_text = subprocess.run(f"hdc shell pidof 'com.ohos.settings'", stdout=subprocess.PIPE, text=True, check=True) 140 else: 141 #获得该应用的进程PID 142 pid_text = subprocess.run(f"hdc shell pidof 'com.ohos.launcher'", stdout=subprocess.PIPE, text=True, check=True) 143 pidinfo = pid_text.stdout 144 #读文本文件,修改对应的pid 145 file_content = Template('request_id: 1 \n' 146 ' session_config { \n' 147 ' buffers { \n' 148 ' pages: 16384 \n' 149 ' } \n' 150 ' } \n' 151 ' plugin_configs { \n' 152 ' plugin_name: "memory-plugin" \n' 153 ' sample_interval: 5000 \n' 154 ' config_data { \n' 155 ' report_process_tree: false \n' 156 ' report_sysmem_mem_info: false \n' 157 ' report_sysmem_vmem_info: false \n' 158 ' report_process_mem_info: true \n' 159 ' report_app_mem_info: false \n' 160 ' report_app_mem_by_memory_service: false\n' 161 ' pid: ${s1} \n' 162 ' report_purgeable_ashmem_info: true \n' 163 ' report_dma_mem_info: true \n' 164 ' report_gpu_mem_info: true \n' 165 ' report_smaps_mem_info: true \n' 166 ' report_gpu_dump_info: true \n' 167 ' } \n' 168 ' } \n') 169 vmfile = file_content.safe_substitute(s1=pidinfo.strip()) 170 #写入文件 171 write_str_file("../inputfiles/memory_plugin/config_memory_vmtracker.txt", vmfile) 172 173 subprocess.check_output(f"hdc file send ..\inputfiles\memory_plugin\config_memory_vmtracker.txt /data/local/tmp/", shell=False, 174 text=True, encoding="utf-8") 175 task_thread = threading.Thread(target=task_vmtracker, args=()) 176 task_thread.start() 177 task_thread.join() 178 subprocess.run(f'hdc file recv /data/local/tmp/test_memory_vmtracker.htrace ../outputfiles/', shell=False, 179 text=True, encoding="utf-8") 180 # 检查文件大小 181 file_size = get_file_size(f"../outputfiles/test_memory_vmtracker.htrace") 182 assert (file_size > 1024) 183 subprocess.check_output( 184 r"../inputfiles/trace_streamer_db.exe ../outputfiles/test_memory_vmtracker.htrace -e ../outputfiles/test_memory_vmtracker.db") 185 # 连接数据库文件 186 conn = sqlite3.connect(r'../outputfiles/test_memory_vmtracker.db') 187 #抓取结束后,检查是否存在hidumper 进程 188 output_text = subprocess.run(f'hdc shell "ps -ef | grep hidumper"', stdout=subprocess.PIPE, text=True, check=True) 189 process_info = output_text.stdout 190 lines = process_info.strip().split('\n') 191 check_index = False 192 for line in lines: 193 if line.find("hidumper -s") != -1: 194 check_index = True 195 # 结束后不存在hidumper 子进程 196 assert (check_index == False) 197 # # 创建游标对象 198 cursor = conn.cursor() 199 cursor.execute("select * from memory_dma limit 0,10") 200 result = cursor.fetchall() 201 row_count = len(result) 202 #检查存在dma 数据 203 assert(row_count > 0) 204 for row in result: 205 assert(row[3] > 0 and row[4] > 0 and row[5] > 0 and row[6] > 0 and row[7] > 0 and row[8] > 0 and row[9] > 0) 206 #检查是否存在smaps 207 cursor.execute("select * from smaps limit 0,10") 208 result = cursor.fetchall() 209 row_count = len(result) 210 assert(row_count > 0) 211 for row in result: 212 assert(row[2] != '' and row[3] != '' and row[7] >= 0 and row[8] >= 0) 213 #检查是否存在GPU数据 214 cursor.execute("select * from memory_process_gpu limit 0,10") 215 result = cursor.fetchall() 216 row_count = len(result) 217 assert(row_count > 0) 218 for row in result: 219 assert(row[3] > 0 and row[7] > 0) 220 cursor.close() 221 conn.close()