feat(接口自动化): 数据迁移初版
This commit is contained in:
parent
b65c79424b
commit
fc8c997716
|
@ -14,7 +14,6 @@ import io.metersphere.api.service.*;
|
|||
import io.metersphere.base.domain.ApiTest;
|
||||
import io.metersphere.base.domain.Schedule;
|
||||
import io.metersphere.commons.constants.RoleConstants;
|
||||
import io.metersphere.commons.constants.ScheduleGroup;
|
||||
import io.metersphere.commons.utils.CronUtils;
|
||||
import io.metersphere.commons.utils.PageUtils;
|
||||
import io.metersphere.commons.utils.Pager;
|
||||
|
@ -60,6 +59,8 @@ public class APITestController {
|
|||
private ScheduleService scheduleService;
|
||||
@Resource
|
||||
private APIReportService apiReportService;
|
||||
@Resource
|
||||
private HistoricalDataUpgradeService historicalDataUpgradeService;
|
||||
|
||||
@GetMapping("recent/{count}")
|
||||
public List<APITestResult> recentTest(@PathVariable int count) {
|
||||
|
@ -109,6 +110,7 @@ public class APITestController {
|
|||
public void mergeCreate(@RequestPart("request") SaveAPITestRequest request, @RequestPart(value = "file") MultipartFile file, @RequestPart(value = "selectIds") List<String> selectIds) {
|
||||
apiTestService.mergeCreate(request, file, selectIds);
|
||||
}
|
||||
|
||||
@PostMapping(value = "/update", consumes = {"multipart/form-data"})
|
||||
public void update(@RequestPart("request") SaveAPITestRequest request, @RequestPart(value = "file") MultipartFile file, @RequestPart(value = "files") List<MultipartFile> bodyFiles) {
|
||||
checkownerService.checkApiTestOwner(request.getId());
|
||||
|
@ -189,19 +191,19 @@ public class APITestController {
|
|||
//查询完成率、进行中、已完成
|
||||
List<ApiDataCountResult> countResultByStatelList = apiDefinitionService.countStateByProjectID(projectId);
|
||||
apiCountResult.countStatus(countResultByStatelList);
|
||||
long allCount = apiCountResult.getFinishedCount()+apiCountResult.getRunningCount()+apiCountResult.getNotStartedCount();
|
||||
long allCount = apiCountResult.getFinishedCount() + apiCountResult.getRunningCount() + apiCountResult.getNotStartedCount();
|
||||
|
||||
if(allCount!=0){
|
||||
float complateRageNumber =(float)apiCountResult.getFinishedCount()*100/allCount;
|
||||
if (allCount != 0) {
|
||||
float complateRageNumber = (float) apiCountResult.getFinishedCount() * 100 / allCount;
|
||||
DecimalFormat df = new DecimalFormat("0.0");
|
||||
apiCountResult.setCompletionRage(df.format(complateRageNumber)+"%");
|
||||
apiCountResult.setCompletionRage(df.format(complateRageNumber) + "%");
|
||||
}
|
||||
|
||||
apiCountResult.setHttpCountStr("HTTP <br/><br/>"+apiCountResult.getHttpApiDataCountNumber());
|
||||
apiCountResult.setRpcCountStr("RPC <br/><br/>"+apiCountResult.getRpcApiDataCountNumber());
|
||||
apiCountResult.setTcpCountStr("TCP <br/><br/>"+apiCountResult.getTcpApiDataCountNumber());
|
||||
apiCountResult.setSqlCountStr("SQL <br/><br/>"+apiCountResult.getSqlApiDataCountNumber());
|
||||
return apiCountResult;
|
||||
apiCountResult.setHttpCountStr("HTTP <br/><br/>" + apiCountResult.getHttpApiDataCountNumber());
|
||||
apiCountResult.setRpcCountStr("RPC <br/><br/>" + apiCountResult.getRpcApiDataCountNumber());
|
||||
apiCountResult.setTcpCountStr("TCP <br/><br/>" + apiCountResult.getTcpApiDataCountNumber());
|
||||
apiCountResult.setSqlCountStr("SQL <br/><br/>" + apiCountResult.getSqlApiDataCountNumber());
|
||||
return apiCountResult;
|
||||
}
|
||||
|
||||
@GetMapping("/testCaseInfoCount/{projectId}")
|
||||
|
@ -222,21 +224,21 @@ public class APITestController {
|
|||
//未覆盖 已覆盖: 统计当前接口下是否含有案例
|
||||
List<ApiDataCountResult> countResultByApiCoverageList = apiDefinitionService.countApiCoverageByProjectID(projectId);
|
||||
apiCountResult.countApiCoverage(countResultByApiCoverageList);
|
||||
long allCount = apiCountResult.getCoverageCount()+apiCountResult.getUncoverageCount();
|
||||
long allCount = apiCountResult.getCoverageCount() + apiCountResult.getUncoverageCount();
|
||||
|
||||
if(allCount!=0){
|
||||
float coverageRageNumber =(float)apiCountResult.getCoverageCount()*100/allCount;
|
||||
if (allCount != 0) {
|
||||
float coverageRageNumber = (float) apiCountResult.getCoverageCount() * 100 / allCount;
|
||||
DecimalFormat df = new DecimalFormat("0.0");
|
||||
apiCountResult.setCoverageRage(df.format(coverageRageNumber)+"%");
|
||||
apiCountResult.setCoverageRage(df.format(coverageRageNumber) + "%");
|
||||
}
|
||||
|
||||
|
||||
apiCountResult.setHttpCountStr("HTTP <br/><br/>"+apiCountResult.getHttpApiDataCountNumber());
|
||||
apiCountResult.setRpcCountStr("RPC <br/><br/>"+apiCountResult.getRpcApiDataCountNumber());
|
||||
apiCountResult.setTcpCountStr("TCP <br/><br/>"+apiCountResult.getTcpApiDataCountNumber());
|
||||
apiCountResult.setSqlCountStr("SQL <br/><br/>"+apiCountResult.getSqlApiDataCountNumber());
|
||||
apiCountResult.setHttpCountStr("HTTP <br/><br/>" + apiCountResult.getHttpApiDataCountNumber());
|
||||
apiCountResult.setRpcCountStr("RPC <br/><br/>" + apiCountResult.getRpcApiDataCountNumber());
|
||||
apiCountResult.setTcpCountStr("TCP <br/><br/>" + apiCountResult.getTcpApiDataCountNumber());
|
||||
apiCountResult.setSqlCountStr("SQL <br/><br/>" + apiCountResult.getSqlApiDataCountNumber());
|
||||
|
||||
return apiCountResult;
|
||||
return apiCountResult;
|
||||
}
|
||||
|
||||
@GetMapping("/testSceneInfoCount/{projectId}")
|
||||
|
@ -263,15 +265,15 @@ public class APITestController {
|
|||
List<ApiDataCountResult> countResultByRunResult = apiAutomationService.countRunResultByProjectID(projectId);
|
||||
apiCountResult.countRunResult(countResultByRunResult);
|
||||
|
||||
long allCount = apiCountResult.getUnexecuteCount()+apiCountResult.getExecutionPassCount()+apiCountResult.getExecutionFailedCount();
|
||||
long allCount = apiCountResult.getUnexecuteCount() + apiCountResult.getExecutionPassCount() + apiCountResult.getExecutionFailedCount();
|
||||
|
||||
if(allCount!=0){
|
||||
float coverageRageNumber =(float)apiCountResult.getExecutionPassCount()*100/allCount;
|
||||
if (allCount != 0) {
|
||||
float coverageRageNumber = (float) apiCountResult.getExecutionPassCount() * 100 / allCount;
|
||||
DecimalFormat df = new DecimalFormat("0.0");
|
||||
apiCountResult.setPassRage(df.format(coverageRageNumber)+"%");
|
||||
apiCountResult.setPassRage(df.format(coverageRageNumber) + "%");
|
||||
}
|
||||
|
||||
return apiCountResult;
|
||||
return apiCountResult;
|
||||
|
||||
}
|
||||
|
||||
|
@ -287,7 +289,7 @@ public class APITestController {
|
|||
apiCountResult.setThisWeekAddedCount(taskCountInThisWeek);
|
||||
long api_executedInThisWeekCountNumber = apiReportService.countByProjectIdAndCreateInThisWeek(projectId);
|
||||
long scene_executedInThisWeekCountNumber = apiScenarioReportService.countByProjectIdAndCreateAndByScheduleInThisWeek(projectId);
|
||||
long executedInThisWeekCountNumber = api_executedInThisWeekCountNumber+scene_executedInThisWeekCountNumber;
|
||||
long executedInThisWeekCountNumber = api_executedInThisWeekCountNumber + scene_executedInThisWeekCountNumber;
|
||||
apiCountResult.setThisWeekExecutedCount(executedInThisWeekCountNumber);
|
||||
|
||||
//统计 失败 成功 以及总数
|
||||
|
@ -299,41 +301,41 @@ public class APITestController {
|
|||
apiCountResult.countScheduleExecute(allExecuteResult);
|
||||
|
||||
long allCount = apiCountResult.getExecutedCount();
|
||||
if(allCount!=0){
|
||||
float coverageRageNumber =(float)apiCountResult.getSuccessCount()*100/allCount;
|
||||
if (allCount != 0) {
|
||||
float coverageRageNumber = (float) apiCountResult.getSuccessCount() * 100 / allCount;
|
||||
DecimalFormat df = new DecimalFormat("0.0");
|
||||
apiCountResult.setSuccessRage(df.format(coverageRageNumber)+"%");
|
||||
apiCountResult.setSuccessRage(df.format(coverageRageNumber) + "%");
|
||||
}
|
||||
|
||||
return apiCountResult;
|
||||
return apiCountResult;
|
||||
}
|
||||
|
||||
@GetMapping("/faliureCaseAboutTestPlan/{projectId}/{limitNumber}")
|
||||
public List<ExecutedCaseInfoDTO> faliureCaseAboutTestPlan(@PathVariable String projectId, @PathVariable int limitNumber) {
|
||||
|
||||
List<ExecutedCaseInfoResult> selectDataList = apiDefinitionExecResultService.findFaliureCaseInfoByProjectIDAndLimitNumberInSevenDays(projectId,limitNumber);
|
||||
List<ExecutedCaseInfoResult> selectDataList = apiDefinitionExecResultService.findFaliureCaseInfoByProjectIDAndLimitNumberInSevenDays(projectId, limitNumber);
|
||||
|
||||
List<ExecutedCaseInfoDTO> returnList = new ArrayList<>(limitNumber);
|
||||
|
||||
for(int dataIndex = 0;dataIndex < limitNumber;dataIndex ++){
|
||||
for (int dataIndex = 0; dataIndex < limitNumber; dataIndex++) {
|
||||
|
||||
ExecutedCaseInfoDTO dataDTO = new ExecutedCaseInfoDTO();
|
||||
dataDTO.setSortIndex(dataIndex+1);
|
||||
dataDTO.setSortIndex(dataIndex + 1);
|
||||
|
||||
if(dataIndex<selectDataList.size()){
|
||||
if (dataIndex < selectDataList.size()) {
|
||||
ExecutedCaseInfoResult selectData = selectDataList.get(dataIndex);
|
||||
|
||||
dataDTO.setCaseName(selectData.getCaseName());
|
||||
dataDTO.setTestPlan(selectData.getTestPlan());
|
||||
dataDTO.setFailureTimes(selectData.getFailureTimes());
|
||||
dataDTO.setCaseType(selectData.getCaseType());
|
||||
}else {
|
||||
} else {
|
||||
dataDTO.setCaseName("");
|
||||
dataDTO.setTestPlan("");
|
||||
}
|
||||
returnList.add(dataDTO);
|
||||
}
|
||||
return returnList;
|
||||
return returnList;
|
||||
}
|
||||
|
||||
@GetMapping("/runningTask/{projectID}")
|
||||
|
@ -343,11 +345,11 @@ public class APITestController {
|
|||
for (TaskInfoResult taskInfo :
|
||||
resultList) {
|
||||
Date nextExecutionTime = CronUtils.getNextTriggerTime(taskInfo.getRule());
|
||||
if(nextExecutionTime!=null){
|
||||
if (nextExecutionTime != null) {
|
||||
taskInfo.setNextExecutionTime(nextExecutionTime.getTime());
|
||||
}
|
||||
}
|
||||
return resultList;
|
||||
return resultList;
|
||||
}
|
||||
|
||||
@PostMapping(value = "/schedule/updateEnableByPrimyKey")
|
||||
|
@ -356,4 +358,10 @@ public class APITestController {
|
|||
schedule.setEnable(request.isEnable());
|
||||
apiAutomationService.updateSchedule(schedule);
|
||||
}
|
||||
|
||||
|
||||
@PostMapping(value = "/historicalDataUpgrade")
|
||||
public String historicalDataUpgrade(@RequestBody SaveHistoricalDataUpgrade request) {
|
||||
return historicalDataUpgradeService.upgrade(request);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -121,5 +121,6 @@ public class ApiAutomationController {
|
|||
public void createSchedule(@RequestBody Schedule request) {
|
||||
apiAutomationService.createSchedule(request);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
package io.metersphere.api.dto;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Setter
|
||||
@Getter
|
||||
public class SaveHistoricalDataUpgrade {
|
||||
private List<String> testIds;
|
||||
|
||||
private String projectId;
|
||||
|
||||
private String modulePath;
|
||||
|
||||
private String moduleId;
|
||||
}
|
|
@ -31,7 +31,7 @@ public class MsDubboSampler extends MsTestElement {
|
|||
private String type = "DubboSampler";
|
||||
|
||||
@JSONField(ordinal = 52)
|
||||
private String protocol;
|
||||
private String protocol = "DUBBO";
|
||||
@JsonProperty(value = "interface")
|
||||
@JSONField(ordinal = 53, name = "interface")
|
||||
private String _interface;
|
||||
|
|
|
@ -172,7 +172,7 @@ public class MsHTTPSamplerProxy extends MsTestElement {
|
|||
LogUtil.error(e);
|
||||
}
|
||||
// REST参数
|
||||
if (CollectionUtils.isNotEmpty(this.getArguments())) {
|
||||
if (CollectionUtils.isNotEmpty(this.getRest())) {
|
||||
sampler.setArguments(httpArguments(this.getRest()));
|
||||
}
|
||||
// 请求参数
|
||||
|
@ -186,7 +186,9 @@ public class MsHTTPSamplerProxy extends MsTestElement {
|
|||
if (StringUtils.isNotEmpty(this.body.getType()) && this.body.getType().equals("Form Data")) {
|
||||
sampler.setDoMultipart(true);
|
||||
}
|
||||
sampler.setArguments(httpArguments(bodyParams));
|
||||
if (CollectionUtils.isNotEmpty(bodyParams)) {
|
||||
sampler.setArguments(httpArguments(bodyParams));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,331 @@
|
|||
package io.metersphere.api.service;
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import io.metersphere.api.dto.SaveHistoricalDataUpgrade;
|
||||
import io.metersphere.api.dto.automation.ScenarioStatus;
|
||||
import io.metersphere.api.dto.definition.request.MsScenario;
|
||||
import io.metersphere.api.dto.definition.request.MsTestElement;
|
||||
import io.metersphere.api.dto.definition.request.assertions.MsAssertions;
|
||||
import io.metersphere.api.dto.definition.request.controller.MsIfController;
|
||||
import io.metersphere.api.dto.definition.request.extract.MsExtract;
|
||||
import io.metersphere.api.dto.definition.request.processors.post.MsJSR223PostProcessor;
|
||||
import io.metersphere.api.dto.definition.request.processors.pre.MsJSR223PreProcessor;
|
||||
import io.metersphere.api.dto.definition.request.sampler.MsDubboSampler;
|
||||
import io.metersphere.api.dto.definition.request.sampler.MsHTTPSamplerProxy;
|
||||
import io.metersphere.api.dto.definition.request.sampler.MsJDBCSampler;
|
||||
import io.metersphere.api.dto.definition.request.sampler.MsTCPSampler;
|
||||
import io.metersphere.api.dto.definition.request.timer.MsConstantTimer;
|
||||
import io.metersphere.api.dto.scenario.Scenario;
|
||||
import io.metersphere.api.dto.scenario.request.*;
|
||||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.ApiScenarioMapper;
|
||||
import io.metersphere.base.mapper.ApiTestMapper;
|
||||
import io.metersphere.base.mapper.ext.ExtApiScenarioMapper;
|
||||
import io.metersphere.commons.utils.BeanUtils;
|
||||
import io.metersphere.commons.utils.DateUtils;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.commons.utils.SessionUtils;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.ibatis.session.ExecutorType;
|
||||
import org.apache.ibatis.session.SqlSession;
|
||||
import org.apache.ibatis.session.SqlSessionFactory;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.*;
|
||||
import java.net.URL;
|
||||
import java.util.*;
|
||||
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class HistoricalDataUpgradeService {
|
||||
@Resource
|
||||
private ApiTestMapper apiTestMapper;
|
||||
@Resource
|
||||
private ExtApiScenarioMapper extApiScenarioMapper;
|
||||
@Resource
|
||||
SqlSessionFactory sqlSessionFactory;
|
||||
|
||||
private int getNextNum(String projectId) {
|
||||
ApiScenario apiScenario = extApiScenarioMapper.getNextNum(projectId);
|
||||
if (apiScenario == null) {
|
||||
return 100001;
|
||||
} else {
|
||||
return Optional.of(apiScenario.getNum() + 1).orElse(100001);
|
||||
}
|
||||
}
|
||||
|
||||
private MsScenario createScenario(Scenario oldScenario) {
|
||||
MsScenario scenario = new MsScenario();
|
||||
scenario.setVariables(oldScenario.getVariables());
|
||||
scenario.setName(oldScenario.getName());
|
||||
scenario.setEnableCookieShare(oldScenario.isEnableCookieShare());
|
||||
scenario.setEnvironmentId(oldScenario.getEnvironmentId());
|
||||
scenario.setReferenced("Upgrade");
|
||||
scenario.setId(oldScenario.getId());
|
||||
scenario.setResourceId(UUID.randomUUID().toString());
|
||||
LinkedList<MsTestElement> testElements = new LinkedList<>();
|
||||
int index = 1;
|
||||
for (Request request : oldScenario.getRequests()) {
|
||||
// 条件控制器
|
||||
MsIfController ifController = null;
|
||||
if (request.getController() != null && StringUtils.isNotEmpty(request.getController().getValue())
|
||||
&& StringUtils.isNotEmpty(request.getController().getVariable())) {
|
||||
ifController = new MsIfController();
|
||||
BeanUtils.copyBean(ifController, request.getController());
|
||||
ifController.setType("IfController");
|
||||
ifController.setName("IfController");
|
||||
ifController.setIndex(index + "");
|
||||
ifController.setResourceId(UUID.randomUUID().toString());
|
||||
}
|
||||
// 等待控制器
|
||||
if (request.getTimer() != null && StringUtils.isNotEmpty(request.getTimer().getDelay())) {
|
||||
MsConstantTimer constantTimer = new MsConstantTimer();
|
||||
BeanUtils.copyBean(constantTimer, request.getTimer());
|
||||
constantTimer.setType("ConstantTimer");
|
||||
constantTimer.setIndex(index + "");
|
||||
constantTimer.setResourceId(UUID.randomUUID().toString());
|
||||
testElements.add(constantTimer);
|
||||
}
|
||||
|
||||
MsTestElement element = null;
|
||||
if (request instanceof HttpRequest) {
|
||||
element = new MsHTTPSamplerProxy();
|
||||
HttpRequest request1 = (HttpRequest) request;
|
||||
if (StringUtils.isEmpty(request1.getPath()) && StringUtils.isNotEmpty(request1.getUrl())) {
|
||||
try {
|
||||
URL urlObject = new URL(request1.getUrl());
|
||||
String envPath = StringUtils.equals(urlObject.getPath(), "/") ? "" : urlObject.getPath();
|
||||
request1.setPath(envPath);
|
||||
} catch (Exception ex) {
|
||||
LogUtil.error(ex.getMessage());
|
||||
}
|
||||
}
|
||||
BeanUtils.copyBean(element, request1);
|
||||
((MsHTTPSamplerProxy) element).setProtocol(RequestType.HTTP);
|
||||
((MsHTTPSamplerProxy) element).setArguments(request1.getParameters());
|
||||
element.setType("HTTPSamplerProxy");
|
||||
}
|
||||
if (request instanceof DubboRequest) {
|
||||
String requestJson = JSON.toJSONString(request);
|
||||
element = JSON.parseObject(requestJson, MsDubboSampler.class);
|
||||
element.setType("DubboSampler");
|
||||
}
|
||||
if (request instanceof SqlRequest) {
|
||||
element = new MsJDBCSampler();
|
||||
SqlRequest request1 = (SqlRequest) request;
|
||||
BeanUtils.copyBean(element, request1);
|
||||
element.setType("JDBCSampler");
|
||||
}
|
||||
if (request instanceof TCPRequest) {
|
||||
element = new MsTCPSampler();
|
||||
TCPRequest request1 = (TCPRequest) request;
|
||||
BeanUtils.copyBean(element, request1);
|
||||
element.setType("TCPSampler");
|
||||
}
|
||||
element.setIndex(index + "");
|
||||
element.setResourceId(UUID.randomUUID().toString());
|
||||
LinkedList<MsTestElement> msTestElements = new LinkedList<>();
|
||||
// 断言规则
|
||||
if (request.getAssertions() != null && ((request.getAssertions().getDuration() != null && request.getAssertions().getDuration().getValue() > 0) ||
|
||||
CollectionUtils.isNotEmpty(request.getAssertions().getJsonPath()) || CollectionUtils.isNotEmpty(request.getAssertions().getJsr223()) ||
|
||||
CollectionUtils.isNotEmpty(request.getAssertions().getRegex()) || CollectionUtils.isNotEmpty(request.getAssertions().getXpath2()))) {
|
||||
String assertions = JSON.toJSONString(request.getAssertions());
|
||||
MsAssertions msAssertions = JSON.parseObject(assertions, MsAssertions.class);
|
||||
msAssertions.setType("Assertions");
|
||||
msAssertions.setIndex(index + "");
|
||||
msAssertions.setResourceId(UUID.randomUUID().toString());
|
||||
msTestElements.add(msAssertions);
|
||||
}
|
||||
// 提取规则
|
||||
if (request.getExtract() != null && (CollectionUtils.isNotEmpty(request.getExtract().getJson()) ||
|
||||
CollectionUtils.isNotEmpty(request.getExtract().getRegex()) || CollectionUtils.isNotEmpty(request.getExtract().getXpath()))) {
|
||||
String extractJson = JSON.toJSONString(request.getExtract());
|
||||
MsExtract extract = JSON.parseObject(extractJson, MsExtract.class);
|
||||
extract.setType("Extract");
|
||||
extract.setIndex(index + "");
|
||||
extract.setResourceId(UUID.randomUUID().toString());
|
||||
msTestElements.add(extract);
|
||||
}
|
||||
// 前置脚本
|
||||
if (request.getJsr223PreProcessor() != null && StringUtils.isNotEmpty(request.getJsr223PreProcessor().getScript())) {
|
||||
String preJson = JSON.toJSONString(request.getJsr223PreProcessor());
|
||||
MsJSR223PreProcessor preProcessor = JSON.parseObject(preJson, MsJSR223PreProcessor.class);
|
||||
preProcessor.setType("JSR223PreProcessor");
|
||||
preProcessor.setIndex(index + "");
|
||||
preProcessor.setResourceId(UUID.randomUUID().toString());
|
||||
msTestElements.add(preProcessor);
|
||||
}
|
||||
// 后置脚本
|
||||
if (request.getJsr223PostProcessor() != null && StringUtils.isNotEmpty(request.getJsr223PostProcessor().getScript())) {
|
||||
String preJson = JSON.toJSONString(request.getJsr223PostProcessor());
|
||||
MsJSR223PostProcessor preProcessor = JSON.parseObject(preJson, MsJSR223PostProcessor.class);
|
||||
preProcessor.setType("JSR223PostProcessor");
|
||||
preProcessor.setIndex(index + "");
|
||||
preProcessor.setResourceId(UUID.randomUUID().toString());
|
||||
msTestElements.add(preProcessor);
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(msTestElements)) {
|
||||
element.setHashTree(msTestElements);
|
||||
}
|
||||
if (ifController != null) {
|
||||
LinkedList<MsTestElement> elements = new LinkedList<>();
|
||||
elements.add(element);
|
||||
ifController.setHashTree(elements);
|
||||
testElements.add(ifController);
|
||||
} else {
|
||||
testElements.add(element);
|
||||
}
|
||||
index++;
|
||||
}
|
||||
scenario.setHashTree(testElements);
|
||||
return scenario;
|
||||
}
|
||||
|
||||
private ApiScenarioWithBLOBs checkNameExist(Scenario oldScenario, String projectId, ApiScenarioMapper mapper) {
|
||||
ApiScenarioExample example = new ApiScenarioExample();
|
||||
example.createCriteria().andIdEqualTo(oldScenario.getId());
|
||||
List<ApiScenarioWithBLOBs> list = mapper.selectByExampleWithBLOBs(example);
|
||||
if (list.size() > 0) {
|
||||
return list.get(0);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
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) {
|
||||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void copyDir(String sourcePathDir, String newPathDir) {
|
||||
File start = new File(sourcePathDir);
|
||||
File end = new File(newPathDir);
|
||||
String[] filePath = start.list();
|
||||
if (!end.exists()) {
|
||||
end.mkdir();
|
||||
}
|
||||
for (String temp : filePath) {
|
||||
//添加满足情况的条件
|
||||
if (new File(sourcePathDir + File.separator + temp).isFile()) {
|
||||
//为文件则进行拷贝
|
||||
copyFile(sourcePathDir + File.separator + temp, newPathDir + File.separator + temp);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void createBodyFiles(String testId) {
|
||||
String dir = BODY_FILE_DIR + "/" + testId;
|
||||
File testDir = new File(dir);
|
||||
if (testDir.exists()) {
|
||||
testDir.mkdirs();
|
||||
}
|
||||
copyDir(dir, BODY_FILE_DIR);
|
||||
}
|
||||
|
||||
private void createApiScenarioWithBLOBs(SaveHistoricalDataUpgrade saveHistoricalDataUpgrade, Scenario oldScenario, String scenarioDefinition, ApiScenarioMapper mapper) {
|
||||
if (StringUtils.isEmpty(oldScenario.getName())) {
|
||||
oldScenario.setName("默认名称-" + DateUtils.getTimeStr(System.currentTimeMillis()));
|
||||
}
|
||||
ApiScenarioWithBLOBs scenario = checkNameExist(oldScenario, saveHistoricalDataUpgrade.getProjectId(), mapper);
|
||||
if (scenario != null) {
|
||||
scenario.setName(oldScenario.getName());
|
||||
scenario.setProjectId(saveHistoricalDataUpgrade.getProjectId());
|
||||
scenario.setTags(scenario.getTags());
|
||||
scenario.setLevel("P0");
|
||||
scenario.setModulePath(saveHistoricalDataUpgrade.getModulePath());
|
||||
scenario.setApiScenarioModuleId(saveHistoricalDataUpgrade.getModuleId());
|
||||
scenario.setPrincipal(Objects.requireNonNull(SessionUtils.getUser()).getId());
|
||||
scenario.setStepTotal(oldScenario.getRequests().size());
|
||||
scenario.setScenarioDefinition(scenarioDefinition);
|
||||
scenario.setUpdateTime(System.currentTimeMillis());
|
||||
scenario.setStatus(ScenarioStatus.Underway.name());
|
||||
scenario.setUserId(SessionUtils.getUserId());
|
||||
scenario.setNum(getNextNum(saveHistoricalDataUpgrade.getProjectId()));
|
||||
mapper.updateByPrimaryKeySelective(scenario);
|
||||
} else {
|
||||
scenario = new ApiScenarioWithBLOBs();
|
||||
scenario.setId(oldScenario.getId());
|
||||
scenario.setName(oldScenario.getName());
|
||||
scenario.setProjectId(saveHistoricalDataUpgrade.getProjectId());
|
||||
scenario.setTags(scenario.getTags());
|
||||
scenario.setLevel("P0");
|
||||
scenario.setModulePath(saveHistoricalDataUpgrade.getModulePath());
|
||||
scenario.setApiScenarioModuleId(saveHistoricalDataUpgrade.getModuleId());
|
||||
scenario.setPrincipal(Objects.requireNonNull(SessionUtils.getUser()).getId());
|
||||
scenario.setStepTotal(oldScenario.getRequests().size());
|
||||
scenario.setScenarioDefinition(scenarioDefinition);
|
||||
scenario.setCreateTime(System.currentTimeMillis());
|
||||
scenario.setUpdateTime(System.currentTimeMillis());
|
||||
scenario.setStatus(ScenarioStatus.Underway.name());
|
||||
scenario.setUserId(SessionUtils.getUserId());
|
||||
scenario.setNum(getNextNum(saveHistoricalDataUpgrade.getProjectId()));
|
||||
mapper.insert(scenario);
|
||||
}
|
||||
}
|
||||
|
||||
public String upgrade(SaveHistoricalDataUpgrade saveHistoricalDataUpgrade) {
|
||||
ApiTestExample example = new ApiTestExample();
|
||||
example.createCriteria().andIdIn(saveHistoricalDataUpgrade.getTestIds());
|
||||
List<ApiTest> blobs = apiTestMapper.selectByExampleWithBLOBs(example);
|
||||
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
|
||||
ApiScenarioMapper mapper = sqlSession.getMapper(ApiScenarioMapper.class);
|
||||
for (ApiTest test : blobs) {
|
||||
// 附件迁移
|
||||
createBodyFiles(test.getId());
|
||||
|
||||
List<Scenario> scenarios = JSON.parseArray(test.getScenarioDefinition(), Scenario.class);
|
||||
if (CollectionUtils.isNotEmpty(scenarios)) {
|
||||
// 批量处理
|
||||
for (Scenario scenario : scenarios) {
|
||||
MsScenario scenario1 = createScenario(scenario);
|
||||
String scenarioDefinition = JSON.toJSONString(scenario1);
|
||||
createApiScenarioWithBLOBs(saveHistoricalDataUpgrade, scenario, scenarioDefinition, mapper);
|
||||
}
|
||||
}
|
||||
}
|
||||
sqlSession.flushStatements();
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -58,8 +58,8 @@
|
|||
<p class="tip">{{$t('api_test.definition.request.req_param')}} </p>
|
||||
<ms-api-request-form :referenced="true" :headers="request.headers " :request="request" v-if="request.protocol==='HTTP' || request.type==='HTTPSamplerProxy'"/>
|
||||
<ms-tcp-basis-parameters :request="request" v-if="request.protocol==='TCP'|| request.type==='TCPSampler'"/>
|
||||
<ms-sql-basis-parameters :request="request" v-if="request.protocol==='SQL'|| request.type==='JDBCSampler'"/>
|
||||
<ms-dubbo-basis-parameters :request="request" v-if="request.protocol==='DUBBO' || request.protocol==='dubbo://'|| request.type==='DubboSampler'"/>
|
||||
<ms-sql-basis-parameters :request="request" v-if="request.protocol==='SQL'|| request.type==='JDBCSampler'" :showScript="false"/>
|
||||
<ms-dubbo-basis-parameters :request="request" v-if="request.protocol==='DUBBO' || request.protocol==='dubbo://'|| request.type==='DubboSampler'" :showScript="false"/>
|
||||
|
||||
<p class="tip">{{$t('api_test.definition.request.res_param')}} </p>
|
||||
<ms-request-result-tail :currentProtocol="request.protocol" :response="request.requestResult" ref="runResult"/>
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
import MsApiAssertionRegex from "./ApiAssertionRegex";
|
||||
import MsApiAssertionDuration from "./ApiAssertionDuration";
|
||||
import MsApiAssertionJsonPath from "./ApiAssertionJsonPath";
|
||||
import MsApiAssertionJsr223 from "@/business/components/api/test/components/assertion/ApiAssertionJsr223";
|
||||
import MsApiAssertionJsr223 from "./ApiAssertionJsr223";
|
||||
import MsApiAssertionXPath2 from "./ApiAssertionXPath2";
|
||||
|
||||
export default {
|
||||
|
|
|
@ -63,18 +63,19 @@
|
|||
</el-tabs>
|
||||
</el-form>
|
||||
</div>
|
||||
<div v-for="row in request.hashTree" :key="row.id" v-loading="isReloadData" style="margin-left: 20px;width: 100%">
|
||||
<!-- 前置脚本 -->
|
||||
<ms-jsr233-processor v-if="row.label ==='JSR223 PreProcessor'" @copyRow="copyRow" @remove="remove" :is-read-only="false" :title="$t('api_test.definition.request.pre_script')" style-type="color: #B8741A;background-color: #F9F1EA"
|
||||
:jsr223-processor="row"/>
|
||||
<!--后置脚本-->
|
||||
<ms-jsr233-processor v-if="row.label ==='JSR223 PostProcessor'" @copyRow="copyRow" @remove="remove" :is-read-only="false" :title="$t('api_test.definition.request.post_script')" style-type="color: #783887;background-color: #F2ECF3"
|
||||
:jsr223-processor="row"/>
|
||||
<!--断言规则-->
|
||||
<ms-api-assertions v-if="row.type==='Assertions'" @copyRow="copyRow" @remove="remove" :is-read-only="isReadOnly" :assertions="row"/>
|
||||
<!--提取规则-->
|
||||
<ms-api-extract :is-read-only="isReadOnly" @copyRow="copyRow" @remove="remove" v-if="row.type==='Extract'" :extract="row"/>
|
||||
|
||||
<div v-if="showScript">
|
||||
<div v-for="row in request.hashTree" :key="row.id" v-loading="isReloadData" style="margin-left: 20px;width: 100%">
|
||||
<!-- 前置脚本 -->
|
||||
<ms-jsr233-processor v-if="row.label ==='JSR223 PreProcessor'" @copyRow="copyRow" @remove="remove" :is-read-only="false" :title="$t('api_test.definition.request.pre_script')" style-type="color: #B8741A;background-color: #F9F1EA"
|
||||
:jsr223-processor="row"/>
|
||||
<!--后置脚本-->
|
||||
<ms-jsr233-processor v-if="row.label ==='JSR223 PostProcessor'" @copyRow="copyRow" @remove="remove" :is-read-only="false" :title="$t('api_test.definition.request.post_script')" style-type="color: #783887;background-color: #F2ECF3"
|
||||
:jsr223-processor="row"/>
|
||||
<!--断言规则-->
|
||||
<ms-api-assertions v-if="row.type==='Assertions'" @copyRow="copyRow" @remove="remove" :is-read-only="isReadOnly" :assertions="row"/>
|
||||
<!--提取规则-->
|
||||
<ms-api-extract :is-read-only="isReadOnly" @copyRow="copyRow" @remove="remove" v-if="row.type==='Extract'" :extract="row"/>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
<el-col :span="3" class="ms-left-cell" v-if="showScript">
|
||||
|
|
|
@ -41,19 +41,19 @@
|
|||
|
||||
</el-form>
|
||||
</div>
|
||||
|
||||
<div v-for="row in request.hashTree" :key="row.id" v-loading="isReloadData" style="margin-left: 20px;width: 100%">
|
||||
<!-- 前置脚本 -->
|
||||
<ms-jsr233-processor v-if="row.label ==='JSR223 PreProcessor'" @copyRow="copyRow" @remove="remove" :is-read-only="false" :title="$t('api_test.definition.request.pre_script')" style-type="color: #B8741A;background-color: #F9F1EA"
|
||||
:jsr223-processor="row"/>
|
||||
<!--后置脚本-->
|
||||
<ms-jsr233-processor v-if="row.label ==='JSR223 PostProcessor'" @copyRow="copyRow" @remove="remove" :is-read-only="false" :title="$t('api_test.definition.request.post_script')" style-type="color: #783887;background-color: #F2ECF3"
|
||||
:jsr223-processor="row"/>
|
||||
<!--断言规则-->
|
||||
<ms-api-assertions v-if="row.type==='Assertions'" @copyRow="copyRow" @remove="remove" :is-read-only="isReadOnly" :assertions="row"/>
|
||||
<!--提取规则-->
|
||||
<ms-api-extract :is-read-only="isReadOnly" @copyRow="copyRow" @remove="remove" v-if="row.type==='Extract'" :extract="row"/>
|
||||
|
||||
<div v-if="showScript">
|
||||
<div v-for="row in request.hashTree" :key="row.id" v-loading="isReloadData" style="margin-left: 20px;width: 100%">
|
||||
<!-- 前置脚本 -->
|
||||
<ms-jsr233-processor v-if="row.label ==='JSR223 PreProcessor'" @copyRow="copyRow" @remove="remove" :is-read-only="false" :title="$t('api_test.definition.request.pre_script')" style-type="color: #B8741A;background-color: #F9F1EA"
|
||||
:jsr223-processor="row"/>
|
||||
<!--后置脚本-->
|
||||
<ms-jsr233-processor v-if="row.label ==='JSR223 PostProcessor'" @copyRow="copyRow" @remove="remove" :is-read-only="false" :title="$t('api_test.definition.request.post_script')" style-type="color: #783887;background-color: #F2ECF3"
|
||||
:jsr223-processor="row"/>
|
||||
<!--断言规则-->
|
||||
<ms-api-assertions v-if="row.type==='Assertions'" @copyRow="copyRow" @remove="remove" :is-read-only="isReadOnly" :assertions="row"/>
|
||||
<!--提取规则-->
|
||||
<ms-api-extract :is-read-only="isReadOnly" @copyRow="copyRow" @remove="remove" v-if="row.type==='Extract'" :extract="row"/>
|
||||
</div>
|
||||
</div>
|
||||
</el-col>
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
:title="$t('commons.test')"
|
||||
@create="create" :createTip="$t('load_test.create')" :runTip="$t('load_test.run')"
|
||||
:show-run="true"
|
||||
@runTest="runTest"/>
|
||||
@runTest="runTest" @historicalDataUpgrade="historicalDataUpgrade"/>
|
||||
|
||||
</template>
|
||||
|
||||
|
@ -54,7 +54,8 @@
|
|||
</el-card>
|
||||
|
||||
<api-copy-dialog ref="apiCopy" @refresh="search"/>
|
||||
|
||||
<ms-upgrade ref="upgrade" :select-ids="selectIds"
|
||||
:select-project-names="selectProjectNames" :select-project-id="selectProjectId"/>
|
||||
</ms-main-container>
|
||||
</ms-container>
|
||||
</template>
|
||||
|
@ -72,13 +73,14 @@
|
|||
import {TEST_CONFIGS} from "../../common/components/search/search-components";
|
||||
import {ApiEvent, LIST_CHANGE} from "@/business/components/common/head/ListEvent";
|
||||
import ApiCopyDialog from "./components/ApiCopyDialog";
|
||||
import MsUpgrade from "./Upgrade";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ApiCopyDialog,
|
||||
OneClickOperation,
|
||||
MsTableOperators,
|
||||
MsApiTestStatus, MsMainContainer, MsContainer, MsTableHeader, MsTablePagination, MsTableOperator
|
||||
MsApiTestStatus, MsMainContainer, MsContainer, MsTableHeader, MsTablePagination, MsTableOperator, MsUpgrade
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -204,6 +206,13 @@
|
|||
_filter(filters, this.condition);
|
||||
this.init();
|
||||
},
|
||||
historicalDataUpgrade() {
|
||||
if (this.selectIds.size < 1) {
|
||||
this.$warning(this.$t('test_track.plan_view.select_manipulate'));
|
||||
} else {
|
||||
this.$refs.upgrade.openOneClickOperation();
|
||||
}
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.init();
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
<template>
|
||||
<el-dialog
|
||||
title="选则模块"
|
||||
:visible.sync="oneClickOperationVisible"
|
||||
width="600px"
|
||||
left
|
||||
:destroy-on-close="true"
|
||||
show-close
|
||||
@closed="handleClose" v-loading="loading">
|
||||
<el-form :model="ruleForm" label-position="right" label-width="80px" size="small" :rules="rule">
|
||||
<el-form-item :label="$t('test_track.module.module')" prop="apiScenarioModuleId">
|
||||
<el-select size="small" style="width: 80%" v-model="apiScenarioModuleId">
|
||||
<el-option v-for="item in moduleOptions" :key="item.id" :label="item.path" :value="item.id"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<span slot="footer" class="dialog-footer">
|
||||
<ms-dialog-footer
|
||||
@cancel="oneClickOperationVisible = false"
|
||||
@confirm="confirm"/>
|
||||
</span>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import MsDialogFooter from '../../common/components/MsDialogFooter'
|
||||
import MsApiScenarioConfig from "./components/ApiScenarioConfig";
|
||||
import MsApiReportStatus from "../report/ApiReportStatus";
|
||||
import MsApiReportDialog from "./ApiReportDialog";
|
||||
import {getUUID, getCurrentProjectID} from "@/common/js/utils";
|
||||
import {buildNodePath} from "../definition/model/NodeTree";
|
||||
|
||||
|
||||
export default {
|
||||
name: "MsUpgrade",
|
||||
components: {
|
||||
MsApiReportDialog, MsApiReportStatus, MsApiScenarioConfig, MsDialogFooter
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
oneClickOperationVisible: false,
|
||||
apiScenarioModuleId: "",
|
||||
moduleOptions: [],
|
||||
ruleForm: {},
|
||||
loading: false,
|
||||
rule: {
|
||||
apiScenarioModuleId: [
|
||||
{required: true, message: this.$t('test_track.module.module'), trigger: 'blur'},
|
||||
],
|
||||
}
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.initModule();
|
||||
},
|
||||
props: {
|
||||
selectIds: {
|
||||
type: Set
|
||||
},
|
||||
selectProjectNames: {
|
||||
type: Set
|
||||
},
|
||||
selectProjectId: {
|
||||
type: Set
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
openOneClickOperation() {
|
||||
this.oneClickOperationVisible = true;
|
||||
},
|
||||
getPath(id) {
|
||||
let path = this.moduleOptions.filter(function (item) {
|
||||
return item.id === id ? item.path : "";
|
||||
});
|
||||
return path[0].path;
|
||||
},
|
||||
confirm() {
|
||||
this.loading = true;
|
||||
let arr = Array.from(this.selectIds);
|
||||
let obj = {testIds: arr, projectId: getCurrentProjectID(), modulePath: this.getPath(this.apiScenarioModuleId), moduleId: this.apiScenarioModuleId};
|
||||
this.$post("/api/historicalDataUpgrade", obj, response => {
|
||||
this.loading = false;
|
||||
this.$success(this.$t('organization.integration.successful_operation'));
|
||||
this.oneClickOperationVisible = false;
|
||||
})
|
||||
},
|
||||
initModule() {
|
||||
let url = "/api/automation/module/list/" + getCurrentProjectID();
|
||||
this.$get(url, response => {
|
||||
if (response.data != undefined && response.data != null) {
|
||||
this.data = response.data;
|
||||
let modules = [];
|
||||
this.data.forEach(node => {
|
||||
buildNodePath(node, {path: ''}, modules);
|
||||
});
|
||||
this.moduleOptions = modules;
|
||||
}
|
||||
});
|
||||
},
|
||||
handleClose() {
|
||||
this.ruleForm = {}
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
|
@ -13,6 +13,8 @@
|
|||
<ms-table-button :is-tester-permission="isTesterPermission" v-if="showRun" icon="el-icon-video-play"
|
||||
type="primary"
|
||||
:content="runTip" @click="runTest"/>
|
||||
<ms-table-button :is-tester-permission="isTesterPermission" v-if="showRun" icon="el-icon-circle-plus-outline"
|
||||
content="转场景测试" @click="historicalDataUpgrade"/>
|
||||
|
||||
<slot name="button"></slot>
|
||||
</span>
|
||||
|
@ -84,6 +86,9 @@
|
|||
},
|
||||
runTest() {
|
||||
this.$emit('runTest')
|
||||
},
|
||||
historicalDataUpgrade() {
|
||||
this.$emit('historicalDataUpgrade');
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
|
Loading…
Reference in New Issue