View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2009 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.testcase;
14  
15  import java.util.Arrays;
16  import java.util.HashSet;
17  import java.util.List;
18  import java.util.Set;
19  
20  import com.eviware.soapui.SoapUI;
21  import com.eviware.soapui.impl.wsdl.WsdlTestSuite;
22  import com.eviware.soapui.impl.wsdl.support.AbstractTestRunner;
23  import com.eviware.soapui.model.propertyexpansion.DefaultPropertyExpansionContext;
24  import com.eviware.soapui.model.support.TestRunListenerAdapter;
25  import com.eviware.soapui.model.testsuite.TestCase;
26  import com.eviware.soapui.model.testsuite.TestCaseRunContext;
27  import com.eviware.soapui.model.testsuite.TestCaseRunner;
28  import com.eviware.soapui.model.testsuite.TestRunListener;
29  import com.eviware.soapui.model.testsuite.TestSuite;
30  import com.eviware.soapui.model.testsuite.TestSuiteRunListener;
31  import com.eviware.soapui.model.testsuite.TestSuiteRunner;
32  import com.eviware.soapui.model.testsuite.TestSuite.TestSuiteRunType;
33  import com.eviware.soapui.support.types.StringToObjectMap;
34  
35  /***
36   * WSDL TestCase Runner - runs all steps in a testcase and collects performance
37   * data
38   * 
39   * @author Ole.Matzura
40   */
41  
42  public class WsdlTestSuiteRunner extends AbstractTestRunner<WsdlTestSuite, WsdlTestSuiteRunContext> implements
43  		TestSuiteRunner
44  {
45  	private TestSuiteRunListener[] listeners;
46  	private Set<TestCaseRunner> finishedRunners = new HashSet<TestCaseRunner>();
47  	private Set<TestCaseRunner> activeRunners = new HashSet<TestCaseRunner>();
48  	private int currentTestCaseIndex;
49  	private WsdlTestCase currentTestCase;
50  	private TestRunListener parallellTestRunListener = new ParallellTestRunListener();
51  
52  	public WsdlTestSuiteRunner( WsdlTestSuite testSuite, StringToObjectMap properties )
53  	{
54  		super( testSuite, properties );
55  	}
56  
57  	public WsdlTestSuiteRunContext createContext( StringToObjectMap properties )
58  	{
59  		return new WsdlTestSuiteRunContext( this, properties );
60  	}
61  
62  	public void onCancel( String reason )
63  	{
64  		for( TestCaseRunner runner : activeRunners.toArray( new TestCaseRunner[activeRunners.size()] ) )
65  		{
66  			runner.cancel( reason );
67  		}
68  	}
69  
70  	public void onFail( String reason )
71  	{
72  		for( TestCaseRunner runner : activeRunners.toArray( new TestCaseRunner[activeRunners.size()] ) )
73  		{
74  			runner.fail( reason );
75  		}
76  	}
77  
78  	public void internalRun( WsdlTestSuiteRunContext runContext ) throws Exception
79  	{
80  		WsdlTestSuite testSuite = getTestRunnable();
81  
82  		testSuite.runSetupScript( runContext, this );
83  		if( !isRunning() )
84  			return;
85  
86  		if( testSuite.getTimeout() > 0 )
87  		{
88  			startTimeoutTimer( testSuite.getTimeout() );
89  		}
90  
91  		listeners = testSuite.getTestSuiteRunListeners();
92  		notifyBeforeRun();
93  		if( !isRunning() )
94  			return;
95  
96  		if( testSuite.getRunType() == TestSuiteRunType.SEQUENTIAL )
97  		{
98  			runSequential( testSuite, runContext );
99  		}
100 		else if( testSuite.getRunType() == TestSuiteRunType.PARALLEL )
101 		{
102 			runParallel( testSuite, runContext );
103 		}
104 	}
105 
106 	private void runParallel( WsdlTestSuite testSuite, WsdlTestSuiteRunContext runContext )
107 	{
108 		currentTestCaseIndex = -1;
109 		currentTestCase = null;
110 
111 		for( TestCase testCase : testSuite.getTestCaseList() )
112 		{
113 			if( !testCase.isDisabled() )
114 			{
115 				testCase.addTestRunListener( parallellTestRunListener );
116 				notifyBeforeRunTestCase( testCase );
117 				runTestCase( ( WsdlTestCase )testCase, true );
118 			}
119 		}
120 
121 		try
122 		{
123 			synchronized( activeRunners )
124 			{
125 				activeRunners.wait();
126 			}
127 		}
128 		catch( InterruptedException e )
129 		{
130 			e.printStackTrace();
131 		}
132 	}
133 
134 	private void runSequential( WsdlTestSuite testSuite, WsdlTestSuiteRunContext runContext )
135 	{
136 		currentTestCaseIndex = 0;
137 		for( ; isRunning() && currentTestCaseIndex < testSuite.getTestCaseCount(); currentTestCaseIndex++ )
138 		{
139 			currentTestCase = testSuite.getTestCaseAt( currentTestCaseIndex );
140 			if( !currentTestCase.isDisabled() )
141 			{
142 				notifyBeforeRunTestCase( currentTestCase );
143 				TestCaseRunner testCaseRunner = runTestCase( currentTestCase, false );
144 				activeRunners.remove( testCaseRunner );
145 				finishedRunners.add( testCaseRunner );
146 				notifyAfterRunTestCase( testCaseRunner );
147 			}
148 		}
149 
150 		updateStatus();
151 	}
152 
153 	private void updateStatus()
154 	{
155 		for( TestCaseRunner runner : finishedRunners )
156 		{
157 			if( runner.getStatus() == Status.FAILED )
158 			{
159 				setStatus( Status.FAILED );
160 				break;
161 			}
162 		}
163 	}
164 
165 	private TestCaseRunner runTestCase( WsdlTestCase testCaseAt, boolean async )
166 	{
167 		DefaultPropertyExpansionContext properties = ( DefaultPropertyExpansionContext )getRunContext().getProperties();
168 		properties.put( "#TestSuiteRunner#", this );
169 
170 		TestCaseRunner currentRunner = testCaseAt.run( properties, true );
171 		activeRunners.add( currentRunner );
172 		if( !async )
173 			currentRunner.waitUntilFinished();
174 
175 		return currentRunner;
176 	}
177 
178 	protected void internalFinally( WsdlTestSuiteRunContext runContext )
179 	{
180 		WsdlTestSuite testSuite = getTestRunnable();
181 
182 		try
183 		{
184 			testSuite.runTearDownScript( runContext, this );
185 		}
186 		catch( Exception e )
187 		{
188 			SoapUI.logError( e );
189 		}
190 		
191 		notifyAfterRun();
192 
193 		runContext.clear();
194 		listeners = null;
195 	}
196 
197 	private void notifyAfterRun()
198 	{
199 		if( listeners == null || listeners.length == 0 )
200 			return;
201 
202 		for( int i = 0; i < listeners.length; i++ )
203 		{
204 			listeners[i].afterRun( this, getRunContext() );
205 		}
206 	}
207 
208 	private void notifyBeforeRun()
209 	{
210 		if( listeners == null || listeners.length == 0 )
211 			return;
212 
213 		for( int i = 0; i < listeners.length; i++ )
214 		{
215 			listeners[i].beforeRun( this, getRunContext() );
216 		}
217 	}
218 
219 	private void notifyAfterRunTestCase( TestCaseRunner testCaseRunner )
220 	{
221 		if( listeners == null || listeners.length == 0 )
222 			return;
223 
224 		for( int i = 0; i < listeners.length; i++ )
225 		{
226 			listeners[i].afterTestCase( this, getRunContext(), testCaseRunner );
227 		}
228 	}
229 
230 	private void notifyBeforeRunTestCase( TestCase testCase )
231 	{
232 		if( listeners == null || listeners.length == 0 )
233 			return;
234 
235 		for( int i = 0; i < listeners.length; i++ )
236 		{
237 			listeners[i].beforeTestCase( this, getRunContext(), testCase );
238 		}
239 	}
240 
241 	public TestSuite getTestSuite()
242 	{
243 		return getTestRunnable();
244 	}
245 
246 	public List<TestCaseRunner> getResults()
247 	{
248 		return Arrays.asList( finishedRunners.toArray( new TestCaseRunner[finishedRunners.size()] ) );
249 	}
250 
251 	public int getCurrentTestCaseIndex()
252 	{
253 		return currentTestCaseIndex;
254 	}
255 
256 	public WsdlTestCase getCurrentTestCase()
257 	{
258 		return currentTestCase;
259 	}
260 
261 	private class ParallellTestRunListener extends TestRunListenerAdapter
262 	{
263 		@Override
264 		public void afterRun( TestCaseRunner testRunner, TestCaseRunContext runContext )
265 		{
266 			notifyAfterRunTestCase( testRunner );
267 
268 			activeRunners.remove( testRunner );
269 			finishedRunners.add( testRunner );
270 
271 			testRunner.getTestCase().removeTestRunListener( parallellTestRunListener );
272 
273 			if( activeRunners.isEmpty() )
274 			{
275 				updateStatus();
276 
277 				synchronized( activeRunners )
278 				{
279 					activeRunners.notify();
280 				}
281 			}
282 		}
283 	}
284 }