fix: 解决冲突

This commit is contained in:
chenjianxing 2021-01-08 17:16:32 +08:00
commit 9723f85c46
8 changed files with 320 additions and 189 deletions

View File

@ -252,6 +252,18 @@
#{value}
</foreach>
</when>
<when test="key=='method'">
and api_definition.method in
<foreach collection="values" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</when>
<when test="key=='user_id'">
and api_definition.user_id in
<foreach collection="values" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</when>
</choose>
</if>
</foreach>
@ -270,7 +282,12 @@
<if test="request.orders != null and request.orders.size() > 0">
order by
<foreach collection="request.orders" separator="," item="order">
<if test="order.name == 'user_name'">
user_name ${order.type}
</if>
<if test="order.name != 'user_name'">
api_definition.${order.name} ${order.type}
</if>
</foreach>
</if>
</select>
@ -351,9 +368,29 @@
</foreach>
</if>
<if test="request.filters != null and request.filters.size() > 0">
and api_definition.status in
<foreach collection="request.filters" item="value" separator="," open="(" close=")">
#{value}
<foreach collection="request.filters.entrySet()" index="key" item="values">
<if test="values != null and values.size() > 0">
<choose>
<when test="key=='status'">
and api_definition.status in
<foreach collection="values" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</when>
<when test="key=='method'">
and api_definition.method in
<foreach collection="values" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</when>
<when test="key=='user_id'">
and api_definition.user_id in
<foreach collection="values" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</when>
</choose>
</if>
</foreach>
</if>
and exists (

View File

@ -72,6 +72,12 @@
#{value}
</foreach>
</when>
<when test="key == 'user_id'">
and c.create_user_id in
<foreach collection="values" item="value" separator="," open="(" close=")">
#{value}
</foreach>
</when>
</choose>
</if>
</foreach>
@ -83,6 +89,9 @@
<when test="order.name == 'update_time'">
t.${order.name} ${order.type}
</when>
<when test="order.name == 'create_user'">
create_user_id ${order.type}
</when>
<otherwise>
${order.name} ${order.type}
</otherwise>

View File

@ -76,6 +76,8 @@ public class PerformanceTestService {
private TestCaseService testCaseService;
@Resource
private PerformanceNoticeTask performanceNoticeTask;
@Resource
private TestResourcePoolMapper testResourcePoolMapper;
public List<LoadTestDTO> list(QueryTestPlanRequest request) {
request.setOrders(ServiceUtils.getDefaultOrder(request.getOrders()));
@ -217,6 +219,14 @@ public class PerformanceTestService {
if (StringUtils.equalsAny(loadTest.getStatus(), PerformanceTestStatus.Running.name(), PerformanceTestStatus.Starting.name())) {
MSException.throwException(Translator.get("load_test_is_running"));
}
String testResourcePoolId = loadTest.getTestResourcePoolId();
TestResourcePool testResourcePool = testResourcePoolMapper.selectByPrimaryKey(testResourcePoolId);
if (testResourcePool == null) {
MSException.throwException("Test resource pool not exists.");
}
if (ResourceStatusEnum.INVALID.name().equals(testResourcePool.getStatus())) {
MSException.throwException("Test resource pool invalid.");
}
// check kafka
checkKafka();
@ -479,9 +489,9 @@ public class PerformanceTestService {
quotaService.checkLoadTestQuota(request, create);
}
}
public List<LoadTest> getLoadTestListByIds(List<String> ids) {
if (CollectionUtils.isEmpty(ids)) {
if (CollectionUtils.isEmpty(ids)) {
return new ArrayList<>();
}
LoadTestExample loadTestExample = new LoadTestExample();

View File

@ -3,9 +3,9 @@
:is-api-list-enable="isApiListEnable"
@isApiListEnableChange="isApiListEnableChange">
<ms-environment-select :project-id="projectId" v-if="isTestPlan" :is-read-only="isReadOnly" @setEnvironment="setEnvironment"/>
<ms-environment-select :project-id="projectId" v-if="isTestPlan" :is-read-only="isReadOnly" @setEnvironment="setEnvironment"/>
<el-input placeholder="搜索" @blur="initTable" class="search-input" size="small" @keyup.enter.native="initTable" v-model="condition.name"/>
<el-input placeholder="搜索" @blur="initTable" class="search-input" size="small" @keyup.enter.native="initTable" v-model="condition.name"/>
<el-table v-loading="result.loading"
@ -36,7 +36,7 @@
show-overflow-tooltip>
<template v-slot:default="scope" class="request-method">
<el-tag size="mini" :style="{'background-color': getColor(scope.row.method), border: getColor(true, scope.row.method)}" class="api-el-tag">
{{ scope.row.method}}
{{ scope.row.method }}
</el-tag>
</template>
</el-table-column>
@ -74,189 +74,187 @@
<script>
import MsTableOperator from "../../../../common/components/MsTableOperator";
import MsTableOperatorButton from "../../../../common/components/MsTableOperatorButton";
import {LIST_CHANGE, TrackEvent} from "@/business/components/common/head/ListEvent";
import MsTablePagination from "../../../../common/pagination/TablePagination";
import MsTag from "../../../../common/components/MsTag";
import MsBottomContainer from "../../../definition/components/BottomContainer";
import ShowMoreBtn from "../../../../track/case/components/ShowMoreBtn";
import MsBatchEdit from "../../../definition/components/basis/BatchEdit";
import {API_METHOD_COLOUR, CASE_PRIORITY} from "../../../definition/model/JsonData";
import {getCurrentProjectID} from "@/common/js/utils";
import ApiListContainer from "../../../definition/components/list/ApiListContainer";
import PriorityTableItem from "../../../../track/common/tableItems/planview/PriorityTableItem";
import {_filter, _sort} from "../../../../../../common/js/utils";
import {_handleSelect, _handleSelectAll} from "../../../../../../common/js/tableUtils";
import MsEnvironmentSelect from "../../../definition/components/case/MsEnvironmentSelect";
import MsTableOperator from "../../../../common/components/MsTableOperator";
import MsTableOperatorButton from "../../../../common/components/MsTableOperatorButton";
import MsTablePagination from "../../../../common/pagination/TablePagination";
import MsTag from "../../../../common/components/MsTag";
import MsBottomContainer from "../../../definition/components/BottomContainer";
import ShowMoreBtn from "../../../../track/case/components/ShowMoreBtn";
import MsBatchEdit from "../../../definition/components/basis/BatchEdit";
import {API_METHOD_COLOUR, CASE_PRIORITY} from "../../../definition/model/JsonData";
import {getCurrentProjectID} from "@/common/js/utils";
import ApiListContainer from "../../../definition/components/list/ApiListContainer";
import PriorityTableItem from "../../../../track/common/tableItems/planview/PriorityTableItem";
import {_filter, _sort} from "../../../../../../common/js/utils";
import {_handleSelect, _handleSelectAll} from "../../../../../../common/js/tableUtils";
import MsEnvironmentSelect from "../../../definition/components/case/MsEnvironmentSelect";
export default {
name: "RelevanceApiList",
components: {
MsEnvironmentSelect,
PriorityTableItem,
ApiListContainer,
MsTableOperatorButton,
MsTableOperator,
MsTablePagination,
MsTag,
MsBottomContainer,
ShowMoreBtn,
MsBatchEdit
export default {
name: "RelevanceApiList",
components: {
MsEnvironmentSelect,
PriorityTableItem,
ApiListContainer,
MsTableOperatorButton,
MsTableOperator,
MsTablePagination,
MsTag,
MsBottomContainer,
ShowMoreBtn,
MsBatchEdit
},
data() {
return {
condition: {},
selectCase: {},
result: {},
moduleId: "",
deletePath: "/test/case/delete",
selectRows: new Set(),
typeArr: [
{id: 'priority', name: this.$t('test_track.case.priority')},
],
priorityFilters: [
{text: 'P0', value: 'P0'},
{text: 'P1', value: 'P1'},
{text: 'P2', value: 'P2'},
{text: 'P3', value: 'P3'}
],
valueArr: {
priority: CASE_PRIORITY,
},
methodColorMap: new Map(API_METHOD_COLOUR),
tableData: [],
currentPage: 1,
pageSize: 10,
total: 0,
environmentId: ""
}
},
props: {
currentProtocol: String,
selectNodeIds: Array,
visible: {
type: Boolean,
default: false,
},
data() {
return {
condition: {},
selectCase: {},
result: {},
moduleId: "",
deletePath: "/test/case/delete",
selectRows: new Set(),
typeArr: [
{id: 'priority', name: this.$t('test_track.case.priority')},
],
priorityFilters: [
{text: 'P0', value: 'P0'},
{text: 'P1', value: 'P1'},
{text: 'P2', value: 'P2'},
{text: 'P3', value: 'P3'}
],
valueArr: {
priority: CASE_PRIORITY,
},
methodColorMap: new Map(API_METHOD_COLOUR),
tableData: [],
currentPage: 1,
pageSize: 10,
total: 0,
environmentId: ""
}
isApiListEnable: {
type: Boolean,
default: false,
},
props: {
currentProtocol: String,
selectNodeIds: Array,
visible: {
type: Boolean,
default: false,
},
isApiListEnable: {
type: Boolean,
default: false,
},
isReadOnly: {
type: Boolean,
default: false
},
isCaseRelevance: {
type: Boolean,
default: false,
},
projectId: String,
planId: String,
isTestPlan: Boolean
isReadOnly: {
type: Boolean,
default: false
},
created: function () {
isCaseRelevance: {
type: Boolean,
default: false,
},
projectId: String,
planId: String,
isTestPlan: Boolean
},
created: function () {
this.initTable();
},
watch: {
selectNodeIds() {
this.initTable();
},
watch: {
selectNodeIds() {
this.initTable();
},
currentProtocol() {
this.initTable();
},
projectId() {
this.initTable();
}
currentProtocol() {
this.initTable();
},
computed: {},
methods: {
isApiListEnableChange(data) {
this.$emit('isApiListEnableChange', data);
},
initTable() {
this.selectRows = new Set();
this.condition.filters = {status: ["Prepare", "Underway", "Completed"]};
this.condition.moduleIds = this.selectNodeIds;
if (this.trashEnable) {
this.condition.filters = ["Trash"];
this.condition.moduleIds = [];
}
if (this.projectId != null) {
this.condition.projectId = this.projectId;
} else {
this.condition.projectId = getCurrentProjectID();
}
if (this.currentProtocol != null) {
this.condition.protocol = this.currentProtocol;
}
let url = '/api/definition/list/';
if (this.isTestPlan) {
url = '/api/definition/list/relevance/';
this.condition.planId = this.planId;
}
this.result = this.$post(url + this.currentPage + "/" + this.pageSize, this.condition, response => {
this.total = response.data.itemCount;
this.tableData = response.data.listObject;
});
},
handleSelect(selection, row) {
_handleSelect(this, selection, row, this.selectRows);
},
showExecResult(row) {
this.visible = false;
this.$emit('showExecResult', row);
},
filter(filters) {
_filter(filters, this.condition);
this.initTable();
},
sort(column) {
//
if (this.condition.orders) {
this.condition.orders = [];
}
_sort(column, this.condition);
this.initTable();
},
handleSelectAll(selection) {
_handleSelectAll(this, selection, this.tableData, this.selectRows);
},
buildPagePath(path) {
return path + "/" + this.currentPage + "/" + this.pageSize;
},
getColor(method) {
return this.methodColorMap.get(method);
},
setEnvironment(data) {
this.environmentId = data.id;
}
projectId() {
this.initTable();
}
},
computed: {},
methods: {
isApiListEnableChange(data) {
this.$emit('isApiListEnableChange', data);
},
}
initTable() {
this.selectRows = new Set();
this.condition.filters = {status: ["Prepare", "Underway", "Completed"]};
this.condition.moduleIds = this.selectNodeIds;
if (this.trashEnable) {
this.condition.filters = {status: ["Trash"]};
this.condition.moduleIds = [];
}
if (this.projectId != null) {
this.condition.projectId = this.projectId;
} else {
this.condition.projectId = getCurrentProjectID();
}
if (this.currentProtocol != null) {
this.condition.protocol = this.currentProtocol;
}
let url = '/api/definition/list/';
if (this.isTestPlan) {
url = '/api/definition/list/relevance/';
this.condition.planId = this.planId;
}
this.result = this.$post(url + this.currentPage + "/" + this.pageSize, this.condition, response => {
this.total = response.data.itemCount;
this.tableData = response.data.listObject;
});
},
handleSelect(selection, row) {
_handleSelect(this, selection, row, this.selectRows);
},
showExecResult(row) {
this.visible = false;
this.$emit('showExecResult', row);
},
filter(filters) {
_filter(filters, this.condition);
this.initTable();
},
sort(column) {
//
if (this.condition.orders) {
this.condition.orders = [];
}
_sort(column, this.condition);
this.initTable();
},
handleSelectAll(selection) {
_handleSelectAll(this, selection, this.tableData, this.selectRows);
},
buildPagePath(path) {
return path + "/" + this.currentPage + "/" + this.pageSize;
},
getColor(method) {
return this.methodColorMap.get(method);
},
setEnvironment(data) {
this.environmentId = data.id;
}
},
}
</script>
<style scoped>
.operate-button > div {
display: inline-block;
margin-left: 10px;
}
.operate-button > div {
display: inline-block;
margin-left: 10px;
}
.request-method {
padding: 0 5px;
color: #1E90FF;
}
.request-method {
padding: 0 5px;
color: #1E90FF;
}
.api-el-tag {
color: white;
}
.api-el-tag {
color: white;
}
.search-input {
float: right;
width: 30%;
margin-bottom: 20px;
margin-right: 20px;
}
.search-input {
float: right;
width: 30%;
margin-bottom: 20px;
margin-right: 20px;
}
</style>

View File

@ -49,6 +49,9 @@
<el-table-column
prop="method"
sortable="custom"
column-key="method"
:filters="methodFilters"
:label="$t('api_test.definition.api_type')"
show-overflow-tooltip>
<template v-slot:default="scope" class="request-method">
@ -66,6 +69,9 @@
<el-table-column
prop="userName"
sortable="custom"
:filters="userFilters"
column-key="user_id"
:label="$t('api_test.definition.api_principal')"
show-overflow-tooltip/>
@ -77,7 +83,11 @@
</template>
</el-table-column>
<el-table-column width="160" :label="$t('api_test.definition.api_last_time')" prop="updateTime">
<el-table-column
width="160"
:label="$t('api_test.definition.api_last_time')"
sortable="custom"
prop="updateTime">
<template v-slot:default="scope">
<span>{{ scope.row.updateTime | timestampFormatDate }}</span>
</template>
@ -180,6 +190,21 @@ export default {
{text: this.$t('test_track.plan.plan_status_completed'), value: 'Completed'},
{text: this.$t('test_track.plan.plan_status_trash'), value: 'Trash'},
],
methodFilters: [
{text: 'GET', value: 'GET'},
{text: 'POST', value: 'POST'},
{text: 'PUT', value: 'PUT'},
{text: 'PATCH', value: 'PATCH'},
{text: 'DELETE', value: 'DELETE'},
{text: 'OPTIONS', value: 'OPTIONS'},
{text: 'HEAD', value: 'HEAD'},
{text: 'CONNECT', value: 'CONNECT'},
{text: 'DUBBO', value: 'DUBBO'},
{text: 'dubbo://', value: 'dubbo://'},
{text: 'SQL', value: 'SQL'},
{text: 'TCP', value: 'TCP'},
],
userFilters: [],
valueArr: {
status: API_STATUS,
method: REQ_METHOD,
@ -292,6 +317,9 @@ export default {
let workspaceId = localStorage.getItem(WORKSPACE_ID);
this.$post('/user/ws/member/tester/list', {workspaceId: workspaceId}, response => {
this.valueArr.userId = response.data;
this.userFilters = response.data.map(u => {
return {text: u.name, value: u.id}
});
});
},
handleSelect(selection, row) {

View File

@ -26,12 +26,13 @@
</template>
</el-table-column>
<el-table-column prop="num" label="ID" show-overflow-tooltip/>
<el-table-column prop="name" :label="$t('api_test.definition.api_name')" show-overflow-tooltip/>
<el-table-column prop="num" sortable="custom" label="ID" show-overflow-tooltip/>
<el-table-column prop="name" sortable="custom" :label="$t('api_test.definition.api_name')" show-overflow-tooltip/>
<el-table-column
prop="priority"
:filters="priorityFilters"
sortable="custom"
column-key="priority"
:label="$t('test_track.case.priority')"
show-overflow-tooltip>
@ -47,6 +48,9 @@
<el-table-column
prop="createUser"
column-key="user_id"
sortable="custom"
:filters="userFilters"
:label="'创建人'"
show-overflow-tooltip/>
@ -134,6 +138,7 @@ import MsRun from "../../../../../api/definition/components/Run";
import TestPlanApiCaseResult from "./TestPlanApiCaseResult";
import TestPlan from "../../../../../api/definition/components/jmeter/components/test-plan";
import ThreadGroup from "../../../../../api/definition/components/jmeter/components/thread-group";
import {WORKSPACE_ID} from "@/common/js/constants";
export default {
name: "TestPlanApiCaseList",
@ -177,6 +182,7 @@ export default {
],
valueArr: {
priority: CASE_PRIORITY,
userId: [],
},
methodColorMap: new Map(API_METHOD_COLOUR),
tableData: [],
@ -189,7 +195,8 @@ export default {
runData: [],
reportId: "",
response: {},
rowLoading: ""
rowLoading: "",
userFilters: []
}
},
props: {
@ -220,6 +227,7 @@ export default {
planId: String
},
created: function () {
this.getMaintainerOptions();
this.initTable();
},
watch: {
@ -248,6 +256,15 @@ export default {
},
},
methods: {
getMaintainerOptions() {
let workspaceId = localStorage.getItem(WORKSPACE_ID);
this.$post('/user/ws/member/tester/list', {workspaceId: workspaceId}, response => {
this.valueArr.userId = response.data;
this.userFilters = response.data.map(u => {
return {text: u.name, value: u.id}
});
});
},
isApiListEnableChange(data) {
this.$emit('isApiListEnableChange', data);
},

View File

@ -63,9 +63,9 @@ export default {
},
methods: {
refresh() {
this.selectNodeIds = [];
this.selectProjectId = '';
this.selectParentNodes = [];
this.$refs.testCaseLoadRelevance.search();
this.$refs.testPlanLoadCaseList.initTable();
this.getNodeTreeByPlanId();
},
initData() {

View File

@ -143,7 +143,8 @@ export default {
{text: 'Error', value: 'Error'}
],
reportId: '',
loading: false
loading: false,
statusScheduler: null
}
},
props: {
@ -156,6 +157,7 @@ export default {
},
created() {
this.initTable();
this.refreshStatus();
},
watch: {
selectProjectId() {
@ -179,6 +181,16 @@ export default {
this.tableData = data.listObject;
})
},
refreshStatus() {
this.refreshScheduler = setInterval(() => {
let arr = this.tableData.filter(data => data.status !== 'Completed' && data.status !== 'Error');
if (arr.length > 0) {
this.initTable();
} else {
clearInterval(this.refreshScheduler);
}
}, 4000);
},
handleSelectAll(selection) {
if (selection.length > 0) {
this.tableData.forEach(item => {
@ -220,17 +232,29 @@ export default {
})
},
handleRunBatch() {
this.selectRows.forEach(loadCase => {
this.run(loadCase);
})
},
run(loadCase) {
this.$post('/test/plan/load/case/run', {
id: loadCase.loadCaseId,
testPlanLoadId: loadCase.id,
triggerMode: 'MANUAL'
}, response => {
let reportId = response.data;
}).then(() => {
this.$notify({
title: loadCase.caseName,
message: '正在执行....',
type: 'success'
});
this.initTable();
}).catch(() => {
this.$notify.error({
title: loadCase.caseName,
message: '用例执行错误,请单独调试该用例!'
});
})
this.refreshStatus();
},
handleDelete(loadCase) {
this.result = this.$get('/test/plan/load/case/delete/' + loadCase.id, () => {
@ -268,8 +292,16 @@ export default {
// this.initTable();
}
})
},
cancelRefresh() {
if (this.refreshScheduler) {
clearInterval(this.refreshScheduler);
}
}
}
},
beforeDestroy() {
this.cancelRefresh();
},
}
</script>