def headers(self,headers): self.__headers = {} if headers == None or headers.strip() == "": self.__headers['User-Agent'] = ServiceConf.framework_version return try: if isDictJson(headers): header_dict = json.loads(headers) if "User-Agent" not in header_dict.keys(): header_dict['User-Agent'] = ServiceConf.framework_version else: try: header_dict = eval(headers) if TypeTool.is_dict(header_dict) == False: raise ValueError(u"EXCEPTION: 参数headers类型不正确,应为合法JSON字符串,实际是:\n%s。" % headers) except Exception as e: raise ValueError(u"EXCEPTION: 参数headers类型不正确,应为合法JSON字符串,实际是:\n%s。" % headers) except Exception as e: raise ValueError(u"EXCEPTION: 处理头信息发生异常:请检查,应该为合法JSON字符串,实际是:\n%s。" % str(headers)) if TypeTool.is_dict(header_dict): self.__headers = {} for k,v in header_dict.items(): if isContainCN(k): k = urllib.parse.quote(k,encoding="utf-8") if isContainCN(v): v= urllib.parse.quote(v,encoding="utf-8").replace("%3D","=") self.__headers[k] = v else: raise ValueError(u"EXCEPTION: 参数headers转换后类型不正确,请检查,应该为dict类型。实际是%s。" % type(header_dict))
def generateVarsStringByVarsPoolAndVarsKeyList(self): """ 根据varsPool生成当前的变量列表。 Returns: 当前变量列表 """ retStr = "" for tmpKey in self.calledVarsKeyList: if tmpKey.startswith("[ANNOTATION]") or tmpKey.startswith( "[EXECUTE]"): #注释值显示后面部分不显示key: retStr += "%s ;(来源:%s)\n" % ( str(self.varsPool[tmpKey]).replace(";", "\\;"), self.varsPool[self.getVarkeyPathKey(tmpKey)] if self. getVarkeyPathKey(tmpKey) in self.varsPool.keys() else "无") else: #不是注释和执行类,正常变量的话 try: if TypeTool.is_list( self.varsPool[tmpKey]) or TypeTool.is_dict( self.varsPool[tmpKey]): strToBerepalced = json.dumps(self.varsPool[tmpKey]) else: strToBerepalced = str(self.varsPool[tmpKey]) except: strToBerepalced = str(self.varsPool[tmpKey]) retStr += "%s = %s ;(来源:%s)\n" % ( tmpKey, strToBerepalced.replace(";", "\\;"), self.varsPool[self.getVarkeyPathKey(tmpKey)] if self. getVarkeyPathKey(tmpKey) in self.varsPool.keys() else "无") return retStr.strip()
def recur_data(expect,actual): if TypeTool.is_list(expect): # 如果预期和实际的任何一个为空,则断言通过, # 如果都不为空,判定第一个值 if TypeTool.is_list(actual): if len(expect) == 0 or len(actual) == 0: #如果任何一个长度为0,则不断言,直接通过。 fail[0] = fail[0] + "PASS: 断言通过!预期结构Key(%s)或者实际结构的Key长度为0,不进行比对。\r\n" % (global_key[0]) else: #否则,把第一个结构进行断言 if TypeTool.is_list(expect[0]) or TypeTool.is_dict(expect[0]): # 如果值是list或者dict,递归判断 pathAdd(0) recur_data(expect[0], actual[0]) pathRemove() else: # 否则判断类型 pathAdd(0) asssert_type(expect[0], actual[0]) pathRemove() else: failPointCount[0] += 1 fail[0] = fail[0] + "FAIL: 断言失败!预期结构Key(%s)的值与实际结构类型不一致,预期list,实际%s。\r\n" % ( global_key[0], type(actual)) elif TypeTool.is_dict(expect): #如果预期的是dict,先判断长度一致,再进行递归断言 if TypeTool.is_dict(actual): #实际结果也是dict if len(expect) == len(actual): # 进行判断每个key的类型 for innerKey, innerValue in expect.items(): if innerKey in actual.keys(): if TypeTool.is_list(innerValue) or TypeTool.is_dict(innerValue): #如果值是list或者dict,递归判断 pathAdd(innerKey) recur_data(expect[innerKey],actual[innerKey]) pathRemove() else: #否则判断类型 pathAdd(innerKey) asssert_type(expect[innerKey], actual[innerKey]) pathRemove() else: # 结构一致,长度不一致 failPointCount[0] += 1 fail[0] = fail[0] + "FAIL: 断言失败!预期结构Key(%s)的值与实际结构的长度不一致,预期长度%s,实际长度%s。\r\n" % ( global_key[0], len(expect), len(actual)) else: #实际结果不是dict failPointCount[0] += 1 fail[0] = fail[0] + "FAIL: 断言失败!预期结构Key(%s)的值与实际结构类型不一致,预期dict,实际%s。\r\n" % (global_key[0], type(actual)) else: #不是list不是字典,进行类型判断 asssert_type(expect,actual) pathRemove()
def recur_data(expect, actual): if TypeTool.is_list(expect): # 如果预期和实际的任何一个为空,则断言通过, # 如果都不为空,判定第一个值 if TypeTool.is_list(actual): # 如果实际结果也是list,进行逐个断言 if len(expect) > len(actual): # 长度超过了实际长度,断言石板 failPointCount[0] += 1 fail[0] = fail[0] + "FAIL: 断言失败!预期结果Key(%s)的长度%d超过了实际长度%d。\r\n" % (global_key[0], len(expect), len(actual)) else: #长度符合实际长度,进行预期结果的断言 for tmpListIndex in range(0,len(expect)): pathAdd(tmpListIndex) if TypeTool.is_list(expect[tmpListIndex]) or TypeTool.is_dict(expect[tmpListIndex]): recur_data(expect[tmpListIndex],actual[tmpListIndex]) else: #进行实际断言 asssert_value(expect[tmpListIndex],actual[tmpListIndex]) pathRemove() else: #如果实际结果不是list,那么就失败了 failPointCount[0] += 1 fail[0] = fail[0] + "FAIL: 断言失败!预期结果Key(%s)的值与实际结果类型不一致,预期list,实际%s。\r\n" % (global_key[0], type(actual)) elif TypeTool.is_dict(expect): # 如果预期的是dict,先判断长度一致,再进行递归断言 if TypeTool.is_dict(actual): # 实际结果也是dict # 进行判断每个key的类型 for innerKey, innerValue in expect.items(): if innerKey in actual.keys(): #实际结果有这个值 pathAdd(innerKey) if TypeTool.is_list(innerValue) or TypeTool.is_dict(innerValue): # 如果值是list或者dict,递归判断 recur_data(expect[innerKey], actual[innerKey]) else: # 否则判断类型 asssert_value(expect[innerKey], actual[innerKey]) pathRemove() else: #实际结果不存在这个值 failPointCount[0] += 1 fail[0] = fail[0] + "FAIL: 断言失败!预期结果Key(%s)在实际结果中不存在。\r\n" % (global_key[0]) else: # 实际结果不是dict failPointCount[0] += 1 fail[0] = fail[0] + "FAIL: 断言失败!预期结果Key(%s)的值与实际结果类型不一致,预期dict,实际%s。\r\n" % (global_key[0], type(actual)) else: # 不是list不是字典,进行类型判断 asssert_value(expect, actual) pathRemove()
def JSON_PATH_GET_FIRST(value, context, strTobeProcessed=""): paramList = getParamList(strTobeProcessed, context) if context.testResult == ResultConst.ERROR or context.testResult == ResultConst.EXCEPTION: retMsg = "CASE_ERROR:关键字JSON_PATH_GET执行时解析参数列表返回错误。返回参数列表为%s" % str( paramList) context.assertResult = "%s\n%s" % (retMsg, context.assertResult) return retMsg jsonString = "" jsonPath = "" if len(paramList) == 2: jsonPath = paramList[1].strip().replace('"', "'") jsonString = paramList[0].strip() try: if isJson(jsonString): jsonDict = json.loads(jsonString) else: jsonDict = json.loads(processJsonString(jsonString)) jsonValue = eval("""jsonpath.jsonpath(jsonDict,"%s")""" % jsonPath) if TypeTool.is_list(jsonValue) and len(jsonValue) > 0: jsonValue = jsonValue[0] if TypeTool.is_list(jsonValue) or TypeTool.is_dict(jsonValue): jsonValue = json.dumps(jsonValue, ensure_ascii=False) else: jsonValue = str(jsonValue) except Exception as e: logging.error(traceback.format_exc()) logging.error("JSONSTRING:\n%s\nJSON_PATH: %s" % (jsonString, jsonPath)) jsonValue = "<ERROR:JSON或者路径错误>" context.setResult("ERROR", jsonValue) else: jsonValue = "<ERROR:参数错误>" context.setResult("ERROR", jsonValue) return jsonValue
def JSON_LIST_LEN(value, context, strTobeProcessed=""): # 开始处理paramsString jsonstring),( path paramList = getParamList(strTobeProcessed, context) if context.testResult == ResultConst.ERROR or context.testResult == ResultConst.EXCEPTION: retMsg = "CASE_ERROR:关键字JSON_LIST_LEN执行时解析参数列表返回错误。返回参数列表为%s" % str( paramList) context.assertResult = "%s\n%s" % (retMsg, context.assertResult) return retMsg jsonValue = "" lenRes = "0" jsonString = "" jsonPath = "" if len(paramList) == 1: paramList.append("") if len(paramList) == 2: jsonPath = paramList[1].strip() jsonString = paramList[0].strip() try: jsonDict = transferJsonToDict(jsonString) if jsonPath.strip() == "": jsonValue = jsonDict else: jsonValue = eval("jsonDict%s" % jsonPath) if TypeTool.is_list(jsonValue): lenRes = str(len(jsonValue)) else: lenRes = "<ERROR:不是列表不进行长度判断>" context.setERROR(lenRes) except Exception as e: lenRes = "<ERROR:JSON格式错误>" context.setERROR(lenRes) else: lenRes = "<ERROR:参数长度[%d]错误>" % len(paramList) context.setERROR(lenRes) return lenRes
def setResult(self, result=ResultConst.ERROR, errorMsg=""): """ 设置测试结果 Args: result: 测试结果 PASS FAIL等 errorMsg: 测试消息。 Returns: 无。 """ if result not in self.validResultList: self.testResult = ResultConst.ERROR self.assertResult = "%s: %s" % (ResultConst.ERROR, "不是合法的测试结果[%s]" % result) self.actualResult = "不是合法的测试结果[%s]" % result return self.assertResult = "%s: %s\n%s\n" % (result, errorMsg, self.assertResult) if TypeTool.is_str(self.actualResult) and self.actualResult == "": self.actualResult = errorMsg self.testResult = result
def bodyContent(self, bodyContent): if self.method == self.supportMethodList[ 0] or self.method == self.supportMethodList[ 3] or bodyContent == None: #get head请求的时候没有body体 self.__bodyContent = None return if self.bodyType == self.bodyTypeList[0]: #form-data self.__bodyContent = [] #如果是fordmdata就是设置一个list #去掉content-type相关的错误的header,formdata需要自己生成header if TypeTool.is_dict(self.headers) == False: raise ValueError(u"EXCEPTION: headers类型错误!应为字典,实际是[%s]。" % (type(self.headers))) headerKeysList = deepcopy(list(self.headers.keys())) for k in headerKeysList: if k.lower() == "content-type": self.headers.pop(k) # logging.debug("bodyContent:%s"% bodyContent) if bodyContent == "" or bodyContent == None: return if TypeTool.is_str(bodyContent) == False: raise ValueError( u"EXCEPTION: 参数bodyType为%s时,bodyContent必须是字符串。" % (self.bodyType)) if isListJson(bodyContent) == False: raise ValueError( u"EXCEPTION: 参数bodyType为%s时,bodyContent必须是合法的json列表字符串。" % (self.bodyType)) bodyContentList = json.loads(bodyContent) #遍历formdata数据列表 for tmpFormAttrDict in bodyContentList: if TypeTool.is_dict(tmpFormAttrDict) == False: #元素必须是字典 raise ValueError( u"EXCEPTION: 参数bodyType为%s时,列表中的每个元素必须是字典。" % (self.bodyType)) if "key" not in tmpFormAttrDict.keys( ) or "type" not in tmpFormAttrDict.keys( ) or "value" not in tmpFormAttrDict.keys(): #必须包含必要的key raise ValueError( u"EXCEPTION: 参数bodyType为%s时,元素缺少必要字段,必须包含key,type,value这些字段。" % (self.bodyType)) tmpKey = tmpFormAttrDict['key'] tmpType = tmpFormAttrDict['type'] tmpValue = tmpFormAttrDict['value'] if isContainCN(tmpKey): tmpKey = urllib.parse.quote( tmpKey, encoding="utf-8") #key urlencode中文,key不能有中文字符。 if tmpType == self.formdataTypeList[0]: # text try: if TypeTool.is_dict(tmpValue): # 如果是字段dump成字符串 tmpValue = json.dumps(tmpValue, ensure_ascii=False) # tmpValue = tmpValue # tmpValue = urllib.parse.quote(tmpValue,encoding="utf-8") #urlencode中文不适用quote, # 20180122 HTTP_INTERFACE_2001上进行测试,测试结果:文本类型不适用quote,不会出现错误,可以正常测试。 # 问题是如果这里不用quote,接触出来的请求头中的文件名等中文的话就是编码而不是文字显示。 self.__bodyContent.append( (tmpKey, (None, tmpValue, "text/plain; charset=UTF-8"))) # 判断是否是utf8 except Exception as e: raise ValueError( u"EXCEPTION: 参数bodyType为%s时,类型为text时,value无法转换为utf8。" % self.bodyType) elif tmpType == self.formdataTypeList[1]: # file if TypeTool.is_dict(tmpValue): #必须是字典,包含对应的值 if "filename" not in tmpValue.keys( ) or "realPath" not in tmpValue.keys( ) or "fileType" not in tmpValue.keys(): raise ValueError( u"EXCEPTION: 参数bodyType为%s时,元素的value缺少必要字段。" % (self.bodyType)) if RunTcpServerConf.ip != TcpServerConf.ip: filePath = "%s/%s" % ( LogConfig.uploadsRoot, tmpValue['realPath'].split("/uploads/")[-1]) dirPath = "/".join(filePath.split("/")[:-1]) if not getFTPFile( TcpServerConf.ip, "getUploadFile", "getUploadFile", dirPath, filePath, tmpValue['realPath'].split( "/uploads/")[-1]): raise ValueError( u"EXCEPTION: 执行机非主服务器时,文件获取失败") tmpValue['realPath'] = filePath if os.path.isfile(tmpValue['realPath']): #如果存在文件,加入file #如果不quote直接用中文是否报错? #20180122 HTTP_INTERFACE_2001上进行测试,测试结果:文件类型如果不使用quote,在上传中文文件的时候,就返回错 误。所以必须使用quote if isContainCN(tmpValue['filename']): fileName = urllib.parse.quote( tmpValue['filename'], encoding="utf-8") else: fileName = tmpValue['filename'] # fileName = tmpValue['filename'] self.__bodyContent.append( (tmpKey, (fileName, open(tmpValue['realPath'], "rb"), tmpValue['fileType']))) else: #文件不存在抛出异常 raise ValueError( u"EXCEPTION: 参数bodyType为%s时,服务器端未找到对应的文件,请重新上传或者联系管理员。" % (self.bodyType)) else: #不是字典 raise ValueError( u"EXCEPTION: 参数bodyType为%s时,元素的value必须是字典。" % (self.bodyType)) else: #类型错误抛出异常 raise ValueError( u"EXCEPTION: 参数bodyType为%s时,content只支持%s,不支持当前类型%s。" % (self.bodyType, self.formdataTypeList, tmpType)) elif self.bodyType == self.bodyTypeList[ 1] or self.bodyType == self.bodyTypeList[2]: # x-www-form-urlencoded # raw try: if TypeTool.is_str(bodyContent): #如果是字符串,转换成utf8字节码 self.__bodyContent = bodyContent.encode('utf8') #转到utf8 elif TypeTool.is_bytes(bodyContent): #如果是字节码,直接赋值 self.__bodyContent = bodyContent else: raise ValueError( u"EXCEPTION: bodyContent必须是UTF-8字符集的字符串或有效的字节码。" % (bodyContent)) except Exception as e: raise ValueError(u"EXCEPTION: 参数bodyType为%s时,内容content格式错误。" % self.bodyType) elif self.bodyType == self.bodyTypeList[3]: #binary try: if TypeTool.is_bytes(bodyContent): #如果是字节码,直接赋值 self.__bodyContent = bodyContent elif TypeTool.is_str(bodyContent) and isDictJson(bodyContent): bodyContentDict = json.loads(bodyContent) if ("realPath" in bodyContentDict.keys()) and TypeTool.is_str( bodyContentDict['realPath']): #binary方式字符串正确 if os.path.isfile(bodyContentDict['realPath']): #服务器端存在文件 self.__bodyContent = open( bodyContentDict['realPath'], "rb") else: #服务器端不存在文件 raise ValueError( u"EXCEPTION: 参数bodyType为%s时,内容content文件realPath路径错误,不存在此文件。" % self.bodyType) else: #binary方式json字符串格式错误 raise ValueError( u"EXCEPTION: 参数bodyType为%s时,内容content格式错误。" % self.bodyType) else: #不正确的bodycontent格式,必须是字节码或者有效的json字符串。 raise ValueError( u"EXCEPTION: 参数bodyType为%s时,内容必须是json或者字节码。" % self.bodyType) except Exception as e: #未知异常 logging.error( "EXCEPTION: 参数bodys的type为%s时,内容content出现未知异常如下:\r\n%s" % (self.bodyType, traceback.format_exc())) raise ValueError( "EXCEPTION: 参数bodys的type为%s时,内容content出现未知异常如下:\r\n%s" % (self.bodyType, e)) elif self.bodyType == self.bodyTypeList[4]: self.__bodyContent = None
def sess(self, sess): if TypeTool.is_requests_session(sess): self.__sess = sess else: raise ValueError( u"EXCEPTION: 参数sess类型不正确,请检查,应该为requests.session()类型。")
def GET_LIST_KEY_VALUE_TO_STRING_WITH_SPLIT_TAG(value, context, strTobeProcessed=""): #GET_LIST_KEY_VALUE_TO_STRING_WITH_SPLIT_TAG(listStr,path,splitTag) """ [ { "id": "1002", "datacell": [ "1002", "oHrET0mak8nXtfFuJiC6Ge9AdjVI", "蓝翔坦克", "", "", 0, "wxafc354d761cdcfad" ] }, { "id": "1003", "datacell": [ "1003", "oHrET0sldwXTwQQch4dQYZoyzkag", "静", "", "", 0, "wxafc354d761cdcfad" ] }, { "id": "1402", "datacell": [ "1402", "oHrET0t8a3j5LMhEtL7ZgNpQgamg", "史超", "史超", "15010452531", 1, "wxafc354d761cdcfad" ] }, { "id": "1101", "datacell": [ "1101", "oHrET0qvKFd-5tLUkUBek3JeqLEI", "fanger", "", "", 0, "wxafc354d761cdcfad" ] } ] """ paramList = getParamList(strTobeProcessed, context) if context.testResult == ResultConst.ERROR or context.testResult == ResultConst.EXCEPTION: retMsg = "CASE_ERROR:关键字GET_LIST_KEY_VALUE_TO_STRING_WITH_SPLIT_TAG执行时解析参数列表返回错误。返回参数列表为%s" % str( paramList) context.assertResult = "%s\n%s" % (retMsg, context.assertResult) return retMsg lenRes = "" if len(paramList) != 3 and len(paramList) != 2: lenRes = "<ERROR:参数错误>" context.setERROR(lenRes) return lenRes listStr = paramList[0] keyPath = paramList[1] if len(paramList) == 3: splitTag = str(paramList[2]) elif len(paramList) == 2: splitTag = "," listObj = [] if isListJson(listStr): listObj = json.loads(listStr) else: lenRes = "<ERROR:第一个参数必须是LIST>" context.setERROR(lenRes) return lenRes countCurrentIndex = 0 retListStr = "" for i in range(0, len(listObj)): tmpDict = listObj[i] if TypeTool.is_str(tmpDict) and isDictJson(tmpDict): tmpDict = json.loads(tmpDict) if TypeTool.is_dict(tmpDict): # 是dict try: tmpKeyValue = str(eval("tmpDict%s" % keyPath)) if i == 0: tSplitTag = "" else: tSplitTag = splitTag retListStr = "%s%s%s" % (retListStr, tSplitTag, tmpKeyValue) except Exception as e: # 异常,没有对应的key,继续下一个 continue else: # 不是dict,继续遍历下一个元素 continue return retListStr
def GET_JSON_FROM_LIST_BY_KEYVALUE(value, context, strTobeProcessed=""): # 开始处理GET_JSON_FROM_LIST_BY_KEYVALUE(listStr,keyPath,keyValue,index) paramList = getParamList(strTobeProcessed, context) if context.testResult == ResultConst.ERROR or context.testResult == ResultConst.EXCEPTION: retMsg = "CASE_ERROR:关键字GET_JSON_FROM_LIST_BY_KEYVALUE执行时解析参数列表返回错误。返回参数列表为%s" % str( paramList) context.assertResult = "%s\n%s" % (retMsg, context.assertResult) return retMsg lenRes = "" if len(paramList) != 3 and len(paramList) != 4: lenRes = "<ERROR:参数错误>" context.setERROR(lenRes) return lenRes listStr = paramList[0] keyPath = paramList[1] keyValue = str(paramList[2]) index = 1 if len(paramList) == 4: if isInt(paramList[3]): index = int(paramList[3]) else: lenRes = "<ERROR:第四个参数索引必须是数字>" context.setERROR(lenRes) return lenRes listObj = [] if isListJson(listStr): listObj = json.loads(listStr) else: lenRes = "<ERROR:第一个参数必须是LIST>" context.setERROR(lenRes) return lenRes countCurrentIndex = 0 for i in range(0, len(listObj)): tmpDict = listObj[i] if TypeTool.is_str(tmpDict) and isDictJson(tmpDict): tmpDict = json.loads(tmpDict) if TypeTool.is_dict(tmpDict): #是dict try: tmpKeyValue = str(eval("tmpDict%s" % keyPath)) if tmpKeyValue == keyValue: #找到当前dict countCurrentIndex += 1 if countCurrentIndex == index: lenRes = json.dumps(tmpDict, ensure_ascii=False) return lenRes else: continue else: #未找到dict continue except Exception as e: #异常,没有对应的key,继续下一个 continue else: #不是dict,继续遍历下一个元素 continue lenRes = "<ERROR:未找到对应的元素>" context.setERROR(lenRes) return lenRes
def send_mail(email_list,subject,emailText,filepath = "",subType = "text"): try: #发送email receiver = [] receivertmp = email_list.split(';') for mail in receivertmp: if VerifyTool.IsEmail(mail): receiver.append(mail) sender = EmailConfig.sender smtpserver = EmailConfig.smtpserver username = EmailConfig.username password = EmailConfig.password # 三个参数:第一个为文本内容,第二个 plain 设置文本格式,第三个 utf-8 设置编码 msg=MIMEMultipart() # if subType == "text": text_msg = MIMEText(emailText, 'plain', 'utf-8') #文本格式 elif subType == "html": text_msg = MIMEText(emailText, _subtype='html', _charset='utf-8') # html格式 else: text_msg = MIMEText(emailText, 'plain', 'utf-8') # 文本格式 msg.attach(text_msg) msg['From'] = sender msg['To'] = ";".join(receiver) msg['Subject'] = Header(subject, 'utf-8') # 构造MIMEBase对象做为文件附件内容并附加到根容器 ## 读入文件内容并格式化 filepath = filepath.strip() if os.path.isfile(filepath): contype = 'application/octet-stream' maintype, subtype = contype.split('/', 1) data = open(filepath, 'rb') file_msg = MIMEBase(maintype, subtype) file_msg.set_payload(data.read( )) data.close( ) email.encoders.encode_base64(file_msg) ## 设置附件头 filename_list = filepath.split('/') filename = filename_list[len(filename_list)-1] basename = os.path.basename(filename) file_msg.add_header('Content-Disposition', 'attachment', filename = basename) msg.attach(file_msg) isSendSuccess = False resendTimes = 0 for i in range(0,2): try: smtp = "" smtp = smtplib.SMTP(smtpserver) smtp.login(username, password) # 用smtp发送邮件 smtp.sendmail(sender, receiver, msg.as_string()) isSendSuccess = True break except Exception as e: resendTimes += 1 time.sleep(10) #休眠10秒,10秒后重发 logging.info("subject[%s]发送失败,重发%d!%s" % (subject,resendTimes,traceback.format_exc())) if len(email_list) == 0: return False finally: if TypeTool.is_str(smtp) == False: smtp.quit() if isSendSuccess: logging.info("DONE:send subject[%s] email to %s,receiver is [%s],RetryTimes[%d]" % (subject,email_list,receiver,resendTimes)) return True else: logging.info("NOTSEND:send subject[%s] email to %s,receiver is [%s],RetryTimes[%d]" % (subject,email_list,receiver,resendTimes)) return False except Exception as e: logging.error(traceback.format_exc()) return False
def sendHttpRequest(self, whetherSetResult=True): """ 发送http请求 Returns: 发送请求结果 False/True """ try: httpProcesser = HttpProcesserV2( method=self.method, host=self.host, url=self.url, headers=self.header, params=self.params, bodyType=self.bodyType, bodyContent=self.bodyContent, sess=self.current_session, timeout=int(self.httprequestTimeout), allow_redirects=self.urlRedirectStatus) requestStartTime = time.time() self.interface_response = httpProcesser.sendRequest() requestEndTime = time.time() self.executeTakeTime = int( (requestEndTime - requestStartTime) * 1000) if TypeTool.is_requests_Response(self.interface_response): self.response = self.interface_response self.method = self.response.request.method respReqUrl = self.response.request.url headerHost = respReqUrl.replace("http://", "").replace("https://", "").split("/")[0] realFinalUrlList = respReqUrl.split("?") if len(realFinalUrlList) >= 1: self.urlFinalStr = realFinalUrlList[0] if len(realFinalUrlList) >= 2: finPStr = "" for pStrIndex in range(1, len(realFinalUrlList)): if pStrIndex == len(realFinalUrlList) - 1: finPStr += realFinalUrlList[pStrIndex] else: finPStr += realFinalUrlList[pStrIndex] + "?" self.paramsFinalStr = finPStr self.headerDict = {} self.headerDict['Host'] = headerHost self.headerDict.update(self.response.request.headers) self.header = json.dumps(dict(self.headerDict)) self.headerFinalStr = json.dumps(dict(self.headerDict)) #开始处理实际request的请求体 if self.response.request.body == None: self.bodyContentFinalStr = "" else: #处理最新的request request = self.response.request theEncoding = "utf8" try: reqBody = urllib.parse.unquote( bytes.decode(request.body, encoding=theEncoding)) except: # 转码失败的话, reqBody就设置为空 processedReqHeader = request.headers if "Content-Type" in processedReqHeader.keys( ) and processedReqHeader['Content-Type'].startswith( "multipart/form-data"): # s = a.encode("raw_unicode_escape") 变成bytes,并且带着中文的编码 # formdata 类型 boundary = processedReqHeader[ 'Content-Type'].split("boundary=")[1] splitBoundary = ("--%s" % boundary).encode(theEncoding) startStr0 = 'filename="'.encode(theEncoding) startStr = "Content-Type: application".encode( theEncoding) splitBList = request.body.split(splitBoundary) reqBodyBytes = splitBoundary for bindex in range(1, len(splitBList) - 1): if startStr0 in splitBList[bindex]: # 是文件类型 舍弃后面的二进制 reqBodyBytes = reqBodyBytes + splitBList[ bindex].split( startStr )[0] + b'\r\n\r\nIgnore the real bytes when request is file...\r\n' + splitBoundary else: # 不是文件类型,直接拼接 reqBodyBytes = reqBodyBytes + splitBList[ bindex] + splitBoundary reqBodyBytes += splitBList[-1] try: reqBody = urllib.parse.unquote( reqBodyBytes.decode(theEncoding)) except: # 如果转码失败,那么就是处理后没有文件的也失败了,进行截取操作 tobeProcessedBody = str(reqBodyBytes) reqBody = tobeProcessedBody[2:-1] if len( tobeProcessedBody ) < 1000 else tobeProcessedBody[ 2: 999] + "\r\n(请求体超长,后续省略...)" # 去掉开头的b' 和 结尾的 ' 最多拿1000个字符。 else: # 入股不是formdata,那么就直接byte转换看效果 tobeProcessedBody = str(request.body) reqBody = tobeProcessedBody[2:-1] if len( tobeProcessedBody ) < 1000 else tobeProcessedBody[ 2: 999] + "\r\n(请求体超长,后续省略...)" # 去掉开头的b' 和 结尾的 ' 最多拿1000个字符。 finally: self.bodyContentFinalStr = reqBody respDict = {} respDict['status_code'] = int( getRespCodeByResponse(self.response)) respDict['reason'] = getRespReasonByResponse(self.response) respDict['headers'] = getRespHeaderDictByResponse( self.response) respDict['content'] = getRespTextByResponse(self.response) self.actualResult = json.dumps(dict(respDict)) elif TypeTool.is_str(self.interface_response): self.headerDict = {} self.headerDict['Host'] = self.host.split("://")[1] if isDictJson(self.header): self.headerDict.update(json.loads(self.header)) self.header = json.dumps(dict(self.headerDict)) self.headerFinalStr = json.dumps(dict(self.headerDict)) self.bodyContentFinalStr = self.bodyContent if self.interface_response == "TIMEOUT": if whetherSetResult: self.setFAIL("HTTP请求超时,超时时间[%s秒]内没有响应。" % self.httprequestTimeout) else: self.actualResult = "HTTP请求超时,超时时间[%s秒]内没有响应。" % self.httprequestTimeout else: if whetherSetResult: self.setERROR("HTTP请求异常,没有正常返回。返回内容是:%s" % self.interface_response) else: self.actualResult = "HTTP请求异常,没有正常返回。返回内容是:%s" % self.interface_response elif TypeTool.is_ValueError(self.interface_response): self.headerDict = {} self.headerDict['Host'] = self.host.split("://")[1] if isDictJson(self.header): self.headerDict.update(json.loads(self.header)) self.header = json.dumps(dict(self.headerDict)) self.headerFinalStr = json.dumps(dict(self.headerDict)) self.bodyContentFinalStr = self.bodyContent if whetherSetResult: self.setERROR(str(self.interface_response)) else: self.actualResult = str(self.interface_response) else: if whetherSetResult: self.setERROR("HTTP请求异常,没有返回预期类型和数据,返回的类型是[%s]。" % type(self.interface_response)) else: self.actualResult = "HTTP请求异常,没有返回预期类型和数据,返回的类型是[%s]。" % type( self.interface_response) except Exception as e: self.headerDict = {} tmpHostList = self.host.split("://") if len(tmpHostList) == 2: self.headerDict['Host'] = tmpHostList[1] else: self.headerDict['Host'] = "<ERROR: 错误的请求主机:%s>" % str( self.host) if isDictJson(self.header): self.headerDict.update(json.loads(self.header)) self.header = json.dumps(dict(self.headerDict)) self.headerFinalStr = json.dumps(dict(self.headerDict)) self.bodyContentFinalStr = self.bodyContent if whetherSetResult: self.setERROR("%s: HTTP请求异常[%s]" % (ResultConst.ERROR, e)) else: self.actualResult = "%s: HTTP请求异常[%s]" % (ResultConst.ERROR, e) finally: self.isRequested = True
def __init__(self, host="", url="/", header="{}", params="", sess=requests.session(), timeout=20): self.sess = sess self.timeout = timeout #host应校验末尾是数字或字母,并且开头是http://,否则host格式不合法,创建对象失败,验证host。如果host 斜杠结束那么去掉斜杠 host = host.strip().lower() if host[-1:] == "/": host = host[0:-1] if ((host[-1:].isalpha() or host[-1:].isdigit()) and (host[0:7] == "http://" or host[0:8] == "https://")): self.__host = host else: raise ValueError(u"EXCEPTION: 参数host格式不正确,请检查。 host: %s" % host) #url应校验是/开头 if (url[0:1] == "/" and url[-1:] != "/") or url == "/" or url == "": self.__url = url else: raise ValueError(u"EXCEPTION: 参数url格式不正确,请检查。 url: %s" % url) #params companyKey=874d8c821358a5e26f2524b10f43a292&https=0&ajax=1 需要处理为map类型 self.__params = {} self.paramType = "" logging.debug("得到的参数是:%s" % params) if params.strip() != "": if isJson(params): self.paramType = "json" self.__params = json.loads(params) #如果是json给param赋值 else: self.paramType = "x-www-form-urlencoded" keyvaluelist = params.split("&") for keyvalue in keyvaluelist: tmplist = keyvalue.split("=") if len(tmplist) == 2: self.__params[tmplist[0]] = tmplist[1] elif len(tmplist) < 2: raise ValueError( u"EXCEPTION: 参数params格式不正确,请检查[参数%s的长度为%d.]。 params: %s" % (tmplist[0], len(tmplist), params)) elif len(tmplist) > 2: tag = 0 key = tmplist[0] value = tmplist[1] for tmp in tmplist: if tag == 0 or tag == 1: tag += 1 else: value += "=" + tmp self.__params[key] = value if TypeTool.is_dict(self.__params) == False: raise ValueError( u"EXCEPTION: 参数params类型不正确,请检查,目前支Content-Type[application/x-www-form-urlencoded]或者[application/json]" ) else: logging.debug("没有参数需要处理!") #应为map类型 try: header = header.strip() == "" and "{}" or header header_dict = json.JSONDecoder().decode(header) except Exception as e: # logging.error(traceback.format_exc()) raise ValueError(u"EXCEPTION: 参数header类型不正确,请检查,应该为合法JSON字符串。") if TypeTool.is_dict(header_dict): self.__header = header_dict else: raise ValueError(u"EXCEPTION: 参数header类型不正确,请检查,应该为dict类型。")
def header(self, headers): #应为map类型 if TypeTool.is_dict(headers): self.__header = headers else: raise ValueError(u"EXCEPTION: 参数headers类型不正确,请检查,应该为dict类型。")