file metadata add column engine
This commit is contained in:
parent
4927d97630
commit
4e5e8c9809
|
@ -18,9 +18,16 @@
|
|||
<shiro.version>1.5.1</shiro.version>
|
||||
<java.version>1.8</java.version>
|
||||
<jmeter.version>5.2.1</jmeter.version>
|
||||
<kubernetes-client.version>4.9.0</kubernetes-client.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<!-- kubernetes client-->
|
||||
<dependency>
|
||||
<groupId>io.fabric8</groupId>
|
||||
<artifactId>kubernetes-client</artifactId>
|
||||
<version>${kubernetes-client.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
|
|
|
@ -9,12 +9,14 @@ public class FileMetadata implements Serializable {
|
|||
|
||||
private String type;
|
||||
|
||||
private Long size;
|
||||
private String engine;
|
||||
|
||||
private Long createTime;
|
||||
|
||||
private Long updateTime;
|
||||
|
||||
private Long size;
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
public String getId() {
|
||||
|
@ -41,12 +43,12 @@ public class FileMetadata implements Serializable {
|
|||
this.type = type == null ? null : type.trim();
|
||||
}
|
||||
|
||||
public Long getSize() {
|
||||
return size;
|
||||
public String getEngine() {
|
||||
return engine;
|
||||
}
|
||||
|
||||
public void setSize(Long size) {
|
||||
this.size = size;
|
||||
public void setEngine(String engine) {
|
||||
this.engine = engine == null ? null : engine.trim();
|
||||
}
|
||||
|
||||
public Long getCreateTime() {
|
||||
|
@ -64,4 +66,12 @@ public class FileMetadata implements Serializable {
|
|||
public void setUpdateTime(Long updateTime) {
|
||||
this.updateTime = updateTime;
|
||||
}
|
||||
|
||||
public Long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public void setSize(Long size) {
|
||||
this.size = size;
|
||||
}
|
||||
}
|
|
@ -314,63 +314,73 @@ public class FileMetadataExample {
|
|||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSizeIsNull() {
|
||||
addCriterion("size is null");
|
||||
public Criteria andEngineIsNull() {
|
||||
addCriterion("engine is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSizeIsNotNull() {
|
||||
addCriterion("size is not null");
|
||||
public Criteria andEngineIsNotNull() {
|
||||
addCriterion("engine is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSizeEqualTo(Long value) {
|
||||
addCriterion("size =", value, "size");
|
||||
public Criteria andEngineEqualTo(String value) {
|
||||
addCriterion("engine =", value, "engine");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSizeNotEqualTo(Long value) {
|
||||
addCriterion("size <>", value, "size");
|
||||
public Criteria andEngineNotEqualTo(String value) {
|
||||
addCriterion("engine <>", value, "engine");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSizeGreaterThan(Long value) {
|
||||
addCriterion("size >", value, "size");
|
||||
public Criteria andEngineGreaterThan(String value) {
|
||||
addCriterion("engine >", value, "engine");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSizeGreaterThanOrEqualTo(Long value) {
|
||||
addCriterion("size >=", value, "size");
|
||||
public Criteria andEngineGreaterThanOrEqualTo(String value) {
|
||||
addCriterion("engine >=", value, "engine");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSizeLessThan(Long value) {
|
||||
addCriterion("size <", value, "size");
|
||||
public Criteria andEngineLessThan(String value) {
|
||||
addCriterion("engine <", value, "engine");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSizeLessThanOrEqualTo(Long value) {
|
||||
addCriterion("size <=", value, "size");
|
||||
public Criteria andEngineLessThanOrEqualTo(String value) {
|
||||
addCriterion("engine <=", value, "engine");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSizeIn(List<Long> values) {
|
||||
addCriterion("size in", values, "size");
|
||||
public Criteria andEngineLike(String value) {
|
||||
addCriterion("engine like", value, "engine");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSizeNotIn(List<Long> values) {
|
||||
addCriterion("size not in", values, "size");
|
||||
public Criteria andEngineNotLike(String value) {
|
||||
addCriterion("engine not like", value, "engine");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSizeBetween(Long value1, Long value2) {
|
||||
addCriterion("size between", value1, value2, "size");
|
||||
public Criteria andEngineIn(List<String> values) {
|
||||
addCriterion("engine in", values, "engine");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSizeNotBetween(Long value1, Long value2) {
|
||||
addCriterion("size not between", value1, value2, "size");
|
||||
public Criteria andEngineNotIn(List<String> values) {
|
||||
addCriterion("engine not in", values, "engine");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andEngineBetween(String value1, String value2) {
|
||||
addCriterion("engine between", value1, value2, "engine");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andEngineNotBetween(String value1, String value2) {
|
||||
addCriterion("engine not between", value1, value2, "engine");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
|
@ -493,6 +503,66 @@ public class FileMetadataExample {
|
|||
addCriterion("update_time not between", value1, value2, "updateTime");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSizeIsNull() {
|
||||
addCriterion("size is null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSizeIsNotNull() {
|
||||
addCriterion("size is not null");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSizeEqualTo(Long value) {
|
||||
addCriterion("size =", value, "size");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSizeNotEqualTo(Long value) {
|
||||
addCriterion("size <>", value, "size");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSizeGreaterThan(Long value) {
|
||||
addCriterion("size >", value, "size");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSizeGreaterThanOrEqualTo(Long value) {
|
||||
addCriterion("size >=", value, "size");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSizeLessThan(Long value) {
|
||||
addCriterion("size <", value, "size");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSizeLessThanOrEqualTo(Long value) {
|
||||
addCriterion("size <=", value, "size");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSizeIn(List<Long> values) {
|
||||
addCriterion("size in", values, "size");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSizeNotIn(List<Long> values) {
|
||||
addCriterion("size not in", values, "size");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSizeBetween(Long value1, Long value2) {
|
||||
addCriterion("size between", value1, value2, "size");
|
||||
return (Criteria) this;
|
||||
}
|
||||
|
||||
public Criteria andSizeNotBetween(Long value1, Long value2) {
|
||||
addCriterion("size not between", value1, value2, "size");
|
||||
return (Criteria) this;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Criteria extends GeneratedCriteria {
|
||||
|
|
|
@ -5,9 +5,10 @@
|
|||
<id column="id" jdbcType="VARCHAR" property="id" />
|
||||
<result column="name" jdbcType="VARCHAR" property="name" />
|
||||
<result column="type" jdbcType="VARCHAR" property="type" />
|
||||
<result column="size" jdbcType="BIGINT" property="size" />
|
||||
<result column="engine" jdbcType="VARCHAR" property="engine" />
|
||||
<result column="create_time" jdbcType="BIGINT" property="createTime" />
|
||||
<result column="update_time" jdbcType="BIGINT" property="updateTime" />
|
||||
<result column="size" jdbcType="BIGINT" property="size" />
|
||||
</resultMap>
|
||||
<sql id="Example_Where_Clause">
|
||||
<where>
|
||||
|
@ -68,7 +69,7 @@
|
|||
</where>
|
||||
</sql>
|
||||
<sql id="Base_Column_List">
|
||||
id, name, type, size, create_time, update_time
|
||||
id, name, type, engine, create_time, update_time, size
|
||||
</sql>
|
||||
<select id="selectByExample" parameterType="io.metersphere.base.domain.FileMetadataExample" resultMap="BaseResultMap">
|
||||
select
|
||||
|
@ -102,11 +103,11 @@
|
|||
</delete>
|
||||
<insert id="insert" parameterType="io.metersphere.base.domain.FileMetadata">
|
||||
insert into file_metadata (id, name, type,
|
||||
size, create_time, update_time
|
||||
)
|
||||
engine, create_time, update_time,
|
||||
size)
|
||||
values (#{id,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, #{type,jdbcType=VARCHAR},
|
||||
#{size,jdbcType=BIGINT}, #{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT}
|
||||
)
|
||||
#{engine,jdbcType=VARCHAR}, #{createTime,jdbcType=BIGINT}, #{updateTime,jdbcType=BIGINT},
|
||||
#{size,jdbcType=BIGINT})
|
||||
</insert>
|
||||
<insert id="insertSelective" parameterType="io.metersphere.base.domain.FileMetadata">
|
||||
insert into file_metadata
|
||||
|
@ -120,8 +121,8 @@
|
|||
<if test="type != null">
|
||||
type,
|
||||
</if>
|
||||
<if test="size != null">
|
||||
size,
|
||||
<if test="engine != null">
|
||||
engine,
|
||||
</if>
|
||||
<if test="createTime != null">
|
||||
create_time,
|
||||
|
@ -129,6 +130,9 @@
|
|||
<if test="updateTime != null">
|
||||
update_time,
|
||||
</if>
|
||||
<if test="size != null">
|
||||
size,
|
||||
</if>
|
||||
</trim>
|
||||
<trim prefix="values (" suffix=")" suffixOverrides=",">
|
||||
<if test="id != null">
|
||||
|
@ -140,8 +144,8 @@
|
|||
<if test="type != null">
|
||||
#{type,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="size != null">
|
||||
#{size,jdbcType=BIGINT},
|
||||
<if test="engine != null">
|
||||
#{engine,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="createTime != null">
|
||||
#{createTime,jdbcType=BIGINT},
|
||||
|
@ -149,6 +153,9 @@
|
|||
<if test="updateTime != null">
|
||||
#{updateTime,jdbcType=BIGINT},
|
||||
</if>
|
||||
<if test="size != null">
|
||||
#{size,jdbcType=BIGINT},
|
||||
</if>
|
||||
</trim>
|
||||
</insert>
|
||||
<select id="countByExample" parameterType="io.metersphere.base.domain.FileMetadataExample" resultType="java.lang.Long">
|
||||
|
@ -169,8 +176,8 @@
|
|||
<if test="record.type != null">
|
||||
type = #{record.type,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.size != null">
|
||||
size = #{record.size,jdbcType=BIGINT},
|
||||
<if test="record.engine != null">
|
||||
engine = #{record.engine,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="record.createTime != null">
|
||||
create_time = #{record.createTime,jdbcType=BIGINT},
|
||||
|
@ -178,6 +185,9 @@
|
|||
<if test="record.updateTime != null">
|
||||
update_time = #{record.updateTime,jdbcType=BIGINT},
|
||||
</if>
|
||||
<if test="record.size != null">
|
||||
size = #{record.size,jdbcType=BIGINT},
|
||||
</if>
|
||||
</set>
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
|
@ -188,9 +198,10 @@
|
|||
set id = #{record.id,jdbcType=VARCHAR},
|
||||
name = #{record.name,jdbcType=VARCHAR},
|
||||
type = #{record.type,jdbcType=VARCHAR},
|
||||
size = #{record.size,jdbcType=BIGINT},
|
||||
engine = #{record.engine,jdbcType=VARCHAR},
|
||||
create_time = #{record.createTime,jdbcType=BIGINT},
|
||||
update_time = #{record.updateTime,jdbcType=BIGINT}
|
||||
update_time = #{record.updateTime,jdbcType=BIGINT},
|
||||
size = #{record.size,jdbcType=BIGINT}
|
||||
<if test="_parameter != null">
|
||||
<include refid="Update_By_Example_Where_Clause" />
|
||||
</if>
|
||||
|
@ -204,8 +215,8 @@
|
|||
<if test="type != null">
|
||||
type = #{type,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="size != null">
|
||||
size = #{size,jdbcType=BIGINT},
|
||||
<if test="engine != null">
|
||||
engine = #{engine,jdbcType=VARCHAR},
|
||||
</if>
|
||||
<if test="createTime != null">
|
||||
create_time = #{createTime,jdbcType=BIGINT},
|
||||
|
@ -213,6 +224,9 @@
|
|||
<if test="updateTime != null">
|
||||
update_time = #{updateTime,jdbcType=BIGINT},
|
||||
</if>
|
||||
<if test="size != null">
|
||||
size = #{size,jdbcType=BIGINT},
|
||||
</if>
|
||||
</set>
|
||||
where id = #{id,jdbcType=VARCHAR}
|
||||
</update>
|
||||
|
@ -220,9 +234,10 @@
|
|||
update file_metadata
|
||||
set name = #{name,jdbcType=VARCHAR},
|
||||
type = #{type,jdbcType=VARCHAR},
|
||||
size = #{size,jdbcType=BIGINT},
|
||||
engine = #{engine,jdbcType=VARCHAR},
|
||||
create_time = #{createTime,jdbcType=BIGINT},
|
||||
update_time = #{updateTime,jdbcType=BIGINT}
|
||||
update_time = #{updateTime,jdbcType=BIGINT},
|
||||
size = #{size,jdbcType=BIGINT}
|
||||
where id = #{id,jdbcType=VARCHAR}
|
||||
</update>
|
||||
</mapper>
|
|
@ -1,5 +1,5 @@
|
|||
package io.metersphere.commons.constants;
|
||||
|
||||
public enum EngineType {
|
||||
JMX
|
||||
DOCKER, KUBERNETES
|
||||
}
|
||||
|
|
|
@ -7,7 +7,8 @@ import io.metersphere.base.domain.FileMetadata;
|
|||
import io.metersphere.base.domain.LoadTestWithBLOBs;
|
||||
import io.metersphere.commons.constants.EngineType;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.engine.jmx.JmxEngine;
|
||||
import io.metersphere.engine.docker.DockerTestEngine;
|
||||
import io.metersphere.engine.kubernetes.KubernetesTestEngine;
|
||||
import io.metersphere.parse.EngineSourceParser;
|
||||
import io.metersphere.parse.EngineSourceParserFactory;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
@ -19,8 +20,11 @@ public class EngineFactory {
|
|||
public static Engine createEngine(String engineType) {
|
||||
final EngineType type = EngineType.valueOf(engineType);
|
||||
|
||||
if (type == EngineType.JMX) {
|
||||
return new JmxEngine();
|
||||
if (type == EngineType.DOCKER) {
|
||||
return new DockerTestEngine();
|
||||
}
|
||||
if (type == EngineType.KUBERNETES) {
|
||||
return new KubernetesTestEngine();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
package io.metersphere.engine.docker;
|
||||
|
||||
import io.metersphere.engine.Engine;
|
||||
import io.metersphere.engine.EngineContext;
|
||||
|
||||
public class DockerTestEngine implements Engine {
|
||||
@Override
|
||||
public boolean init(EngineContext context) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
|
||||
}
|
||||
}
|
|
@ -1,106 +0,0 @@
|
|||
package io.metersphere.engine.jmx;
|
||||
|
||||
import io.metersphere.engine.Engine;
|
||||
import io.metersphere.engine.EngineContext;
|
||||
import io.metersphere.engine.EngineThread;
|
||||
import io.metersphere.engine.jmx.client.DistributedRunner;
|
||||
import io.metersphere.engine.jmx.client.JmeterProperties;
|
||||
import org.apache.jmeter.JMeter;
|
||||
import org.apache.jmeter.save.SaveService;
|
||||
import org.apache.jmeter.services.FileServer;
|
||||
import org.apache.jmeter.threads.ThreadGroup;
|
||||
import org.apache.jorphan.collections.HashTree;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Set;
|
||||
|
||||
public class JmxEngine extends EngineThread implements Engine {
|
||||
private static final Logger log = LoggerFactory.getLogger(JmxEngine.class);
|
||||
/// todo:从测试属性中读取
|
||||
private final static Integer MAX_DURATION = 60;
|
||||
/// todo:从测试属性中读取
|
||||
private final static String REMOTE_HOSTS = "127.0.0.1";
|
||||
/// todo:jmeter home如何确定
|
||||
private final static String jmeterHome = "/opt/fit2cloud/apache-jmeter-5.2.1";
|
||||
private static Method readTreeMethod;
|
||||
|
||||
static {
|
||||
try {
|
||||
readTreeMethod = SaveService.class.getDeclaredMethod("readTree", InputStream.class, File.class);
|
||||
readTreeMethod.setAccessible(true);
|
||||
} catch (NoSuchMethodException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
private EngineContext context;
|
||||
private DistributedRunner runner;
|
||||
|
||||
private static void setMaxTestDuration(HashTree jmxTree) {
|
||||
for (HashTree item : jmxTree.values()) {
|
||||
Set treeKeys = item.keySet();
|
||||
for (Object key : treeKeys) {
|
||||
if (key instanceof ThreadGroup) {
|
||||
((ThreadGroup) key).setProperty(ThreadGroup.SCHEDULER, true);
|
||||
((ThreadGroup) key).setProperty(ThreadGroup.DURATION, MAX_DURATION);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getEngineName() {
|
||||
return "JMX";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean init(EngineContext context) {
|
||||
this.context = context;
|
||||
|
||||
new JmeterProperties(JmxEngine.jmeterHome).initJmeterProperties();
|
||||
FileServer.getFileServer().setBaseForScript(new File(JmxEngine.jmeterHome + File.separator + "nothing"));
|
||||
|
||||
final HashTree jmxTree = loadTree(this.context.getInputStream());
|
||||
if (jmxTree == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
JMeter.convertSubTree(jmxTree, true);
|
||||
|
||||
setMaxTestDuration(jmxTree);
|
||||
|
||||
this.runner = new DistributedRunner(jmxTree, REMOTE_HOSTS);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
this.runner.run();
|
||||
} catch (Throwable e) {
|
||||
log.error("run test error, id: " + this.context.getEngineId(), e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
super.stop(false);
|
||||
this.runner.stop();
|
||||
}
|
||||
|
||||
private HashTree loadTree(InputStream inputStream) {
|
||||
try (BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream)) {
|
||||
return (HashTree) readTreeMethod.invoke(null, bufferedInputStream, null);
|
||||
} catch (Exception e) {
|
||||
log.error("Failed to load tree", e);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -1,137 +0,0 @@
|
|||
package io.metersphere.engine.jmx.client;
|
||||
|
||||
import org.apache.jmeter.engine.ClientJMeterEngine;
|
||||
import org.apache.jmeter.engine.JMeterEngine;
|
||||
import org.apache.jmeter.report.dashboard.ReportGenerator;
|
||||
import org.apache.jmeter.samplers.Remoteable;
|
||||
import org.apache.jmeter.testelement.TestStateListener;
|
||||
import org.apache.jmeter.util.JMeterUtils;
|
||||
import org.apache.jorphan.collections.HashTree;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
public class DistributedRunner extends org.apache.jmeter.engine.DistributedRunner {
|
||||
private static final String HOSTS_SEPARATOR = ",";
|
||||
private HashTree jmxTree;
|
||||
private String hosts;
|
||||
// 脚本运行完成后是否停止jmeter-server
|
||||
private boolean remoteStop = false;
|
||||
|
||||
public DistributedRunner(HashTree jmxTree, String hosts) {
|
||||
this.jmxTree = jmxTree;
|
||||
this.hosts = hosts;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
final List<String> hosts = getRemoteHosts();
|
||||
final ListenToTest listener = new ListenToTest(remoteStop, null);
|
||||
jmxTree.add(jmxTree.getArray()[0], listener);
|
||||
init(hosts, jmxTree);
|
||||
listener.setStartedRemoteEngines(new ArrayList<>(getEngines()));
|
||||
start();
|
||||
}
|
||||
|
||||
private List<String> getRemoteHosts() {
|
||||
StringTokenizer st = new StringTokenizer(hosts, HOSTS_SEPARATOR);
|
||||
List<String> list = new LinkedList<>();
|
||||
while (st.hasMoreElements()) {
|
||||
list.add((String) st.nextElement());
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
private static class ListenToTest implements TestStateListener, Remoteable {
|
||||
private final Logger log = LoggerFactory.getLogger(ListenToTest.class);
|
||||
private final ReportGenerator reportGenerator;
|
||||
private AtomicInteger startedRemoteEngines = new AtomicInteger(0);
|
||||
private ConcurrentLinkedQueue<JMeterEngine> remoteEngines = new ConcurrentLinkedQueue<>();
|
||||
private boolean remoteStop;
|
||||
|
||||
ListenToTest(boolean remoteStop, ReportGenerator reportGenerator) {
|
||||
this.remoteStop = remoteStop;
|
||||
this.reportGenerator = reportGenerator;
|
||||
}
|
||||
|
||||
void setStartedRemoteEngines(List<JMeterEngine> engines) {
|
||||
this.remoteEngines.clear();
|
||||
this.remoteEngines.addAll(engines);
|
||||
this.startedRemoteEngines = new AtomicInteger(remoteEngines.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
// N.B. this is called by a daemon RMI thread from the remote host
|
||||
public void testEnded(String host) {
|
||||
final long now = System.currentTimeMillis();
|
||||
log.info("Finished remote host: {} ({})", host, now);
|
||||
if (startedRemoteEngines.decrementAndGet() <= 0) {
|
||||
log.info("All remote engines have ended test, starting RemoteTestStopper thread");
|
||||
Thread stopSoon = new Thread(() -> endTest(true), "RemoteTestStopper");
|
||||
// the calling thread is a daemon; this thread must not be
|
||||
// see Bug 59391
|
||||
stopSoon.setDaemon(false);
|
||||
stopSoon.start();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testEnded() {
|
||||
endTest(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testStarted(String host) {
|
||||
final long now = System.currentTimeMillis();
|
||||
log.info("Started remote host: {} ({})", host, now);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testStarted() {
|
||||
if (log.isInfoEnabled()) {
|
||||
final long now = System.currentTimeMillis();
|
||||
log.info("{} ({})", JMeterUtils.getResString("running_test"), now);//$NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
private void endTest(boolean isDistributed) {
|
||||
long now = System.currentTimeMillis();
|
||||
if (isDistributed) {
|
||||
log.info("Tidying up remote @ " + new Date(now) + " (" + now + ")");
|
||||
} else {
|
||||
log.info("Tidying up ... @ " + new Date(now) + " (" + now + ")");
|
||||
}
|
||||
|
||||
if (isDistributed) {
|
||||
if (remoteStop) {
|
||||
log.info("Exiting remote servers:" + remoteEngines);
|
||||
for (JMeterEngine engine : remoteEngines) {
|
||||
log.info("Exiting remote server:" + engine);
|
||||
engine.exit();
|
||||
}
|
||||
}
|
||||
try {
|
||||
TimeUnit.SECONDS.sleep(5); // Allow listeners to close files
|
||||
} catch (InterruptedException ignored) {
|
||||
Thread.currentThread().interrupt();
|
||||
}
|
||||
ClientJMeterEngine.tidyRMI(log);
|
||||
}
|
||||
|
||||
if (reportGenerator != null) {
|
||||
try {
|
||||
log.info("Generating Dashboard");
|
||||
reportGenerator.generate();
|
||||
log.info("Dashboard generated");
|
||||
} catch (Exception ex) {
|
||||
System.err.println("Error generating the report: " + ex);
|
||||
log.error("Error generating the report: {}", ex.getMessage(), ex);
|
||||
}
|
||||
}
|
||||
log.info("... end of run");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
package io.metersphere.engine.jmx.client;
|
||||
|
||||
import org.apache.jmeter.util.JMeterUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
public class JmeterProperties extends Properties {
|
||||
private final static Logger logger = LoggerFactory.getLogger(JmeterProperties.class);
|
||||
|
||||
private final String jmeterHome;
|
||||
|
||||
public JmeterProperties(String jmeterHome) {
|
||||
this.jmeterHome = jmeterHome;
|
||||
}
|
||||
|
||||
public void initJmeterProperties() {
|
||||
JMeterUtils.loadJMeterProperties(getJmeterHomeBin() + File.separator + "jmeter.properties");
|
||||
JMeterUtils.setJMeterHome(getJmeterHome());
|
||||
JMeterUtils.initLocale();
|
||||
|
||||
Properties jmeterProps = JMeterUtils.getJMeterProperties();
|
||||
|
||||
// Add local JMeter properties, if the file is found
|
||||
String userProp = JMeterUtils.getPropDefault("user.properties", "");
|
||||
if (userProp.length() > 0) {
|
||||
File file = JMeterUtils.findFile(userProp);
|
||||
if (file.canRead()) {
|
||||
try (FileInputStream fis = new FileInputStream(file)) {
|
||||
Properties tmp = new Properties();
|
||||
tmp.load(fis);
|
||||
jmeterProps.putAll(tmp);
|
||||
} catch (IOException e) {
|
||||
logger.error("Failed to init jmeter properties", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add local system properties, if the file is found
|
||||
String sysProp = JMeterUtils.getPropDefault("system.properties", "");
|
||||
if (sysProp.length() > 0) {
|
||||
File file = JMeterUtils.findFile(sysProp);
|
||||
if (file.canRead()) {
|
||||
try (FileInputStream fis = new FileInputStream(file)) {
|
||||
System.getProperties().load(fis);
|
||||
} catch (IOException e) {
|
||||
logger.error("Failed to init jmeter properties", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
jmeterProps.put("jmeter.version", JMeterUtils.getJMeterVersion());
|
||||
for (Map.Entry<Object, Object> entry : jmeterProps.entrySet()) {
|
||||
put(entry.getKey(), entry.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
private String getJmeterHome() {
|
||||
return jmeterHome;
|
||||
}
|
||||
|
||||
private String getJmeterHomeBin() {
|
||||
return getJmeterHome() + File.separator + "bin";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package io.metersphere.engine.kubernetes;
|
||||
|
||||
import io.metersphere.engine.Engine;
|
||||
import io.metersphere.engine.EngineContext;
|
||||
|
||||
public class KubernetesTestEngine implements Engine {
|
||||
@Override
|
||||
public boolean init(EngineContext context) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
|
||||
}
|
||||
}
|
|
@ -93,7 +93,9 @@ public class FuctionalTestService {
|
|||
fileMetadata.setSize(file.getSize());
|
||||
fileMetadata.setCreateTime(System.currentTimeMillis());
|
||||
fileMetadata.setUpdateTime(System.currentTimeMillis());
|
||||
fileMetadata.setType(EngineType.JMX.name());
|
||||
fileMetadata.setType("jmx");
|
||||
// TODO engine 选择
|
||||
fileMetadata.setEngine(EngineType.DOCKER.name());
|
||||
fileMetadataMapper.insert(fileMetadata);
|
||||
|
||||
FileContent fileContent = new FileContent();
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
package io.metersphere.service;
|
||||
|
||||
import io.metersphere.base.domain.*;
|
||||
import io.metersphere.base.mapper.*;
|
||||
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.ext.ExtLoadTestMapper;
|
||||
import io.metersphere.commons.constants.EngineType;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.controller.request.testplan.*;
|
||||
import io.metersphere.dto.LoadTestDTO;
|
||||
import io.metersphere.engine.Engine;
|
||||
|
@ -29,8 +33,6 @@ public class LoadTestService {
|
|||
@Resource
|
||||
private ExtLoadTestMapper extLoadTestMapper;
|
||||
@Resource
|
||||
private ProjectMapper projectMapper;
|
||||
@Resource
|
||||
private FileMetadataMapper fileMetadataMapper;
|
||||
@Resource
|
||||
private FileContentMapper fileContentMapper;
|
||||
|
@ -51,7 +53,7 @@ public class LoadTestService {
|
|||
|
||||
public String save(SaveTestPlanRequest request, MultipartFile file) {
|
||||
if (file == null) {
|
||||
throw new IllegalArgumentException("文件不能为空!");
|
||||
throw new IllegalArgumentException(Translator.get("file_cannot_be_null"));
|
||||
}
|
||||
|
||||
final FileMetadata fileMetadata = saveFile(file);
|
||||
|
@ -95,7 +97,9 @@ public class LoadTestService {
|
|||
fileMetadata.setSize(file.getSize());
|
||||
fileMetadata.setCreateTime(System.currentTimeMillis());
|
||||
fileMetadata.setUpdateTime(System.currentTimeMillis());
|
||||
fileMetadata.setType(EngineType.JMX.name());
|
||||
fileMetadata.setType("jmx");
|
||||
// TODO engine 选择
|
||||
fileMetadata.setEngine(EngineType.DOCKER.name());
|
||||
fileMetadataMapper.insert(fileMetadata);
|
||||
|
||||
FileContent fileContent = new FileContent();
|
||||
|
@ -123,7 +127,7 @@ public class LoadTestService {
|
|||
|
||||
final LoadTestWithBLOBs loadTest = loadTestMapper.selectByPrimaryKey(request.getId());
|
||||
if (loadTest == null) {
|
||||
MSException.throwException("无法编辑测试,未找到测试:" + request.getId());
|
||||
MSException.throwException(Translator.get("edit_load_test_not_found") + request.getId());
|
||||
} else {
|
||||
loadTest.setName(request.getName());
|
||||
loadTest.setProjectId(request.getProjectId());
|
||||
|
@ -141,23 +145,25 @@ public class LoadTestService {
|
|||
public void run(RunTestPlanRequest request) {
|
||||
final LoadTestWithBLOBs loadTest = loadTestMapper.selectByPrimaryKey(request.getId());
|
||||
if (loadTest == null) {
|
||||
MSException.throwException("无法运行测试,未找到测试:" + request.getId());
|
||||
MSException.throwException(Translator.get("run_load_test_not_found") + request.getId());
|
||||
}
|
||||
|
||||
final FileMetadata fileMetadata = fileService.getFileMetadataByTestId(request.getId());
|
||||
if (fileMetadata == null) {
|
||||
MSException.throwException("无法运行测试,无法获取测试文件元信息,测试ID:" + request.getId());
|
||||
MSException.throwException(Translator.get("run_load_test_file_not_found") + request.getId());
|
||||
}
|
||||
|
||||
final FileContent fileContent = fileService.getFileContent(fileMetadata.getId());
|
||||
if (fileContent == null) {
|
||||
MSException.throwException("无法运行测试,无法获取测试文件内容,测试ID:" + request.getId());
|
||||
MSException.throwException(Translator.get("run_load_test_file_content_not_found") + request.getId());
|
||||
}
|
||||
|
||||
System.out.println("开始运行:" + loadTest.getName());
|
||||
final Engine engine = EngineFactory.createEngine(fileMetadata.getType());
|
||||
LogUtil.info("Load test started " + loadTest.getName());
|
||||
// engine type (DOCKER|KUBERNETES)
|
||||
// todo set type
|
||||
final Engine engine = EngineFactory.createEngine(fileMetadata.getEngine());
|
||||
if (engine == null) {
|
||||
MSException.throwException(String.format("无法运行测试,未识别测试文件类型,测试ID:%s,文件类型:%s",
|
||||
MSException.throwException(String.format("Test cannot be run,test ID:%s,file type:%s",
|
||||
request.getId(),
|
||||
fileMetadata.getType()));
|
||||
}
|
||||
|
@ -169,12 +175,12 @@ public class LoadTestService {
|
|||
MSException.throwException(e);
|
||||
}
|
||||
if (!init) {
|
||||
MSException.throwException(String.format("无法运行测试,初始化运行环境失败,测试ID:%s", request.getId()));
|
||||
MSException.throwException(Translator.get("run_load_test_file_init_error") + request.getId());
|
||||
}
|
||||
|
||||
engine.start();
|
||||
|
||||
/// todo:通过调用stop方法能够停止正在运行的engine,但是如果部署了多个backend实例,页面发送的停止请求如何定位到具体的engine
|
||||
// todo:通过调用stop方法能够停止正在运行的engine,但是如果部署了多个backend实例,页面发送的停止请求如何定位到具体的engine
|
||||
}
|
||||
|
||||
public List<LoadTestDTO> recentTestPlans(QueryTestPlanRequest request) {
|
||||
|
|
|
@ -11,6 +11,7 @@ CREATE TABLE IF NOT EXISTS `file_metadata` (
|
|||
`id` varchar(64) NOT NULL COMMENT 'File ID',
|
||||
`name` varchar(64) NOT NULL COMMENT 'File name',
|
||||
`type` varchar(64) DEFAULT NULL COMMENT 'File type',
|
||||
`engine` varchar(64) DEFAULT 'DOCKER' COMMENT 'engine type',
|
||||
`size` bigint(13) NOT NULL COMMENT 'File size',
|
||||
`create_time` bigint(13) NOT NULL COMMENT 'Create timestamp',
|
||||
`update_time` bigint(13) NOT NULL COMMENT 'Update timestamp',
|
||||
|
|
|
@ -6,5 +6,11 @@
|
|||
"workspace_name_is_null": "Workspace name cannot be null",
|
||||
"workspace_name_already_exists": "The workspace name already exists",
|
||||
"workspace_does_not_belong_to_user": "The current workspace does not belong to the current user",
|
||||
"organization_does_not_belong_to_user": "The current organization does not belong to the current user"
|
||||
"organization_does_not_belong_to_user": "The current organization does not belong to the current user",
|
||||
"file_cannot_be_null": "File cannot be empty!",
|
||||
"edit_load_test_not_found": "Cannot edit test, test not found:",
|
||||
"run_load_test_not_found": "Cannot run test, test not found:",
|
||||
"run_load_test_file_not_found": "Unable to run test, unable to get test file meta information, test ID:",
|
||||
"run_load_test_file_content_not_found": "Cannot run test, cannot get test file content, test ID:",
|
||||
"run_load_test_file_init_error": "Failed to run test, failed to initialize run environment, test ID:"
|
||||
}
|
|
@ -6,5 +6,11 @@
|
|||
"workspace_name_is_null": "工作空间名不能为空",
|
||||
"workspace_name_already_exists": "工作空间名已存在",
|
||||
"workspace_does_not_belong_to_user": "当前工作空间不属于当前用户",
|
||||
"organization_does_not_belong_to_user": "当前组织不属于当前用户"
|
||||
"organization_does_not_belong_to_user": "当前组织不属于当前用户",
|
||||
"file_cannot_be_null": "文件不能为空!",
|
||||
"edit_load_test_not_found": "无法编辑测试,未找到测试:",
|
||||
"run_load_test_not_found": "无法运行测试,未找到测试:",
|
||||
"run_load_test_file_not_found": "无法运行测试,无法获取测试文件元信息,测试ID:",
|
||||
"run_load_test_file_content_not_found": "无法运行测试,无法获取测试文件内容,测试ID:",
|
||||
"run_load_test_file_init_error": "无法运行测试,初始化运行环境失败,测试ID:"
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
package io.metersphere;
|
||||
|
||||
import io.fabric8.kubernetes.api.model.Pod;
|
||||
import io.fabric8.kubernetes.api.model.PodList;
|
||||
import io.fabric8.kubernetes.client.ConfigBuilder;
|
||||
import io.fabric8.kubernetes.client.DefaultKubernetesClient;
|
||||
import io.fabric8.kubernetes.client.KubernetesClient;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class BaseTest {
|
||||
protected KubernetesClient kubernetesClient;
|
||||
|
||||
@Before
|
||||
public void before() {
|
||||
|
||||
try {
|
||||
ConfigBuilder configBuilder = new ConfigBuilder();
|
||||
configBuilder.withMasterUrl("https://172.16.10.93:6443");
|
||||
kubernetesClient = new DefaultKubernetesClient(configBuilder.build());
|
||||
} catch (Exception e) {
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test1() {
|
||||
PodList list = kubernetesClient.pods().list();
|
||||
for (Pod item : list.getItems()) {
|
||||
System.out.println(item);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue