/* * SoapUI, Copyright (C) 2004-2016 SmartBear Software * * Licensed under the EUPL, Version 1.1 or - as soon as they will be approved by the European Commission - subsequent * versions of the EUPL (the "Licence"); * You may not use this work except in compliance with the Licence. * You may obtain a copy of the Licence at: * * http://ec.europa.eu/idabc/eupl * * Unless required by applicable law or agreed to in writing, software distributed under the Licence is * distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either * express or implied. See the Licence for the specific language governing permissions and limitations * under the Licence. */ package com.eviware.soapui.impl.wsdl.loadtest; import com.eviware.soapui.SoapUI; import com.eviware.soapui.config.LoadStrategyConfig; import com.eviware.soapui.config.LoadTestAssertionConfig; import com.eviware.soapui.config.LoadTestConfig; import com.eviware.soapui.config.LoadTestLimitTypesConfig; import com.eviware.soapui.config.LoadTestLimitTypesConfig.Enum; import com.eviware.soapui.impl.wsdl.AbstractWsdlModelItem; import com.eviware.soapui.impl.wsdl.loadtest.assertions.AbstractLoadTestAssertion; import com.eviware.soapui.impl.wsdl.loadtest.assertions.LoadTestAssertionRegistry; import com.eviware.soapui.impl.wsdl.loadtest.data.LoadTestStatistics; import com.eviware.soapui.impl.wsdl.loadtest.log.LoadTestLog; import com.eviware.soapui.impl.wsdl.loadtest.log.LoadTestLogErrorEntry; import com.eviware.soapui.impl.wsdl.loadtest.strategy.BurstLoadStrategy; import com.eviware.soapui.impl.wsdl.loadtest.strategy.LoadStrategy; import com.eviware.soapui.impl.wsdl.loadtest.strategy.LoadStrategyFactory; import com.eviware.soapui.impl.wsdl.loadtest.strategy.LoadStrategyRegistry; import com.eviware.soapui.impl.wsdl.loadtest.strategy.SimpleLoadStrategy; import com.eviware.soapui.impl.wsdl.support.Configurable; import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase; import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCaseRunner; import com.eviware.soapui.impl.wsdl.teststeps.SimplePathPropertySupport; import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestStep; import com.eviware.soapui.model.support.LoadTestRunListenerAdapter; import com.eviware.soapui.model.testsuite.LoadTest; import com.eviware.soapui.model.testsuite.LoadTestRunContext; import com.eviware.soapui.model.testsuite.LoadTestRunListener; import com.eviware.soapui.model.testsuite.LoadTestRunner; import com.eviware.soapui.model.testsuite.TestCaseRunContext; import com.eviware.soapui.model.testsuite.TestCaseRunner; import com.eviware.soapui.model.testsuite.TestRunnable; import com.eviware.soapui.model.testsuite.TestRunner; import com.eviware.soapui.model.testsuite.TestRunner.Status; import com.eviware.soapui.model.testsuite.TestStepResult; import com.eviware.soapui.settings.HttpSettings; import com.eviware.soapui.support.StringUtils; import com.eviware.soapui.support.scripting.SoapUIScriptEngine; import com.eviware.soapui.support.scripting.SoapUIScriptEngineRegistry; import com.eviware.soapui.support.types.StringList; import com.eviware.soapui.support.types.StringToObjectMap; import org.apache.commons.collections.list.TreeList; import org.apache.log4j.Logger; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.File; import java.io.FileNotFoundException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Date; import java.util.HashSet; import java.util.List; import java.util.Set; /** * TestCase implementation for LoadTests * * @author Ole.Matzura * @todo add assertionFailed event to LoadTestListener * @todo create and return LoadTestAssertionResult from load-test assertions */ @SuppressWarnings("unchecked") public class WsdlLoadTest extends AbstractWsdlModelItem<LoadTestConfig> implements LoadTest, TestRunnable { public final static String THREADCOUNT_PROPERTY = WsdlLoadTest.class.getName() + "@threadcount"; public final static String STARTDELAY_PROPERTY = WsdlLoadTest.class.getName() + "@startdelay"; public final static String TESTLIMIT_PROPERTY = WsdlLoadTest.class.getName() + "@testlimit"; public final static String HISTORYLIMIT_PROPERTY = WsdlLoadTest.class.getName() + "@historylimit"; public final static String LIMITTYPE_PROPERRY = WsdlLoadTest.class.getName() + "@limittype"; public final static String SAMPLEINTERVAL_PROPERRY = WsdlLoadTest.class.getName() + "@sample-interval"; public static final String MAXASSERTIONERRORS_PROPERTY = WsdlLoadTest.class.getName() + "@max-assertion-errors"; public final static String SETUP_SCRIPT_PROPERTY = WsdlTestCase.class.getName() + "@setupScript"; public final static String TEARDOWN_SCRIPT_PROPERTY = WsdlTestCase.class.getName() + "@tearDownScript"; private final static Logger logger = Logger.getLogger(WsdlLoadTest.class); public static final int DEFAULT_STRATEGY_INTERVAL = 500; public static final String ICON_NAME = "/loadTest.png"; private InternalTestRunListener internalTestRunListener = new InternalTestRunListener(); private WsdlTestCase testCase; private LoadTestStatistics statisticsModel; private LoadStrategy loadStrategy = new BurstLoadStrategy(this); private LoadTestLog loadTestLog; private LoadStrategyConfigurationChangeListener loadStrategyListener = new LoadStrategyConfigurationChangeListener(); private List<LoadTestAssertion> assertions = new ArrayList<LoadTestAssertion>(); private ConfigurationChangePropertyListener configurationChangeListener = new ConfigurationChangePropertyListener(); private Set<LoadTestListener> loadTestListeners = new HashSet<LoadTestListener>(); private Set<LoadTestRunListener> loadTestRunListeners = new HashSet<LoadTestRunListener>(); private List<LoadTestLogErrorEntry> assertionErrors = new TreeList(); private WsdlLoadTestRunner runner; private StatisticsLogger statisticsLogger = new StatisticsLogger(); private SoapUIScriptEngine setupScriptEngine; private SoapUIScriptEngine tearDownScriptEngine; @SuppressWarnings("unused") private SimplePathPropertySupport logFolder; private LoadTestRunListener[] loadTestRunListenersArray; public WsdlLoadTest(WsdlTestCase testCase, LoadTestConfig config) { super(config, testCase, ICON_NAME); this.testCase = testCase; if (getConfig().getThreadCount() < 1) { getConfig().setThreadCount(5); } if (getConfig().getLimitType() == null) { getConfig().setLimitType(LoadTestLimitTypesConfig.TIME); getConfig().setTestLimit(60); } if (!getConfig().isSetHistoryLimit()) { getConfig().setHistoryLimit(-1); } addLoadTestRunListener(internalTestRunListener); LoadStrategyConfig ls = getConfig().getLoadStrategy(); if (ls == null) { ls = getConfig().addNewLoadStrategy(); ls.setType(SimpleLoadStrategy.STRATEGY_TYPE); } LoadStrategyFactory factory = LoadStrategyRegistry.getInstance().getFactory(ls.getType()); if (factory == null) { ls.setType(SimpleLoadStrategy.STRATEGY_TYPE); factory = LoadStrategyRegistry.getInstance().getFactory(ls.getType()); } loadStrategy = factory.build(ls.getConfig(), this); loadStrategy.addConfigurationChangeListener(loadStrategyListener); addLoadTestRunListener(loadStrategy); statisticsModel = new LoadTestStatistics(this); if (getConfig().xgetSampleInterval() == null) { setSampleInterval(LoadTestStatistics.DEFAULT_SAMPLE_INTERVAL); } statisticsModel.setUpdateFrequency(getSampleInterval()); List<LoadTestAssertionConfig> assertionList = getConfig().getAssertionList(); for (LoadTestAssertionConfig assertionConfig : assertionList) { AbstractLoadTestAssertion assertion = LoadTestAssertionRegistry.buildAssertion(assertionConfig, this); if (assertion != null) { assertions.add(assertion); assertion.addPropertyChangeListener(LoadTestAssertion.CONFIGURATION_PROPERTY, configurationChangeListener); } else { logger.warn("Failed to build LoadTestAssertion from getConfig() [" + assertionConfig + "]"); } } if (getConfig().xgetResetStatisticsOnThreadCountChange() == null) { getConfig().setResetStatisticsOnThreadCountChange(true); } if (getConfig().xgetCalculateTPSOnTimePassed() == null) { getConfig().setCalculateTPSOnTimePassed(true); } if (!getConfig().isSetMaxAssertionErrors()) { getConfig().setMaxAssertionErrors(100); } if (getConfig().xgetCancelExcessiveThreads() == null) { getConfig().setCancelExcessiveThreads(true); } if (getConfig().xgetStrategyInterval() == null) { getConfig().setStrategyInterval(DEFAULT_STRATEGY_INTERVAL); } loadTestLog = new LoadTestLog(this); for (LoadTestRunListener listener : SoapUI.getListenerRegistry().getListeners(LoadTestRunListener.class)) { addLoadTestRunListener(listener); } // set close-connections to same as global so override works ok if (!getSettings().isSet(HttpSettings.CLOSE_CONNECTIONS)) { getSettings().setBoolean(HttpSettings.CLOSE_CONNECTIONS, SoapUI.getSettings().getBoolean(HttpSettings.CLOSE_CONNECTIONS)); } } public LoadTestStatistics getStatisticsModel() { return statisticsModel; } public StatisticsLogger getStatisticsLogger() { return statisticsLogger; } public long getThreadCount() { return getConfig().getThreadCount(); } public void setThreadCount(long threadCount) { long oldCount = getThreadCount(); if (threadCount == oldCount) { return; } if (getLogStatisticsOnThreadChange() && isRunning()) { statisticsLogger.logStatistics("ThreadCount change from " + oldCount + " to " + threadCount); } getConfig().setThreadCount((int) threadCount); notifyPropertyChanged(THREADCOUNT_PROPERTY, oldCount, threadCount); } public boolean getResetStatisticsOnThreadCountChange() { return getConfig().getResetStatisticsOnThreadCountChange(); } public void setResetStatisticsOnThreadCountChange(boolean value) { getConfig().setResetStatisticsOnThreadCountChange(value); } public boolean getCancelOnReachedLimit() { return getConfig().getCancelOnReachedLimit(); } public void setCancelOnReachedLimit(boolean value) { getConfig().setCancelOnReachedLimit(value); } public boolean getCancelExcessiveThreads() { return getConfig().getCancelExcessiveThreads(); } public void setCancelExcessiveThreads(boolean value) { getConfig().setCancelExcessiveThreads(value); } public boolean getLogStatisticsOnThreadChange() { return getConfig().getLogStatisticsOnThreadChange(); } public void setLogStatisticsOnThreadChange(boolean value) { getConfig().setLogStatisticsOnThreadChange(value); } public String getStatisticsLogFolder() { return getConfig().getStatisticsLogFolder(); } public void setStatisticsLogFolder(String value) { getConfig().setStatisticsLogFolder(value); } public boolean getCalculateTPSOnTimePassed() { return getConfig().getCalculateTPSOnTimePassed(); } public void setCalculateTPSOnTimePassed(boolean value) { getConfig().setCalculateTPSOnTimePassed(value); } public int getStartDelay() { return getConfig().getStartDelay(); } public void setStartDelay(int startDelay) { if (startDelay < 0) { return; } int oldDelay = getStartDelay(); getConfig().setStartDelay(startDelay); notifyPropertyChanged(STARTDELAY_PROPERTY, oldDelay, startDelay); } public long getHistoryLimit() { return getConfig().getHistoryLimit(); } public void setHistoryLimit(long historyLimit) { long oldLimit = getHistoryLimit(); getConfig().setHistoryLimit(historyLimit); if (historyLimit == 0) { notifyPropertyChanged(HISTORYLIMIT_PROPERTY, oldLimit, historyLimit); } } public long getTestLimit() { return getConfig().getTestLimit(); } public void setTestLimit(long testLimit) { if (testLimit < 0) { return; } long oldLimit = getTestLimit(); getConfig().setTestLimit(testLimit); notifyPropertyChanged(TESTLIMIT_PROPERTY, oldLimit, testLimit); } public long getMaxAssertionErrors() { return getConfig().getMaxAssertionErrors(); } public void setMaxAssertionErrors(long testLimit) { if (testLimit < 0) { return; } long oldLimit = getMaxAssertionErrors(); getConfig().setMaxAssertionErrors(testLimit); notifyPropertyChanged(MAXASSERTIONERRORS_PROPERTY, oldLimit, testLimit); } public long getStatisticsLogInterval() { return getConfig().getStatisticsLogInterval(); } public void setStatisticsLogInterval(int sampleInterval) { if (sampleInterval < 0) { return; } long oldInterval = getStatisticsLogInterval(); getConfig().setStatisticsLogInterval(sampleInterval); notifyPropertyChanged(SAMPLEINTERVAL_PROPERRY, oldInterval, sampleInterval); if (oldInterval == 0 && sampleInterval > 0 && isRunning()) { statisticsLogger.start(); } } public long getSampleInterval() { return getConfig().getSampleInterval(); } public void setSampleInterval(int sampleInterval) { if (sampleInterval < 0) { return; } long oldInterval = getSampleInterval(); getConfig().setSampleInterval(sampleInterval); statisticsModel.setUpdateFrequency(sampleInterval); notifyPropertyChanged(SAMPLEINTERVAL_PROPERRY, oldInterval, sampleInterval); } public Enum getLimitType() { return getConfig().getLimitType(); } public void setLimitType(Enum limitType) { if (limitType == null) { return; } Enum oldType = getLimitType(); getConfig().setLimitType(limitType); notifyPropertyChanged(LIMITTYPE_PROPERRY, oldType, limitType); } public WsdlTestCase getTestCase() { return testCase; } public synchronized WsdlLoadTestRunner run() { getStatisticsModel().reset(); if (runner != null && runner.getStatus() == Status.RUNNING) { return null; } if (runner != null) { runner.release(); } assertionErrors.clear(); runner = new WsdlLoadTestRunner(this); runner.start(); return runner; } private class InternalTestRunListener extends LoadTestRunListenerAdapter { @Override public void afterLoadTest(LoadTestRunner loadTestRunner, LoadTestRunContext context) { statisticsLogger.finish(); } @Override public void beforeLoadTest(LoadTestRunner loadTestRunner, LoadTestRunContext context) { statisticsLogger.init(context); if (getStatisticsLogInterval() > 0) { statisticsLogger.start(); } } @Override public void afterTestCase(LoadTestRunner loadTestRunner, LoadTestRunContext context, TestCaseRunner testRunner, TestCaseRunContext runContext) { if (!assertions.isEmpty()) { for (LoadTestAssertion assertion : assertions) { String error = assertion.assertResults(loadTestRunner, context, testRunner, runContext); if (error != null) { int threadIndex = 0; try { threadIndex = Integer.parseInt(runContext.getProperty("ThreadIndex").toString()); } catch (Throwable t) { } loadTestLog.addEntry(new LoadTestLogErrorEntry(assertion.getName(), error, assertion.getIcon(), threadIndex)); statisticsModel.addError(LoadTestStatistics.TOTAL); } } } } @Override public void afterTestStep(LoadTestRunner loadTestRunner, LoadTestRunContext context, TestCaseRunner testRunner, TestCaseRunContext runContext, TestStepResult result) { boolean added = false; if (!assertions.isEmpty()) { for (LoadTestAssertion assertion : assertions) { String error = assertion.assertResult(loadTestRunner, context, result, testRunner, runContext); if (error != null) { int indexOfTestStep = testRunner.getTestCase().getIndexOfTestStep(result.getTestStep()); int threadIndex = 0; try { threadIndex = Integer.parseInt(runContext.getProperty("ThreadIndex").toString()); } catch (Throwable t) { } LoadTestLogErrorEntry errorEntry = new LoadTestLogErrorEntry(assertion.getName(), error, result, assertion.getIcon(), threadIndex); loadTestLog.addEntry(errorEntry); statisticsModel.addError(indexOfTestStep); long maxAssertionErrors = getMaxAssertionErrors(); if (maxAssertionErrors > 0) { synchronized (assertionErrors) { assertionErrors.add(errorEntry); while (assertionErrors.size() > maxAssertionErrors) { assertionErrors.remove(0).discard(); } } } added = true; } } } // discard if set to discard and there were no errors if (!added) { if (getTestCase().getDiscardOkResults() || getTestCase().getMaxResults() == 0) { result.discard(); } else if (getTestCase().getMaxResults() > 0 && testRunner instanceof WsdlTestCaseRunner) { ((WsdlTestCaseRunner) testRunner).enforceMaxResults(getTestCase().getMaxResults()); } } } } public LoadStrategy getLoadStrategy() { return loadStrategy; } public void setLoadStrategy(LoadStrategy loadStrategy) { this.loadStrategy.removeConfigurationChangeListener(loadStrategyListener); removeLoadTestRunListener(this.loadStrategy); this.loadStrategy = loadStrategy; this.loadStrategy.addConfigurationChangeListener(loadStrategyListener); addLoadTestRunListener(this.loadStrategy); getConfig().getLoadStrategy().setType(loadStrategy.getType()); getConfig().getLoadStrategy().setConfig(loadStrategy.getConfig()); } private class LoadStrategyConfigurationChangeListener implements PropertyChangeListener { public void propertyChange(PropertyChangeEvent evt) { getConfig().getLoadStrategy().setConfig(loadStrategy.getConfig()); } } public LoadTestAssertion addAssertion(String type, String targetStep, boolean showConfig) { LoadTestAssertion assertion = LoadTestAssertionRegistry.createAssertion(type, this); assertion.setTargetStep(targetStep); if (assertion instanceof Configurable && showConfig) { if (!((Configurable) assertion).configure()) { return null; } } assertions.add(assertion); getConfig().addNewAssertion().set(assertion.getConfiguration()); assertion.addPropertyChangeListener(LoadTestAssertion.CONFIGURATION_PROPERTY, configurationChangeListener); fireAssertionAdded(assertion); return assertion; } public void removeAssertion(LoadTestAssertion assertion) { int ix = assertions.indexOf(assertion); if (ix >= 0) { try { assertions.remove(ix); fireAssertionRemoved(assertion); } finally { assertion.removePropertyChangeListener(configurationChangeListener); assertion.release(); getConfig().removeAssertion(ix); } } } private void fireAssertionRemoved(LoadTestAssertion assertion) { if (!loadTestListeners.isEmpty()) { LoadTestListener[] l = loadTestListeners.toArray(new LoadTestListener[loadTestListeners.size()]); for (LoadTestListener listener : l) { listener.assertionRemoved(assertion); } } } private void fireAssertionAdded(LoadTestAssertion assertion) { if (!loadTestListeners.isEmpty()) { LoadTestListener[] l = loadTestListeners.toArray(new LoadTestListener[loadTestListeners.size()]); for (LoadTestListener listener : l) { listener.assertionAdded(assertion); } } } public int getAssertionCount() { return assertions.size(); } public LoadTestAssertion getAssertionAt(int index) { return index < 0 || index >= assertions.size() ? null : assertions.get(index); } public LoadTestAssertion getAssertionByName(String name) { for (LoadTestAssertion assertion : assertions) { if (assertion.getName().equals(name)) { return assertion; } } return null; } private class ConfigurationChangePropertyListener implements PropertyChangeListener { public void propertyChange(PropertyChangeEvent evt) { int ix = assertions.indexOf(evt.getSource()); if (ix >= 0) { getConfig().getAssertionArray(ix).set(assertions.get(ix).getConfiguration()); } } } public LoadTestLog getLoadTestLog() { return loadTestLog; } public List<LoadTestAssertion> getAssertionList() { return assertions; } public void addLoadTestListener(LoadTestListener listener) { loadTestListeners.add(listener); } public void removeLoadTestListener(LoadTestListener listener) { loadTestListeners.remove(listener); } public void addLoadTestRunListener(LoadTestRunListener listener) { loadTestRunListeners.add(listener); loadTestRunListenersArray = null; } public void removeLoadTestRunListener(LoadTestRunListener listener) { loadTestRunListeners.remove(listener); loadTestRunListenersArray = null; } public LoadTestRunListener[] getLoadTestRunListeners() { if (loadTestRunListenersArray == null) { loadTestRunListenersArray = loadTestRunListeners .toArray(new LoadTestRunListener[loadTestRunListeners.size()]); } return loadTestRunListenersArray; } /** * Release internal objects so they can remove listeners */ @Override public void release() { super.release(); statisticsModel.release(); loadTestLog.release(); for (LoadTestAssertion assertion : assertions) { assertion.release(); } loadTestRunListeners.clear(); loadTestListeners.clear(); } public boolean isRunning() { return runner != null && runner.getStatus() == LoadTestRunner.Status.RUNNING; } public WsdlLoadTestRunner getRunner() { return runner; } public void resetConfigOnMove(LoadTestConfig config) { setConfig(config); loadStrategy.updateConfig(config.getLoadStrategy().getConfig()); List<LoadTestAssertionConfig> assertionList = config.getAssertionList(); for (int c = 0; c < assertionList.size(); c++) { assertions.get(c).updateConfiguration(assertionList.get(c)); } } public class StatisticsLogger implements Runnable { private boolean stopped; private List<PrintWriter> writers = new ArrayList<PrintWriter>(); private long startTime; public void run() { stopped = false; while (!stopped && getStatisticsLogInterval() > 0) { try { long statisticsInterval = getStatisticsLogInterval(); Thread.sleep(statisticsInterval); if (!stopped) { logStatistics("Interval"); } } catch (InterruptedException e) { e.printStackTrace(); } } } public void start() { new Thread(this, "Statistics Logger for LoadTest [" + getName() + "]").start(); } public void init(LoadTestRunContext context) { writers.clear(); String statisticsLogFolder = context.expand(getStatisticsLogFolder()); if (StringUtils.isNullOrEmpty(statisticsLogFolder)) { return; } File folder = new File(statisticsLogFolder); if (!folder.exists()) { if (!folder.mkdirs()) { SoapUI.logError(new Exception("Failed to create statistics log folder [" + statisticsLogFolder + "]")); return; } } for (int c = 0; c < testCase.getTestStepCount(); c++) { try { WsdlTestStep testStep = testCase.getTestStepAt(c); String fileName = StringUtils.createFileName(testStep.getName(), '_') + ".log"; PrintWriter writer = new PrintWriter(new File(folder, fileName)); writers.add(writer); addHeaders(writer); } catch (FileNotFoundException e) { e.printStackTrace(); writers.add(null); } } // and one writer for the testcase.. try { String fileName = StringUtils.createFileName(testCase.getName(), '_') + ".log"; writers.add(new PrintWriter(new File(folder, fileName))); } catch (FileNotFoundException e) { e.printStackTrace(); } startTime = System.nanoTime(); } private void addHeaders(PrintWriter writer) { writer.print("date,threads,elapsed,min,max,avg,last,cnt,tps,bytes,bps,err,reason\n"); } public void finish() { stopped = true; logStatistics("Finished"); for (PrintWriter writer : writers) { if (writer != null) { writer.close(); } } } private synchronized void logStatistics(String trigger) { if (writers.isEmpty()) { return; } long timestamp = System.nanoTime(); String elapsedString = String.valueOf((timestamp - startTime) / 1000000); String dateString = new Date().toString(); String threadCountString = String.valueOf(getThreadCount()); StringList[] snapshot = statisticsModel.getSnapshot(); for (int c = 0; c < snapshot.length; c++) { PrintWriter writer = writers.get(c); if (writer == null) { continue; } StringList values = snapshot[c]; writer.append(dateString).append(','); writer.append(threadCountString).append(','); writer.append(elapsedString); for (String value : values) { writer.append(',').append(value); } writer.append(',').append(trigger).append('\n'); writer.flush(); } } } public void setSetupScript(String script) { String oldScript = getSetupScript(); if (!getConfig().isSetSetupScript()) { getConfig().addNewSetupScript(); } getConfig().getSetupScript().setStringValue(script); if (setupScriptEngine != null) { setupScriptEngine.setScript(script); } notifyPropertyChanged(SETUP_SCRIPT_PROPERTY, oldScript, script); } public String getSetupScript() { return getConfig().isSetSetupScript() ? getConfig().getSetupScript().getStringValue() : null; } public void setTearDownScript(String script) { String oldScript = getTearDownScript(); if (!getConfig().isSetTearDownScript()) { getConfig().addNewTearDownScript(); } getConfig().getTearDownScript().setStringValue(script); if (tearDownScriptEngine != null) { tearDownScriptEngine.setScript(script); } notifyPropertyChanged(TEARDOWN_SCRIPT_PROPERTY, oldScript, script); } public String getTearDownScript() { return getConfig().isSetTearDownScript() ? getConfig().getTearDownScript().getStringValue() : null; } public Object runSetupScript(LoadTestRunContext runContext, LoadTestRunner runner) throws Exception { String script = getSetupScript(); if (StringUtils.isNullOrEmpty(script)) { return null; } if (setupScriptEngine == null) { setupScriptEngine = SoapUIScriptEngineRegistry.create(this); setupScriptEngine.setScript(script); } setupScriptEngine.setVariable("context", runContext); setupScriptEngine.setVariable("loadTestRunner", runner); setupScriptEngine.setVariable("log", SoapUI.ensureGroovyLog()); return setupScriptEngine.run(); } public Object runTearDownScript(LoadTestRunContext runContext, LoadTestRunner runner) throws Exception { String script = getTearDownScript(); if (StringUtils.isNullOrEmpty(script)) { return null; } if (tearDownScriptEngine == null) { tearDownScriptEngine = SoapUIScriptEngineRegistry.create(this); tearDownScriptEngine.setScript(script); } tearDownScriptEngine.setVariable("context", runContext); tearDownScriptEngine.setVariable("loadTestRunner", runner); tearDownScriptEngine.setVariable("log", SoapUI.ensureGroovyLog()); return tearDownScriptEngine.run(); } public int getStrategyInterval() { return getConfig().getStrategyInterval(); } public void setStrategyInterval(int interval) { getConfig().setStrategyInterval(interval); } public boolean getUpdateStatisticsPerTestStep() { return getConfig().getUpdateStatisticsPerTestStep(); } public void setUpdateStatisticsPerTestStep(boolean updateStatisticsPerTestStep) { getConfig().setUpdateStatisticsPerTestStep(updateStatisticsPerTestStep); } public TestRunner run(StringToObjectMap context, boolean async) { // TODO Auto-generated method stub return null; } }