diff --git a/docker/Dockerfile b/docker/Dockerfile index e2e8a04a53c64de1a176e5c7271f1425a85ab920..5c7bf6ddf57d5b06beeaf63722f86bc3b96a6e90 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -18,7 +18,8 @@ RUN mkdir -p ${APP_HOME}/logs/app && mkdir -p ${APP_HOME}/logs/supervisord ADD . ${APP_HOME} # 更新apt-get、 pip、安装pip包 -RUN ${PIP_INSTALL} supervisor && \ +RUN apt-get install git && \ + ${PIP_INSTALL} supervisor && \ ${PIP_INSTALL} -r ${APP_HOME}/docker/requirements.txt #设置时区 diff --git a/docker/supervisord.conf b/docker/supervisord.conf index 5cb41aee4377b90a966b02a2531c8ecef47ab72f..def0afe263027997f83f0cac2138175c0f39e8a9 100644 --- a/docker/supervisord.conf +++ b/docker/supervisord.conf @@ -40,13 +40,12 @@ startsecs=60 [program:django_q_schedule] directory=%(ENV_APP_HOME)s -command=python manage.py qcluster +command=python3 manage.py qcluster autostart=true autorestart=true redirect_stderr=true stopasgroup=true stdout_logfile=%(ENV_APP_HOME)s/logs/app/django_q_schedule.log -environment=PATH="/home/admin/tone/virtualenv/bin" stopwaitsecs=1800 stopsignal=TERM startsecs=60 \ No newline at end of file diff --git a/initial/base_config/data.py b/initial/base_config/data.py index 941d0ee3416639f17b6202a0e2448da510772a3e..80b7489a53808e063721065e12c5db2be88402e9 100644 --- a/initial/base_config/data.py +++ b/initial/base_config/data.py @@ -94,7 +94,7 @@ BASE_CONFIG_DATA = [ 'config_type': 'script', 'config_key': 'RUN_TEST', 'config_value': RUN_TEST.format( - tone_storage_host=cp.get('tone_storage_host'), + tone_storage_host=cp.get('tone_storage_domain'), tone_storage_sftp_port=cp.get('tone_storage_sftp_port'), tone_storage_proxy_port=cp.get('tone_storage_proxy_port'), tone_storage_user=cp.get('tone_storage_user'), @@ -107,7 +107,7 @@ BASE_CONFIG_DATA = [ 'config_type': 'script', 'config_key': 'UPLOAD', 'config_value': UPLOAD.format( - tone_storage_host=cp.get('tone_storage_host'), + tone_storage_host=cp.get('tone_storage_domain'), tone_storage_sftp_port=cp.get('tone_storage_sftp_port'), tone_storage_proxy_port=cp.get('tone_storage_proxy_port'), tone_storage_user=cp.get('tone_storage_user'), @@ -162,7 +162,7 @@ BASE_CONFIG_DATA = [ 'config_type': 'script', 'config_key': 'RUN_TEST_DEBIAN', 'config_value': RUN_TEST_DEBIAN.format( - tone_storage_host=cp.get('tone_storage_host'), + tone_storage_host=cp.get('tone_storage_domain'), tone_storage_sftp_port=cp.get('tone_storage_sftp_port'), tone_storage_proxy_port=cp.get('tone_storage_proxy_port'), tone_storage_user=cp.get('tone_storage_user'), @@ -175,7 +175,7 @@ BASE_CONFIG_DATA = [ 'config_type': 'script', 'config_key': 'UPLOAD_FILE', 'config_value': UPLOAD_FILE.format( - tone_storage_host=cp.get('tone_storage_host'), + tone_storage_host=cp.get('tone_storage_domain'), tone_storage_sftp_port=cp.get('tone_storage_sftp_port'), tone_storage_proxy_port=cp.get('tone_storage_proxy_port'), tone_storage_user=cp.get('tone_storage_user'), diff --git a/initial/base_config/script/run_test.py b/initial/base_config/script/run_test.py index b8f2631f902b2102616910d908f521c330a87746..65a5571e9b8c054014ace9dadf14b064d21d1677 100644 --- a/initial/base_config/script/run_test.py +++ b/initial/base_config/script/run_test.py @@ -25,7 +25,7 @@ TONE_STORAGE_PROXY_PORT={tone_storage_proxy_port} TONE_STORAGE_USER={tone_storage_user} TONE_STORAGE_PASSWORD={tone_storage_password} TONE_STORAGE_BUCKET=${{7:-results}} -SFTP_PARAMS="set ftp:ssl-allow no; set net:timeoit 60; set net:reconnect-interval-base 10; set net:max-retries 2" +SFTP_PARAMS="set sftp:auto-confirm yes; set net:timeout 60; set net:reconnect-interval-base 10; set net:max-retries 2" TONE_RESULT_PATH=$TONE_PATH/result/$TEST_SUITE/$CONF_SHORT_NAME TONE_RESULT_PATH_LEN=$((${{#TONE_RESULT_PATH}}+1)) diff --git a/initial/base_config/script/upload.py b/initial/base_config/script/upload.py index 7af53bbb9f3bbd58e6e41e470611bed1e16d6f9b..71867e4b17ffa83f8bac86480224232beaed0fe3 100644 --- a/initial/base_config/script/upload.py +++ b/initial/base_config/script/upload.py @@ -24,7 +24,7 @@ LOG=/tmp/tone_${{TEST_SUITE}}_${{CONF_SHORT_NAME}}.log ALL_LOG=/tmp/tone.log TONE_RESULT_PATH=$TONE_PATH/result/$TEST_SUITE/$CONF_SHORT_NAME TONE_RESULT_PATH_LEN=$((${{#TONE_RESULT_PATH}}+1)) - +SFTP_PARAMS="set sftp:auto-confirm yes; set net:timeout 60; set net:reconnect-interval-base 10; set net:max-retries 2" install_utils() {{ @@ -56,7 +56,7 @@ function upload_file(){{ return fi - lftp -u ${{TONE_STORAGE_USER}},${{TONE_STORAGE_PASSWORD}} sftp://${{TONE_STORAGE_HOST}}:${{TONE_STORAGE_SFTP_PORT}} >> $ALL_LOG 2>&1 <> $ALL_LOG 2>&1 < 1: - count_li[0] += 1 - compare_groups = conf_value.get('compare_groups', list()) - for i in range(len(compare_groups)): - if len(compare_groups[i]) > 1: - count_li[i + 1] += 1 - - @staticmethod - def get_obj(obj_id, is_job): - obj_data = {'obj_id': obj_id, 'is_job': is_job} - if is_job: - test_job = TestJob.objects.get(id=obj_id) - name = test_job.name - obj_data['name'] = name - return obj_data - class CompareConfInfoService(CommonService): + def filter(self, data): suite_id = data.get('suite_id') test_job_list = data.get('test_job_id') + test_type = data.get('test_type') is_baseline = data.get('is_baseline', 0) - job_id_list = ','.join(str(e) for e in test_job_list) + job_id_list = tuple(test_job_list) test_case_data = dict() + uniq_id = 'baseline_id' if is_baseline else 'job_id' if is_baseline: - raw_sql = 'SELECT distinct a.test_case_id,b.name AS conf_name FROM func_baseline_detail a ' \ - 'LEFT JOIN test_case b ON a.test_case_id= b.id WHERE a.test_suite_id=%s AND ' \ - 'a.baseline_id IN (' + job_id_list + ') UNION ' \ - 'SELECT distinct a.test_case_id,b.name AS conf_name FROM perf_baseline_detail a ' \ - 'LEFT JOIN test_case b ON a.test_case_id= b.id WHERE a.test_suite_id=%s AND ' \ - 'a.baseline_id IN (' + job_id_list + ')' - all_test_cases = query_all_dict(raw_sql.replace('\'', ''), [suite_id, suite_id]) + detail_table = 'func_baseline_detail' if test_type == 'functional' else 'perf_baseline_detail' else: - raw_sql = 'SELECT distinct a.test_case_id,b.name AS conf_name FROM test_job_case a ' \ - 'LEFT JOIN test_case b ON a.test_case_id= b.id WHERE a.test_suite_id=%s AND' \ - ' a.job_id IN (' + job_id_list + ')' - all_test_cases = query_all_dict(raw_sql.replace('\'', ''), [suite_id]) + detail_table = 'test_job_case' + raw_sql = 'SELECT distinct a.test_case_id,b.name AS conf_name FROM {} a ' \ + 'LEFT JOIN test_case b ON a.test_case_id= b.id WHERE ' \ + 'a.test_suite_id=%s AND a.{} IN %s'.format(detail_table, uniq_id) + all_test_cases = query_all_dict(raw_sql.replace('\'', ''), [suite_id, job_id_list]) for job_case in all_test_cases: case_id = job_case['test_case_id'] test_case_data[case_id] = { diff --git a/tone/services/job/test_services.py b/tone/services/job/test_services.py index de87516cade05dcf217ebbefe34026bb4972d8cb..0a8863546e3e9c57bb19925c5457efe17c793b20 100644 --- a/tone/services/job/test_services.py +++ b/tone/services/job/test_services.py @@ -18,6 +18,7 @@ from django.db.models import Q from django.db import transaction, connection from itertools import chain from threading import Thread +from tone import settings from tone.core.common.callback import CallBackType, JobCallBack from tone.core.utils.common_utils import query_all_dict @@ -95,8 +96,12 @@ class JobTestService(CommonService): def db_filter_job(self, data, operator): # noqa: C901 data = self.check_data_param(data) - page_num = int(data.get('page_num', 1)) - page_size = int(data.get('page_size', 20)) + page_num = data.get('page_num', '1') + page_size = data.get('page_size', '20') + if not page_num.isdigit() or not page_size.isdigit(): + raise ValueError(ErrorCode.ILLEGALITY_PARAM_ERROR) + page_num = int(page_num) + page_size = int(page_size) res = [] create_name_map = {} project_name_map = {} @@ -566,11 +571,11 @@ class JobTestService(CommonService): ftp_path = oss_file.replace(MEDIA_ROOT.strip('/'), '') res = sftp_client.upload_file(target_file, ftp_path) if res: - oss_link = 'http://' + sftp_client.host + ':' + str(sftp_client.proxy_port) + ftp_path + oss_link = f'http://{settings.TONE_STORAGE_DOMAIN}:' + str(sftp_client.proxy_port) + ftp_path self.del_dir(job_path) JobDownloadRecord.objects.filter(job_id=test_job_id).update(state='success', job_url=oss_link) else: - JobDownloadRecord.objects.filter(job_id=test_job_id).update(state='success', job_url='ftp upload fail.') + JobDownloadRecord.objects.filter(job_id=test_job_id).update(state='fail', job_url='ftp upload fail.') else: JobDownloadRecord.objects.filter(job_id=test_job_id).update(state='fail', job_url='job not exists') except Exception as e: diff --git a/tone/services/notice/core/notice_service.py b/tone/services/notice/core/notice_service.py index ce9ef08bcc29b2a321040bde0476953d9dc96f71..b3a05a75f095e444b932135b77fc3ce2e5b19e49 100644 --- a/tone/services/notice/core/notice_service.py +++ b/tone/services/notice/core/notice_service.py @@ -41,6 +41,8 @@ def send_ding_message(message_id): # @app.task def send_email_message(message_id): message = OutSiteMsg.objects.get(id=message_id) + if len(message.send_to.strip()) <= 1: + return send_to = message.send_to.strip().split(',') cc_to = message.cc_to.strip().split(',') bcc_to = message.bcc_to.strip().split(',') diff --git a/tone/services/sys/baseline_services.py b/tone/services/sys/baseline_services.py index ebdd5996b7f3fdaba4bd6a0876f093bd9b4f7456..e64d0ade970db21042cc4b5b17e6844c5312194a 100644 --- a/tone/services/sys/baseline_services.py +++ b/tone/services/sys/baseline_services.py @@ -14,6 +14,7 @@ import stat import uuid from django.db import transaction from django_q.tasks import async_task +from tone import settings from tone.core.common.constant import OFFLINE_DATA_DIR from tone.settings import MEDIA_ROOT @@ -245,7 +246,7 @@ class BaselineService(CommonService): ftp_path = oss_file.replace(MEDIA_ROOT.strip('/'), '') res = sftp_client.upload_file(target_file, ftp_path) if res: - oss_link = 'http://' + sftp_client.host + ':' + str(sftp_client.proxy_port) + ftp_path + oss_link = f'http://{settings.TONE_STORAGE_DOMAIN}:' + str(sftp_client.proxy_port) + ftp_path self.del_dir(file_path) BaselineDownloadRecord.objects.filter(baseline_id=baseline_id).\ update(state='success', target_url=oss_link) diff --git a/tone/services/sys/server_services.py b/tone/services/sys/server_services.py index d05988bf9901c98c4960c31eb4e5cca12dbbccc1..315d5815ea26b0b1cc0547ac44f1b68f832a4a9a 100644 --- a/tone/services/sys/server_services.py +++ b/tone/services/sys/server_services.py @@ -575,10 +575,16 @@ class CloudServerService(CommonService): is_instance = False q &= Q(is_instance=is_instance) if data.get('server_conf'): - if data.get('is_instance') == "true": - q &= Q(instance_name__icontains=data.get('server_conf')) + if data.get('query_size') and data.get('query_size') == '1': + if data.get('is_instance') == "true": + q &= Q(instance_name=data.get('server_conf')) + else: + q &= Q(template_name=data.get('server_conf')) else: - q &= Q(template_name__icontains=data.get('server_conf')) + if data.get('is_instance') == "true": + q &= Q(instance_name__icontains=data.get('server_conf')) + else: + q &= Q(template_name__icontains=data.get('server_conf')) if data.get('description'): q &= Q(description__icontains=data.get('description')) if data.get('ws_id'): diff --git a/tone/services/sys/testcase_services.py b/tone/services/sys/testcase_services.py index efada7efdbbf55f1bd827e471f12b9c989e78e18..93c2a0c97ded3c2d3de58a1680156154760027cb 100644 --- a/tone/services/sys/testcase_services.py +++ b/tone/services/sys/testcase_services.py @@ -578,7 +578,8 @@ class TestSuiteService(CommonService): continue case_name = '' for i, item in enumerate(line.split()): - case_name += f'{title_list[i]}={item},' + if item.lower() != 'na': + case_name += f'{title_list[i]}={item},' case_list.append(case_name.strip(',')) if not case_list: case_list = ['default'] @@ -633,7 +634,8 @@ class TestSuiteService(CommonService): continue case_name = '' for i, item in enumerate(line.split()): - case_name += f'{title_list[i]}={item},' + if item.lower() != 'na': + case_name += f'{title_list[i]}={item},' case_list.append(case_name.strip(',')) if not case_list: case_list = ['default'] diff --git a/tone/views/api/create_job.py b/tone/views/api/create_job.py index 19657949a300940f6f6903ef1e7eaa6bf0b139bb..9e1cf1efb1c148914751f63361646152a028a9db 100644 --- a/tone/views/api/create_job.py +++ b/tone/views/api/create_job.py @@ -16,7 +16,7 @@ from tone.core.handle.job_handle import JobDataHandle from tone.core.common.verify_token import token_required from tone.core.common.expection_handler.error_code import ErrorCode from tone.core.common.expection_handler.error_catch import api_catch_error -from tone.serializers.job.test_serializers import JobTestSerializer, JobSerializerForAPI +from tone.core.utils.permission_manage import check_ws_operator_permission @api_catch_error @@ -57,6 +57,8 @@ def conversion_data(data): # noqa: C901 ws_name = data.get('workspace') assert ws_name, ValueError(ErrorCode.WS_NAME_NEED) ws_id = get_ws(ws_name) + if not check_ws_operator_permission(data.get('username'), ws_id): + assert None, ValueError(ErrorCode.PERMISSION_ERROR) if data.get('template') or data.get('template_id'): data['data_from'] = 'template' template = TestTemplate.objects.get(id=data.get('template_id')) if data.get('template_id') else get_template( @@ -218,8 +220,13 @@ def get_ws(ws_name): def get_server_list(request): data = request.GET ws_id = data.get('ws_id') + assert ws_id, ValueError(ErrorCode.WS_NEED) provider = data.get('provider') + assert provider, ValueError(ErrorCode.PROVIDER_NEED) run_mode = data.get('run_mode') + assert run_mode, ValueError(ErrorCode.PARAMS_ERROR) + if not check_ws_operator_permission(request.GET.get('username', None), ws_id): + assert None, ValueError(ErrorCode.PERMISSION_ERROR) resp = CommResp() if provider == 'aligroup' and run_mode == 'standalone': queryset = TestServer.objects.exclude(ip='').\ @@ -232,11 +239,16 @@ def get_server_list(request): values_list('instance_id', flat=True).distinct() resp.data = list(queryset) return resp.json_resp() + + @token_required @api_catch_error def get_server_tag_list(request): data = request.GET ws_id = data.get('ws_id') + assert ws_id, ValueError(ErrorCode.WS_NEED) + if not check_ws_operator_permission(request.GET.get('username', None), ws_id): + assert None, ValueError(ErrorCode.PERMISSION_ERROR) resp = CommResp() queryset = ServerTag.objects.filter(ws_id=ws_id).values_list('name', flat=True) resp.data = list(queryset) diff --git a/tone/views/api/get_suite_info.py b/tone/views/api/get_suite_info.py index 586e597f91b61d76b0d3d2e2e53fee71bbaec9f1..bc31e382ef60c0745f57a3a41b3baaa891e9b30e 100644 --- a/tone/views/api/get_suite_info.py +++ b/tone/views/api/get_suite_info.py @@ -6,11 +6,15 @@ from tone.core.common.verify_token import token_required from tone.core.common.expection_handler.error_catch import api_catch_error from datetime import datetime from tone.core.handle.report_handle import ReportHandle +from tone.core.utils.permission_manage import check_admin_operator_permission +from tone.core.common.expection_handler.error_code import ErrorCode @api_catch_error @token_required def get_suite_list(request): + if not check_admin_operator_permission(request.GET.get('username', None)): + assert None, ValueError(ErrorCode.PERMISSION_ERROR) resp = CommResp() serialize_flag, queryset = WorkspaceRetrieveService.filter(WorkspaceCaseRelation.objects.all(), request.GET) resp.data = queryset @@ -20,6 +24,8 @@ def get_suite_list(request): @api_catch_error @token_required def get_case_list(request): + if not check_admin_operator_permission(request.GET.get('username', None)): + assert None, ValueError(ErrorCode.PERMISSION_ERROR) resp = CommResp() queryset = TestCaseService.filter(TestCase.objects.all(), request.GET) case_data_list = [{'id': case_info.id, 'name': case_info.name, @@ -32,6 +38,8 @@ def get_case_list(request): @api_catch_error @token_required def get_metric_list(request): + if not check_admin_operator_permission(request.GET.get('username', None)): + assert None, ValueError(ErrorCode.PERMISSION_ERROR) resp = CommResp() queryset = TestMetricService.filter(TestMetric.objects.all(), request.GET) metric_data_list = [{'id': metric.id, 'name': metric.name} for metric in queryset] @@ -39,9 +47,11 @@ def get_metric_list(request): return resp.json_resp() -# @api_catch_error -# @token_required +@api_catch_error +@token_required def get_suite_increase(request): + if not check_admin_operator_permission(request.GET.get('username', None)): + assert None, ValueError(ErrorCode.PERMISSION_ERROR) resp = CommResp() last_sync_time = request.GET['last_sync_time'] queryset = TestCase.objects.filter( diff --git a/tone/views/api/handle_job.py b/tone/views/api/handle_job.py index 95ac12be7825b412536321ba518e8dcd111c2ab0..a78cf0a7eeaeacc3d65f582b79b382b17b860a2f 100644 --- a/tone/views/api/handle_job.py +++ b/tone/views/api/handle_job.py @@ -27,5 +27,6 @@ def stop_job(request): id=job_id, state__in=['running', 'pending', 'pending_q'] ).update(state='stop', end_time=datetime.now()) + operation_after_stop_job(job_obj, 'The job stop by ' + request.GET.get('username', None)) return resp.json_resp() diff --git a/tone/views/api/query_job.py b/tone/views/api/query_job.py index 96a7a7618dc961113e18b17fe232d83fd172ce6e..cedd8fdaf33731e8c0734fcf11f859079018c179 100644 --- a/tone/views/api/query_job.py +++ b/tone/views/api/query_job.py @@ -21,7 +21,8 @@ from tone.core.common.job_result_helper import calc_job, get_job_case_server, ge splice_job_link from tone.services.sys.testcase_services import TestCaseInfoService from tone.services.job.test_services import package_server_list -from tone.core.utils.permission_manage import check_job_operator_permission, check_ws_operator_permission +from tone.core.utils.permission_manage import check_job_operator_permission, check_ws_operator_permission, \ + check_admin_operator_permission def _replace_statics_key(case_statics): @@ -176,6 +177,8 @@ def get_job_case(request): resp = CommResp() case_data_list = [] test_job = TestJob.objects.filter(id=request.GET.get('job_id')).first() + if not check_job_operator_permission(request.GET.get('username', None), test_job): + assert None, ValueError(ErrorCode.PERMISSION_ERROR) if test_job and test_job.test_type == 'functional': queryset = TestCaseInfoService.filter(FuncResult.objects.all(), request.GET) test_case_list = TestCase.objects.filter(id__in=[case_info.test_case_id for case_info in queryset]).values_list( @@ -210,6 +213,12 @@ def get_job_case(request): @api_catch_error @token_required def get_job_type(request): + ws_id = request.GET.get('ws_id', None) + assert ws_id, ValueError(ErrorCode.WS_NEED) + test_type = request.GET.get('test_type', None) + assert test_type, ValueError(ErrorCode.TEST_TYPE_LACK) + if not check_ws_operator_permission(request.GET.get('username', None), ws_id): + assert None, ValueError(ErrorCode.PERMISSION_ERROR) resp = CommResp() queryset = JobType.objects.filter(ws_id=request.GET.get('ws_id'), test_type=request.GET.get('test_type'), enable=True) @@ -221,6 +230,10 @@ def get_job_type(request): @api_catch_error @token_required def get_project(request): + ws_id = request.GET.get('ws_id', None) + assert ws_id, ValueError(ErrorCode.WS_NEED) + if not check_ws_operator_permission(request.GET.get('username', None), ws_id): + assert None, ValueError(ErrorCode.PERMISSION_ERROR) resp = CommResp() queryset = Project.objects.filter(ws_id=request.GET.get('ws_id')) project_list = [{'id': project.id, 'name': project.name, 'is_default': project.is_default} for project in queryset] @@ -231,6 +244,8 @@ def get_project(request): @api_catch_error @token_required def get_workspace(request): + if not check_admin_operator_permission(request.GET.get('username', None)): + assert None, ValueError(ErrorCode.PERMISSION_ERROR) resp = CommResp() queryset = Workspace.objects.all() ws_list = [{'id': ws.id, 'name': ws.name} for ws in queryset] @@ -279,40 +294,31 @@ def get_job_info_list(request): resp = CommResp() data = json.loads(request.body) product_name = data.get('product', None) - if product_name: - assert isinstance(product_name, str), ValueError(ErrorCode.ILLEGALITY_PARAM_ERROR) project_name = data.get('project', None) - if project_name: - assert isinstance(project_name, str), ValueError(ErrorCode.ILLEGALITY_PARAM_ERROR) tag_name = data.get('tag', None) - if tag_name: - assert isinstance(tag_name, str), ValueError(ErrorCode.ILLEGALITY_PARAM_ERROR) ws_id = data.get('ws_id', None) assert ws_id, ValueError(ErrorCode.WS_NEED) - assert isinstance(ws_id, str), ValueError(ErrorCode.ILLEGALITY_PARAM_ERROR) - raw_sql = "SELECT DISTINCT A.id, A.name AS job_name,A.state,A.start_time,A.end_time,A.test_type,A.test_result," \ - "B.name AS product_name,C.name AS project_name,F.username AS creator FROM " \ - "test_job A, product B, project C, job_tag D, job_tag_relation E, user F " \ - "WHERE A.is_deleted=0 AND B.is_deleted=0 AND C.is_deleted=0 AND D.is_deleted=0 AND " \ - "A.product_id=B.id AND A.project_id=C.id AND A.id=E.job_id AND E.tag_id=D.id AND" \ - " A.creator=F.id AND A.ws_id='" + ws_id + "'" - if not tag_name: - raw_sql = "SELECT DISTINCT A.id, A.name AS job_name,A.state,A.start_time,A.end_time,A.test_type," \ - "A.test_result, B.name AS product_name,C.name AS project_name,F.username AS creator FROM " \ - "test_job A, product B, project C, user F " \ - "WHERE A.is_deleted=0 AND B.is_deleted=0 AND C.is_deleted=0 AND " \ - "A.product_id=B.id AND A.project_id=C.id AND " \ - " A.creator=F.id AND A.ws_id='" + ws_id + "'" + if not check_ws_operator_permission(data.get('username'), ws_id): + assert None, ValueError(ErrorCode.PERMISSION_ERROR) + params = [ws_id] + raw_sql = "SELECT DISTINCT A.id, A.name AS job_name,A.state,A.start_time,A.end_time,A.test_type," \ + "A.test_result, B.name AS product_name,C.name AS project_name,A.project_id," \ + "F.username AS creator FROM " \ + "test_job A, product B, project C, user F " \ + "WHERE A.is_deleted=0 AND B.is_deleted=0 AND C.is_deleted=0 AND " \ + "A.product_id=B.id AND A.project_id=C.id AND " \ + " A.creator=F.id AND A.ws_id=%s" if product_name: - raw_sql += " AND B.name='{}'".format(product_name) + raw_sql += " AND B.name=%s " + params.append(product_name) if project_name: - raw_sql += " AND C.name='{}'".format(project_name) - if tag_name: - tag_list = ','.join('\'' + e + '\'' for e in tag_name.split(',')) - raw_sql += " AND D.name IN ({})".format(tag_list) - job_result_list = query_all_dict(raw_sql, params=None) + raw_sql += " AND C.name=%s " + params.append(project_name) + job_result_list = query_all_dict(raw_sql, params=params) res_list = list() + job_id_list = list() for job_info in job_result_list: + job_id_list.append(job_info['id']) job_dict = dict( job_id=job_info['id'], job_name=job_info['job_name'], @@ -323,8 +329,24 @@ def get_job_info_list(request): test_result=job_info['test_result'], product_name=job_info['product_name'], project_name=job_info['project_name'], + project_id=job_info['project_id'], creator=job_info['creator'] ) res_list.append(job_dict) - resp.data = res_list + tag_sql = "SELECT a.id,a.name,c.id AS tag_id,C.name AS tag_name FROM test_job a LEFT JOIN job_tag_relation b " \ + "ON a.id=b.job_id LEFT JOIN job_tag c ON b.tag_id=c.id where A.is_deleted=0 AND B.is_deleted=0 " \ + "AND C.is_deleted=0 AND a.id IN %s" + tags_result = query_all_dict(tag_sql, params=[tuple(job_id_list)]) + job_filter_tag_list = list() + for res_job_info in res_list: + tags = [tag for tag in tags_result if tag['id'] == res_job_info['job_id']] + tag_info = dict() + tag_name_list = list() + for job_tag in tags: + tag_info[job_tag['tag_id']] = job_tag['tag_name'] + tag_name_list.append(job_tag['tag_name']) + if tag_name and set(tag_name.split(',')).issubset(set(tag_name_list)): + job_filter_tag_list.append(res_job_info) + res_job_info['tags'] = tag_info + resp.data = job_filter_tag_list if tag_name else res_list return resp.json_resp() diff --git a/tone/views/job/test_view.py b/tone/views/job/test_view.py index 7213f1ec4249279933b5502fc2989eac18280a54..160ea93c7b8ab6b7bc78151b94275dfccef48702 100644 --- a/tone/views/job/test_view.py +++ b/tone/views/job/test_view.py @@ -587,7 +587,10 @@ class JobDownloadRecordView(CommonAPIView): test_job_id = request.GET.get('job_id') record = JobDownloadRecord.objects.filter(job_id=test_job_id).first() if record: - response_data = self.get_response_only_for_data(record.to_dict()) + record_dict = record.to_dict().copy() + if record.state == 'fail': + record_dict['job_url'] = '' + response_data = self.get_response_only_for_data(record_dict) else: response_data = self.get_response_only_for_data(None) return Response(response_data)