def list_dir_between_time(self, dir_path, start_time, end_time): '''列取目录下 起止时间点之间的文件 start_time end_time 时间戳 返回文件绝对路径 列表 ''' # ls - l # -rwxrwx--- 1 root root 19897899 2018-12-27 18:02 com.alibaba.ailabs.ar.fireeye2_dumpheap_2018_12_27_18_02_52.hprof result = self.run_shell_cmd('ls -l %s' % dir_path) if not result: return "" result = result.replace('\r\r\n', '\n') if 'No such file or directory' in result: logger.error('文件(夹) %s 不存在' % dir_path) file_list = [] re_time = re.compile(r'\S*\s+(\d+-\d+-\d+\s+\d+:\d+)\s+\S+') for line in result.split('\n'): items = line.split() match = re_time.search(line) if match: last_modify_time = match.group(1) logger.debug(last_modify_time) last_modify_timestamp = TimeUtils.getTimeStamp(last_modify_time, "%Y-%m-%d %H:%M") # logger.debug(last_modify_timestamp) if start_time < last_modify_timestamp and last_modify_timestamp < end_time: logger.debug("append file:" + items[-1]) file_list.append('%s/%s' % (dir_path, items[-1])) return file_list
def list_process(self): '''获取进程列表 ''' import re result = self.run_shell_cmd('ps -A') # 不能使用grep result = result.replace('\r', '') lines = result.split('\n') busybox = False if lines[0].startswith('PID'): busybox = True result_list = [] for i in range(1, len(lines)): items = lines[i].split() if not busybox: if len(items) < 9: err_msg = "ps命令返回格式错误:\n%s" % lines[i] if len(items) == 8: result_list.append({'pid': int(items[1]), 'ppid': int(items[2]), 'proc_name': items[7]}) else: logger.error(err_msg) else: result_list.append({'pid': int(items[1]), 'ppid': int(items[2]), 'proc_name': items[8]}) else: idx = 4 cmd = items[idx] if len(cmd) == 1: # 有时候发现此处会有“N” idx += 1 cmd = items[idx] idx += 1 if cmd[0] == '{' and cmd[-1] == '}': cmd = items[idx] ppid = 0 if items[1].isdigit(): ppid = int(items[1]) # 有些版本中没有ppid result_list.append({'pid': int(items[0]), 'ppid': ppid, 'proc_name': cmd}) return result_list
def _get_fd_save(self, fd_data, timestamp): if isinstance(fd_data, dict): self.fd_file = fd_data['fd_file'] logger.debug("fd_file: " + str(self.fd_file)) else: try: ''' 0 1 2 3 fd_data: ("datatime", "pckagename", "pid", "fd num") 对应的值是:[formatTimeStamp(collection_time), packagename, pid,fd_num] ''' fd_data[0] = timestamp dic = { "time": fd_data[0] * 1000, "package": fd_data[1], "pid": fd_data[2], "fd": fd_data[3] } self.perf_data['fd'].append(dic) with open(self.fd_file, 'a+') as writer: logger.debug( "write fd data in dataworker。。。。。。 fd timestamp: " + str(fd_data[0])) if isinstance(fd_data[0], float): fd_data[0] = TimeUtils.formatTimeStamp(fd_data[0]) tmp_dic = copy.deepcopy(dic) tmp_dic["time"] = fd_data[0] logger.debug(tmp_dic) writer_p = csv.writer(writer, lineterminator='\n') writer_p.writerow(fd_data) except Exception as e: logger.error('fd save error') s = traceback.format_exc() logger.debug(s)
def _get_activity_save(self, activity_data, timestamp): if self.first_time: activity_title = ("datetime", "current_activity") self.first_time = False self.activity_file = os.path.join(RuntimeData.package_save_path, 'current_activity.csv') try: with open(self.activity_file, 'a+') as af: csv.writer(af, lineterminator='\n').writerow(activity_title) except Exception as e: logger.error("file not found: " + str(self.activity_file)) else: try: activity_data[0] = timestamp dic = { "time": activity_data[0] * 1000, "name": activity_data[1] } self.perf_data['activity'].append(dic) with open(self.activity_file, 'a+') as writer: if isinstance(activity_data[0], float): activity_data[0] = TimeUtils.formatTimeStamp( activity_data[0]) tmp_dic = copy.deepcopy(dic) tmp_dic["time"] = activity_data[0] logger.debug(tmp_dic) writer_p = csv.writer(writer, lineterminator='\n') writer_p.writerow(activity_data) except Exception as e: logger.error("activity save error ") s = traceback.format_exc() logger.debug(s)
def _get_fps_save(self, fps_data, timestamp): if isinstance(fps_data, dict): self.fps_filename = fps_data['fps_file'] logger.debug("fps_filename: " + str(self.fps_filename)) else: try: '''0 1 2 3 fps_data: ("datetime", "activity","fps", "jank") 对应的值是:[formatter(collection_time), activity,fps,jank], ''' fps_data[0] = timestamp dic = { "time": fps_data[0] * 1000, "activity": fps_data[1], "fps": fps_data[2], "jank": fps_data[3] } self.perf_data['fluency'].append(dic) with open(self.fps_filename, 'a+') as writer: logger.debug( "dataworker write fps data in dataworker。fps timestamp: " + str(fps_data[0])) fps_data[0] = TimeUtils.formatTimeStamp(fps_data[0]) tmp_dic = copy.deepcopy(dic) tmp_dic["time"] = fps_data[0] logger.debug(tmp_dic) writer_p = csv.writer(writer, lineterminator='\n') writer_p.writerow(fps_data) except Exception as e: s = traceback.format_exc() logger.error(s) # 将堆栈信息打印到log中 logger.error("fps save error")
def pull_file(self, src_path, dst_path): '''从手机中拉取文件 ''' result = self.run_adb_cmd('pull', src_path, dst_path, timeout=180) if result and 'failed to copy' in result: logger.error("failed to pull file:" + src_path) return result
def trim_value(self, content): try: content[2] = ms2s(float(content[2])) #将this_time转化单位转化为s content[3] = ms2s(float(content[3])) #将total_time 转化为s except Exception as e: logger.error(e) return [] return content
def recover(): if ADB.checkAdbNormal(): logger.debug("adb is normal") return else: logger.error("adb is not normal") ADB.kill_server() ADB.start_server()
def get_device_imei(self): '''获取手机串号 ''' result = self.run_shell_cmd('dumpsys iphonesubinfo') result = result.replace('\r\r\n', '\n') for line in result.split('\n'): if line.find('Device ID') >= 0: return line.split('=')[1].strip() logger.error('获取imei号失败:%r' % result)
def pull_file(self, src_path, dst_path): '''从手机中拉取文件 ''' # 抓包时使用 root权限抓包,在这里先修改抓到的包的 所有者和所在组,否则后面的pull_file有可能由于权限问题失败 # self.run_root_shell_cmd('chown shell:shell %s' % src_path) result = self.run_adb_cmd('pull', src_path, dst_path, timeout=180) if result and 'failed to copy' in result: logger.error("failed to pull file:" + src_path) return result
def get_pckinfo_from_ps(self, packagename): ''' 从ps中获取应用的信息:pid,uid,packagename :param packagename: 目标包名 :return: 返回目标包名的列表信息 ''' # get list_process 有重复代码 results = self.run_shell_cmd('ps -A') lines = results.replace('\r', '').splitlines() # logger.debug(lines) busybox = False if lines[0].startswith('PID'): busybox = True result_list = [] for line in lines: # logger.debug(line) if packagename in line: items = line.split() if not busybox: if len(items) < 9: err_msg = "ps命令返回格式错误:\n%s" % line if len(items) == 8: target_pkg = items[7] # 只保存与packagename完全相同的进程,对于以包名开头的其他进程将不会被保存,例如packagename:com.xx,com.xx:play不会保存 if packagename == target_pkg: result_list.append( {'pid': int(items[1]), 'uid': items[0], 'proc_name': items[-1], 'status': items[-2]}) else: logger.error(err_msg) else: target_pck = items[-1] # 只保存与packagename完全相同的进程,对于以包名开头的其他进程将不会被保存,例如packagename:com.xx,com.xx:play不会保存 if packagename == target_pck: result_list.append( {'pid': int(items[1]), 'uid': items[0], 'proc_name': items[-1], 'status': items[-2]}) else: # busybox = True idx = 4 cmd = items[idx] if len(cmd) == 1: # 有时候发现此处会有“N” idx += 1 cmd = items[idx] idx += 1 if cmd[0] == '{' and cmd[-1] == '}': cmd = items[idx] target_pkg = items[-1] if packagename == target_pkg: result_list.append( {'pid': int(items[0]), 'uid': items[1], 'proc_name': cmd, 'status': items[-2]}) if len(result_list) > 0: logger.debug(" get pckinfo from ps: " + str(result_list)) return result_list
def parse_data_from_config(self): ''' 从配置文件中解析出需要的信息,包名,时间间隔,设备的序列号等 :return:配置文件中读出来的数值的字典 ''' config_dic = {} configpath = os.path.join(RuntimeData.top_dir, "config.conf") logger.debug("configpath:%s" % configpath) if not os.path.isfile(configpath): logger.error("the config file didn't exist: " + configpath) raise RuntimeError("the config file didn't exist: " + configpath) # 避免windows会用系统默认的gbk打开 with open(configpath, encoding="utf-8") as f: content = f.read() # Window下用记事本打开配置文件并修改保存后,编码为UNICODE或UTF-8的文件的文件头 # 会被相应的加上\xff\xfe(\xff\xfe)或\xef\xbb\xbf,然后再传递给ConfigParser解析的时候会出错 # ,因此解析之前,先替换掉 content = re.sub(r"\xfe\xff", "", content) content = re.sub(r"\xff\xfe", "", content) content = re.sub(r"\xef\xbb\xbf", "", content) open(configpath, 'w', encoding="utf-8").write(content) paser = ConfigParser() paser.read(configpath, encoding="utf-8") config_dic = self.check_config_option(config_dic, paser, "Common", "package") config_dic = self.check_config_option(config_dic, paser, "Common", "pid_change_focus_package") config_dic = self.check_config_option(config_dic, paser, "Common", "frequency") config_dic = self.check_config_option(config_dic, paser, "Common", "dumpheap_freq") config_dic = self.check_config_option(config_dic, paser, "Common", "timeout") config_dic = self.check_config_option(config_dic, paser, "Common", "serialnum") config_dic = self.check_config_option(config_dic, paser, "Common", "mailbox") config_dic = self.check_config_option(config_dic, paser, "Common", "exceptionlog") config_dic = self.check_config_option(config_dic, paser, "Common", "save_path") config_dic = self.check_config_option(config_dic, paser, "Common", "phone_log_path") # 读取monkey配置 config_dic = self.check_config_option(config_dic, paser, "Common", "monkey") config_dic = self.check_config_option(config_dic, paser, "Common", "main_activity") config_dic = self.check_config_option(config_dic, paser, "Common", "activity_list") logger.debug(config_dic) return config_dic
def _parse_package(self): ''' 解析top命令中的包的cpu信息 :return: ''' if self.packages == None or self.packages == "": logger.error("no process name input, please input") for package in self.packages: package_dic = {"package": package, "pid": "", "pid_cpu": ""} sp_lines = self.source.split('\n') for line in sp_lines: # logger.debug(line) if package in line: #解析进程cpu信息 tmp = line.split() self.pid = tmp[0] target_pck = tmp[-1] #从中解析出的最后一个值是包名 self.datetime = TimeUtils.getCurrentTime() logger.debug("cpuinfos, _parse top target_pck is : " + str(target_pck) + " , self.pacakgename : " + package) if package == target_pck: #只统计包名完全相同的进程 if int(self.pid) > 0: logger.debug( "cpuinfos, into _parse_pck packege is target package, pid is :" + str(self.pid)) # logger.debug("into _parse_pck packege is target package, pid is :" + str(self.pid)) cpu_index = self.get_cpucol_index() uid_index = self.get_uidcol_index() if (len(tmp) > cpu_index): self.pck_cpu_rate = tmp[cpu_index] # CPU% 9% 有的格式会有% self.pck_cpu_rate = self.pck_cpu_rate.replace( "%", "") if (len(tmp) > uid_index): self.uid = tmp[uid_index] package_dic = { "package": package, "pid": self.pid, "pid_cpu": str(self.pck_cpu_rate), "uid": self.uid } # self.package_list.append(package_dic) # 将top中解析出来的信息保存在一个列表中,作为一条记录添加在package_list中 logger.debug("package: " + package + ", cpu_rate: " + str(self.pck_cpu_rate)) self.total_pid_cpu = self.total_pid_cpu + float( self.pck_cpu_rate) break self.package_list.append(package_dic) logger.debug(package_dic)
def _install_apk(self, apk_path, over_install=True, downgrade=False): ''' ''' timeout = 3 * 60 # TODO: 确认3分钟是否足够 tmp_path = '/data/local/tmp/' + os.path.split(apk_path)[-1] self.push_file(apk_path, tmp_path) cmdline = 'pm install %s %s %s' % ('-r -t' if over_install else '', "-d" if downgrade else "", tmp_path) ret = '' for i in range(3): # TODO: 处理一些必然会失败的情况,如方法数超标之类的问题 try: ret = self.run_shell_cmd( cmdline, retry_count=1, timeout=timeout) # 使用root权限安装,可以在小米2S上不弹出确认对话框 logger.debug(ret) if i > 1 and 'INSTALL_FAILED_ALREADY_EXISTS' in ret: # 出现至少一次超时,认为安装完成 ret = 'Success' break if 'INSTALL_PARSE_FAILED_NO_CERTIFICATES' in ret or \ 'INSTALL_FAILED_INSUFFICIENT_STORAGE' in ret: raise RuntimeError('安装应用失败:%s' % ret) if 'INSTALL_FAILED_UID_CHANGED' in ret: logger.error(ret) # /data/data目录下存在文件夹没有删除 # package_name = self._get_package_name(apk_path) # dir_path = '/data/data/%s' % package_name # for _ in range(3): # # 防止删除没有成功 # self.delete_folder(dir_path) # if 'No such file or directory' in self.run_root_shell_cmd('ls -l %s' % dir_path): break continue if 'Success' in ret or 'INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES' in ret or \ 'INSTALL_FAILED_ALREADY_EXISTS' in ret: break except: if i >= 2: logger.warning('install app failed') ret = self.run_shell_cmd(cmdline, timeout=timeout) # 改用非root权限安装 logger.debug(ret) if ret and 'INSTALL_FAILED_ALREADY_EXISTS' in ret: ret = 'Success' try: self.delete_file('/data/local/tmp/*.apk') except: pass return ret
def run_shell_cmd(self, cmd, **kwds): '''执行 adb shell 命令 ''' # 如果失去连接后,adb又正常连接了 if not self.before_connect and self.after_connect: cpu_uptime_file = os.path.join(RuntimeData.package_save_path, "uptime.txt") with open(cpu_uptime_file, "a+",encoding = "utf-8") as writer: writer.write(TimeUtils.getCurrentTimeUnderline() + " /proc/uptime:" + self.run_adb_cmd("shell cat /proc/uptime") + "\n") self.before_connect = True ret = self.run_adb_cmd('shell', '%s' % cmd, **kwds) # 当 adb 命令传入 sync=False时,ret是Poen对象 if ret == None: logger.error(u'adb cmd failed:%s ' % cmd) return ret
def _activity_monitor_thread(self): activity_title = ("datetime", "current_activity") self.activity_file = os.path.join(RuntimeData.package_save_path, 'current_activity.csv') try: with open(self.activity_file, 'a+') as af: csv.writer(af, lineterminator='\n').writerow(activity_title) except Exception as e: logger.error("file not found: " + str(self.activity_file)) while not self.stop_event.is_set(): try: before = time.time() self.current_activity = self.device.adb.get_current_activity() collection_time = time.time() activity_list = [collection_time, self.current_activity] if self.activity_queue: logger.debug("activity monitor thread activity_list: " + str(activity_list)) self.activity_queue.put(activity_list) if self.current_activity: logger.debug("current activity: " + self.current_activity) if self.main_activity and self.activity_list: if self.current_activity not in self.activity_list: start_activity = self.packagename + "/" + self.main_activity[ random.randint(0, len(self.main_activity) - 1)] logger.debug("start_activity:" + start_activity) self.device.adb.start_activity(start_activity) activity_tuple = (TimeUtils.getCurrentTime(), self.current_activity) # 写文件 try: with open(self.activity_file, 'a+') as writer: writer_p = csv.writer(writer, lineterminator='\n') writer_p.writerow(activity_tuple) except RuntimeError as e: logger.error(e) time_consume = time.time() - before delta_inter = self.interval - time_consume logger.debug("get app activity time consumed: " + str(time_consume)) if delta_inter > 0: time.sleep(delta_inter) except Exception as e: s = traceback.format_exc() logger.debug(s) # 将堆栈信息打印到log中 if self.activity_queue: self.activity_queue.task_done()
def _get_traffic_save(self, traffic_data, timestamp): if isinstance(traffic_data, dict): self.traffic_filename = traffic_data['traffic_file'] logger.debug("dataworker traffic_filename: " + str(self.traffic_filename)) else: try: ''' 0 1 2 3 4 5 6 7 8 9 10 11 traffic_data: ("datetime","packagename","uid","uid_total(KB)", "uid_total_packets", "rx(KB)", "rx_packets","tx(KB)","tx_packets","fg(KB)","bg(KB)","lo(KB)") example: [collection_time, traffic_snapshot.packagename, traffic_snapshot.uid,TrafficUtils.byte2kb(traffic_snapshot.total_uid_bytes), traffic_snapshot.total_uid_packets, TrafficUtils.byte2kb(traffic_snapshot.rx_uid_bytes),traffic_snapshot.rx_uid_packets, TrafficUtils.byte2kb(traffic_snapshot.tx_uid_bytes), traffic_snapshot.tx_uid_packets, TrafficUtils.byte2kb(traffic_snapshot.fg_bytes), TrafficUtils.byte2kb(traffic_snapshot.bg_bytes), TrafficUtils.byte2kb(traffic_snapshot.lo_uid_bytes)] ''' traffic_data[0] = timestamp dic = { "time": traffic_data[0] * 1000, "total": traffic_data[3], "total_packets": traffic_data[4], "rx": traffic_data[5], "rx_packets": traffic_data[6], "tx": traffic_data[7], "tx_packets": traffic_data[8], "fg": traffic_data[9], "bg": traffic_data[10], "lo": traffic_data[11] } self.perf_data['traffic'].append(dic) with open(self.traffic_filename, 'a+') as writer: logger.debug( "write traffic data in dataworker traffic data timestamp: " + str(traffic_data[0])) if isinstance(traffic_data[0], float): traffic_data[0] = TimeUtils.formatTimeStamp( traffic_data[0]) tmp_dic = copy.deepcopy(dic) tmp_dic["time"] = traffic_data[0] logger.debug(tmp_dic) writer_p = csv.writer(writer, lineterminator='\n') # logger.debug("------------------ dataworker trafficdata: " + str(traffic_data)) writer_p.writerow(traffic_data) except Exception as e: logger.error("traffic save error") s = traceback.format_exc() logger.debug(s)
def wait_proc_exit(self, proc_list, timeout=10): '''等待指定进程退出 :param proc_list: 进程名列表 ''' if not isinstance(proc_list, list): logger.error('proc_list参数要求list类型') time0 = time.time() while time.time() - time0 < timeout: flag = True proc_list = self.list_process() for proc in proc_list: if proc['proc_name'] in proc_list: flag = False break if flag == True: return True time.sleep(1) return False
def list_dir(self, dir_path): '''列取目录下文件 文件夹 返回 文件名 列表 ''' result = self.run_shell_cmd('ls -l %s' % dir_path) if not result: return "" result = result.replace('\r\r\n', '\n') if 'No such file or directory' in result: logger.error('文件(夹) %s 不存在' % dir_path) file_list = [] for line in result.split('\n'): items = line.split() # total 180 去掉total这行 if items[0] != "total" and len(items) != 2: file_list.append(items[-1]) return file_list
def _top_cpuinfo(self): self._top_pipe = self.device.adb.run_shell_cmd(self.top_cmd, sync=False) out = self._top_pipe.stdout.read() error = self._top_pipe.stderr.read() if error: logger.error("into cpuinfos error : " + str(error)) return out = str(out, "utf-8") out.replace('\r', '') top_file = os.path.join(RuntimeData.package_save_path, 'top.txt') with open(top_file, "a+", encoding="utf-8") as writer: writer.write(TimeUtils.getCurrentTime() + " top info:\n") writer.write(out + "\n\n") #避免文件过大,超过100M清理 if FileUtils.get_FileSize(top_file) > 100: os.remove(top_file) return PckCpuinfo(self.packages, out, self.sdkversion)
def push_file(self, src_path, dst_path): '''拷贝文件到手机中 :param str src_path: 原文件路径 :param str dst_path: 拷贝到的文件路径 :return: 执行adb push命令的子进程或执行的结果 :rtype: Popen or str ''' file_size = os.path.getsize(src_path) # 处理路径空格,加上双引号 if " " in src_path: src_path = '"' + src_path + '"' for i in range(3): result = self.run_adb_cmd('push', src_path, dst_path, timeout=30) if result.find('No such file or directory') >= 0: logger.error('file:%s not exist' % src_path) if ('%d' % file_size) in result: return result logger.error(u'push file failed:%s' % result)
def getUID(device, pkg): """""" uid = None _cmd = 'dumpsys package %s' % pkg out = device.adb.run_shell_cmd(_cmd) lines = out.replace('\r', '').splitlines() logger.debug("line length:" + str(len(lines))) if len(lines) > 0: for line in lines: if "Unable to find package:" in line: logger.error(" trafficstat: Unable to find package : " + pkg) continue adb_result = re.findall(u'userId=(\d+)', out) if len(adb_result) > 0: uid = adb_result[0] logger.debug("getUid for pck: " + pkg + ", UID: " + uid) else: logger.error(" trafficstat: Unable to find package : " + pkg) return uid
def stop(self): for monitor in self.monitors: try: monitor.stop() except Exception as e: # 捕获所有的异常,防止其中一个monitor的stop操作发生异常退出时,影响其他的monitor的stop操作 logger.error(e) try: if self.logcat_monitor: self.logcat_monitor.stop() except Exception as e: logger.error("stop exception for logcat monitor") logger.error(e) if self.config_dic["monkey"] == "true": self.device.adb.kill_process("com.android.commands.monkey") # 统计测试时长 cost_time = round((float)(time.time() - TimeUtils.getTimeStamp( RuntimeData.start_time, TimeUtils.UnderLineFormatter)) / 3600, 2) self.add_device_info("test cost time:", str(cost_time) + "h") # 根据csv生成excel汇总文件 Report(RuntimeData.package_save_path, self.packages) self.pull_heapdump() self.pull_log_files() # self.memory_analyse() # self.device.adb.bugreport(RuntimeData.package_save_path) os._exit(0)
def _collect_thread_num_thread(self, start_time): end_time = time.time() + self._timeout thread_list_titile = ("datatime", "packagename", "pid", "thread_num") thread_num_file = os.path.join(RuntimeData.package_save_path, 'thread_num.csv') try: with open(thread_num_file, 'a+') as df: csv.writer(df, lineterminator='\n').writerow(thread_list_titile) if self.thread_queue: thread_file_dic = {'thread_file': thread_num_file} self.thread_queue.put(thread_file_dic) except RuntimeError as e: logger.error(e) while not self._stop_event.is_set() and time.time() < end_time: try: before = time.time() logger.debug( "-----------into _collect_thread_num_thread loop, thread is : " + str(threading.current_thread().name)) # 获取pakagename的thread num信息 thread_pck_info = self.get_process_thread_num(self.packagename) logger.debug(thread_pck_info) current_time = TimeUtils.getCurrentTime() if not thread_pck_info: continue else: logger.debug("current time: " + current_time + ", processname: " + thread_pck_info[1] + ", pid: " + str(thread_pck_info[2]) + " thread num: " + str(thread_pck_info[3])) if self.thread_queue: self.thread_queue.put(thread_pck_info) if not self.thread_queue: #为了本地单个文件运行 try: with open(thread_num_file, 'a+') as thread_writer: writer_p = csv.writer(thread_writer, lineterminator='\n') thread_pck_info[0] = current_time writer_p.writerow(thread_pck_info) except RuntimeError as e: logger.error(e) after = time.time() time_consume = after - before delta_inter = self._interval - time_consume logger.debug("time_consume for thread num infos: " + str(time_consume)) if delta_inter > 0: time.sleep(delta_inter) except: logger.error( "an exception hanpend in thread num thread, reason unkown!" ) s = traceback.format_exc() logger.debug(s) if self.thread_queue: self.thread_queue.task_done()
def _get_cpu_save(self, cpu_data, timestamp): if isinstance(cpu_data, dict): self.cpu_filename = cpu_data['cpu_file'] logger.debug("cpu_filename: " + str(self.cpu_filename)) else: try: ''' 0 1 2 3 4 5 6 7 8 9 cpu_data: ("datetime", " cpu_rate%", "user%", "system%", "all_jiffies","packagename", "pid", "uid", "pck_jiffies", "pid_cpu%") 对应的值是:[collection_time, cpu_info.cpu_rate, cpu_info.user_rate, cpu_info.system_rate, cpu_info.cpu_jiffs, cpu_pck_info.pckagename, cpu_pck_info.pid, cpu_pck_info.uid,cpu_pck_info.p_cpu_jiffs, cpu_pck_info.p_cpu_rate], ''' cpu_data[0] = timestamp dic = { "time": cpu_data[0] * 1000, "total": cpu_data[1], "cpu_jiffies": cpu_data[4], "user": cpu_data[2], "sys": cpu_data[3], "pck_jiffies": cpu_data[8], "pid_cpu": cpu_data[9] } self.perf_data['cpu'].append(dic) with open(self.cpu_filename, 'a+') as writer: logger.debug( "write cpu data in dataworker mem timestamp: " + str(cpu_data[0])) cpu_data[0] = TimeUtils.formatTimeStamp(cpu_data[0]) tmp_dic = copy.deepcopy(dic) tmp_dic["time"] = cpu_data[0] logger.debug(tmp_dic) writer_p = csv.writer(writer, lineterminator='\n') # logger.debug("------------------ dataworker cpudate: " + str(cpu_data)) writer_p.writerow(cpu_data) except Exception as e: logger.error('cpu save error') s = traceback.format_exc() logger.error(s)
def _get_power_save(self, power_data, timestamp): if isinstance(power_data, dict): self.power_filename = power_data['power_file'] logger.debug("dataworker power_filename: " + str(self.power_filename)) else: try: ''' 0 1 2 3 4 power_data: ("datetime","level","voltage(V)","tempreture(C)","current(mA)") example: [collection_time, device_power_info.level, device_power_info.voltage, device_power_info.temp, device_power_info.current] ''' power_data[0] = timestamp dic = { "time": power_data[0] * 1000, "level": power_data[1], "vol": power_data[2], "temp": power_data[3], "current": power_data[4] } self.perf_data['power'].append(dic) with open(self.power_filename, 'a+') as writer: logger.debug( "write power data in dataworker。。。。。。 timestamp:" + str(power_data[0])) if isinstance(power_data[0], float): power_data[0] = TimeUtils.formatTimeStamp( power_data[0]) tmp_dic = copy.deepcopy(dic) tmp_dic["time"] = power_data[0] logger.debug(tmp_dic) writer_p = csv.writer(writer, lineterminator='\n') # logger.debug("------------------ dataworker power data: " + str(power_data)) writer_p.writerow(power_data) except Exception as e: logger.error('power save error') s = traceback.format_exc() logger.debug(s)
def _get_mem_save(self, mem_data, timestamp): if isinstance(mem_data, dict): self.mem_filename = mem_data['mem_file'] logger.debug("mem_filename: " + str(self.mem_filename)) else: try: ''' 0 1 2 3 4 5 6 mem_data: ("datatime", "total_ram(KB)", "free_ram(KB)", "pckagename", "pid", "pid_pss(KB)", "pid_alloc_heap(KB)") 对应的值是:[formatTimeStamp(collection_time), cpu_info.cpu_rate, cpu_info.user_rate, cpu_info.system_rate, cpu_info.cpu_jiffs, cpu_pck_info.pckagename, cpu_pck_info.pid, cpu_pck_info.uid,cpu_pck_info.p_cpu_jiffs, cpu_pck_info.p_cpu_rate] ''' mem_data[0] = timestamp dic = { "time": mem_data[0] * 1000, "total": mem_data[1], "free": mem_data[2], "pss": mem_data[5], "heap": mem_data[6] } self.perf_data['mem'].append(dic) with open(self.mem_filename, 'a+') as writer: logger.debug( "write mem data in dataworker。。。。。。 mem timestamp: " + str(mem_data[0])) if isinstance(mem_data[0], float): mem_data[0] = TimeUtils.formatTimeStamp(mem_data[0]) tmp_dic = copy.deepcopy(dic) tmp_dic["time"] = mem_data[0] logger.debug(tmp_dic) writer_p = csv.writer(writer, lineterminator='\n') # logger.debug("------------------ dataworker memdata: " + str(mem_data)) writer_p.writerow(mem_data) except Exception as e: logger.error('mem save error') s = traceback.format_exc() logger.debug(s)
def is_overtime_days(self, filepath, days=7): result = self.run_shell_cmd('ls -l %s' % filepath) if not result: return False result = result.replace('\r\r\n', '\n') if 'No such file or directory' in result: logger.error('文件(夹) %s 不存在' % filepath) return False re_time = re.compile(r'\S*\s+(\d+-\d+-\d+\s+\d+:\d+)\s+\S+') match = re_time.search(result) if match: last_modify_time = match.group(1) logger.debug(last_modify_time) last_modify_timestamp = TimeUtils.getTimeStamp(last_modify_time, "%Y-%m-%d %H:%M") # logger.debug(last_modify_timestamp) if last_modify_timestamp < (time.time() - days * 24 * 60 * 60): logger.debug(filepath + " is overtime days:" + str(days)) return True else: logger.debug(filepath + " is not overtime days:" + str(days)) return False logger.debug(filepath + " not have match time formatter") return False
def _monkey_thread_func(self,save_dir): '''获取monkey线程,保存monkey日志,monkey Crash日志暂不处理,后续有需要再处理 ''' self.append_log_line_num = 0 self.file_log_line_num = 0 self.log_file_create_time = None log_is_none = 0 logs = [] logger.debug("monkey_thread_func") if RuntimeData.start_time is None: RuntimeData.start_time = TimeUtils.getCurrentTime() while self.running: try: log = self._log_pipe.stdout.readline().strip() if not isinstance(log, str): # 先编码为unicode try: log = str(log, "utf8") except Exception as e: log = repr(log) logger.error('str error:' + log) logger.error(e) if log: logs.append(log) self.append_log_line_num = self.append_log_line_num + 1 self.file_log_line_num = self.file_log_line_num + 1 # if self.append_log_line_num > 1000: if self.append_log_line_num > 100: if not self.log_file_create_time: self.log_file_create_time = TimeUtils.getCurrentTimeUnderline() log_file = os.path.join(save_dir, 'monkey_%s.log' % self.log_file_create_time) self.append_log_line_num = 0 # 降低音量,避免音量过大,导致语音指令失败 self.device.adb.run_shell_cmd("input keyevent 25") self.save(log_file, logs) logs = [] # 新建文件 if self.file_log_line_num > 600000: # if self.file_log_line_num > 200: self.file_log_line_num = 0 self.log_file_create_time = TimeUtils.getCurrentTimeUnderline() log_file = os.path.join(save_dir, 'monkey_%s.log' % self.log_file_create_time) self.save(log_file, logs) logs = [] else: log_is_none = log_is_none + 1 if log_is_none % 1000 == 0: logger.info("log is none") if not self.device.adb.is_process_running("com.android.commands.monkey") and self.running: self.device.adb.kill_process("com.android.commands.monkey") self._log_pipe = self.device.adb.run_shell_cmd(self.monkey_cmd, sync=False) except: logger.error("an exception hanpend in monkey thread, reason unkown!") s = traceback.format_exc() logger.debug(s)
def _collect_power_thread(self,start_time): ''' 搜集电池信息的线程 :return: ''' end_time = time.time() + self._timeout power_list_titile = ("datetime","level","voltage(V)","tempreture(C)","current(mA)") power_device_file = os.path.join(RuntimeData.package_save_path, 'powerinfo.csv') try: with open(power_device_file, 'a+') as df: csv.writer(df, lineterminator='\n').writerow(power_list_titile) if self.power_queue: power_file_dic = {'power_file':power_device_file} self.power_queue.put(power_file_dic) except RuntimeError as e: logger.error(e) while not self._stop_event.is_set() and time.time() < end_time: try: before = time.time() logger.debug("------------into _collect_power_thread loop thread is : " + str(threading.current_thread().name)) device_power_info = self._get_battaryproperties() if device_power_info.source == '': logger.debug("can't get power info , break!") break device_power_info = self.trim_data(device_power_info)#debug collection_time = time.time() logger.debug(" collection time in powerconsumption is : " + str(collection_time)) power_tmp_list = [collection_time, device_power_info.level, device_power_info.voltage, device_power_info.temp, device_power_info.current] if self.power_queue: self.power_queue.put(power_tmp_list) if not self.power_queue:#为了本地单个脚本运行 power_tmp_list[0] = TimeUtils.formatTimeStamp(power_tmp_list[0]) try: with open(power_device_file,'a+',encoding="utf-8") as writer: writer_p = csv.writer(writer, lineterminator='\n') writer_p.writerow(power_tmp_list) except RuntimeError as e: logger.error(e) after = time.time() time_consume = after - before delta_inter = self._interval - time_consume if delta_inter > 0: time.sleep(delta_inter) except: logger.error("an exception hanpend in powerconsumption thread , reason unkown!") s = traceback.format_exc() logger.debug(s) if self.power_queue: self.power_queue.task_done()