def update_job(job_log_dict): # 构造查询条件,即取唯一索引 # 构造 Job 数据库写入模型 # job_log_ = TableJobLog.query.filter_by(task_id=job_log_dict['task_id'], # job_id=job_log_dict[ # 'job_id']).first() filter_dict = { 'task_id': job_log_dict.pop('task_id'), 'job_id': job_log_dict.pop('job_id') } _, job_log_list = DBUtils.query(TableJobLog, filter_dict=filter_dict) if not job_log_list: logger.info('TableJobLog is not found:') return job_log = job_log_list[0] end_time = job_log_dict['end_time'] job_log_dict.update( {'cost_time': (end_time - job_log.start_time).total_seconds() * 1000}) DBUtils.update(TableJobLog, filter_dict=filter_dict, update_dict=job_log_dict)
def search_user_place(type: str = 'search', city_id: int = 1, keyword: str = None) -> Dict: """ 根据type,city_id和keyword查询最近的地点 [{"name":"普天科创产业园","address":"上海市徐汇区宜山路700号","latitude":31.176567,"longitude":121.417537,"geohash":"31.176567,121.417537"},{"name":"上海普天工业园A区","address":"上海市奉贤区南桥环城北路999号","latitude":30.955165,"longitude":121.442938,"geohash":"30.955165,121.442938"},{"name":"上海普天科技产业基地三期","address":"上海市徐汇区 ","latitude":31.177047,"longitude":121.418087,"geohash":"31.177047,121.418087"},{"name":"上海普天工业园B区","address":"上海市奉贤区南桥环城北路1099号","latitude":30.953371,"longitude":121.440985,"geohash":"30.953371,121.440985"},{"name":"上海普天工业园","address":"上海市奉贤区沪杭公路1377号内部西南方向80米","latitude":30.953068,"longitude":121.444041,"geohash":"30.953068,121.444041"},{"name":"上海普天信息产业园B2楼","address":"上海市徐汇区田林街道宜山路700号普天信息产业园b2座","latitude":31.175891,"longitude":121.41769,"geohash":"31.175891,121.41769"},{"name":"中国普天","address":"上海市嘉定区墨玉南路888号上海国际汽车城大厦6层","latitude":31.281632,"longitude":121.165238,"geohash":"31.281632,121.165238"},{"name":"上海普天物流有限公司(浏翔公路)","address":"上海市嘉定区浏翔公路2377号","latitude":31.356752,"longitude":121.309631,"geohash":"31.356752,121.309631"},{"name":"普天信息产业园C1楼","address":"上海市徐汇区 ","latitude":31.175351,"longitude":121.418253,"geohash":"31.175351,121.418253"},{"name":"中国普天上海信息工业园区","address":"上海市奉贤区南桥环城北路168号","latitude":30.95887,"longitude":121.45285,"geohash":"30.95887,121.45285"}] """ city_info = get_city_info_by_id(city_id, cities.city_info) # 搜索地址 place_info = search_place(keyword=keyword, city_name=city_info['name'], type=type) logger.info(f"查询的位置信息为:{place_info}") # name: item.title, # address: item.address, # latitude: item.location.lat, # longitude: item.location.lng, # geohash: item.location.lat + ',' + item.location.lng if place_info.get('status') == 0: city_list = [] for place in place_info['data']: data = {'name': place.get('title'), 'address': place.get('address'), 'latitude': place.get('location').get('lat'), 'longitude': place.get('location').get('lng'), 'geohash': ','.join([str(place.get('location').get('lat')), str(place.get('location').get('lng'))])} city_list.append(data) return city_list else: logger.error('调用腾讯API地图查询接口查询失败,请稍后再试') return resp_200_fail(resp_type='posi_search', message='调用腾讯API地图查询接口查询失败,请稍后再试')
def get_cities(type: str) -> Dict: """ 根据type返回城市信息,直接返回的是一个json {"pinyin":"shanghai","is_map":true,"longitude":121.473701,"latitude":31.23037,"sort":1,"area_code":"021","abbr":"SH","name":"上海","id":1} """ # 先猜测用户是哪个区域的 if type == 'guess': # 此处为了方便,就不调用第三方接口了,直接返回上海 city_name = '上海' # 根据城市名字从city_info中获取城市信息 # city_info = {} # for k, v in cities.city_info.items(): # for content in v: # if content.get('name') == city_name: # city_info.update(content) city_info = get_city_info_by_name(city_name, cities.city_info) if not city_info: raise CustomErr(ERROR_CODE, msg_dict={"REASON": "根据定位信息无法查询到城市信息"}) logger.info('guess获取的城市信息:{}'.format(city_info)) return city_info if type == 'hot': # 此处为了方便,就不调用第三方接口了,直接返回上海 # 根据城市名字从city_info中获取城市信息 return cities.city_info['hotCities'] if type == 'group': # 此处为了方便,就不调用第三方接口了,直接返回上海 city_name = '上海' # 根据城市名字从city_info中获取城市信息 return cities.city_info
async def area_list( token: APIKey = Depends(get_api_key), db: Session = Depends(get_db), region_filters: RegionFilters = Depends(get_region_filters), hmt_filters: Hmtfilters = Depends(get_hmt_filters) ) -> AreaListInResponse: """ 查询指定国家的疫情城市列表数据 <br/> region: 国家 <br/> include_hmt: 默认为 true,当 region 为 China 时返回包含港澳台疫情数据信息,false 为不返回 """ logger.info( f"received parameters, token:{token}, region_filters:{region_filters}, hmt_filters: {hmt_filters}" ) try: area_data = Covid19.get_area_list(db=db, region=region_filters.name, hmt=hmt_filters.include_hmt) data = [_d[0] for _d in area_data if _d[0] and _d[0] != "Recovered"] except Exception as e: logger.error(f"{SYSTEM_ERROR}: {e}") raise CustomException(SYSTEM_ERROR) return AreaListInResponse(data=data)
async def infection_global_detail(token: APIKey = Depends(get_api_key), db: Session = Depends(get_db) ) -> InfectionGlobalDataInResponse: """ 查询全球疫情数据信息 <br/> """ logger.info(f"received parameters, token:{token}") try: global_detail = GlobalDataModel() global_data = Covid19.get_infection_global_data(db=db) last_update_date = Covid19.get_last_update_date(db=db) for _d in global_data: global_detail.region.update({ _d.country_en: { "confirmed_add": _d.confirmed_add, "deaths_add": _d.deaths_add, "recovered_add": _d.recovered_add } }) global_detail.last_update_date = str(last_update_date) global_detail.confirmed_add += _d.confirmed_add global_detail.deaths_add += _d.deaths_add global_detail.recovered_add += _d.recovered_add except Exception as e: logger.error(f"{SYSTEM_ERROR}: {e}") raise CustomException(SYSTEM_ERROR) return InfectionGlobalDataInResponse(data={"global": global_detail})
def runtask(filename, joblist, flag): """ start a task """ if not filename: click.echo(click.style('file name error, please check !', fg='red')) sys.exit() create_sqlite_db() init_db_info() task_id = common.get_time_uuid().replace('-', '') try: task_detail_loader = ParameterTaskDetailLoader( task_id, filename, joblist, None, flag, None, 'agbot-cmd', 'agbot-cmd' ) # task_content 配置 task_detail = task_detail_loader.load() # type: TaskDetail logger.info('start task-------------------------------------------task_id:' + task_id) # 检查任务是否已经存在 _, tab_task_log = DBUtils.query(TableTaskLog, filter_dict={'task_id': task_id}) if tab_task_log: click.echo(click.style('task already exists', fg='red')) sys.exit(-1) # 直接使用线程执行 task , 然后返回前端成功状态 click.echo(click.style('task [{}] running, please wait ...'.format(task_id), fg='green')) event_loop.run_until_complete(task_executor.execute(task_detail)) except Exception as e: logger.exception('runtask error, {}'.format(str(e))) click.echo(click.style('创建任务失败, 请检查脚本文件. 错误原因: {}'.format(str(e)), fg='red'))
def send_mail(self, msg, adds): """ 发送邮件 :param msg: 邮件内容 :param adds: 收件人信息 :return: bool """ receivers = adds message = MIMEText(msg, 'plain', 'utf-8') message['From'] = Header(SENDER, 'utf-8') message['To'] = Header("", 'utf-8') subject = SUBJECT message['Subject'] = Header(subject, 'utf-8') try: smtp = smtplib.SMTP_SSL(host=MAIL_HOST) smtp.connect(MAIL_HOST, MAIL_PORT) smtp.login(MAIL_USER, MAIL_PASS) smtp.sendmail(SENDER, receivers, message.as_string()) logger.info( f"send email notification successfully, the recipient is: {adds}. message: {msg}" ) return True except Exception as e: logger.error(f"Failed to send mail to: {adds}. error: {e}") return False
def execute(self, request): # 发起接口调用请求并接收响应 try: host = self.tp_conf.get(ActiveMqTestPointEnum.host.key) port = self.tp_conf.get(ActiveMqTestPointEnum.port.key) user_name = self.tp_conf.get(ActiveMqTestPointEnum.port.key) password = self.tp_conf.get(ActiveMqTestPointEnum.password.key) destination = self.tp_conf.get( ActiveMqTestPointEnum.destination.key) conn = stomp.Connection10(host_and_ports=[(host, port)]) conn.start() conn.connect(username=user_name, password=password) conn.send(destination=destination, body=json.dumps(request), headers={'amq-msg-type': 'text'}) conn.disconnect() logger.info('tp->active mq:消息发送成功,destination=' + destination + 'msg=' + json.dumps(request)) result = {'result_value': True} return result, '' except ConnectionError as e: logger.error('tp->active mq:connection error:', str(e)) raise RuntimeError('active mq测试,调用被测系统时连接异常') except Exception as e: logger.exception('tp->active mq:runtime error:', str(e)) raise RuntimeError('active mq测试,调用被测系统时执行异常')
async def population( token: APIKey = Depends(get_api_key), db: Session = Depends(get_db), country_filters: RegionFilters = Depends(get_allow_empty_region_filters), ) -> PopulationInResponse: """ 查询人口数据信息 <br/> region: 国家 (非必传,默认值查全部国家) <br/> """ logger.info( f"received parameters, token:{token}, country_filters: {country_filters}" ) try: _population = list() population_data = Population.get_population( db=db, country=country_filters.name) for _d in population_data: _population.append( PopulationModel(name=_d.country_en, population_num=_d.population_num)) except Exception as e: logger.error(f"{SYSTEM_ERROR}: {e}") raise CustomException(SYSTEM_ERROR) return PopulationInResponse(data=_population)
def build_request(self): tc_ctx_dict = self.vertical_context.tc_context try: # 获取请参 TpBase.build_request(self) # 组装heard # 20190403 edit by jun.hu # 新加支持 http_header 配置字典写法 head_dict = {} tc_data_dict = tc_ctx_dict.tc_detail.data tp_conf_header = self.tp_conf.get('http_header', None) if tp_conf_header: try: # 默认配置支持字典的写法 self.__header = json.loads(tp_conf_header) except Exception as ex: logger.info(str(ex)) # 字典取值发生错误时取逗号隔开的值 params_name_list = self.tp_conf.get('http_header').split( ',') for name in params_name_list: head_dict[name] = tc_data_dict.get(name) self.__header = head_dict if self.tp_conf.get('upload_file_path'): upload_file_path = self.tp_conf.get('upload_file_path') upload_file_path = upload_file_path.split('/')[-1] upload_file = next( filter( lambda a: a.id.endswith(upload_file_path), self. vertical_context.job_context.job_model.attachment), None) assert upload_file is not None, 'file not found: {}'.format( upload_file_path) files = { self.tp_conf.get('upload_file_name'): upload_file.content } self.__file = files # 构造json请求参数 if self.tp_conf.get('json_param_name'): json_param_dict = {} if self.tp_conf.get('req_json_data'): params_name_list = self.tp_conf.get('req_json_data').split( ',') for name in params_name_list: json_param_dict[name] = tc_data_dict.get(name) # json参数放入请参字典 self.req_param[self.tp_conf.get( 'json_param_name')] = json.dumps(json_param_dict) return {'content': self.req_param, 'header': self.__header} except Exception as e: logger.exception('tp->api:build params error', str(e)) raise Exception(str(e))
def execute_assert_text(self, **kwargs): exec_element = kwargs['exec_element'] exec_param = kwargs['exec_param'] try: logger.info('assert_text:预测值:%s, 实际值:%s', exec_param, exec_element.text) if exec_param == exec_element.text: return True return False except Exception: logger.error('assert_text error') return False
async def ratio_gender( db: Session = Depends(get_db), area_filters: RegionFilters = Depends(get_area_filters), time_filters: DateFilters = Depends(get_date_filters), ) -> GenderRatioInResponse: """ 查询男女比例信息<br/> """ logger.info( f"received parameters, time_filters:{time_filters}, area_filters:{area_filters}" ) all_data = Covid19.get_all(db) print(all_data) return GenderRatioInResponse()
async def region_list(token: APIKey = Depends(get_api_key), db: Session = Depends(get_db)) -> RegionListInResponse: """ 查询有疫情信息的国家列表 <br/> """ logger.info(f"received parameters, token:{token}") try: region_data = Covid19.get_region_list(db=db) data = [_d[0] for _d in region_data if _d[0]] except Exception as e: logger.error(f"{SYSTEM_ERROR}: {e}") raise CustomException(SYSTEM_ERROR) return RegionListInResponse(data=data)
def to_dict(self, custom_response_id=None): rv = dict(self.payload or ()) rv['code'] = self.return_code if self.msg_dict is not None: s = ERR_MSG[self.return_code].format(**self.msg_dict) else: s = ERR_MSG[self.return_code] rv['message'] = s if custom_response_id: rv.update({'response_id': custom_response_id}) else: rv.update({'response_id': gen_random_str(min_length=36, max_length=36, has_letter=True, has_digit=True)}) s += ' [response_id:{}]'.format(rv['response_id']) logger.info(s) return rv
def create_sqlite_db(): """ init sqlite db """ sqlite_uri = get_db_sqlite_uri( agbot_config.sys_conf_dict['system']['db']['url']) # 如果 sqlite 文件路径已经存在,直接返回 if os.path.exists(sqlite_uri): return '' # 初始化数据库 logger.info('uri is {}'.format(sqlite_uri)) engine = ParserSessionScope.get_engine(sqlite_uri, agbot_config.sys_conf_dict['system']['db']['connection_pool']) Base.metadata.create_all(engine)
def get_file_encoding(file): # 读入文件 file = open(file, 'rb') buf = file.read() result = chardet.detect(buf) encoding = result['encoding'] if encoding.startswith('utf-8'): result_encoding = encoding elif encoding.startswith('UTF-8'): result_encoding = encoding else: result_encoding = 'GB2312' logger.info('get file encoding %s, %s as %s', file.name, encoding, result_encoding) # 关闭文件操作 file.close() return result_encoding
def build_request(self): tc_params_dict = self.vertical_context.tc_context self._tc_params_dict = tc_params_dict script_name = self.tp_conf.get( UiTestPointEnum.script_file_path.key, self.tp_conf.get(UiTestPointEnum.script.key)) script_name = script_name.split('/')[-1] xml_script = next( filter(lambda a: a.id.endswith(script_name), self.vertical_context.job_context.job_model.attachment), None) assert xml_script is not None, 'can not fond xml script {}'.format( script_name) xml_script_content_raw = xml_script.content.decode('utf-8') try: xml_script_content, replacement = get_placeholder_value( xml_script_content_raw, self.vertical_context) self.__extend_tp_replacement(replacement) # 获取命令列表 self._command_list = self._get_command_list(xml_script_content) target_url = '' for command in self._command_list: # 请求参数作用于 open 函数的目标 if command['command'] == 'open': target_url = self._get_command_param(command['target']) logger.info("ui 原始请求地址为 :{}".format(target_url)) # 组装页面地址 if UiTestPointEnum.req_data.key in self.tp_conf and self.tp_conf[ UiTestPointEnum.req_data.key]: TpBase.build_request(self) target_url = target_url + splice_url_params( self.req_param) logger.info("ui 请求地址,拼接参数后为 :{}".format(target_url)) flag = self._set_command_param(command['target'], target_url) if not flag: command['target'] = target_url break except Exception as e: logger.exception('ui 测试脚本: %s ,没有找到或者解析失败', str(self.tp_conf)) raise RuntimeError('ui 测试脚本:' + str(self.tp_conf) + ',没有找到或者解析失败') return {'url': target_url}
def __init__(self): # 创建需要的路径 AgbotConfig.create_need_path() # 生成需要的各类绝对路径名称 AgbotConfig.create_need_abs_filename() # 日志格式 _set_log_file(AgbotConfig._log_abs_filename) sys_conf_dict = {} json_conf_dict = self.read_conf_json( AgbotConfig._conf_json_abs_filename) ini_conf_dict = self.read_conf_ini(AgbotConfig._conf_ini_abs_filename) dict_update_deep(sys_conf_dict, json_conf_dict) dict_update_deep(sys_conf_dict, ini_conf_dict) AgbotConfig.sys_conf_dict = sys_conf_dict logger.info('agbot config load OK!')
def execute_assert_as_json(self, **kwargs): exec_element = kwargs['exec_element'] exec_param = kwargs['exec_param'] # 默认 text 内容为 json 格式,将 text 读做 dict # 根据 param 中表达式进行断言,只断言 '=' 的场景,并且表达式以 ',' 分割 try: text_dict = json.loads(exec_element.text) logger.info('ui 测试 assert_as_json 实际执行结果为 {}'.format(text_dict)) for assert_expression in exec_param.split(','): key, expected_value = assert_expression.split('=') if text_dict[key] == expected_value: continue else: return False return True except Exception: logger.error('assert_as_json error') return False
def update_task_with_task_id(task_log_dict): # 构造查询条件,即取唯一索引 # 构造 Job 数据库写入模型 filter_dict = {'task_id': task_log_dict.pop('task_id')} flag, task_log_list = DBUtils.query(TableTaskLog, filter_dict=filter_dict) if not (flag and task_log_list): logger.info('TableTaskLog is not found:task_id=', filter_dict['task_id']) pass task_log = task_log_list[0] task_log_dict.update({ 'cost_time': (task_log_dict['end_time'] - task_log.start_time).total_seconds() * 1000 }) DBUtils.update(TableTaskLog, filter_dict=filter_dict, update_dict=task_log_dict)
def execute(self, request): try: ssh = paramiko.SSHClient() ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy) host = self.tp_conf.get(ShellTestPointEnum.host.key) user_name = self.tp_conf.get(ShellTestPointEnum.user_name.key) password = self.tp_conf.get(ShellTestPointEnum.password.key) # 默认不填端口为22 port = self.tp_conf.get(ShellTestPointEnum.port.key) if port is None: port = SSH_PORT ssh.connect(host, port=port, username=user_name, password=password, allow_agent=False, look_for_keys=False) shell_cmd = self.tp_conf.get(ShellTestPointEnum.shell_cmd.key) shell_file_path = self.tp_conf.get(ShellTestPointEnum.shell_file_path.key) # 选择shell命令或脚本路径 if shell_cmd is not None: cmd = shell_cmd elif shell_file_path is not None: cmd = 'sh %s' % shell_file_path else: logger.error('tp->shell:execute error %s', 'shell命令为空') raise Exception('tp->shell:execute error shell命令为空') stdin, stdout, stderr = ssh.exec_command(cmd) out_info = stdout.read().decode('utf-8') err_info = stderr.read().decode('utf-8') ssh.close() result = {'result': True} if err_info: result = {'result': err_info} logger.info('tp->shell:execute failed: %s', err_info) logger.info('tp->shell:execute success: %s', out_info) return result, '' except Exception as e: logger.error('tp->shell:execute error %s', str(e)) raise Exception('tp->shell:execute error' + str(e))
async def authentication_register( register_filters: RegisterFilters, db: Session = Depends(get_db), ) -> AuthenticationRegisterInResponse: """ 获取接口调用凭证 <br/> email: 获取凭证的邮箱地址 凭证会以邮件方式发往改邮箱 """ logger.info(f"received parameters, register_filters:{register_filters}") bloom_filter = BloomFilterUtils() email = EmailUtils() if not register_filters or not email.check_email(register_filters.email): raise CustomException(EMAIL_ERROR, msg_dict={"error": "format is incorrect"}) # 邮箱已认证 if bloom_filter.contains(register_filters.email) or CovidUser.get_user( db=db, condition={CovidUser.email.key: register_filters.email}): raise CustomException(EMAIL_ERROR, msg_dict={"error": "email has been certified"}) # 发送 token 信息 token = FishMD5.hmac_md5(register_filters.email, str(get_time_uuid())) send_status = email.send_mail(EMAIL_CONTENT.format(_Token=token), register_filters.email) if not send_status: raise CustomException(EMAIL_ERROR, msg_dict={"error": "failed to send"}) # 保存,记录邮箱信息 CovidUser.add_user(db=db, email=register_filters.email, token=token) bloom_filter.add(register_filters.email) return AuthenticationRegisterInResponse(data={"status": True})
def get_captchas(response: Response) -> Dict: """ 获取验证码信息 {status: 1, code:'图片url'} """ code = str(int(random.random() * 9000 + 1000)) logger.info(f'验证码为:{str(code)}') image = ImageCaptcha().generate_image(code) image.save('./%s.jpg' % code) file_path = os.path.join(os.getcwd(), f'{code}.jpg') try: with open(file_path, 'rb') as f: base64_data = base64.b64encode(f.read()) s = base64_data.decode() url = 'data:image/jpeg;base64,%s' % s response.set_cookie(key='cap', value=code, max_age=3600) return {'status': 1, 'code': url} except Exception as e: raise CustomErr(ERROR_CODE, msg_dict={"REASON": "获取验证码信息失败:{}".format(e)}) finally: os.remove(file_path)
def resolve_expect_data(self, tc_ctx): # 存在四种格式的断言配置需要兼容 key:value,key:value; key=value,key=value; key==value; key,key logger.info("tp_api: {} 期望值替换占位符前为 {}".format( tc_ctx.current_tp_context.id, self.tp_conf.get('expect_data'))) params_name_list = self.tp_conf.get('expect_data').split( ',(?=(?:[^\"]*(?:"[^\"]*")?[^\"]*)*$)') # 处理 key==value 形式 if not exp.is_exp(params_name_list[0]): params_name_list = self.tp_conf.get('expect_data').split(',') # 将 key=value;key,key;key:value 形式转换成字典,需要赋值 self.expect_dict expect_dict_raw = get_params_dict(params_name_list, tc_ctx.tc_detail.data) expect_dict, replacement = resolve_placeholder( expect_dict_raw, self.vertical_context) expect = [expect_dict] self.expect_dict = expect_dict else: expect = [] logger.info("tp_api: {} 期望值替换占位符后为 {}".format( tc_ctx.current_tp_context.id, expect)) tc_ctx.current_tp_context.assertion = expect
def __init__(self): ServerConfig.create_need_abs_filename() # 生成需要的各类绝对路径名称 flag, ServerConfig.dt, count = conf_as_dict( # 读取 server conf 文件中的测试信息, 写入到 bankcard_man 的 dt 字典变量 ServerConfig.server_conf_abs_filename) # 日志格式设置 local_log_mode = ServerConfig.dt.get('server').get('log_mode') # 'logcat'为只在控制台输出日志 if local_log_mode == 'logcat': set_log_stdout() logger.info('日志初始化完成,目前的日志模式为:%s,日志将只在控制台输出' % local_log_mode) # 'file'为日志文件输出 elif local_log_mode == 'file': set_log_file(ServerConfig.log_abs_filename) logger.info('日志初始化完成,目前的日志模式为:%s,日志将只在日志文件输出' % local_log_mode) # 其他的统一输出为日志文件+logcat else: set_log_stdout() set_log_file(ServerConfig.log_abs_filename) logger.info('日志初始化完成,目前的日志模式为:%s,日志将在控制台及日志文件同时输出' % local_log_mode)
def test_format1(self): set_log_file(self.log_filename) log.info('test_format1') assert 'unittest.log.{}'.format(self.suffix_time) in os.listdir( self.log_path)
def test_format3(self): set_log_file(self.log_filename, file_name_format='%date-%project_name-%log') log.info('test_format3') assert 'unittest.log.{}'.format(self.suffix_time) in os.listdir( self.log_path)
def test_status(self): tc_ctx = self.vertical_context.tc_context try: # 配置的期望参数名称 if self.tp_conf.get('expect_data'): self.resolve_expect_data(tc_ctx) params_name_list = self.tp_conf.get('expect_data').split( ',(?=(?:[^\"]*(?:"[^\"]*")?[^\"]*)*$)') # 如果期望判断首个值满足表达式,则认为是表达式 if exp.is_exp(params_name_list[0]): diff_key_set = set() for e in params_name_list: if not self.run_exp(e): diff_key_set.add(e) if not diff_key_set: return TestStatus.PASSED else: logger.info( '[{}, {}, {}] tp->api 断言不通过: {} @ {}'.format( self.vertical_context.task_context.task_model. id, self.vertical_context.job_context.job_model.id, self.vertical_context.tc_context.tc_detail.id, params_name_list, self.vertical_context.tc_context)) return TestStatus.NOT_PASSED # 获取数据文件期望返回的状态码 if self.tp_conf.get('expect_resp_code'): if self.__resp_code != self.tp_conf.get('expect_resp_code'): return TestStatus.NOT_PASSED else: return TestStatus.PASSED # 是否需要 urldecode if self.tp_conf.get('resp_urldecode_name'): name_list = self.tp_conf.get('resp_urldecode_name').split(',') response_str = self.__response_urldecode( str(tc_ctx.current_tp_context.response.content), name_list) else: response_str = tc_ctx.current_tp_context.response.content if response_str is not None: # 校验期望值,验证返回码是否与期望返回码保持一致 diff_key_set = set() diff_key_set = self.__expect_dict_check( self.expect_dict, tc_ctx.current_tp_context.response.content, diff_key_set) check_expect_flag = not diff_key_set check_type = self.tp_conf.get('check_type') \ if self.tp_conf.get('check_type') else CheckExpectType.EQUAL.value if CheckExpectType.UNEQUAL.value == check_type: if check_expect_flag: check_expect_flag = TestStatus.NOT_PASSED else: check_expect_flag = TestStatus.PASSED else: if check_expect_flag: check_expect_flag = TestStatus.PASSED else: check_expect_flag = TestStatus.NOT_PASSED logger.info('check result:' + str(check_expect_flag) + ' diff set:' + str(diff_key_set)) else: check_expect_flag = TestStatus.NOT_PASSED logger.info('check result:' + str(check_expect_flag) + ' target response is none.') except Exception as e: logger.exception('[{}, {}, {}] tp->api期望值判断异常: {} @ {}'.format( self.vertical_context.task_context.task_model.id, self.vertical_context.job_context.job_model.id, self.vertical_context.tc_context.tc_detail.id, str(e), self.vertical_context.tc_context)) raise Exception('期望值判断异常: {}: {}'.format(str(e.__class__.__name__), str(e))) return check_expect_flag
async def infection_region_detail( token: APIKey = Depends(get_api_key), db: Session = Depends(get_db), region_filters: RegionFilters = Depends(get_region_filters), date_filters: DateFilters = Depends(get_date_filters), hmt_filters: Hmtfilters = Depends(get_hmt_filters), ) -> InfectionRegionDetailInResponse: """ 查询指定国家在某段时间内的疫情明细数据信息 <br/> region: 国家 (必传,默认值为 China) <br/> start_date: 开始日期(非必传,不传代表获取最新数据。可单独指定,单独指定表示查询这一天一直到最新一天的的数据信息)) <br/> end_date: 结束日期 (非必传,不传代表获取最新数据。不可单独指定)<br/> include_hmt: 默认为 true,当 region 为 China 时返回包含港澳台疫情数据信息,false 为不返回<br/> 日期最长可以查询10天 """ logger.info( f"received parameters, token:{token}, region_filters:{region_filters}, " f"date_filters: {date_filters}, hmt_filters:{hmt_filters}") # 判断日期 date_filters = check_date_filter(date_filters) # 判断 htm hmt_filters = check_htm_filter(hmt_filters, region_filters) try: data = dict({"area": {}}) area_data = Covid19.get_infection_country_area_data( db=db, country=region_filters.name, start_date=date_filters.start_date, end_date=date_filters.end_date, hmt=hmt_filters.include_hmt) for _d in area_data: if ("Recovered" == str(_d.province_en)): continue if not data.get("area").get(str(_d.province_en)): # 城市不存在 data.get("area").update({ str(_d.province_en): { str(_d.update_date): { "confirmed_add": _d.confirmed_add, "deaths_add": _d.deaths_add, "recovered_add": _d.recovered_add, "confirmed": _d.confirmed, "deaths": _d.deaths, "recovered": _d.recovered } } }) else: # 城市已经存在 if data.get("area").get(_d.province_en).get(str( _d.update_date)): # 日期已经存在 data["area"][str(_d.province_en)][str( _d.update_date)]["confirmed_add"] += _d.confirmed_add data["area"][str(_d.province_en)][str( _d.update_date)]["deaths_add"] += _d.deaths_add data["area"][str(_d.province_en)][str( _d.update_date)]["recovered_add"] += _d.recovered_add data["area"][str(_d.province_en)][str( _d.update_date)]["confirmed"] += _d.confirmed data["area"][str(_d.province_en)][str( _d.update_date)]["deaths"] += _d.deaths data["area"][str(_d.province_en)][str( _d.update_date)]["recovered"] += _d.recovered else: # 日期不存在 data.get("area").get(_d.province_en).update({ str(_d.update_date): { "confirmed_add": _d.confirmed_add, "deaths_add": _d.deaths_add, "recovered_add": _d.recovered_add, "confirmed": _d.confirmed, "deaths": _d.deaths, "recovered": _d.recovered } }) except Exception as e: if isinstance(e, CustomException): logger.error(f"custom exception: {e}") raise e logger.error(f"{SYSTEM_ERROR}: {e}") raise CustomException(SYSTEM_ERROR) return InfectionRegionDetailInResponse(data=data)
def execute(self, request): content = request.get('content') # 请求地址可从数据文件中读取 api_url = self.tp_conf.get('http_url') # 获取 http 请求方法名称 method = self.tp_conf.get('http_method') # 发起接口调用请求并接收响应 try: # 反射得到 http 的方法 exec_func = getattr(requests, method.lower()) # 请求超时时间 try: timeout = int(self.tp_conf.get('timeout', 10)) except Exception as _: timeout = 10 timeout = min(timeout, 120) # 20190315 edit by jun.hu # 根据 conf 中的 content-type 来决定请求数据组织方式 if self.__header.get('Content-Type') == 'application/json': response = exec_func(api_url, json=content, headers=self.__header, files=self.__file, timeout=timeout) else: if method.lower() == 'delete': response = exec_func(api_url, headers=self.__header, timeout=timeout) else: files = self.__file response = exec_func(api_url, content, headers=self.__header, files=files, timeout=timeout) self.__resp_code = str(response.status_code) try: content = response.json() logger.info('[{}, {}, {}] tp->api load as json: {}, {}'.format( self.vertical_context.task_context.task_model.id, self.vertical_context.job_context.job_model.id, self.vertical_context.tc_context.tc_detail.id, response.status_code, content)) return content, self.__resp_code except JSONDecodeError as e: logger.info( '[{}, {}, {}] tp->api load as json error: {}, {}'.format( self.vertical_context.task_context.task_model.id, self.vertical_context.job_context.job_model.id, self.vertical_context.tc_context.tc_detail.id, response.status_code, response.text)) pass try: content = self.__get_xml_dict(response.text) logger.info('[{}, {}, {}] tp->api load as xml: {}, {}'.format( self.vertical_context.task_context.task_model.id, self.vertical_context.job_context.job_model.id, self.vertical_context.tc_context.tc_detail.id, response.status_code, content)) return content, self.__resp_code except Exception as e: logger.info( '[{}, {}, {}] tp->api load as xml error: {}, {}'.format( self.vertical_context.task_context.task_model.id, self.vertical_context.job_context.job_model.id, self.vertical_context.tc_context.tc_detail.id, response.status_code, response.text)) pass if isinstance(response.text, str) and self.tp_conf.get( 'resp_default_key', ''): return { self.tp_conf.get('resp_default_key'): response.text }, self.__resp_code return response.text, self.__resp_code except RequestException as e: logger.error('[{}, {}, {}] tp->api连接异常'.format( self.vertical_context.task_context.task_model.id, self.vertical_context.job_context.job_model.id, self.vertical_context.tc_context.tc_detail.id)) raise RuntimeError('api连接异常, {}'.format(str(e))) except RuntimeError as e: logger.exception('[{}, {}, {}] tp->api运行时异常, {}'.format( self.vertical_context.task_context.task_model.id, self.vertical_context.job_context.job_model.id, self.vertical_context.tc_context.tc_detail.id, str(e))) raise RuntimeError('api运行时异常, {}'.format(str(e)))