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