Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions perf_testing/hapray/actions/perf_action.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import queue
import re
import shutil
import subprocess
import threading
import time
from concurrent.futures import ThreadPoolExecutor, as_completed
Expand Down Expand Up @@ -347,13 +348,13 @@ def execute(args) -> ActionExecuteReturn:
so_dir = Config.get('so_dir', None)
if so_dir is not None:
# hiperf report will use so_dir path to find symbols.
os.system(f'hdc file send {so_dir} /data/local/tmp/so_dir')
subprocess.run(['hdc', 'file', 'send', so_dir, '/data/local/tmp/so_dir'], check=False)

action = PerfAction(reports_path, parsed_args.round, devices=parsed_args.devices)
action.run()

if so_dir is not None:
os.system('hdc shell rm -rf /data/local/tmp/so_dir')
subprocess.run(['hdc', 'shell', 'rm', '-rf', '/data/local/tmp/so_dir'], check=False)

if parsed_args.hapflow:
try:
Expand Down
42 changes: 33 additions & 9 deletions perf_testing/hapray/analyze/fault_tree_analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,28 +110,52 @@ def _analyze_impl(
return result

def _collect_app_invoke_times(self, cursor, name_match: str, app_pids: list) -> int:
return self._collect_invoke_times(cursor, name_match, f'pid in ({",".join(map(str, app_pids))})')
try:
# Validate that app_pids are integers to prevent injection
safe_pids = [int(pid) for pid in app_pids]
placeholders = ','.join('?' * len(safe_pids))
cursor.execute(
f"""
SELECT count(*) FROM callstack
WHERE
name LIKE ?
and callid in (
SELECT id FROM thread
where
ipid in (
SELECT ipid
FROM process
where pid in ({placeholders})
)
)
""",
[name_match] + safe_pids,
)
rows = cursor.fetchall()
return rows[0][0]
except sqlite3.Error as e:
self.logger.error('FaultTreeAnalyzer invoke Database error: %s', str(e))
return 0

def _collect_rs_invoke_times(self, cursor, name_match: str) -> int:
return self._collect_invoke_times(cursor, name_match, "name = 'render_service'")

def _collect_invoke_times(self, cursor, name_match: str, process_match: str) -> int:
try:
cursor.execute(f"""
cursor.execute(
"""
SELECT count(*) FROM callstack
WHERE
name LIKE '{name_match}'
name LIKE ?
and callid in (
SELECT id FROM thread
where
ipid in (
SELECT ipid
FROM process
where {process_match}
where name = 'render_service'
)
)
""")

""",
[name_match],
)
rows = cursor.fetchall()
return rows[0][0]
except sqlite3.Error as e:
Expand Down
7 changes: 4 additions & 3 deletions perf_testing/hapray/core/collection/capture_ui.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import os
import re
import subprocess
import zipfile

from hypium import UiDriver
Expand Down Expand Up @@ -134,9 +135,9 @@ def _capture_screenshot(self, ui_step_dir: str, label_name: str = None) -> str:
self.driver.pull_file(remote_screenshot_path, local_screenshot_path)
else:
# 使用hdc命令直接传输
recv_cmd = f'hdc file recv {remote_screenshot_path} {local_screenshot_path}'
Log.info(f'执行文件传输命令: {recv_cmd}')
os.system(recv_cmd)
recv_cmd = ['hdc', 'file', 'recv', remote_screenshot_path, local_screenshot_path]
Log.info(f'执行文件传输命令: {" ".join(recv_cmd)}')
subprocess.run(recv_cmd, check=False)

# 验证文件是否成功保存
if os.path.exists(local_screenshot_path):
Expand Down
6 changes: 5 additions & 1 deletion perf_testing/hapray/core/common/exe_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import logging
import os
import platform
import shlex
import shutil
import sqlite3
import subprocess
Expand Down Expand Up @@ -354,7 +355,10 @@ def build_hapray_cmd(args: list[str]) -> list[str]:
def execute_command_check_output(cmd, timeout=120000):
ret = 'error'
try:
ret = subprocess.check_output(cmd, timeout=timeout, stderr=subprocess.STDOUT, shell=True)
# Use shell=False with a command list for safety; split string commands with shlex
if isinstance(cmd, str):
cmd = shlex.split(cmd)
ret = subprocess.check_output(cmd, timeout=timeout, stderr=subprocess.STDOUT)
return ret.decode('gbk', 'ignore').encode('utf-8')
except subprocess.CalledProcessError as e:
logger.error('cmd->%s excute error output=%s', cmd, e.output)
Expand Down
5 changes: 3 additions & 2 deletions perf_testing/hapray/core/perf_testcase.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
import json
import os
import re
import subprocess
import time
from abc import ABC, abstractmethod

Expand Down Expand Up @@ -217,14 +218,14 @@ def update_current_page_ext_info(self, ext_info: dict):
def set_device_redundant_mode(self):
# 设置hdc参数
Log.info('设置hdc参数: persist.ark.properties 0x200105c')
os.system('hdc shell param set persist.ark.properties 0x200105c')
subprocess.run(['hdc', 'shell', 'param', 'set', 'persist.ark.properties', '0x200105c'], check=False)
self._redundant_mode_status = True

def reboot_device(self):
regex = re.compile(r'\d+')
# 重启手机
Log.info('重启手机')
os.system('hdc shell reboot')
subprocess.run(['hdc', 'shell', 'reboot'], check=False)

# 检测手机是否重启成功
Log.info('检测手机重启状态')
Expand Down
14 changes: 10 additions & 4 deletions scripts/e2e_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -845,9 +845,15 @@ async function runE2ETests() {

// 配置 LLM 环境变量用于符号恢复模块测试
console.log('🤖 配置 LLM 环境变量...');
process.env.LLM_API_KEY = 'sk-14ccee5142d04e7fbbcda3418b715390';
process.env.LLM_BASE_URL = 'https://api.deepseek.com/v1';
process.env.LLM_MODEL = 'deepseek-chat';
if (!process.env.LLM_API_KEY) {
console.warn('⚠ LLM_API_KEY 未设置,请通过环境变量提供(例如: export LLM_API_KEY=your-key)');
}
if (!process.env.LLM_BASE_URL) {
process.env.LLM_BASE_URL = 'https://api.deepseek.com/v1';
}
if (!process.env.LLM_MODEL) {
process.env.LLM_MODEL = 'deepseek-chat';
}

console.log('✓ LLM 环境变量配置完成:');
console.log(` - 模型名称: ${process.env.LLM_MODEL}`);
Expand Down Expand Up @@ -959,4 +965,4 @@ if (require.main === module) {
runE2ETests();
}

module.exports = { runE2ETests, checkDirectoryExists, checkFileExists, runCommand, testModule };
module.exports = { runE2ETests, checkDirectoryExists, checkFileExists, runCommand, testModule };
15 changes: 8 additions & 7 deletions tools/static_analyzer/src/core/elf/elf_analyzer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -225,14 +225,15 @@ export class ElfAnalyzer {
let SQL = await initSqlJs();
for (const dbFile of perfFiles) {
const db = new SQL.Database(fs.readFileSync(dbFile));
const results = db.exec(`SELECT symbol FROM perf_files where path like '%${path.basename(filePath)}%'`);
if (results.length === 0) {
continue;
const stmt = db.prepare('SELECT symbol FROM perf_files WHERE path LIKE ?');
stmt.bind([`%${path.basename(filePath)}%`]);
while (stmt.step()) {
const row = stmt.get();
if (row[0]) {
invokeSymbols.add(row[0] as string);
}
}

results[0].values.map((row) => {
invokeSymbols.add(row[0] as string);
});
stmt.free();
}

logger.info(`${filePath} parse symbols from perf ${Array.from(invokeSymbols.values()).join('\n')}`);
Expand Down
7 changes: 6 additions & 1 deletion tools/symbol_recovery/core/analyzers/perf_analyzer.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"""

import platform
import re
import shutil
import sqlite3
import subprocess
Expand Down Expand Up @@ -203,7 +204,11 @@ def verify_sqlite_db(self, db_path):
logger.info(f'数据库包含 {len(tables)} 个表:')
for table in tables:
table_name = table[0]
cursor.execute(f'SELECT COUNT(*) FROM {table_name};')
# Validate table name to prevent SQL injection (allow only alphanumeric and underscores)
if not re.match(r'^[A-Za-z_][A-Za-z0-9_]*$', table_name):
logger.warning(f' - {table_name}: 跳过(表名包含非法字符)')
continue
cursor.execute(f'SELECT COUNT(*) FROM [{table_name}];')
count = cursor.fetchone()[0]
logger.info(f' - {table_name}: {count} 行')

Expand Down
Loading