/*
* 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.strategy;
import com.eviware.soapui.impl.wsdl.loadtest.WsdlLoadTest;
import com.eviware.soapui.model.testsuite.LoadTestRunContext;
import com.eviware.soapui.model.testsuite.LoadTestRunner;
import com.eviware.soapui.support.DocumentListenerAdapter;
import com.eviware.soapui.support.UISupport;
import com.eviware.soapui.support.swing.ComponentBag;
import com.eviware.soapui.support.xml.XmlObjectConfigurationBuilder;
import com.eviware.soapui.support.xml.XmlObjectConfigurationReader;
import com.jgoodies.forms.builder.ButtonBarBuilder;
import org.apache.log4j.Logger;
import org.apache.xmlbeans.XmlObject;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.text.Document;
/**
* Simple LoadStrategy that just runs until canceled without any delays
*
* @author Ole.Matzura
*/
public class VarianceLoadStrategy extends AbstractLoadStrategy {
private final static Logger log = Logger.getLogger(VarianceLoadStrategy.class);
public static final String STRATEGY_TYPE = "Variance";
private static final String INTERVAL_ELEMENT = "interval";
private static final String VARIANCE_ELEMENT = "variance";
private static final int DEFAULT_INTERVAL = 60000;
private static final float DEFAULT_VARIANCE = 0.5F;
private JPanel configPanel;
private long interval = DEFAULT_INTERVAL;
private float variance = DEFAULT_VARIANCE;
private JTextField intervalField;
private JTextField varianceField;
private JLabel infoLabel;
private long baseThreadCount;
private long startTime;
private ComponentBag stateDependantComponents = new ComponentBag();
public VarianceLoadStrategy(WsdlLoadTest loadTest) {
super(STRATEGY_TYPE, loadTest);
interval = DEFAULT_INTERVAL;
variance = DEFAULT_VARIANCE;
}
public VarianceLoadStrategy(XmlObject config, WsdlLoadTest loadTest) {
super(STRATEGY_TYPE, loadTest);
XmlObjectConfigurationReader reader = new XmlObjectConfigurationReader(config);
interval = reader.readLong(INTERVAL_ELEMENT, DEFAULT_INTERVAL);
variance = reader.readFloat(VARIANCE_ELEMENT, DEFAULT_VARIANCE);
}
public JComponent getConfigurationPanel() {
if (configPanel == null) {
ButtonBarBuilder builder = new ButtonBarBuilder();
intervalField = new JTextField(4);
UISupport.setPreferredHeight(intervalField, 18);
intervalField.setHorizontalAlignment(JTextField.RIGHT);
intervalField.setText(String.valueOf(interval / 1000));
intervalField.setToolTipText("Sets the interval between variances in seconds");
intervalField.getDocument().addDocumentListener(new DocumentListenerAdapter() {
public void update(Document doc) {
try {
interval = Long.parseLong(intervalField.getText()) * 1000;
notifyConfigurationChanged();
} catch (NumberFormatException e) {
}
}
});
builder.addFixed(new JLabel("Interval"));
builder.addRelatedGap();
builder.addFixed(intervalField);
builder.addRelatedGap();
varianceField = new JTextField(3);
UISupport.setPreferredHeight(varianceField, 18);
varianceField.setHorizontalAlignment(JTextField.RIGHT);
varianceField.setText(String.valueOf(variance));
varianceField.setToolTipText("Specifies the relative magnitude of a variance");
varianceField.getDocument().addDocumentListener(new DocumentListenerAdapter() {
public void update(Document doc) {
try {
variance = Float.parseFloat(varianceField.getText());
notifyConfigurationChanged();
} catch (NumberFormatException e) {
}
}
});
builder.addFixed(new JLabel("Variance"));
builder.addRelatedGap();
builder.addFixed(varianceField);
builder.addRelatedGap();
infoLabel = new JLabel();
builder.addFixed(infoLabel);
configPanel = builder.getPanel();
stateDependantComponents.add(intervalField);
stateDependantComponents.add(varianceField);
}
return configPanel;
}
public XmlObject getConfig() {
XmlObjectConfigurationBuilder builder = new XmlObjectConfigurationBuilder();
builder.add(INTERVAL_ELEMENT, interval);
builder.add(VARIANCE_ELEMENT, variance);
return builder.finish();
}
/**
* Factory for VarianceLoadStrategy class
*
* @author Ole.Matzura
*/
public static class Factory implements LoadStrategyFactory {
public String getType() {
return STRATEGY_TYPE;
}
public LoadStrategy build(XmlObject config, WsdlLoadTest loadTest) {
return new VarianceLoadStrategy(config, loadTest);
}
public LoadStrategy create(WsdlLoadTest loadTest) {
return new VarianceLoadStrategy(loadTest);
}
}
public void beforeLoadTest(LoadTestRunner loadTestRunner, LoadTestRunContext context) {
super.beforeLoadTest(loadTestRunner, context);
baseThreadCount = ((WsdlLoadTest) loadTestRunner.getLoadTest()).getThreadCount();
startTime = System.currentTimeMillis();
stateDependantComponents.setEnabled(false);
}
public void recalculate(LoadTestRunner loadTestRunner, LoadTestRunContext context) {
double timePassed = (System.currentTimeMillis() - startTime) % interval;
float threadCount = baseThreadCount;
// initial increase?
double quarter = (double) interval / 4;
if (timePassed < quarter) {
threadCount += (int) Math.round(((timePassed / quarter) * variance * threadCount));
}
// decrease?
else if (timePassed < quarter * 2) {
threadCount += (int) Math.round(((1 - ((timePassed % quarter) / quarter)) * variance * threadCount));
} else if (timePassed < quarter * 3) {
threadCount -= (int) Math.round((((timePassed % quarter) / quarter) * variance * threadCount));
}
// final increase
else {
threadCount -= (int) Math.round(((1 - ((timePassed % quarter) / quarter)) * variance * threadCount));
}
if (threadCount < 1) {
threadCount = 1;
}
WsdlLoadTest wsdlLoadTest = ((WsdlLoadTest) loadTestRunner.getLoadTest());
if (wsdlLoadTest.getThreadCount() != (int) threadCount) {
log.debug("Changing threadcount to " + threadCount);
wsdlLoadTest.setThreadCount((int) threadCount);
}
}
public void afterLoadTest(LoadTestRunner testRunner, LoadTestRunContext context) {
WsdlLoadTest wsdlLoadTest = (WsdlLoadTest) testRunner.getLoadTest();
wsdlLoadTest.setThreadCount(baseThreadCount);
stateDependantComponents.setEnabled(true);
}
public boolean allowThreadCountChangeDuringRun() {
return false;
}
public long getInterval() {
return interval;
}
public float getVariance() {
return variance;
}
}