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