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.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  		stateDependantComponents.setEnabled( false );
84  		
85  		WsdlLoadTest wsdlLoadTest = ((WsdlLoadTest)loadTestRunner.getLoadTest());
86  		wsdlLoadTest.setThreadCount( startThreadCount );
87  	}
88  	
89  	public void afterLoadTest(LoadTestRunner loadTestRunner, LoadTestRunContext context)
90  	{
91  		stateDependantComponents.setEnabled( true );
92  	}
93  
94  	public boolean allowThreadCountChangeDuringRun()
95  	{
96  		return false;
97  	}
98  
99  	@Override
100 	public void recalculate( LoadTestRunner loadTestRunner, LoadTestRunContext context)
101 	{
102 		// calculate thread count
103 		WsdlLoadTestRunner runner = (WsdlLoadTestRunner) loadTestRunner;
104 		float progress = runner.getProgress();
105 		if( (int)progress != -1 )
106 		{
107 			WsdlLoadTest wsdlLoadTest = ((WsdlLoadTest)loadTestRunner.getLoadTest());
108 			synchronized( wsdlLoadTest )
109 			{
110 				int newThreadCount = (int) (startThreadCount + (progress*(endThreadCount-startThreadCount)+0.5));
111 				if( newThreadCount != wsdlLoadTest.getThreadCount() && newThreadCount <= endThreadCount )
112 				{
113 					log.debug( "Changing threadcount to " + newThreadCount + ", progress = " + progress );
114 					wsdlLoadTest.setThreadCount( newThreadCount );
115 				}
116 			}
117 		}
118 	}
119 
120 	public JComponent getConfigurationPanel()
121 	{
122 		if( configPanel == null )
123 		{
124 			ButtonBarBuilder builder = new ButtonBarBuilder();
125 			
126 			startThreadCountSpinnerNumberModel = new SpinnerNumberModel(startThreadCount, 1, 10000, 1 );
127 			startThreadCountSpinner = new JSpinner( startThreadCountSpinnerNumberModel );
128 			UISupport.setPreferredHeight( startThreadCountSpinner, 18 );
129 			startThreadCountSpinner.setToolTipText( "Sets the initial thread-count" );
130 			startThreadCountSpinnerNumberModel.addChangeListener( new ChangeListener() {
131 
132 				public void stateChanged(ChangeEvent e)
133 				{
134 					startThreadCount = startThreadCountSpinnerNumberModel.getNumber().intValue();
135 					notifyConfigurationChanged();
136 				}});
137 
138 			builder.addFixed( new JLabel( "Start Threads" ));
139 			builder.addRelatedGap();
140 			
141 			builder.addFixed( startThreadCountSpinner );
142 			builder.addRelatedGap();
143 
144 			endThreadCountSpinnerNumberModel = new SpinnerNumberModel(endThreadCount, 1, 10000, 1 );
145 			endThreadCountSpinner = new JSpinner( endThreadCountSpinnerNumberModel );
146 			UISupport.setPreferredHeight( endThreadCountSpinner, 18 );
147 			endThreadCountSpinner.setToolTipText( "Sets the final thread-count" );
148 			endThreadCountSpinnerNumberModel.addChangeListener( new ChangeListener() {
149 
150 				public void stateChanged(ChangeEvent e)
151 				{
152 					endThreadCount = endThreadCountSpinnerNumberModel.getNumber().intValue();
153 					notifyConfigurationChanged();
154 				}});
155 			
156 			builder.addFixed( new JLabel( "End Threads" ));
157 			builder.addRelatedGap();
158 			builder.addFixed( endThreadCountSpinner);
159 
160 			configPanel = builder.getPanel();
161 			
162 			stateDependantComponents.add( startThreadCountSpinner );
163 			stateDependantComponents.add( endThreadCountSpinner );
164 		}
165 
166 		return configPanel;
167 	}
168 	
169 	/***
170 	 * Factory for ThreadCountChangeLoadStrategy class
171 	 * 
172 	 * @author Ole.Matzura
173 	 */
174 
175 	public static class Factory implements LoadStrategyFactory
176 	{
177 		public String getType()
178 		{
179 			return STRATEGY_TYPE;
180 		}
181 
182 		public LoadStrategy build(XmlObject config, WsdlLoadTest loadTest)
183 		{
184 			return new ThreadCountChangeLoadStrategy( config, loadTest );
185 		}
186 
187 		public LoadStrategy create(WsdlLoadTest loadTest)
188 		{
189 			return new ThreadCountChangeLoadStrategy( null, loadTest );
190 		}
191 	}
192 }