diff options
| author | zhangchengwei <[email protected]> | 2022-09-05 16:36:28 +0800 |
|---|---|---|
| committer | zhangchengwei <[email protected]> | 2022-09-05 16:36:28 +0800 |
| commit | f6e94ebdd782e6e59d6270ea468fa100ac212a99 (patch) | |
| tree | 2a6204ae9d8cab4c604a20c902f26d660ae002a3 | |
| parent | 67b76148cfc5867b129163e9a24b1e27d1bfc8cc (diff) | |
增加airtest接口逻辑
| -rw-r--r-- | control/airtest_client_upper/airtest_api_test.py | 68 | ||||
| -rw-r--r-- | control/airtest_client_upper/airtest_client_api.bat | 6 | ||||
| -rw-r--r-- | control/airtest_client_upper/airtest_client_api.py | 182 | ||||
| -rw-r--r-- | control/airtest_server_api.py | 207 | ||||
| -rw-r--r-- | control/business.py | 68 | ||||
| -rw-r--r-- | control/control.py | 3 | ||||
| -rw-r--r-- | control/control_config.ini | 30 | ||||
| -rw-r--r-- | control/gunicorn_config.py | 52 | ||||
| -rw-r--r-- | control/tsg_log.py | 3 |
9 files changed, 598 insertions, 21 deletions
diff --git a/control/airtest_client_upper/airtest_api_test.py b/control/airtest_client_upper/airtest_api_test.py new file mode 100644 index 0000000..3193789 --- /dev/null +++ b/control/airtest_client_upper/airtest_api_test.py @@ -0,0 +1,68 @@ +import requests +import json +import os + + +#测试提交任务总代理接口 +def task(): + url = r"http://192.168.42.7:5000/task" + req_header = {"Content-Type": "application/json"} + data_info = { + "app_name": "python", + "app_operation": "./airtest_test/test1/test.py", + "test_device_id": "testapp", + "packet_name": "", + "upper_device_ip": "192.168.64.27", + "upper_device_id": "111111", # 预留参数 + } + data_info = json.dumps(data_info) + print(data_info) + r = requests.request("post", headers=req_header, url=url, data=data_info) + r_s = json.loads(r.text) + print(r_s) + + +#测试airtest任务中client端代理接口 +def airtest_case(): + url = r"http://127.0.0.1:5001/airtest_case" + url = r"http://192.168.64.27:5001/airtest_case" + req_header = {"Content-Type": "application/json"} + data_info = { + "app_name": "python", + "app_operation": "/airtest_test/test1/test.py", + "test_device_id": "testapp", + "packet_name": "" + } + data_info = json.dumps(data_info) + print(data_info) + #data_info = '{"app_name": "python", "app_operation": "./airtest_test/test1/test.py", "test_device_id": "testapp", "packet_name": ""}' + r = requests.request("post", headers=req_header, url=url, data=data_info) + print(r.text) + +#服务的airtest获取packek_name文件接口 +def upload_s_packet(): + url = r"http://192.168.42.7:5000/upload" + file_abs_path = "D:/zcw/py-auto/airtest_test/test1/api_test/2022082213343303200118349977-allow-only-IpAndApplication-sendMessage-airTest.pcap" + file_name = os.path.basename(file_abs_path) + file_data = {"file": (file_name, open(file_abs_path, "rb"))} + #req_header = {"Content-Type": "multipart/form-data"} + r = requests.request("POST", url=url, files=file_data) + print(r.text) + + +#airtest_client端上位机上传数据包 +def upload_packet(file_abs_path = "D:/zcw/py-auto/airtest_test/test1/api_test/2022082213343303200118349977-allow-only-IpAndApplication-sendMessage-airTest.pcap"): + #url = r"http://127.0.0.1:5001/upload_to_server" + url = r"http://192.168.50.19:5001/upload_to_server" + file_name = os.path.basename(file_abs_path) + file_data = {"file": (None, file_abs_path, "string")} + print(file_data) + r = requests.request("POST", url=url, files=file_data) + print(r.text) + + +if __name__ == '__main__': + #task() + #airtest_case() + #upload_s_packet() + upload_packet()
\ No newline at end of file diff --git a/control/airtest_client_upper/airtest_client_api.bat b/control/airtest_client_upper/airtest_client_api.bat new file mode 100644 index 0000000..350058f --- /dev/null +++ b/control/airtest_client_upper/airtest_client_api.bat @@ -0,0 +1,6 @@ +@echo off +reg add HKEY_CURRENT_USER\Console /v QuickEdit /t REG_DWORD /d 00000000 /f +D: +cd D:\Airtest_client_upper +python D:\Airtest_client_upper\airtest_client_api.py +pause
\ No newline at end of file diff --git a/control/airtest_client_upper/airtest_client_api.py b/control/airtest_client_upper/airtest_client_api.py new file mode 100644 index 0000000..a961425 --- /dev/null +++ b/control/airtest_client_upper/airtest_client_api.py @@ -0,0 +1,182 @@ +# coding=utf-8 +from gevent import monkey +monkey.patch_all() +import os.path +import time +import json +from flask import Flask, request, make_response, jsonify +from gevent import pywsgi +import requests +import subprocess +from concurrent.futures import ThreadPoolExecutor + + +#airtest脚本路径 +airtest_client_path = r"D:\App_automation\air_test_auto\control.py" +airtest_server_ip = "192.168.42.7" #airtest_server服务层代理IP +airtest_server_port = 5000 #airtest_server服务器代理端口 + +#airtest_server接口uri +airtest_server_device_info_url = "/device_info" #airtest_server代理提交设备信息地址 +airtest_server_upload = "/upload" + + +app = Flask(__name__) +app.config['JSON_AS_ASCII'] = False + [email protected]("/client") +def client(): + print("cient") + return "client" + [email protected]("/client1") +def client1(): + print("cient1") + time.sleep(50) + return "client1" + + [email protected]("/airtest_case", methods=["POST"]) #上位机c端代理提供s端代理调用的执行任务接口 +def airtest_case(): + #上位机根据任务信息执行airtest脚本,并将结果返回 + if request.method == "POST": + airtest_case_info = request.json + # 上位机实际处理任务函数 + print(f"airtest_server传过来的参数:{airtest_case_info}") + test_device_id = airtest_case_info["test_device_id"] + app_name = airtest_case_info["app_name"] + app_operation = airtest_case_info["app_operation"] + packet_name = airtest_case_info["packet_name"] + # -d = test_device_id, -n = app_name, -o = app_operation, -p = packet_name + airtest_exec_cmd = " python {} -d {} -n {} -o {} -p {}".format(airtest_client_path, test_device_id, app_name, + app_operation, packet_name) + print("执行命令:{}".format(airtest_exec_cmd)) + airtest_case_task = subprocess.Popen(airtest_exec_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, + shell=True) + exec_result = "" + while True: + exec_result_1 = airtest_case_task.stdout.readline() + try: + exec_result_1 = exec_result_1.decode("gbk") + except: + exec_result_1 = exec_result_1.decode("utf-8") + exec_result_1 = exec_result_1.encode().decode() + exec_result += exec_result_1 + print(exec_result_1, end="") + if exec_result_1 == "": + time.sleep(0.5) + if exec_result_1 == "": + break + else: + exec_result_1 = "" + + # 配置返回数据 + return_info = { + "code": 200, + "success": 0, + "msg": "" + } + status_code = make_response().status_code + return_info["code"] = status_code + return_info["msg"] = exec_result + print(f"测试用例执行结果{exec_result}") + if "The test case succeeded" in exec_result: + return_info["success"] = 0 + else: + return_info["success"] = 1 + print(f"airtest脚本执行结果:{return_info}") + return jsonify(return_info) + [email protected]("/upload_to_server", methods=["POST"]) #airtest_client 上位机代理数据上传接口 +def upload_to_server(): + if request.method == "POST": + print(request.form) + file_abs_name = request.form.get("file") + #调用airtest_sercer服务器代理上传文件接口 + url = "http://{}:{}{}".format(airtest_server_ip, airtest_server_port, airtest_server_upload) + file_name = os.path.basename(file_abs_name) + file_data = {"file": (file_name, open(file_abs_name, "rb"))} + n = 0 + while True: + try: + r = requests.request("post", url=url, files=file_data) + except: + n += 1 + print("调用fusion上次文件接口失败:{}".format(url)) + if n == 3: + return jsonify({"code": 1, "data": {}, "msg": "上传失败"}) + continue + print(r.text) + return jsonify({"code": 0, "data": {}, "msg": "上传成功"}) + + + [email protected]("/upload_c_packet") #airtest_client层,接收上层代理下发的获取捕包文件接口,暂时不使用此方式 +def upload_packet(): + #上传捕包文件脚本 + if request.method == "GET": + packet_name = request.args.get("packet_name") + # 处理捕包文件脚本 + print(f"airtest_client上位机层收到获取捕包数据文件通知:{packet_name}") + return "上位机处理捕包上传文件" + +# 获得device信息,并提交给server端接口 +def call_server_device_info_api(): + #获取本机和连接的测试设备数据 + global airtest_server_ip, airtest_server_port, airtest_server_device_info_url + device_info = { + "upper_device_name": "host1", + "upper_device_ip": "192.168.50.5", + "test_device_info": [ + { + "test_device_type": "mobile", + "test_device_name": "huiwei", + "test_device_ip": "192.168.50.3", + }, + { + "test_device_type": "simulator", + "test_device_name": "leidian", + "test_device_ip": "192.168.50.20", + } + ]} + device_info = json.dumps(device_info) + #调用提交给server接口 + req_header = {"Content-Type": "application/json"} + print(device_info) + url = "http://{}:{}{}".format(airtest_server_ip, airtest_server_port, airtest_server_device_info_url) + r_call_server_deviceinfo_api = requests.request("post", url=url, headers=req_header, data=device_info) + print(r_call_server_deviceinfo_api.text) + +#定时收集上位机ip信息,连接的设备信息(模拟器ip、真机ip、使用情况信息),并上传给server端 +def submit_device_info(): + n = 0 + while True: + #将本机信息提交到server的deviceinfo接口 + call_server_device_info_api() + print(f"搜集上位机和设备的信息:{n}") + time.sleep(100) + n += 1 + +def airtest_client_api_agent(): + app.debug = True + #app.run(host="0.0.0.0", port=5001) + server = pywsgi.WSGIServer(("0.0.0.0", 5001), app) + server.serve_forever() + +def current_thread(): + current_task = ThreadPoolExecutor(max_workers=2) + current_task.submit(airtest_client_api_agent) + current_task.submit(submit_device_info) + +if __name__ == '__main__': + print(11111111111) + #current_thread() + + # app.debug = True + # app.run(host="0.0.0.0", port=5001) + + server = pywsgi.WSGIServer(("0.0.0.0", 5001), app) + server.serve_forever() + + + print(22)
\ No newline at end of file diff --git a/control/airtest_server_api.py b/control/airtest_server_api.py new file mode 100644 index 0000000..c3503cd --- /dev/null +++ b/control/airtest_server_api.py @@ -0,0 +1,207 @@ +#!/usr/bin/python3 +# -*- coding: utf-8 -*- +import shutil +import sys +import os +sys.path.append(r"/opt/test") +import json +from flask import Flask, request, make_response, jsonify +from werkzeug.utils import secure_filename +from gevent import pywsgi +from gevent import monkey +import requests +import copy +import random +import time +import traceback +import configparser +from business import config_abs_path, tsglogger_fun +from automation.control.tsg_log import TsgLogger + +# 将python标准的io方法,都替换成gevent中同名的方法,遇到io阻塞gevent自动进行协程切换 +#monkey.patch_all() + + +airtest_client_port = 5001 #airtest_client上位机层代理端口 +airtest_client_upload_c_packet_url = "/upload_c_packet" #airtest_client上位机层代理提交数据包接口 +airtest_client_airtest_case_url = "/airtest_case" #airtest_client上位机层代理调用任务接口 + + +#获得脚本文件所在的根路径 +abs_script_path = __file__ +work_path = os.path.split(abs_script_path)[0] + +app = Flask(__name__) + + +def airtestlogger_fun(instructNo): + config_parse = configparser.ConfigParser() + config_parse.read(config_abs_path) + root_path = config_parse.get("path_info", "root_path") + log_file_name0 = config_parse.get("log_info", "airtest_file_name") + log_file_name = root_path + log_file_name0 + log_file_level = config_parse.get("log_info", "log_file_level") + log_confole_level = config_parse.get("log_info", "log_console_level") + + tsglogger = TsgLogger(log_file_name, file_level=log_file_level, console_level=log_confole_level, instructNo=instructNo).getLogger() + return tsglogger + + + [email protected]("/server") +def server(): + airtest_logger = airtestlogger_fun("0000000000") + airtest_logger.info("server:{}".format(time.time())) + print("server") + return "server" + [email protected]("/device_info", methods=["POST"]) #服务端获取设备信息接口 +def device_info(): #获取设备信息,包括上位机IP、连接设备类型信息(模拟器IP、真机ip) + if request.method == "POST": + device_info = request.json + # 获得设备信息 + print("-----{}".format(random.randint(1, 8))) + print("得到上位机和其测试设备信息{}".format(device_info)) + # 将设备信息维护一个字典 + return "设备信息" + + [email protected]("/task", methods=["POST"]) #提交任务总代理接口 +def task(): #获取任务,并派给执行函数 + task_dict = request.json + #创建log日志数据文件 + if task_dict["packet_name"]: + task_id = task_dict["packet_name"].split("-")[0] + else: + task_id = "0000000000" + airtest_logger = airtestlogger_fun(task_id) + + # 获取任务,从传来的数据中获取url和data数据 + #print(f"robotframework传来的参数:{task_dict}") + airtest_logger.info(f"robotframework传来的参数:{task_dict}") + airtest_logger.info("临时记录时间{}".format(time.time())) + global airtest_client_port, airtest_client_airtest_case_url + upper_device_ip = task_dict["upper_device_ip"] + + # if upper_device_ip == "192.168.50.19": + # upper_device_ip = "192.168.64.27" + # upper_device_ip = "192.168.50.19" + + url = "http://{}:{}{}".format(upper_device_ip, airtest_client_port, airtest_client_airtest_case_url) #airtest_client的调用任务的url + airtest_client_data = copy.deepcopy(task_dict) + airtest_client_data.pop("upper_device_ip") + airtest_client_data.pop("upper_device_id") + #转化成json格式 + data = json.dumps(airtest_client_data) + #print(f"传给airtest_client端的参数:{data}") + airtest_logger.info(f"传给airtest_client端接口{url}的参数:{data}") + # 根据设备使用情况,下发到对应设备接口执行 + result = exec_airtet_case(url, data, airtest_logger) + # 获取最终执行结果 + return result + [email protected]("/upload_s_packet") #server获取数据包接口,呈上,供给control调用。暂不使用,捕包文件直接调用上次接口即可。 +def upload_s_packet(): + #server获取数据包接口 + if request.method == "GET": + packet_name = request.args.get("packet_name") + upper_device_ip = request.args.get("upper_device_ip") + # 实际处理上传的捕包数据 + print(f"control层请求需要回传的数据包名称参数:{packet_name},获取数据脚本的上位机ip:{upper_device_ip}") + global airtest_client_port, airtest_client_upload_c_packet_url + # 调用airtest_clent层上位机的提供捕包文件的接口 + url = "http://{}:{}{}".format(upper_device_ip, airtest_client_port, airtest_client_upload_c_packet_url) + params_dict = {"packet_name": packet_name} + r = requests.request("get", url=url, params=params_dict) + print(r.text) + return r.text + [email protected]("/upload", methods=["POST"]) #server层代理实际上传文件接口 +def upload(): + if request.method == "POST": + f = request.files + print(f) + f = f["file"] + f_name = secure_filename(f.filename) + print("上传文件名称:{}".format(f_name)) + packet_dir_name = os.path.join(os.path.dirname(work_path), "airtest_packet") + if not os.path.exists(packet_dir_name): + os.mkdir(packet_dir_name) + packet_file_name = os.path.join(packet_dir_name, secure_filename(f_name)) + f.save(packet_file_name) + f_id = f_name.split("-")[0] + airtest_logger = airtestlogger_fun(f_id) + print("文件保存的绝对路径:{}".format(packet_file_name)) + airtest_logger.info("捕包数据文件保存的绝对路径:{}".format(packet_file_name)) + print("文件所属任务id:{}".format(f_id)) + #调用fusion中agent的上次文件接口,将数据查到fusion中。 + config = configparser.ConfigParser() + config.read(config_abs_path) + fusion_host = config.get("interface_info", "fusion_host") + upload_url = "{}/callback/uploadlocal/{}".format(fusion_host, f_id) + file_data = {"file": (None, packet_file_name, "String")} + n = 0 + while True: + try: + r = requests.request("post", url=upload_url, files=file_data) + except: + n += 1 + print("调用fusion上次文件接口失败:{}".format(upload_url)) + if n == 3: + airtest_logger.error("调用fusion上次文件接口失败:{}".format(upload_url)) + return "调用fusion上次文件接口失败:{}".format(upload_url) + continue + break + print(r.text) + airtest_logger.info("上传数据文件返回的结果".format(r.text)) + + #情况5天前的文件 + now_time = time.time() + delete_time = now_time - 3600*24*5 + clear_dir_list = os.listdir(packet_dir_name) + if len(clear_dir_list) > 0: + for path in clear_dir_list: + abs_path = os.path.join(packet_dir_name, path) + abs_path_ctime = os.path.getctime(abs_path) + if abs_path_ctime <= delete_time: + try: + shutil.rmtree(abs_path) + except: + os.remove(abs_path) + + return "{}".format(make_response().status_code) + +#调用执行airtest执行接口,执行任务 +def exec_airtet_case(url, data, airtest_logger): + #调用执行结果执行任务,并获取结果 + req_header = {"Content-Type": "application/json"} + print("下发任务给airtest_client_上位机接口地址:{},数据:{}".format(url, data)) + n = 0 + while True: + try: + r = requests.request("post", url=url, headers=req_header, data=data) + except Exception as e: + print(e) + traceback.print_exc() + n += 1 + print(f"连接失败次数:{n}, 连接地址:{url}") + if n == 3: + print(f"连接失败,连接地址{url}") + airtest_logger.error(f"连接失败,连接地址{url}") + return f"连接失败,连接地址{url}" + continue + break + result = r.text + #print("上位机接口:{},执行用例数据{},执行结果{}".format(url, data, result)) + airtest_logger.info("上位机接口:{},执行用例数据{},执行结果{}".format(url, data, result)) + return result + + + +if __name__ == '__main__': + + app.debug = True + app.run(host="0.0.0.0", port=5000) + + # server = pywsgi.WSGIServer(("0.0.0.0", 5000), app) + # server.serve_forever() diff --git a/control/business.py b/control/business.py index 0a6ad26..1b1f357 100644 --- a/control/business.py +++ b/control/business.py @@ -13,6 +13,7 @@ import sys import subprocess import requests import copy +import traceback from scapy.all import AsyncSniffer, wrpcap, sniff from threading import Thread, RLock from concurrent.futures import ThreadPoolExecutor, as_completed, wait, ALL_COMPLETED @@ -166,6 +167,13 @@ def clear_historical_reort(instructNo_setup_json_abs_path, tsglogger): :param instructNo_setup_json_abs_path: #/opt/test/automation/tasks/2022052717210703000103027569/setup_2022052717210703000103027569.json :return: """ + try: #测试使用的 + a = 1 + b = 1 + c = a + b + except Exception as e: + tsglogger.error("异常:{}".format((traceback.format_exc()))) + tsglogger.info("开始函数:{}".format(clear_historical_reort.__name__)) #print("清楚历史数据...:{}".format(instructNo_setup_json_abs_path)) tsglogger.info("清楚历史数据...:{}".format(instructNo_setup_json_abs_path)) @@ -191,6 +199,7 @@ def clear_historical_reort(instructNo_setup_json_abs_path, tsglogger): dir_ctime = os.path.getctime(dir_abs_path) except Exception as e: tsglogger.error(e) + tsglogger.error("异常:{}".format((traceback.format_exc()))) continue #print(dir_abs_path) #tsglogger.info(dir_abs_path) @@ -202,6 +211,7 @@ def clear_historical_reort(instructNo_setup_json_abs_path, tsglogger): os.remove(dir_abs_path) except Exception as e: tsglogger.error(e) + tsglogger.error("异常:{}".format((traceback.format_exc()))) #删除agent server上的report历史文件: agent_server_host = Linux(ip="192.168.42.4", username="root", password="Xxg-LAB<>90", tsglogger=tsglogger) agent_server_host.connect() @@ -235,7 +245,8 @@ def get_setup_abs_path(instructNo, tsglogger): setup_json_name1 = i except Exception as e: tsglogger.error("没有setup文件") - tsglogger.exception(e) + tsglogger.error(e) + tsglogger.error("异常:{}".format((traceback.format_exc()))) else: instructNo_setup_json_abs_path = root_path + "/automation/tasks/" + instructNo + "/" + setup_json_name1 tsglogger.debug("返回参数,instructNo_setup_json_abs_path:".format(instructNo_setup_json_abs_path)) #通过instrucNo重组setup绝对路径,后面会使用 @@ -359,7 +370,7 @@ def execute_combine_capture_packet(robot_command, tsglogger): #ip = "192.168.42.97" #eth = "eth0" - ip = "192.168" + #ip = "192.168.64.27" tsglogger.debug(f"捕包网卡信息:{eth}") tsglogger.debug(f"捕包的ip信息:{ip}") #tsglogger.error("测试信息。。。") @@ -536,6 +547,7 @@ def get_case_name_from_output_xml(dryrun_output_list,instructNo_setup_json_abs_p output_tree = ET.ElementTree(file=dryrun_output_name_abs_path) except Exception as e: tsglogger.error("没有dryrun命令生成的output.xml文件") + tsglogger.error("异常:{}".format((traceback.format_exc()))) #tsglogger.execption(e) #suit相关信息的列表 suite_info_list = [] @@ -641,7 +653,8 @@ def callback_callback_dryrun_report(generate_case_json, instructNo, tsglogger): r_callback_casereport_text = json.loads(r_callback_casereport.text, encoding="utf-8") except Exception as e: tsglogger.error("从dryrun生成的caselist到fusion接口数据,提交失败") - tsglogger.exception(e) + tsglogger.error(e) + tsglogger.error("异常:{}".format((traceback.format_exc()))) n += 1 time.sleep(0.5) continue @@ -697,6 +710,7 @@ def callback_rest_result_report(instructNo, tsglogger): n += 1 tsglogger.error(e) tsglogger.info(e) + tsglogger.error("异常:{}".format((traceback.format_exc()))) continue else: tsglogger.info(f"提交case返回的响应信息:{r_callback_casereport_text}") @@ -757,6 +771,7 @@ def callbaock_upload_result_file(file_path, instructNo, tsglogger): n += 1 tsglogger.error("调用总结果{}的绝对路径接口失败".format(data)) tsglogger.error(e) + tsglogger.error("异常:{}".format((traceback.format_exc()))) continue else: tsglogger.info(f"响应参数:{r_callback_upload_file_test}") @@ -1023,8 +1038,8 @@ def combine_execute_testcase_commond(execute_case_and_client_list, dryrun_comman :return:caselist、运行robot命令、client信息的对应列表 """ """ - cd /home/hbn/gap_tsg_api0907/ && python -m robot.run -d newsreport/220313 --output test.xml --log test.html --report test.html --dry --pythonpath . --test allow-fqdn-suffix gap_tsg_api/case/policies/security/http.robot - cd /home/hbn/gap_tsg_api0907/ && python -m robot.run -v defaultIp:1.1.1.1 -d newsreport/220313 --output test.xml --log test.html --report test.html --pythonpath . --test allow-fqdn-suffix gap_tsg_api/case/policies/security/http.robot + cd /home/hbn/gap_tsg_api0907/gap_tsg_api/ && python -m robot.run -d newsreport/220313 --output test.xml --log test.html --report test.html --dry --pythonpath . --test allow-fqdn-suffix case/policies/security/http.robot + cd /home/hbn/gap_tsg_api0907/gap_tsg_api/ && python -m robot.run -v defaultIp:1.1.1.1 -d newsreport/220313 --output test.xml --log test.html --report test.html --pythonpath . --test allow-fqdn-suffix case/policies/security/http.robot """ """通过linux命令,执行robot的dryrun命令,并生成dryrun文件""" tsglogger.info(f"开始函数:{combine_execute_testcase_commond.__name__}") @@ -1041,7 +1056,8 @@ def combine_execute_testcase_commond(execute_case_and_client_list, dryrun_comman if cases[0] == case: #只为了执行第一个元素 for i in range(len(case)): case_name = case[i][0].split("/") - case_name:list = case_name[case_name.index("gap_tsg_api"):] + case_name:list = case_name[case_name.index("case"):] + #case_name:list = case_name[case_name.index("gap_tsg_api"):] case_name0 = "/".join(case_name[:-1]) case_name0 = " " + case_name[-1] + " " + case_name0 + ".robot" case_name1 = dryrun_command + " --test " + case_name0 @@ -1098,6 +1114,7 @@ def get_mobile_info_dict(): global config_abs_path control_config.read(config_abs_path) eth_info = control_config.get("mobile_info", "mobile_info_dict") + eth_info = eth_info.lower() #全部转换为小写 mobile_info_dict = json.loads(eth_info) return mobile_info_dict @@ -1155,13 +1172,17 @@ def capture_packet_and_execute_robot(robot_command, client_info, f_dict, common_ mobile_case_rlock.acquire() tsglogger.info("手机客户度信息" + client_info["incomingMobileClientInfo"]["clientModule"]) case_old_id = mobile_case_id_list.index(robot_command) #只是使用索引号做为遍历的起点,没有其它的作用 - mobile_info_allow_case_list = mobile_info_dict[client_info["incomingMobileClientInfo"]["clientModule"]] - + try: + mobile_info_allow_case_list = mobile_info_dict[(client_info["incomingMobileClientInfo"]["clientModule"]).lower()] + except: + tsglogger.error("异常:{}".format((traceback.format_exc()))) + tsglogger.error("在{} 中没有 {}".format(mobile_info_dict, (client_info["incomingMobileClientInfo"]["clientModule"]).lower())) + exit(1) for case_id in range(case_old_id, len(mobile_case_list)): #负载均衡可以手机设备可以执行的用例 mobile_case_list 这个列表才是实际取case的 robot_command_0 = mobile_case_list[case_id] signal = 0 for mobile_info_allow_case in mobile_info_allow_case_list: - if mobile_info_allow_case in robot_command_0: + if mobile_info_allow_case in robot_command_0.lower(): signal = 1 mobile_case_list[case_id] = mobile_case_list[case_old_id] mobile_case_list[case_old_id] = robot_command_0 @@ -1191,7 +1212,7 @@ def capture_packet_and_execute_robot(robot_command, client_info, f_dict, common_ for key, values in mobile_info_dict.items(): #筛选出case命令中可以执行使用的手机设备 signal_1 = 0 for value in values: - if value in robot_command: + if value in robot_command.lower(): client_info_0 = key client_info_0_list.append(client_info_0) signal_1 = 1 @@ -1220,20 +1241,35 @@ def capture_packet_and_execute_robot(robot_command, client_info, f_dict, common_ common_var_str = "" for var in common_configration_variable_list: common_var_str += " -v " + str(var[0]) + ":" + str(var[1]) + " " + #将common_var_str中添加packet_name变量,供给airtest使用,捕包时,传数据包名字。不捕包时,传空值。 + if str(pactureParm) == "1": #捕包参数时,传packet_name变量值非空 + packet_name = "{}-{}".format(instructNo, robot_command.split()[-2]) + common_var_str = "{} -v packet_name:{} ".format(common_var_str, packet_name) + else: + common_var_str = "{} -v packet_name:{} ".format(common_var_str, "") + #重组需要执行的robot_command命令 robot_command = re.sub("-v.*--pythonpath", "-v \"" + list(client_info.keys())[0] + ":" + str(list(client_info.values())[0]) + "\" {} --pythonpath ".format(common_var_str), robot_command) - if str(pactureParm) == "1": #判断是否捕包 + if (str(pactureParm) == "1") and ("incomingMobileClientInfo" not in robot_command): #判断是否捕包,且phone用例不捕包 dpkt = execute_combine_capture_packet(robot_command, tsglogger) - execute_commond_of_robot(robot_command, f_dict, tsglogger) - if str(pactureParm) == "1": + execute_result = execute_commond_of_robot(robot_command, f_dict, tsglogger) + tsglogger.debug("执行测试case的返回结果:{}".format(execute_result)) + tsglogger.debug("执行测试case的的status:{}".format(execute_result["status"])) + if (str(pactureParm) == "1") and ("incomingMobileClientInfo" not in robot_command): #判断是否捕包,且phone用例不捕包 dpkt[0].kill() #dpk = [dpkt, [source_file_info]] + time.sleep(0.5) tsglogger.info(f"线程:{threading.current_thread().name}:完成捕包") #回传捕包数据文件 - tsglogger.info(f"线程:{threading.current_thread().name}:开始回传捕包数据文件") - callbaock_upload_result_file(dpkt[1], instructNo, tsglogger) - tsglogger.info(f"线程:{threading.current_thread().name}:完成回传捕包数据文件") + if execute_result["status"] == 1: #{"case":case_name, "status":1} 1为执行失败,需要回传捕包数据 + tsglogger.info(f"线程:{threading.current_thread().name}:开始回传捕包数据文件") + tsglogger.info("测试失败的用例,需要回传的捕包文件:{}".format(dpkt[1][0])) + callbaock_upload_result_file(dpkt[1], instructNo, tsglogger) + tsglogger.info(f"线程:{threading.current_thread().name}:完成回传捕包数据文件") + else: #{"case":case_name, "status":0} 删除捕包文件 + tsglogger.info("测试通过的用例,需要删除的捕包文件:{}".format(dpkt[1][0])) + os.remove(dpkt[1][0]) client_info_dict[threading_name][1] = 1 #将设备资源重新设置为可以状态 tsglogger.info(f"结束函数:{capture_packet_and_execute_robot.__name__}") diff --git a/control/control.py b/control/control.py index 3a45d12..1881fd8 100644 --- a/control/control.py +++ b/control/control.py @@ -105,7 +105,8 @@ def executeAutomation(instructNo, runMode, onlyDryrun, kill): else: #不检验版本信息 tsglogger.info("无需校验版本信息!") # 获取执行列表中生成dryrun文件命令,重新组合dryrun命令 - dryrun_command_front_past = "cd /opt/test/automation/scripts/ && python3 -m robot.run -d newsreport/220313 --output test.xml --log test.html --report test.html --dry --pythonpath . " + dryrun_command_front_past = "cd /opt/test/automation/scripts/gap_tsg_api/ && python3 -m robot.run -d newsreport/220313 --output test.xml --log test.html --report test.html --dry --pythonpath . " + #dryrun_command_front_past = "cd /opt/test/automation/scripts/ && python3 -m robot.run -d newsreport/220313 --output test.xml --log test.html --report test.html --dry --pythonpath . " for i in range(len(f_dict["commandList"])): f_dict["commandList"][i] = dryrun_command_front_past + f_dict["commandList"][i] dryrun_command_list = f_dict["commandList"] diff --git a/control/control_config.ini b/control/control_config.ini index 4dc04f2..dc19be2 100644 --- a/control/control_config.ini +++ b/control/control_config.ini @@ -11,6 +11,7 @@ incoming_common_variable = /opt/test/automation/scripts/gap_tsg_api/variable [log_info] log_file_name = /automation/tsgauto_log/tsgauto.log +airtest_file_name = /automation/tsgauto_log/airtest_case.log log_file_level = DEBUG log_console_level = INFO @@ -19,16 +20,37 @@ log_console_level = INFO capture_eth = ens16 [mobile_info] -mobile_info_dict = { +#itest使用的测试环境 +mobile_info_dict1 = { "vivoV2031A":["facebook", "freegate", "gmail", "instagram", "instagram", "psiphon3", "qq", "skype", "tachyon", - "taobao", "telegram", "tor", "twitter", "wechat", "whatsapp", "wireguard", "youtube"], + "taobao", "telegram", "tor", "twitter", "wechat", "whatsapp", "wireguard", "youtube", "baidu"], "iphone12":["facebook", "gmail", "instagram", "instagram", "psiphon3", "qq", "skype", "tachyon", - "taobao", "telegram", "tor", "twitter", "wechat", "whatsapp", "wireguard", "youtube"], + "taobao", "telegram", "tor", "twitter", "wechat", "whatsapp", "wireguard", "youtube", "baidu"], "xiaomi":["freegate", "psiphon3", "tachyon", "tor"], "iphoneXR":["freegate", "psiphon3", "tachyon", "youtube"] } +#airtest使用的测试环境 +mobile_info_dict = { + "thunder": ["wechat", "facebook", "Instagram", "gmail", "twitter", "youtube", "qq", "taobao", "bilibili", "V4C", "UGVPN", "TorVPN"], + "free": ["telegram","skype", "whatsapp", "V4C", "UGVPN", "VPNlat", "anonytun_vpn", "urbanVPN", "TurboVPN_mm", "FlashVPN", "ProtonVPN", "Freegate", "TachyonVPN", "visitWebsite", "TorVPN"], + "mumu": ["baidu","psiphon3"], + "honor": ["telegram", "wechat", "facebook", "Instagram", "gmail", "skype", "youtube", "baidu", "qq", "taobao", "bilibili", "psiphon3", "Freegate", "TachyonVPN", "UGVPN", "anonytun_vpn", "TurboVPN_mm", "FlashVPN"], + "vivoV2031A": ["telegram", "wechat", "facebook", "Instagram", "gmail", "skype", "twitter", "youtube", "baidu", "qq", "taobao", "bilibili", "psiphon3", "Freegate", "TachyonVPN", "TorVPN", "TorBrowser", "V4C", "UGVPN", "VPNlat", "anonytun_vpn", "urbanVPN", "TurboVPN_mm", "FlashVPN", "ProtonVPN"], + "xiaomi": ["telegram", "wechat", "facebook", "gmail", "skype", "twitter", "baidu", "qq", "taobao", "bilibili", "psiphon3", "UGVPN", "anonytun_vpn", "FlashVPN", "TurboVPN_mm"], + "yijia": ["telegram", "wechat", "facebook", "Instagram", "gmail", "skype", "twitter", "youtube", "baidu", "qq", "taobao", "bilibili", "psiphon3", "Freegate", "TachyonVPN", "TorVPN", "TorBrowser", "V4C", "UGVPN", "VPNlat", "anonytun_vpn", "urbanVPN", "TurboVPN_mm", "FlashVPN", "ProtonVPN"] + } + +mobile_info_dict2 = { + "thunder":["wechat", "facebook", "Instagram", "gmail", "twitter", "youtube", "qq", "taobao", "bilibili", "V4C", "UGVPN", "TorVPN"], + "free":["telegram","skype", "whatsapp", "V4C", "UGVPN", "VPNlat", "anonytun_vpn", "urbanVPN", "TurboVPN_mm", "FlashVPN", "ProtonVPN", "Freegate", "TachyonVPN", + "visitWebsite", "TorVPN"], + "mumu":["baidu","psiphon3"], + "honor":[], + "vivoV2031A":["telegram", "V4C"] + } + [report_retention_time] control_layer_retention_time = 3 -agent_server_layer_retention_time = 15 +agent_server_layer_retention_time = 10 agent_server_layer_cache_retention_time = 2
\ No newline at end of file diff --git a/control/gunicorn_config.py b/control/gunicorn_config.py new file mode 100644 index 0000000..f136ad6 --- /dev/null +++ b/control/gunicorn_config.py @@ -0,0 +1,52 @@ +import os +import gevent.monkey +gevent.monkey.patch_all() + +import multiprocessing + +debug = True +#gunicorn + gevent部署 +#https://blog.csdn.net/wf1722029940/article/details/120493808 +#https://blog.csdn.net/weixin_46072106/article/details/109708788 +#https://www.cnblogs.com/fengff/p/9225859.html +#gunicorn -c gunicorn_config.py flask_server:app +#gunicorn -c gunicorn_config.py airtest_server_api:app + + +#预加载资源 +preload_app = True + +#绑定ip +bind = "0.0.0.0:5000" + +#进程数量 +workers = multiprocessing.cpu_count() * 2 + 1 + +#线程数量 +threads = multiprocessing.cpu_count() * 10 + +# 等待队列最大长度,超过这个长度的链接将被拒绝连接 +backlog = 2048 + +# 工作模式--协程 +worker_class = "gevent" + +# 最大客户客户端并发数量,对使用线程和协程的worker的工作有影响 +# 服务器配置设置的值 1200:中小型项目 上万并发: 中大型 +# 服务器硬件:宽带+数据库+内存 +# 服务器的架构:集群 主从 +worker_connections = 1200 + +# 进程名称 +proc_name = 'gunicorn.pid' +# 进程pid记录文件 +pidfile = 'airserverlog/app_run.log' +# 日志等级 +loglevel = 'debug' +# 日志文件名 +logfile = 'airserverlog/debug.log' +# 访问记录 +accesslog = 'airserverlog/access.log' +# 访问记录格式 +access_log_format = '%(h)s %(t)s %(U)s %(q)s' + diff --git a/control/tsg_log.py b/control/tsg_log.py index b15e235..f4ab86e 100644 --- a/control/tsg_log.py +++ b/control/tsg_log.py @@ -64,6 +64,9 @@ class TsgLogger(): self.logger.setLevel(logging.DEBUG) self.instrucNO = instructNo + if self.logger.handlers: + self.logger.handlers.clear() + stream_handler = logging.StreamHandler() stream_handler.setLevel(console_level) |
