Merge remote-tracking branch 'origin/dev' into dev
This commit is contained in:
commit
601cc89395
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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=模块树最大深度为
|
||||||
|
|
|
@ -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=模塊樹最大深度為
|
||||||
|
|
|
@ -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 || {};
|
||||||
|
if (this.isCompleted) {
|
||||||
this.content = JSON.parse(this.report.content);
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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},
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -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 () {
|
||||||
|
|
Loading…
Reference in New Issue