def get_use_case_run_log_count(): """ :return: """ param_kwarg = request.get_json() from_time = param_kwarg.get('from_time', None) to_time = param_kwarg.get('to_time', None) function_id = param_kwarg.get('function_id', None) use_case_name = param_kwarg.get('use_case_name', None) if from_time: from_time = shanghai_to_utc_timezone( datetime.strptime(from_time, QUERY_TIME_FMT)) param_kwarg.update({"from_time": from_time.strftime(QUERY_TIME_FMT)}) if to_time: to_time = shanghai_to_utc_timezone( datetime.strptime(to_time, QUERY_TIME_FMT)) param_kwarg.update({"to_time": to_time.strftime(QUERY_TIME_FMT)}) if function_id: use_case_info_list = UseCaseAPI.get_use_case(function_id=function_id) use_case_list = [ use_case_info.get('id') for use_case_info in use_case_info_list ] param_kwarg['use_case_id'] = use_case_list if use_case_name: use_case_info_list = UseCaseAPI.get_use_case_by_name(use_case_name) use_case_list = [ use_case_info.get('id') for use_case_info in use_case_info_list ] param_kwarg['use_case_id'] = use_case_list result = RunLogAPI.get_use_case_run_log_count(**param_kwarg) return jsonify({'success': True, 'res': result})
def use_case_detail(): """ 功能描述: 获取某个use_case的详细信息,包括其包含的interface列表 1. 根据use_case_id获取use_case基本信息 2. 根据use_case_id获取use_case与interface的关联信息 3. 根据关联信息的id查出所有interface的名称信息以及定义的参数信息 4. 信息整理并返回 :return: """ use_case_info = Case_API.get_use_case(**request.get_json(force=True))[0] use_case_info.update({'interface_list': []}) relation_interface_list = Case_API.get_relation( use_case_id=use_case_info.get('id')) for relation_interface in relation_interface_list: relation_interface.pop('use_case_id') relation_interface.pop('create_time') relation_interface.pop('update_time') interface_id = relation_interface.get('interface_id') interface_list = InterfaceAPI.get_interface(id=interface_id) relation_interface.update( {'interface_name': interface_list[0].get('interface_name')}) para_list = Case_API.get_case_parameter_relation( relation_id=relation_interface['id']) relation_interface.update({'param_list': para_list}) use_case_info['interface_list'].append(relation_interface) return jsonify({'success': True, 'res': use_case_info})
def run_batch(batch_id, environment_id=0, auto_run=False, alarm_monitor=False): """ 批次运行接口 :param batch_id: :param environment_id: :param auto_run: :param alarm_monitor: :return: """ start_timer = timeit.default_timer() relation_list = BatchAPI.get_batch_use_case_relation(batch_id=batch_id) use_case_count = len(relation_list) start_time = datetime.utcnow() batch_log_id = RunLogAPI.add_batch_run_log( **{ 'batch_id': batch_id, 'use_case_count': use_case_count, 'start_time': start_time }) counter = 0 for relation in relation_list: counter += 1 use_case = UseCaseAPI.get_use_case(id=relation['use_case_id'])[0] run_use_case_async(use_case['id'], batch_log_id, environment_id=environment_id, use_case_count=use_case_count, batch_start_timer=start_timer, auto_run=auto_run, alarm_monitor=alarm_monitor)
def get_use_case_run_log(): """ :return: """ from_time = request.get_json().get('from_time', None) to_time = request.get_json().get('to_time', None) function_id = request.get_json().get('function_id', None) use_case_name = request.get_json().get('use_case_name', None) if from_time: from_time = shanghai_to_utc_timezone( datetime.strptime(from_time, QUERY_TIME_FMT)) request.get_json().update( {"from_time": from_time.strftime(QUERY_TIME_FMT)}) if to_time: to_time = shanghai_to_utc_timezone( datetime.strptime(to_time, QUERY_TIME_FMT)) request.get_json().update( {"to_time": to_time.strftime(QUERY_TIME_FMT)}) if function_id: use_case_info_list = UseCaseAPI.get_use_case(function_id=function_id) use_case_list = [ use_case_info.get('id') for use_case_info in use_case_info_list ] request.get_json()['use_case_id'] = use_case_list if use_case_name: use_case_info_list = UseCaseAPI.get_use_case_by_name(use_case_name) use_case_list = [ use_case_info.get('id') for use_case_info in use_case_info_list ] request.get_json()['use_case_id'] = use_case_list '' if 'pageIndex' in request.get_json() else request.get_json().update( {'pageIndex': 1}) '' if 'pageSize' in request.get_json() else request.get_json().update( {'pageSize': 10}) result = RunLogAPI.get_use_case_run_log(**request.get_json()) use_case_id_list = [info['use_case_id'] for info in result] use_case_info_dict = UseCaseAPI.get_multi_use_case(use_case_id_list) for use_case_run_log_dict in result: use_case_id = use_case_run_log_dict.get('use_case_id') use_case_info = use_case_info_dict[use_case_id] use_case_name = use_case_info.get('use_case_name') use_case_run_log_dict.update({'use_case_name': use_case_name}) start_time = utc_to_shanghai_timezone( use_case_run_log_dict.get('start_time')) end_time = utc_to_shanghai_timezone( use_case_run_log_dict.get('end_time')) use_case_run_log_dict.update( {'start_time': datetime.strftime(start_time, QUERY_TIME_FMT)}) if end_time: use_case_run_log_dict.update( {'end_time': datetime.strftime(end_time, QUERY_TIME_FMT)}) else: use_case_run_log_dict.update( {'end_time': datetime.strftime(start_time, QUERY_TIME_FMT)}) return jsonify({'success': True, 'res': result})
def batch_search_use_case_list(): """ 获取use_case列表,不需要获取与use_case关联的interface :return: """ param_json = request.get_json() result = UseCaseAPI.get_use_case(**param_json) function_info_dict = MenuTreeAPI.query_line_relation() for use_case_info in result: use_case_info.update(function_info_dict[use_case_info['function_id']]) return jsonify({'success': True, 'res': result})
def del_environment_line(): """ 删除environment_line """ environment_line_id = EnvironmentAPI.del_environment_line( **request.get_json()) use_case_info_list = UseCaseAPI.get_use_case( environment_id=request.get_json().get('id')) for use_case_info in use_case_info_list: UseCaseAPI.modify_use_case(id=use_case_info.get('id'), environment_id=0) return jsonify({'success': True, 'res': environment_line_id})
def use_case_list(): """ 获取use_case列表,不需要获取与use_case关联的interface :return: """ param_json = request.get_json() page_index = int(param_json.pop('pageIndex')) if 'pageIndex' in param_json else 1 page_size = int(param_json.pop('pageSize')) if 'pageSize' in param_json else 10 result = Case_API.get_use_case(**param_json) if page_size == 0: return jsonify({'success': True, 'res': result}) if not(page_index and page_size): return jsonify({'success': True, 'res': result}) return jsonify({'success': True, 'res': result[(page_index - 1) * page_size:page_index * page_size]})
def get_batch_use_case_relation(): """ 查询某一个批次已添加的用例列表 :return:{'success': True, 'res': relation_use_case_list} """ result = BatchAPI.get_batch_use_case_relation(**request.get_json()) relation_use_case_id_list = [(res.get('use_case_id'), res.get('id')) for res in result] use_case_info_lst = [] for relation_id_use_case_id_tuple in relation_use_case_id_list: use_case_info = UseCaseAPI.get_use_case( id=relation_id_use_case_id_tuple[0])[0] use_case_info.update({'id': relation_id_use_case_id_tuple[1]}) use_case_info_lst.append(use_case_info) batch_use_case_relation_info = result[-1] batch_use_case_relation_info.pop('use_case_id') batch_use_case_relation_info.pop('id') batch_use_case_relation_info.update({'use_case_info': use_case_info_lst}) return jsonify({'success': True, 'res': batch_use_case_relation_info})
def batch_detail(): """ :return: """ batch = BatchAPI.get_batch(**request.get_json())[0] relation_list = BatchAPI.get_batch_use_case_relation(batch_id=batch['id']) batch['use_case_list'] = [] for relation in relation_list: use_case = UseCaseAPI.get_use_case(id=relation['use_case_id'])[0] batch['use_case_list'].append({ 'id': relation['id'], 'use_case_name': use_case['use_case_name'], 'desc': use_case['desc'] }) return jsonify({'success': True, 'res': batch})
try: use_case_log_id = RunLogAPI.add_use_case_run_log(**use_case_log_info) except Exception as e: return { 'success': False, 'error_str': '接口{0}数据库'.format(interface_count), 'res': exec_result_list, 'error': '{0}: {1}'.format(str(e.__class__.__name__), str(e)), 'batch_log_id': batch_log_id, 'use_case_count': use_case_count, 'batch_start_timer': batch_start_timer } # 获取用例信息以及用例下接口信息 try: use_case_info = UseCaseAPI.get_use_case(id=use_case_id)[0] if relation_id: interface_list = UseCaseAPI.get_relation(id=relation_id) else: interface_list = UseCaseAPI.get_relation(use_case_id=use_case_id) except Exception as e: use_case_exception_log_update(use_case_log_id, use_case_start) return { 'success': False, 'error_str': '接口{0}数据库'.format(interface_count), 'res': exec_result_list, 'error': '{0}: {1}'.format(str(e.__class__.__name__), str(e)), 'batch_log_id': batch_log_id, 'use_case_count': use_case_count, 'batch_start_timer': batch_start_timer }
def run_use_case(use_case_id, batch_log_id=None, environment_id=None, relation_id=None, use_case_count=None, batch_start_timer=None, auto_run=False, alarm_monitor=False): # if async: # engine.dispose() exec_result_list = [] interface_count = 1 # 信息初始化 start_time = datetime.utcnow() use_case_start = timeit.default_timer() run_pass = True use_case_log_info = { 'use_case_id': use_case_id, 'start_time': start_time, 'auto_run': auto_run } if batch_log_id: use_case_log_info['batch_run_log_id'] = batch_log_id try: use_case_log_id = RunLogAPI.add_use_case_run_log(**use_case_log_info) except Exception as e: error = '{0}: {1}'.format(str(e.__class__.__name__), str(e)) return except_result(interface_count, exec_result_list, error, batch_log_id, use_case_count, batch_start_timer) # 获取用例信息以及用例下接口信息 try: use_case_info = UseCaseAPI.get_use_case(id=use_case_id)[0] if relation_id: interface_list = UseCaseAPI.get_relation(id=relation_id) else: interface_list = UseCaseAPI.get_relation(use_case_id=use_case_id) except Exception as e: use_case_exception_log_update(use_case_log_id, use_case_start) error = '{0}: {1}'.format(str(e.__class__.__name__), str(e)) return except_result(interface_count, exec_result_list, error, batch_log_id, use_case_count, batch_start_timer) try: use_case_info['interface_list'] = [] # 对用例中使用预定义参数的做参数替换 for interface_relation in interface_list: eval_string = interface_relation['eval_string'] interface_id = interface_relation['interface_id'] interface_info = InterfaceAPI.get_interface(id=interface_id)[0] interface_info['interface_delay'] = interface_relation[ 'interface_delay'] interface_info['eval_string'] = eval_string interface_info['param_define_list'] = get_param_define_list( interface_relation['id']) use_case_info['interface_list'].append(interface_info) interface_list = use_case_info['interface_list'] except Exception as e: # 用例运行日志记录 use_case_exception_log_update(use_case_log_id, use_case_start) error = '{0}: {1}'.format(str(e.__class__.__name__), str(e)) return except_result(interface_count, exec_result_list, error, batch_log_id, use_case_count, batch_start_timer) function_id = use_case_info['function_id'] email_addrs = EmailAPI.query_email_by_function_id(function_id) addr_dicts = { email['email_address'].split('@')[0]: email['email_address'] for email in email_addrs } # 由于线上环境配置有host,所以监控模式下,也要配置环境信息 if batch_log_id: environment_id = environment_id else: environment_id = environment_id or use_case_info['environment_id'] environment_info = EnvironmentAPI.get_environment_line_info( environment_id=environment_id) url_map_ip = dict() for element in environment_info: url = element['url'].strip() ip_address = element['map_ip'].strip() url_map_ip[url] = ip_address encryption_dict = EncryptionAPI.get_encryption_id_to_name() with requests.Session() as session: for interface in interface_list: # 添加延时运行接口 interface_delay = int(interface.get('interface_delay')) if interface_delay > 0: time.sleep(interface_delay) interface_name = interface.get('interface_name') interface_log_dict = { 'interface_start_time': datetime.utcnow(), 'use_case_run_log_id': use_case_log_id, 'interface_id': interface['id'] } try: # 将接口未替换的参数全部替换 request_method = interface['interface_method'] result_list = get_item_to_rephrase( interface, exec_result_list, data_type=interface['body_type']) url, header, json_payload = result_list except Exception as e: # 数据处理以及日志记录 interface_log_dict['is_pass'] = False interface_log_dict['error_message'] = '参数替换: {0}: {1}'.format( str(e.__class__.__name__), str(e)) interface_log_insert(interface_log_dict) # 用例运行日志记录 use_case_exception_log_update(use_case_log_id, use_case_start) error = '{0}: {1}'.format(str(e.__class__.__name__), str(e)) return except_result(interface_count, exec_result_list, error, batch_log_id, use_case_count, batch_start_timer) try: # 加密 if interface['body_type'] == 0 and json_payload: requested_interface = get_remote_interface_name( json.loads(json_payload), interface, url) else: requested_interface = get_remote_interface_name( '', interface, url) if header: header = json.loads(header) if json_payload: if interface['interface_encryption'] != 0: encryption_method = encryption_dict[ interface['interface_encryption']] method = getattr(Encryption, encryption_method) if interface['interface_encryption'] in [1, 4]: header = method(json_payload, header) elif interface['interface_encryption'] == 5: url, json_payload = method(url, json_payload) else: json_payload = method(json_payload) except Exception as e: # 数据处理以及日志记录 print(e) interface_log_dict['is_pass'] = False interface_log_dict[ 'error_message'] = 'json处理或加密: {0}: {1}'.format( str(e.__class__.__name__), str(e)) interface_log_dict['s_header'] = str(header) interface_log_dict['s_payload'] = str(json_payload) interface_log_dict['interface_start'] = timeit.default_timer() interface_log_insert(interface_log_dict) # 用例运行日志记录 use_case_exception_log_update(use_case_log_id, use_case_start) error = '{0}: {1}'.format(str(e.__class__.__name__), str(e)) return except_result(interface_count, exec_result_list, error, batch_log_id, use_case_count, batch_start_timer) # 请求接口参数准备 request_kwargs = {'timeout': 30} if header: request_kwargs['headers'] = header else: request_kwargs['headers'] = dict() if json_payload: request_kwargs.update({'json': json_payload}) if interface['body_type'] == 0 \ else request_kwargs.update({"data": json_payload}) # 获取域名对应的服务名 server_name = get_server_name(url) # 获取方法ID, 接口名 # 日志内容 interface_log_dict['s_header'] = json.dumps( header, ensure_ascii=False) if header else '' if interface['body_type'] == 0: interface_log_dict['s_payload'] = json.dumps( json_payload, ensure_ascii=False) if json_payload else '' else: interface_log_dict['s_payload'] = json_payload interface_log_dict['interface_start'] = timeit.default_timer() request_exception = False log_report_code = 0 error_string = '' json_response = result = dict() request_method = request_method.upper() request_kwargs['headers']['Connection'] = 'close' try: url_netloc = url.rsplit('/') prefix = '//'.join([url_netloc[0], url_netloc[2]]) host_name = url_netloc[2] if environment_id: source_address = url_map_ip.get(host_name, None) session.mount(prefix, CustomAdapter(source_address=source_address)) r = session.request(request_method, url, **request_kwargs) time.sleep(0.01) r.encoding = 'utf-8' try: json_response = r.json() json_flag = True except Exception as e: json_flag = False r_type = r.headers['Content-Type'] if 'application/json' != r_type: json_response = r.content.decode() else: json_response = {} interface_log_dict['interface_stop'] = timeit.default_timer() result = { 'r_request': request_kwargs, 'status_code': r.status_code, 'header': dict(r.headers), 'json_response': json_response, 'interface_name': interface_name } interface_log_dict['r_code'] = r.status_code interface_log_dict['r_header'] = json.dumps(result['header'], ensure_ascii=False) if json_flag: interface_log_dict['r_payload'] = json.dumps( result['json_response'], ensure_ascii=False) elif interface['interface_encryption'] == 6: interface_log_dict['r_payload'] = json.dumps( json_response, ensure_ascii=False) else: r.encoding = 'utf-8' interface_log_dict['r_payload'] = r.text result['json_response'] = '<iframe srcdoc="{}" style="width:100%;height:60vh" ' \ 'frameborder="0"></iframe>'.format(html.escape(r.text)) except ConnectTimeout as e: request_exception = True error_string = '{0}: {1} ,{2}'.format( '请求服务连接超时', str(e.__class__.__name__), str(e)) log_report_code = '9991' except ConnectionError as e: if os.getpid() in g_DNS.get_dns(): dns_info = g_DNS.get_dns()[os.getpid()] LOGGER.info_log('连接失败,环境映射信息:{}, 当前url:{}'.format( dns_info, url)) request_exception = True error_string = '{0},{1}: {2}'.format('请求服务连接失败', str(e.__class__.__name__), str(e)) log_report_code = '9992' except KeyError as e: request_exception = True error_string = '错误代码行{0}: {1}'.format(sys._getframe().f_lineno, str(e)) log_report_code = '9993' except Exception as e: request_exception = True error_string = '{0}: {1},{2}'.format(sys._getframe().f_lineno, str(e.__class__.__name__), str(e)) log_report_code = '9994' finally: if request_exception: if alarm_monitor and not app.config['DEBUG']: cost_time = timeit.default_timer( ) - interface_log_dict['interface_start'] LOGGER.request_log(server_name, server_name, requested_interface, log_report_code, str(cost_time)) message = get_email_body( use_case_info['use_case_name'], interface_name, error_string, use_case_log_id) executor.submit(execute_fail_email, addr_dicts, message) # 数据处理以及日志记录 interface_log_dict['is_pass'] = False interface_log_dict['error_message'] = '{0}'.format( error_string) interface_log_insert(interface_log_dict) # 用例运行日志记录 use_case_exception_log_update(use_case_log_id, use_case_start) return except_result(interface_count, exec_result_list, error_string, batch_log_id, use_case_count, batch_start_timer) try: # 验证接口返回 eval_success = eval_interface_result(result, interface['eval_string'], exec_result_list) result['success'] = eval_success run_pass = run_pass and eval_success exec_result_list.append(result) # 数据处理以及日志记录 interface_log_dict['is_pass'] = result['success'] executor.submit(interface_log_insert, interface_log_dict) if alarm_monitor and not app.config['DEBUG']: executor.submit(monitor_request, interface_log_dict, json_response, eval_success, server_name, requested_interface) if not result['success']: message = get_email_body( use_case_info['use_case_name'], interface_name, '返回结果验证失败', use_case_log_id) executor.submit(execute_fail_email, addr_dicts, message) if not result['success']: break except Exception as e: result['success'] = False exec_result_list.append(result) # 数据处理以及日志记录 interface_log_dict['is_pass'] = result['success'] exc_type, exc_obj, exc_tb = sys.exc_info() error = '{0}: {1}'.format(str(e.__class__.__name__), str(e)) interface_log_dict['error_message'] = '验证: {0}: {1},异常信息:{2}'. \ format(str(e.__class__.__name__), str(e), str(traceback.extract_tb(exc_tb))) if alarm_monitor and not app.config['DEBUG']: message = get_email_body( use_case_info['use_case_name'], interface_name, interface_log_dict['error_message'], use_case_log_id) executor.submit(execute_fail_email, addr_dicts, message) interface_log_insert(interface_log_dict) # 用例运行日志记录 use_case_exception_log_update(use_case_log_id, use_case_start) return except_result(interface_count, exec_result_list, error, batch_log_id, use_case_count, batch_start_timer) interface_count += 1 # 用例运行日志记录 use_case_stop = timeit.default_timer() end_time = datetime.utcnow() RunLogAPI.modify_use_case_run_log( **{ 'id': use_case_log_id, 'is_pass': run_pass, 'end_time': end_time, 'cost_time': use_case_stop - use_case_start }) response = { 'pass': run_pass, 'res': exec_result_list, 'batch_log_id': batch_log_id, 'use_case_count': use_case_count, 'batch_start_timer': batch_start_timer } return response