mirror of
https://gitee.com/fit2cloud-feizhiyun/MeterSphere.git
synced 2024-12-04 04:59:48 +08:00
feat(项目设置): 公共脚本执行接口
This commit is contained in:
parent
46d1d3f43f
commit
e3e4af2988
@ -200,6 +200,11 @@ INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT
|
|||||||
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_TEST_PLAN:READ+UPDATE');
|
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_TEST_PLAN:READ+UPDATE');
|
||||||
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_TEST_PLAN:READ+DELETE');
|
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_TEST_PLAN:READ+DELETE');
|
||||||
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_TEST_PLAN:READ+EXECUTE');
|
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_TEST_PLAN:READ+EXECUTE');
|
||||||
|
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_CUSTOM_FUNCTION:READ');
|
||||||
|
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_CUSTOM_FUNCTION:READ+ADD');
|
||||||
|
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_CUSTOM_FUNCTION:READ+UPDATE');
|
||||||
|
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_CUSTOM_FUNCTION:READ+DELETE');
|
||||||
|
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_admin', 'PROJECT_CUSTOM_FUNCTION:READ+EXECUTE');
|
||||||
|
|
||||||
-- 项目成员权限
|
-- 项目成员权限
|
||||||
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'PROJECT_BASE_INFO:READ');
|
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'PROJECT_BASE_INFO:READ');
|
||||||
@ -255,6 +260,8 @@ INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT
|
|||||||
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'PROJECT_BUG:READ+DELETE');
|
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'PROJECT_BUG:READ+DELETE');
|
||||||
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'PROJECT_BUG:READ+EXPORT');
|
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'PROJECT_BUG:READ+EXPORT');
|
||||||
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'PROJECT_BASE_INFO:READ+UPDATE');
|
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'PROJECT_BASE_INFO:READ+UPDATE');
|
||||||
|
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'PROJECT_CUSTOM_FUNCTION:READ');
|
||||||
|
|
||||||
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'PROJECT_API_DEBUG:READ');
|
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'PROJECT_API_DEBUG:READ');
|
||||||
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'PROJECT_API_DEBUG:READ+ADD');
|
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'PROJECT_API_DEBUG:READ+ADD');
|
||||||
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'PROJECT_API_DEBUG:READ+UPDATE');
|
INSERT INTO user_role_permission (id, role_id, permission_id) VALUES (UUID_SHORT(), 'project_member', 'PROJECT_API_DEBUG:READ+UPDATE');
|
||||||
|
@ -203,6 +203,7 @@ public class PermissionConstants {
|
|||||||
public static final String PROJECT_CUSTOM_FUNCTION_ADD = "PROJECT_CUSTOM_FUNCTION:READ+ADD";
|
public static final String PROJECT_CUSTOM_FUNCTION_ADD = "PROJECT_CUSTOM_FUNCTION:READ+ADD";
|
||||||
public static final String PROJECT_CUSTOM_FUNCTION_UPDATE = "PROJECT_CUSTOM_FUNCTION:READ+UPDATE";
|
public static final String PROJECT_CUSTOM_FUNCTION_UPDATE = "PROJECT_CUSTOM_FUNCTION:READ+UPDATE";
|
||||||
public static final String PROJECT_CUSTOM_FUNCTION_DELETE = "PROJECT_CUSTOM_FUNCTION:READ+DELETE";
|
public static final String PROJECT_CUSTOM_FUNCTION_DELETE = "PROJECT_CUSTOM_FUNCTION:READ+DELETE";
|
||||||
|
public static final String PROJECT_CUSTOM_FUNCTION_EXECUTE = "PROJECT_CUSTOM_FUNCTION:READ+EXECUTE";
|
||||||
/*------ end: PROJECT_CUSTOM_FUNCTION ------*/
|
/*------ end: PROJECT_CUSTOM_FUNCTION ------*/
|
||||||
|
|
||||||
/*------ start: PROJECT_TEMPLATE ------*/
|
/*------ start: PROJECT_TEMPLATE ------*/
|
||||||
|
@ -39,7 +39,7 @@ public class TaskRequestDTO implements Serializable {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 资源类型
|
* 资源类型
|
||||||
* ApiResourceType
|
* @see io.metersphere.sdk.constants.ApiExecuteResourceType
|
||||||
*/
|
*/
|
||||||
private String resourceType;
|
private String resourceType;
|
||||||
|
|
||||||
|
@ -475,4 +475,5 @@ env_info_all=环境信息(总).json
|
|||||||
|
|
||||||
# custom_function
|
# custom_function
|
||||||
custom_function_already_exist= 脚本名称已存在
|
custom_function_already_exist= 脚本名称已存在
|
||||||
|
permission.project_custom_function.name=公共脚本
|
||||||
|
permission.project_custom_function.execute=测试
|
@ -513,3 +513,5 @@ env_info_all=All environment info.json
|
|||||||
|
|
||||||
# custom_function
|
# custom_function
|
||||||
custom_function_already_exist= custom function name already exist
|
custom_function_already_exist= custom function name already exist
|
||||||
|
permission.project_custom_function.name=Common script
|
||||||
|
permission.project_custom_function.execute=Test
|
@ -512,3 +512,5 @@ env_info_all=环境信息(总).json
|
|||||||
|
|
||||||
# custom_function
|
# custom_function
|
||||||
custom_function_already_exist= 脚本名称已存在
|
custom_function_already_exist= 脚本名称已存在
|
||||||
|
permission.project_custom_function.name=公共脚本
|
||||||
|
permission.project_custom_function.execute=测试
|
@ -513,3 +513,5 @@ env_info_all=環境信息(总).json
|
|||||||
|
|
||||||
# custom_function
|
# custom_function
|
||||||
custom_function_already_exist= 腳本名稱已存在
|
custom_function_already_exist= 腳本名稱已存在
|
||||||
|
permission.project_custom_function.name=公共腳本
|
||||||
|
permission.project_custom_function.execute=測試
|
@ -309,4 +309,4 @@ operation_history.type.not_blank=变更记录操作类型不能为空
|
|||||||
operation_history.type.length_range=变更记录操作类型长度必须在{min}和{max}之间
|
operation_history.type.length_range=变更记录操作类型长度必须在{min}和{max}之间
|
||||||
operation_history.source_id.not_blank=变更记录资源 ID 不能为空
|
operation_history.source_id.not_blank=变更记录资源 ID 不能为空
|
||||||
operation_history.version_id.not_blank=变更记录版本 ID 不能为空
|
operation_history.version_id.not_blank=变更记录版本 ID 不能为空
|
||||||
operation_history.version_id.length_range=变更记录版本 ID 长度必须在{min}和{max}之间
|
operation_history.version_id.length_range=变更记录版本 ID 长度必须在{min}和{max}之间
|
||||||
|
@ -57,6 +57,11 @@
|
|||||||
<artifactId>ApacheJMeter_http</artifactId>
|
<artifactId>ApacheJMeter_http</artifactId>
|
||||||
<version>${jmeter.version}</version>
|
<version>${jmeter.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.jmeter</groupId>
|
||||||
|
<artifactId>ApacheJMeter_java</artifactId>
|
||||||
|
<version>${jmeter.version}</version>
|
||||||
|
</dependency>
|
||||||
<!-- 自定义jmeter 断言插件 -->
|
<!-- 自定义jmeter 断言插件 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.metersphere</groupId>
|
<groupId>io.metersphere</groupId>
|
||||||
|
@ -1,15 +1,17 @@
|
|||||||
package io.metersphere.api.controller;
|
package io.metersphere.api.controller;
|
||||||
|
|
||||||
|
import io.metersphere.api.service.ApiExecuteService;
|
||||||
import io.metersphere.api.service.ApiTestService;
|
import io.metersphere.api.service.ApiTestService;
|
||||||
import io.metersphere.jmeter.mock.Mock;
|
import io.metersphere.jmeter.mock.Mock;
|
||||||
|
import io.metersphere.project.dto.customfunction.request.CustomFunctionRunRequest;
|
||||||
|
import io.metersphere.sdk.constants.PermissionConstants;
|
||||||
import io.metersphere.system.dto.ProtocolDTO;
|
import io.metersphere.system.dto.ProtocolDTO;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.validation.annotation.Validated;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.*;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -24,6 +26,8 @@ public class ApiTestController {
|
|||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private ApiTestService apiTestService;
|
private ApiTestService apiTestService;
|
||||||
|
@Resource
|
||||||
|
private ApiExecuteService apiExecuteService;
|
||||||
|
|
||||||
@GetMapping("/protocol/{organizationId}")
|
@GetMapping("/protocol/{organizationId}")
|
||||||
@Operation(summary = "获取协议插件的的协议列表")
|
@Operation(summary = "获取协议插件的的协议列表")
|
||||||
@ -37,4 +41,11 @@ public class ApiTestController {
|
|||||||
public String mock(@PathVariable String key) {
|
public String mock(@PathVariable String key) {
|
||||||
return Mock.calculate(key).toString();
|
return Mock.calculate(key).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@PostMapping("/custom/func/run")
|
||||||
|
@Operation(summary = "项目管理-公共脚本-脚本测试")
|
||||||
|
@RequiresPermissions(PermissionConstants.PROJECT_CUSTOM_FUNCTION_EXECUTE)
|
||||||
|
public String run(@Validated @RequestBody CustomFunctionRunRequest runRequest) {
|
||||||
|
return apiExecuteService.runScript(runRequest);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,31 +0,0 @@
|
|||||||
package io.metersphere.api.dto;
|
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Data;
|
|
||||||
|
|
||||||
import java.io.Serial;
|
|
||||||
import java.io.Serializable;
|
|
||||||
|
|
||||||
@Data
|
|
||||||
@AllArgsConstructor
|
|
||||||
public class NodeDTO implements Serializable {
|
|
||||||
|
|
||||||
@Serial
|
|
||||||
private static final long serialVersionUID = 1L;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 接口测试 性能测试 node节点ip
|
|
||||||
*/
|
|
||||||
private String ip;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 接口测试 性能测试 node节点端口
|
|
||||||
*/
|
|
||||||
private String port;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 资源池最大并发数
|
|
||||||
*/
|
|
||||||
private int podThreads;
|
|
||||||
|
|
||||||
}
|
|
@ -0,0 +1,30 @@
|
|||||||
|
package io.metersphere.api.dto.request.controller;
|
||||||
|
|
||||||
|
import io.metersphere.api.dto.request.processors.ScriptProcessor;
|
||||||
|
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||||
|
import io.metersphere.project.dto.environment.KeyValueParam;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公共脚本组件
|
||||||
|
* 主要用于公共脚本测试执行时,生成jmx
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
public class MsCommentScriptElement extends AbstractMsTestElement {
|
||||||
|
/**
|
||||||
|
* 脚本内容
|
||||||
|
*/
|
||||||
|
private String script;
|
||||||
|
/**
|
||||||
|
* 脚本语言
|
||||||
|
* @see ScriptProcessor.ScriptLanguageType
|
||||||
|
*/
|
||||||
|
private String scriptLanguage;
|
||||||
|
/**
|
||||||
|
* 公共脚本入参
|
||||||
|
*/
|
||||||
|
private List<KeyValueParam> params;
|
||||||
|
}
|
@ -2,6 +2,7 @@ package io.metersphere.api.dto.request.processors;
|
|||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonTypeName;
|
import com.fasterxml.jackson.annotation.JsonTypeName;
|
||||||
import io.metersphere.api.dto.request.http.KeyValueParam;
|
import io.metersphere.api.dto.request.http.KeyValueParam;
|
||||||
|
import io.metersphere.project.constants.ScriptLanguageType;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -34,22 +35,4 @@ public class ScriptProcessor extends MsProcessor {
|
|||||||
* 公共脚本入参
|
* 公共脚本入参
|
||||||
*/
|
*/
|
||||||
private List<KeyValueParam> params;
|
private List<KeyValueParam> params;
|
||||||
|
|
||||||
public enum ScriptLanguageType {
|
|
||||||
BEANSHELL("beanshell"),
|
|
||||||
BEANSHELL_JSR233("beanshell-JSR233"),
|
|
||||||
GROOVY("groovy"),
|
|
||||||
JAVASCRIPT("javascript"),
|
|
||||||
PYTHON("python");
|
|
||||||
|
|
||||||
private String value;
|
|
||||||
|
|
||||||
ScriptLanguageType(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,82 @@
|
|||||||
|
package io.metersphere.api.parser.jmeter;
|
||||||
|
|
||||||
|
import io.metersphere.api.dto.request.controller.MsCommentScriptElement;
|
||||||
|
import io.metersphere.api.dto.request.processors.ScriptProcessor;
|
||||||
|
import io.metersphere.api.parser.jmeter.processor.ScriptProcessorConverter;
|
||||||
|
import io.metersphere.plugin.api.dto.ParameterConfig;
|
||||||
|
import io.metersphere.plugin.api.spi.AbstractJmeterElementConverter;
|
||||||
|
import io.metersphere.project.dto.environment.KeyValueParam;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
import org.apache.jmeter.extractor.BeanShellPostProcessor;
|
||||||
|
import org.apache.jmeter.extractor.JSR223PostProcessor;
|
||||||
|
import org.apache.jmeter.modifiers.UserParameters;
|
||||||
|
import org.apache.jmeter.save.SaveService;
|
||||||
|
import org.apache.jmeter.testelement.TestElement;
|
||||||
|
import org.apache.jorphan.collections.HashTree;
|
||||||
|
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import static io.metersphere.api.parser.jmeter.constants.JmeterAlias.USER_PARAMETERS_GUI;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2024-01-18 22:04
|
||||||
|
*/
|
||||||
|
public class MsCommentScriptElementConverter extends AbstractJmeterElementConverter<MsCommentScriptElement> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void toHashTree(HashTree hashTree, MsCommentScriptElement msElement, ParameterConfig config) {
|
||||||
|
|
||||||
|
if (CollectionUtils.isNotEmpty(msElement.getParams())) {
|
||||||
|
// 添加变量
|
||||||
|
List<KeyValueParam> params = msElement.getParams()
|
||||||
|
.stream()
|
||||||
|
.filter(KeyValueParam::isValid)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
if (CollectionUtils.isNotEmpty(params)) {
|
||||||
|
UserParameters userParameters = getUserParameters(params);
|
||||||
|
hashTree.add(userParameters);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加脚本
|
||||||
|
ScriptProcessor scriptProcessor = new ScriptProcessor();
|
||||||
|
scriptProcessor.setScriptLanguage(msElement.getScriptLanguage());
|
||||||
|
scriptProcessor.setScript(msElement.getScript());
|
||||||
|
TestElement scriptElement;
|
||||||
|
if (ScriptProcessorConverter.isJSR233(scriptProcessor)) {
|
||||||
|
scriptElement = new JSR223PostProcessor();
|
||||||
|
} else {
|
||||||
|
scriptElement = new BeanShellPostProcessor();
|
||||||
|
}
|
||||||
|
ScriptProcessorConverter.parse(scriptElement, scriptProcessor);
|
||||||
|
hashTree.add(scriptElement);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UserParameters getUserParameters(List<KeyValueParam> params) {
|
||||||
|
UserParameters processor = new UserParameters();
|
||||||
|
processor.setEnabled(true);
|
||||||
|
processor.setName("User Defined Variables");
|
||||||
|
processor.setPerIteration(true);
|
||||||
|
processor.setProperty(TestElement.TEST_CLASS, UserParameters.class.getName());
|
||||||
|
processor.setProperty(TestElement.GUI_CLASS, SaveService.aliasToClass(USER_PARAMETERS_GUI));
|
||||||
|
if (CollectionUtils.isNotEmpty(params)) {
|
||||||
|
List<String> names = new LinkedList<>();
|
||||||
|
List<Object> values = new LinkedList<>();
|
||||||
|
List<Object> threadValues = new LinkedList<>();
|
||||||
|
for (KeyValueParam param : params) {
|
||||||
|
String name = param.getKey();
|
||||||
|
String value = param.getValue();
|
||||||
|
names.add(name);
|
||||||
|
values.add(value);
|
||||||
|
}
|
||||||
|
processor.setNames(names);
|
||||||
|
threadValues.add(values);
|
||||||
|
processor.setThreadLists(threadValues);
|
||||||
|
}
|
||||||
|
return processor;
|
||||||
|
}
|
||||||
|
}
|
@ -16,4 +16,5 @@ public class JmeterAlias {
|
|||||||
public static final String HTTP_TEST_SAMPLE_GUI = "HttpTestSampleGui";
|
public static final String HTTP_TEST_SAMPLE_GUI = "HttpTestSampleGui";
|
||||||
public static final String XPATH_ASSERTION_GUI = "XPathAssertionGui";
|
public static final String XPATH_ASSERTION_GUI = "XPathAssertionGui";
|
||||||
public static final String X_PATH_2_ASSERTION_GUI = "XPath2AssertionGui";
|
public static final String X_PATH_2_ASSERTION_GUI = "XPath2AssertionGui";
|
||||||
|
public static final String USER_PARAMETERS_GUI = "UserParametersGui";
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package io.metersphere.api.parser.jmeter.processor;
|
package io.metersphere.api.parser.jmeter.processor;
|
||||||
|
|
||||||
import io.metersphere.api.dto.request.processors.ScriptProcessor;
|
import io.metersphere.project.constants.ScriptLanguageType;
|
||||||
import io.metersphere.sdk.exception.MSException;
|
import io.metersphere.sdk.exception.MSException;
|
||||||
import io.metersphere.sdk.util.LogUtils;
|
import io.metersphere.sdk.util.LogUtils;
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
@ -57,10 +57,10 @@ public class ScriptFilter {
|
|||||||
|
|
||||||
public static void verify(String language, String label, String script) {
|
public static void verify(String language, String label, String script) {
|
||||||
// 默认 groovy
|
// 默认 groovy
|
||||||
ScriptProcessor.ScriptLanguageType scriptLanguageType = Arrays.stream(ScriptProcessor.ScriptLanguageType.values())
|
ScriptLanguageType scriptLanguageType = Arrays.stream(ScriptLanguageType.values())
|
||||||
.filter(item -> StringUtils.equals(item.getValue(), language))
|
.filter(item -> StringUtils.equals(item.getValue(), language))
|
||||||
.findFirst()
|
.findFirst()
|
||||||
.orElse(ScriptProcessor.ScriptLanguageType.GROOVY);
|
.orElse(ScriptLanguageType.GROOVY);
|
||||||
|
|
||||||
if (StringUtils.isNotEmpty(script)) {
|
if (StringUtils.isNotEmpty(script)) {
|
||||||
final StringBuffer buffer = new StringBuffer();
|
final StringBuffer buffer = new StringBuffer();
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package io.metersphere.api.parser.jmeter.processor;
|
package io.metersphere.api.parser.jmeter.processor;
|
||||||
|
|
||||||
|
import io.metersphere.project.constants.ScriptLanguageType;
|
||||||
import io.metersphere.api.dto.request.processors.ScriptProcessor;
|
import io.metersphere.api.dto.request.processors.ScriptProcessor;
|
||||||
import io.metersphere.api.parser.jmeter.constants.JmeterAlias;
|
import io.metersphere.api.parser.jmeter.constants.JmeterAlias;
|
||||||
import io.metersphere.api.parser.jmeter.constants.JmeterProperty;
|
import io.metersphere.api.parser.jmeter.constants.JmeterProperty;
|
||||||
@ -36,7 +37,7 @@ public abstract class ScriptProcessorConverter extends MsProcessorConverter<Scri
|
|||||||
testElement.setProperty(JmeterProperty.SCRIPT, scriptProcessor.getScript());
|
testElement.setProperty(JmeterProperty.SCRIPT, scriptProcessor.getScript());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean isJSR233(ScriptProcessor scriptProcessor) {
|
public static boolean isJSR233(ScriptProcessor scriptProcessor) {
|
||||||
return !StringUtils.equals(scriptProcessor.getScriptLanguage(), ScriptProcessor.ScriptLanguageType.BEANSHELL.getValue());
|
return !StringUtils.equals(scriptProcessor.getScriptLanguage(), ScriptLanguageType.BEANSHELL.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package io.metersphere.api.parser.jmeter.processor.assertion;
|
package io.metersphere.api.parser.jmeter.processor.assertion;
|
||||||
|
|
||||||
|
import io.metersphere.project.constants.ScriptLanguageType;
|
||||||
import io.metersphere.api.dto.request.assertion.MsVariableAssertion;
|
import io.metersphere.api.dto.request.assertion.MsVariableAssertion;
|
||||||
import io.metersphere.api.dto.request.processors.ScriptProcessor;
|
import io.metersphere.api.dto.request.processors.ScriptProcessor;
|
||||||
import io.metersphere.api.parser.jmeter.processor.ScriptProcessorConverter;
|
import io.metersphere.api.parser.jmeter.processor.ScriptProcessorConverter;
|
||||||
@ -57,7 +58,7 @@ public class VariableAssertionConverter extends AssertionConverter<MsVariableAss
|
|||||||
String name = String.format("Variable '%s' expect %s %s", variableName, condition.toLowerCase().replace("_", ""), expectedValue);
|
String name = String.format("Variable '%s' expect %s %s", variableName, condition.toLowerCase().replace("_", ""), expectedValue);
|
||||||
scriptProcessor.setName(name);
|
scriptProcessor.setName(name);
|
||||||
|
|
||||||
scriptProcessor.setScriptLanguage(ScriptProcessor.ScriptLanguageType.BEANSHELL_JSR233.getValue());
|
scriptProcessor.setScriptLanguage(ScriptLanguageType.BEANSHELL_JSR233.getValue());
|
||||||
JSR223Assertion jsr223Assertion = new JSR223Assertion();
|
JSR223Assertion jsr223Assertion = new JSR223Assertion();
|
||||||
ScriptProcessorConverter.parse(jsr223Assertion, scriptProcessor);
|
ScriptProcessorConverter.parse(jsr223Assertion, scriptProcessor);
|
||||||
return jsr223Assertion;
|
return jsr223Assertion;
|
||||||
|
@ -4,19 +4,24 @@ import io.metersphere.api.config.JmeterProperties;
|
|||||||
import io.metersphere.api.config.KafkaConfig;
|
import io.metersphere.api.config.KafkaConfig;
|
||||||
import io.metersphere.api.controller.result.ApiResultCode;
|
import io.metersphere.api.controller.result.ApiResultCode;
|
||||||
import io.metersphere.api.dto.debug.ApiResourceRunRequest;
|
import io.metersphere.api.dto.debug.ApiResourceRunRequest;
|
||||||
|
import io.metersphere.api.dto.request.controller.MsCommentScriptElement;
|
||||||
import io.metersphere.api.parser.TestElementParser;
|
import io.metersphere.api.parser.TestElementParser;
|
||||||
import io.metersphere.api.parser.TestElementParserFactory;
|
import io.metersphere.api.parser.TestElementParserFactory;
|
||||||
import io.metersphere.api.utils.ApiDataUtils;
|
import io.metersphere.api.utils.ApiDataUtils;
|
||||||
import io.metersphere.plugin.api.dto.ParameterConfig;
|
import io.metersphere.plugin.api.dto.ParameterConfig;
|
||||||
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||||
import io.metersphere.project.domain.ProjectApplication;
|
import io.metersphere.project.domain.ProjectApplication;
|
||||||
|
import io.metersphere.project.dto.customfunction.request.CustomFunctionRunRequest;
|
||||||
import io.metersphere.project.service.FileAssociationService;
|
import io.metersphere.project.service.FileAssociationService;
|
||||||
import io.metersphere.project.service.FileManagementService;
|
import io.metersphere.project.service.FileManagementService;
|
||||||
import io.metersphere.project.service.FileMetadataService;
|
import io.metersphere.project.service.FileMetadataService;
|
||||||
import io.metersphere.project.service.ProjectApplicationService;
|
import io.metersphere.project.service.ProjectApplicationService;
|
||||||
|
import io.metersphere.sdk.constants.ApiExecuteResourceType;
|
||||||
|
import io.metersphere.sdk.constants.ApiExecuteRunMode;
|
||||||
import io.metersphere.sdk.constants.ProjectApplicationType;
|
import io.metersphere.sdk.constants.ProjectApplicationType;
|
||||||
import io.metersphere.sdk.constants.StorageType;
|
import io.metersphere.sdk.constants.StorageType;
|
||||||
import io.metersphere.sdk.dto.api.task.ApiExecuteFileInfo;
|
import io.metersphere.sdk.dto.api.task.ApiExecuteFileInfo;
|
||||||
|
import io.metersphere.sdk.dto.api.task.ApiRunModeConfigDTO;
|
||||||
import io.metersphere.sdk.dto.api.task.TaskRequestDTO;
|
import io.metersphere.sdk.dto.api.task.TaskRequestDTO;
|
||||||
import io.metersphere.sdk.exception.MSException;
|
import io.metersphere.sdk.exception.MSException;
|
||||||
import io.metersphere.sdk.util.*;
|
import io.metersphere.sdk.util.*;
|
||||||
@ -27,6 +32,7 @@ import io.metersphere.system.dto.pool.TestResourceNodeDTO;
|
|||||||
import io.metersphere.system.service.CommonProjectService;
|
import io.metersphere.system.service.CommonProjectService;
|
||||||
import io.metersphere.system.service.SystemParameterService;
|
import io.metersphere.system.service.SystemParameterService;
|
||||||
import io.metersphere.system.service.TestResourcePoolService;
|
import io.metersphere.system.service.TestResourcePoolService;
|
||||||
|
import io.metersphere.system.uid.IDGenerator;
|
||||||
import io.metersphere.system.utils.TaskRunnerClient;
|
import io.metersphere.system.utils.TaskRunnerClient;
|
||||||
import jakarta.annotation.PostConstruct;
|
import jakarta.annotation.PostConstruct;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
@ -39,7 +45,6 @@ import org.springframework.stereotype.Service;
|
|||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.security.SecureRandom;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@ -66,6 +71,8 @@ public class ApiExecuteService {
|
|||||||
@Resource
|
@Resource
|
||||||
private StringRedisTemplate stringRedisTemplate;
|
private StringRedisTemplate stringRedisTemplate;
|
||||||
@Resource
|
@Resource
|
||||||
|
private RoundRobinService roundRobinService;
|
||||||
|
@Resource
|
||||||
private JmeterProperties jmeterProperties;
|
private JmeterProperties jmeterProperties;
|
||||||
@Resource
|
@Resource
|
||||||
private ApiFileResourceService apiFileResourceService;
|
private ApiFileResourceService apiFileResourceService;
|
||||||
@ -104,16 +111,14 @@ public class ApiExecuteService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void debug(ApiResourceRunRequest request) {
|
public void debug(ApiResourceRunRequest request) {
|
||||||
TestResourceDTO resourcePoolDTO = getAvailableResourcePoolDTO(request.getProjectId());
|
|
||||||
String reportId = request.getReportId();
|
String reportId = request.getReportId();
|
||||||
String testId = request.getTestId();
|
String testId = request.getTestId();
|
||||||
|
|
||||||
TaskRequestDTO taskRequest = new TaskRequestDTO();
|
TaskRequestDTO taskRequest = new TaskRequestDTO();
|
||||||
BeanUtils.copyBean(taskRequest, request);
|
BeanUtils.copyBean(taskRequest, request);
|
||||||
taskRequest.setKafkaConfig(EncryptUtils.aesEncrypt(JSON.toJSONString(KafkaConfig.getKafkaConfig())));
|
|
||||||
taskRequest.setMinioConfig(EncryptUtils.aesEncrypt(JSON.toJSONString(getMinio())));
|
|
||||||
taskRequest.setMsUrl(systemParameterService.getBaseInfo().getUrl());
|
|
||||||
taskRequest.setRealTime(true);
|
taskRequest.setRealTime(true);
|
||||||
|
taskRequest.setResourceId(testId);
|
||||||
|
setServerInfoParam(taskRequest);
|
||||||
|
|
||||||
// 设置执行文件参数
|
// 设置执行文件参数
|
||||||
setTaskFileParam(request, taskRequest);
|
setTaskFileParam(request, taskRequest);
|
||||||
@ -128,15 +133,30 @@ public class ApiExecuteService {
|
|||||||
parameterConfig.setReportId(reportId);
|
parameterConfig.setReportId(reportId);
|
||||||
String executeScript = parseExecuteScript(request.getRequest(), parameterConfig);
|
String executeScript = parseExecuteScript(request.getRequest(), parameterConfig);
|
||||||
|
|
||||||
|
TestResourceNodeDTO testResourceNodeDTO = getProjectExecuteNode(request.getProjectId());
|
||||||
|
|
||||||
|
doDebug(reportId, testId, taskRequest, executeScript, testResourceNodeDTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 发送执行任务
|
||||||
|
* @param reportId 报告ID
|
||||||
|
* @param testId 资源ID
|
||||||
|
* @param taskRequest 执行参数
|
||||||
|
* @param executeScript 执行脚本
|
||||||
|
* @param testResourceNodeDTO 资源池
|
||||||
|
*/
|
||||||
|
private void doDebug(String reportId,
|
||||||
|
String testId,
|
||||||
|
TaskRequestDTO taskRequest,
|
||||||
|
String executeScript,
|
||||||
|
TestResourceNodeDTO testResourceNodeDTO) {
|
||||||
// 将测试脚本缓存到 redis
|
// 将测试脚本缓存到 redis
|
||||||
String scriptRedisKey = getScriptRedisKey(reportId, testId);
|
String scriptRedisKey = getScriptRedisKey(reportId, testId);
|
||||||
stringRedisTemplate.opsForValue().set(scriptRedisKey, executeScript);
|
stringRedisTemplate.opsForValue().set(scriptRedisKey, executeScript);
|
||||||
|
|
||||||
List<TestResourceNodeDTO> nodesList = resourcePoolDTO.getNodesList();
|
|
||||||
int index = new SecureRandom().nextInt(nodesList.size());
|
|
||||||
TestResourceNodeDTO testResourceNodeDTO = nodesList.get(index);
|
|
||||||
String endpoint = TaskRunnerClient.getEndpoint(testResourceNodeDTO.getIp(), testResourceNodeDTO.getPort());
|
|
||||||
try {
|
try {
|
||||||
|
String endpoint = TaskRunnerClient.getEndpoint(testResourceNodeDTO.getIp(), testResourceNodeDTO.getPort());
|
||||||
LogUtils.info(String.format("开始发送请求【 %s 】到 %s 节点执行", testId, endpoint), reportId);
|
LogUtils.info(String.format("开始发送请求【 %s 】到 %s 节点执行", testId, endpoint), reportId);
|
||||||
TaskRunnerClient.debugApi(endpoint, taskRequest);
|
TaskRunnerClient.debugApi(endpoint, taskRequest);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
@ -147,6 +167,57 @@ public class ApiExecuteService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private TestResourceNodeDTO getProjectExecuteNode(String projectId) {
|
||||||
|
String resourcePoolId = getProjectApiResourcePoolId(projectId);
|
||||||
|
TestResourceDTO resourcePoolDTO = getAvailableResourcePoolDTO(projectId, resourcePoolId);
|
||||||
|
roundRobinService.initializeNodes(resourcePoolId, resourcePoolDTO.getNodesList());
|
||||||
|
try {
|
||||||
|
return roundRobinService.getNextNode(resourcePoolId);
|
||||||
|
} catch (Exception e) {
|
||||||
|
LogUtils.error(e);
|
||||||
|
throw new MSException("get execute node error", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置minio kafka ms 等信息
|
||||||
|
*
|
||||||
|
* @param taskRequest
|
||||||
|
*/
|
||||||
|
private void setServerInfoParam(TaskRequestDTO taskRequest) {
|
||||||
|
taskRequest.setKafkaConfig(EncryptUtils.aesEncrypt(JSON.toJSONString(KafkaConfig.getKafkaConfig())));
|
||||||
|
taskRequest.setMinioConfig(EncryptUtils.aesEncrypt(JSON.toJSONString(getMinio())));
|
||||||
|
taskRequest.setMsUrl(systemParameterService.getBaseInfo().getUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公共脚本执行
|
||||||
|
* @param runRequest
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String runScript(CustomFunctionRunRequest runRequest) {
|
||||||
|
String reportId = IDGenerator.nextStr();
|
||||||
|
String testId = runRequest.getProjectId();
|
||||||
|
// 生成执行脚本
|
||||||
|
MsCommentScriptElement msCommentScriptElement = BeanUtils.copyBean(new MsCommentScriptElement(), runRequest);
|
||||||
|
String executeScript = parseExecuteScript(msCommentScriptElement, new ParameterConfig());
|
||||||
|
// 设置执行参数
|
||||||
|
TaskRequestDTO taskRequest = new TaskRequestDTO();
|
||||||
|
setServerInfoParam(taskRequest);
|
||||||
|
taskRequest.setRealTime(true);
|
||||||
|
taskRequest.setReportId(reportId);
|
||||||
|
taskRequest.setResourceId(testId);
|
||||||
|
taskRequest.setResourceType(ApiExecuteResourceType.API_DEBUG.name());
|
||||||
|
ApiRunModeConfigDTO apiRunModeConfig = new ApiRunModeConfigDTO();
|
||||||
|
apiRunModeConfig.setRunMode(ApiExecuteRunMode.BACKEND_DEBUG.name());
|
||||||
|
taskRequest.setRunModeConfig(apiRunModeConfig);
|
||||||
|
|
||||||
|
TestResourceNodeDTO testResourceNodeDTO = getProjectExecuteNode(runRequest.getProjectId());
|
||||||
|
|
||||||
|
doDebug(reportId, testId, taskRequest, executeScript, testResourceNodeDTO);
|
||||||
|
return reportId;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 给 taskRequest 设置文件相关参数
|
* 给 taskRequest 设置文件相关参数
|
||||||
*
|
*
|
||||||
@ -236,14 +307,18 @@ public class ApiExecuteService {
|
|||||||
* 生成执行脚本
|
* 生成执行脚本
|
||||||
*
|
*
|
||||||
* @param testElementStr
|
* @param testElementStr
|
||||||
* @param msParameter
|
* @param config
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private static String parseExecuteScript(String testElementStr, ParameterConfig msParameter) {
|
private static String parseExecuteScript(String testElementStr, ParameterConfig config) {
|
||||||
|
// 解析生成脚本
|
||||||
|
return parseExecuteScript(ApiDataUtils.parseObject(testElementStr, AbstractMsTestElement.class), config);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String parseExecuteScript(AbstractMsTestElement msTestElement, ParameterConfig config) {
|
||||||
// 解析生成脚本
|
// 解析生成脚本
|
||||||
TestElementParser defaultParser = TestElementParserFactory.getDefaultParser();
|
TestElementParser defaultParser = TestElementParserFactory.getDefaultParser();
|
||||||
AbstractMsTestElement msTestElement = ApiDataUtils.parseObject(testElementStr, AbstractMsTestElement.class);
|
return defaultParser.parse(msTestElement, config);
|
||||||
return defaultParser.parse(msTestElement, msParameter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -262,14 +337,7 @@ public class ApiExecuteService {
|
|||||||
* @param projectId
|
* @param projectId
|
||||||
* @param
|
* @param
|
||||||
*/
|
*/
|
||||||
public TestResourceDTO getAvailableResourcePoolDTO(String projectId) {
|
public TestResourceDTO getAvailableResourcePoolDTO(String projectId, String resourcePoolId) {
|
||||||
// 查询接口默认资源池
|
|
||||||
ProjectApplication resourcePoolConfig = projectApplicationService.getByType(projectId, ProjectApplicationType.API.API_RESOURCE_POOL_ID.name());
|
|
||||||
// 没有配置接口默认资源池
|
|
||||||
if (resourcePoolConfig == null || StringUtils.isBlank(resourcePoolConfig.getTypeValue())) {
|
|
||||||
throw new MSException(ApiResultCode.EXECUTE_RESOURCE_POOL_NOT_CONFIG);
|
|
||||||
}
|
|
||||||
String resourcePoolId = StringUtils.isBlank(resourcePoolConfig.getTypeValue()) ? null : resourcePoolConfig.getTypeValue();
|
|
||||||
TestResourcePool testResourcePool = testResourcePoolService.getTestResourcePool(resourcePoolId);
|
TestResourcePool testResourcePool = testResourcePoolService.getTestResourcePool(resourcePoolId);
|
||||||
if (testResourcePool == null ||
|
if (testResourcePool == null ||
|
||||||
// 资源池禁用
|
// 资源池禁用
|
||||||
@ -280,4 +348,15 @@ public class ApiExecuteService {
|
|||||||
}
|
}
|
||||||
return testResourcePoolService.getTestResourceDTO(resourcePoolId);
|
return testResourcePoolService.getTestResourceDTO(resourcePoolId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getProjectApiResourcePoolId(String projectId) {
|
||||||
|
// 查询接口默认资源池
|
||||||
|
ProjectApplication resourcePoolConfig = projectApplicationService.getByType(projectId, ProjectApplicationType.API.API_RESOURCE_POOL_ID.name());
|
||||||
|
// 没有配置接口默认资源池
|
||||||
|
if (resourcePoolConfig == null || StringUtils.isBlank(resourcePoolConfig.getTypeValue())) {
|
||||||
|
throw new MSException(ApiResultCode.EXECUTE_RESOURCE_POOL_NOT_CONFIG);
|
||||||
|
}
|
||||||
|
String resourcePoolId = StringUtils.isBlank(resourcePoolConfig.getTypeValue()) ? null : resourcePoolConfig.getTypeValue();
|
||||||
|
return resourcePoolId;
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
package io.metersphere.api.service;
|
package io.metersphere.api.service;
|
||||||
|
|
||||||
import io.metersphere.api.dto.NodeDTO;
|
|
||||||
import io.metersphere.sdk.util.JSON;
|
import io.metersphere.sdk.util.JSON;
|
||||||
|
import io.metersphere.system.dto.pool.TestResourceNodeDTO;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.data.redis.core.RedisTemplate;
|
import org.springframework.data.redis.core.RedisTemplate;
|
||||||
@ -17,7 +17,7 @@ public class RoundRobinService {
|
|||||||
/**
|
/**
|
||||||
* 获取下一个节点
|
* 获取下一个节点
|
||||||
*/
|
*/
|
||||||
public String getNextNode(String poolId) throws Exception {
|
public TestResourceNodeDTO getNextNode(String poolId) throws Exception {
|
||||||
// 从列表头部获取下一个节点
|
// 从列表头部获取下一个节点
|
||||||
String node = redisTemplate.opsForList().leftPop(poolId);
|
String node = redisTemplate.opsForList().leftPop(poolId);
|
||||||
|
|
||||||
@ -35,22 +35,24 @@ public class RoundRobinService {
|
|||||||
if (StringUtils.isNotBlank(node)) {
|
if (StringUtils.isNotBlank(node)) {
|
||||||
// 将节点重新放回列表尾部,实现轮询
|
// 将节点重新放回列表尾部,实现轮询
|
||||||
redisTemplate.opsForList().rightPush(poolId, node);
|
redisTemplate.opsForList().rightPush(poolId, node);
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return node;
|
return JSON.parseObject(node, TestResourceNodeDTO.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 初始化节点列表
|
* 初始化节点列表
|
||||||
*/
|
*/
|
||||||
public void initializeNodes(String poolId, List<NodeDTO> nodes) {
|
public void initializeNodes(String poolId, List<TestResourceNodeDTO> nodes) {
|
||||||
// 检查节点是否有变更
|
// 检查节点是否有变更
|
||||||
Long poolSize = redisTemplate.opsForList().size(poolId);
|
Long poolSize = redisTemplate.opsForList().size(poolId);
|
||||||
int size = poolSize != null ? poolSize.intValue() : 0;
|
int size = poolSize != null ? poolSize.intValue() : 0;
|
||||||
if (size == nodes.size()) {
|
if (size == nodes.size()) {
|
||||||
// 对比redis中的节点列表和传入的节点列表是否一致
|
// 对比redis中的节点列表和传入的节点列表是否一致
|
||||||
boolean isSame = true;
|
boolean isSame = true;
|
||||||
for (NodeDTO node : nodes) {
|
for (TestResourceNodeDTO node : nodes) {
|
||||||
boolean isExist = false;
|
boolean isExist = false;
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
if (JSON.toJSONString(node).equals(redisTemplate.opsForList().index(poolId, i))) {
|
if (JSON.toJSONString(node).equals(redisTemplate.opsForList().index(poolId, i))) {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package io.metersphere.api.utils;
|
package io.metersphere.api.utils;
|
||||||
|
|
||||||
|
import io.metersphere.api.parser.jmeter.MsCommentScriptElementConverter;
|
||||||
import io.metersphere.api.parser.jmeter.MsCommonElementConverter;
|
import io.metersphere.api.parser.jmeter.MsCommonElementConverter;
|
||||||
import io.metersphere.api.parser.jmeter.MsHTTPElementConverter;
|
import io.metersphere.api.parser.jmeter.MsHTTPElementConverter;
|
||||||
import io.metersphere.plugin.api.spi.AbstractJmeterElementConverter;
|
import io.metersphere.plugin.api.spi.AbstractJmeterElementConverter;
|
||||||
@ -28,6 +29,7 @@ public class JmeterElementConverterRegister {
|
|||||||
// 注册默认的转换器 todo 注册插件的转换器
|
// 注册默认的转换器 todo 注册插件的转换器
|
||||||
register(MsHTTPElementConverter.class);
|
register(MsHTTPElementConverter.class);
|
||||||
register(MsCommonElementConverter.class);
|
register(MsCommonElementConverter.class);
|
||||||
|
register(MsCommentScriptElementConverter.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -16,22 +16,16 @@ import io.metersphere.api.parser.ImportParserFactory;
|
|||||||
import io.metersphere.api.parser.TestElementParserFactory;
|
import io.metersphere.api.parser.TestElementParserFactory;
|
||||||
import io.metersphere.api.parser.jmeter.MsScenarioConverter;
|
import io.metersphere.api.parser.jmeter.MsScenarioConverter;
|
||||||
import io.metersphere.api.service.ApiFileResourceService;
|
import io.metersphere.api.service.ApiFileResourceService;
|
||||||
|
import io.metersphere.api.service.BaseResourcePoolTestService;
|
||||||
import io.metersphere.api.utils.ApiDataUtils;
|
import io.metersphere.api.utils.ApiDataUtils;
|
||||||
import io.metersphere.plugin.api.dto.ParameterConfig;
|
import io.metersphere.plugin.api.dto.ParameterConfig;
|
||||||
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||||
import io.metersphere.project.domain.ProjectApplication;
|
|
||||||
import io.metersphere.project.domain.ProjectTestResourcePool;
|
|
||||||
import io.metersphere.project.domain.ProjectTestResourcePoolExample;
|
|
||||||
import io.metersphere.project.dto.filemanagement.FileInfo;
|
import io.metersphere.project.dto.filemanagement.FileInfo;
|
||||||
import io.metersphere.project.dto.filemanagement.request.FileUploadRequest;
|
import io.metersphere.project.dto.filemanagement.request.FileUploadRequest;
|
||||||
import io.metersphere.project.mapper.ProjectApplicationMapper;
|
|
||||||
import io.metersphere.project.mapper.ProjectTestResourcePoolMapper;
|
|
||||||
import io.metersphere.project.service.FileAssociationService;
|
import io.metersphere.project.service.FileAssociationService;
|
||||||
import io.metersphere.project.service.FileMetadataService;
|
import io.metersphere.project.service.FileMetadataService;
|
||||||
import io.metersphere.sdk.constants.DefaultRepositoryDir;
|
import io.metersphere.sdk.constants.DefaultRepositoryDir;
|
||||||
import io.metersphere.sdk.constants.PermissionConstants;
|
import io.metersphere.sdk.constants.PermissionConstants;
|
||||||
import io.metersphere.sdk.constants.ProjectApplicationType;
|
|
||||||
import io.metersphere.sdk.constants.ResourcePoolTypeEnum;
|
|
||||||
import io.metersphere.sdk.file.FileCenter;
|
import io.metersphere.sdk.file.FileCenter;
|
||||||
import io.metersphere.sdk.file.FileRequest;
|
import io.metersphere.sdk.file.FileRequest;
|
||||||
import io.metersphere.sdk.util.BeanUtils;
|
import io.metersphere.sdk.util.BeanUtils;
|
||||||
@ -40,28 +34,16 @@ import io.metersphere.sdk.util.JSON;
|
|||||||
import io.metersphere.system.base.BaseTest;
|
import io.metersphere.system.base.BaseTest;
|
||||||
import io.metersphere.system.controller.handler.ResultHolder;
|
import io.metersphere.system.controller.handler.ResultHolder;
|
||||||
import io.metersphere.system.domain.TestResourcePool;
|
import io.metersphere.system.domain.TestResourcePool;
|
||||||
import io.metersphere.system.domain.TestResourcePoolBlob;
|
|
||||||
import io.metersphere.system.domain.TestResourcePoolOrganization;
|
|
||||||
import io.metersphere.system.domain.TestResourcePoolOrganizationExample;
|
|
||||||
import io.metersphere.system.dto.pool.TestResourceDTO;
|
|
||||||
import io.metersphere.system.dto.pool.TestResourceNodeDTO;
|
|
||||||
import io.metersphere.system.dto.pool.TestResourcePoolDTO;
|
|
||||||
import io.metersphere.system.log.constants.OperationLogType;
|
import io.metersphere.system.log.constants.OperationLogType;
|
||||||
import io.metersphere.system.mapper.TestResourcePoolBlobMapper;
|
|
||||||
import io.metersphere.system.mapper.TestResourcePoolMapper;
|
|
||||||
import io.metersphere.system.mapper.TestResourcePoolOrganizationMapper;
|
|
||||||
import io.metersphere.system.uid.IDGenerator;
|
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import org.apache.commons.collections.CollectionUtils;
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
import org.apache.jorphan.collections.ListedHashTree;
|
import org.apache.jorphan.collections.ListedHashTree;
|
||||||
import org.junit.jupiter.api.*;
|
import org.junit.jupiter.api.*;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
import org.springframework.http.MediaType;
|
import org.springframework.http.MediaType;
|
||||||
import org.springframework.mock.web.MockMultipartFile;
|
import org.springframework.mock.web.MockMultipartFile;
|
||||||
import org.springframework.test.web.servlet.MvcResult;
|
import org.springframework.test.web.servlet.MvcResult;
|
||||||
import org.testcontainers.shaded.org.apache.commons.lang3.StringUtils;
|
|
||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -92,19 +74,7 @@ public class ApiDebugControllerTests extends BaseTest {
|
|||||||
@Resource
|
@Resource
|
||||||
private FileMetadataService fileMetadataService;
|
private FileMetadataService fileMetadataService;
|
||||||
@Resource
|
@Resource
|
||||||
private ProjectApplicationMapper projectApplicationMapper;
|
private BaseResourcePoolTestService baseResourcePoolTestService;
|
||||||
@Resource
|
|
||||||
private TestResourcePoolOrganizationMapper testResourcePoolOrganizationMapper;
|
|
||||||
@Resource
|
|
||||||
private ProjectTestResourcePoolMapper projectTestResourcePoolMapper;
|
|
||||||
@Resource
|
|
||||||
private TestResourcePoolMapper testResourcePoolMapper;
|
|
||||||
@Resource
|
|
||||||
private TestResourcePoolBlobMapper testResourcePoolBlobMapper;
|
|
||||||
@Value("${embedded.mockserver.host}")
|
|
||||||
private String mockServerHost;
|
|
||||||
@Value("${embedded.mockserver.port}")
|
|
||||||
private int mockServerHostPort;
|
|
||||||
private static ApiDebug addApiDebug;
|
private static ApiDebug addApiDebug;
|
||||||
private static ApiDebug anotherAddApiDebug;
|
private static ApiDebug anotherAddApiDebug;
|
||||||
private static String fileMetadataId;
|
private static String fileMetadataId;
|
||||||
@ -397,13 +367,13 @@ public class ApiDebugControllerTests extends BaseTest {
|
|||||||
|
|
||||||
// @校验组织没有资源池权限异常
|
// @校验组织没有资源池权限异常
|
||||||
assertErrorCode(this.requestPost(DEBUG, request), ApiResultCode.EXECUTE_RESOURCE_POOL_NOT_CONFIG);
|
assertErrorCode(this.requestPost(DEBUG, request), ApiResultCode.EXECUTE_RESOURCE_POOL_NOT_CONFIG);
|
||||||
TestResourcePool resourcePool = insertResourcePool();
|
TestResourcePool resourcePool = baseResourcePoolTestService.insertResourcePool();
|
||||||
insertResourcePoolOrg(resourcePool);
|
baseResourcePoolTestService.insertResourcePoolOrg(resourcePool);
|
||||||
// @校验项目没有资源池权限异常
|
// @校验项目没有资源池权限异常
|
||||||
assertErrorCode(this.requestPost(DEBUG, request), ApiResultCode.EXECUTE_RESOURCE_POOL_NOT_CONFIG);
|
assertErrorCode(this.requestPost(DEBUG, request), ApiResultCode.EXECUTE_RESOURCE_POOL_NOT_CONFIG);
|
||||||
|
|
||||||
insertResourcePoolProject(resourcePool);
|
baseResourcePoolTestService.insertResourcePoolProject(resourcePool);
|
||||||
insertProjectApplication(resourcePool);
|
baseResourcePoolTestService.insertProjectApplication(resourcePool);
|
||||||
// @校验资源池调用失败
|
// @校验资源池调用失败
|
||||||
assertErrorCode(this.requestPost(DEBUG, request), ApiResultCode.RESOURCE_POOL_EXECUTE_ERROR);
|
assertErrorCode(this.requestPost(DEBUG, request), ApiResultCode.RESOURCE_POOL_EXECUTE_ERROR);
|
||||||
|
|
||||||
@ -485,71 +455,6 @@ public class ApiDebugControllerTests extends BaseTest {
|
|||||||
this.requestPostWithOk(DEBUG, request);
|
this.requestPostWithOk(DEBUG, request);
|
||||||
}
|
}
|
||||||
|
|
||||||
private TestResourcePool insertResourcePool() {
|
|
||||||
String id = IDGenerator.nextStr();
|
|
||||||
TestResourcePoolDTO testResourcePool = new TestResourcePoolDTO();
|
|
||||||
testResourcePool.setId(id);
|
|
||||||
testResourcePool.setApiTest(true);
|
|
||||||
testResourcePool.setCreateTime(System.currentTimeMillis());
|
|
||||||
testResourcePool.setUpdateTime(System.currentTimeMillis());
|
|
||||||
testResourcePool.setDeleted(false);
|
|
||||||
testResourcePool.setName("api debug test");
|
|
||||||
testResourcePool.setCreateUser("admin");
|
|
||||||
testResourcePool.setAllOrg(false);
|
|
||||||
testResourcePool.setEnable(true);
|
|
||||||
testResourcePool.setType(ResourcePoolTypeEnum.NODE.name());
|
|
||||||
TestResourcePoolBlob testResourcePoolBlob = new TestResourcePoolBlob();
|
|
||||||
testResourcePoolBlob.setId(id);
|
|
||||||
TestResourceDTO testResourceDTO = new TestResourceDTO();
|
|
||||||
TestResourceNodeDTO testResourceNodeDTO = new TestResourceNodeDTO();
|
|
||||||
testResourceNodeDTO.setIp(mockServerHost);
|
|
||||||
testResourceNodeDTO.setPort(mockServerHostPort + StringUtils.EMPTY);
|
|
||||||
testResourceNodeDTO.setConcurrentNumber(10);
|
|
||||||
testResourceDTO.setNodesList(List.of(testResourceNodeDTO));
|
|
||||||
String configuration = JSON.toJSONString(testResourceDTO);
|
|
||||||
testResourcePoolBlob.setConfiguration(configuration.getBytes());
|
|
||||||
testResourcePool.setTestResourceDTO(testResourceDTO);
|
|
||||||
|
|
||||||
testResourcePoolMapper.insert(testResourcePool);
|
|
||||||
testResourcePoolBlobMapper.insert(testResourcePoolBlob);
|
|
||||||
return testResourcePool;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void insertProjectApplication(TestResourcePool resourcePool) {
|
|
||||||
ProjectApplication projectApplication = new ProjectApplication();
|
|
||||||
projectApplication.setTypeValue(resourcePool.getId());
|
|
||||||
projectApplication.setType(ProjectApplicationType.API.API_RESOURCE_POOL_ID.name());
|
|
||||||
projectApplication.setProjectId(DEFAULT_PROJECT_ID);
|
|
||||||
projectApplicationMapper.insert(projectApplication);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void insertResourcePoolProject(TestResourcePool resourcePool) {
|
|
||||||
ProjectTestResourcePoolExample example = new ProjectTestResourcePoolExample();
|
|
||||||
example.createCriteria().andProjectIdEqualTo(DEFAULT_PROJECT_ID);
|
|
||||||
example.createCriteria().andTestResourcePoolIdEqualTo(resourcePool.getId());
|
|
||||||
List<ProjectTestResourcePool> projectTestResourcePools = projectTestResourcePoolMapper.selectByExample(example);
|
|
||||||
if (CollectionUtils.isEmpty(projectTestResourcePools)) {
|
|
||||||
ProjectTestResourcePool projectTestResourcePool = new ProjectTestResourcePool();
|
|
||||||
projectTestResourcePool.setTestResourcePoolId(resourcePool.getId());
|
|
||||||
projectTestResourcePool.setProjectId(DEFAULT_PROJECT_ID);
|
|
||||||
projectTestResourcePoolMapper.insert(projectTestResourcePool);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void insertResourcePoolOrg(TestResourcePool resourcePool) {
|
|
||||||
TestResourcePoolOrganizationExample example = new TestResourcePoolOrganizationExample();
|
|
||||||
example.createCriteria().andOrgIdEqualTo(DEFAULT_ORGANIZATION_ID);
|
|
||||||
example.createCriteria().andTestResourcePoolIdEqualTo(resourcePool.getId());
|
|
||||||
List<TestResourcePoolOrganization> testResourcePoolOrganizations = testResourcePoolOrganizationMapper.selectByExample(example);
|
|
||||||
if (CollectionUtils.isEmpty(testResourcePoolOrganizations)) {
|
|
||||||
TestResourcePoolOrganization resourcePoolOrganization = new TestResourcePoolOrganization();
|
|
||||||
resourcePoolOrganization.setTestResourcePoolId(resourcePool.getId());
|
|
||||||
resourcePoolOrganization.setOrgId(DEFAULT_ORGANIZATION_ID);
|
|
||||||
resourcePoolOrganization.setId(IDGenerator.nextStr());
|
|
||||||
testResourcePoolOrganizationMapper.insert(resourcePoolOrganization);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Order(7)
|
@Order(7)
|
||||||
public void delete() throws Exception {
|
public void delete() throws Exception {
|
||||||
@ -568,4 +473,5 @@ public class ApiDebugControllerTests extends BaseTest {
|
|||||||
// @@校验权限
|
// @@校验权限
|
||||||
requestGetPermissionTest(PermissionConstants.PROJECT_API_DEBUG_DELETE, DEFAULT_DELETE, addApiDebug.getId());
|
requestGetPermissionTest(PermissionConstants.PROJECT_API_DEBUG_DELETE, DEFAULT_DELETE, addApiDebug.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,12 +1,20 @@
|
|||||||
package io.metersphere.api.controller;
|
package io.metersphere.api.controller;
|
||||||
|
|
||||||
|
import io.metersphere.api.service.BaseResourcePoolTestService;
|
||||||
|
import io.metersphere.project.constants.ScriptLanguageType;
|
||||||
|
import io.metersphere.project.dto.customfunction.request.CustomFunctionRunRequest;
|
||||||
|
import io.metersphere.project.dto.environment.KeyValueParam;
|
||||||
|
import io.metersphere.sdk.constants.PermissionConstants;
|
||||||
import io.metersphere.system.base.BaseTest;
|
import io.metersphere.system.base.BaseTest;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
import org.junit.jupiter.api.MethodOrderer;
|
import org.junit.jupiter.api.MethodOrderer;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.TestMethodOrder;
|
import org.junit.jupiter.api.TestMethodOrder;
|
||||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||||
import org.springframework.boot.test.context.SpringBootTest;
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Author: jianxing
|
* @Author: jianxing
|
||||||
* @CreateTime: 2023-11-07 17:07
|
* @CreateTime: 2023-11-07 17:07
|
||||||
@ -19,7 +27,10 @@ public class ApiTestControllerTests extends BaseTest {
|
|||||||
private static final String BASE_PATH = "/api/test/";
|
private static final String BASE_PATH = "/api/test/";
|
||||||
protected static final String PROTOCOL_LIST = "protocol/{0}";
|
protected static final String PROTOCOL_LIST = "protocol/{0}";
|
||||||
protected static final String MOCK = "mock/{0}";
|
protected static final String MOCK = "mock/{0}";
|
||||||
|
protected static final String CUSTOM_FUNC_RUN = "custom/func/run";
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private BaseResourcePoolTestService baseResourcePoolTestService;
|
||||||
@Override
|
@Override
|
||||||
protected String getBasePath() {
|
protected String getBasePath() {
|
||||||
return BASE_PATH;
|
return BASE_PATH;
|
||||||
@ -36,4 +47,30 @@ public class ApiTestControllerTests extends BaseTest {
|
|||||||
// @@请求成功
|
// @@请求成功
|
||||||
this.requestGetWithOk(MOCK, "@integer").andReturn();
|
this.requestGetWithOk(MOCK, "@integer").andReturn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void runCustomFunc() throws Exception {
|
||||||
|
mockPost("/api/debug", "");
|
||||||
|
// 初始化资源池
|
||||||
|
baseResourcePoolTestService.initProjectResourcePool();
|
||||||
|
|
||||||
|
CustomFunctionRunRequest request = new CustomFunctionRunRequest();
|
||||||
|
request.setProjectId(DEFAULT_PROJECT_ID);
|
||||||
|
request.setType(ScriptLanguageType.BEANSHELL.getValue());
|
||||||
|
request.setScript("""
|
||||||
|
log.info("========");
|
||||||
|
log.info("${test}");
|
||||||
|
""");
|
||||||
|
// @@请求成功
|
||||||
|
this.requestPostWithOk(CUSTOM_FUNC_RUN, request);
|
||||||
|
|
||||||
|
KeyValueParam keyValueParam = new KeyValueParam();
|
||||||
|
keyValueParam.setKey("test");
|
||||||
|
keyValueParam.setValue("value");
|
||||||
|
request.setParams(List.of(keyValueParam));
|
||||||
|
// @@请求成功
|
||||||
|
this.requestPostWithOk(CUSTOM_FUNC_RUN, request);
|
||||||
|
// @@校验权限
|
||||||
|
requestPostPermissionTest(PermissionConstants.PROJECT_CUSTOM_FUNCTION_EXECUTE, CUSTOM_FUNC_RUN, request);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@ import io.metersphere.api.parser.TestElementParserFactory;
|
|||||||
import io.metersphere.api.utils.ApiDataUtils;
|
import io.metersphere.api.utils.ApiDataUtils;
|
||||||
import io.metersphere.plugin.api.dto.ParameterConfig;
|
import io.metersphere.plugin.api.dto.ParameterConfig;
|
||||||
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
import io.metersphere.plugin.api.spi.AbstractMsTestElement;
|
||||||
|
import io.metersphere.project.constants.ScriptLanguageType;
|
||||||
import io.metersphere.sdk.constants.MsAssertionCondition;
|
import io.metersphere.sdk.constants.MsAssertionCondition;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
@ -135,13 +136,13 @@ public class MsHTTPElementTest {
|
|||||||
ScriptProcessor scriptProcessor = new ScriptProcessor();
|
ScriptProcessor scriptProcessor = new ScriptProcessor();
|
||||||
scriptProcessor.setEnable(true);
|
scriptProcessor.setEnable(true);
|
||||||
scriptProcessor.setScript("script");
|
scriptProcessor.setScript("script");
|
||||||
scriptProcessor.setScriptLanguage(ScriptProcessor.ScriptLanguageType.JAVASCRIPT.getValue());
|
scriptProcessor.setScriptLanguage(ScriptLanguageType.JAVASCRIPT.getValue());
|
||||||
processors.add(scriptProcessor);
|
processors.add(scriptProcessor);
|
||||||
|
|
||||||
ScriptProcessor beanShellScriptProcessor = new ScriptProcessor();
|
ScriptProcessor beanShellScriptProcessor = new ScriptProcessor();
|
||||||
beanShellScriptProcessor.setEnable(true);
|
beanShellScriptProcessor.setEnable(true);
|
||||||
beanShellScriptProcessor.setScript("script");
|
beanShellScriptProcessor.setScript("script");
|
||||||
beanShellScriptProcessor.setScriptLanguage(ScriptProcessor.ScriptLanguageType.BEANSHELL.getValue());
|
beanShellScriptProcessor.setScriptLanguage(ScriptLanguageType.BEANSHELL.getValue());
|
||||||
processors.add(beanShellScriptProcessor);
|
processors.add(beanShellScriptProcessor);
|
||||||
|
|
||||||
SQLProcessor sqlProcessor = new SQLProcessor();
|
SQLProcessor sqlProcessor = new SQLProcessor();
|
||||||
|
@ -0,0 +1,131 @@
|
|||||||
|
package io.metersphere.api.service;
|
||||||
|
|
||||||
|
import io.metersphere.project.domain.ProjectApplication;
|
||||||
|
import io.metersphere.project.domain.ProjectApplicationExample;
|
||||||
|
import io.metersphere.project.domain.ProjectTestResourcePool;
|
||||||
|
import io.metersphere.project.domain.ProjectTestResourcePoolExample;
|
||||||
|
import io.metersphere.project.mapper.ProjectApplicationMapper;
|
||||||
|
import io.metersphere.project.mapper.ProjectTestResourcePoolMapper;
|
||||||
|
import io.metersphere.sdk.constants.ProjectApplicationType;
|
||||||
|
import io.metersphere.sdk.constants.ResourcePoolTypeEnum;
|
||||||
|
import io.metersphere.sdk.util.JSON;
|
||||||
|
import io.metersphere.system.domain.TestResourcePool;
|
||||||
|
import io.metersphere.system.domain.TestResourcePoolBlob;
|
||||||
|
import io.metersphere.system.domain.TestResourcePoolOrganization;
|
||||||
|
import io.metersphere.system.domain.TestResourcePoolOrganizationExample;
|
||||||
|
import io.metersphere.system.dto.pool.TestResourceDTO;
|
||||||
|
import io.metersphere.system.dto.pool.TestResourceNodeDTO;
|
||||||
|
import io.metersphere.system.dto.pool.TestResourcePoolDTO;
|
||||||
|
import io.metersphere.system.mapper.TestResourcePoolBlobMapper;
|
||||||
|
import io.metersphere.system.mapper.TestResourcePoolMapper;
|
||||||
|
import io.metersphere.system.mapper.TestResourcePoolOrganizationMapper;
|
||||||
|
import io.metersphere.system.uid.IDGenerator;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.testcontainers.shaded.org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2023-10-20 11:32
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class BaseResourcePoolTestService {
|
||||||
|
@Resource
|
||||||
|
private ProjectApplicationMapper projectApplicationMapper;
|
||||||
|
@Resource
|
||||||
|
private TestResourcePoolOrganizationMapper testResourcePoolOrganizationMapper;
|
||||||
|
@Resource
|
||||||
|
private ProjectTestResourcePoolMapper projectTestResourcePoolMapper;
|
||||||
|
@Resource
|
||||||
|
private TestResourcePoolMapper testResourcePoolMapper;
|
||||||
|
@Resource
|
||||||
|
private TestResourcePoolBlobMapper testResourcePoolBlobMapper;
|
||||||
|
@Value("${embedded.mockserver.host}")
|
||||||
|
private String mockServerHost;
|
||||||
|
@Value("${embedded.mockserver.port}")
|
||||||
|
private int mockServerHostPort;
|
||||||
|
protected static final String DEFAULT_PROJECT_ID = "100001100001";
|
||||||
|
protected static final String DEFAULT_ORGANIZATION_ID = "100001";
|
||||||
|
|
||||||
|
public void initProjectResourcePool() {
|
||||||
|
TestResourcePool resourcePool = insertResourcePool();
|
||||||
|
insertResourcePoolOrg(resourcePool);
|
||||||
|
insertResourcePoolProject(resourcePool);
|
||||||
|
insertProjectApplication(resourcePool);
|
||||||
|
}
|
||||||
|
|
||||||
|
public TestResourcePool insertResourcePool() {
|
||||||
|
String id = IDGenerator.nextStr();
|
||||||
|
TestResourcePoolDTO testResourcePool = new TestResourcePoolDTO();
|
||||||
|
testResourcePool.setId(id);
|
||||||
|
testResourcePool.setApiTest(true);
|
||||||
|
testResourcePool.setCreateTime(System.currentTimeMillis());
|
||||||
|
testResourcePool.setUpdateTime(System.currentTimeMillis());
|
||||||
|
testResourcePool.setDeleted(false);
|
||||||
|
testResourcePool.setName("api debug test");
|
||||||
|
testResourcePool.setCreateUser("admin");
|
||||||
|
testResourcePool.setAllOrg(false);
|
||||||
|
testResourcePool.setEnable(true);
|
||||||
|
testResourcePool.setType(ResourcePoolTypeEnum.NODE.name());
|
||||||
|
TestResourcePoolBlob testResourcePoolBlob = new TestResourcePoolBlob();
|
||||||
|
testResourcePoolBlob.setId(id);
|
||||||
|
TestResourceDTO testResourceDTO = new TestResourceDTO();
|
||||||
|
TestResourceNodeDTO testResourceNodeDTO = new TestResourceNodeDTO();
|
||||||
|
testResourceNodeDTO.setIp(mockServerHost);
|
||||||
|
testResourceNodeDTO.setPort(mockServerHostPort + StringUtils.EMPTY);
|
||||||
|
testResourceNodeDTO.setConcurrentNumber(10);
|
||||||
|
testResourceDTO.setNodesList(List.of(testResourceNodeDTO));
|
||||||
|
String configuration = JSON.toJSONString(testResourceDTO);
|
||||||
|
testResourcePoolBlob.setConfiguration(configuration.getBytes());
|
||||||
|
testResourcePool.setTestResourceDTO(testResourceDTO);
|
||||||
|
|
||||||
|
testResourcePoolMapper.insert(testResourcePool);
|
||||||
|
testResourcePoolBlobMapper.insert(testResourcePoolBlob);
|
||||||
|
return testResourcePool;
|
||||||
|
}
|
||||||
|
|
||||||
|
public synchronized void insertProjectApplication(TestResourcePool resourcePool) {
|
||||||
|
ProjectApplicationExample example = new ProjectApplicationExample();
|
||||||
|
example.createCriteria().andProjectIdEqualTo(DEFAULT_PROJECT_ID)
|
||||||
|
.andTypeEqualTo(ProjectApplicationType.API.API_RESOURCE_POOL_ID.name());
|
||||||
|
if (projectApplicationMapper.countByExample(example) > 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ProjectApplication projectApplication = new ProjectApplication();
|
||||||
|
projectApplication.setTypeValue(resourcePool.getId());
|
||||||
|
projectApplication.setType(ProjectApplicationType.API.API_RESOURCE_POOL_ID.name());
|
||||||
|
projectApplication.setProjectId(DEFAULT_PROJECT_ID);
|
||||||
|
projectApplicationMapper.insert(projectApplication);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void insertResourcePoolProject(TestResourcePool resourcePool) {
|
||||||
|
ProjectTestResourcePoolExample example = new ProjectTestResourcePoolExample();
|
||||||
|
example.createCriteria().andProjectIdEqualTo(DEFAULT_PROJECT_ID);
|
||||||
|
example.createCriteria().andTestResourcePoolIdEqualTo(resourcePool.getId());
|
||||||
|
List<ProjectTestResourcePool> projectTestResourcePools = projectTestResourcePoolMapper.selectByExample(example);
|
||||||
|
if (CollectionUtils.isEmpty(projectTestResourcePools)) {
|
||||||
|
ProjectTestResourcePool projectTestResourcePool = new ProjectTestResourcePool();
|
||||||
|
projectTestResourcePool.setTestResourcePoolId(resourcePool.getId());
|
||||||
|
projectTestResourcePool.setProjectId(DEFAULT_PROJECT_ID);
|
||||||
|
projectTestResourcePoolMapper.insert(projectTestResourcePool);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void insertResourcePoolOrg(TestResourcePool resourcePool) {
|
||||||
|
TestResourcePoolOrganizationExample example = new TestResourcePoolOrganizationExample();
|
||||||
|
example.createCriteria().andOrgIdEqualTo(DEFAULT_ORGANIZATION_ID);
|
||||||
|
example.createCriteria().andTestResourcePoolIdEqualTo(resourcePool.getId());
|
||||||
|
List<TestResourcePoolOrganization> testResourcePoolOrganizations = testResourcePoolOrganizationMapper.selectByExample(example);
|
||||||
|
if (CollectionUtils.isEmpty(testResourcePoolOrganizations)) {
|
||||||
|
TestResourcePoolOrganization resourcePoolOrganization = new TestResourcePoolOrganization();
|
||||||
|
resourcePoolOrganization.setTestResourcePoolId(resourcePool.getId());
|
||||||
|
resourcePoolOrganization.setOrgId(DEFAULT_ORGANIZATION_ID);
|
||||||
|
resourcePoolOrganization.setId(IDGenerator.nextStr());
|
||||||
|
testResourcePoolOrganizationMapper.insert(resourcePoolOrganization);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
package io.metersphere.api.service;
|
package io.metersphere.api.service;
|
||||||
|
|
||||||
import io.metersphere.api.dto.NodeDTO;
|
|
||||||
import io.metersphere.sdk.util.LogUtils;
|
import io.metersphere.sdk.util.LogUtils;
|
||||||
|
import io.metersphere.system.dto.pool.TestResourceNodeDTO;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import org.junit.jupiter.api.MethodOrderer;
|
import org.junit.jupiter.api.MethodOrderer;
|
||||||
import org.junit.jupiter.api.Order;
|
import org.junit.jupiter.api.Order;
|
||||||
@ -24,11 +24,11 @@ public class RoundRobinServiceTests {
|
|||||||
@Test
|
@Test
|
||||||
@Order(1)
|
@Order(1)
|
||||||
public void testInit() throws Exception {
|
public void testInit() throws Exception {
|
||||||
List<NodeDTO> nodes = new LinkedList<>();
|
List<TestResourceNodeDTO> nodes = new LinkedList<>();
|
||||||
nodes.add(new NodeDTO("172.0.0.1", "8080", 10));
|
nodes.add(new TestResourceNodeDTO("172.0.0.1", "8080", null, 10));
|
||||||
nodes.add(new NodeDTO("172.0.0.2", "8080", 10));
|
nodes.add(new TestResourceNodeDTO("172.0.0.2", "8080", null, 10));
|
||||||
nodes.add(new NodeDTO("172.0.0.3", "8080", 10));
|
nodes.add(new TestResourceNodeDTO("172.0.0.3", "8080", null, 10));
|
||||||
nodes.add(new NodeDTO("172.0.0.4", "8080", 10));
|
nodes.add(new TestResourceNodeDTO("172.0.0.4", "8080", null, 10));
|
||||||
|
|
||||||
roundRobinService.initializeNodes("test", nodes);
|
roundRobinService.initializeNodes("test", nodes);
|
||||||
}
|
}
|
||||||
@ -48,15 +48,15 @@ public class RoundRobinServiceTests {
|
|||||||
@Test
|
@Test
|
||||||
@Order(3)
|
@Order(3)
|
||||||
public void testInitAfter() throws Exception {
|
public void testInitAfter() throws Exception {
|
||||||
List<NodeDTO> nodes = new LinkedList<>();
|
List<TestResourceNodeDTO> nodes = new LinkedList<>();
|
||||||
nodes.add(new NodeDTO("172.0.0.1", "8080", 10));
|
nodes.add(new TestResourceNodeDTO("172.0.0.1", "8080", null, 10));
|
||||||
nodes.add(new NodeDTO("172.0.0.2", "8080", 10));
|
nodes.add(new TestResourceNodeDTO("172.0.0.2", "8080", null, 10));
|
||||||
nodes.add(new NodeDTO("172.0.0.3", "8080", 10));
|
nodes.add(new TestResourceNodeDTO("172.0.0.3", "8080", null, 10));
|
||||||
roundRobinService.initializeNodes("test", nodes);
|
roundRobinService.initializeNodes("test", nodes);
|
||||||
|
|
||||||
nodes.add(new NodeDTO("172.0.0.3", "8080", 10));
|
nodes.add(new TestResourceNodeDTO("172.0.0.3", "8080", null, 10));
|
||||||
nodes.add(new NodeDTO("172.0.0.7", "8080", 10));
|
nodes.add(new TestResourceNodeDTO("172.0.0.7", "8080", null, 10));
|
||||||
nodes.add(new NodeDTO("172.0.0.6", "8080", 10));
|
nodes.add(new TestResourceNodeDTO("172.0.0.6", "8080", null, 10));
|
||||||
roundRobinService.initializeNodes("test", nodes);
|
roundRobinService.initializeNodes("test", nodes);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,23 @@
|
|||||||
|
package io.metersphere.project.constants;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author: jianxing
|
||||||
|
* @CreateTime: 2024-01-19 18:19
|
||||||
|
*/
|
||||||
|
public enum ScriptLanguageType {
|
||||||
|
BEANSHELL("beanshell"),
|
||||||
|
BEANSHELL_JSR233("beanshell-jsr233"),
|
||||||
|
GROOVY("groovy"),
|
||||||
|
JAVASCRIPT("javascript"),
|
||||||
|
PYTHON("python");
|
||||||
|
|
||||||
|
private String value;
|
||||||
|
|
||||||
|
ScriptLanguageType(String value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
@ -91,6 +91,4 @@ public class CustomFunctionController {
|
|||||||
public void delete(@PathVariable String id) {
|
public void delete(@PathVariable String id) {
|
||||||
customFunctionService.delete(id);
|
customFunctionService.delete(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,34 @@
|
|||||||
|
package io.metersphere.project.dto.customfunction.request;
|
||||||
|
|
||||||
|
import io.metersphere.project.dto.environment.KeyValueParam;
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import jakarta.validation.constraints.NotBlank;
|
||||||
|
import jakarta.validation.constraints.Size;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serial;
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class CustomFunctionRunRequest implements Serializable {
|
||||||
|
@Serial
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Schema(description = "脚本语言类型")
|
||||||
|
@NotBlank
|
||||||
|
@Size(max = 50)
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
@Schema(description = "参数列表")
|
||||||
|
private List<KeyValueParam> params;
|
||||||
|
|
||||||
|
@Schema(description = "函数体")
|
||||||
|
@NotBlank
|
||||||
|
private String script;
|
||||||
|
|
||||||
|
@Schema(description = "项目ID")
|
||||||
|
@NotBlank
|
||||||
|
@Size(max = 50)
|
||||||
|
private String projectId;
|
||||||
|
}
|
@ -16,7 +16,7 @@ public class ScriptProcessor extends MsProcessor {
|
|||||||
/**
|
/**
|
||||||
* 脚本语言
|
* 脚本语言
|
||||||
*
|
*
|
||||||
* @see ScriptLanguageType
|
* @see io.metersphere.project.constants.ScriptLanguageType
|
||||||
*/
|
*/
|
||||||
private String scriptLanguage;
|
private String scriptLanguage;
|
||||||
/**
|
/**
|
||||||
@ -31,22 +31,4 @@ public class ScriptProcessor extends MsProcessor {
|
|||||||
* 公共脚本入参
|
* 公共脚本入参
|
||||||
*/
|
*/
|
||||||
private List<KeyValueParam> params;
|
private List<KeyValueParam> params;
|
||||||
|
|
||||||
public enum ScriptLanguageType {
|
|
||||||
BEANSHELL("beanshell"),
|
|
||||||
BEANSHELL_JSR233("beanshell-JSR233"),
|
|
||||||
GROOVY("groovy"),
|
|
||||||
JAVASCRIPT("javascript"),
|
|
||||||
PYTHON("python");
|
|
||||||
|
|
||||||
private String value;
|
|
||||||
|
|
||||||
ScriptLanguageType(String value) {
|
|
||||||
this.value = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getValue() {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -225,6 +225,28 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"id": "PROJECT_CUSTOM_FUNCTION",
|
||||||
|
"name": "permission.project_custom_function.name",
|
||||||
|
"permissions": [
|
||||||
|
{
|
||||||
|
"id": "PROJECT_CUSTOM_FUNCTION:READ"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PROJECT_CUSTOM_FUNCTION:READ+ADD"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PROJECT_CUSTOM_FUNCTION:READ+UPDATE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PROJECT_CUSTOM_FUNCTION:READ+DELETE"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "PROJECT_CUSTOM_FUNCTION:READ+EXECUTE",
|
||||||
|
"name": "permission.project_custom_function.execute"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"id": "PROJECT_LOG",
|
"id": "PROJECT_LOG",
|
||||||
"name": "permission.project_log.name",
|
"name": "permission.project_log.name",
|
||||||
|
@ -1,11 +1,15 @@
|
|||||||
package io.metersphere.system.dto.pool;
|
package io.metersphere.system.dto.pool;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
|
||||||
@Getter
|
@Getter
|
||||||
@Setter
|
@Setter
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
public class TestResourceNodeDTO {
|
public class TestResourceNodeDTO {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -136,18 +136,22 @@ public class PluginControllerTests extends BaseTest {
|
|||||||
Assertions.assertEquals(Arrays.asList("connect", "disconnect", "pub", "sub"), getScriptIdsByPlugId(plugin.getId()));
|
Assertions.assertEquals(Arrays.asList("connect", "disconnect", "pub", "sub"), getScriptIdsByPlugId(plugin.getId()));
|
||||||
addPlugin = plugin;
|
addPlugin = plugin;
|
||||||
|
|
||||||
// 模拟其他节点加载插件
|
try {
|
||||||
unloadAndDeletePlugin(jarFile, plugin);
|
// 模拟其他节点加载插件
|
||||||
pluginLoadService.handlePluginAddNotified(plugin.getId(), jarFile.getName());
|
unloadAndDeletePlugin(jarFile, plugin);
|
||||||
|
pluginLoadService.handlePluginAddNotified(plugin.getId(), jarFile.getName());
|
||||||
|
|
||||||
// 增加覆盖率
|
// 增加覆盖率
|
||||||
unloadAndDeletePlugin(jarFile, plugin);
|
unloadAndDeletePlugin(jarFile, plugin);
|
||||||
pluginLoadService.loadPlugin(jarFile.getName());
|
pluginLoadService.loadPlugin(jarFile.getName());
|
||||||
|
|
||||||
unloadAndDeletePlugin(jarFile, plugin);
|
unloadAndDeletePlugin(jarFile, plugin);
|
||||||
pluginLoadService.loadPlugins();
|
pluginLoadService.loadPlugins();
|
||||||
|
|
||||||
pluginLoadService.getExtensions(Platform.class);
|
pluginLoadService.getExtensions(Platform.class);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
// 增加覆盖率
|
// 增加覆盖率
|
||||||
this.requestGetWithOkAndReturn(DEFAULT_LIST);
|
this.requestGetWithOkAndReturn(DEFAULT_LIST);
|
||||||
|
Loading…
Reference in New Issue
Block a user