Merge remote-tracking branch 'origin/dev' into dev

This commit is contained in:
Captain.B 2020-05-21 18:13:28 +08:00
commit 601cc89395
11 changed files with 85 additions and 27 deletions

View File

@ -18,6 +18,7 @@ import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource; import javax.annotation.Resource;
import java.util.List; import java.util.List;
@RestController @RestController
@ -64,7 +65,7 @@ public class APITestController {
} }
@PostMapping(value = "/run") @PostMapping(value = "/run")
public void run(@RequestBody SaveAPITestRequest request) { public String run(@RequestBody SaveAPITestRequest request) {
apiTestService.run(request); return apiTestService.run(request);
} }
} }

View File

@ -61,7 +61,7 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl
queue.forEach((id, sampleResults) -> { queue.forEach((id, sampleResults) -> {
TestResult testResult = new TestResult(); TestResult testResult = new TestResult();
testResult.setId(id); testResult.setTestId(id);
testResult.setTotal(sampleResults.size()); testResult.setTotal(sampleResults.size());
// key: 场景Id // key: 场景Id
@ -104,7 +104,7 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl
testResult.getScenarios().addAll(scenarios.values()); testResult.getScenarios().addAll(scenarios.values());
testResult.getScenarios().sort(Comparator.comparing(ScenarioResult::getOrder)); testResult.getScenarios().sort(Comparator.comparing(ScenarioResult::getOrder));
apiTestService.changeStatus(id, APITestStatus.Completed); apiTestService.changeStatus(id, APITestStatus.Completed);
apiReportService.save(testResult); apiReportService.complete(testResult);
}); });
queue.clear(); queue.clear();
super.teardownTest(context); super.teardownTest(context);

View File

@ -8,7 +8,7 @@ import java.util.List;
@Data @Data
public class TestResult { public class TestResult {
private String id; private String testId;
private int success = 0; private int success = 0;

View File

@ -5,12 +5,15 @@ import io.metersphere.api.dto.APIReportResult;
import io.metersphere.api.dto.DeleteAPIReportRequest; import io.metersphere.api.dto.DeleteAPIReportRequest;
import io.metersphere.api.dto.QueryAPIReportRequest; import io.metersphere.api.dto.QueryAPIReportRequest;
import io.metersphere.api.jmeter.TestResult; import io.metersphere.api.jmeter.TestResult;
import io.metersphere.base.domain.ApiTest;
import io.metersphere.base.domain.ApiTestReport; import io.metersphere.base.domain.ApiTestReport;
import io.metersphere.base.domain.ApiTestWithBLOBs; import io.metersphere.base.domain.ApiTestReportExample;
import io.metersphere.base.mapper.ApiTestReportMapper; import io.metersphere.base.mapper.ApiTestReportMapper;
import io.metersphere.base.mapper.ext.ExtApiTestReportMapper; import io.metersphere.base.mapper.ext.ExtApiTestReportMapper;
import io.metersphere.commons.constants.APITestStatus; import io.metersphere.commons.constants.APITestStatus;
import io.metersphere.commons.exception.MSException;
import io.metersphere.dto.DashboardTestDTO; import io.metersphere.dto.DashboardTestDTO;
import io.metersphere.i18n.Translator;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@ -25,8 +28,6 @@ import javax.annotation.Resource;
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public class APIReportService { public class APIReportService {
@Resource
private APITestService apiTestService;
@Resource @Resource
private ApiTestReportMapper apiTestReportMapper; private ApiTestReportMapper apiTestReportMapper;
@Resource @Resource
@ -52,24 +53,58 @@ public class APIReportService {
apiTestReportMapper.deleteByPrimaryKey(request.getId()); apiTestReportMapper.deleteByPrimaryKey(request.getId());
} }
public void save(TestResult result) { public void deleteByTestId(String testId) {
ApiTestWithBLOBs test = apiTestService.get(result.getId()); ApiTestReportExample example = new ApiTestReportExample();
ApiTestReport report = new ApiTestReport(); example.createCriteria().andTestIdEqualTo(testId);
report.setId(UUID.randomUUID().toString()); apiTestReportMapper.deleteByExample(example);
report.setTestId(result.getId());
report.setName(test.getName());
report.setDescription(test.getDescription());
report.setContent(JSONObject.toJSONString(result));
report.setCreateTime(System.currentTimeMillis());
report.setUpdateTime(System.currentTimeMillis());
report.setStatus(APITestStatus.Completed.name());
apiTestReportMapper.insert(report);
} }
public void complete(TestResult result) {
ApiTestReport report = getRunningReport(result.getTestId());
if (report == null) {
MSException.throwException(Translator.get("api_report_is_null"));
}
report.setContent(JSONObject.toJSONString(result));
report.setUpdateTime(System.currentTimeMillis());
report.setStatus(APITestStatus.Completed.name());
apiTestReportMapper.updateByPrimaryKeySelective(report);
}
public String create(ApiTest test) {
ApiTestReport running = getRunningReport(test.getId());
if (running != null) {
return running.getId();
}
ApiTestReport report = new ApiTestReport();
report.setId(UUID.randomUUID().toString());
report.setTestId(test.getId());
report.setName(test.getName());
report.setDescription(test.getDescription());
report.setCreateTime(System.currentTimeMillis());
report.setUpdateTime(System.currentTimeMillis());
report.setStatus(APITestStatus.Running.name());
apiTestReportMapper.insert(report);
return report.getId();
}
public ApiTestReport getRunningReport(String testId) {
ApiTestReportExample example = new ApiTestReportExample();
example.createCriteria().andTestIdEqualTo(testId).andStatusEqualTo(APITestStatus.Running.name());
List<ApiTestReport> apiTestReports = apiTestReportMapper.selectByExample(example);
if (apiTestReports.size() > 0) {
return apiTestReports.get(0);
} else {
return null;
}
}
public List<DashboardTestDTO> dashboardTests(String workspaceId) { public List<DashboardTestDTO> dashboardTests(String workspaceId) {
Instant oneYearAgo = Instant.now().plus(-365, ChronoUnit.DAYS); Instant oneYearAgo = Instant.now().plus(-365, ChronoUnit.DAYS);
long startTimestamp = oneYearAgo.toEpochMilli(); long startTimestamp = oneYearAgo.toEpochMilli();
return extApiTestReportMapper.selectDashboardTests(workspaceId, startTimestamp); return extApiTestReportMapper.selectDashboardTests(workspaceId, startTimestamp);
} }
} }

View File

@ -39,6 +39,8 @@ public class APITestService {
private FileService fileService; private FileService fileService;
@Resource @Resource
private JMeterService jMeterService; private JMeterService jMeterService;
@Resource
private APIReportService apiReportService;
public List<APITestResult> list(QueryAPITestRequest request) { public List<APITestResult> list(QueryAPITestRequest request) {
return extApiTestMapper.list(request); return extApiTestMapper.list(request);
@ -71,18 +73,23 @@ public class APITestService {
public void delete(DeleteAPITestRequest request) { public void delete(DeleteAPITestRequest request) {
deleteFileByTestId(request.getId()); deleteFileByTestId(request.getId());
apiReportService.deleteByTestId(request.getId());
apiTestMapper.deleteByPrimaryKey(request.getId()); apiTestMapper.deleteByPrimaryKey(request.getId());
} }
public void run(SaveAPITestRequest request) { public String run(SaveAPITestRequest request) {
ApiTestFile file = getFileByTestId(request.getId()); ApiTestFile file = getFileByTestId(request.getId());
if (file == null) { if (file == null) {
MSException.throwException(Translator.get("file_cannot_be_null")); MSException.throwException(Translator.get("file_cannot_be_null"));
} }
byte[] bytes = fileService.loadFileAsBytes(file.getFileId()); byte[] bytes = fileService.loadFileAsBytes(file.getFileId());
InputStream is = new ByteArrayInputStream(bytes); InputStream is = new ByteArrayInputStream(bytes);
String reportId = apiReportService.create(get(request.getId()));
changeStatus(request.getId(), APITestStatus.Running); changeStatus(request.getId(), APITestStatus.Running);
jMeterService.run(is); jMeterService.run(is);
return reportId;
} }
public void changeStatus(String id, APITestStatus status) { public void changeStatus(String id, APITestStatus status) {

View File

@ -37,6 +37,7 @@ organization_does_not_belong_to_user=The current organization does not belong to
organization_id_is_null=Organization ID cannot be null organization_id_is_null=Organization ID cannot be null
#api #api
api_load_script_error=Load script error api_load_script_error=Load script error
api_report_is_null="Report is null, can't update"
#test case #test case
test_case_node_level=level test_case_node_level=level
test_case_node_level_tip=The node tree maximum depth is test_case_node_level_tip=The node tree maximum depth is

View File

@ -37,6 +37,7 @@ organization_does_not_belong_to_user=当前组织不属于当前用户
organization_id_is_null=组织 ID 不能为空 organization_id_is_null=组织 ID 不能为空
#api #api
api_load_script_error=读取脚本失败 api_load_script_error=读取脚本失败
api_report_is_null="测试报告是未生成,无法更新"
#test case #test case
test_case_node_level= test_case_node_level=
test_case_node_level_tip=模块树最大深度为 test_case_node_level_tip=模块树最大深度为

View File

@ -37,6 +37,7 @@ organization_does_not_belong_to_user=當前組織不屬於當前用戶
organization_id_is_null=組織 ID 不能為空 organization_id_is_null=組織 ID 不能為空
#api #api
api_load_script_error=讀取腳本失敗 api_load_script_error=讀取腳本失敗
api_report_is_null="測試報告是未生成,無法更新"
#test case #test case
test_case_node_level= test_case_node_level=
test_case_node_level_tip=模塊樹最大深度為 test_case_node_level_tip=模塊樹最大深度為

View File

@ -5,9 +5,9 @@
<section class="report-container" v-if="this.report.testId"> <section class="report-container" v-if="this.report.testId">
<header class="report-header"> <header class="report-header">
<span>{{report.projectName}} / </span> <span>{{report.projectName}} / </span>
<router-link :to="path">{{report.testName}}</router-link> <router-link :to="path">{{report.testName}} [{{report.createTime | timestampFormatDate}}]</router-link>
</header> </header>
<main> <main v-if="this.isCompleted">
<div class="scenario-chart"> <div class="scenario-chart">
<ms-metric-chart :content="content"></ms-metric-chart> <ms-metric-chart :content="content"></ms-metric-chart>
</div> </div>
@ -59,11 +59,17 @@
methods: { methods: {
getReport() { getReport() {
this.report = {};
this.content = {};
if (this.reportId) { if (this.reportId) {
let url = "/api/report/get/" + this.reportId; let url = "/api/report/get/" + this.reportId;
this.result = this.$get(url, response => { this.result = this.$get(url, response => {
this.report = response.data || {}; this.report = response.data || {};
this.content = JSON.parse(this.report.content); if (this.isCompleted) {
this.content = JSON.parse(this.report.content);
} else {
setTimeout(this.getReport, 2000)
}
}); });
} }
} }
@ -83,6 +89,9 @@
}, },
path() { path() {
return "/api/test/edit?id=" + this.report.testId; return "/api/test/edit?id=" + this.report.testId;
},
isCompleted() {
return "Completed" === this.report.status;
} }
} }
} }

View File

@ -96,8 +96,8 @@
show: false show: false
}, },
data: [ data: [
{value: this.content.success, name: this.$t('api_report.success')}, {value: this.content.success},
{value: this.content.error, name: this.$t('api_report.fail')}, {value: this.content.error},
] ]
} }
] ]

View File

@ -120,8 +120,11 @@
}) })
}, },
runTest: function () { runTest: function () {
this.result = this.$post("/api/run", {id: this.test.id}, () => { this.result = this.$post("/api/run", {id: this.test.id}, (response) => {
this.$success(this.$t('api_test.running')); this.$success(this.$t('api_test.running'));
this.$router.push({
path: '/api/report/view/' + response.data
})
}); });
}, },
saveRunTest: function () { saveRunTest: function () {