Merge remote-tracking branch 'origin/master'

This commit is contained in:
Captain.B 2021-01-26 17:50:29 +08:00
commit f6a34e7076
18 changed files with 144 additions and 82 deletions

View File

@ -59,6 +59,20 @@ public class MsScenario extends MsTestElement {
if (!this.isEnable()) {
return;
}
if (this.getReferenced() != null && this.getReferenced().equals("Deleted")) {
return;
} else if (this.getReferenced() != null && this.getReferenced().equals("REF")) {
try {
ApiAutomationService apiAutomationService = CommonBeanFactory.getBean(ApiAutomationService.class);
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
ApiScenarioWithBLOBs scenario = apiAutomationService.getApiScenario(this.getId());
JSONObject element = JSON.parseObject(scenario.getScenarioDefinition());
hashTree = mapper.readValue(element.getString("hashTree"), new TypeReference<LinkedList<MsTestElement>>() {});
} catch (Exception ex) {
ex.printStackTrace();
}
}
config.setStep(this.name);
config.setStepType("SCENARIO");
config.setEnableCookieShare(enableCookieShare);
@ -72,26 +86,6 @@ public class MsScenario extends MsTestElement {
if (CollectionUtils.isNotEmpty(this.getVariables())) {
config.setVariables(this.variables);
}
if (this.getReferenced() != null && this.getReferenced().equals("Deleted")) {
return;
} else if (this.getReferenced() != null && this.getReferenced().equals("REF")) {
try {
ApiAutomationService apiAutomationService = CommonBeanFactory.getBean(ApiAutomationService.class);
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
ApiScenarioWithBLOBs scenario = apiAutomationService.getApiScenario(this.getId());
JSONObject element = JSON.parseObject(scenario.getScenarioDefinition());
LinkedList<MsTestElement> elements = mapper.readValue(element.getString("hashTree"), new TypeReference<LinkedList<MsTestElement>>() {
});
if (hashTree == null) {
hashTree = elements;
} else {
hashTree.addAll(elements);
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
// 场景变量和环境变量
tree.add(arguments(config));
addCsvDataSet(tree);

View File

@ -124,6 +124,12 @@ public class ApiAutomationService {
apiScenarioMapper.deleteByExample(example);
}
public void removeToGcByIds(List<String> nodeIds) {
ApiScenarioExample example = new ApiScenarioExample();
example.createCriteria().andApiScenarioModuleIdIn(nodeIds);
extApiScenarioMapper.removeToGcByExample(example);
}
public ApiScenario create(SaveApiScenarioRequest request, List<MultipartFile> bodyFiles) {
request.setId(UUID.randomUUID().toString());
checkNameExist(request);

View File

@ -174,6 +174,11 @@ public class ApiModuleService extends NodeTreeService<ApiModuleDTO> {
ApiModuleExample.Criteria criteria = example.createCriteria();
criteria.andNameEqualTo(node.getName())
.andProjectIdEqualTo(node.getProjectId());
if (StringUtils.isNotBlank(node.getProtocol())) {
criteria.andProtocolEqualTo(node.getProtocol());
}
if (StringUtils.isNotBlank(node.getParentId())) {
criteria.andParentIdEqualTo(node.getParentId());
} else {
@ -235,7 +240,7 @@ public class ApiModuleService extends NodeTreeService<ApiModuleDTO> {
public int deleteNode(List<String> nodeIds) {
ApiDefinitionExample apiDefinitionExample = new ApiDefinitionExample();
apiDefinitionExample.createCriteria().andModuleIdIn(nodeIds);
apiDefinitionMapper.deleteByExample(apiDefinitionExample);
extApiDefinitionMapper.removeToGcByExample(apiDefinitionExample); // 删除模块则模块下的接口放入回收站
ApiModuleExample apiDefinitionNodeExample = new ApiModuleExample();
apiDefinitionNodeExample.createCriteria().andIdIn(nodeIds);

View File

@ -194,7 +194,7 @@ public class ApiScenarioModuleService extends NodeTreeService<ApiScenarioModuleD
}
public int deleteNode(List<String> nodeIds) {
apiAutomationService.deleteByIds(nodeIds);
apiAutomationService.removeToGcByIds(nodeIds);
ApiScenarioModuleExample apiScenarioModuleExample = new ApiScenarioModuleExample();
apiScenarioModuleExample.createCriteria().andIdIn(nodeIds);

View File

@ -39,8 +39,11 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.io.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.net.URL;
import java.nio.channels.FileChannel;
import java.util.*;
@Service
@ -276,45 +279,12 @@ public class HistoricalDataUpgradeService {
private static final String BODY_FILE_DIR = "/opt/metersphere/data/body";
//文件的拷贝
private static void copyFile(String sourcePath, String newPath) {
File readfile = new File(sourcePath);
File newFile = new File(newPath);
BufferedWriter bufferedWriter = null;
Writer writer = null;
FileOutputStream fileOutputStream = null;
BufferedReader bufferedReader = null;
try {
fileOutputStream = new FileOutputStream(newFile, true);
writer = new OutputStreamWriter(fileOutputStream, "UTF-8");
bufferedWriter = new BufferedWriter(writer);
bufferedReader = new BufferedReader(new FileReader(readfile));
String line = null;
while ((line = bufferedReader.readLine()) != null) {
bufferedWriter.write(line);
bufferedWriter.newLine();
bufferedWriter.flush();
}
} catch (IOException e) {
public static void copyFile(String sourcePath, String newPath) {
try (FileChannel inChannel = new FileInputStream(new File(sourcePath)).getChannel();
FileChannel outChannel = new FileOutputStream(new File(newPath)).getChannel();) {
inChannel.transferTo(0, inChannel.size(), outChannel);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (bufferedWriter != null) {
bufferedWriter.close();
}
if (bufferedReader != null) {
bufferedReader.close();
}
if (writer != null) {
writer.close();
}
if (fileOutputStream != null) {
fileOutputStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@ -6,6 +6,8 @@ import io.metersphere.api.dto.definition.ApiDefinitionRequest;
import io.metersphere.api.dto.definition.ApiDefinitionResult;
import io.metersphere.api.dto.definition.ApiSwaggerUrlDTO;
import io.metersphere.base.domain.ApiDefinition;
import io.metersphere.base.domain.ApiDefinitionExample;
import io.metersphere.base.domain.ApiModuleExample;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@ -19,6 +21,8 @@ public interface ExtApiDefinitionMapper {
int removeToGc(@Param("ids") List<String> ids);
int removeToGcByExample(ApiDefinitionExample example);
int reduction(@Param("ids") List<String> ids);
List<ApiDataCountResult> countProtocolByProjectID(String projectId);

View File

@ -311,6 +311,15 @@
</foreach>
</update>
<update id="removeToGcByExample" parameterType="io.metersphere.base.domain.ApiDefinitionExample">
update api_definition
set
status = 'Trash', module_path = null, module_id = null
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
</update>
<update id="reduction">
update api_definition
set

View File

@ -4,6 +4,7 @@ import io.metersphere.api.dto.automation.ApiScenarioDTO;
import io.metersphere.api.dto.automation.ApiScenarioRequest;
import io.metersphere.api.dto.datacount.ApiDataCountResult;
import io.metersphere.base.domain.ApiScenario;
import io.metersphere.base.domain.ApiScenarioExample;
import io.metersphere.base.domain.ApiScenarioWithBLOBs;
import org.apache.ibatis.annotations.Param;
@ -20,6 +21,8 @@ public interface ExtApiScenarioMapper {
int removeToGc(@Param("ids") List<String> ids);
int removeToGcByExample(ApiScenarioExample example);
int reduction(@Param("ids") List<String> ids);
long countByProjectID(String projectId);

View File

@ -7,6 +7,35 @@
<result column="project_name" property="projectName"/>
<result column="user_name" property="userName"/>
</resultMap>
<sql id="Example_Where_Clause">
<where>
<foreach collection="oredCriteria" item="criteria" separator="or">
<if test="criteria.valid">
<trim prefix="(" prefixOverrides="and" suffix=")">
<foreach collection="criteria.criteria" item="criterion">
<choose>
<when test="criterion.noValue">
and ${criterion.condition}
</when>
<when test="criterion.singleValue">
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue">
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue">
and ${criterion.condition}
<foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql id="condition">
<choose>
<when test='${object}.operator == "like"'>
@ -243,6 +272,15 @@
</foreach>
</update>
<update id="removeToGcByExample" parameterType="io.metersphere.base.domain.ApiScenarioExample">
update api_scenario
set
status = 'Trash', module_path = null, api_scenario_module_id = null
<if test="_parameter != null">
<include refid="Example_Where_Clause" />
</if>
</update>
<update id="reduction">
update api_scenario
set

View File

@ -10,6 +10,7 @@ import io.metersphere.commons.utils.LogUtil;
import io.metersphere.dto.NodeDTO;
import io.metersphere.dto.TestResourcePoolDTO;
import io.metersphere.i18n.Translator;
import javafx.util.Pair;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.http.HttpStatus;
@ -39,29 +40,16 @@ public class NodeResourcePoolService {
}
deleteTestResource(testResourcePool.getId());
List<String> nodeIps = testResourcePool.getResources().stream()
List Ip_Port = testResourcePool.getResources().stream()
.map(resource -> {
NodeDTO nodeDTO = JSON.parseObject(resource.getConfiguration(), NodeDTO.class);
return nodeDTO.getIp();
return new Pair(nodeDTO.getIp(), nodeDTO.getPort());
})
.distinct()
.collect(Collectors.toList());
List<Integer> nodePorts = testResourcePool.getResources().stream()
.map(resource -> {
NodeDTO nodeDTO = JSON.parseObject(resource.getConfiguration(), NodeDTO.class);
return nodeDTO.getPort();
})
.distinct()
.collect(Collectors.toList());
if (nodeIps.size() < testResourcePool.getResources().size() && nodePorts.size() < testResourcePool.getResources().size()) {
if (Ip_Port.size() < testResourcePool.getResources().size()) {
MSException.throwException(Translator.get("duplicate_node_ip_port"));
}
else if (nodeIps.size() < testResourcePool.getResources().size()) {
MSException.throwException(Translator.get("duplicate_node_ip"));
}
else if (nodePorts.size() < testResourcePool.getResources().size()) {
MSException.throwException(Translator.get("duplicate_node_port"));
}
testResourcePool.setStatus(VALID.name());
boolean isValid = true;
for (TestResource resource : testResourcePool.getResources()) {

View File

@ -50,7 +50,7 @@ public class TestPlanController {
QueryTestPlanRequest request = new QueryTestPlanRequest();
request.setWorkspaceId(workspaceId);
request.setProjectId(projectId);
return testPlanService.listTestPlan(request);
return testPlanService.listTestPlanByProject(request);
}
@PostMapping("/list/all")

View File

@ -28,7 +28,13 @@
<el-table-column prop="num" label="ID"
sortable="custom"
show-overflow-tooltip/>
show-overflow-tooltip>
<template slot-scope="scope">
<el-tooltip content="编辑">
<a style="cursor:pointer" @click="edit(scope.row)"> {{ scope.row.num }} </a>
</el-tooltip>
</template>
</el-table-column>
<el-table-column prop="name"
sortable="custom"
:label="$t('api_test.automation.scenario_name')"

View File

@ -234,6 +234,9 @@
} else {
request = JSON.parse(this.api.request);
}
if (!request.hashTree) {
request.hashTree = [];
}
let obj = {apiDefinitionId: this.api.id, name: '', priority: 'P0', active: true, tags: []};
obj.request = request;
this.apiCaseList.unshift(obj);

View File

@ -31,7 +31,13 @@
</template>
</el-table-column>
<el-table-column prop="num" label="ID" show-overflow-tooltip/>
<el-table-column prop="num" label="ID" show-overflow-tooltip>
<template slot-scope="scope">
<el-tooltip content="编辑">
<a style="cursor:pointer" @click="handleTestCase(scope.row)"> {{ scope.row.num }} </a>
</el-tooltip>
</template>
</el-table-column>
<el-table-column prop="name" :label="$t('test_track.case.name')" show-overflow-tooltip/>
<el-table-column

View File

@ -31,7 +31,13 @@
</el-table-column>
<el-table-column prop="num" label="ID" show-overflow-tooltip
sortable="custom"/>
sortable="custom">
<template slot-scope="scope">
<el-tooltip content="编辑">
<a style="cursor:pointer" @click="editApi(scope.row)"> {{ scope.row.num }} </a>
</el-tooltip>
</template>
</el-table-column>
<el-table-column prop="name" :label="$t('api_test.definition.api_name')"
show-overflow-tooltip
sortable="custom" min-width="120px"/>

View File

@ -27,18 +27,30 @@
methods: {
addPre() {
let jsr223PreProcessor = createComponent("JSR223PreProcessor");
if (!this.request.hashTree) {
this.request.hashTree = [];
}
this.request.hashTree.push(jsr223PreProcessor);
},
addPost() {
let jsr223PostProcessor = createComponent("JSR223PostProcessor");
if (!this.request.hashTree) {
this.request.hashTree = [];
}
this.request.hashTree.push(jsr223PostProcessor);
},
addAssertions() {
let assertions = new Assertions();
if (!this.request.hashTree) {
this.request.hashTree = [];
}
this.request.hashTree.push(assertions);
},
addExtract() {
let jsonPostProcessor = new Extract();
if (!this.request.hashTree) {
this.request.hashTree = [];
}
this.request.hashTree.push(jsonPostProcessor);
},
}

View File

@ -105,21 +105,33 @@
methods: {
addPre() {
let jsr223PreProcessor = createComponent("JSR223PreProcessor");
if (!this.request.hashTree) {
this.request.hashTree = [];
}
this.request.hashTree.push(jsr223PreProcessor);
this.reload();
},
addPost() {
let jsr223PostProcessor = createComponent("JSR223PostProcessor");
if (!this.request.hashTree) {
this.request.hashTree = [];
}
this.request.hashTree.push(jsr223PostProcessor);
this.reload();
},
addAssertions() {
let assertions = new Assertions();
if (!this.request.hashTree) {
this.request.hashTree = [];
}
this.request.hashTree.push(assertions);
this.reload();
},
addExtract() {
let jsonPostProcessor = new Extract();
if (!this.request.hashTree) {
this.request.hashTree = [];
}
this.request.hashTree.push(jsonPostProcessor);
this.reload();
},

View File

@ -32,7 +32,7 @@
@cell-mouse-enter="showPopover"
row-key="id"
class="test-content adjust-table ms-select-all"
ref="table">
ref="table" @row-click="handleEdit">
<el-table-column
width="50"