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.teststeps;
14  
15  import java.util.HashSet;
16  import java.util.Map;
17  import java.util.Set;
18  
19  import com.eviware.soapui.config.LoadTestConfig;
20  import com.eviware.soapui.config.RunTestCaseStepConfig;
21  import com.eviware.soapui.config.TestCaseConfig;
22  import com.eviware.soapui.config.TestStepConfig;
23  import com.eviware.soapui.impl.wsdl.support.XmlBeansPropertiesTestPropertyHolder;
24  import com.eviware.soapui.impl.wsdl.support.XmlBeansPropertiesTestPropertyHolder.PropertiesStepProperty;
25  import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase;
26  import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCaseRunner;
27  import com.eviware.soapui.model.propertyexpansion.PropertyExpansionUtils;
28  import com.eviware.soapui.model.support.ModelSupport;
29  import com.eviware.soapui.model.support.TestPropertyListenerAdapter;
30  import com.eviware.soapui.model.support.TestRunListenerAdapter;
31  import com.eviware.soapui.model.support.TestSuiteListenerAdapter;
32  import com.eviware.soapui.model.testsuite.MessageExchangeTestStepResult;
33  import com.eviware.soapui.model.testsuite.TestCase;
34  import com.eviware.soapui.model.testsuite.TestProperty;
35  import com.eviware.soapui.model.testsuite.TestPropertyListener;
36  import com.eviware.soapui.model.testsuite.TestRunContext;
37  import com.eviware.soapui.model.testsuite.TestRunListener;
38  import com.eviware.soapui.model.testsuite.TestRunner;
39  import com.eviware.soapui.model.testsuite.TestStepResult;
40  import com.eviware.soapui.model.testsuite.TestStepResult.TestStepStatus;
41  import com.eviware.soapui.support.UISupport;
42  import com.eviware.soapui.support.types.StringList;
43  import com.eviware.soapui.support.types.StringToObjectMap;
44  
45  public class WsdlRunTestCaseTestStep extends WsdlTestStep
46  {
47  	public static final String TARGET_TESTCASE = WsdlRunTestCaseTestStep.class.getName() + "@target_testcase";
48  	
49  	private RunTestCaseStepConfig stepConfig;
50  	private WsdlTestCaseRunner testCaseRunner;
51  	private XmlBeansPropertiesTestPropertyHolder propertyHolderSupport;
52  	private String currentLabel;
53  	private WsdlTestCase targetTestCase;
54  	private InternalTestSuiteListener testSuiteListener = new InternalTestSuiteListener();
55  	private InternalTestRunListener testRunListener = new InternalTestRunListener();
56  	private InternalTestPropertyListener testPropertyListener = new InternalTestPropertyListener();
57  	private Set<TestRunListener> testRunListeners = new HashSet<TestRunListener>();
58  
59  	private WsdlTestCase runningTestCase; 
60  
61  	public WsdlRunTestCaseTestStep( WsdlTestCase testCase, TestStepConfig config, boolean forLoadTest )
62  	{
63  		super( testCase, config, true, forLoadTest );
64  		
65  		if( config.getConfig() == null )
66  		{
67  			stepConfig = (RunTestCaseStepConfig) config.addNewConfig().changeType( RunTestCaseStepConfig.type );
68  			stepConfig.addNewProperties();
69  			stepConfig.addNewReturnProperties();
70  		}
71  		else
72  		{
73  			stepConfig = (RunTestCaseStepConfig) config.getConfig().changeType( RunTestCaseStepConfig.type );
74  		}
75  		
76  		setIcon( UISupport.createImageIcon( "/run_testcase_step.gif" ) );
77  		
78  		propertyHolderSupport = new XmlBeansPropertiesTestPropertyHolder( this, stepConfig.getProperties() );
79  	}
80  	
81  	@Override
82  	public void afterLoad() 
83  	{
84  		setTargetTestCase( findTargetTestCase() );
85  	}
86  
87  	private void syncProperties()
88  	{
89  		for( String name : propertyHolderSupport.getPropertyNames())
90  		{
91  			if( !targetTestCase.hasProperty( name ))
92  				propertyHolderSupport.removeProperty( name );
93  		}
94  		
95  		for( String name : targetTestCase.getPropertyNames())
96  		{
97  			if( !propertyHolderSupport.hasProperty( name ))
98  				propertyHolderSupport.addProperty( name );
99  		}
100 	}
101 
102 	private WsdlTestCase findTargetTestCase()
103 	{
104 		return ModelSupport.findModelItemById( getTestCaseId(), getTestCase().getTestSuite().getProject() );
105 	}
106 
107 	public StringList getReturnProperties()
108 	{
109 		return new StringList( stepConfig.getReturnProperties().getEntryList() );
110 	}
111 	
112 	public void setReturnProperties( StringList returnProperties )
113 	{
114 		stepConfig.getReturnProperties().setEntryArray( returnProperties.toStringArray() );
115 	}
116 	
117 	public TestStepResult run( TestRunner testRunner, TestRunContext testRunContext )
118 	{
119 		WsdlMessageExchangeTestStepResult result = new WsdlMessageExchangeTestStepResult( this );
120 		
121 		testCaseRunner = null;
122 		
123 		if( targetTestCase != null )
124 		{
125 			runningTestCase = createTestCase( targetTestCase );
126 			for( TestRunListener listener : testRunListeners )
127 				runningTestCase.addTestRunListener( listener );
128 			
129 			StringList returnProperties = getReturnProperties();
130 			Map<String, TestProperty> props = getProperties();
131 			for( String key : props.keySet() )
132 			{
133 				if( runningTestCase.hasProperty( key ) && !returnProperties.contains( key ))
134 				{
135 					String value = props.get( key ).getValue();
136 					runningTestCase.setPropertyValue( key, PropertyExpansionUtils.expandProperties( testRunContext, value ));
137 				}
138 			}
139 			
140 			currentLabel = getLabel();
141 			runningTestCase.addTestRunListener( testRunListener );
142 			
143 			StringToObjectMap properties = new StringToObjectMap();
144 			for( String name : testRunContext.getPropertyNames() )
145 				properties.put( name, testRunContext.getProperty( name ));
146 			
147 			result.startTimer();
148 			testCaseRunner = runningTestCase.run( properties, false );
149 			result.stopTimer();
150 			
151 			for( String key : returnProperties )
152 			{
153 				if( runningTestCase.hasProperty( key ))
154 					setPropertyValue( key, runningTestCase.getPropertyValue( key ) );
155 			}
156 
157 			// aggregate results
158 			for( TestStepResult testStepResult : testCaseRunner.getResults())
159 			{
160 				result.addMessages( testStepResult.getMessages() );
161 				
162 				if( testStepResult instanceof MessageExchangeTestStepResult )
163 				{
164 					result.addMessages( ((MessageExchangeTestStepResult)testStepResult).getMessageExchanges());
165 				}
166 			}
167 			
168 			switch( testCaseRunner.getStatus() )
169 			{
170 				case CANCELED : result.setStatus( TestStepStatus.CANCELED ); break;
171 				case FAILED : result.setStatus( TestStepStatus.FAILED ); break;
172 				case FINISHED : result.setStatus( TestStepStatus.OK ); break;
173 				default : result.setStatus( TestStepStatus.UNKNOWN ); break;
174 			}
175 			
176 			for( TestRunListener listener : testRunListeners )
177 				runningTestCase.removeTestRunListener( listener );
178 			
179 			runningTestCase.release();
180 			runningTestCase = null;
181 			testCaseRunner = null;
182 		}
183 		else
184 		{
185 			result.setStatus( TestStepStatus.FAILED );
186 			result.addMessage( "Missing testCase in project" );
187 			result.stopTimer();
188 		}
189 		
190 		return result;
191 	}
192 	
193 	@Override
194 	public String getLabel()
195 	{
196 		String name = getName();
197 		
198 		if( testCaseRunner != null )
199 		{
200 			name += " - [" + testCaseRunner.getStatus() + "]";
201 		}
202 		
203 		if( isDisabled() )
204 			return name + " (disabled)";
205 		else
206 			return name;
207 	}
208 
209 	@Override
210 	public boolean cancel()
211 	{
212 		if( testCaseRunner != null )
213 		{
214 			testCaseRunner.cancel( "Canceled by calling TestCase" );
215 		}
216 		
217 		return true;
218 	}
219 
220 	private String getTestCaseId()
221 	{
222 		return stepConfig.getTargetTestCase();
223 	}
224 
225 	public void setTargetTestCase( WsdlTestCase testCase )
226 	{
227 		if( targetTestCase != null )
228 		{
229 			targetTestCase.getTestSuite().removeTestSuiteListener( testSuiteListener );
230 			targetTestCase.removeTestPropertyListener( testPropertyListener );
231 		}
232 		
233 		WsdlTestCase oldTestCase = this.targetTestCase;
234 		this.targetTestCase = testCase;
235 		
236 		if( testCase != null )
237 		{
238 			stepConfig.setTargetTestCase( testCase.getId() );
239 			
240 			targetTestCase.getTestSuite().addTestSuiteListener( testSuiteListener );
241 			targetTestCase.addTestPropertyListener( testPropertyListener );
242 			
243 			syncProperties();
244 		}
245 		
246 		notifyPropertyChanged( TARGET_TESTCASE, oldTestCase, testCase );
247 	}
248 	
249 	/***
250 	 * Creates a copy of the underlying WsdlTestCase with all LoadTests removed and configured for LoadTesting
251 	 */
252 	
253 	private WsdlTestCase createTestCase( WsdlTestCase testCase )
254 	{
255 		// clone config and remove and loadtests
256 		testCase.beforeSave();
257 		TestCaseConfig config = (TestCaseConfig) testCase.getConfig().copy();
258 		config.setLoadTestArray( new LoadTestConfig[0] );
259 		
260 		//	 clone entire testCase
261 		WsdlTestCase wsdlTestCase = new WsdlTestCase( testCase.getTestSuite(), config, true );
262 		wsdlTestCase.afterLoad();
263 		return wsdlTestCase;
264 	}
265 
266 	public void addTestPropertyListener( TestPropertyListener listener )
267 	{
268 		propertyHolderSupport.addTestPropertyListener( listener );
269 	}
270 
271 	public Map<String, TestProperty> getProperties()
272 	{
273 		return propertyHolderSupport.getProperties();
274 	}
275 
276 	public PropertiesStepProperty getProperty( String name )
277 	{
278 		return propertyHolderSupport.getProperty( name );
279 	}
280 
281 	public String[] getPropertyNames()
282 	{
283 		return propertyHolderSupport.getPropertyNames();
284 	}
285 
286 	public String getPropertyValue( String name )
287 	{
288 		return propertyHolderSupport.getPropertyValue( name );
289 	}
290 
291 	public boolean hasProperty( String name )
292 	{
293 		return propertyHolderSupport.hasProperty( name );
294 	}
295 
296 	public void removeTestPropertyListener( TestPropertyListener listener )
297 	{
298 		propertyHolderSupport.removeTestPropertyListener( listener );
299 	}
300 
301 	public void setPropertyValue( String name, String value )
302 	{
303 		propertyHolderSupport.setPropertyValue( name, value );
304 	}
305 
306 	private void updateLabelDuringRun()
307 	{
308 		notifyPropertyChanged( WsdlTestStep.LABEL_PROPERTY, currentLabel, getLabel() );
309 		currentLabel = getLabel();
310 	}
311 	
312 	private final class InternalTestPropertyListener extends TestPropertyListenerAdapter
313 	{
314 		@Override
315 		public void propertyAdded( String name )
316 		{
317 			propertyHolderSupport.addProperty( name );
318 		}
319 
320 		@Override
321 		public void propertyRemoved( String name )
322 		{
323 			propertyHolderSupport.removeProperty( name );
324 		}
325 
326 		@Override
327 		public void propertyRenamed( String oldName, String newName )
328 		{
329 			propertyHolderSupport.renameProperty( oldName, newName );
330 		}
331 	}
332 
333 	private final class InternalTestRunListener extends TestRunListenerAdapter
334 	{
335 		@Override
336 		public void beforeRun( TestRunner testRunner, TestRunContext runContext )
337 		{
338 			updateLabelDuringRun();
339 		}
340 
341 		@Override
342 		public void afterRun( TestRunner testRunner, TestRunContext runContext )
343 		{
344 			updateLabelDuringRun();
345 		}
346 
347 		@Override
348 		public void afterStep( TestRunner testRunner, TestRunContext runContext, TestStepResult result )
349 		{
350 			updateLabelDuringRun();
351 		}
352 
353 		@Override
354 		public void beforeStep( TestRunner testRunner, TestRunContext runContext )
355 		{
356 			updateLabelDuringRun();
357 		}
358 	}
359 	
360 	@Override
361 	public void resetConfigOnMove( TestStepConfig config )
362 	{
363 		super.resetConfigOnMove( config );
364 		
365 		stepConfig = (RunTestCaseStepConfig) config.getConfig().changeType(RunTestCaseStepConfig.type);
366 		propertyHolderSupport.resetPropertiesConfig( stepConfig.getProperties() );
367 	}
368 
369 	@Override
370 	public void release()
371 	{
372 		if( targetTestCase != null )
373 		{
374 			targetTestCase.getTestSuite().removeTestSuiteListener( testSuiteListener );
375 			targetTestCase.removeTestPropertyListener( testPropertyListener );
376 		}
377 		
378 		super.release();
379 	}
380 
381 	private final class InternalTestSuiteListener extends TestSuiteListenerAdapter
382 	{
383 		@Override
384 		public void testCaseRemoved( TestCase testCase )
385 		{
386 			setTargetTestCase( findTargetTestCase() );
387 		}
388 	}
389 
390 	public WsdlTestCase getTargetTestCase()
391 	{
392 		return targetTestCase;
393 	}
394 
395 	public void addTestRunListener( TestRunListener listener )
396 	{
397 		testRunListeners.add( listener );
398 	}
399 
400 	public void removeTestRunListener( TestRunListener listener )
401 	{
402 		testRunListeners.remove( listener);
403 	}
404 
405 	public WsdlTestCase getRunningTestCase()
406 	{
407 		return runningTestCase;
408 	}
409 
410 	public WsdlTestCaseRunner getTestCaseRunner()
411 	{
412 		return testCaseRunner;
413 	}
414 }