python脚本自动消除安卓版_Android:检测内存泄漏的自动化测试Python脚本

这个Python脚本用于自动检测安卓应用的内存泄漏。它通过`adb`命令执行Monkey测试,同时定时记录内存信息,当达到设定的时间间隔时,会生成hprof文件以便分析。脚本还会检查环境是否为eng或userdebug版本,并确保应用具有debuggable标志。
摘要由CSDN通过智能技术生成

#! /usr/bin/python3#-*- coding: utf-8 -*-

importos, sys, time, logging#下列时间单位均为秒#执行时间

exec_time = 15 * 60 * 60 #10 hours, 可改成60s供测试该脚本#记录内存间隔时间,exec_time/exec_interval + 1 即为记录内存次数

exec_interval = 10 #10 s#导出hprof文件间隔

dump_interval = 60 * 60 #1 hour, 可改成30s供测试该脚本

time_passed=0#打印提示间隔次数,以查看当前进度

print_interval = 1packageName= "com.android.systemui"bulid_type= ""

#所有产生文件的输出目录,必须指定且存在#OUTPUT_DIR = os.path.join(os.path.expanduser('~'), "test") # 目录"~/test"

OUTPUT_DIR = os.path.join('d:\\', '\\tools\\tmp\\') #目录"D:\tools\tmp"

logger= logging.getLogger('memoryleak')

FILE_LOG=True

LOG_LEVEL=logging.DEBUGdefinit_logger():

logger.setLevel(LOG_LEVEL)#create formatter

#[%(filename)s:%(lineno)d] 代码位置,暂不配

log_format = logging.Formatter("%(asctime)s %(name)s %(levelname)-8s: %(message)s")defadd_ch():#create console handler and set level to debug

ch =logging.StreamHandler()

ch.setLevel(LOG_LEVEL)

ch.setFormatter(log_format)#add handler to logger

logger.addHandler(ch)defadd_fh():

logfile= os.path.join(OUTPUT_DIR, "memoryleak_" + time.strftime('%Y%m%d%H%M%S') + ".log")

fh=logging.FileHandler(logfile)

fh.setLevel(LOG_LEVEL)

fh.setFormatter(log_format)

logger.warning('log will be outputed to console and file:[%s]' %logfile)

logger.addHandler(fh)

add_ch()if not (OUTPUT_DIR and os.path.isdir(OUTPUT_DIR) andos.access(OUTPUT_DIR, os.W_OK)):

logger.error('OUTPUT_DIR:' + OUTPUT_DIR + 'not exist or not writable, please check it up, exiting...')

sys.exit(-1)ifFILE_LOG:

add_fh()defstart_monkey():#adb shell monkey -p com.gionee.filemanager --throttle 800 -v -v 300

command = "adb shell monkey -p" +packageName

command+= "--ignore-crashes"command+= "--ignore-timeouts"command+= "--ignore-security-exceptions"command+= "--ignore-native-crashes"command+= "--monitor-native-crashes"command+= "--throttle 800"command+= "-v -v 1000000"command+= ">" + os.path.join(OUTPUT_DIR, "monkeytest.log")

logger.info("插入monkey命令:" +command)

os.popen(command)defrecord_memory():globaltime_passedif "eng" inbulid_type:

memfile= os.path.join(OUTPUT_DIR, 'procrank.txt')#第一次执行命令

command = 'adb shell \"procrank | grep' + packageName + '\|cmdline' + '>' +memfile#后续执行命令

commandOther = 'adb shell \"procrank | grep' + packageName + '>>' + memfile + "\""

else:

memfile= os.path.join(OUTPUT_DIR, "meminfo.txt")

command= 'adb shell \"dumpsys meminfo' + packageName +\'| grep "Dalvik Heap" -A 14 -B 4 | grep -ie Private -ie Tota\"' + '>' +memfile

commandOther= 'adb shell \"dumpsys meminfo' + packageName + '| grep TOTAL -m 1\"' + '>>' +memfile

exec_count= exec_time // exec_interval + 1logger.info("开始记录内存信息,待记录次数:" +str(exec_count))for i inrange(exec_count):

os.popen(command)#运行命令

#执行初始命令后切换为后续命令

if i ==0:

command=commandOtherif i % print_interval ==0:

logger.info("当前记录内存次数:" +str(i))if (time_passed) % dump_interval ==0:

logger.info("当前dump hprof次数:" + str(time_passed //dump_interval))

dumpheap(str(time_passed//dump_interval))

time_passed+=exec_interval

time.sleep(exec_interval)#休息n秒,再进入下一个循环,也就是每隔n秒打印一次procrank的信息

logger.info("记录内存信息结束") #运行完毕的标志

defdumpheap(name):

command= "adb shell \"am dumpheap" + packageName + "/data/local/tmp/hprofs/\""command+= "count" + name + ".hprof"os.popen(command)defstop_monkey():#adb shell kill -9 `adb shell ps | grep com.android.commands.monkey | awk '{print $2}'`

pid = os.popen("adb shell \"ps | grep monkey | awk '{print $2}'\"").read()

pid= pid.replace("\n", "")

logger.info("monkey pid is:" + pid + ", kill it")

os.system("adb shell kill" +pid)defcopyheap():

logger.info("开始导出hprof文件...")

os.system("adb pull /data/local/tmp/hprofs/" +OUTPUT_DIR)

os.system("adb shell rm -r /data/local/tmp/hprofs")

logger.info("导出hprof文件结束")#Ensure in eng release or seleted app has flag android:debuggable="true"

defcheck_env():globalbulid_type

bulid_type_prop= os.popen("adb shell \"getprop | grep ro.build.type\"").read()

logger.info("当前rom版本信息 :" +bulid_type_prop)if "eng" inbulid_type_prop:

bulid_type= "eng"logger.info("当前rom版本: eng")elif "userdebug" inbulid_type_prop:

bulid_type= "userdebug"logger.info("当前rom版本: userdebug")else:

bulid_type= "user"logger.info("当前rom版本: user")

package_flags= os.popen("adb shell \"dumpsys package" + packageName + "| grep pkgFlags=\"").read()if "DEBUGGABLE" not inpackage_flags:

logger.info("当前为user版本且应用没有设置android:debuggable=\"true\", 无法导出内存信息, 请确认环境。")

sys.exit(-1)#清空及建立hprof文件存放目录

if 'hprofs' in os.popen('adb shell ls /data/local/tmp').read():

logger.info('在设备中清除上次运行产生的临时目录"/data/local/tmp/hprofs"...')

os.system("adb shell rm -r /data/local/tmp/hprofs")

logger.info('在设备中新建临时目录"/data/local/tmp/hprofs"...')

os.system("adb shell mkdir -p /data/local/tmp/hprofs")defmain():

init_logger()

check_env()

start_monkey()#循环进行,程序主体

record_memory()

stop_monkey()

copyheap()if __name__ == '__main__':

main()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值