View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2007 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.model.testsuite.TestRunContext;
31  import com.eviware.soapui.model.testsuite.TestRunner;
32  import com.eviware.soapui.support.UISupport;
33  import com.eviware.soapui.support.swing.ComponentBag;
34  import com.eviware.soapui.support.xml.XmlObjectConfigurationBuilder;
35  import com.eviware.soapui.support.xml.XmlObjectConfigurationReader;
36  import com.jgoodies.forms.builder.ButtonBarBuilder;
37  
38  /***
39   * LoadStrategy allowing maximum runs and request delays
40   * 
41   * @author Ole.Matzura
42   */
43  
44  public class ThreadCountChangeLoadStrategy extends AbstractLoadStrategy
45  {
46  	private final static Logger log = Logger.getLogger(ThreadCountChangeLoadStrategy.class);
47  	
48  	private static final int DEFAULT_END_THREAD_COUNT = 10;
49  	private static final int DEFAULT_START_THREAD_COUNT = 1;
50  	public static final String STRATEGY_TYPE = "Thread";
51  	
52  	private int startThreadCount = DEFAULT_START_THREAD_COUNT;
53  	private int endThreadCount = DEFAULT_END_THREAD_COUNT;
54  
55  	private JPanel configPanel;
56  	private ComponentBag stateDependantComponents = new ComponentBag();
57  	
58  	private SpinnerNumberModel startThreadCountSpinnerNumberModel;
59  	private JSpinner startThreadCountSpinner;
60  	private SpinnerNumberModel endThreadCountSpinnerNumberModel;
61  	private JSpinner endThreadCountSpinner;
62  	
63  	public ThreadCountChangeLoadStrategy(XmlObject config)
64  	{
65  		super( STRATEGY_TYPE );
66  		
67  		if( config != null )
68  		{
69  			XmlObjectConfigurationReader reader = new XmlObjectConfigurationReader( config );
70  			startThreadCount = reader.readInt( "startThreadCount", DEFAULT_START_THREAD_COUNT );
71  			endThreadCount = reader.readInt( "endThreadCount", DEFAULT_END_THREAD_COUNT );
72  		}
73  	}
74  	
75  	public XmlObject getConfig()
76  	{
77  		XmlObjectConfigurationBuilder builder = new XmlObjectConfigurationBuilder();
78  		builder.add( "startThreadCount", startThreadCount );
79        builder.add( "endThreadCount", endThreadCount );
80        return builder.finish();
81  	}
82  	
83  	public void beforeLoadTest(LoadTestRunner loadTestRunner, LoadTestRunContext context)
84  	{
85  		stateDependantComponents.setEnabled( false );
86  		
87  		WsdlLoadTest wsdlLoadTest = ((WsdlLoadTest)loadTestRunner.getLoadTest());
88  		wsdlLoadTest.setThreadCount( startThreadCount );
89  	}
90  	
91  	public void afterLoadTest(LoadTestRunner loadTestRunner, LoadTestRunContext context)
92  	{
93  		stateDependantComponents.setEnabled( true );
94  	}
95  
96  	public boolean allowThreadCountChangeDuringRun()
97  	{
98  		return false;
99  	}
100 
101 	public void beforeTestCase(LoadTestRunner loadTestRunner, LoadTestRunContext context, TestRunner testRunner, TestRunContext runContext)
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() )
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, 100, 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 				public void stateChanged(ChangeEvent e)
134 				{
135 					startThreadCount = startThreadCountSpinnerNumberModel.getNumber().intValue();
136 					notifyConfigurationChanged();
137 				}});
138 
139 			builder.addFixed( new JLabel( "Start Threads" ));
140 			builder.addRelatedGap();
141 			
142 			builder.addFixed( startThreadCountSpinner );
143 			builder.addRelatedGap();
144 
145 			endThreadCountSpinnerNumberModel = new SpinnerNumberModel(endThreadCount, 1, 100, 1 );
146 			endThreadCountSpinner = new JSpinner( endThreadCountSpinnerNumberModel );
147 			UISupport.setPreferredHeight( endThreadCountSpinner, 18 );
148 			endThreadCountSpinner.setToolTipText( "Sets the final thread-count" );
149 			endThreadCountSpinnerNumberModel.addChangeListener( new ChangeListener() {
150 
151 				public void stateChanged(ChangeEvent e)
152 				{
153 					endThreadCount = endThreadCountSpinnerNumberModel.getNumber().intValue();
154 					notifyConfigurationChanged();
155 				}});
156 			
157 			builder.addFixed( new JLabel( "End Threads" ));
158 			builder.addRelatedGap();
159 			builder.addFixed( endThreadCountSpinner);
160 
161 			configPanel = builder.getPanel();
162 			
163 			stateDependantComponents.add( startThreadCountSpinner );
164 			stateDependantComponents.add( endThreadCountSpinner );
165 		}
166 
167 		return configPanel;
168 	}
169 	
170 	/***
171 	 * Factory for ThreadCountChangeLoadStrategy class
172 	 * 
173 	 * @author Ole.Matzura
174 	 */
175 
176 	public static class Factory implements LoadStrategyFactory
177 	{
178 		public String getType()
179 		{
180 			return STRATEGY_TYPE;
181 		}
182 
183 		public LoadStrategy build(XmlObject config)
184 		{
185 			return new ThreadCountChangeLoadStrategy( config );
186 		}
187 
188 		public LoadStrategy create()
189 		{
190 			return new ThreadCountChangeLoadStrategy( null );
191 		}
192 	}
193 }