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/inputfiles/memory_plugin/config_memory_plugin.txt -o /data/local/tmp/test_memory_kernel.htrace -t 60 -s -k"') 33 34 35def task_vminfo(): 36 subprocess.check_output(f'hdc shell "hiprofiler_cmd -c /data/local/tmp/inputfiles/memory_plugin/config_memory_vmeminfo.txt -o /data/local/tmp/test_memory_vmeminfo.htrace -t 60 -s -k"') 37 38 39def task_vmtracker(): 40 subprocess.check_output(f'hdc shell "hiprofiler_cmd -c /data/local/tmp/inputfiles/memory_plugin/config_memory_vmtracker.txt -o /data/local/tmp/test_memory_vmtracker.htrace -t 60 -s -k"') 41 42 43def write_str_file(file_path, large_string): 44 lines = large_string.split('\n') 45 with open(file_path, 'w') as file: 46 for line in lines: 47 file.write(line + '\n') 48 49 50class TestHiprofilerMemoryPlugin: 51 # 检查内核的 memory info 52 @pytest.mark.L0 53 def test_memory_plugin_kernel(self): 54 subprocess.check_output(f"hdc file send ./inputfiles/memory_plugin/config_memory_plugin.txt /data/local/tmp/", shell=False, 55 text=True, encoding="utf-8") 56 task_thread = threading.Thread(target=task, args=()) 57 task_thread.start() 58 59 task_thread.join() 60 subprocess.run(f'hdc file recv /data/local/tmp/test_memory_kernel.htrace ./outputfiles/', shell=False, 61 text=True, encoding="utf-8") 62 # 检查文件大小 63 file_size = get_file_size(f"./outputfiles/test_memory_kernel.htrace") 64 assert (file_size > 1024) 65 subprocess.check_output( 66 r"./inputfiles/trace_streamer_db.exe ./outputfiles/test_memory_kernel.htrace -e ./outputfiles/test_memory_kernel.db") 67 # 连接数据库文件 68 conn = sqlite3.connect(r'./outputfiles/test_memory_kernel.db') 69 # # 创建游标对象 70 cursor = conn.cursor() 71 cursor.execute("select * from sys_mem_measure,sys_event_filter where filter_id = id and name ='sys.mem.mapped'") 72 result = cursor.fetchall() 73 row_count = len(result) 74 #检查获得sys_mem 数据是否正确 75 assert (row_count > 0) 76 #检查是否存在map 的事件 77 for row in result: 78 assert (row[3] >= 0) 79 #检查是否存在sys_mem_total 事件 80 cursor = conn.cursor() 81 cursor.execute("select * from sys_mem_measure,sys_event_filter where filter_id = id and name ='sys.mem.total'") 82 result = cursor.fetchall() 83 row_count = len(result) 84 assert (row_count > 0) 85 for row in result: 86 assert (row[3] >= 0) 87 cursor.close() 88 conn.close() 89 90 # 检查内核的 virture memory info stats 91 @pytest.mark.L0 92 def test_memory_plugin_vmeminfo(self): 93 subprocess.check_output(f"hdc file send ./inputfiles/memory_plugin/config_memory_vmeminfo.txt /data/local/tmp/", shell=False, 94 text=True, encoding="utf-8") 95 task_thread = threading.Thread(target=task_vminfo, args=()) 96 task_thread.start() 97 98 task_thread.join() 99 subprocess.run(f'hdc file recv /data/local/tmp/test_memory_vmeminfo.htrace ./outputfiles/', shell=False, 100 text=True, encoding="utf-8") 101 # 检查文件大小 102 file_size = get_file_size(f"./outputfiles/test_memory_vmeminfo.htrace") 103 assert (file_size > 1024) 104 subprocess.check_output( 105 r"./inputfiles/trace_streamer_db.exe ./outputfiles/test_memory_vmeminfo.htrace -e ./outputfiles/test_memory_vmeminfo.db") 106 # 连接数据库文件 107 conn = sqlite3.connect(r'./outputfiles/test_memory_vmeminfo.db') 108 # # 创建游标对象 109 cursor = conn.cursor() 110 cursor.execute("select * from sys_mem_measure,sys_event_filter where filter_id = id and name ='sys.virtual.mem.nr.free.pages'") 111 result = cursor.fetchall() 112 row_count = len(result) 113 #检查获得free pages 数据是否正确 114 assert (row_count > 0) 115 #检查是否存在 free pages 的事件 116 for row in result: 117 assert (row[3] >= 0) 118 #检查是否存在active file 事件 119 cursor = conn.cursor() 120 cursor.execute("select * from sys_mem_measure,sys_event_filter where filter_id = id and name ='sys.virtual.mem.nr.active_file'") 121 result = cursor.fetchall() 122 row_count = len(result) 123 assert (row_count > 0) 124 for row in result: 125 assert (row[3] >= 0) 126 cursor.close() 127 conn.close() 128 129 # 检查某一个进程的vm ,观测点,DMA 数据,smaps 数据。 130 @pytest.mark.L0 131 def test_memory_plugin_vmtracker(self): 132 #获得32位还是64位 133 sys_bit = subprocess.run(f"hdc shell getconf LONG_BIT", stdout=subprocess.PIPE, text=True, check=True) 134 sysinfo = sys_bit.stdout 135 if sysinfo.strip() == "32": 136 subprocess.check_output(f"hdc shell aa start -a com.ohos.settings.MainAbility -b com.ohos.settings", shell=False, text=True, encoding="utf-8") 137 time.sleep(2) 138 pid_text = subprocess.run(f"hdc shell pidof 'com.ohos.settings'", stdout=subprocess.PIPE, text=True, check=True) 139 else: 140 #打开系统设置的应用 141 subprocess.check_output(f"hdc shell aa start -a com.huawei.hmos.settings.MainAbility -b com.huawei.hmos.settings", shell=False, 142 text=True, encoding="utf-8") 143 time.sleep(2) 144 #获得该应用的进程PID 145 pid_text = subprocess.run(f"hdc shell pidof 'com.huawei.hmos.settings'", stdout=subprocess.PIPE, text=True, check=True) 146 pidinfo = pid_text.stdout 147 #读文本文件,修改对应的pid 148 file_content = Template('request_id: 1 \n' 149 ' session_config { \n' 150 ' buffers { \n' 151 ' pages: 16384 \n' 152 ' } \n' 153 ' } \n' 154 ' plugin_configs { \n' 155 ' plugin_name: "memory-plugin" \n' 156 ' sample_interval: 5000 \n' 157 ' config_data { \n' 158 ' report_process_tree: false \n' 159 ' report_sysmem_mem_info: false \n' 160 ' report_sysmem_vmem_info: false \n' 161 ' report_process_mem_info: true \n' 162 ' report_app_mem_info: false \n' 163 ' report_app_mem_by_memory_service: false\n' 164 ' pid: ${s1} \n' 165 ' report_purgeable_ashmem_info: true \n' 166 ' report_dma_mem_info: true \n' 167 ' report_gpu_mem_info: true \n' 168 ' report_smaps_mem_info: true \n' 169 ' report_gpu_dump_info: true \n' 170 ' } \n' 171 ' } \n') 172 vmfile = file_content.safe_substitute(s1=pidinfo.strip()) 173 #写入文件 174 write_str_file("./inputfiles/memory_plugin/config_memory_vmtracker.txt", vmfile) 175 176 subprocess.check_output(f"hdc file send ./inputfiles/memory_plugin/config_memory_vmtracker.txt /data/local/tmp/", shell=False, 177 text=True, encoding="utf-8") 178 task_thread = threading.Thread(target=task_vmtracker, args=()) 179 task_thread.start() 180 task_thread.join() 181 subprocess.run(f'hdc file recv /data/local/tmp/test_memory_vmtracker.htrace ./outputfiles/', shell=False, 182 text=True, encoding="utf-8") 183 # 检查文件大小 184 file_size = get_file_size(f"./outputfiles/test_memory_vmtracker.htrace") 185 assert (file_size > 1024) 186 subprocess.check_output( 187 r"./inputfiles/trace_streamer_db.exe ./outputfiles/test_memory_vmtracker.htrace -e ./outputfiles/test_memory_vmtracker.db") 188 # 连接数据库文件 189 conn = sqlite3.connect(r'./outputfiles/test_memory_vmtracker.db') 190 #抓取结束后,检查是否存在hidumper 进程 191 output_text = subprocess.run(f'hdc shell "ps -ef | grep hidumper"', stdout=subprocess.PIPE, text=True, check=True) 192 process_info = output_text.stdout 193 lines = process_info.strip().split('\n') 194 check_index = False 195 for line in lines: 196 if line.find("hidumper -s") != -1: 197 check_index = True 198 # 结束后不存在hidumper 子进程 199 assert (check_index == False) 200 # # 创建游标对象 201 cursor = conn.cursor() 202 cursor.execute("select * from memory_dma limit 0,10") 203 result = cursor.fetchall() 204 row_count = len(result) 205 #检查存在dma 数据 206 assert (row_count > 0) 207 for row in result: 208 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) 209 #检查是否存在smaps 210 cursor.execute("select * from smaps limit 0,10") 211 result = cursor.fetchall() 212 row_count = len(result) 213 assert (row_count > 0) 214 for row in result: 215 assert (row[2] != '' and row[3] != '' and row[7] >= 0 and row[8] >= 0) 216 #检查是否存在GPU数据 217 cursor.execute("select * from memory_process_gpu limit 0,10") 218 result = cursor.fetchall() 219 row_count = len(result) 220 assert (row_count > 0) 221 for row in result: 222 assert (row[3] > 0 and row[7] > 0) 223 cursor.close() 224 conn.close()