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.JSpinner;
19  import javax.swing.SpinnerNumberModel;
20  import javax.swing.event.ChangeEvent;
21  import javax.swing.event.ChangeListener;
22  
23  import org.apache.log4j.Logger;
24  import org.apache.xmlbeans.XmlObject;
25  
26  import com.eviware.soapui.impl.wsdl.loadtest.WsdlLoadTest;
27  import com.eviware.soapui.impl.wsdl.loadtest.WsdlLoadTestRunner;
28  import com.eviware.soapui.model.testsuite.LoadTestRunContext;
29  import com.eviware.soapui.model.testsuite.LoadTestRunner;
30  import com.eviware.soapui.support.UISupport;
31  import com.eviware.soapui.support.swing.ComponentBag;
32  import com.eviware.soapui.support.xml.XmlObjectConfigurationBuilder;
33  import com.eviware.soapui.support.xml.XmlObjectConfigurationReader;
34  import com.jgoodies.forms.builder.ButtonBarBuilder;
35  
36  /***
37   * LoadStrategy allowing maximum runs and request delays
38   * 
39   * @author Ole.Matzura
40   */
41  
42  public class ThreadCountChangeLoadStrategy extends AbstractLoadStrategy
43  {
44  	private final static Logger log = Logger.getLogger( ThreadCountChangeLoadStrategy.class );
45  
46  	private static final int DEFAULT_END_THREAD_COUNT = 10;
47  	private static final int DEFAULT_START_THREAD_COUNT = 1;
48  	public static final String STRATEGY_TYPE = "Thread";
49  
50  	private int startThreadCount = DEFAULT_START_THREAD_COUNT;
51  	private int endThreadCount = DEFAULT_END_THREAD_COUNT;
52  
53  	private JPanel configPanel;
54  	private ComponentBag stateDependantComponents = new ComponentBag();
55  
56  	private SpinnerNumberModel startThreadCountSpinnerNumberModel;
57  	private JSpinner startThreadCountSpinner;
58  	private SpinnerNumberModel endThreadCountSpinnerNumberModel;
59  	private JSpinner endThreadCountSpinner;
60  
61  	public ThreadCountChangeLoadStrategy( XmlObject config, WsdlLoadTest loadTest )
62  	{
63  		super( STRATEGY_TYPE, loadTest );
64  
65  		if( config != null )
66  		{
67  			XmlObjectConfigurationReader reader = new XmlObjectConfigurationReader( config );
68  			startThreadCount = reader.readInt( "startThreadCount", DEFAULT_START_THREAD_COUNT );
69  			endThreadCount = reader.readInt( "endThreadCount", DEFAULT_END_THREAD_COUNT );
70  		}
71  	}
72  
73  	public XmlObject getConfig()
74  	{
75  		XmlObjectConfigurationBuilder builder = new XmlObjectConfigurationBuilder();
76  		builder.add( "startThreadCount", startThreadCount );
77  		builder.add( "endThreadCount", endThreadCount );
78  		return builder.finish();
79  	}
80  
81  	public void beforeLoadTest( LoadTestRunner loadTestRunner, LoadTestRunContext context )
82  	{
83  		super.beforeLoadTest( loadTestRunner, context );
84  		stateDependantComponents.setEnabled( false );
85  
86  		WsdlLoadTest wsdlLoadTest = ( ( WsdlLoadTest )loadTestRunner.getLoadTest() );
87  		wsdlLoadTest.setThreadCount( startThreadCount );
88  	}
89  
90  	public void afterLoadTest( LoadTestRunner loadTestRunner, LoadTestRunContext context )
91  	{
92  		stateDependantComponents.setEnabled( true );
93  	}
94  
95  	public boolean allowThreadCountChangeDuringRun()
96  	{
97  		return false;
98  	}
99  
100 	@Override
101 	public void recalculate( LoadTestRunner loadTestRunner, LoadTestRunContext context )
102 	{
103 		// calculate thread count
104 		WsdlLoadTestRunner runner = ( WsdlLoadTestRunner )loadTestRunner;
105 		float progress = runner.getProgress();
106 		if( ( int )progress != -1 )
107 		{
108 			WsdlLoadTest wsdlLoadTest = ( ( WsdlLoadTest )loadTestRunner.getLoadTest() );
109 			synchronized( wsdlLoadTest )
110 			{
111 				int newThreadCount = ( int )( startThreadCount + ( progress * ( endThreadCount - startThreadCount ) + 0.5 ) );
112 				if( newThreadCount != wsdlLoadTest.getThreadCount() && newThreadCount <= endThreadCount )
113 				{
114 					log.debug( "Changing threadcount to " + newThreadCount + ", progress = " + progress );
115 					wsdlLoadTest.setThreadCount( newThreadCount );
116 				}
117 			}
118 		}
119 	}
120 
121 	public JComponent getConfigurationPanel()
122 	{
123 		if( configPanel == null )
124 		{
125 			ButtonBarBuilder builder = new ButtonBarBuilder();
126 
127 			startThreadCountSpinnerNumberModel = new SpinnerNumberModel( startThreadCount, 1, 10000, 1 );
128 			startThreadCountSpinner = new JSpinner( startThreadCountSpinnerNumberModel );
129 			UISupport.setPreferredHeight( startThreadCountSpinner, 18 );
130 			startThreadCountSpinner.setToolTipText( "Sets the initial thread-count" );
131 			startThreadCountSpinnerNumberModel.addChangeListener( new ChangeListener()
132 			{
133 
134 				public void stateChanged( ChangeEvent e )
135 				{
136 					startThreadCount = startThreadCountSpinnerNumberModel.getNumber().intValue();
137 					notifyConfigurationChanged();
138 				}
139 			} );
140 
141 			builder.addFixed( new JLabel( "Start Threads" ) );
142 			builder.addRelatedGap();
143 
144 			builder.addFixed( startThreadCountSpinner );
145 			builder.addRelatedGap();
146 
147 			endThreadCountSpinnerNumberModel = new SpinnerNumberModel( endThreadCount, 1, 10000, 1 );
148 			endThreadCountSpinner = new JSpinner( endThreadCountSpinnerNumberModel );
149 			UISupport.setPreferredHeight( endThreadCountSpinner, 18 );
150 			endThreadCountSpinner.setToolTipText( "Sets the final thread-count" );
151 			endThreadCountSpinnerNumberModel.addChangeListener( new ChangeListener()
152 			{
153 
154 				public void stateChanged( ChangeEvent e )
155 				{
156 					endThreadCount = endThreadCountSpinnerNumberModel.getNumber().intValue();
157 					notifyConfigurationChanged();
158 				}
159 			} );
160 
161 			builder.addFixed( new JLabel( "End Threads" ) );
162 			builder.addRelatedGap();
163 			builder.addFixed( endThreadCountSpinner );
164 
165 			configPanel = builder.getPanel();
166 
167 			stateDependantComponents.add( startThreadCountSpinner );
168 			stateDependantComponents.add( endThreadCountSpinner );
169 		}
170 
171 		return configPanel;
172 	}
173 
174 	/***
175 	 * Factory for ThreadCountChangeLoadStrategy class
176 	 * 
177 	 * @author Ole.Matzura
178 	 */
179 
180 	public static class Factory implements LoadStrategyFactory
181 	{
182 		public String getType()
183 		{
184 			return STRATEGY_TYPE;
185 		}
186 
187 		public LoadStrategy build( XmlObject config, WsdlLoadTest loadTest )
188 		{
189 			return new ThreadCountChangeLoadStrategy( config, loadTest );
190 		}
191 
192 		public LoadStrategy create( WsdlLoadTest loadTest )
193 		{
194 			return new ThreadCountChangeLoadStrategy( null, loadTest );
195 		}
196 	}
197 }