View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2008 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  				public void update( Document doc )
92  				{
93  					try
94  					{
95  						interval = Long.parseLong(intervalField.getText())*1000;
96  						notifyConfigurationChanged();
97  					}
98  					catch (NumberFormatException e)
99  					{
100 					}
101 				}}
102 				);
103 			
104 			builder.addFixed( new JLabel( "Interval" ));
105 			builder.addRelatedGap();
106 			
107 			builder.addFixed( intervalField );
108 			builder.addRelatedGap();
109 
110 			varianceField = new JTextField( 3 );
111 			UISupport.setPreferredHeight( varianceField, 18 );
112 			varianceField.setHorizontalAlignment( JTextField.RIGHT );
113 			varianceField.setText( String.valueOf( variance ));
114 			varianceField.setToolTipText( "Specifies the relative magnitude of a variance" );
115 			varianceField.getDocument().addDocumentListener( new DocumentListenerAdapter(){
116 
117 				public void update( Document doc )
118 				{
119 					try
120 					{
121 						variance = Float.parseFloat(varianceField.getText());
122 						notifyConfigurationChanged();
123 					}
124 					catch (NumberFormatException e)
125 					{
126 					}
127 				}}
128 				);
129 			
130 			builder.addFixed( new JLabel( "Variance" ));
131 			builder.addRelatedGap();
132 			builder.addFixed( varianceField);
133 			builder.addRelatedGap();
134 			
135 			infoLabel = new JLabel();
136 			builder.addFixed( infoLabel );
137 			
138 			configPanel = builder.getPanel();
139 			
140 			stateDependantComponents.add( intervalField );
141 			stateDependantComponents.add( varianceField );
142 		}
143 
144 		return configPanel;
145 	}
146 
147 	public XmlObject getConfig()
148 	{
149 		XmlObjectConfigurationBuilder builder = new XmlObjectConfigurationBuilder();
150 		builder.add( INTERVAL_ELEMENT, interval );
151       builder.add( VARIANCE_ELEMENT, variance );
152       return builder.finish();
153 	}
154 
155 	/***
156 	 * Factory for VarianceLoadStrategy class
157 	 * 
158 	 * @author Ole.Matzura
159 	 */
160 
161 	public static class Factory implements LoadStrategyFactory
162 	{
163 		public String getType()
164 		{
165 			return STRATEGY_TYPE;
166 		}
167 
168 		public LoadStrategy build(XmlObject config,WsdlLoadTest loadTest)
169 		{
170 			return new VarianceLoadStrategy( config, loadTest );
171 		}
172 
173 		public LoadStrategy create(WsdlLoadTest loadTest)
174 		{
175 			return new VarianceLoadStrategy(loadTest);
176 		}
177 	}
178 
179 	public void beforeLoadTest(LoadTestRunner loadTestRunner, LoadTestRunContext context)
180 	{
181 		baseThreadCount = ((WsdlLoadTest)loadTestRunner.getLoadTest()).getThreadCount();
182 		startTime = System.currentTimeMillis();
183 		stateDependantComponents.setEnabled( false );
184 	}
185 
186 	public void recalculate( LoadTestRunner loadTestRunner, LoadTestRunContext context)
187 	{
188 		double timePassed = (System.currentTimeMillis() - startTime)%interval;
189 		float threadCount = baseThreadCount;
190 		
191 		// initial increase?
192 		double quarter = (double)interval/4;
193 		
194 		if( timePassed < quarter )
195 		{
196 			threadCount += (int) Math.round(((timePassed/quarter)*variance*threadCount));
197 		}
198 		// decrease?
199 		else if( timePassed < quarter*2)
200 		{
201 			threadCount += (int) Math.round(((1-((timePassed%quarter)/quarter))*variance*threadCount));
202 		}
203 		else if( timePassed < quarter*3)
204 		{
205 			threadCount -= (int) Math.round((((timePassed%quarter)/quarter)*variance*threadCount));
206 		}
207 		// final increase
208 		else 
209 		{
210 			threadCount -= (int) Math.round(((1-((timePassed%quarter)/quarter))*variance*threadCount));
211 		}
212 		
213 		if( threadCount < 1 )
214 			threadCount = 1;
215 		
216 		WsdlLoadTest wsdlLoadTest = ((WsdlLoadTest)loadTestRunner.getLoadTest());
217 		if( wsdlLoadTest.getThreadCount() != (int)threadCount )
218 		{
219 			log.debug( "Changing threadcount to " + threadCount );
220 			wsdlLoadTest.setThreadCount( (int) threadCount );
221 		}
222 	}
223 	
224 	public void afterLoadTest(LoadTestRunner testRunner, LoadTestRunContext context)
225 	{
226 		WsdlLoadTest wsdlLoadTest = (WsdlLoadTest) testRunner.getLoadTest();
227 		wsdlLoadTest.setThreadCount( baseThreadCount );
228 		stateDependantComponents.setEnabled( true );
229 	}
230 	
231 	public boolean allowThreadCountChangeDuringRun()
232 	{
233 		return false;
234 	}
235 }