1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.loadtest.strategy;
14
15 import javax.swing.JComponent;
16 import javax.swing.JLabel;
17 import javax.swing.JPanel;
18 import javax.swing.JTextField;
19 import javax.swing.text.Document;
20
21 import org.apache.log4j.Logger;
22 import org.apache.xmlbeans.XmlObject;
23
24 import com.eviware.soapui.impl.wsdl.loadtest.WsdlLoadTest;
25 import com.eviware.soapui.model.testsuite.LoadTestRunContext;
26 import com.eviware.soapui.model.testsuite.LoadTestRunner;
27 import com.eviware.soapui.support.DocumentListenerAdapter;
28 import com.eviware.soapui.support.UISupport;
29 import com.eviware.soapui.support.swing.ComponentBag;
30 import com.eviware.soapui.support.xml.XmlObjectConfigurationBuilder;
31 import com.eviware.soapui.support.xml.XmlObjectConfigurationReader;
32 import com.jgoodies.forms.builder.ButtonBarBuilder;
33
34 /***
35 * Simple LoadStrategy that just runs until canceled without any delays
36 *
37 * @author Ole.Matzura
38 */
39
40 public class VarianceLoadStrategy extends AbstractLoadStrategy
41 {
42 private final static Logger log = Logger.getLogger( VarianceLoadStrategy.class );
43
44 public static final String STRATEGY_TYPE = "Variance";
45 private static final String INTERVAL_ELEMENT = "interval";
46 private static final String VARIANCE_ELEMENT = "variance";
47 private static final int DEFAULT_INTERVAL = 60000;
48 private static final float DEFAULT_VARIANCE = 0.5F;
49
50 private JPanel configPanel;
51
52 private long interval = DEFAULT_INTERVAL;
53 private float variance = DEFAULT_VARIANCE;
54 private JTextField intervalField;
55 private JTextField varianceField;
56 private JLabel infoLabel;
57 private long baseThreadCount;
58 private long startTime;
59 private ComponentBag stateDependantComponents = new ComponentBag();
60
61 public VarianceLoadStrategy( WsdlLoadTest loadTest )
62 {
63 super( STRATEGY_TYPE, loadTest );
64
65 interval = DEFAULT_INTERVAL;
66 variance = DEFAULT_VARIANCE;
67 }
68
69 public VarianceLoadStrategy( XmlObject config, WsdlLoadTest loadTest )
70 {
71 super( STRATEGY_TYPE, loadTest );
72
73 XmlObjectConfigurationReader reader = new XmlObjectConfigurationReader( config );
74 interval = reader.readLong( INTERVAL_ELEMENT, DEFAULT_INTERVAL );
75 variance = reader.readFloat( VARIANCE_ELEMENT, DEFAULT_VARIANCE );
76 }
77
78 public JComponent getConfigurationPanel()
79 {
80 if( configPanel == null )
81 {
82 ButtonBarBuilder builder = new ButtonBarBuilder();
83
84 intervalField = new JTextField( 4 );
85 UISupport.setPreferredHeight( intervalField, 18 );
86 intervalField.setHorizontalAlignment( JTextField.RIGHT );
87 intervalField.setText( String.valueOf( interval / 1000 ) );
88 intervalField.setToolTipText( "Sets the interval between variances in seconds" );
89 intervalField.getDocument().addDocumentListener( new DocumentListenerAdapter()
90 {
91
92 public void update( Document doc )
93 {
94 try
95 {
96 interval = Long.parseLong( intervalField.getText() ) * 1000;
97 notifyConfigurationChanged();
98 }
99 catch( NumberFormatException e )
100 {
101 }
102 }
103 } );
104
105 builder.addFixed( new JLabel( "Interval" ) );
106 builder.addRelatedGap();
107
108 builder.addFixed( intervalField );
109 builder.addRelatedGap();
110
111 varianceField = new JTextField( 3 );
112 UISupport.setPreferredHeight( varianceField, 18 );
113 varianceField.setHorizontalAlignment( JTextField.RIGHT );
114 varianceField.setText( String.valueOf( variance ) );
115 varianceField.setToolTipText( "Specifies the relative magnitude of a variance" );
116 varianceField.getDocument().addDocumentListener( new DocumentListenerAdapter()
117 {
118
119 public void update( Document doc )
120 {
121 try
122 {
123 variance = Float.parseFloat( varianceField.getText() );
124 notifyConfigurationChanged();
125 }
126 catch( NumberFormatException e )
127 {
128 }
129 }
130 } );
131
132 builder.addFixed( new JLabel( "Variance" ) );
133 builder.addRelatedGap();
134 builder.addFixed( varianceField );
135 builder.addRelatedGap();
136
137 infoLabel = new JLabel();
138 builder.addFixed( infoLabel );
139
140 configPanel = builder.getPanel();
141
142 stateDependantComponents.add( intervalField );
143 stateDependantComponents.add( varianceField );
144 }
145
146 return configPanel;
147 }
148
149 public XmlObject getConfig()
150 {
151 XmlObjectConfigurationBuilder builder = new XmlObjectConfigurationBuilder();
152 builder.add( INTERVAL_ELEMENT, interval );
153 builder.add( VARIANCE_ELEMENT, variance );
154 return builder.finish();
155 }
156
157 /***
158 * Factory for VarianceLoadStrategy class
159 *
160 * @author Ole.Matzura
161 */
162
163 public static class Factory implements LoadStrategyFactory
164 {
165 public String getType()
166 {
167 return STRATEGY_TYPE;
168 }
169
170 public LoadStrategy build( XmlObject config, WsdlLoadTest loadTest )
171 {
172 return new VarianceLoadStrategy( config, loadTest );
173 }
174
175 public LoadStrategy create( WsdlLoadTest loadTest )
176 {
177 return new VarianceLoadStrategy( loadTest );
178 }
179 }
180
181 public void beforeLoadTest( LoadTestRunner loadTestRunner, LoadTestRunContext context )
182 {
183 super.beforeLoadTest( loadTestRunner, context );
184 baseThreadCount = ( ( WsdlLoadTest )loadTestRunner.getLoadTest() ).getThreadCount();
185 startTime = System.currentTimeMillis();
186 stateDependantComponents.setEnabled( false );
187 }
188
189 public void recalculate( LoadTestRunner loadTestRunner, LoadTestRunContext context )
190 {
191 double timePassed = ( System.currentTimeMillis() - startTime ) % interval;
192 float threadCount = baseThreadCount;
193
194
195 double quarter = ( double )interval / 4;
196
197 if( timePassed < quarter )
198 {
199 threadCount += ( int )Math.round( ( ( timePassed / quarter ) * variance * threadCount ) );
200 }
201
202 else if( timePassed < quarter * 2 )
203 {
204 threadCount += ( int )Math.round( ( ( 1 - ( ( timePassed % quarter ) / quarter ) ) * variance * threadCount ) );
205 }
206 else if( timePassed < quarter * 3 )
207 {
208 threadCount -= ( int )Math.round( ( ( ( timePassed % quarter ) / quarter ) * variance * threadCount ) );
209 }
210
211 else
212 {
213 threadCount -= ( int )Math.round( ( ( 1 - ( ( timePassed % quarter ) / quarter ) ) * variance * threadCount ) );
214 }
215
216 if( threadCount < 1 )
217 threadCount = 1;
218
219 WsdlLoadTest wsdlLoadTest = ( ( WsdlLoadTest )loadTestRunner.getLoadTest() );
220 if( wsdlLoadTest.getThreadCount() != ( int )threadCount )
221 {
222 log.debug( "Changing threadcount to " + threadCount );
223 wsdlLoadTest.setThreadCount( ( int )threadCount );
224 }
225 }
226
227 public void afterLoadTest( LoadTestRunner testRunner, LoadTestRunContext context )
228 {
229 WsdlLoadTest wsdlLoadTest = ( WsdlLoadTest )testRunner.getLoadTest();
230 wsdlLoadTest.setThreadCount( baseThreadCount );
231 stateDependantComponents.setEnabled( true );
232 }
233
234 public boolean allowThreadCountChangeDuringRun()
235 {
236 return false;
237 }
238 }