001: /*
002: * soapUI, copyright (C) 2004-2007 eviware.com
003: *
004: * soapUI is free software; you can redistribute it and/or modify it under the
005: * terms of version 2.1 of the GNU Lesser General Public License as published by
006: * the Free Software Foundation.
007: *
008: * soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
009: * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
010: * See the GNU Lesser General Public License for more details at gnu.org.
011: */
012:
013: package com.eviware.soapui.impl.wsdl.loadtest.strategy;
014:
015: import javax.swing.JComponent;
016: import javax.swing.JLabel;
017: import javax.swing.JPanel;
018: import javax.swing.JTextField;
019: import javax.swing.text.Document;
020:
021: import org.apache.log4j.Logger;
022: import org.apache.xmlbeans.XmlObject;
023:
024: import com.eviware.soapui.impl.wsdl.loadtest.WsdlLoadTest;
025: import com.eviware.soapui.model.testsuite.LoadTestRunContext;
026: import com.eviware.soapui.model.testsuite.LoadTestRunner;
027: import com.eviware.soapui.model.testsuite.TestRunContext;
028: import com.eviware.soapui.model.testsuite.TestRunner;
029: import com.eviware.soapui.support.DocumentListenerAdapter;
030: import com.eviware.soapui.support.UISupport;
031: import com.eviware.soapui.support.swing.ComponentBag;
032: import com.eviware.soapui.support.xml.XmlObjectConfigurationBuilder;
033: import com.eviware.soapui.support.xml.XmlObjectConfigurationReader;
034: import com.jgoodies.forms.builder.ButtonBarBuilder;
035:
036: /**
037: * Simple LoadStrategy that just runs until canceled without any delays
038: *
039: * @author Ole.Matzura
040: */
041:
042: public class VarianceLoadStrategy extends AbstractLoadStrategy {
043: private final static Logger log = Logger
044: .getLogger(VarianceLoadStrategy.class);
045:
046: public static final String STRATEGY_TYPE = "Variance";
047: private static final String INTERVAL_ELEMENT = "interval";
048: private static final String VARIANCE_ELEMENT = "variance";
049: private static final int DEFAULT_INTERVAL = 60000;
050: private static final float DEFAULT_VARIANCE = 0.5F;
051:
052: private JPanel configPanel;
053:
054: private long interval = DEFAULT_INTERVAL;
055: private float variance = DEFAULT_VARIANCE;
056: private JTextField intervalField;
057: private JTextField varianceField;
058: private JLabel infoLabel;
059: private long baseThreadCount;
060: private long startTime;
061: private ComponentBag stateDependantComponents = new ComponentBag();
062:
063: public VarianceLoadStrategy() {
064: super (STRATEGY_TYPE);
065:
066: interval = DEFAULT_INTERVAL;
067: variance = DEFAULT_VARIANCE;
068: }
069:
070: public VarianceLoadStrategy(XmlObject config) {
071: super (STRATEGY_TYPE);
072:
073: XmlObjectConfigurationReader reader = new XmlObjectConfigurationReader(
074: config);
075: interval = reader.readLong(INTERVAL_ELEMENT, DEFAULT_INTERVAL);
076: variance = reader.readFloat(VARIANCE_ELEMENT, DEFAULT_VARIANCE);
077: }
078:
079: public JComponent getConfigurationPanel() {
080: if (configPanel == null) {
081: ButtonBarBuilder builder = new ButtonBarBuilder();
082:
083: intervalField = new JTextField(4);
084: UISupport.setPreferredHeight(intervalField, 18);
085: intervalField.setHorizontalAlignment(JTextField.RIGHT);
086: intervalField.setText(String.valueOf(interval / 1000));
087: intervalField
088: .setToolTipText("Sets the interval between variances in seconds");
089: intervalField.getDocument().addDocumentListener(
090: new DocumentListenerAdapter() {
091:
092: public void update(Document doc) {
093: try {
094: interval = Long.parseLong(intervalField
095: .getText()) * 1000;
096: notifyConfigurationChanged();
097: } catch (NumberFormatException e) {
098: }
099: }
100: });
101:
102: builder.addFixed(new JLabel("Interval"));
103: builder.addRelatedGap();
104:
105: builder.addFixed(intervalField);
106: builder.addRelatedGap();
107:
108: varianceField = new JTextField(3);
109: UISupport.setPreferredHeight(varianceField, 18);
110: varianceField.setHorizontalAlignment(JTextField.RIGHT);
111: varianceField.setText(String.valueOf(variance));
112: varianceField
113: .setToolTipText("Specifies the relative magnitude of a variance");
114: varianceField.getDocument().addDocumentListener(
115: new DocumentListenerAdapter() {
116:
117: public void update(Document doc) {
118: try {
119: variance = Float
120: .parseFloat(varianceField
121: .getText());
122: notifyConfigurationChanged();
123: } catch (NumberFormatException e) {
124: }
125: }
126: });
127:
128: builder.addFixed(new JLabel("Variance"));
129: builder.addRelatedGap();
130: builder.addFixed(varianceField);
131: builder.addRelatedGap();
132:
133: infoLabel = new JLabel();
134: builder.addFixed(infoLabel);
135:
136: configPanel = builder.getPanel();
137:
138: stateDependantComponents.add(intervalField);
139: stateDependantComponents.add(varianceField);
140: }
141:
142: return configPanel;
143: }
144:
145: public XmlObject getConfig() {
146: XmlObjectConfigurationBuilder builder = new XmlObjectConfigurationBuilder();
147: builder.add(INTERVAL_ELEMENT, interval);
148: builder.add(VARIANCE_ELEMENT, variance);
149: return builder.finish();
150: }
151:
152: /**
153: * Factory for VarianceLoadStrategy class
154: *
155: * @author Ole.Matzura
156: */
157:
158: public static class Factory implements LoadStrategyFactory {
159: public String getType() {
160: return STRATEGY_TYPE;
161: }
162:
163: public LoadStrategy build(XmlObject config) {
164: return new VarianceLoadStrategy(config);
165: }
166:
167: public LoadStrategy create() {
168: return new VarianceLoadStrategy();
169: }
170: }
171:
172: public void beforeLoadTest(LoadTestRunner loadTestRunner,
173: LoadTestRunContext context) {
174: baseThreadCount = ((WsdlLoadTest) loadTestRunner.getLoadTest())
175: .getThreadCount();
176: startTime = System.currentTimeMillis();
177: stateDependantComponents.setEnabled(false);
178: }
179:
180: public void beforeTestCase(LoadTestRunner loadTestRunner,
181: LoadTestRunContext context, TestRunner testRunner,
182: TestRunContext runContext) {
183: double timePassed = (System.currentTimeMillis() - startTime)
184: % interval;
185: float threadCount = baseThreadCount;
186:
187: // initial increase?
188: double quarter = (double) interval / 4;
189:
190: if (timePassed < quarter) {
191: threadCount += (int) Math.round(((timePassed / quarter)
192: * variance * threadCount));
193: }
194: // decrease?
195: else if (timePassed < quarter * 2) {
196: threadCount += (int) Math
197: .round(((1 - ((timePassed % quarter) / quarter))
198: * variance * threadCount));
199: } else if (timePassed < quarter * 3) {
200: threadCount -= (int) Math
201: .round((((timePassed % quarter) / quarter)
202: * variance * threadCount));
203: }
204: // final increase
205: else {
206: threadCount -= (int) Math
207: .round(((1 - ((timePassed % quarter) / quarter))
208: * variance * threadCount));
209: }
210:
211: if (threadCount < 1)
212: threadCount = 1;
213:
214: WsdlLoadTest wsdlLoadTest = ((WsdlLoadTest) loadTestRunner
215: .getLoadTest());
216: if (wsdlLoadTest.getThreadCount() != (int) threadCount) {
217: log.debug("Changing threadcount to " + threadCount);
218: wsdlLoadTest.setThreadCount((int) threadCount);
219: }
220: }
221:
222: public void afterLoadTest(LoadTestRunner testRunner,
223: LoadTestRunContext context) {
224: WsdlLoadTest wsdlLoadTest = (WsdlLoadTest) testRunner
225: .getLoadTest();
226: wsdlLoadTest.setThreadCount(baseThreadCount);
227: stateDependantComponents.setEnabled(true);
228: }
229:
230: public boolean allowThreadCountChangeDuringRun() {
231: return false;
232: }
233: }
|