From 90d215a0bddd5e810f797232ec255c73343451be Mon Sep 17 00:00:00 2001 From: yileye <695084435@qq.com> Date: Wed, 19 Sep 2018 20:14:27 +0800 Subject: [PATCH 1/6] =?UTF-8?q?=20fix(docs):=20=E4=BF=AE=E5=A4=8Dlocus?= =?UTF-8?q?=E5=9C=A8=E4=BE=9D=E8=B5=96=E4=B8=AD=E5=AE=89=E8=A3=85=E6=8A=A5?= =?UTF-8?q?=E9=94=99=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit locust ==0.8 变更为 locustio==0.8 Issue #101 Close #101 --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index c28f938..978f31e 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,7 +4,7 @@ requests == 2.18.4 colorama == 0.3.9 colorlog == 3.1.2 Jinja2 == 2.10 -locust == 0.8 +locustio == 0.8 eventlet == 0.22.1 mysqlclient == 1.3.12 django-celery == 3.2.2 From 984c2ebf6811b619777fa7d51ecfad048d3d97e0 Mon Sep 17 00:00:00 2001 From: yileye <695084435@qq.com> Date: Wed, 19 Sep 2018 20:20:01 +0800 Subject: [PATCH 2/6] =?UTF-8?q?feat(<=E8=A7=86=E5=9B=BE=E5=B1=82>):=20=20?= =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=AF=BC=E5=87=BA=E7=94=A8=E4=BE=8B=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 支持项目级别和模块级别的用例导出 --- static/assets/js/commons.js | 8 ++++++++ templates/module_list.html | 5 +++++ templates/project_list.html | 6 ++++++ 3 files changed, 19 insertions(+) diff --git a/static/assets/js/commons.js b/static/assets/js/commons.js index 3ac4d2f..dde23a4 100644 --- a/static/assets/js/commons.js +++ b/static/assets/js/commons.js @@ -425,3 +425,11 @@ function init_acs(language, theme, editor) { } +function download_from_project(id,type) { + var $eleForm = $("
"); + $eleForm.attr("action", "/api/file_down/"+id); + $(document.body).append($eleForm); + $eleForm.submit(); +} + + diff --git a/templates/module_list.html b/templates/module_list.html index e876309..a2613bb 100644 --- a/templates/module_list.html +++ b/templates/module_list.html @@ -232,6 +232,11 @@ data-am-popover="{content: '删除', trigger: 'hover focus'}" onclick="invalid('{{ foo.id }}')"> + diff --git a/templates/project_list.html b/templates/project_list.html index 5f7ef25..fa344cc 100644 --- a/templates/project_list.html +++ b/templates/project_list.html @@ -159,6 +159,7 @@ + @@ -251,6 +252,11 @@ data-am-popover="{content: '删除', trigger: 'hover focus'}" onclick="invalid('{{ foo.id }}')"> + From e1f47b2e7d818a1f809bd6cb8be7e58bd78e8a44 Mon Sep 17 00:00:00 2001 From: yileye <695084435@qq.com> Date: Wed, 19 Sep 2018 20:21:02 +0800 Subject: [PATCH 3/6] =?UTF-8?q?=E8=A1=A5=E6=8F=90=E4=BA=A4=E8=A7=86?= =?UTF-8?q?=E5=9B=BE=E5=B1=82=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ApiManager/views.py | 46 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/ApiManager/views.py b/ApiManager/views.py index 809a8c5..5aa83f3 100644 --- a/ApiManager/views.py +++ b/ApiManager/views.py @@ -5,8 +5,10 @@ import sys import paramiko +import yaml from django.http import HttpResponse, HttpResponseRedirect, JsonResponse, StreamingHttpResponse from django.shortcuts import render_to_response +from django.utils.encoding import escape_uri_path from django.utils.safestring import mark_safe from djcelery.models import PeriodicTask from dwebsocket import accept_websocket @@ -799,3 +801,47 @@ def echo(request): for i, line in enumerate(stdout): request.websocket.send(bytes(line, encoding='utf8')) client.close() + + +@login_check +def file_down(request, id): + if request.method == 'GET': + if id: + info = id.split('_') + id = info[0] + type = info[1] + if type == 'project': + summary = ProjectInfo.objects.get(id=id) + request = TestCaseInfo.objects.filter(belong_module__belong_project=id) + name = summary.project_name + elif type == 'module': + summary = ModuleInfo.objects.get(id=id) + request = TestCaseInfo.objects.filter(belong_module=id) + name = summary.module_name + + if os.path.exists(os.path.join(os.getcwd(), "download")): + shutil.rmtree(os.path.join(os.getcwd(), "download")) + os.makedirs(os.path.join(os.getcwd(), "download")) + download_path = os.path.join(os.getcwd(), "download") + "{}{}.yaml".format(separator, name) + with open(download_path, 'a+', encoding='utf-8') as stream: + for i in request: + + yaml.dump(eval(i.request), stream, encoding='utf-8', allow_unicode=True) + + def file_iterator(file_name, chunk_size=512): + + with open(file_name) as f: + while True: + c = f.read(chunk_size) + if c: + yield c + else: + break + the_file_name = name+".yaml" + file_path = os.path.join(os.getcwd(), "download")+"/"+the_file_name + response = StreamingHttpResponse(file_iterator(file_path)) + response['Content-Type'] = 'application/octet-stream' + # 如果文件名中带有中文,必须使用如下代码进行编码,否则会使用默认名字 + response['Content-Disposition'] = "attachment; filename*=utf-8''{}".format(escape_uri_path(the_file_name)) + return response + From 997b2660de30fad25ab298144eeda2cccf74fbc8 Mon Sep 17 00:00:00 2001 From: yileye <695084435@qq.com> Date: Thu, 20 Sep 2018 16:25:11 +0800 Subject: [PATCH 4/6] =?UTF-8?q?feat(<=E8=A7=86=E5=9B=BE=E5=B1=82>):=20=20?= =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=89=B9=E9=87=8F=E5=AF=BC=E5=87=BA=E7=94=A8?= =?UTF-8?q?=E4=BE=8B=E5=8A=9F=E8=83=BD=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 支持层级,依赖,配置导出, --- ApiManager/utils/common.py | 10 ++++++- ApiManager/views.py | 56 +++++++++++++++---------------------- static/assets/js/commons.js | 8 ------ templates/module_list.html | 2 +- templates/project_list.html | 2 +- 5 files changed, 34 insertions(+), 44 deletions(-) diff --git a/ApiManager/utils/common.py b/ApiManager/utils/common.py index 2d50f75..20e1bb0 100644 --- a/ApiManager/utils/common.py +++ b/ApiManager/utils/common.py @@ -3,7 +3,7 @@ import json import logging import os -import platform +import tarfile from json import JSONDecodeError import yaml @@ -644,3 +644,11 @@ def timestamp_to_datetime(summary, type=True): except Exception: pass return summary + + +def make_targz(output_filename, source_dir): + try: + with tarfile.open(output_filename, "w:gz") as tar: + tar.add(source_dir, arcname=os.path.basename(source_dir)) + except IOError: + return "读写异常,请重试" diff --git a/ApiManager/views.py b/ApiManager/views.py index 5aa83f3..e26853d 100644 --- a/ApiManager/views.py +++ b/ApiManager/views.py @@ -5,10 +5,8 @@ import sys import paramiko -import yaml from django.http import HttpResponse, HttpResponseRedirect, JsonResponse, StreamingHttpResponse from django.shortcuts import render_to_response -from django.utils.encoding import escape_uri_path from django.utils.safestring import mark_safe from djcelery.models import PeriodicTask from dwebsocket import accept_websocket @@ -19,7 +17,7 @@ from ApiManager.tasks import main_hrun from ApiManager.utils.common import module_info_logic, project_info_logic, case_info_logic, config_info_logic, \ set_filter_session, get_ajax_msg, register_info_logic, task_logic, load_modules, upload_file_logic, \ - init_filter_session, get_total_values, timestamp_to_datetime + init_filter_session, get_total_values, timestamp_to_datetime, make_targz from ApiManager.utils.operation import env_data_logic, del_module_data, del_project_data, del_test_data, copy_test_data, \ del_report_data, add_suite_data, copy_suite_data, del_suite_data, edit_suite_data from ApiManager.utils.pagination import get_pager_info @@ -261,6 +259,7 @@ def run_batch_test(request): if request.is_ajax(): kwargs = json.loads(request.body.decode('utf-8')) test_list = kwargs.pop('id') + print(test_list) base_url = kwargs.pop('env_name') type = kwargs.pop('type') report_name = kwargs.get('report_name', None) @@ -803,45 +802,36 @@ def echo(request): client.close() -@login_check -def file_down(request, id): - if request.method == 'GET': - if id: - info = id.split('_') - id = info[0] - type = info[1] - if type == 'project': - summary = ProjectInfo.objects.get(id=id) - request = TestCaseInfo.objects.filter(belong_module__belong_project=id) - name = summary.project_name - elif type == 'module': - summary = ModuleInfo.objects.get(id=id) - request = TestCaseInfo.objects.filter(belong_module=id) - name = summary.module_name - - if os.path.exists(os.path.join(os.getcwd(), "download")): - shutil.rmtree(os.path.join(os.getcwd(), "download")) - os.makedirs(os.path.join(os.getcwd(), "download")) - download_path = os.path.join(os.getcwd(), "download") + "{}{}.yaml".format(separator, name) - with open(download_path, 'a+', encoding='utf-8') as stream: - for i in request: - - yaml.dump(eval(i.request), stream, encoding='utf-8', allow_unicode=True) +def file_down(request): + if os.path.exists(os.path.join(os.getcwd(), "download")): + shutil.rmtree(os.path.join(os.getcwd(), "download")) + download_dir_path = os.path.join(os.getcwd(), "download") + zip_dir_path = os.path.join(download_dir_path, get_time_stamp()) + the_file_name = 'export.tar.gz' + if request.method == 'POST': + kwargs = request.POST + id = kwargs.get('id') + base_url = kwargs.get('env_name', '') + type = kwargs.get('type') + run_test_by_type(id, base_url, zip_dir_path, type) + status = make_targz(download_dir_path+'/'+the_file_name, zip_dir_path) + if status != None: + if type == 'project': + return HttpResponse(get_ajax_msg(status, 'ok')) + else: + return HttpResponse(get_ajax_msg(status, 'ok')) def file_iterator(file_name, chunk_size=512): - - with open(file_name) as f: + with open(file_name, 'rb') as f: while True: c = f.read(chunk_size) if c: yield c else: break - the_file_name = name+".yaml" - file_path = os.path.join(os.getcwd(), "download")+"/"+the_file_name - response = StreamingHttpResponse(file_iterator(file_path)) + response = StreamingHttpResponse(file_iterator(download_dir_path+'/'+the_file_name)) response['Content-Type'] = 'application/octet-stream' # 如果文件名中带有中文,必须使用如下代码进行编码,否则会使用默认名字 - response['Content-Disposition'] = "attachment; filename*=utf-8''{}".format(escape_uri_path(the_file_name)) + response['Content-Disposition'] = "attachment; filename*=utf-8''{}".format(the_file_name) return response diff --git a/static/assets/js/commons.js b/static/assets/js/commons.js index dde23a4..3ac4d2f 100644 --- a/static/assets/js/commons.js +++ b/static/assets/js/commons.js @@ -425,11 +425,3 @@ function init_acs(language, theme, editor) { } -function download_from_project(id,type) { - var $eleForm = $(""); - $eleForm.attr("action", "/api/file_down/"+id); - $(document.body).append($eleForm); - $eleForm.submit(); -} - - diff --git a/templates/module_list.html b/templates/module_list.html index a2613bb..7f2efcd 100644 --- a/templates/module_list.html +++ b/templates/module_list.html @@ -235,7 +235,7 @@ diff --git a/templates/project_list.html b/templates/project_list.html index fa344cc..de4e6d4 100644 --- a/templates/project_list.html +++ b/templates/project_list.html @@ -255,7 +255,7 @@ From 5b543dcdfbb05d68c6f754b35b348153bbc19360 Mon Sep 17 00:00:00 2001 From: yileye <695084435@qq.com> Date: Thu, 20 Sep 2018 16:27:35 +0800 Subject: [PATCH 5/6] =?UTF-8?q?fix(=E6=95=B0=E6=8D=AE=E5=B1=82):=20?= =?UTF-8?q?=E8=A7=A3=E5=86=B3=E7=94=A8=E4=BE=8B=E4=B8=AD=E4=B8=AD=E6=96=87?= =?UTF-8?q?=E7=BC=96=E7=A0=81=E5=9C=A8=E5=AF=BC=E5=87=BA=E6=97=B6=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ymal.dump 方法增加allow_unicode=True设置 --- ApiManager/utils/testcase.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ApiManager/utils/testcase.py b/ApiManager/utils/testcase.py index c7acea6..aa6bfbd 100644 --- a/ApiManager/utils/testcase.py +++ b/ApiManager/utils/testcase.py @@ -18,7 +18,7 @@ def dump_yaml_file(yaml_file, data): """ load yaml file and check file content format """ with io.open(yaml_file, 'w', encoding='utf-8') as stream: - yaml.dump(data, stream, indent=4, default_flow_style=False, encoding='utf-8') + yaml.dump(data, stream, indent=4, default_flow_style=False, encoding='utf-8', allow_unicode=True) def _dump_json_file(json_file, data): From e1b1e890eda989d12bf740b743851e13e17eb13e Mon Sep 17 00:00:00 2001 From: yileye <695084435@qq.com> Date: Thu, 20 Sep 2018 18:00:57 +0800 Subject: [PATCH 6/6] =?UTF-8?q?fix(=E6=95=B0=E6=8D=AE=E5=B1=82):=20=20?= =?UTF-8?q?=E6=89=B9=E9=87=8F=E5=AF=BC=E5=85=A5=E7=94=A8=E4=BE=8B=E6=97=B6?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E5=AF=BC=E5=85=A5=E5=85=A8=E5=B1=80=E7=8E=AF?= =?UTF-8?q?=E5=A2=83=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在导入config时解析数据,多一步全局环境配置入库操作 --- ApiManager/utils/common.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ApiManager/utils/common.py b/ApiManager/utils/common.py index 20e1bb0..2dc5891 100644 --- a/ApiManager/utils/common.py +++ b/ApiManager/utils/common.py @@ -13,7 +13,7 @@ from ApiManager.models import ModuleInfo, TestCaseInfo, TestReports, TestSuite from ApiManager.utils.operation import add_project_data, add_module_data, add_case_data, add_config_data, \ - add_register_data + add_register_data, env_data_logic from ApiManager.utils.task_opt import create_task @@ -548,6 +548,14 @@ def upload_file_logic(files, project, module, account): if 'config' in test_case.keys(): test_case.get('config')['config_info'] = test_dict add_config_data(type=True, **test_case) + if test_case['config'].get('request').get('base_url', '') is '': + pass + else: + env_config = dict() + env_config['index'] = 'add' + env_config['env_name'] = test_case['config']['name'] + env_config['base_url'] = test_case['config']['request']['base_url'] + env_data_logic(**env_config) if 'test' in test_case.keys(): # 忽略config test_case.get('test')['case_info'] = test_dict