通过保存并运行按钮本地运行上传文件
This commit is contained in:
parent
677bdb959a
commit
951fe9f5d2
|
@ -17,6 +17,7 @@
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<shiro.version>1.4.0</shiro.version>
|
<shiro.version>1.4.0</shiro.version>
|
||||||
<java.version>1.8</java.version>
|
<java.version>1.8</java.version>
|
||||||
|
<jmeter.version>5.2.1</jmeter.version>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
@ -137,6 +138,19 @@
|
||||||
<artifactId>slf4j-simple</artifactId>
|
<artifactId>slf4j-simple</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- jmeter -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.jmeter</groupId>
|
||||||
|
<artifactId>ApacheJMeter_http</artifactId>
|
||||||
|
<version>${jmeter.version}</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>org.apache.logging.log4j</groupId>
|
||||||
|
<artifactId>log4j-slf4j-impl</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
package io.metersphere.runner;
|
||||||
|
|
||||||
|
public interface Engine {
|
||||||
|
boolean init(EngineContext context);
|
||||||
|
|
||||||
|
void start();
|
||||||
|
|
||||||
|
void stop();
|
||||||
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
package io.metersphere.runner;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
public class EngineContext {
|
||||||
|
private String engineId;
|
||||||
|
private InputStream inputStream;
|
||||||
|
|
||||||
|
public String getEngineId() {
|
||||||
|
return engineId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEngineId(String engineId) {
|
||||||
|
this.engineId = engineId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InputStream getInputStream() {
|
||||||
|
return inputStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInputStream(InputStream inputStream) {
|
||||||
|
this.inputStream = inputStream;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
package io.metersphere.runner;
|
||||||
|
|
||||||
|
import io.metersphere.base.domain.FileContent;
|
||||||
|
import io.metersphere.base.domain.LoadTestWithBLOBs;
|
||||||
|
import io.metersphere.commons.constants.LoadTestFileType;
|
||||||
|
import io.metersphere.runner.jmx.JmxEngine;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
public class EngineFactory {
|
||||||
|
public static Engine createEngine(String engineType) {
|
||||||
|
final LoadTestFileType type = LoadTestFileType.valueOf(engineType);
|
||||||
|
|
||||||
|
if (type == LoadTestFileType.JMX) {
|
||||||
|
return new JmxEngine();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static EngineContext createContext(LoadTestWithBLOBs loadTest, FileContent fileContent) {
|
||||||
|
final EngineContext engineContext = new EngineContext();
|
||||||
|
engineContext.setEngineId(loadTest.getId());
|
||||||
|
engineContext.setInputStream(new ByteArrayInputStream(fileContent.getFile().getBytes(StandardCharsets.UTF_8)));
|
||||||
|
|
||||||
|
return engineContext;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
package io.metersphere.runner;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
|
public abstract class EngineThread implements Runnable {
|
||||||
|
private Thread thread;
|
||||||
|
protected volatile boolean stopped = false;
|
||||||
|
protected boolean isDaemon = false;
|
||||||
|
|
||||||
|
private final AtomicBoolean started = new AtomicBoolean(false);
|
||||||
|
|
||||||
|
public abstract String getEngineName();
|
||||||
|
|
||||||
|
public void start() {
|
||||||
|
if (!started.compareAndSet(false, true)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
stopped = false;
|
||||||
|
this.thread = new Thread(this, getEngineName());
|
||||||
|
this.thread.setDaemon(isDaemon);
|
||||||
|
this.thread.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop() {
|
||||||
|
this.stop(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void stop(final boolean interrupt) {
|
||||||
|
if (!started.get()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.stopped = true;
|
||||||
|
|
||||||
|
if (interrupt) {
|
||||||
|
this.thread.interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public boolean isStopped() {
|
||||||
|
return stopped;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDaemon() {
|
||||||
|
return isDaemon;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDaemon(boolean daemon) {
|
||||||
|
isDaemon = daemon;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,106 @@
|
||||||
|
package io.metersphere.runner.jmx;
|
||||||
|
|
||||||
|
import io.metersphere.runner.Engine;
|
||||||
|
import io.metersphere.runner.EngineContext;
|
||||||
|
import io.metersphere.runner.EngineThread;
|
||||||
|
import io.metersphere.runner.jmx.client.DistributedRunner;
|
||||||
|
import io.metersphere.runner.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;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,167 @@
|
||||||
|
package io.metersphere.runner.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.apache.jorphan.util.JOrphanUtils;
|
||||||
|
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;
|
||||||
|
|
||||||
|
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(false, 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);//NOSONAR
|
||||||
|
log.error("Error generating the report: {}", ex.getMessage(), ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
checkForRemainingThreads();
|
||||||
|
log.info("... end of run");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs daemon thread which waits a short while;
|
||||||
|
* if JVM does not exit, lists remaining non-daemon threads on stdout.
|
||||||
|
*/
|
||||||
|
private void checkForRemainingThreads() {
|
||||||
|
// This cannot be a JMeter class variable, because properties
|
||||||
|
// are not initialised until later.
|
||||||
|
final int pauseToCheckForRemainingThreads =
|
||||||
|
JMeterUtils.getPropDefault("jmeter.exit.check.pause", 2000); // $NON-NLS-1$
|
||||||
|
|
||||||
|
if (pauseToCheckForRemainingThreads > 0) {
|
||||||
|
Thread daemon = new Thread(() -> {
|
||||||
|
try {
|
||||||
|
TimeUnit.MILLISECONDS.sleep(pauseToCheckForRemainingThreads); // Allow enough time for JVM to exit
|
||||||
|
} catch (InterruptedException ignored) {
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
// This is a daemon thread, which should only reach here if there are other
|
||||||
|
// non-daemon threads still active
|
||||||
|
System.out.println("The JVM should have exited but did not.");//NOSONAR
|
||||||
|
System.out.println("The following non-daemon threads are still running (DestroyJavaVM is OK):");//NOSONAR
|
||||||
|
JOrphanUtils.displayThreads(false);
|
||||||
|
});
|
||||||
|
daemon.setDaemon(true);
|
||||||
|
daemon.start();
|
||||||
|
} else if (pauseToCheckForRemainingThreads <= 0) {
|
||||||
|
log.debug("jmeter.exit.check.pause is <= 0, JMeter won't check for unterminated non-daemon threads");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,70 @@
|
||||||
|
package io.metersphere.runner.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";
|
||||||
|
}
|
||||||
|
}
|
|
@ -64,6 +64,10 @@ public class FileService {
|
||||||
return fileMetadataMapper.selectByPrimaryKey(loadTestFiles.get(0).getFileId());
|
return fileMetadataMapper.selectByPrimaryKey(loadTestFiles.get(0).getFileId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public FileContent getFileContent(String fileId) {
|
||||||
|
return fileContentMapper.selectByPrimaryKey(fileId);
|
||||||
|
}
|
||||||
|
|
||||||
public void deleteFileByTestId(String testId) {
|
public void deleteFileByTestId(String testId) {
|
||||||
LoadTestFileExample loadTestFileExample = new LoadTestFileExample();
|
LoadTestFileExample loadTestFileExample = new LoadTestFileExample();
|
||||||
loadTestFileExample.createCriteria().andTestIdEqualTo(testId);
|
loadTestFileExample.createCriteria().andTestIdEqualTo(testId);
|
||||||
|
|
|
@ -8,6 +8,8 @@ import io.metersphere.commons.exception.MSException;
|
||||||
import io.metersphere.commons.utils.IOUtils;
|
import io.metersphere.commons.utils.IOUtils;
|
||||||
import io.metersphere.controller.request.testplan.*;
|
import io.metersphere.controller.request.testplan.*;
|
||||||
import io.metersphere.dto.LoadTestDTO;
|
import io.metersphere.dto.LoadTestDTO;
|
||||||
|
import io.metersphere.runner.Engine;
|
||||||
|
import io.metersphere.runner.EngineFactory;
|
||||||
import org.apache.commons.lang3.RandomUtils;
|
import org.apache.commons.lang3.RandomUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
@ -151,6 +153,31 @@ public class LoadTestService {
|
||||||
MSException.throwException("无法运行测试,未找到测试:" + request.getId());
|
MSException.throwException("无法运行测试,未找到测试:" + request.getId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final FileMetadata fileMetadata = fileService.getFileMetadataByTestId(request.getId());
|
||||||
|
if (fileMetadata == null) {
|
||||||
|
MSException.throwException("无法运行测试,无法获取测试文件元信息,测试ID:" + request.getId());
|
||||||
|
}
|
||||||
|
|
||||||
|
final FileContent fileContent = fileService.getFileContent(fileMetadata.getId());
|
||||||
|
if (fileContent == null) {
|
||||||
|
MSException.throwException("无法运行测试,无法获取测试文件内容,测试ID:" + request.getId());
|
||||||
|
}
|
||||||
|
|
||||||
System.out.println("开始运行:" + loadTest.getName());
|
System.out.println("开始运行:" + loadTest.getName());
|
||||||
|
final Engine engine = EngineFactory.createEngine(fileMetadata.getType());
|
||||||
|
if (engine == null) {
|
||||||
|
MSException.throwException(String.format("无法运行测试,未识别测试文件类型,测试ID:%s,文件类型:%s",
|
||||||
|
request.getId(),
|
||||||
|
fileMetadata.getType()));
|
||||||
|
}
|
||||||
|
|
||||||
|
final boolean init = engine.init(EngineFactory.createContext(loadTest, fileContent));
|
||||||
|
if (!init) {
|
||||||
|
MSException.throwException(String.format("无法运行测试,初始化运行环境失败,测试ID:%s", request.getId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
engine.start();
|
||||||
|
|
||||||
|
/// todo:通过调用stop方法能够停止正在运行的engine,但是如果部署了多个backend实例,页面发送的停止请求如何定位到具体的engine
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue