View Javadoc

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