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 		for( int c = 0; c < initCount && c < testCase.getTestStepCount(); c++ )
156 		{
157 			WsdlTestStep testStep = testCase.getTestStepAt( c );
158 			if( !testStep.isDisabled() )
159 				testStep.finish( this, runContext );
160 		}
161 
162 		notifyAfterRun();
163 
164 		try
165 		{
166 			testCase.runTearDownScript( runContext, this );
167 		}
168 		catch( Exception e )
169 		{
170 			SoapUI.logError( e );
171 		}
172 
173 		runContext.clear();
174 		listeners = null;
175 	}
176 
177 	public TestStepResult runTestStepByName( String name )
178 	{
179 		return runTestStep( getTestCase().getTestStepByName( name ), true, true );
180 	}
181 
182 	public TestStepResult runTestStep( TestStep testStep )
183 	{
184 		return runTestStep( testStep, true, true );
185 	}
186 
187 	public TestStepResult runTestStep( TestStep testStep, boolean discard, boolean process )
188 	{
189 		for( int i = 0; i < listeners.length; i++ )
190 		{
191 			listeners[i].beforeStep( this, getRunContext(), testStep );
192 			if( !isRunning() )
193 				return null;
194 		}
195 
196 		TestStepResult stepResult = testStep.run( this, getRunContext() );
197 		testStepResults.add( stepResult );
198 		resultCount++ ;
199 		enforceMaxResults( getTestRunnable().getMaxResults() );
200 
201 		for( int i = 0; i < listeners.length; i++ )
202 		{
203 			listeners[i].afterStep( this, getRunContext(), stepResult );
204 		}
205 
206 		// discard?
207 		if( discard && stepResult.getStatus() == TestStepStatus.OK && getTestRunnable().getDiscardOkResults()
208 				&& !stepResult.isDiscarded() )
209 		{
210 			stepResult.discard();
211 		}
212 
213 		if( process && stepResult.getStatus() == TestStepStatus.FAILED )
214 		{
215 			if( getTestRunnable().getFailOnError() )
216 			{
217 				setError( stepResult.getError() );
218 				fail( "Cancelling due to failed test step" );
219 			}
220 			else
221 			{
222 				getRunContext().setProperty( TestCaseRunner.Status.class.getName(), TestCaseRunner.Status.FAILED );
223 			}
224 		}
225 
226 		return stepResult;
227 	}
228 
229 	private void notifyAfterRun()
230 	{
231 		if( listeners == null || listeners.length == 0 )
232 			return;
233 
234 		for( int i = 0; i < listeners.length; i++ )
235 		{
236 			try
237 			{
238 				listeners[i].afterRun( this, getRunContext() );
239 			}
240 			catch( Throwable t )
241 			{
242 				SoapUI.logError( t );
243 			}
244 		}
245 	}
246 
247 	private void notifyBeforeRun()
248 	{
249 		if( listeners == null || listeners.length == 0 )
250 			return;
251 
252 		for( int i = 0; i < listeners.length; i++ )
253 		{
254 			try
255 			{
256 				listeners[i].beforeRun( this, getRunContext() );
257 			}
258 			catch( Throwable t )
259 			{
260 				SoapUI.logError( t );
261 			}
262 		}
263 	}
264 
265 	public TestCase getTestCase()
266 	{
267 		return getTestRunnable();
268 	}
269 
270 	public long getTimeTaken()
271 	{
272 		long sum = 0;
273 		for( int c = 0; c < testStepResults.size(); c++ )
274 		{
275 			TestStepResult testStepResult = testStepResults.get( c );
276 			if( testStepResult != null )
277 				sum += testStepResult.getTimeTaken();
278 		}
279 
280 		return sum;
281 	}
282 
283 	public List<TestStepResult> getResults()
284 	{
285 		return testStepResults;
286 	}
287 
288 	public int getResultCount()
289 	{
290 		return resultCount;
291 	}
292 
293 	public void gotoStep( int index )
294 	{
295 		gotoStepIndex = index;
296 	}
297 
298 	public void enforceMaxResults( long maxResults )
299 	{
300 		if( maxResults < 1 )
301 			return;
302 
303 		synchronized( this )
304 		{
305 			while( testStepResults.size() > maxResults )
306 			{
307 				testStepResults.remove( 0 );
308 			}
309 		}
310 	}
311 
312 	public void gotoStepByName( String stepName )
313 	{
314 		TestStep testStep = getTestCase().getTestStepByName( stepName );
315 		if( testStep != null )
316 			gotoStep( getTestCase().getIndexOfTestStep( testStep ) );
317 	}
318 }