View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2010 eviware.com 
3    *
4    *  soapUI is free software; you can redistribute it and/or modify it under the 
5    *  terms of version 2.1 of the GNU Lesser General Public License as published by 
6    *  the Free Software Foundation.
7    *
8    *  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
9    *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
10   *  See the GNU Lesser General Public License for more details at gnu.org.
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 		// initial increase?
195 		double quarter = ( double )interval / 4;
196 
197 		if( timePassed < quarter )
198 		{
199 			threadCount += ( int )Math.round( ( ( timePassed / quarter ) * variance * threadCount ) );
200 		}
201 		// decrease?
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 		// final increase
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 }