This commit is contained in:
chenjianxing 2020-04-01 16:18:55 +08:00
commit 810927feb9
28 changed files with 295 additions and 358 deletions

View File

@ -9,16 +9,12 @@ public class LoadTestReport implements Serializable {
private String name;
private String description;
private Long createTime;
private Long updateTime;
private String status;
private String content;
private static final long serialVersionUID = 1L;
public String getId() {
@ -45,14 +41,6 @@ public class LoadTestReport implements Serializable {
this.name = name == null ? null : name.trim();
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description == null ? null : description.trim();
}
public Long getCreateTime() {
return createTime;
}
@ -76,12 +64,4 @@ public class LoadTestReport implements Serializable {
public void setStatus(String status) {
this.status = status == null ? null : status.trim();
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content == null ? null : content.trim();
}
}

View File

@ -314,76 +314,6 @@ public class LoadTestReportExample {
return (Criteria) this;
}
public Criteria andDescriptionIsNull() {
addCriterion("description is null");
return (Criteria) this;
}
public Criteria andDescriptionIsNotNull() {
addCriterion("description is not null");
return (Criteria) this;
}
public Criteria andDescriptionEqualTo(String value) {
addCriterion("description =", value, "description");
return (Criteria) this;
}
public Criteria andDescriptionNotEqualTo(String value) {
addCriterion("description <>", value, "description");
return (Criteria) this;
}
public Criteria andDescriptionGreaterThan(String value) {
addCriterion("description >", value, "description");
return (Criteria) this;
}
public Criteria andDescriptionGreaterThanOrEqualTo(String value) {
addCriterion("description >=", value, "description");
return (Criteria) this;
}
public Criteria andDescriptionLessThan(String value) {
addCriterion("description <", value, "description");
return (Criteria) this;
}
public Criteria andDescriptionLessThanOrEqualTo(String value) {
addCriterion("description <=", value, "description");
return (Criteria) this;
}
public Criteria andDescriptionLike(String value) {
addCriterion("description like", value, "description");
return (Criteria) this;
}
public Criteria andDescriptionNotLike(String value) {
addCriterion("description not like", value, "description");
return (Criteria) this;
}
public Criteria andDescriptionIn(List<String> values) {
addCriterion("description in", values, "description");
return (Criteria) this;
}
public Criteria andDescriptionNotIn(List<String> values) {
addCriterion("description not in", values, "description");
return (Criteria) this;
}
public Criteria andDescriptionBetween(String value1, String value2) {
addCriterion("description between", value1, value2, "description");
return (Criteria) this;
}
public Criteria andDescriptionNotBetween(String value1, String value2) {
addCriterion("description not between", value1, value2, "description");
return (Criteria) this;
}
public Criteria andCreateTimeIsNull() {
addCriterion("create_time is null");
return (Criteria) this;

View File

@ -0,0 +1,27 @@
package io.metersphere.base.domain;
import java.io.Serializable;
public class LoadTestReportWithBLOBs extends LoadTestReport implements Serializable {
private String description;
private String content;
private static final long serialVersionUID = 1L;
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description == null ? null : description.trim();
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content == null ? null : content.trim();
}
}

View File

@ -2,6 +2,7 @@ package io.metersphere.base.mapper;
import io.metersphere.base.domain.LoadTestReport;
import io.metersphere.base.domain.LoadTestReportExample;
import io.metersphere.base.domain.LoadTestReportWithBLOBs;
import org.apache.ibatis.annotations.Param;
import java.util.List;
@ -13,25 +14,25 @@ public interface LoadTestReportMapper {
int deleteByPrimaryKey(String id);
int insert(LoadTestReport record);
int insert(LoadTestReportWithBLOBs record);
int insertSelective(LoadTestReport record);
int insertSelective(LoadTestReportWithBLOBs record);
List<LoadTestReport> selectByExampleWithBLOBs(LoadTestReportExample example);
List<LoadTestReportWithBLOBs> selectByExampleWithBLOBs(LoadTestReportExample example);
List<LoadTestReport> selectByExample(LoadTestReportExample example);
LoadTestReport selectByPrimaryKey(String id);
LoadTestReportWithBLOBs selectByPrimaryKey(String id);
int updateByExampleSelective(@Param("record") LoadTestReport record, @Param("example") LoadTestReportExample example);
int updateByExampleSelective(@Param("record") LoadTestReportWithBLOBs record, @Param("example") LoadTestReportExample example);
int updateByExampleWithBLOBs(@Param("record") LoadTestReport record, @Param("example") LoadTestReportExample example);
int updateByExampleWithBLOBs(@Param("record") LoadTestReportWithBLOBs record, @Param("example") LoadTestReportExample example);
int updateByExample(@Param("record") LoadTestReport record, @Param("example") LoadTestReportExample example);
int updateByPrimaryKeySelective(LoadTestReport record);
int updateByPrimaryKeySelective(LoadTestReportWithBLOBs record);
int updateByPrimaryKeyWithBLOBs(LoadTestReport record);
int updateByPrimaryKeyWithBLOBs(LoadTestReportWithBLOBs record);
int updateByPrimaryKey(LoadTestReport record);
}

View File

@ -5,12 +5,12 @@
<id column="id" jdbcType="VARCHAR" property="id" />
<result column="test_id" jdbcType="VARCHAR" property="testId" />
<result column="name" jdbcType="VARCHAR" property="name" />
<result column="description" jdbcType="VARCHAR" property="description" />
<result column="create_time" jdbcType="BIGINT" property="createTime" />
<result column="update_time" jdbcType="BIGINT" property="updateTime" />
<result column="status" jdbcType="VARCHAR" property="status" />
</resultMap>
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="io.metersphere.base.domain.LoadTestReport">
<resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="io.metersphere.base.domain.LoadTestReportWithBLOBs">
<result column="description" jdbcType="LONGVARCHAR" property="description" />
<result column="content" jdbcType="LONGVARCHAR" property="content" />
</resultMap>
<sql id="Example_Where_Clause">
@ -72,10 +72,10 @@
</where>
</sql>
<sql id="Base_Column_List">
id, test_id, name, description, create_time, update_time, status
id, test_id, name, create_time, update_time, status
</sql>
<sql id="Blob_Column_List">
content
description, content
</sql>
<select id="selectByExampleWithBLOBs" parameterType="io.metersphere.base.domain.LoadTestReportExample" resultMap="ResultMapWithBLOBs">
select
@ -125,15 +125,15 @@
<include refid="Example_Where_Clause" />
</if>
</delete>
<insert id="insert" parameterType="io.metersphere.base.domain.LoadTestReport">
<insert id="insert" parameterType="io.metersphere.base.domain.LoadTestReportWithBLOBs">
insert into load_test_report (id, test_id, name,
description, create_time, update_time,
status, content)
create_time, update_time, status,
description, content)
values (#{id,jdbcType=VARCHAR}, #{testId,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR},
#{description,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT},
#{status,jdbcType=VARCHAR}, #{content,jdbcType=LONGVARCHAR})
#{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT}, #{status,jdbcType=VARCHAR},
#{description,jdbcType=LONGVARCHAR}, #{content,jdbcType=LONGVARCHAR})
</insert>
<insert id="insertSelective" parameterType="io.metersphere.base.domain.LoadTestReport">
<insert id="insertSelective" parameterType="io.metersphere.base.domain.LoadTestReportWithBLOBs">
insert into load_test_report
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">
@ -145,9 +145,6 @@
<if test="name != null">
name,
</if>
<if test="description != null">
description,
</if>
<if test="createTime != null">
create_time,
</if>
@ -157,6 +154,9 @@
<if test="status != null">
status,
</if>
<if test="description != null">
description,
</if>
<if test="content != null">
content,
</if>
@ -171,9 +171,6 @@
<if test="name != null">
#{name,jdbcType=VARCHAR},
</if>
<if test="description != null">
#{description,jdbcType=VARCHAR},
</if>
<if test="createTime != null">
#{createTime,jdbcType=BIGINT},
</if>
@ -183,6 +180,9 @@
<if test="status != null">
#{status,jdbcType=VARCHAR},
</if>
<if test="description != null">
#{description,jdbcType=LONGVARCHAR},
</if>
<if test="content != null">
#{content,jdbcType=LONGVARCHAR},
</if>
@ -206,9 +206,6 @@
<if test="record.name != null">
name = #{record.name,jdbcType=VARCHAR},
</if>
<if test="record.description != null">
description = #{record.description,jdbcType=VARCHAR},
</if>
<if test="record.createTime != null">
create_time = #{record.createTime,jdbcType=BIGINT},
</if>
@ -218,6 +215,9 @@
<if test="record.status != null">
status = #{record.status,jdbcType=VARCHAR},
</if>
<if test="record.description != null">
description = #{record.description,jdbcType=LONGVARCHAR},
</if>
<if test="record.content != null">
content = #{record.content,jdbcType=LONGVARCHAR},
</if>
@ -231,10 +231,10 @@
set id = #{record.id,jdbcType=VARCHAR},
test_id = #{record.testId,jdbcType=VARCHAR},
name = #{record.name,jdbcType=VARCHAR},
description = #{record.description,jdbcType=VARCHAR},
create_time = #{record.createTime,jdbcType=BIGINT},
update_time = #{record.updateTime,jdbcType=BIGINT},
status = #{record.status,jdbcType=VARCHAR},
description = #{record.description,jdbcType=LONGVARCHAR},
content = #{record.content,jdbcType=LONGVARCHAR}
<if test="_parameter != null">
<include refid="Update_By_Example_Where_Clause" />
@ -245,7 +245,6 @@
set id = #{record.id,jdbcType=VARCHAR},
test_id = #{record.testId,jdbcType=VARCHAR},
name = #{record.name,jdbcType=VARCHAR},
description = #{record.description,jdbcType=VARCHAR},
create_time = #{record.createTime,jdbcType=BIGINT},
update_time = #{record.updateTime,jdbcType=BIGINT},
status = #{record.status,jdbcType=VARCHAR}
@ -253,7 +252,7 @@
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
<update id="updateByPrimaryKeySelective" parameterType="io.metersphere.base.domain.LoadTestReport">
<update id="updateByPrimaryKeySelective" parameterType="io.metersphere.base.domain.LoadTestReportWithBLOBs">
update load_test_report
<set>
<if test="testId != null">
@ -262,9 +261,6 @@
<if test="name != null">
name = #{name,jdbcType=VARCHAR},
</if>
<if test="description != null">
description = #{description,jdbcType=VARCHAR},
</if>
<if test="createTime != null">
create_time = #{createTime,jdbcType=BIGINT},
</if>
@ -274,20 +270,23 @@
<if test="status != null">
status = #{status,jdbcType=VARCHAR},
</if>
<if test="description != null">
description = #{description,jdbcType=LONGVARCHAR},
</if>
<if test="content != null">
content = #{content,jdbcType=LONGVARCHAR},
</if>
</set>
where id = #{id,jdbcType=VARCHAR}
</update>
<update id="updateByPrimaryKeyWithBLOBs" parameterType="io.metersphere.base.domain.LoadTestReport">
<update id="updateByPrimaryKeyWithBLOBs" parameterType="io.metersphere.base.domain.LoadTestReportWithBLOBs">
update load_test_report
set test_id = #{testId,jdbcType=VARCHAR},
name = #{name,jdbcType=VARCHAR},
description = #{description,jdbcType=VARCHAR},
create_time = #{createTime,jdbcType=BIGINT},
update_time = #{updateTime,jdbcType=BIGINT},
status = #{status,jdbcType=VARCHAR},
description = #{description,jdbcType=LONGVARCHAR},
content = #{content,jdbcType=LONGVARCHAR}
where id = #{id,jdbcType=VARCHAR}
</update>
@ -295,7 +294,6 @@
update load_test_report
set test_id = #{testId,jdbcType=VARCHAR},
name = #{name,jdbcType=VARCHAR},
description = #{description,jdbcType=VARCHAR},
create_time = #{createTime,jdbcType=BIGINT},
update_time = #{updateTime,jdbcType=BIGINT},
status = #{status,jdbcType=VARCHAR}

View File

@ -8,7 +8,9 @@ import java.util.List;
public interface ExtLoadTestReportMapper {
List<ReportDTO> getReportList(@Param("reportRequest")ReportRequest request);
List<ReportDTO> getReportList(@Param("reportRequest") ReportRequest request);
ReportDTO getReportTestAndProInfo(@Param("id") String id);
int appendLine(@Param("testId") String id, @Param("line") String line);
}

View File

@ -11,6 +11,7 @@
AND ltr.name like CONCAT('%', #{reportRequest.name},'%')
</if>
</where>
ORDER BY ltr.update_time DESC
</select>
<select id="getReportTestAndProInfo" resultType="io.metersphere.dto.ReportDTO">
@ -21,4 +22,10 @@
where ltr.id = #{id}
</select>
<update id="appendLine">
UPDATE load_test_report
SET content = concat(content, #{line})
WHERE id = #{testId}
</update>
</mapper>

View File

@ -1,5 +1,5 @@
package io.metersphere.commons.constants;
public enum TestStatus {
Running, Completed
Starting, Running, Completed, Error
}

View File

@ -8,6 +8,7 @@ import io.metersphere.commons.utils.PageUtils;
import io.metersphere.commons.utils.Pager;
import io.metersphere.controller.request.ReportRequest;
import io.metersphere.dto.ReportDTO;
import io.metersphere.report.base.ChartsData;
import io.metersphere.report.base.Errors;
import io.metersphere.report.base.TestOverview;
import io.metersphere.report.dto.ErrorsTop5DTO;
@ -76,5 +77,9 @@ public class ReportController {
return reportService.getTestOverview(reportId);
}
@GetMapping("/content/load_chart/{reportId}")
public ChartsData getLoadChartData(@PathVariable String reportId) {
return reportService.getLoadChartData(reportId);
}
}

View File

@ -17,10 +17,14 @@ import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import java.util.List;
import java.util.UUID;
public abstract class AbstractEngine implements Engine {
public static final String REGISTRY = "registry.fit2cloud.com/metersphere/";
public static final String JMETER_IMAGE = "jmeter-master:0.0.2";
private Long startTime;
private String reportId;
protected LoadTestWithBLOBs loadTest;
protected LoadTestService loadTestService;
protected Integer threadNum;
@ -32,6 +36,8 @@ public abstract class AbstractEngine implements Engine {
public AbstractEngine() {
testResourcePoolService = CommonBeanFactory.getBean(TestResourcePoolService.class);
testResourceService = CommonBeanFactory.getBean(TestResourceService.class);
this.startTime = System.currentTimeMillis();
this.reportId = UUID.randomUUID().toString();
}
protected void init(LoadTestWithBLOBs loadTest) {
@ -82,4 +88,14 @@ public abstract class AbstractEngine implements Engine {
}
return s;
}
@Override
public Long getStartTime() {
return startTime;
}
@Override
public String getReportId() {
return reportId;
}
}

View File

@ -1,6 +1,9 @@
package io.metersphere.engine;
public interface Engine {
Long getStartTime();
String getReportId();
void start();

View File

@ -11,6 +11,8 @@ public class EngineContext {
private String content;
private String resourcePoolId;
private Long threadNum;
private Long startTime;
private String reportId;
private Map<String, Object> properties = new HashMap<>();
private Map<String, String> testData = new HashMap<>();
@ -89,4 +91,20 @@ public class EngineContext {
public void setThreadNum(Long threadNum) {
this.threadNum = threadNum;
}
public Long getStartTime() {
return startTime;
}
public void setStartTime(Long startTime) {
this.startTime = startTime;
}
public String getReportId() {
return reportId;
}
public void setReportId(String reportId) {
this.reportId = reportId;
}
}

View File

@ -54,7 +54,7 @@ public class EngineFactory {
return null;
}
public static EngineContext createContext(LoadTestWithBLOBs loadTest, long threadNum) throws Exception {
public static EngineContext createContext(LoadTestWithBLOBs loadTest, long threadNum, long startTime, String reportId) throws Exception {
final List<FileMetadata> fileMetadataList = fileService.getFileMetadataByTestId(loadTest.getId());
if (org.springframework.util.CollectionUtils.isEmpty(fileMetadataList)) {
MSException.throwException(Translator.get("run_load_test_file_not_found") + loadTest.getId());
@ -76,6 +76,8 @@ public class EngineFactory {
engineContext.setFileType(jmxFile.getType());
engineContext.setThreadNum(threadNum);
engineContext.setResourcePoolId(loadTest.getTestResourcePoolId());
engineContext.setStartTime(startTime);
engineContext.setReportId(reportId);
if (StringUtils.isNotEmpty(loadTest.getLoadConfiguration())) {
final JSONArray jsonArray = JSONObject.parseArray(loadTest.getLoadConfiguration());

View File

@ -10,9 +10,8 @@ import io.metersphere.dto.NodeDTO;
import io.metersphere.engine.AbstractEngine;
import io.metersphere.engine.EngineContext;
import io.metersphere.engine.EngineFactory;
import io.metersphere.engine.docker.request.DockerLoginRequest;
import io.metersphere.engine.docker.request.BaseRequest;
import io.metersphere.engine.docker.request.TestRequest;
import io.metersphere.engine.kubernetes.registry.RegistryService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.client.RestTemplate;
@ -22,9 +21,7 @@ import java.util.stream.Collectors;
public class DockerTestEngine extends AbstractEngine {
private static final String BASE_URL = "http://%s:%d";
private RestTemplate restTemplate;
private RegistryService registryService;
public DockerTestEngine(LoadTestWithBLOBs loadTest) {
this.init(loadTest);
@ -34,7 +31,6 @@ public class DockerTestEngine extends AbstractEngine {
protected void init(LoadTestWithBLOBs loadTest) {
super.init(loadTest);
this.restTemplate = CommonBeanFactory.getBean(RestTemplate.class);
this.registryService = CommonBeanFactory.getBean(RegistryService.class);
// todo 初始化操作
}
@ -66,7 +62,7 @@ public class DockerTestEngine extends AbstractEngine {
// todo 运行测试
EngineContext context = null;
try {
context = EngineFactory.createContext(loadTest, realThreadNum);
context = EngineFactory.createContext(loadTest, realThreadNum, this.getStartTime(), this.getReportId());
} catch (Exception e) {
MSException.throwException(e);
}
@ -84,11 +80,9 @@ public class DockerTestEngine extends AbstractEngine {
testRequest.setSize(1);
testRequest.setTestId(testId);
testRequest.setFileString(content);
testRequest.setImage(registryService.getRegistry() + JMETER_IMAGE);
testRequest.setImage(REGISTRY + JMETER_IMAGE);
testRequest.setTestData(context.getTestData());
testRequest.setRegistry(registryService.getRegistryUrl());
testRequest.setPassword(registryService.getRegistryPassword());
testRequest.setUsername(registryService.getRegistryUsername());
// todo 判断测试状态
String taskStatusUri = String.format(BASE_URL + "/jmeter/task/status/" + testId, nodeIp, port);
List containerList = restTemplate.postForObject(taskStatusUri, testRequest, List.class);
@ -106,7 +100,7 @@ public class DockerTestEngine extends AbstractEngine {
public void stop() {
// TODO 停止运行测试
String testId = loadTest.getId();
DockerLoginRequest request = new DockerLoginRequest();
BaseRequest request = new BaseRequest();
this.resourceList.forEach(r -> {
NodeDTO node = JSON.parseObject(r.getConfiguration(), NodeDTO.class);
String ip = node.getIp();

View File

@ -0,0 +1,5 @@
package io.metersphere.engine.docker.request;
public class BaseRequest {
}

View File

@ -1,31 +0,0 @@
package io.metersphere.engine.docker.request;
public class DockerLoginRequest {
private String username;
private String password;
private String registry;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getRegistry() {
return registry;
}
public void setRegistry(String registry) {
this.registry = registry;
}
}

View File

@ -3,7 +3,7 @@ package io.metersphere.engine.docker.request;
import java.util.HashMap;
import java.util.Map;
public class TestRequest extends DockerLoginRequest {
public class TestRequest extends BaseRequest {
private int size;
private String fileString;

View File

@ -7,7 +7,6 @@ import io.fabric8.kubernetes.client.KubernetesClient;
import io.metersphere.base.domain.LoadTestWithBLOBs;
import io.metersphere.commons.constants.FileType;
import io.metersphere.commons.exception.MSException;
import io.metersphere.commons.utils.CommonBeanFactory;
import io.metersphere.commons.utils.LogUtil;
import io.metersphere.engine.AbstractEngine;
import io.metersphere.engine.EngineContext;
@ -16,14 +15,12 @@ import io.metersphere.engine.kubernetes.crds.jmeter.Jmeter;
import io.metersphere.engine.kubernetes.crds.jmeter.JmeterSpec;
import io.metersphere.engine.kubernetes.provider.ClientCredential;
import io.metersphere.engine.kubernetes.provider.KubernetesProvider;
import io.metersphere.engine.kubernetes.registry.RegistryService;
import org.apache.commons.collections.MapUtils;
import java.util.HashMap;
public class KubernetesTestEngine extends AbstractEngine {
private RegistryService registryService;
public KubernetesTestEngine(LoadTestWithBLOBs loadTest) {
this.init(loadTest);
@ -32,7 +29,6 @@ public class KubernetesTestEngine extends AbstractEngine {
@Override
public void init(LoadTestWithBLOBs loadTest) {
super.init(loadTest);
this.registryService = CommonBeanFactory.getBean(RegistryService.class);
}
@ -50,7 +46,7 @@ public class KubernetesTestEngine extends AbstractEngine {
MSException.throwException("Insufficient resources");
}
try {
EngineContext context = EngineFactory.createContext(loadTest, threadNum);
EngineContext context = EngineFactory.createContext(loadTest, threadNum, this.getStartTime(), this.getReportId());
runTest(context, clientCredential);
} catch (Exception e) {
MSException.throwException(e);
@ -63,8 +59,6 @@ public class KubernetesTestEngine extends AbstractEngine {
// create namespace
kubernetesProvider.confirmNamespace(context.getNamespace());
// docker registry
registryService.dockerRegistry(kubernetesProvider, context.getNamespace());
// create cm
try (KubernetesClient client = kubernetesProvider.getKubernetesClient()) {
String configMapName = context.getTestId() + "-files";
@ -93,7 +87,7 @@ public class KubernetesTestEngine extends AbstractEngine {
}});
jmeter.setSpec(new JmeterSpec() {{
setReplicas(1);
setImage(registryService.getRegistry() + JMETER_IMAGE);
setImage(REGISTRY + JMETER_IMAGE);
}});
LogUtil.info("Load test started. " + context.getTestId());
kubernetesProvider.applyCustomResource(jmeter);
@ -117,7 +111,7 @@ public class KubernetesTestEngine extends AbstractEngine {
}});
jmeter.setSpec(new JmeterSpec() {{
setReplicas(1);
setImage(registryService.getRegistry() + JMETER_IMAGE);
setImage(REGISTRY + JMETER_IMAGE);
}});
provider.deleteCustomResource(jmeter);
} catch (Exception e) {

View File

@ -1,94 +0,0 @@
package io.metersphere.engine.kubernetes.registry;
import io.metersphere.base.domain.SystemParameter;
import io.metersphere.base.domain.SystemParameterExample;
import io.metersphere.base.mapper.SystemParameterMapper;
import io.metersphere.commons.constants.ParamConstants;
import io.metersphere.commons.utils.EncryptUtils;
import io.metersphere.engine.kubernetes.provider.AbstractClientProvider;
import io.metersphere.engine.kubernetes.provider.DockerRegistry;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@Service
public class RegistryService {
@Resource
private SystemParameterMapper parameterMapper;
/**
* 获取镜像仓库地址
* 地址+项目
*
* @return eg: registry.demo.com/demo/
*/
public String getRegistry() {
StringBuilder sb = new StringBuilder();
Map<String, String> paramMap = getRegistryInfo();
String url = paramMap.getOrDefault(ParamConstants.Registry.URL.getValue(), "");
String project = paramMap.getOrDefault(ParamConstants.Registry.REPO.getValue(), "");
if (url.startsWith("http://") || url.startsWith("https://")) {
url = url.replace("http://", "");
url = url.replace("https://", "");
}
sb.append(url);
if (!url.endsWith("/")) {
sb.append("/");
}
if (StringUtils.isNotEmpty(project)) {
sb.append(project);
sb.append("/");
}
return sb.toString();
}
public String getRegistryUrl() {
Map<String, String> paramMap = getRegistryInfo();
String url = paramMap.get(ParamConstants.Registry.URL.getValue());
if (url.startsWith("http://") || url.startsWith("https://")) {
url = url.replace("http://", "");
url = url.replace("https://", "");
}
return url;
}
public String getRegistryUsername() {
Map<String, String> paramMap = getRegistryInfo();
return paramMap.get(ParamConstants.Registry.USERNAME.getValue());
}
public String getRegistryPassword() {
Map<String, String> paramMap = getRegistryInfo();
return paramMap.get(ParamConstants.Registry.PASSWORD.getValue());
}
public void dockerRegistry(AbstractClientProvider clientProvider, String namespace) {
DockerRegistry registry = new DockerRegistry();
registry.setUrl(this.getRegistryUrl());
registry.setUsername(this.getRegistryUsername());
registry.setPassword(this.getRegistryPassword());
registry.setNamespace(namespace);
clientProvider.dockerRegistry(registry);
}
private Map<String, String> getRegistryInfo() {
Map<String, String> map = new HashMap<>();
SystemParameterExample example = new SystemParameterExample();
example.createCriteria().andParamKeyLike(ParamConstants.Classify.REGISTRY.getValue() + "%");
List<SystemParameter> parameters = parameterMapper.selectByExample(example);
for (SystemParameter parameter : parameters) {
if (StringUtils.equalsIgnoreCase(ParamConstants.Type.PASSWORD.getValue(), parameter.getType())) {
parameter.setParamValue(EncryptUtils.aesDecrypt(parameter.getParamValue()).toString());
}
parameters.forEach(param -> map.put(param.getParamKey(), param.getParamValue()));
}
return map;
}
}

View File

@ -567,10 +567,11 @@ public class JmeterDocumentParser implements DocumentParser {
collectionProp.appendChild(createKafkaProp(document, "kafka.batch.size", kafkaProperties.getBatchSize()));
collectionProp.appendChild(createKafkaProp(document, "kafka.client.id", kafkaProperties.getClientId()));
collectionProp.appendChild(createKafkaProp(document, "kafka.connections.max.idle.ms", kafkaProperties.getConnectionsMaxIdleMs()));
// 添加关联关系 test.id test.name test.startTime
// 添加关联关系 test.id test.name test.startTime test.reportId
collectionProp.appendChild(createKafkaProp(document, "test.id", context.getTestId()));
collectionProp.appendChild(createKafkaProp(document, "test.name", context.getTestName()));
collectionProp.appendChild(createKafkaProp(document, "test.startTime", "" + System.currentTimeMillis()));
collectionProp.appendChild(createKafkaProp(document, "test.startTime", context.getStartTime().toString()));
collectionProp.appendChild(createKafkaProp(document, "test.reportId", context.getReportId()));
elementProp.appendChild(collectionProp);
// set elementProp

View File

@ -294,8 +294,8 @@ public class JtlResolver {
List<String> hits = new ArrayList<>();
List<String> erorrs = new ArrayList<>();
List<String> timeList = new ArrayList<>();
////
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//// todo SimpleDateFormat
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
DecimalFormat df = new DecimalFormat("0.0");
total.sort(Comparator.comparing(metric -> Long.valueOf(metric.getTimestamp())));
@ -310,8 +310,8 @@ public class JtlResolver {
public int compare(Map.Entry<String, List<Metric>> t1, Map.Entry<String, List<Metric>> t2) {
Date date1 = null,date2 = null;
try {
date1 = sdf.parse(t1.getKey());
date2 = sdf.parse(t2.getKey());
date1 = simpleDateFormat.parse(t1.getKey());
date2 = simpleDateFormat.parse(t2.getKey());
} catch (ParseException e) {
e.printStackTrace();
}
@ -323,6 +323,8 @@ public class JtlResolver {
int failSize = 0;
Map.Entry<String, List<Metric>> map = entries.get(i);
List<Metric> metrics = map.getValue();
Map<String, List<Metric>> metricsMap = metrics.stream().collect(Collectors.groupingBy(Metric::getThreadName));
int maxUsers = metricsMap.size();
for (int j = 0; j < metrics.size(); j++) {
Metric metric = metrics.get(j);
String success = metric.getSuccess();
@ -330,17 +332,22 @@ public class JtlResolver {
failSize++;
}
}
// todo
timeList.add(map.getKey());
hits.add(String.valueOf(metrics.size()));
users.add(String.valueOf(metrics.size()));
hits.add(df.format(metrics.size() * 1.0 / maxUsers));
users.add(String.valueOf(maxUsers));
erorrs.add(String.valueOf(failSize));
}
data.setTime(timeList);
data.setUsers(users);
data.setHits(hits);
data.setErrors(erorrs);
return data;
}
private static String stampToDate(String s){
String res;
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

View File

@ -1,5 +1,7 @@
package io.metersphere.report.base;
import java.util.List;
public class ChartsData {
private String xAxis;
@ -7,6 +9,12 @@ public class ChartsData {
private String yAxis1;
private String serices;
////
private List<String> time;
private List<String> users;
private List<String> hits;
private List<String> errors;
public String getxAxis() {
return xAxis;
}
@ -38,4 +46,36 @@ public class ChartsData {
public void setSerices(String serices) {
this.serices = serices;
}
public List<String> getTime() {
return time;
}
public void setTime(List<String> time) {
this.time=time;
}
public List<String> getUsers() {
return users;
}
public void setUsers(List<String> users) {
this.users=users;
}
public List<String> getHits() {
return hits;
}
public void setHits(List<String> hits) {
this.hits=hits;
}
public List<String> getErrors() {
return errors;
}
public void setErrors(List<String> errors) {
this.errors=errors;
}
}

View File

@ -1,11 +1,9 @@
package io.metersphere.service;
import io.metersphere.base.domain.*;
import io.metersphere.base.mapper.FileContentMapper;
import io.metersphere.base.mapper.FileMetadataMapper;
import io.metersphere.base.mapper.LoadTestFileMapper;
import io.metersphere.base.mapper.LoadTestMapper;
import io.metersphere.base.mapper.*;
import io.metersphere.base.mapper.ext.ExtLoadTestMapper;
import io.metersphere.base.mapper.ext.ExtLoadTestReportMapper;
import io.metersphere.commons.constants.FileType;
import io.metersphere.commons.constants.TestStatus;
import io.metersphere.commons.exception.MSException;
@ -31,6 +29,8 @@ import java.util.stream.Collectors;
@Service
@Transactional(rollbackFor = Exception.class)
public class LoadTestService {
private static final String HEADERS = "timestamp,elapsed,label,responseCode,responseMessage,threadName,dataType,success,failureMessage,bytes,sentBytes,grpThreads,allThreads,URL,Latency,IdleTime,Connect";
@Resource
private LoadTestMapper loadTestMapper;
@Resource
@ -44,7 +44,9 @@ public class LoadTestService {
@Resource
private FileService fileService;
@Resource
private TestResourcePoolService testResourcePoolService;
private LoadTestReportMapper loadTestReportMapper;
@Resource
private ExtLoadTestReportMapper extLoadTestReportMapper;
public List<LoadTestDTO> list(QueryTestPlanRequest request) {
return extLoadTestMapper.list(request);
@ -176,12 +178,34 @@ public class LoadTestService {
if (engine == null) {
MSException.throwException(String.format("Test cannot be runtest ID%s", request.getId()));
}
LoadTestReportWithBLOBs testReport = new LoadTestReportWithBLOBs();
testReport.setId(engine.getReportId());
testReport.setCreateTime(engine.getStartTime());
testReport.setUpdateTime(engine.getStartTime());
testReport.setTestId(loadTest.getId());
testReport.setName(loadTest.getName());
// 启动测试
engine.start();
// 标记running状态
loadTest.setStatus(TestStatus.Running.name());
loadTestMapper.updateByPrimaryKeySelective(loadTest);
try {
engine.start();
// 标记running状态
loadTest.setStatus(TestStatus.Starting.name());
loadTestMapper.updateByPrimaryKeySelective(loadTest);
testReport.setContent(HEADERS);
testReport.setStatus(TestStatus.Starting.name());
loadTestReportMapper.insertSelective(testReport);
// append \n
extLoadTestReportMapper.appendLine(testReport.getId(), "\n");
} catch (Exception e) {
loadTest.setStatus(TestStatus.Error.name());
loadTestMapper.updateByPrimaryKeySelective(loadTest);
//
testReport.setStatus(TestStatus.Error.name());
testReport.setDescription(e.getMessage());
loadTestReportMapper.insertSelective(testReport);
}
// todo通过调用stop方法能够停止正在运行的engine但是如果部署了多个backend实例页面发送的停止请求如何定位到具体的engine
}

View File

@ -2,11 +2,13 @@ package io.metersphere.service;
import io.metersphere.base.domain.LoadTestReport;
import io.metersphere.base.domain.LoadTestReportExample;
import io.metersphere.base.domain.LoadTestReportWithBLOBs;
import io.metersphere.base.mapper.LoadTestReportMapper;
import io.metersphere.base.mapper.ext.ExtLoadTestReportMapper;
import io.metersphere.controller.request.ReportRequest;
import io.metersphere.dto.ReportDTO;
import io.metersphere.report.JtlResolver;
import io.metersphere.report.base.ChartsData;
import io.metersphere.report.base.Errors;
import io.metersphere.report.base.TestOverview;
import io.metersphere.report.dto.ErrorsTop5DTO;
@ -48,30 +50,37 @@ public class ReportService {
}
public RequestStatisticsDTO getReport(String id) {
LoadTestReport loadTestReport = loadTestReportMapper.selectByPrimaryKey(id);
LoadTestReportWithBLOBs loadTestReport = loadTestReportMapper.selectByPrimaryKey(id);
String content = loadTestReport.getContent();
RequestStatisticsDTO requestStatistics = JtlResolver.getRequestStatistics(content);
return requestStatistics;
}
public List<Errors> getReportErrors(String id) {
LoadTestReport loadTestReport = loadTestReportMapper.selectByPrimaryKey(id);
LoadTestReportWithBLOBs loadTestReport = loadTestReportMapper.selectByPrimaryKey(id);
String content = loadTestReport.getContent();
List<Errors> errors = JtlResolver.getErrorsList(content);
return errors;
}
public ErrorsTop5DTO getReportErrorsTOP5(String id) {
LoadTestReport loadTestReport = loadTestReportMapper.selectByPrimaryKey(id);
LoadTestReportWithBLOBs loadTestReport = loadTestReportMapper.selectByPrimaryKey(id);
String content = loadTestReport.getContent();
ErrorsTop5DTO errors = JtlResolver.getErrorsTop5DTO(content);
return errors;
}
public TestOverview getTestOverview(String id) {
LoadTestReport loadTestReport = loadTestReportMapper.selectByPrimaryKey(id);
LoadTestReportWithBLOBs loadTestReport = loadTestReportMapper.selectByPrimaryKey(id);
String content = loadTestReport.getContent();
TestOverview testOverview = JtlResolver.getTestOverview(content);
return testOverview;
}
public ChartsData getLoadChartData(String id) {
LoadTestReportWithBLOBs loadTestReport = loadTestReportMapper.selectByPrimaryKey(id);
String content = loadTestReport.getContent();
ChartsData chartsData = JtlResolver.getLoadChartData(content);
return chartsData;
}
}

View File

@ -10,7 +10,3 @@ INSERT INTO role (id, name, description, type, create_time, update_time) VALUES
INSERT INTO role (id, name, description, type, create_time, update_time) VALUES ('test_user', '测试人员', null, null, 1581576575948, 1581576575948);
INSERT INTO role (id, name, description, type, create_time, update_time) VALUES ('test_viewer', 'Viewer', null, null, 1581576575948, 1581576575948);
INSERT INTO `system_parameter`(`param_key`, `param_value`, `type`, `sort`) VALUES ('registry.password', '', 'password', 4);
INSERT INTO `system_parameter`(`param_key`, `param_value`, `type`, `sort`) VALUES ('registry.repo', '', 'text', 2);
INSERT INTO `system_parameter`(`param_key`, `param_value`, `type`, `sort`) VALUES ('registry.url', '', 'text', 1);
INSERT INTO `system_parameter`(`param_key`, `param_value`, `type`, `sort`) VALUES ('registry.username', '', 'text', 3);

View File

@ -5,7 +5,6 @@ import io.metersphere.base.domain.SystemParameter;
import io.metersphere.base.mapper.UserMapper;
import io.metersphere.commons.constants.ParamConstants;
import io.metersphere.commons.utils.CompressUtils;
import io.metersphere.engine.kubernetes.registry.RegistryService;
import io.metersphere.service.RegistryParamService;
import org.junit.Test;
import org.junit.runner.RunWith;
@ -22,8 +21,6 @@ public class ApplicationTests {
UserMapper userMapper;
@Resource
private RegistryParamService registryParamService;
@Resource
private RegistryService registryService;
@Test
public void test1() {
@ -54,10 +51,4 @@ public class ApplicationTests {
}
@Test
public void test3() {
String registry = registryService.getRegistry();
System.out.println(registry);
}
}

View File

@ -148,6 +148,7 @@
message: this.$t('load_test.is_running'),
type: 'success'
});
this.$router.push({path: '/performance/report/all'})
})
});
},

View File

@ -59,7 +59,7 @@
<el-row>
<el-col :span="12">
<chart ref="chart1" :options="option1" :autoresize="true"></chart>
<chart ref="chart1" :options="option" :autoresize="true"></chart>
</el-col>
<el-col :span="12">
<chart ref="chart2" :options="option2" :autoresize="true"></chart>
@ -79,53 +79,7 @@
avgResponseTime: "0",
responseTime90: "0",
avgBandwidth: "0",
option1: {
legend: {
top: 20,
data: ['Users', 'Hits/s', 'Error(s)']
},
xAxis: {
type: 'category',
data: ["10:22:01", "10:22:02", "10:22:04", "10:22:06",
"10:22:07", "10:22:08", "10:22:09", "10:22:10", "10:22:11", "10:22:12"]
},
yAxis: [{
name: 'User',
type: 'value',
min: 0,
max: 30,
splitNumber: 5,
interval: 30 / 5
},
{
name: 'Hits/s',
type: 'value'
}
],
series: [
{
name: 'Users',
color: '#0CA74A',
data: [6,9,10,15,1,10,25,19,15,2],
type: 'line',
yAxisIndex: 0
},
{
name: 'Hits/s',
color: '#65A2FF',
data: [1,1,1,1,1,1,1,1,1,1],
type: 'line',
yAxisIndex: 1
},
{
name: 'Error(s)',
color: '#E6113C',
data: [0,0,0,0,1,1,2,0,5,2],
type: 'line',
yAxisIndex: 1
}
]
},
option: {},
option2: {
legend: {
top: 20,
@ -173,6 +127,59 @@
this.responseTime90 = data.responseTime90;
this.avgBandwidth = data.avgBandwidth;
})
this.$get("/report/content/load_chart/" + this.id, res => {
let data = res.data;
this.option = this.generateOption(data);
})
},
generateOption(data) {
let option = {
legend: {
top: 20,
data: ['Users', 'Hits/s', 'Error(s)']
},
xAxis: {
type: 'category',
},
yAxis: [{
name: 'User',
type: 'value',
min: 0,
splitNumber: 5,
interval: 10 / 5
},
{
name: 'Hits/s',
type: 'value'
}
],
series: [
{
name: 'Users',
color: '#0CA74A',
type: 'line',
yAxisIndex: 0
},
{
name: 'Hits/s',
color: '#65A2FF',
type: 'line',
yAxisIndex: 1
},
{
name: 'Error(s)',
color: '#E6113C',
type: 'line',
yAxisIndex: 1
}
]
}
this.$set(option.xAxis, "data", data.time);
this.$set(option.series[0], "data", data.users);
this.$set(option.series[1], "data", data.hits);
this.$set(option.series[2], "data", data.errors);
return option;
}
},
created() {
@ -193,6 +200,10 @@
this.responseTime90 = data.responseTime90;
this.avgBandwidth = data.avgBandwidth;
})
this.$get("/report/content/load_chart/" + reportId, res => {
let data = res.data;
this.option1 = this.generateOption(data);
})
}
}
}