refactor(任务中心): 重构部分执行代码,删除多余函数。
This commit is contained in:
parent
e3c9ea94f8
commit
f7dbb8be14
|
@ -3,9 +3,7 @@ package io.metersphere.api.jmeter;
|
|||
import com.alibaba.fastjson.JSON;
|
||||
import io.metersphere.api.dto.RunRequest;
|
||||
import io.metersphere.api.dto.automation.RunModeConfig;
|
||||
import io.metersphere.api.dto.scenario.request.BodyFile;
|
||||
import io.metersphere.api.service.ApiScenarioReportService;
|
||||
import io.metersphere.base.domain.JarConfig;
|
||||
import io.metersphere.base.domain.TestResource;
|
||||
import io.metersphere.base.domain.TestResourcePool;
|
||||
import io.metersphere.base.mapper.TestResourcePoolMapper;
|
||||
|
@ -13,7 +11,6 @@ import io.metersphere.commons.constants.ApiRunMode;
|
|||
import io.metersphere.commons.constants.ResourcePoolTypeEnum;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||
import io.metersphere.commons.utils.CompressUtils;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.config.JmeterProperties;
|
||||
import io.metersphere.dto.BaseSystemConfigDTO;
|
||||
|
@ -21,36 +18,23 @@ import io.metersphere.dto.NodeDTO;
|
|||
import io.metersphere.i18n.Translator;
|
||||
import io.metersphere.performance.engine.Engine;
|
||||
import io.metersphere.performance.engine.EngineFactory;
|
||||
import io.metersphere.service.JarConfigService;
|
||||
import io.metersphere.service.SystemParameterService;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.jmeter.config.Arguments;
|
||||
import org.apache.jmeter.config.CSVDataSet;
|
||||
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy;
|
||||
import org.apache.jmeter.protocol.http.util.HTTPFileArg;
|
||||
import org.apache.jmeter.save.SaveService;
|
||||
import org.apache.jmeter.util.JMeterUtils;
|
||||
import org.apache.jmeter.visualizers.backend.BackendListener;
|
||||
import org.apache.jorphan.collections.HashTree;
|
||||
import org.springframework.context.i18n.LocaleContextHolder;
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import javax.annotation.Resource;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
@Service
|
||||
public class JMeterService {
|
||||
|
@ -74,7 +58,7 @@ public class JMeterService {
|
|||
JMeterUtils.setLocale(LocaleContextHolder.getLocale());
|
||||
}
|
||||
|
||||
public void run(String testId, String debugReportId, InputStream is) {
|
||||
public void runOld(String testId, String debugReportId, InputStream is) {
|
||||
init();
|
||||
try {
|
||||
Object scriptWrapper = SaveService.loadElement(is);
|
||||
|
@ -126,195 +110,11 @@ public class JMeterService {
|
|||
testPlan.add(testPlan.getArray()[0], backendListener);
|
||||
}
|
||||
|
||||
private void addBackendListener(String testId, String debugReportId, String runMode, HashTree testPlan, RunModeConfig config) {
|
||||
BackendListener backendListener = new BackendListener();
|
||||
backendListener.setName(testId);
|
||||
Arguments arguments = new Arguments();
|
||||
arguments.addArgument(APIBackendListenerClient.TEST_ID, testId);
|
||||
if (StringUtils.isNotBlank(runMode)) {
|
||||
arguments.addArgument("runMode", runMode);
|
||||
}
|
||||
if (StringUtils.isNotBlank(debugReportId)) {
|
||||
arguments.addArgument("debugReportId", debugReportId);
|
||||
}
|
||||
backendListener.setArguments(arguments);
|
||||
backendListener.setClassname(APIBackendListenerClient.class.getCanonicalName());
|
||||
testPlan.add(testPlan.getArray()[0], backendListener);
|
||||
}
|
||||
|
||||
public void addBackendListener(String testId, HashTree testPlan) {
|
||||
BackendListener backendListener = new BackendListener();
|
||||
backendListener.setName(testId);
|
||||
Arguments arguments = new Arguments();
|
||||
arguments.addArgument(APIBackendListenerClient.TEST_ID, testId);
|
||||
backendListener.setArguments(arguments);
|
||||
backendListener.setClassname(APIBackendListenerClient.class.getCanonicalName());
|
||||
testPlan.add(testPlan.getArray()[0], backendListener);
|
||||
}
|
||||
|
||||
public void runDefinition(String testId, HashTree testPlan, String debugReportId, String runMode) {
|
||||
try {
|
||||
init();
|
||||
addBackendListener(testId, debugReportId, runMode, testPlan);
|
||||
LocalRunner runner = new LocalRunner(testPlan);
|
||||
runner.run();
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
MSException.throwException(Translator.get("api_load_script_error"));
|
||||
}
|
||||
}
|
||||
|
||||
public void runSerial(String testId, HashTree testPlan, String debugReportId, String runMode, RunModeConfig config) {
|
||||
try {
|
||||
init();
|
||||
addBackendListener(testId, debugReportId, runMode, testPlan, config);
|
||||
LocalRunner runner = new LocalRunner(testPlan);
|
||||
runner.run();
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
MSException.throwException(Translator.get("api_load_script_error"));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前jmx 涉及到的文件
|
||||
*
|
||||
* @param tree
|
||||
*/
|
||||
public void getFiles(HashTree tree, List<BodyFile> files) {
|
||||
for (Object key : tree.keySet()) {
|
||||
HashTree node = tree.get(key);
|
||||
if (key instanceof HTTPSamplerProxy) {
|
||||
HTTPSamplerProxy source = (HTTPSamplerProxy) key;
|
||||
if (source != null && source.getHTTPFiles().length > 0) {
|
||||
for (HTTPFileArg arg : source.getHTTPFiles()) {
|
||||
BodyFile file = new BodyFile();
|
||||
file.setId(arg.getParamName());
|
||||
file.setName(arg.getPath());
|
||||
files.add(file);
|
||||
}
|
||||
}
|
||||
} else if (key instanceof CSVDataSet) {
|
||||
CSVDataSet source = (CSVDataSet) key;
|
||||
if (source != null && source.getFilename() != null) {
|
||||
BodyFile file = new BodyFile();
|
||||
file.setId(source.getFilename());
|
||||
file.setName(source.getFilename());
|
||||
files.add(file);
|
||||
}
|
||||
}
|
||||
if (node != null) {
|
||||
getFiles(node, files);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] fileToByte(File tradeFile) {
|
||||
byte[] buffer = null;
|
||||
try (FileInputStream fis = new FileInputStream(tradeFile);
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();) {
|
||||
byte[] b = new byte[1024];
|
||||
int n;
|
||||
while ((n = fis.read(b)) != -1) {
|
||||
bos.write(b, 0, n);
|
||||
}
|
||||
buffer = bos.toByteArray();
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public List<Object> getZipJar() {
|
||||
List<Object> jarFiles = new LinkedList<>();
|
||||
// jar 包
|
||||
JarConfigService jarConfigService = CommonBeanFactory.getBean(JarConfigService.class);
|
||||
List<JarConfig> jars = jarConfigService.list();
|
||||
List<File> files = new ArrayList<>();
|
||||
|
||||
jars.forEach(jarConfig -> {
|
||||
String path = jarConfig.getPath();
|
||||
File file = new File(path);
|
||||
if (file.isDirectory() && !path.endsWith("/")) {
|
||||
file = new File(path + "/");
|
||||
}
|
||||
files.add(file);
|
||||
});
|
||||
|
||||
try {
|
||||
File file = CompressUtils.zipFiles(UUID.randomUUID().toString() + ".zip", files);
|
||||
FileSystemResource resource = new FileSystemResource(file);
|
||||
byte[] fileByte = this.fileToByte(file);
|
||||
if (fileByte != null) {
|
||||
ByteArrayResource byteArrayResource = new ByteArrayResource(fileByte) {
|
||||
@Override
|
||||
public String getFilename() throws IllegalStateException {
|
||||
return resource.getFilename();
|
||||
}
|
||||
};
|
||||
jarFiles.add(byteArrayResource);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return jarFiles;
|
||||
}
|
||||
|
||||
public List<Object> getJar() {
|
||||
List<Object> jarFiles = new LinkedList<>();
|
||||
// jar 包
|
||||
JarConfigService jarConfigService = CommonBeanFactory.getBean(JarConfigService.class);
|
||||
List<JarConfig> jars = jarConfigService.list();
|
||||
jars.forEach(jarConfig -> {
|
||||
try {
|
||||
String path = jarConfig.getPath();
|
||||
File file = new File(path);
|
||||
if (file.isDirectory() && !path.endsWith("/")) {
|
||||
file = new File(path + "/");
|
||||
}
|
||||
FileSystemResource resource = new FileSystemResource(file);
|
||||
byte[] fileByte = this.fileToByte(file);
|
||||
if (fileByte != null) {
|
||||
ByteArrayResource byteArrayResource = new ByteArrayResource(fileByte) {
|
||||
@Override
|
||||
public String getFilename() throws IllegalStateException {
|
||||
return resource.getFilename();
|
||||
}
|
||||
};
|
||||
jarFiles.add(byteArrayResource);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
}
|
||||
});
|
||||
return jarFiles;
|
||||
}
|
||||
|
||||
public List<Object> getMultipartFiles(HashTree hashTree) {
|
||||
List<Object> multipartFiles = new LinkedList<>();
|
||||
// 获取附件
|
||||
List<BodyFile> files = new LinkedList<>();
|
||||
getFiles(hashTree, files);
|
||||
if (CollectionUtils.isNotEmpty(files)) {
|
||||
for (BodyFile bodyFile : files) {
|
||||
File file = new File(bodyFile.getName());
|
||||
if (file != null && !file.exists()) {
|
||||
FileSystemResource resource = new FileSystemResource(file);
|
||||
byte[] fileByte = this.fileToByte(file);
|
||||
if (fileByte != null) {
|
||||
ByteArrayResource byteArrayResource = new ByteArrayResource(fileByte) {
|
||||
@Override
|
||||
public String getFilename() throws IllegalStateException {
|
||||
return resource.getFilename();
|
||||
}
|
||||
};
|
||||
multipartFiles.add(byteArrayResource);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return multipartFiles;
|
||||
public void runLocal(String testId, HashTree testPlan, String debugReportId, String runMode) {
|
||||
init();
|
||||
addBackendListener(testId, debugReportId, runMode, testPlan);
|
||||
LocalRunner runner = new LocalRunner(testPlan);
|
||||
runner.run();
|
||||
}
|
||||
|
||||
public void runTest(String testId, String reportId, String runMode, String testPlanScenarioId, RunModeConfig config) {
|
||||
|
|
|
@ -0,0 +1,568 @@
|
|||
/*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||
* contributor license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright ownership.
|
||||
* The ASF licenses this file to you under the Apache License, Version 2.0
|
||||
* (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package io.metersphere.api.jmeter;
|
||||
|
||||
import org.apache.jmeter.engine.util.NoThreadClone;
|
||||
import org.apache.jmeter.reporters.AbstractListenerElement;
|
||||
import org.apache.jmeter.reporters.Summariser;
|
||||
import org.apache.jmeter.samplers.*;
|
||||
import org.apache.jmeter.save.CSVSaveService;
|
||||
import org.apache.jmeter.save.SaveService;
|
||||
import org.apache.jmeter.services.FileServer;
|
||||
import org.apache.jmeter.testelement.TestStateListener;
|
||||
import org.apache.jmeter.testelement.property.BooleanProperty;
|
||||
import org.apache.jmeter.testelement.property.ObjectProperty;
|
||||
import org.apache.jmeter.util.JMeterUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* This class handles all saving of samples.
|
||||
* The class must be thread-safe because it is shared between threads (NoThreadClone).
|
||||
*/
|
||||
public class MsResultCollector extends AbstractListenerElement implements SampleListener, Clearable, Serializable,
|
||||
TestStateListener, Remoteable, NoThreadClone {
|
||||
/**
|
||||
* Keep track of the file writer and the configuration,
|
||||
* as the instance used to close them is not the same as the instance that creates
|
||||
* them. This means one cannot use the saved PrintWriter or use getSaveConfig()
|
||||
*/
|
||||
private static class FileEntry {
|
||||
final PrintWriter pw;
|
||||
final SampleSaveConfiguration config;
|
||||
|
||||
FileEntry(PrintWriter printWriter, SampleSaveConfiguration sampleSaveConfiguration) {
|
||||
this.pw = printWriter;
|
||||
this.config = sampleSaveConfiguration;
|
||||
}
|
||||
}
|
||||
|
||||
private static final class ShutdownHook implements Runnable {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
log.info("Shutdown hook started");
|
||||
synchronized (LOCK) {
|
||||
finalizeFileOutput();
|
||||
}
|
||||
log.info("Shutdown hook ended");
|
||||
}
|
||||
}
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(MsResultCollector.class);
|
||||
|
||||
private static final long serialVersionUID = 234L;
|
||||
|
||||
// This string is used to identify local test runs, so must not be a valid host name
|
||||
private static final String TEST_IS_LOCAL = "*local*"; // $NON-NLS-1$
|
||||
|
||||
private static final String TESTRESULTS_START = "<testResults>"; // $NON-NLS-1$
|
||||
|
||||
private static final String TESTRESULTS_START_V1_1_PREVER = "<testResults version=\""; // $NON-NLS-1$
|
||||
|
||||
private static final String TESTRESULTS_START_V1_1_POSTVER = "\">"; // $NON-NLS-1$
|
||||
|
||||
private static final String TESTRESULTS_END = "</testResults>"; // $NON-NLS-1$
|
||||
|
||||
// we have to use version 1.0, see bug 59973
|
||||
private static final String XML_HEADER = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"; // $NON-NLS-1$
|
||||
|
||||
private static final int MIN_XML_FILE_LEN = XML_HEADER.length() + TESTRESULTS_START.length()
|
||||
+ TESTRESULTS_END.length();
|
||||
|
||||
public static final String FILENAME = "filename"; // $NON-NLS-1$
|
||||
|
||||
private static final String SAVE_CONFIG = "saveConfig"; // $NON-NLS-1$
|
||||
|
||||
private static final String ERROR_LOGGING = "MsResultCollector.error_logging"; // $NON-NLS-1$
|
||||
|
||||
private static final String SUCCESS_ONLY_LOGGING = "MsResultCollector.success_only_logging"; // $NON-NLS-1$
|
||||
|
||||
/**
|
||||
* AutoFlush on each line
|
||||
*/
|
||||
private static final boolean SAVING_AUTOFLUSH = JMeterUtils.getPropDefault("jmeter.save.saveservice.autoflush", false); //$NON-NLS-1$
|
||||
|
||||
// Static variables
|
||||
|
||||
// Lock used to guard static mutable variables
|
||||
private static final Object LOCK = new Object();
|
||||
|
||||
private static final Map<String, FileEntry> files = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Shutdown Hook that ensures PrintWriter is flushed is CTRL+C or kill is called during a test
|
||||
*/
|
||||
private static Thread shutdownHook;
|
||||
|
||||
/**
|
||||
* The instance count is used to keep track of whether any tests are currently running.
|
||||
* It's not possible to use the constructor or threadStarted etc as tests may overlap
|
||||
* e.g. a remote test may be started,
|
||||
* and then a local test started whilst the remote test is still running.
|
||||
*/
|
||||
private static int instanceCount; // Keep track of how many instances are active
|
||||
|
||||
// Instance variables (guarded by volatile)
|
||||
private transient volatile PrintWriter out;
|
||||
|
||||
/**
|
||||
* Is a test running ?
|
||||
*/
|
||||
private volatile boolean inTest = false;
|
||||
|
||||
private volatile boolean isStats = false;
|
||||
|
||||
/**
|
||||
* the summarizer to which this result collector will forward the samples
|
||||
*/
|
||||
private volatile Summariser summariser;
|
||||
|
||||
/**
|
||||
* No-arg constructor.
|
||||
*/
|
||||
public MsResultCollector() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor which sets the used {@link Summariser}
|
||||
*
|
||||
* @param summer The {@link Summariser} to use
|
||||
*/
|
||||
public MsResultCollector(Summariser summer) {
|
||||
setErrorLogging(false);
|
||||
setSuccessOnlyLogging(false);
|
||||
setProperty(new ObjectProperty(SAVE_CONFIG, new SampleSaveConfiguration()));
|
||||
summariser = summer;
|
||||
}
|
||||
|
||||
// Ensure that the sample save config is not shared between copied nodes
|
||||
// N.B. clone only seems to be used for client-server tests
|
||||
@Override
|
||||
public Object clone() {
|
||||
MsResultCollector clone = (MsResultCollector) super.clone();
|
||||
clone.setSaveConfig((SampleSaveConfiguration) clone.getSaveConfig().clone());
|
||||
// Unfortunately AbstractTestElement does not call super.clone()
|
||||
clone.summariser = this.summariser;
|
||||
return clone;
|
||||
}
|
||||
|
||||
private void setFilenameProperty(String f) {
|
||||
setProperty(FILENAME, f);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the filename of the file this collector uses
|
||||
*
|
||||
* @return The name of the file
|
||||
*/
|
||||
public String getFilename() {
|
||||
return getPropertyAsString(FILENAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the state of error logging
|
||||
*
|
||||
* @return Flag whether errors should be logged
|
||||
*/
|
||||
public boolean isErrorLogging() {
|
||||
return getPropertyAsBoolean(ERROR_LOGGING);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets error logging flag
|
||||
*
|
||||
* @param errorLogging The flag whether errors should be logged
|
||||
*/
|
||||
public final void setErrorLogging(boolean errorLogging) {
|
||||
setProperty(new BooleanProperty(ERROR_LOGGING, errorLogging));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the flag whether only successful samples should be logged
|
||||
*
|
||||
* @param value The flag whether only successful samples should be logged
|
||||
*/
|
||||
public final void setSuccessOnlyLogging(boolean value) {
|
||||
if (value) {
|
||||
setProperty(new BooleanProperty(SUCCESS_ONLY_LOGGING, true));
|
||||
} else {
|
||||
removeProperty(SUCCESS_ONLY_LOGGING);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the state of successful only logging
|
||||
*
|
||||
* @return Flag whether only successful samples should be logged
|
||||
*/
|
||||
public boolean isSuccessOnlyLogging() {
|
||||
return getPropertyAsBoolean(SUCCESS_ONLY_LOGGING, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decides whether or not to a sample is wanted based on:
|
||||
* <ul>
|
||||
* <li>errorOnly</li>
|
||||
* <li>successOnly</li>
|
||||
* <li>sample success</li>
|
||||
* </ul>
|
||||
* Should only be called for single samples.
|
||||
*
|
||||
* @param success is sample successful
|
||||
* @return whether to log/display the sample
|
||||
*/
|
||||
public boolean isSampleWanted(boolean success) {
|
||||
boolean errorOnly = isErrorLogging();
|
||||
boolean successOnly = isSuccessOnlyLogging();
|
||||
return isSampleWanted(success, errorOnly, successOnly);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decides whether or not to a sample is wanted based on:
|
||||
* <ul>
|
||||
* <li>errorOnly</li>
|
||||
* <li>successOnly</li>
|
||||
* <li>sample success</li>
|
||||
* </ul>
|
||||
* This version is intended to be called by code that loops over many samples;
|
||||
* it is cheaper than fetching the settings each time.
|
||||
*
|
||||
* @param success status of sample
|
||||
* @param errorOnly if errors only wanted
|
||||
* @param successOnly if success only wanted
|
||||
* @return whether to log/display the sample
|
||||
*/
|
||||
public static boolean isSampleWanted(boolean success, boolean errorOnly,
|
||||
boolean successOnly) {
|
||||
return (!errorOnly && !successOnly) ||
|
||||
(success && successOnly) ||
|
||||
(!success && errorOnly);
|
||||
// successOnly and errorOnly cannot both be set
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the filename attribute of the MsResultCollector object.
|
||||
*
|
||||
* @param f the new filename value
|
||||
*/
|
||||
public void setFilename(String f) {
|
||||
if (inTest) {
|
||||
return;
|
||||
}
|
||||
setFilenameProperty(f);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testEnded(String host) {
|
||||
synchronized (LOCK) {
|
||||
instanceCount--;
|
||||
if (instanceCount <= 0) {
|
||||
// No need for the hook now
|
||||
// Bug 57088 - prevent (im?)possible NPE
|
||||
if (shutdownHook != null) {
|
||||
Runtime.getRuntime().removeShutdownHook(shutdownHook);
|
||||
} else {
|
||||
log.warn("Should not happen: shutdownHook==null, instanceCount={}", instanceCount);
|
||||
}
|
||||
finalizeFileOutput();
|
||||
out = null;
|
||||
inTest = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (summariser != null) {
|
||||
summariser.testEnded(host);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testStarted(String host) {
|
||||
synchronized (LOCK) {
|
||||
if (instanceCount == 0) { // Only add the hook once
|
||||
shutdownHook = new Thread(new ShutdownHook());
|
||||
Runtime.getRuntime().addShutdownHook(shutdownHook);
|
||||
}
|
||||
instanceCount++;
|
||||
try {
|
||||
if (out == null) {
|
||||
try {
|
||||
// Note: getFileWriter ignores a null filename
|
||||
out = getFileWriter(getFilename(), getSaveConfig());
|
||||
} catch (FileNotFoundException e) {
|
||||
out = null;
|
||||
}
|
||||
}
|
||||
if (getVisualizer() != null) {
|
||||
this.isStats = getVisualizer().isStats();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error("Exception occurred while initializing file output.", e);
|
||||
}
|
||||
}
|
||||
inTest = true;
|
||||
|
||||
if (summariser != null) {
|
||||
summariser.testStarted(host);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testEnded() {
|
||||
testEnded(TEST_IS_LOCAL);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void testStarted() {
|
||||
testStarted(TEST_IS_LOCAL);
|
||||
}
|
||||
|
||||
private static void writeFileStart(PrintWriter writer, SampleSaveConfiguration saveConfig) {
|
||||
if (saveConfig.saveAsXml()) {
|
||||
writer.print(XML_HEADER);
|
||||
// Write the EOL separately so we generate LF line ends on Unix and Windows
|
||||
writer.print("\n"); // $NON-NLS-1$
|
||||
String pi = saveConfig.getXmlPi();
|
||||
if (pi.length() > 0) {
|
||||
writer.println(pi);
|
||||
}
|
||||
// Can't do it as a static initialisation, because SaveService
|
||||
// is being constructed when this is called
|
||||
writer.print(TESTRESULTS_START_V1_1_PREVER);
|
||||
writer.print(SaveService.getVERSION());
|
||||
writer.print(TESTRESULTS_START_V1_1_POSTVER);
|
||||
// Write the EOL separately so we generate LF line ends on Unix and Windows
|
||||
writer.print("\n"); // $NON-NLS-1$
|
||||
} else if (saveConfig.saveFieldNames()) {
|
||||
writer.println(CSVSaveService.printableFieldNamesToString(saveConfig));
|
||||
}
|
||||
}
|
||||
|
||||
private static void writeFileEnd(PrintWriter pw, SampleSaveConfiguration saveConfig) {
|
||||
if (saveConfig.saveAsXml()) {
|
||||
pw.print("\n"); // $NON-NLS-1$
|
||||
pw.print(TESTRESULTS_END);
|
||||
pw.print("\n");// Added in version 1.1 // $NON-NLS-1$
|
||||
}
|
||||
}
|
||||
|
||||
private static PrintWriter getFileWriter(final String pFilename, SampleSaveConfiguration saveConfig)
|
||||
throws IOException {
|
||||
if (pFilename == null || pFilename.length() == 0) {
|
||||
return null;
|
||||
}
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Getting file: {} in thread {}", pFilename, Thread.currentThread().getName());
|
||||
}
|
||||
String filename = FileServer.resolveBaseRelativeName(pFilename);
|
||||
filename = new File(filename).getCanonicalPath(); // try to ensure uniqueness (Bug 60822)
|
||||
FileEntry fe = files.get(filename);
|
||||
PrintWriter writer = null;
|
||||
boolean trimmed = true;
|
||||
|
||||
if (fe == null) {
|
||||
if (saveConfig.saveAsXml()) {
|
||||
trimmed = trimLastLine(filename);
|
||||
} else {
|
||||
trimmed = new File(filename).exists();
|
||||
}
|
||||
// Find the name of the directory containing the file
|
||||
// and create it - if there is one
|
||||
File pdir = new File(filename).getParentFile();
|
||||
if (pdir != null) {
|
||||
// returns false if directory already exists, so need to check again
|
||||
if (pdir.mkdirs()) {
|
||||
if (log.isInfoEnabled()) {
|
||||
log.info("Folder at {} was created", pdir.getAbsolutePath());
|
||||
}
|
||||
} // else if might have been created by another process so not a problem
|
||||
if (!pdir.exists()) {
|
||||
log.warn("Error creating directories for {}", pdir);
|
||||
}
|
||||
}
|
||||
writer = new PrintWriter(new OutputStreamWriter(new BufferedOutputStream(new FileOutputStream(filename,
|
||||
trimmed)), SaveService.getFileEncoding(StandardCharsets.UTF_8.name())), SAVING_AUTOFLUSH);
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Opened file: {} in thread {}", filename, Thread.currentThread().getName());
|
||||
}
|
||||
files.put(filename, new FileEntry(writer, saveConfig));
|
||||
} else {
|
||||
writer = fe.pw;
|
||||
}
|
||||
if (!trimmed) {
|
||||
log.debug("Writing header to file: {}", filename);
|
||||
writeFileStart(writer, saveConfig);
|
||||
}
|
||||
return writer;
|
||||
}
|
||||
|
||||
// returns false if the file did not contain the terminator
|
||||
private static boolean trimLastLine(String filename) {
|
||||
try (RandomAccessFile raf = new RandomAccessFile(filename, "rw")) { // $NON-NLS-1$
|
||||
long len = raf.length();
|
||||
if (len < MIN_XML_FILE_LEN) {
|
||||
return false;
|
||||
}
|
||||
raf.seek(len - TESTRESULTS_END.length() - 10);
|
||||
String line;
|
||||
long pos = raf.getFilePointer();
|
||||
int end = 0;
|
||||
while ((line = raf.readLine()) != null)// reads to end of line OR end of file
|
||||
{
|
||||
end = line.indexOf(TESTRESULTS_END);
|
||||
if (end >= 0) // found the string
|
||||
{
|
||||
break;
|
||||
}
|
||||
pos = raf.getFilePointer();
|
||||
}
|
||||
if (line == null) {
|
||||
log.warn("Unexpected EOF trying to find XML end marker in {}", filename);
|
||||
return false;
|
||||
}
|
||||
raf.setLength(pos + end);// Truncate the file
|
||||
} catch (FileNotFoundException e) {
|
||||
return false;
|
||||
} catch (IOException e) {
|
||||
if (log.isWarnEnabled()) {
|
||||
log.warn("Error trying to find XML terminator. {}", e.toString());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sampleStarted(SampleEvent e) {
|
||||
// NOOP
|
||||
}
|
||||
|
||||
@Override
|
||||
public void sampleStopped(SampleEvent e) {
|
||||
// NOOP
|
||||
}
|
||||
|
||||
/**
|
||||
* When a test result is received, display it and save it.
|
||||
*
|
||||
* @param event the sample event that was received
|
||||
*/
|
||||
@Override
|
||||
public void sampleOccurred(SampleEvent event) {
|
||||
SampleResult result = event.getResult();
|
||||
log.info("*****************************" + result.getThreadName() + " == " + result.getSampleLabel());
|
||||
if (isSampleWanted(result.isSuccessful())) {
|
||||
sendToVisualizer(result);
|
||||
if (out != null && !isResultMarked(result) && !this.isStats) {
|
||||
SampleSaveConfiguration config = getSaveConfig();
|
||||
result.setSaveConfig(config);
|
||||
try {
|
||||
if (config.saveAsXml()) {
|
||||
SaveService.saveSampleResult(event, out);
|
||||
} else { // !saveAsXml
|
||||
CSVSaveService.saveSampleResult(event, out);
|
||||
}
|
||||
} catch (Exception err) {
|
||||
log.error("Error trying to record a sample", err); // should throw exception back to caller
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (summariser != null) {
|
||||
summariser.sampleOccurred(event);
|
||||
}
|
||||
}
|
||||
|
||||
protected final void sendToVisualizer(SampleResult r) {
|
||||
if (getVisualizer() != null) {
|
||||
getVisualizer().add(r);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the sample result is marked or not, and marks it
|
||||
*
|
||||
* @param res - the sample result to check
|
||||
* @return <code>true</code> if the result was marked
|
||||
*/
|
||||
private boolean isResultMarked(SampleResult res) {
|
||||
String filename = getFilename();
|
||||
return res.markFile(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Flush PrintWriter to synchronize file contents
|
||||
*/
|
||||
public void flushFile() {
|
||||
if (out != null) {
|
||||
log.info("forced flush through MsResultCollector#flushFile");
|
||||
out.flush();
|
||||
}
|
||||
}
|
||||
|
||||
private static void finalizeFileOutput() {
|
||||
for (Map.Entry<String, MsResultCollector.FileEntry> me : files.entrySet()) {
|
||||
String key = me.getKey();
|
||||
MsResultCollector.FileEntry value = me.getValue();
|
||||
try {
|
||||
log.debug("Closing: {}", key);
|
||||
writeFileEnd(value.pw, value.config);
|
||||
value.pw.close();
|
||||
if (value.pw.checkError()) {
|
||||
log.warn("Problem detected during use of {}", key);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
log.error("Error closing file {}", key, ex);
|
||||
}
|
||||
}
|
||||
files.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns the saveConfig.
|
||||
*/
|
||||
public SampleSaveConfiguration getSaveConfig() {
|
||||
try {
|
||||
return (SampleSaveConfiguration) getProperty(SAVE_CONFIG).getObjectValue();
|
||||
} catch (ClassCastException e) {
|
||||
setSaveConfig(new SampleSaveConfiguration());
|
||||
return getSaveConfig();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param saveConfig The saveConfig to set.
|
||||
*/
|
||||
public void setSaveConfig(SampleSaveConfiguration saveConfig) {
|
||||
getProperty(SAVE_CONFIG).setObjectValue(saveConfig);
|
||||
}
|
||||
|
||||
// This is required so that
|
||||
// @see org.apache.jmeter.gui.tree.JMeterTreeModel.getNodesOfType()
|
||||
// can find the Clearable nodes - the userObject has to implement the interface.
|
||||
@Override
|
||||
public void clearData() {
|
||||
// NOOP
|
||||
}
|
||||
}
|
|
@ -236,7 +236,7 @@ public class APITestService {
|
|||
mailService.sendHtml(reportId,notice,"api");
|
||||
}*/
|
||||
changeStatus(request.getId(), APITestStatus.Running);
|
||||
jMeterService.run(request.getId(), null, is);
|
||||
jMeterService.runOld(request.getId(), null, is);
|
||||
return reportId;
|
||||
}
|
||||
|
||||
|
@ -445,7 +445,7 @@ public class APITestService {
|
|||
LogUtil.error(e.getMessage(), e);
|
||||
}
|
||||
|
||||
jMeterService.run(request.getId(), reportId, is);
|
||||
jMeterService.runOld(request.getId(), reportId, is);
|
||||
return reportId;
|
||||
}
|
||||
|
||||
|
|
|
@ -1233,7 +1233,7 @@ public class ApiAutomationService {
|
|||
List<String> reportIds = new LinkedList<>();
|
||||
try {
|
||||
HashTree hashTree = generateHashTree(apiScenarios, request, reportIds);
|
||||
jMeterService.runSerial(JSON.toJSONString(reportIds), hashTree, request.getReportId(), runMode, request.getConfig());
|
||||
jMeterService.runLocal(JSON.toJSONString(reportIds), hashTree, request.getReportId(), runMode);
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e.getMessage());
|
||||
MSException.throwException(e.getMessage());
|
||||
|
@ -1334,7 +1334,7 @@ public class ApiAutomationService {
|
|||
FileUtils.createBodyFiles(request.getScenarioFileIds(), scenarioFiles);
|
||||
|
||||
// 调用执行方法
|
||||
jMeterService.runDefinition(request.getId(), hashTree, request.getReportId(), ApiRunMode.SCENARIO.name());
|
||||
jMeterService.runLocal(request.getId(), hashTree, request.getReportId(), ApiRunMode.SCENARIO.name());
|
||||
return request.getId();
|
||||
}
|
||||
|
||||
|
|
|
@ -593,7 +593,7 @@ public class ApiDefinitionService {
|
|||
if (request.getConfig() != null && StringUtils.isNotBlank(request.getConfig().getResourcePoolId())) {
|
||||
jMeterService.runTest(request.getId(), request.getId(), runMode, null, request.getConfig());
|
||||
} else {
|
||||
jMeterService.runDefinition(request.getId(), hashTree, request.getReportId(), runMode);
|
||||
jMeterService.runLocal(request.getId(), hashTree, request.getReportId(), runMode);
|
||||
}
|
||||
return request.getId();
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import io.metersphere.base.mapper.TestPlanApiScenarioMapper;
|
|||
import io.metersphere.commons.constants.ApiRunMode;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.commons.utils.CommonBeanFactory;
|
||||
import io.metersphere.commons.utils.FileUtils;
|
||||
import io.metersphere.commons.utils.LogUtil;
|
||||
import io.metersphere.service.JarConfigService;
|
||||
import io.metersphere.track.service.TestPlanApiCaseService;
|
||||
|
@ -91,7 +92,7 @@ public class ApiJmeterFileService {
|
|||
if (file.isDirectory() && !path.endsWith("/")) {
|
||||
file = new File(path + "/");
|
||||
}
|
||||
byte[] fileByte = jMeterService.fileToByte(file);
|
||||
byte[] fileByte = FileUtils.fileToByte(file);
|
||||
if (fileByte != null) {
|
||||
jarFiles.put(file.getName(), fileByte);
|
||||
}
|
||||
|
@ -106,12 +107,12 @@ public class ApiJmeterFileService {
|
|||
Map<String, byte[]> multipartFiles = new LinkedHashMap<>();
|
||||
// 获取附件
|
||||
List<BodyFile> files = new LinkedList<>();
|
||||
jMeterService.getFiles(hashTree, files);
|
||||
FileUtils.getFiles(hashTree, files);
|
||||
if (CollectionUtils.isNotEmpty(files)) {
|
||||
for (BodyFile bodyFile : files) {
|
||||
File file = new File(bodyFile.getName());
|
||||
if (file != null && !file.exists()) {
|
||||
byte[] fileByte = jMeterService.fileToByte(file);
|
||||
byte[] fileByte = FileUtils.fileToByte(file);
|
||||
if (fileByte != null) {
|
||||
multipartFiles.put(file.getName(), fileByte);
|
||||
}
|
||||
|
|
|
@ -606,7 +606,7 @@ public class ApiTestCaseService {
|
|||
String runMode = ApiRunMode.JENKINS.name();
|
||||
*/
|
||||
// 调用执行方法
|
||||
jMeterService.runDefinition(request.getCaseId(), jmeterHashTree, request.getReportId(), request.getRunMode());
|
||||
jMeterService.runLocal(request.getCaseId(), jmeterHashTree, request.getReportId(), request.getRunMode());
|
||||
|
||||
} catch (Exception ex) {
|
||||
LogUtil.error(ex.getMessage());
|
||||
|
@ -625,7 +625,7 @@ public class ApiTestCaseService {
|
|||
request.setTestPlanId(testPlanID);
|
||||
HashTree jmeterHashTree = this.generateHashTree(request, apiCaseBolbs);
|
||||
// 调用执行方法
|
||||
jMeterService.runDefinition(id, jmeterHashTree, debugReportId, runMode);
|
||||
jMeterService.runLocal(id, jmeterHashTree, debugReportId, runMode);
|
||||
} catch (Exception ex) {
|
||||
LogUtil.error(ex.getMessage());
|
||||
}
|
||||
|
|
|
@ -29,7 +29,7 @@ public class ParallelScenarioExecTask<T> implements Callable<T> {
|
|||
if (request.getConfig() != null && StringUtils.isNotBlank(request.getConfig().getResourcePoolId())) {
|
||||
jMeterService.runTest(runModeDataDTO.getTestId(), runModeDataDTO.getReportId(), request.getRunMode(), request.getPlanScenarioId(), request.getConfig());
|
||||
} else {
|
||||
jMeterService.runSerial(runModeDataDTO.getReportId(), runModeDataDTO.getHashTree(), request.getReportId(), request.getRunMode(), request.getConfig());
|
||||
jMeterService.runLocal(runModeDataDTO.getReportId(), runModeDataDTO.getHashTree(), request.getReportId(), request.getRunMode());
|
||||
}
|
||||
return null;
|
||||
} catch (Exception ex) {
|
||||
|
|
|
@ -35,7 +35,7 @@ public class SerialScenarioExecTask<T> implements Callable<T> {
|
|||
if (request.getConfig() != null && StringUtils.isNotBlank(request.getConfig().getResourcePoolId())) {
|
||||
jMeterService.runTest(runModeDataDTO.getTestId(), runModeDataDTO.getReportId(), request.getRunMode(), request.getPlanScenarioId(), request.getConfig());
|
||||
} else {
|
||||
jMeterService.runSerial(runModeDataDTO.getReportId(), runModeDataDTO.getHashTree(), request.getReportId(), request.getRunMode(), request.getConfig());
|
||||
jMeterService.runLocal(runModeDataDTO.getReportId(), runModeDataDTO.getHashTree(), request.getReportId(), request.getRunMode());
|
||||
}
|
||||
// 轮询查看报告状态,最多200次,防止死循环
|
||||
int index = 1;
|
||||
|
|
|
@ -1,13 +1,24 @@
|
|||
package io.metersphere.commons.utils;
|
||||
|
||||
import io.metersphere.api.dto.scenario.request.BodyFile;
|
||||
import io.metersphere.base.domain.JarConfig;
|
||||
import io.metersphere.commons.exception.MSException;
|
||||
import io.metersphere.i18n.Translator;
|
||||
import io.metersphere.service.JarConfigService;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.jmeter.config.CSVDataSet;
|
||||
import org.apache.jmeter.protocol.http.sampler.HTTPSamplerProxy;
|
||||
import org.apache.jmeter.protocol.http.util.HTTPFileArg;
|
||||
import org.apache.jorphan.collections.HashTree;
|
||||
import org.aspectj.util.FileUtil;
|
||||
import org.springframework.core.io.ByteArrayResource;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -135,4 +146,146 @@ public class FileUtils {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 获取当前jmx 涉及到的文件
|
||||
*
|
||||
* @param tree
|
||||
*/
|
||||
public static void getFiles(HashTree tree, List<BodyFile> files) {
|
||||
for (Object key : tree.keySet()) {
|
||||
HashTree node = tree.get(key);
|
||||
if (key instanceof HTTPSamplerProxy) {
|
||||
HTTPSamplerProxy source = (HTTPSamplerProxy) key;
|
||||
if (source != null && source.getHTTPFiles().length > 0) {
|
||||
for (HTTPFileArg arg : source.getHTTPFiles()) {
|
||||
BodyFile file = new BodyFile();
|
||||
file.setId(arg.getParamName());
|
||||
file.setName(arg.getPath());
|
||||
files.add(file);
|
||||
}
|
||||
}
|
||||
} else if (key instanceof CSVDataSet) {
|
||||
CSVDataSet source = (CSVDataSet) key;
|
||||
if (source != null && source.getFilename() != null) {
|
||||
BodyFile file = new BodyFile();
|
||||
file.setId(source.getFilename());
|
||||
file.setName(source.getFilename());
|
||||
files.add(file);
|
||||
}
|
||||
}
|
||||
if (node != null) {
|
||||
getFiles(node, files);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static byte[] fileToByte(File tradeFile) {
|
||||
byte[] buffer = null;
|
||||
try (FileInputStream fis = new FileInputStream(tradeFile);
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();) {
|
||||
byte[] b = new byte[1024];
|
||||
int n;
|
||||
while ((n = fis.read(b)) != -1) {
|
||||
bos.write(b, 0, n);
|
||||
}
|
||||
buffer = bos.toByteArray();
|
||||
} catch (Exception e) {
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
|
||||
public List<Object> getZipJar() {
|
||||
List<Object> jarFiles = new LinkedList<>();
|
||||
// jar 包
|
||||
JarConfigService jarConfigService = CommonBeanFactory.getBean(JarConfigService.class);
|
||||
List<JarConfig> jars = jarConfigService.list();
|
||||
List<File> files = new ArrayList<>();
|
||||
|
||||
jars.forEach(jarConfig -> {
|
||||
String path = jarConfig.getPath();
|
||||
File file = new File(path);
|
||||
if (file.isDirectory() && !path.endsWith("/")) {
|
||||
file = new File(path + "/");
|
||||
}
|
||||
files.add(file);
|
||||
});
|
||||
|
||||
try {
|
||||
File file = CompressUtils.zipFiles(UUID.randomUUID().toString() + ".zip", files);
|
||||
FileSystemResource resource = new FileSystemResource(file);
|
||||
byte[] fileByte = this.fileToByte(file);
|
||||
if (fileByte != null) {
|
||||
ByteArrayResource byteArrayResource = new ByteArrayResource(fileByte) {
|
||||
@Override
|
||||
public String getFilename() throws IllegalStateException {
|
||||
return resource.getFilename();
|
||||
}
|
||||
};
|
||||
jarFiles.add(byteArrayResource);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return jarFiles;
|
||||
}
|
||||
|
||||
public List<Object> getJar() {
|
||||
List<Object> jarFiles = new LinkedList<>();
|
||||
// jar 包
|
||||
JarConfigService jarConfigService = CommonBeanFactory.getBean(JarConfigService.class);
|
||||
List<JarConfig> jars = jarConfigService.list();
|
||||
jars.forEach(jarConfig -> {
|
||||
try {
|
||||
String path = jarConfig.getPath();
|
||||
File file = new File(path);
|
||||
if (file.isDirectory() && !path.endsWith("/")) {
|
||||
file = new File(path + "/");
|
||||
}
|
||||
FileSystemResource resource = new FileSystemResource(file);
|
||||
byte[] fileByte = this.fileToByte(file);
|
||||
if (fileByte != null) {
|
||||
ByteArrayResource byteArrayResource = new ByteArrayResource(fileByte) {
|
||||
@Override
|
||||
public String getFilename() throws IllegalStateException {
|
||||
return resource.getFilename();
|
||||
}
|
||||
};
|
||||
jarFiles.add(byteArrayResource);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
LogUtil.error(e.getMessage(), e);
|
||||
}
|
||||
});
|
||||
return jarFiles;
|
||||
}
|
||||
|
||||
public List<Object> getMultipartFiles(HashTree hashTree) {
|
||||
List<Object> multipartFiles = new LinkedList<>();
|
||||
// 获取附件
|
||||
List<BodyFile> files = new LinkedList<>();
|
||||
getFiles(hashTree, files);
|
||||
if (CollectionUtils.isNotEmpty(files)) {
|
||||
for (BodyFile bodyFile : files) {
|
||||
File file = new File(bodyFile.getName());
|
||||
if (file != null && !file.exists()) {
|
||||
FileSystemResource resource = new FileSystemResource(file);
|
||||
byte[] fileByte = this.fileToByte(file);
|
||||
if (fileByte != null) {
|
||||
ByteArrayResource byteArrayResource = new ByteArrayResource(fileByte) {
|
||||
@Override
|
||||
public String getFilename() throws IllegalStateException {
|
||||
return resource.getFilename();
|
||||
}
|
||||
};
|
||||
multipartFiles.add(byteArrayResource);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return multipartFiles;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -933,7 +933,7 @@ public class TestPlanService {
|
|||
testPlan.toHashTree(jmeterHashTree, testPlan.getHashTree(), new ParameterConfig());
|
||||
String runMode = ApiRunMode.SCHEDULE_SCENARIO_PLAN.name();
|
||||
// 调用执行方法
|
||||
jMeterService.runDefinition(request.getId(), jmeterHashTree, request.getReportId(), runMode);
|
||||
jMeterService.runLocal(request.getId(), jmeterHashTree, request.getReportId(), runMode);
|
||||
}
|
||||
|
||||
return returnId;
|
||||
|
|
|
@ -34,7 +34,7 @@ public class ParallelApiExecTask<T> implements Callable<T> {
|
|||
if (config != null && StringUtils.isNotBlank(config.getResourcePoolId())) {
|
||||
jMeterService.runTest(runModeDataDTO.getTestId(), runModeDataDTO.getReportId(), runMode, null, config);
|
||||
} else {
|
||||
jMeterService.runDefinition(runModeDataDTO.getReportId(), runModeDataDTO.getHashTree(), null, runMode);
|
||||
jMeterService.runLocal(runModeDataDTO.getReportId(), runModeDataDTO.getHashTree(), null, runMode);
|
||||
}
|
||||
return null;
|
||||
} catch (Exception ex) {
|
||||
|
|
|
@ -36,7 +36,7 @@ public class SerialApiExecTask<T> implements Callable<T> {
|
|||
if (config != null && StringUtils.isNotBlank(config.getResourcePoolId())) {
|
||||
jMeterService.runTest(runModeDataDTO.getTestId(), runModeDataDTO.getReportId(), runMode, null, config);
|
||||
} else {
|
||||
jMeterService.runDefinition(runModeDataDTO.getReportId(), runModeDataDTO.getHashTree(), null, runMode);
|
||||
jMeterService.runLocal(runModeDataDTO.getReportId(), runModeDataDTO.getHashTree(), null, runMode);
|
||||
}
|
||||
// 轮询查看报告状态,最多200次,防止死循环
|
||||
ApiDefinitionExecResult report = null;
|
||||
|
|
Loading…
Reference in New Issue