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 10e3fbecac
commit 6f063e268f
8 changed files with 222 additions and 63 deletions

View File

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

View File

@ -332,14 +332,16 @@ public class APIBackendListenerClient extends AbstractBackendListenerClient impl
executionTime = sdf.format(new Date(Long.parseLong(time_)));
}
//执行人
String userName = apiAutomationService.getUser(apiScenario.getUserId()).getName();
if(apiScenario != null){
String userName = apiAutomationService.getUser(apiScenario.getUserId()).getName();
reportTask.setExecutor(userName);
}
//报告内容
reportTask = new ApiTestReportVariable();
reportTask.setStatus(scenarioReport.getStatus());
reportTask.setId(scenarioReport.getId());
reportTask.setTriggerMode(scenarioReport.getTriggerMode());
reportTask.setName(scenarioReport.getName());
reportTask.setExecutor(userName);
reportTask.setExecutionTime(executionTime);
reportTask.setExecutionEnvironment(name);
SystemParameterService systemParameterService = CommonBeanFactory.getBean(SystemParameterService.class);

View File

@ -1752,20 +1752,9 @@ public class ApiAutomationService {
String jmx = generateJmx(item);
if (StringUtils.isNotEmpty(jmx)) {
ApiScenrioExportJmx scenrioExportJmx = new ApiScenrioExportJmx(item.getName(), apiTestService.updateJmxString(jmx, null, true).getXml());
//扫描需要哪些文件
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.setFileMetadataList(dto.getFileMetadataList());
resList.add(scenrioExportJmx);
}

View File

@ -1,7 +1,9 @@
package io.metersphere.api.service;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONValidator;
import io.metersphere.api.dto.mockconfig.MockConfigRequest;
import io.metersphere.api.dto.mockconfig.MockExpectConfigRequest;
import io.metersphere.api.dto.mockconfig.response.JsonSchemaReturnObj;
@ -178,10 +180,12 @@ public class MockConfigService {
}
JSONObject requestObj = model.getRequest();
boolean isJsonParam = requestObj.getBoolean("jsonParam");
JSONObject mockExpectJson = new JSONObject();
if (isJsonParam) {
mockExpectJson = JSONObject.parseObject(requestObj.getString("jsonData"));
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);
@ -197,11 +201,10 @@ public class MockConfigService {
mockExpectJson.put(name, value);
}
}
if (mockExpectJson.isEmpty()) {
return model;
}
}
if (mockExpectJson.isEmpty()) {
return model;
}
}
}
for (MockExpectConfigResponse model : mockExpectConfigList) {
@ -213,7 +216,18 @@ public class MockConfigService {
boolean isJsonParam = requestObj.getBoolean("jsonParam");
JSONObject mockExpectJson = new JSONObject();
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 {
JSONArray jsonArray = requestObj.getJSONArray("variables");
for (int i = 0; i < jsonArray.size(); i++) {
@ -244,6 +258,99 @@ public class MockConfigService {
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) {
String returnStr = "";
try {
@ -415,31 +522,23 @@ public class MockConfigService {
for (String key : keySet) {
try {
JsonSchemaReturnObj obj = bodyReturnObj.getObject(key, JsonSchemaReturnObj.class);
if(StringUtils.equals("object",obj.getType())) {
if (StringUtils.equals("object", obj.getType())) {
JSONObject itemObj = this.parseJsonSchema(obj.getProperties());
if (!itemObj.isEmpty()) {
returnObj.put(key, itemObj);
}
}else if(StringUtils.equals("array",obj.getType())){
if(obj.getItems() != null){
} else if (StringUtils.equals("array", obj.getType())) {
if (obj.getItems() != null) {
JSONObject itemObj = obj.getItems();
if(itemObj.containsKey("type")){
if(StringUtils.equals("object",itemObj.getString("type"))&& itemObj.containsKey("properties")){
if (itemObj.containsKey("type")) {
if (StringUtils.equals("object", itemObj.getString("type")) && itemObj.containsKey("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);
JSONArray array = new JSONArray();
array.add(parseObj);
returnObj.put(key, array);
}else if(StringUtils.equals("string",itemObj.getString("type"))&& itemObj.containsKey("mock")){
JsonSchemaReturnObj arrayObj = JSONObject.toJavaObject(itemObj,JsonSchemaReturnObj.class);
} else if (StringUtils.equals("string", itemObj.getString("type")) && itemObj.containsKey("mock")) {
JsonSchemaReturnObj arrayObj = JSONObject.toJavaObject(itemObj, JsonSchemaReturnObj.class);
String value = this.getMockValues(arrayObj.getMockValue());
JSONArray array = new JSONArray();
array.add(value);
@ -489,7 +588,6 @@ public class MockConfigService {
public JSONObject getGetParamMap(String urlParams, ApiDefinitionWithBLOBs api, HttpServletRequest request) {
JSONObject paramMap = this.getSendRestParamMapByIdAndUrl(api, urlParams);
Enumeration<String> paramNameItor = request.getParameterNames();
JSONObject object = new JSONObject();
while (paramNameItor.hasMoreElements()) {
String key = paramNameItor.nextElement();
String value = request.getParameter(key);
@ -498,16 +596,21 @@ public class MockConfigService {
return paramMap;
}
public JSONObject getPostParamMap(HttpServletRequest request) {
public JSON getPostParamMap(HttpServletRequest request) {
if (StringUtils.equalsIgnoreCase("application/JSON", request.getContentType())) {
JSONObject object = null;
JSON returnJson = null;
try {
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) {
e.printStackTrace();
}
return object;
return returnJson;
} else if (StringUtils.equalsIgnoreCase("text/xml", request.getContentType())) {
String xmlString = this.readXml(request);
System.out.println(xmlString);
@ -772,19 +875,28 @@ public class MockConfigService {
String returnStr = "";
boolean isMatch = false;
List<ApiDefinitionWithBLOBs> aualifiedApiList = new ArrayList<>();
if(project!=null){
if (project != null) {
String urlSuffix = this.getUrlSuffix(project.getSystemId(), request);
aualifiedApiList = apiDefinitionService.preparedUrl(project.getId(), method, urlSuffix, urlSuffix);
JSONObject paramMap = this.getPostParamMap(request);
List<String> apiIdList = aualifiedApiList.stream().map(ApiDefinitionWithBLOBs::getId).collect(Collectors.toList());
MockConfigResponse mockConfigData = this.findByApiIdList(apiIdList);
if (mockConfigData != null && mockConfigData.getMockExpectConfigList() != null) {
MockExpectConfigResponse finalExpectConfig = this.findExpectConfig(mockConfigData.getMockExpectConfigList(), paramMap);
if (finalExpectConfig != null) {
isMatch = true;
returnStr = this.updateHttpServletResponse(finalExpectConfig, response);
JSON paramJson = this.getPostParamMap(request);
if(paramJson instanceof JSONObject){
JSONObject paramMap = (JSONObject)paramJson;
MockExpectConfigResponse finalExpectConfig = this.findExpectConfig(mockConfigData.getMockExpectConfigList(), paramMap);
if (finalExpectConfig != null) {
isMatch = true;
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) {
if (matchObjItem instanceof JSONObject) {
if (sourceObjItem instanceof JSONObject) {

View File

@ -683,7 +683,7 @@ public class PerformanceTestService {
deleteLoadTestFiles(testId);
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);
}
private void saveOtherFile(List<String> fileNames, String loadTestId) {
List<String> files = fileNames;
for (int i = 0; i < files.size(); i++) {
String fileName = files.get(i);
private void saveOtherFile(List<FileMetadata> fileNames, String loadTestId) {
for (int i = 0; i < fileNames.size(); i++) {
FileMetadata model = fileNames.get(i);
String fileName = model.getName();
File file = FileUtils.getFileByName(fileName);
saveUploadFile(file, loadTestId, i + 1);
}

View File

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

View File

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