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.LinkedList;
16  import java.util.List;
17  
18  import org.apache.commons.httpclient.HttpState;
19  
20  import com.eviware.soapui.SoapUI;
21  import com.eviware.soapui.impl.wsdl.support.AbstractTestRunner;
22  import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestStep;
23  import com.eviware.soapui.model.iface.SubmitContext;
24  import com.eviware.soapui.model.testsuite.TestCase;
25  import com.eviware.soapui.model.testsuite.TestCaseRunner;
26  import com.eviware.soapui.model.testsuite.TestRunListener;
27  import com.eviware.soapui.model.testsuite.TestStep;
28  import com.eviware.soapui.model.testsuite.TestStepResult;
29  import com.eviware.soapui.model.testsuite.TestStepResult.TestStepStatus;
30  import com.eviware.soapui.support.types.StringToObjectMap;
31  
32  /***
33   * WSDL TestCase Runner - runs all steps in a testcase and collects performance
34   * data
35   * 
36   * @author Ole.Matzura
37   */
38  
39  public class WsdlTestCaseRunner extends AbstractTestRunner<WsdlTestCase, WsdlTestRunContext> implements TestCaseRunner
40  {
41  	private TestRunListener[] listeners;
42  	private List<TestStepResult> testStepResults = new LinkedList<TestStepResult>();
43  	private int gotoStepIndex;
44  	private int resultCount;
45  	// private HashMap<String, WsrmSequence> wsrmMap;
46  
47  	// private final static Logger log =
48  	// Logger.getLogger(WsdlTestCaseRunner.class);
49  	private int initCount;
50  
51  	public WsdlTestCaseRunner( WsdlTestCase testCase, StringToObjectMap properties )
52  	{
53  		super( testCase, properties );
54  	}
55  
56  	public WsdlTestRunContext createContext( StringToObjectMap properties )
57  	{
58  		return new WsdlTestRunContext( this, properties );
59  	}
60  
61  	public void onCancel( String reason )
62  	{
63  		TestStep currentStep = getRunContext().getCurrentStep();
64  		if( currentStep != null )
65  			currentStep.cancel();
66  	}
67  
68  	public void onFail( String reason )
69  	{
70  		TestStep currentStep = getRunContext().getCurrentStep();
71  		if( currentStep != null )
72  			currentStep.cancel();
73  	}
74  
75  	public void internalRun( WsdlTestRunContext runContext ) throws Exception
76  	{
77  		WsdlTestCase testCase = getTestRunnable();
78  		gotoStepIndex = -1;
79  		testStepResults.clear();
80  
81  		// create state for testcase if specified
82  		if( testCase.getKeepSession() )
83  		{
84  			runContext.setProperty( SubmitContext.HTTP_STATE_PROPERTY, new HttpState() );
85  		}
86  
87  		testCase.runSetupScript( runContext, this );
88  		if( !isRunning() )
89  			return;
90  
91  		if( testCase.getTimeout() > 0 )
92  		{
93  			startTimeoutTimer( testCase.getTimeout() );
94  		}
95  
96  		listeners = testCase.getTestRunListeners();
97  		notifyBeforeRun();
98  		if( !isRunning() )
99  			return;
100 
101 		initCount = 0;
102 
103 		for( ; initCount < testCase.getTestStepCount() && isRunning(); initCount++ )
104 		{
105 			WsdlTestStep testStep = testCase.getTestStepAt( initCount );
106 			if( testStep.isDisabled() )
107 				continue;
108 
109 			try
110 			{
111 				testStep.prepare( this, runContext );
112 			}
113 			catch( Exception e )
114 			{
115 				setStatus( Status.FAILED );
116 				SoapUI.logError( e );
117 				throw new Exception( "Failed to prepare testStep [" + testStep.getName() + "]; " + e.toString() );
118 			}
119 		}
120 
121 		int currentStepIndex = 0;
122 
123 		for( ; isRunning() && currentStepIndex < testCase.getTestStepCount(); currentStepIndex++ )
124 		{
125 			TestStep currentStep = runContext.getCurrentStep();
126 			if( !currentStep.isDisabled() )
127 			{
128 				TestStepResult stepResult = runTestStep( currentStep, true, true );
129 				if( stepResult == null )
130 					return;
131 
132 				if( !isRunning() )
133 					return;
134 
135 				if( gotoStepIndex != -1 )
136 				{
137 					currentStepIndex = gotoStepIndex - 1;
138 					gotoStepIndex = -1;
139 				}
140 			}
141 
142 			runContext.setCurrentStep( currentStepIndex + 1 );
143 		}
144 
145 		if( runContext.getProperty( TestCaseRunner.Status.class.getName() ) == TestCaseRunner.Status.FAILED
146 				&& testCase.getFailTestCaseOnErrors() )
147 		{
148 			fail( "Failing due to failed test step" );
149 		}
150 	}
151 
152 	protected void internalFinally( WsdlTestRunContext runContext )
153 	{
154 		WsdlTestCase testCase = getTestRunnable();
155 		
156 		try
157 		{
158 			testCase.runTearDownScript( runContext, this );
159 		}
160 		catch( Exception e )
161 		{
162 			SoapUI.logError( e );
163 		}
164 		
165 		for( int c = 0; c < initCount && c < testCase.getTestStepCount(); c++ )
166 		{
167 			WsdlTestStep testStep = testCase.getTestStepAt( c );
168 			if( !testStep.isDisabled() )
169 				testStep.finish( this, runContext );
170 		}
171 
172 		notifyAfterRun();
173 
174 		runContext.clear();
175 		listeners = null;
176 	}
177 
178 	public TestStepResult runTestStepByName( String name )
179 	{
180 		return runTestStep( getTestCase().getTestStepByName( name ), true, true );
181 	}
182 
183 	public TestStepResult runTestStep( TestStep testStep )
184 	{
185 		return runTestStep( testStep, true, true );
186 	}
187 
188 	public TestStepResult runTestStep( TestStep testStep, boolean discard, boolean process )
189 	{
190 		for( int i = 0; i < listeners.length; i++ )
191 		{
192 			listeners[i].beforeStep( this, getRunContext(), testStep );
193 			if( !isRunning() )
194 				return null;
195 		}
196 
197 		TestStepResult stepResult = testStep.run( this, getRunContext() );
198 		testStepResults.add( stepResult );
199 		resultCount++ ;
200 		enforceMaxResults( getTestRunnable().getMaxResults() );
201 
202 		for( int i = 0; i < listeners.length; i++ )
203 		{
204 			listeners[i].afterStep( this, getRunContext(), stepResult );
205 		}
206 
207 		// discard?
208 		if( discard && stepResult.getStatus() == TestStepStatus.OK && getTestRunnable().getDiscardOkResults()
209 				&& !stepResult.isDiscarded() )
210 		{
211 			stepResult.discard();
212 		}
213 
214 		if( process && stepResult.getStatus() == TestStepStatus.FAILED )
215 		{
216 			if( getTestRunnable().getFailOnError() )
217 			{
218 				setError( stepResult.getError() );
219 				fail( "Cancelling due to failed test step" );
220 			}
221 			else
222 			{
223 				getRunContext().setProperty( TestCaseRunner.Status.class.getName(), TestCaseRunner.Status.FAILED );
224 			}
225 		}
226 
227 		return stepResult;
228 	}
229 
230 	private void notifyAfterRun()
231 	{
232 		if( listeners == null || listeners.length == 0 )
233 			return;
234 
235 		for( int i = 0; i < listeners.length; i++ )
236 		{
237 			try
238 			{
239 				listeners[i].afterRun( this, getRunContext() );
240 			}
241 			catch( Throwable t )
242 			{
243 				SoapUI.logError( t );
244 			}
245 		}
246 	}
247 
248 	private void notifyBeforeRun()
249 	{
250 		if( listeners == null || listeners.length == 0 )
251 			return;
252 
253 		for( int i = 0; i < listeners.length; i++ )
254 		{
255 			try
256 			{
257 				listeners[i].beforeRun( this, getRunContext() );
258 			}
259 			catch( Throwable t )
260 			{
261 				SoapUI.logError( t );
262 			}
263 		}
264 	}
265 
266 	public TestCase getTestCase()
267 	{
268 		return getTestRunnable();
269 	}
270 
271 	public long getTimeTaken()
272 	{
273 		long sum = 0;
274 		for( int c = 0; c < testStepResults.size(); c++ )
275 		{
276 			TestStepResult testStepResult = testStepResults.get( c );
277 			if( testStepResult != null )
278 				sum += testStepResult.getTimeTaken();
279 		}
280 
281 		return sum;
282 	}
283 
284 	public List<TestStepResult> getResults()
285 	{
286 		return testStepResults;
287 	}
288 
289 	public int getResultCount()
290 	{
291 		return resultCount;
292 	}
293 
294 	public void gotoStep( int index )
295 	{
296 		gotoStepIndex = index;
297 	}
298 
299 	public void enforceMaxResults( long maxResults )
300 	{
301 		if( maxResults < 1 )
302 			return;
303 
304 		synchronized( this )
305 		{
306 			while( testStepResults.size() > maxResults )
307 			{
308 				testStepResults.remove( 0 );
309 			}
310 		}
311 	}
312 
313 	public void gotoStepByName( String stepName )
314 	{
315 		TestStep testStep = getTestCase().getTestStepByName( stepName );
316 		if( testStep != null )
317 			gotoStep( getTestCase().getIndexOfTestStep( testStep ) );
318 	}
319 }