fix(接口测试、测试计划): 修复请求参数为JSON数组或Mock期望为JSON数组时产生的前端控制台报错问题,修复测试计划定时任务不发送报告的问题

修复请求参数为JSON数组或Mock期望为JSON数组时产生的前端控制台报错问题,修复测试计划定时任务不发送报告的问题
This commit is contained in:
song-tianyang 2021-06-28 16:12:28 +08:00 committed by 刘瑞斌
parent 66b4a6fb19
commit 4840d9b5ab
7 changed files with 218 additions and 61 deletions

View File

@ -12,7 +12,6 @@ public class ApiScenrioExportJmx {
private String name; private String name;
private String jmx; private String jmx;
private Integer version; private Integer version;
List<String> files;
//性能测试引用场景时需要场景下的附件 //性能测试引用场景时需要场景下的附件
private List<FileMetadata> fileMetadataList; private List<FileMetadata> fileMetadataList;

View File

@ -1762,20 +1762,9 @@ public class ApiAutomationService {
String jmx = generateJmx(item); String jmx = generateJmx(item);
if (StringUtils.isNotEmpty(jmx)) { if (StringUtils.isNotEmpty(jmx)) {
ApiScenrioExportJmx scenrioExportJmx = new ApiScenrioExportJmx(item.getName(), apiTestService.updateJmxString(jmx, null, true).getXml()); ApiScenrioExportJmx scenrioExportJmx = new ApiScenrioExportJmx(item.getName(), apiTestService.updateJmxString(jmx, null, true).getXml());
//扫描需要哪些文件
JmxInfoDTO dto = apiTestService.updateJmxString(jmx, item.getName(), true); JmxInfoDTO dto = apiTestService.updateJmxString(jmx, item.getName(), true);
if (MapUtils.isNotEmpty(dto.getAttachFiles())) {
List<String> fileList = new ArrayList<>();
for (String fileName : dto.getAttachFiles().values()) {
if (!fileList.contains(fileName)) {
fileList.add(fileName);
}
}
if (!fileList.isEmpty()) {
scenrioExportJmx.setFiles(fileList);
}
}
scenrioExportJmx.setVersion(item.getVersion()); scenrioExportJmx.setVersion(item.getVersion());
//扫描需要哪些文件
scenrioExportJmx.setFileMetadataList(dto.getFileMetadataList()); scenrioExportJmx.setFileMetadataList(dto.getFileMetadataList());
resList.add(scenrioExportJmx); resList.add(scenrioExportJmx);
} }

View File

@ -1,7 +1,9 @@
package io.metersphere.api.service; package io.metersphere.api.service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONValidator;
import io.metersphere.api.dto.mockconfig.MockConfigRequest; import io.metersphere.api.dto.mockconfig.MockConfigRequest;
import io.metersphere.api.dto.mockconfig.MockExpectConfigRequest; import io.metersphere.api.dto.mockconfig.MockExpectConfigRequest;
import io.metersphere.api.dto.mockconfig.response.JsonSchemaReturnObj; import io.metersphere.api.dto.mockconfig.response.JsonSchemaReturnObj;
@ -178,10 +180,12 @@ public class MockConfigService {
} }
JSONObject requestObj = model.getRequest(); JSONObject requestObj = model.getRequest();
boolean isJsonParam = requestObj.getBoolean("jsonParam"); boolean isJsonParam = requestObj.getBoolean("jsonParam");
JSONObject mockExpectJson = new JSONObject();
if (isJsonParam) { if (isJsonParam) {
mockExpectJson = JSONObject.parseObject(requestObj.getString("jsonData")); if(StringUtils.isEmpty(requestObj.getString("jsonData"))){
return model;
}
} else { } else {
JSONObject mockExpectJson = new JSONObject();
JSONArray jsonArray = requestObj.getJSONArray("variables"); JSONArray jsonArray = requestObj.getJSONArray("variables");
for (int i = 0; i < jsonArray.size(); i++) { for (int i = 0; i < jsonArray.size(); i++) {
JSONObject object = jsonArray.getJSONObject(i); JSONObject object = jsonArray.getJSONObject(i);
@ -197,11 +201,10 @@ public class MockConfigService {
mockExpectJson.put(name, value); mockExpectJson.put(name, value);
} }
} }
}
if (mockExpectJson.isEmpty()) { if (mockExpectJson.isEmpty()) {
return model; return model;
} }
}
} }
} }
for (MockExpectConfigResponse model : mockExpectConfigList) { for (MockExpectConfigResponse model : mockExpectConfigList) {
@ -213,7 +216,18 @@ public class MockConfigService {
boolean isJsonParam = requestObj.getBoolean("jsonParam"); boolean isJsonParam = requestObj.getBoolean("jsonParam");
JSONObject mockExpectJson = new JSONObject(); JSONObject mockExpectJson = new JSONObject();
if (isJsonParam) { if (isJsonParam) {
mockExpectJson = JSONObject.parseObject(requestObj.getString("jsonData")); String jsonParams = requestObj.getString("jsonData");
JSONValidator jsonValidator = JSONValidator.from(jsonParams);
if(StringUtils.equalsIgnoreCase("Array",jsonValidator.getType().name())){
JSONArray mockExpectArr = JSONArray.parseArray(jsonParams);
for(int expectIndex = 0;expectIndex < mockExpectArr.size(); expectIndex ++){
JSONObject itemObj = mockExpectArr.getJSONObject(expectIndex);
mockExpectJson = itemObj;
}
}else if(StringUtils.equalsIgnoreCase("Object",jsonValidator.getType().name())){
JSONObject mockExpectJsonItem = JSONObject.parseObject(jsonParams);
mockExpectJson = mockExpectJsonItem;
}
} else { } else {
JSONArray jsonArray = requestObj.getJSONArray("variables"); JSONArray jsonArray = requestObj.getJSONArray("variables");
for (int i = 0; i < jsonArray.size(); i++) { for (int i = 0; i < jsonArray.size(); i++) {
@ -244,6 +258,99 @@ public class MockConfigService {
return returnModel; return returnModel;
} }
public MockExpectConfigResponse findExpectConfig(List<MockExpectConfigResponse> mockExpectConfigList, JSONArray reqJsonArray) {
MockExpectConfigResponse returnModel = null;
if (reqJsonArray == null || reqJsonArray.isEmpty()) {
for (MockExpectConfigResponse model : mockExpectConfigList) {
if (!model.isStatus()) {
continue;
}
JSONObject requestObj = model.getRequest();
boolean isJsonParam = requestObj.getBoolean("jsonParam");
if (isJsonParam) {
if(StringUtils.isEmpty(requestObj.getString("jsonData"))){
return model;
}
} else {
JSONObject mockExpectJson = new JSONObject();
JSONArray jsonArray = requestObj.getJSONArray("variables");
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject object = jsonArray.getJSONObject(i);
String name = "";
String value = "";
if (object.containsKey("name")) {
name = String.valueOf(object.get("name")).trim();
}
if (object.containsKey("value")) {
value = String.valueOf(object.get("value")).trim();
}
if (StringUtils.isNotEmpty(name)) {
mockExpectJson.put(name, value);
}
}
if (mockExpectJson.isEmpty()) {
return model;
}
}
}
}
for (MockExpectConfigResponse model : mockExpectConfigList) {
try {
if (!model.isStatus()) {
continue;
}
JSONObject requestObj = model.getRequest();
boolean isJsonParam = requestObj.getBoolean("jsonParam");
boolean mathing = false;
if (isJsonParam) {
String jsonParams = requestObj.getString("jsonData");
JSONValidator jsonValidator = JSONValidator.from(jsonParams);
if(StringUtils.equalsIgnoreCase("Array",jsonValidator.getType().name())){
JSONArray mockExpectArr = JSONArray.parseArray(jsonParams);
for(int expectIndex = 0;expectIndex < mockExpectArr.size(); expectIndex ++){
JSONObject itemObj = mockExpectArr.getJSONObject(expectIndex);
mathing = JsonPathUtils.checkJsonArrayCompliance(reqJsonArray, itemObj);
if(!mathing){
break;
}
}
}else if(StringUtils.equalsIgnoreCase("Object",jsonValidator.getType().name())){
JSONObject mockExpectJson = JSONObject.parseObject(jsonParams);
mathing = JsonPathUtils.checkJsonArrayCompliance(reqJsonArray, mockExpectJson);
}
} else {
JSONArray jsonArray = requestObj.getJSONArray("variables");
JSONObject mockExpectJson = new JSONObject();
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject object = jsonArray.getJSONObject(i);
String name = "";
String value = "";
if (object.containsKey("name")) {
name = String.valueOf(object.get("name")).trim();
}
if (object.containsKey("value")) {
value = String.valueOf(object.get("value")).trim();
}
if (StringUtils.isNotEmpty(name)) {
mockExpectJson.put(name, value);
}
}
mathing = JsonPathUtils.checkJsonArrayCompliance(reqJsonArray, mockExpectJson);
}
if (mathing) {
returnModel = model;
break;
}
} catch (Exception e) {
e.printStackTrace();
}
}
return returnModel;
}
public String updateHttpServletResponse(MockExpectConfigResponse finalExpectConfig, HttpServletResponse response) { public String updateHttpServletResponse(MockExpectConfigResponse finalExpectConfig, HttpServletResponse response) {
String returnStr = ""; String returnStr = "";
try { try {
@ -426,14 +533,6 @@ public class MockConfigService {
if (itemObj.containsKey("type")) { if (itemObj.containsKey("type")) {
if (StringUtils.equals("object", itemObj.getString("type")) && itemObj.containsKey("properties")) { if (StringUtils.equals("object", itemObj.getString("type")) && itemObj.containsKey("properties")) {
JSONObject arrayObj = itemObj.getJSONObject("properties"); JSONObject arrayObj = itemObj.getJSONObject("properties");
// Set<String> arrayKeys = arrayObj.keySet();
//
// JSONObject parseObj = new JSONObject();
// for (String arrayKey : arrayKeys) {
// JsonSchemaReturnObj arrayItemObj = arrayObj.getObject(arrayKey, JsonSchemaReturnObj.class);
// String value = this.getMockValues(arrayItemObj.getMockValue());
// parseObj.put(arrayKey,value);
// }
JSONObject parseObj = this.parseJsonSchema(arrayObj); JSONObject parseObj = this.parseJsonSchema(arrayObj);
JSONArray array = new JSONArray(); JSONArray array = new JSONArray();
array.add(parseObj); array.add(parseObj);
@ -489,7 +588,6 @@ public class MockConfigService {
public JSONObject getGetParamMap(String urlParams, ApiDefinitionWithBLOBs api, HttpServletRequest request) { public JSONObject getGetParamMap(String urlParams, ApiDefinitionWithBLOBs api, HttpServletRequest request) {
JSONObject paramMap = this.getSendRestParamMapByIdAndUrl(api, urlParams); JSONObject paramMap = this.getSendRestParamMapByIdAndUrl(api, urlParams);
Enumeration<String> paramNameItor = request.getParameterNames(); Enumeration<String> paramNameItor = request.getParameterNames();
JSONObject object = new JSONObject();
while (paramNameItor.hasMoreElements()) { while (paramNameItor.hasMoreElements()) {
String key = paramNameItor.nextElement(); String key = paramNameItor.nextElement();
String value = request.getParameter(key); String value = request.getParameter(key);
@ -498,16 +596,21 @@ public class MockConfigService {
return paramMap; return paramMap;
} }
public JSONObject getPostParamMap(HttpServletRequest request) { public JSON getPostParamMap(HttpServletRequest request) {
if (StringUtils.equalsIgnoreCase("application/JSON", request.getContentType())) { if (StringUtils.equalsIgnoreCase("application/JSON", request.getContentType())) {
JSONObject object = null; JSON returnJson = null;
try { try {
String param = this.getRequestPostStr(request); String param = this.getRequestPostStr(request);
object = JSONObject.parseObject(param); JSONValidator jsonValidator = JSONValidator.from(param);
if(StringUtils.equalsIgnoreCase("Array",jsonValidator.getType().name())){
returnJson = JSONArray.parseArray(param);
}else if(StringUtils.equalsIgnoreCase("Object",jsonValidator.getType().name())){
returnJson = JSONObject.parseObject(param);
}
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
return object; return returnJson;
} else if (StringUtils.equalsIgnoreCase("text/xml", request.getContentType())) { } else if (StringUtils.equalsIgnoreCase("text/xml", request.getContentType())) {
String xmlString = this.readXml(request); String xmlString = this.readXml(request);
System.out.println(xmlString); System.out.println(xmlString);
@ -775,17 +878,26 @@ public class MockConfigService {
if (project != null) { if (project != null) {
String urlSuffix = this.getUrlSuffix(project.getSystemId(), request); String urlSuffix = this.getUrlSuffix(project.getSystemId(), request);
aualifiedApiList = apiDefinitionService.preparedUrl(project.getId(), method, urlSuffix, urlSuffix); aualifiedApiList = apiDefinitionService.preparedUrl(project.getId(), method, urlSuffix, urlSuffix);
JSONObject paramMap = this.getPostParamMap(request);
List<String> apiIdList = aualifiedApiList.stream().map(ApiDefinitionWithBLOBs::getId).collect(Collectors.toList()); List<String> apiIdList = aualifiedApiList.stream().map(ApiDefinitionWithBLOBs::getId).collect(Collectors.toList());
MockConfigResponse mockConfigData = this.findByApiIdList(apiIdList); MockConfigResponse mockConfigData = this.findByApiIdList(apiIdList);
if (mockConfigData != null && mockConfigData.getMockExpectConfigList() != null) { if (mockConfigData != null && mockConfigData.getMockExpectConfigList() != null) {
JSON paramJson = this.getPostParamMap(request);
if(paramJson instanceof JSONObject){
JSONObject paramMap = (JSONObject)paramJson;
MockExpectConfigResponse finalExpectConfig = this.findExpectConfig(mockConfigData.getMockExpectConfigList(), paramMap); MockExpectConfigResponse finalExpectConfig = this.findExpectConfig(mockConfigData.getMockExpectConfigList(), paramMap);
if (finalExpectConfig != null) { if (finalExpectConfig != null) {
isMatch = true; isMatch = true;
returnStr = this.updateHttpServletResponse(finalExpectConfig, response); returnStr = this.updateHttpServletResponse(finalExpectConfig, response);
} }
}else if(paramJson instanceof JSONArray){
JSONArray paramArray = (JSONArray)paramJson;
MockExpectConfigResponse finalExpectConfig = this.findExpectConfig(mockConfigData.getMockExpectConfigList(), paramArray);
if (finalExpectConfig != null) {
isMatch = true;
returnStr = this.updateHttpServletResponse(finalExpectConfig, response);
}
}
} }
} }

View File

@ -164,6 +164,49 @@ public class JsonPathUtils {
} }
} }
/**
* 检查一个JSON对象的数据集合是否包含另一个对象包含
* @param sourceArray
* @param matchObj
* @return
*/
public static boolean checkJsonArrayCompliance(JSONArray sourceArray, JSONObject matchObj) {
if (sourceArray == null && matchObj == null) {
return true;
} else if (sourceArray != null && matchObj != null) {
boolean isMatch = false;
try {
Set<String> matchKeys = matchObj.keySet();
for(int sourceIndex = 0;sourceIndex < sourceArray.size();sourceIndex ++){
JSONObject sourceObj = sourceArray.getJSONObject(sourceIndex);
for (String key : matchKeys) {
if (sourceObj.containsKey(key)) {
Object sourceObjItem = sourceObj.get(key);
Object matchObjItem = matchObj.get(key);
isMatch = checkObjCompliance(sourceObjItem, matchObjItem);
if(!isMatch){
break;
}
} else {
isMatch = false;
break;
}
}
if(isMatch){
break;
}
}
} catch (Exception e) {
e.printStackTrace();
}
return isMatch;
} else {
return false;
}
}
private static boolean checkObjCompliance(Object sourceObjItem, Object matchObjItem) { private static boolean checkObjCompliance(Object sourceObjItem, Object matchObjItem) {
if (matchObjItem instanceof JSONObject) { if (matchObjItem instanceof JSONObject) {
if (sourceObjItem instanceof JSONObject) { if (sourceObjItem instanceof JSONObject) {

View File

@ -683,7 +683,7 @@ public class PerformanceTestService {
deleteLoadTestFiles(testId); deleteLoadTestFiles(testId);
saveJmxFile(apiScenrioExportJmx, loadTest.getProjectId(), loadTest.getId()); saveJmxFile(apiScenrioExportJmx, loadTest.getProjectId(), loadTest.getId());
saveOtherFile(apiScenrioExportJmx.getFiles(), loadTest.getId()); saveOtherFile(apiScenrioExportJmx.getFileMetadataList(), loadTest.getId());
} }
@ -696,10 +696,10 @@ public class PerformanceTestService {
saveLoadTestFile(fileMetadata, loadTestId, 0); saveLoadTestFile(fileMetadata, loadTestId, 0);
} }
private void saveOtherFile(List<String> fileNames, String loadTestId) { private void saveOtherFile(List<FileMetadata> fileNames, String loadTestId) {
List<String> files = fileNames; for (int i = 0; i < fileNames.size(); i++) {
for (int i = 0; i < files.size(); i++) { FileMetadata model = fileNames.get(i);
String fileName = files.get(i); String fileName = model.getName();
File file = FileUtils.getFileByName(fileName); File file = FileUtils.getFileByName(fileName);
saveUploadFile(file, loadTestId, i + 1); saveUploadFile(file, loadTestId, i + 1);
} }

View File

@ -215,7 +215,7 @@ public class ScheduleService {
public void createSchedule(ScheduleRequest request) { public void createSchedule(ScheduleRequest request) {
Schedule schedule = this.buildApiTestSchedule(request); Schedule schedule = this.buildApiTestSchedule(request);
schedule.setJob(ApiScenarioTestJob.class.getName());
JobKey jobKey = null; JobKey jobKey = null;
TriggerKey triggerKey = null; TriggerKey triggerKey = null;
@ -229,7 +229,8 @@ public class ScheduleService {
jobKey = TestPlanTestJob.getJobKey(request.getResourceId()); jobKey = TestPlanTestJob.getJobKey(request.getResourceId());
triggerKey = TestPlanTestJob.getTriggerKey(request.getResourceId()); triggerKey = TestPlanTestJob.getTriggerKey(request.getResourceId());
clazz = TestPlanTestJob.class; clazz = TestPlanTestJob.class;
}else { // 实际上在场景中添加定时任务并不会执行到这里? schedule.setJob(TestPlanTestJob.class.getName());
}else {
//默认为情景 //默认为情景
ApiScenarioWithBLOBs apiScene = apiScenarioMapper.selectByPrimaryKey(request.getResourceId()); ApiScenarioWithBLOBs apiScene = apiScenarioMapper.selectByPrimaryKey(request.getResourceId());
schedule.setName(apiScene.getName()); schedule.setName(apiScene.getName());
@ -239,6 +240,7 @@ public class ScheduleService {
jobKey = ApiScenarioTestJob.getJobKey(request.getResourceId()); jobKey = ApiScenarioTestJob.getJobKey(request.getResourceId());
triggerKey = ApiScenarioTestJob.getTriggerKey(request.getResourceId()); triggerKey = ApiScenarioTestJob.getTriggerKey(request.getResourceId());
clazz = ApiScenarioTestJob.class; clazz = ApiScenarioTestJob.class;
schedule.setJob(ApiScenarioTestJob.class.getName());
} }
this.addSchedule(schedule); this.addSchedule(schedule);
@ -246,7 +248,7 @@ public class ScheduleService {
} }
public void updateSchedule(Schedule request) { public void updateSchedule(Schedule request) {
this.editSchedule(request);
JobKey jobKey = null; JobKey jobKey = null;
TriggerKey triggerKey = null; TriggerKey triggerKey = null;
@ -255,12 +257,15 @@ public class ScheduleService {
jobKey = TestPlanTestJob.getJobKey(request.getResourceId()); jobKey = TestPlanTestJob.getJobKey(request.getResourceId());
triggerKey = TestPlanTestJob.getTriggerKey(request.getResourceId()); triggerKey = TestPlanTestJob.getTriggerKey(request.getResourceId());
clazz = TestPlanTestJob.class; clazz = TestPlanTestJob.class;
request.setJob(TestPlanTestJob.class.getName());
}else { }else {
//默认为情景 //默认为情景
jobKey = ApiScenarioTestJob.getJobKey(request.getResourceId()); jobKey = ApiScenarioTestJob.getJobKey(request.getResourceId());
triggerKey = ApiScenarioTestJob.getTriggerKey(request.getResourceId()); triggerKey = ApiScenarioTestJob.getTriggerKey(request.getResourceId());
clazz = ApiScenarioTestJob.class; clazz = ApiScenarioTestJob.class;
request.setJob(ApiScenarioTestJob.class.getName());
} }
this.editSchedule(request);
this.addOrUpdateCronJob(request,jobKey ,triggerKey , clazz); this.addOrUpdateCronJob(request,jobKey ,triggerKey , clazz);
} }

View File

@ -350,17 +350,26 @@ public class TestPlanReportService {
try { try {
JSONObject failurCaseObject = JSONObject.parseObject(failCaseString); JSONObject failurCaseObject = JSONObject.parseObject(failCaseString);
if (failurCaseObject.containsKey("apiTestCases") && failurCaseObject.getJSONArray("apiTestCases").size() >= 0) { if (failurCaseObject.containsKey("apiTestCases") && failurCaseObject.getJSONArray("apiTestCases").size() >= 0) {
JSONArray array = failurCaseObject.getJSONArray("apiTestCases");
if(array.size() > 0){
status = TestPlanReportStatus.FAILED.name(); status = TestPlanReportStatus.FAILED.name();
return status; return status;
} }
}
if (failurCaseObject.containsKey("loadTestCases") && failurCaseObject.getJSONArray("loadTestCases").size() >= 0) { if (failurCaseObject.containsKey("loadTestCases") && failurCaseObject.getJSONArray("loadTestCases").size() >= 0) {
JSONArray array = failurCaseObject.getJSONArray("loadTestCases");
if(array.size() > 0){
status = TestPlanReportStatus.FAILED.name(); status = TestPlanReportStatus.FAILED.name();
return status; return status;
} }
}
if (failurCaseObject.containsKey("scenarioTestCases") && failurCaseObject.getJSONArray("scenarioTestCases").size() >= 0) { if (failurCaseObject.containsKey("scenarioTestCases") && failurCaseObject.getJSONArray("scenarioTestCases").size() >= 0) {
JSONArray array = failurCaseObject.getJSONArray("scenarioTestCases");
if(array.size() > 0){
status = TestPlanReportStatus.FAILED.name(); status = TestPlanReportStatus.FAILED.name();
return status; return status;
} }
}
} catch (Exception e) { } catch (Exception e) {
status = TestPlanReportStatus.FAILED.name(); status = TestPlanReportStatus.FAILED.name();
} }