Exemple #1
0
def init_ui_task_queue():
    db = DBTool().initGlobalDBConf()
    # DONE 初始化 taskrun  {'do': 3, 'TaskExecuteId': '1'}
    colsStr = "id"
    tbName = "tb_ui_test_execute"
    whereStr = "execStatus = %d or execStatus = %d " % (ExecStatus.NOTRUN, ExecStatus.RUNNING)
    orderBy = "addTime asc"
    sql = "select %s from %s where %s order by %s" % (colsStr, tbName, whereStr, orderBy)
    res = db.execute_sql(sql)
    #重置所有模拟器
    mobileServer = db.execute_sql("UPDATE tb_ui_mobile_server SET STATUS = 0")

    db.release()
    logging.debug("init_ui_task_queue: 初始化tb_ui_test_execute结果:%s" % str(res))
    if res == False:
        logging.error("init_ui_task_queue: 初始化任务执行队列失败!")
        return False
    if mobileServer == False:
        logging.error("init_ui_task_queue: 初始化模拟器状态失败!")
        return False
    for tRes in res:
        tmpData = {}
        tmpData[Do.KEY_DO] = Do.TYPE_UITASK_EXECUTE
        tmpData[Do.KEY_UITASK_EXEC_ID] = tRes['id']
        uiTaskQueue.append(tmpData)
        logging.info("init_ui_task_queue: uiTaskQueue加入新data:%s 。来源表:%s" % (tmpData, tbName))
        logging.info("init_ui_task_queue: uiTaskQueue:%s" % uiTaskQueue)

    logging.info("init_ui_task_queue: 初始化任务执行表完成uiTaskQueue:%s" % uiTaskQueue)
Exemple #2
0
    def generate_http_conf_by_key(self):
        """
        通过key从数据库获取配置的信息。
        Returns:执行结果

        """
        db = DBTool().initGlobalDBConf()
        colstr = "id, httpConfKey, serviceConfKey, alias, httpConfDesc, state, addBy, modBy, addTime, modTime"
        sql = """ SELECT %s FROM tb_config_http where httpConfKey = '%s' """ % (colstr,self.key)
        res = db.execute_sql(sql,auto_release=True)
        db.release()
        if res:
            tmpConf = res[0]
            self.id = tmpConf['id']
            self.alias = tmpConf['alias']
            self.desc = tmpConf['httpConfDesc']
            self.state = tmpConf['state']
            self.addBy = tmpConf['addBy']
            self.modBy = tmpConf['modBy']
            self.addTime = tmpConf['addTime']
            self.modTime = tmpConf['modTime']

            # httpConfStr = tmpConf['httpConf']
            # self.confDict = Config().getConfDictByString(httpConfStr)
            self.confServiceLayer.key = tmpConf['serviceConfKey']
            return self.confServiceLayer.generate_service_conf_by_key()
        else:
            return False
    def generate_service_conf_by_key(self):
        """
        通过key从数据库获取对应的service配置信息。
        Returns:执行结果,True False

        """
        clostr = "id, serviceConfKey, alias, serviceConfDesc, serviceConf, state, addBy, modBy, addTime, modTime"
        sql = """select %s from tb_config_service where serviceConfKey = '%s'""" % (
            clostr, self.key)
        db = DBTool().initGlobalDBConf()
        res = db.execute_sql(sql, auto_release=True)
        db.release()
        if res:
            tmpConf = res[0]
            self.id = tmpConf['id']
            self.key = tmpConf['serviceConfKey']
            self.alias = tmpConf['alias']
            self.desc = tmpConf['serviceConfDesc']
            self.state = tmpConf['state']
            self.addBy = tmpConf['addBy']
            self.modBy = tmpConf['modBy']
            self.addTime = tmpConf['addTime']
            self.modTime = tmpConf['modTime']

            serviceConfStr = tmpConf['serviceConf']
            # self.confDict = Config().getConfDictByString(serviceConfStr)
            self.confDict = json.loads(serviceConfStr)
            return True
        else:
            return False
Exemple #4
0
def cancelTaskSuite(dataDict):
    try:
        redisCache = RedisTool()
        redisCache.initRedisConf()

        db = DBTool()
        db.initGlobalDBConf()

        # taskExecStatus = json.loads(redisCache.get_data("%s_taskSuite_%s_task_%s" % (dataDict[Do.TYPE_PROTOCOL],dataDict[Do.KEY_TASK_SUITE_EXECUTE_ID], dataDict[Do.KEY_TASK_EXECUTE_ID])))
        # taskExecStatus["execStatus"] = ExecStatus.CANCELED
        # redisCache.set_data("%s_taskSuite_%s_task_%s" % (dataDict[Do.TYPE_PROTOCOL],dataDict[Do.KEY_TASK_SUITE_EXECUTE_ID], dataDict[Do.KEY_TASK_EXECUTE_ID]),json.dumps(taskExecStatus),60*60*12)
        redisCache.del_data("%s_taskSuite_%s_task_%s" % (dataDict[Do.TYPE_PROTOCOL],dataDict[Do.KEY_TASK_SUITE_EXECUTE_ID], dataDict[Do.KEY_TASK_EXECUTE_ID]))

    finally:
    #将任务集设置为已取消
        if dataDict[Do.TYPE_PROTOCOL] == Protocol.HTTP_PROTOCOL:
            db.execute_sql("UPDATE tb_task_suite_execute SET execStatus = '%s' where id = %s" % (ExecStatus.CANCELED,dataDict[Do.KEY_TASK_SUITE_EXECUTE_ID]))
        elif dataDict[Do.TYPE_PROTOCOL] == Protocol.DUBBO_PROTOCOL:
            db.execute_sql("UPDATE tb2_dubbo_task_suite_execute SET execStatus = '%s' where id = %s" % (ExecStatus.CANCELED, dataDict[Do.KEY_TASK_SUITE_EXECUTE_ID]))
        db.release()
Exemple #5
0
def init_global_queue(taskQueueList,taskCancelQueueList):
    # taskQueue.put([])
    # taskCancelQueue.put([])
    # serviceListQueue.put([])
    redis = RedisTool()
    redis.initRedisConf()
    db = DBTool()
    db.initGlobalDBConf()
    #启动时将所有执行服务器设置为离线
    db.execute_sql("UPDATE tb_run_server_conf SET STATUS = 0 ")
    #======加入未执行的接口调试 数据表tb_http_interface_debug
    # init_debug_queue_interface(db)
    # init_debug_queue_case(db)
    init_task_queue(db,redis,taskQueueList)
    init_task_cancel_queue(db,redis,taskCancelQueueList)
    init_dubbo_task_queue(db,taskQueueList)
    init_dubbo_task_cancel_queue(db,taskCancelQueueList)
    init_task_suite_queue(db,"HTTP")
    init_task_suite_queue(db,"DUBBO")
    db.release()
Exemple #6
0
    def getSelfKeywordDict():
        selfKwList = []
        selfKwDict = {}
        db = DBTool().initGlobalDBConf()
        kwDictList = db.execute_sql(
            "SELECT keywordKey,keywordCode FROM tb4_data_keyword WHERE status = 3 AND state =1 AND type='DATA_KEYWORD' ORDER BY id"
        )
        for tmpDict in kwDictList:
            selfKwList.append(tmpDict['keywordKey'])
            selfKwDict[tmpDict['keywordKey']] = tmpDict['keywordCode']

        selfKwList = SelfKeywordProcesser.sortKwKeyList(selfKwList)
        db.release()
        return selfKwList, selfKwDict
Exemple #7
0
def init_cancel_ui_task_queue():
    db = DBTool().initGlobalDBConf()
    # DONE 初始化 taskrun  {'do': 3, 'TaskExecuteId': '1'}
    colsStr = "id"
    tbName = "tb_ui_test_execute"
    whereStr = "execStatus = %d " % (ExecStatus.CANCELING)
    orderBy = "addTime asc"
    sql = "select %s from %s where %s order by %s" % (colsStr, tbName, whereStr, orderBy)
    res = db.execute_sql(sql)
    db.release()
    logging.debug("init_cancel_ui_task_queue: 初始化tb_ui_test_execute结果:%s" % str(res))
    if res == False:
        logging.error("init_cancel_ui_task_queue: 初始化任务执行队列失败!")
        return False
    for tRes in res:
        tmpData = {}
        tmpData[Do.KEY_DO] = Do.TYPE_UITASK_CANCEL
        tmpData[Do.KEY_UITASK_EXEC_ID] = tRes['id']
        uiTaskCancelQueue.append(tmpData)
        logging.info("init_cancel_ui_task_queue: uiTaskCancelQueue加入新data:%s 。来源表:%s" % (tmpData, tbName))
        logging.info("init_cancel_ui_task_queue: uiTaskCancelQueue:%s" % uiTaskCancelQueue)

    logging.info("init_cancel_ui_task_queue: 初始化任务执行表完成uiTaskCancelQueuee:%s" % uiTaskCancelQueue)
class UITestTask(object):

    reportFileName = "report.html"
    logFileName = "report.log"
    pickleFileName = "unquitdriverlist.pkl"

    def __init__(self):
        #基本信息
        self.id = 0
        self.taskExecuteId = 0

        self.taskId = ""
        self.title = ""
        self.taskdesc = ""
        self.businessLineId = ""
        self.businessLineName = ""
        self.moduleId = ""
        self.moduleName = ""
        self.sourceGroup = ""

        self.fileName = ""
        self.fileAddBy = ""
        self.sheetName = ""
        self.httpConfKey = ""
        self.reportDir = ""

        self.packageId = ""
        self.serverId = ""
        #执行信息
        self.execStatus = 1  # 1 新建排队中未执行 2执行中 3执行完成 4执行异常
        self.execCommand = ""
        self.execStartTime = ""
        self.execEndTime = ""
        self.execTakeTime = ""
        self.execProgressString = ""
        #执行结果信息
        self.testResult = ""
        self.testResultMessage = ""

        self.execComments = ""
        self.isSendEmail = 0
        self.emailList = ""

        #通用信息
        self.state = 1
        self.addBy = ""
        self.modBy = ""
        self.addTime = ""
        self.modTime = ""

        self.globalDB = DBTool()

    def generateByTaskExecuteId(self):
        self.globalDB.initGlobalDBConf()
        self.taskExecuteId = int(self.taskExecuteId)
        sqlTasExec = "select * from tb_ui_test_execute where id=%d" % int(
            self.taskExecuteId)
        resTaskExec = self.globalDB.execute_sql(sqlTasExec)
        if resTaskExec:
            tmpResTaskInfo = resTaskExec[0]
            self.id = tmpResTaskInfo['id']

            self.taskId = tmpResTaskInfo['taskId']
            self.title = tmpResTaskInfo['title']
            self.taskdesc = tmpResTaskInfo['taskdesc']
            self.businessLineId = tmpResTaskInfo['businessLineId']
            self.moduleId = tmpResTaskInfo['moduleId']
            self.sourceGroup = tmpResTaskInfo['sourceGroup']

            self.fileName = tmpResTaskInfo['fileName']
            self.fileAddBy = tmpResTaskInfo["fileAddBy"]
            self.sheetName = tmpResTaskInfo['sheetName']
            self.httpConfKey = tmpResTaskInfo['httpConfKey']
            self.reportDir = tmpResTaskInfo['reportDir'].strip()
            self.addBy = tmpResTaskInfo['addBy']

            self.packageId = tmpResTaskInfo['packageId'].strip()
            self.serverId = tmpResTaskInfo["serverId"]

            self.execComments = tmpResTaskInfo['execComments']
            self.isSendEmail = int(tmpResTaskInfo['isSendEmail'])
            self.emailList = tmpResTaskInfo['emailList']

            self.testResult = tmpResTaskInfo['testResult']
            self.execStatus = tmpResTaskInfo['execStatus']

            self.generateBusinessLineAndModuleName()
        else:
            self.taskExecuteId = -1
        self.globalDB.release()

    def generateBusinessLineAndModuleName(self):
        self.globalDB.connect()
        businessLineDict = self.globalDB.execute_sql(
            "select * from tb_business_line where id=%d" %
            (int(self.businessLineId)))
        moduleDict = self.globalDB.execute_sql(
            "select * from tb_modules where id=%d" % (int(self.moduleId)))
        self.globalDB.release()
        self.businessLineName = businessLineDict[0]['bussinessLineName']
        self.moduleName = moduleDict[0]['moduleName']

    def getPackageInfo(self):
        self.globalDB.connect()
        packageInfo = self.globalDB.execute_sql(
            "select * from tb_ui_package where packageId='%s'" %
            self.packageId)
        if packageInfo:
            return packageInfo[0]
        else:
            return False

    def bindTaskMobileServer(self, taskExecuteId, serverId):
        self.globalDB.connect()
        self.globalDB.execute_sql(
            "UPDATE tb_ui_test_execute SET serverId = %s WHERE id = %s" %
            (taskExecuteId, serverId))

    def getDevice(self, serverType):
        self.globalDB.connect()
        if serverType.lower() == "android":
            typeKey = 1
        elif serverType.lower() == "ios":
            typeKey = 2
        mobileServer = self.globalDB.execute_sql(
            "select * from tb_ui_mobile_server where state = 1 and status = 0 and serverType = %s"
            % typeKey)
        if mobileServer:
            self.serverId = mobileServer[0]["id"]
            self.globalDB.execute_sql(
                "UPDATE tb_ui_mobile_server SET STATUS = 1 WHERE id = %s" %
                mobileServer[0]["id"])
            self.globalDB.execute_sql(
                "UPDATE tb_ui_test_execute SET serverId = %s WHERE id = %s" %
                (mobileServer[0]["id"], self.taskExecuteId))
            return mobileServer[0]
        else:
            return False

    def resetAppiumServer(self):
        self.globalDB.connect()
        if self.serverId != 0:
            self.globalDB.execute_sql(
                "update tb_ui_mobile_server set status=0 where id=%d" %
                (int(self.serverId)))

    def execute(self):
        if self.taskExecuteId == -1:
            self.execStatus = 4
            self.setExecStatus()
            return

        self.execStatus = 2
        if self.reportDir.strip() == "":
            self.reportDir = "%s_%s" % (self.taskExecuteId,
                                        get_current_time_YYYYMMDD_HHMMSS())
        self.execStartTime = get_current_time()
        self.testResult = ResultConst.NOTRUN
        self.saveToDB()
        taskExecStartTimestamp = time.time()
        reportBaseDir = "%s/static/ui_test/reports/%s/" % (
            EnvConfig.WEB_ROOT, self.reportDir)  # 必须有/结尾
        excelBaseDir = "%s/ui_file_uploads/%s" % (EnvConfig.WEB_ROOT,
                                                  self.fileAddBy)

        appParamString = ""
        if self.packageId != "":
            #设置定制的appParamString
            pacInfo = self.getPackageInfo()
            if pacInfo:
                if pacInfo['packageType'] == 1:
                    #android
                    appUrl = "%s/static/ui_test/app_uploads/%s/%s" % (
                        EnvConfig.WEB_URI, pacInfo['addBy'],
                        pacInfo['appFileName'])
                    appParamString = "--app=%s--appPackage=%s--appActivity=%s" % (
                        appUrl, pacInfo['appPackage'], pacInfo['appActivity'])
                elif pacInfo['packageType'] == 2:
                    # iPhone
                    appUrl = "%s/static/ui_test/app_uploads/%s/%s" % (
                        EnvConfig.WEB_URI, pacInfo['addBy'],
                        pacInfo['appFileName'])
                    appParamString = "--app=%s--bundleId=%s" % (
                        appUrl, pacInfo['bundleId'])
                elif pacInfo['packageType'] == 3:
                    # iPad
                    appUrl = "%s/static/ui_test/app_uploads/%s/%s" % (
                        EnvConfig.WEB_URI, pacInfo['addBy'],
                        pacInfo['appFileName'])
                    appParamString = "--app=%s--bundleId=%s" % (
                        appUrl, pacInfo['bundleId'])

        execAnfReportParamInfoStr = "--filepath=%s/%s--sheetName=%s--httpConfKey=%s--reportFolder=%s" % (
            excelBaseDir, self.fileName, self.sheetName, self.httpConfKey,
            reportBaseDir)

        dbParamInfoStr = "--dbMode=true--dbHost=%s--dbPort=%s--dbUsername=%s--dbPassword=%s--dbName=%s--dbTaskExecuteId=%d" % (
            DBConf.dbHost, DBConf.dbPort, DBConf.dbUsername, DBConf.dbPassword,
            DBConf.dbName, int(self.taskExecuteId))
        driverConfigConfStr = "--driverConfigPath=%s/RobotUiTest/DriverConfig.conf" % EnvConfig.PLATFORM_ROOT
        #如果不是app
        if self.sourceGroup == webTypeKey:
            logging.debug("web任务!")
            if isReleaseEnv:
                driverConfigConfStr = "%s--ip=%s--port=%s" % (
                    driverConfigConfStr, driverConfDict["hub"]["ip"],
                    driverConfDict["hub"]["port"])
            logging.debug("driverConfigConfStr %s" % driverConfigConfStr)
        if self.sourceGroup == androidTypeKey:
            logging.debug("android任务!")
            androidServer = self.getDevice("Android")
            if androidServer:
                logging.debug("发现Android设备 %s " % androidServer["id"])
                self.bindTaskMobileServer(self.taskExecuteId,
                                          androidServer["id"])
                appParamString = "%s--ip=%s--port=%s--udid=%s--deviceName=%s" % (
                    appParamString, androidServer["serverIp"],
                    androidServer["serverPort"], androidServer["udid"],
                    androidServer["deviceName"])
            else:
                #这就是没有获取到模拟器
                logging.error("没有发现Android设备 ")
                self.testResultMessage = "没获取到模拟器"
                self.execStatus = 4
                self.setExecStatus()
                self.globalDB.release()
        if self.sourceGroup == iosTypeKey:
            logging.debug("ios任务!")
            iosServer = self.getDevice("IOS")
            if iosServer:
                logging.debug("发现ios设备 %s " % iosServer["id"])
                self.bindTaskMobileServer(self.taskExecuteId, iosServer["id"])
                appParamString = "%s--ip=%s--port=%s--udid=%s--deviceName=%s--wdaLocalPort=%s" % (
                    appParamString, iosServer["serverIp"],
                    iosServer["serverPort"], iosServer["udid"],
                    iosServer["deviceName"], iosServer["wdaLocalPort"])
            else:
                #这就是没有获取到模拟器
                logging.error("没获取到ios设备 ")
                self.testResultMessage = "没获取到模拟器"
                self.execStatus = 4
                self.setExecStatus()
                self.globalDB.release()
        # if self.sourceGroup == iosTypeKey:
        #     appParamString = "%s--ip=%s--port=%s--udid=%s" % (appParamString,"10.10.20.229","9966","127.0.0.1:21503")
        pythoneExecuteString = "python3 %s/test_run/runUITest.py --print=0%s%s%s%s" % (
            EnvConfig.UI_FRAMEWORK_ROOT, execAnfReportParamInfoStr,
            dbParamInfoStr, driverConfigConfStr, appParamString)

        print(pythoneExecuteString)
        if isLinuxSystem():
            order = "%s > /dev/null 2>&1 " % pythoneExecuteString
        else:
            order = "start /b %s " % pythoneExecuteString
        logging.debug(order)
        self.execCommand = "python3 runUITest.py %s%s" % (
            execAnfReportParamInfoStr, appParamString)  #去掉数据库等敏感信息
        self.saveToDB()
        try:
            os.popen(order)
        except Exception as e:
            logging.error("发生执行异常")
            self.globalDB.release()
        #开始循环判断执行状态,如果状态是结束,那么结束。a d
        try:
            self.globalDB.initGlobalDBConf()
            while True:
                res = self.globalDB.execute_sql(
                    "select * from tb_ui_test_execute where id=%d" %
                    (int(self.taskExecuteId)))
                if res:
                    resUITaskDict = res[0]
                    self.execStatus = resUITaskDict['execStatus']
                    if self.execStatus == 2:
                        #如果在执行中,等待一会。
                        time.sleep(1)
                        continue
                    else:
                        #如果不是执行中,那就是框架反写到数据库中执行状态执行结束了。
                        self.testResult = resUITaskDict['testResult']
                        self.testResultMessage = resUITaskDict[
                            'testResultMessage']
                        #判断如果使用了模拟器把模拟器设为可用
                        break
                else:
                    #如果没有找到对应的执行状态,报异常。
                    self.execStatus = 4
                    self.testResult = ResultConst.EXCEPTION
                    self.testResultMessage = "执行异常,没有找到任务执行数据!"
                    self.saveToDB()
        finally:
            self.execEndTime = get_current_time()
            taskExecEndTimestamp = time.time()
            self.execTakeTime = str(taskExecEndTimestamp -
                                    taskExecStartTimestamp)
            self.saveExecEndTimeAndTaskTakeTimeToDB()
            if self.isSendEmail > 0:
                self.sendEmailToExecutor()
            if self.serverId != 0:
                self.resetAppiumServer()
            self.globalDB.release()

    def setExecStatus(self):
        self.globalDB.initGlobalDBConf()
        self.taskExecuteId = int(self.taskExecuteId)
        sqlTasExec = "update tb_ui_test_execute set execStatus=%d where id=%d" % (
            self.execStatus, int(self.taskExecuteId))
        resTaskExec = self.globalDB.execute_update_sql(sqlTasExec)
        self.globalDB.release()

    def saveReportDirToDB(self):
        self.globalDB.initGlobalDBConf()
        self.taskExecuteId = int(self.taskExecuteId)
        sqlTasExec = "update tb_ui_test_execute set reportDir='%s' where id=%d" % (
            self.reportDir, int(self.taskExecuteId))
        resTaskExec = self.globalDB.execute_update_sql(sqlTasExec)
        self.globalDB.release()

    def saveProgressToDB(self):
        self.globalDB.initGlobalDBConf()
        self.taskExecuteId = int(self.taskExecuteId)
        sqlTasExec = "update tb_ui_test_execute set execProgressString='%s' where id=%d" % (
            self.execProgressString, int(self.taskExecuteId))
        resTaskExec = self.globalDB.execute_update_sql(sqlTasExec)
        self.globalDB.release()

    def saveExecEndTimeAndTaskTakeTimeToDB(self):
        self.globalDB.initGlobalDBConf()
        self.taskExecuteId = int(self.taskExecuteId)
        saveAttrString = "execStatus=%d," % self.execStatus
        if self.execEndTime != "":
            saveAttrString += "execEndTime = '%s'," % self.execEndTime
        if self.execTakeTime != "":
            saveAttrString += "execTakeTime = '%s'," % self.execTakeTime
        try:
            if saveAttrString != "":
                saveAttrString = saveAttrString[:-1]
                sqlTasExec = "update tb_ui_test_execute set %s where id=%d" % (
                    saveAttrString, int(self.taskExecuteId))
                res = self.globalDB.execute_update_sql(sqlTasExec)
                return res
            else:
                return False
        finally:
            self.globalDB.release()

    def cancelTask(self):
        try:
            logging.debug("当前执行状态:%s" % self.execStatus)
            if self.execStatus == 2 or self.execStatus == 10:
                if self.serverId != 0:
                    self.resetAppiumServer()
                reportBaseDir = "%s/static/ui_test/reports/%s/" % (
                    EnvConfig.WEB_ROOT, self.reportDir)  # 必须有/结尾
                reportFileRealPath = "%s%s" % (reportBaseDir,
                                               UITestTask.reportFileName)
                pickleFileRealPath = "%s%s" % (reportBaseDir,
                                               UITestTask.pickleFileName)

                #STEP1 杀进程
                if isLinuxSystem():
                    #linux下杀进程
                    getPidCommand = "ps -ef |grep %s |grep -v grep |grep -v /dev/null" % reportBaseDir
                    logging.debug(getPidCommand)
                    pidPopenRes = os.popen(getPidCommand)
                    pidOutput = pidPopenRes.read().strip()
                    logging.debug(pidOutput)
                    retResList = pidOutput.split(" ")
                    logging.debug(retResList)
                    pidTobeKilled = 0
                    for tmpPid in retResList:
                        if isInt(tmpPid.strip()):
                            pidTobeKilled = int(tmpPid.strip())
                            break
                    logging.debug("PidTobeKilledInLinux:%d" % pidTobeKilled)
                    if pidTobeKilled > 0:
                        killRes = os.popen("kill -9 %d" % pidTobeKilled)
                        killOutputStr = killRes.read()
                        logging.info("进程[%d]killed!%s" %
                                     (pidTobeKilled, killOutputStr))
                else:
                    #windows下杀进程
                    getPidCommand = """wmic process where caption="python3.exe" get handle,caption,commandline /value"""
                    pidRes = os.popen(getPidCommand)
                    outPidTaskString = pidRes.read()
                    handleStringList = outPidTaskString.split("Handle=")
                    for i in range(0, len(handleStringList)):
                        if reportBaseDir in handleStringList[i]:
                            realWindowsPid = get_sub_string(
                                handleStringList[i + 1], "", "\n").strip()
                            if isInt(realWindowsPid):
                                killRes = os.popen("taskkill /pid %s -f" %
                                                   realWindowsPid)
                                kilResOutput = killRes.read()
                                logging.info("进程[%s]killed!%s" %
                                             (realWindowsPid, kilResOutput))
                # step3 更新状态先更新状态再ui出driver,因为退出driver比较慢。
                self.execStatus = 11
                self.testResult = "CANCEL"
                self.saveToDB()
                #STEP2退出未推出的driver
                try:
                    # 反序列化退出所有有效的driver
                    if os.path.exists(pickleFileRealPath) and os.path.isfile(
                            pickleFileRealPath):
                        logging.info("任务【%s】取消,发现pickle文件!" %
                                     self.taskExecuteId)
                        # 先判断有没有pkl文件
                        #存在pkl,进行退出
                        with open(pickleFileRealPath, 'rb') as f:
                            aa = pickle.load(f)
                        for tmpDriver in aa:
                            try:
                                tmpDriver.quit()
                                logging.info("WebDriver quited!")
                            except Exception as e:
                                logging.info(
                                    "WebDriver unquited! Exception occured when quit!"
                                )
                                logging.debug(traceback.format_exc())

                        os.remove(pickleFileRealPath)
                    else:
                        logging.info("任务【%s】取消,没有发现pickle文件!" %
                                     self.taskExecuteId)
                except Exception as e:
                    logging.error(str(e))

            return True
        except Exception as e:
            return False
        finally:
            self.globalDB.release()

    def saveToDB(self):
        self.globalDB.initGlobalDBConf()
        self.taskExecuteId = int(self.taskExecuteId)
        saveAttrString = "execStatus=%d," % self.execStatus
        if self.reportDir != "":
            saveAttrString += "reportDir = '%s'," % self.reportDir
        if self.execStartTime != "":
            saveAttrString += "execStartTime = '%s'," % self.execStartTime
        if self.execEndTime != "":
            saveAttrString += "execEndTime = '%s'," % self.execEndTime
        if self.execTakeTime != "":
            saveAttrString += "execTakeTime = '%s'," % self.execTakeTime
        if self.execProgressString != "":
            saveAttrString += "execProgressString = '%s'," % self.execProgressString
        if self.testResult != "":
            saveAttrString += "testResult = '%s'," % self.testResult
        if self.testResultMessage != "":
            saveAttrString += "testResultMessage = '%s'," % self.testResultMessage
        if self.execCommand != "":
            saveAttrString += "execCommand = '%s'," % self.execCommand
        try:
            if saveAttrString != "":
                saveAttrString = saveAttrString[:-1]
                sqlTasExec = "update tb_ui_test_execute set %s where id=%d" % (
                    saveAttrString, int(self.taskExecuteId))
                res = self.globalDB.execute_update_sql(sqlTasExec)
                return res
            else:
                return False
        finally:
            self.globalDB.release()

    def sendEmailToExecutor(self):
        self.globalDB.initGlobalDBConf()
        res = self.globalDB.execute_sql(
            "select email from tb_user where loginName='%s' " % self.addBy)
        self.globalDB.release()
        resEmailList = self.emailList
        print("self.emailList", self.emailList)
        if res:
            # emailList = "%s" % res[0]['email']  # ;分号间隔
            emailList = ""  # ;分号间隔

            if resEmailList.strip() != "":
                resEmList = resEmailList.split(",")
                for tmpMail in resEmList:
                    emailList = emailList + ";" + tmpMail
                # emailList = emailList + ";[email protected]"

            subject = "[%s]UI任务[%s:%s]测试报告" % (self.testResult, self.taskId,
                                               self.title)

            # 开始生成emailText的html###############################################################################
            """
(一)测试报告概况:
任务ID:HTTP_TASK_62
执行环境:预发布灰度
执行结果:FAIL
执行耗时:36秒
任务名称:SFA-CPQ团队-自动化测试【staging灰度环境】
任务描述:(1)【产品】PC端和APP端 (2)【价格表】&【价格表明细】PC端和APP端(3)【合同】PC端和APP端
包含ywx:['SFA']
包含mk:['产品', '合同', '价格表']
备注:在jenkins上执行自动化测试任务

所有统计:

(1)用例统计:用例总数10个,通过7,失败3,通过率70%。【说明:因为任务中的用例都会被执行,通过率 = 通过数量 / 总数量】
(2)接口统计:接口总数500个,通过400个,失败50个,未执行50个,通过率80%。【说明:接口总数包含独立接口和用例接口之和。因为用例的靠前的接口可能失败,靠后的接口不会被执行,通过率定义方式大家可以多提建议。通过率 =  通过数量 / 总数量】
(二)失败的所有接口汇总:【说明:包含独立接口和用例接口】
(1)mk:【产品】
接口[/json/crm_product/save.action]:已执行4次,通过0,失败4,通过率0.00%。
(2)mk:【合同】
接口[/mobile/common/search.action]:已执行2次,通过1,失败1,通过率50.00%。
接口[/json/crm_common_detail/lock-data.action]:已执行1次,通过0,失败1,通过率0.00%。
 详情见附件。
            """
            bgColor = "#f2dede"
            if self.testResult == "PASS":
                bgColor = "#dff0d8"
            emailText = "<html><body style='background-color:%s;display:block;'>" % bgColor

            # 1、测试报告概况
            emailText = emailText + (
                """
            <h1>(一)UI测试报告概况</h1>
            <h2>任务基本信息</h2>
            <table border="1px" cellpadding="3px" width="80%%">
            <tr><th width="20%%"  align="left">任务ID</th><td width="80%%">%s</td></tr>
            <tr><th align="left">执行环境</th><td>%s</td></tr>
            <tr><th align="left">执行时间</th><td>%s</td></tr>
            <tr><th align="left">执行结果</th><td>%s</td></tr>
            <tr><th align="left">执行耗时</th><td>%s秒</td></tr>
            <tr><th align="left">任务名称</th><td>%s</td></tr>
            <tr><th align="left">任务描述</th><td>%s</td></tr>
            <tr><th align="left">包含%s</th><td>%s</td></tr>
            <tr><th align="left">包含%s</th><td>%s</td></tr>
            <tr><th align="left">备注</th><td>%s</td></tr>
            </table>""" %
                (self.taskId, self.httpConfKey, self.execStartTime,
                 self.testResult, self.execTakeTime, self.title, self.taskdesc,
                 CommonConf.groupLevel1, self.businessLineName,
                 CommonConf.groupLevel2, self.moduleName,
                 (self.execComments.strip() == "" and "无"
                  or self.execComments.strip())))
            if isDictJson(self.testResultMessage):
                resDict = json.loads(self.testResultMessage)
                if resDict['caseTotalCount'] == 0:
                    caseRate = 0.00
                else:
                    caseRate = float(resDict['casePassCount']) / float(
                        resDict['caseTotalCount'])

                if resDict['caseStepTotalCount'] == 0:
                    stepRate = 0.00
                else:
                    stepRate = float(resDict['caseStepPassCount']) / float(
                        resDict['caseStepTotalCount'])

                # 所有统计信息开始################################################################
                emailText = emailText + "<h2>结果统计信息</h2>"
                emailText = emailText + """
    <table border="1px" cellpadding="3px" width="80%%">  
        <thead>
            <tr style="background-color:#fcf8e3;"> 
                <th width="5%%"></th>
                <th width="10%%">总计</th>
                <th width="10%%">PASS</th>
                <th width="10%%">FAIL</th>
                <th width="10%%">WARNING</th>
                <th width="10%%">通过率</th>
            </tr>
        </thead>
        <tbody>
            <tr style="background-color:%s;" id="total_summay"><td>用例</td>
                <td><bdi id="summay_totalCount">%s</bdi></td>
                <td><bdi id="summay_passCount">%s</bdi>
                <td><bdi id="summay_failCount">%s</bdi></td>
                <td><bdi id="summay_failCount">%s</bdi></td>
                <td><bdi id="summay_passPercent">%.2f%%</bdi></td></tr>
            <tr style="background-color:%s;" id="total_summay"><td>步骤</td> 
                <td><bdi id="summay_totalCount">%s</bdi></td>
                <td><bdi id="summay_passCount">%s</bdi></td>
                <td><bdi id="summay_failCount">%s</bdi></td>
                <td><bdi id="summay_failCount">%s</bdi></td>
                <td><bdi id="summay_passPercent">%.2f%%</bdi></td></tr>
        </tbody>
    </table>""" % (bgColor, resDict['caseTotalCount'],
                   resDict['casePassCount'], resDict['caseFailCount'],
                   resDict['caseWarningCount'], caseRate * 100, bgColor,
                   resDict['caseStepTotalCount'], resDict['caseStepPassCount'],
                   resDict['caseStepFailCount'],
                   resDict['caseStepWarningCount'], stepRate * 100)

            else:
                # task 执行结果 结果没有返回正常的json
                emailText = emailText + self.testResultMessage + "<br>"

            # self.isSendEmail  是否发送是否带附件PassFailErrorException
            isSendMailStr = str(self.isSendEmail)
            # 不够6位后面补1
            addOneCount = 6 - len(isSendMailStr)
            for i in range(0, addOneCount):
                isSendMailStr = isSendMailStr + "1"
            if int(isSendMailStr[1]) == 1:
                emailText = emailText + "<br>详情见附件。"
            else:
                tmpurl = "%s/static/ui_test/reports/%s/report.html" % (
                    EnvConfig.WEB_URI, self.reportDir)
                emailText = emailText + (
                    "<br>详情见:&nbsp;&nbsp;<a href='%s'>%s</a>" %
                    (tmpurl, tmpurl))

            emailText = emailText + "</body></html>"

            # 结束生成emailText的html###############################################################################
            # 开始发送邮件
            def subSendMail():
                if int(isSendMailStr[1]) == 1:
                    # 发送附件
                    testReportFilePath = "%s/static/ui_test/reports/%s/report.html" % (
                        EnvConfig.WEB_ROOT, self.reportDir)
                    UsualTool.send_mail(emailList,
                                        subject,
                                        emailText,
                                        testReportFilePath,
                                        subType="html")
                else:
                    # 不发送附件
                    UsualTool.send_mail(emailList,
                                        subject,
                                        emailText,
                                        subType="html")

            if self.testResult == ResultConst.PASS and int(
                    isSendMailStr[2]) == 1:
                subSendMail()
            elif self.testResult == ResultConst.FAIL and int(
                    isSendMailStr[3]) == 1:
                subSendMail()
            elif self.testResult == ResultConst.ERROR and int(
                    isSendMailStr[4]) == 1:
                subSendMail()
            elif self.testResult == ResultConst.EXCEPTION and int(
                    isSendMailStr[5]) == 1:
                subSendMail()
        else:
            emailList = EmailConfig.sender  # ;分号间隔
            subject = "[%s]任务[%s:%s]测试报告,没有找到收件人,执行者为%s" % (
                self.testResult, self.taskId, self.title, self.addBy)
            emailText = "[%s]任务[%s:%s]测试报告,没有找到收件人,执行者为%s" % (
                self.testResult, self.taskId, self.title, self.addBy)
            UsualTool.send_mail(emailList, subject, emailText, subType="html")