Esempio n. 1
0
    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)
Esempio n. 2
0
    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
Esempio n. 3
0
 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
Esempio n. 4
0
    def _collect_memory_thread(self, start_time):
        end_time = time.time() + self._timeout
        mem_list_titile = ["datatime", "total_ram(MB)", "free_ram(MB)"]
        pid_list_titile = ["datatime"]
        pss_detail_titile = [
            "datatime", "package", "pid", "pss", "java_heap", "native_heap",
            "system"
        ]
        for i in range(0, len(self.packages)):
            mem_list_titile.extend(["package", "pid", "pid_pss(MB)"])
            pid_list_titile.extend(["package", "pid"])
        if len(self.packages) > 1:
            mem_list_titile.append("total_pss(MB)")
        mem_file = os.path.join(RuntimeData.package_save_path, 'meminfo.csv')
        pid_file = os.path.join(RuntimeData.package_save_path,
                                'pid_change.csv')
        for package in self.packages:
            pss_detail_file = os.path.join(
                RuntimeData.package_save_path,
                'pss_%s.csv' % package.split(".")[-1].replace(":", "_"))
            with open(pss_detail_file, 'a+') as df:
                csv.writer(df, lineterminator='\n').writerow(pss_detail_titile)
        try:
            with open(mem_file, 'a+') as df:
                csv.writer(df, lineterminator='\n').writerow(mem_list_titile)
                if self.mem_queue:
                    mem_file_dic = {'mem_file': mem_file}
                    self.mem_queue.put(mem_file_dic)

            with open(pid_file, 'a+') as df:
                csv.writer(df, lineterminator='\n').writerow(pid_list_titile)
        except RuntimeError as e:
            logger.error(e)
        starttime_stamp = TimeUtils.getTimeStamp(start_time,
                                                 "%Y_%m_%d_%H_%M_%S")
        old_package_pid_pss_list = []
        dumpsys_mem_times = 0
        # D系统上会报错 System server has no access to file context
        # hprof_path = "/sdcard/hprof"
        hprof_path = "/data/local/tmp"
        self.device.adb.run_shell_cmd("mkdir " + hprof_path)
        # sdcard 卡目录下dump需要打开这个开关
        self.device.adb.run_shell_cmd("setenforce 0")
        first_dump = True
        while not self._stop_event.is_set() and time.time() < end_time:
            try:
                before = time.time()
                logger.debug(
                    "-----------into _collect_mem_thread loop, thread is : " +
                    str(threading.current_thread().name))
                collection_time = time.time()
                # # 获取主进程的详细信息
                for package in self.packages:
                    mem_pck_snapshot = self._dumpsys_process_meminfo(package)
                    if 0 == mem_pck_snapshot.totalPSS:
                        logger.error("package total pss is 0:%s" % package)
                        continue
                    pss_detail_file = os.path.join(
                        RuntimeData.package_save_path, 'pss_%s.csv' %
                        package.split(".")[-1].replace(":", "_"))
                    pss_detail_list = [
                        TimeUtils.formatTimeStamp(collection_time), package,
                        mem_pck_snapshot.pid, mem_pck_snapshot.totalPSS,
                        mem_pck_snapshot.javaHeap, mem_pck_snapshot.nativeHeap,
                        mem_pck_snapshot.system
                    ]
                    with open(pss_detail_file, 'a+') as pss_writer:
                        writer_p = csv.writer(pss_writer, lineterminator='\n')
                        writer_p.writerow(pss_detail_list)
                #         写到pss_detail表格中

                # 手机每5分钟 dumpheap一次
                if (before - starttime_stamp) > 300 or first_dump:
                    #     先清理hprof文件
                    filelist = self.device.adb.list_dir(hprof_path)
                    if filelist:
                        for file in filelist:
                            for package in self.packages:
                                if package in file:
                                    self.device.adb.delete_file(hprof_path +
                                                                "/" + file)
                # if (before - starttime_stamp) % 60 < self._interval and "D" in self.device.adb.get_system_version():
                    for package in self.packages:
                        self.device.adb.dumpheap(package,
                                                 RuntimeData.package_save_path)
                    starttime_stamp = before
                    # self.device.adb.run_shell_cmd("kill -10 %s"%str(mem_pck_snapshot.pid))
                # dumpsys meminfo 耗时长,可能会导致system server cpu占用变高,降低采集频率
                dumpsys_mem_times = dumpsys_mem_times + 1
                # 10倍率frequency dumpsys meminfo一次
                if dumpsys_mem_times % 10 == 0 or first_dump:
                    mem_device_snapshot = self._dumpsys_meminfo()
                    # 如果没有采集到dumpsys meminfo的信息,正常情况totalmem不可能为0
                    if mem_device_snapshot == None or not mem_device_snapshot.package_pid_pss_list or mem_device_snapshot.totalmem == 0:
                        logger.error("mem_device_snapshot is none")
                        # 如果获取不到结果,继续延长采集间隔
                        dumpsys_mem_times = dumpsys_mem_times - 1
                        continue
                    first_dump = False
                    logger.debug("current time: " +
                                 TimeUtils.getCurrentTime() +
                                 ", processname: " + ",total pss:" +
                                 str(mem_device_snapshot.total_pss))
                    logger.debug("collection time in meminfo is : " +
                                 TimeUtils.getCurrentTime())
                    gather_list = [
                        TimeUtils.formatTimeStamp(collection_time),
                        mem_device_snapshot.totalmem,
                        mem_device_snapshot.freemem
                    ]
                    pid_list = [TimeUtils.formatTimeStamp(collection_time)]
                    pid_change = False
                    for i in range(0, len(self.packages)):
                        if len(mem_device_snapshot.package_pid_pss_list
                               ) == len(self.packages):
                            gather_list.extend([
                                mem_device_snapshot.package_pid_pss_list[i]
                                ["package"],
                                mem_device_snapshot.package_pid_pss_list[i]
                                ["pid"],
                                mem_device_snapshot.package_pid_pss_list[i]
                                ["pss"]
                            ])
                    if not old_package_pid_pss_list:
                        old_package_pid_pss_list = mem_device_snapshot.package_pid_pss_list
                        pid_change = True
                    else:
                        for i in range(0, len(self.packages)):
                            package = mem_device_snapshot.package_pid_pss_list[
                                i]["package"]
                            if mem_device_snapshot.package_pid_pss_list[i]["pid"] and \
                                    old_package_pid_pss_list[i]["pid"]!=mem_device_snapshot.package_pid_pss_list[i]["pid"]:
                                pid_change = True
                                # 确保上次pid也有
                                if old_package_pid_pss_list[i]["pid"]:
                                    if package and package in RuntimeData.config_dic[
                                            "pid_change_focus_package"]:
                                        # 确保有tombstones文件才提单
                                        self.device.adb.pull_file(
                                            "/data/vendor/tombstones",
                                            RuntimeData.package_save_path)
                    if pid_change:
                        old_package_pid_pss_list = mem_device_snapshot.package_pid_pss_list
                        for i in range(0, len(self.packages)):
                            if len(old_package_pid_pss_list) == len(
                                    self.packages):
                                pid_list.extend([
                                    old_package_pid_pss_list[i]["package"],
                                    old_package_pid_pss_list[i]["pid"]
                                ])
                        try:
                            with open(pid_file, 'a+') as pid_writer:
                                writer_p = csv.writer(pid_writer,
                                                      lineterminator='\n')
                                writer_p.writerow(pid_list)
                                logger.debug("write to file:" + pid_file)
                                logger.debug(pid_list)
                        except RuntimeError as e:
                            logger.error(e)
                    if len(self.packages) > 1:
                        gather_list.append(mem_device_snapshot.total_pss)
                    if self.mem_queue:
                        gather_list[0] = collection_time
                        self.mem_queue.put(gather_list)
                    if not self.mem_queue:  #为了本地单个文件运行
                        try:
                            with open(mem_file, 'a+') as mem_writer:
                                writer_p = csv.writer(mem_writer,
                                                      lineterminator='\n')
                                writer_p.writerow(gather_list)
                                logger.debug("write to file:" + mem_file)
                                logger.debug(gather_list)
                        except RuntimeError as e:
                            logger.error(e)

                after = time.time()
                time_consume = after - before
                delta_inter = self._interval - time_consume
                logger.info("time consume for meminfos: " + str(time_consume))
                if delta_inter > 0:
                    time.sleep(delta_inter)
            except:
                logger.error(
                    "an exception hanpend in meminfo thread, reason unkown!")
                s = traceback.format_exc()
                logger.debug(s)
                if self.mem_queue:
                    self.mem_queue.task_done()

        logger.debug("stop event is set or timeout")