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() throws Exception
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 		if( targetTestCase != null )
123 		{
124 			runningTestCase = createTestCase( targetTestCase );
125 			for( TestRunListener listener : testRunListeners )
126 				runningTestCase.addTestRunListener( listener );
127 			
128 			StringList returnProperties = getReturnProperties();
129 			Map<String, TestProperty> props = getProperties();
130 			for( String key : props.keySet() )
131 			{
132 				if( runningTestCase.hasProperty( key ) && !returnProperties.contains( key ))
133 				{
134 					String value = props.get( key ).getValue();
135 					runningTestCase.setPropertyValue( key, PropertyExpansionUtils.expandProperties( testRunContext, value ));
136 				}
137 			}
138 			
139 			currentLabel = getLabel();
140 			runningTestCase.addTestRunListener( testRunListener );
141 			
142 			StringToObjectMap properties = new StringToObjectMap();
143 			for( String name : testRunContext.getPropertyNames() )
144 				properties.put( name, testRunContext.getProperty( name ));
145 			
146 			testCaseRunner = runningTestCase.run( properties, false );
147 			
148 			for( String key : returnProperties )
149 			{
150 				if( runningTestCase.hasProperty( key ))
151 					setPropertyValue( key, runningTestCase.getPropertyValue( key ) );
152 			}
153 
154 			// aggregate results
155 			for( TestStepResult testStepResult : testCaseRunner.getResults())
156 			{
157 				result.addMessages( testStepResult.getMessages() );
158 				
159 				if( testStepResult instanceof MessageExchangeTestStepResult )
160 				{
161 					result.addMessages( ((MessageExchangeTestStepResult)testStepResult).getMessageExchanges());
162 				}
163 			}
164 			
165 			switch( testCaseRunner.getStatus() )
166 			{
167 				case CANCELED : result.setStatus( TestStepStatus.CANCELED ); break;
168 				case FAILED : result.setStatus( TestStepStatus.FAILED ); break;
169 				case FINISHED : result.setStatus( TestStepStatus.OK ); break;
170 				default : result.setStatus( TestStepStatus.UNKNOWN ); break;
171 			}
172 			
173 			for( TestRunListener listener : testRunListeners )
174 				runningTestCase.removeTestRunListener( listener );
175 			
176 			runningTestCase.release();
177 			runningTestCase = null;
178 			testCaseRunner = null;
179 		}
180 		else
181 		{
182 			result.setStatus( TestStepStatus.FAILED );
183 			result.addMessage( "Missing testCase in project" );
184 		}
185 		
186 		return result;
187 	}
188 	
189 	@Override
190 	public String getLabel()
191 	{
192 		String name = getName();
193 		
194 		if( testCaseRunner != null )
195 		{
196 			name += " - [" + testCaseRunner.getStatus() + "]";
197 		}
198 		
199 		if( isDisabled() )
200 			return name + " (disabled)";
201 		else
202 			return name;
203 	}
204 
205 	@Override
206 	public boolean cancel()
207 	{
208 		if( testCaseRunner != null )
209 		{
210 			testCaseRunner.cancel( "Canceled by calling TestCase" );
211 		}
212 		
213 		return true;
214 	}
215 
216 	private String getTestCaseId()
217 	{
218 		return stepConfig.getTargetTestCase();
219 	}
220 
221 	public void setTargetTestCase( WsdlTestCase testCase )
222 	{
223 		if( targetTestCase != null )
224 		{
225 			targetTestCase.getTestSuite().removeTestSuiteListener( testSuiteListener );
226 			targetTestCase.removeTestPropertyListener( testPropertyListener );
227 		}
228 		
229 		WsdlTestCase oldTestCase = this.targetTestCase;
230 		this.targetTestCase = testCase;
231 		
232 		if( testCase != null )
233 		{
234 			stepConfig.setTargetTestCase( testCase.getId() );
235 			
236 			targetTestCase.getTestSuite().addTestSuiteListener( testSuiteListener );
237 			targetTestCase.addTestPropertyListener( testPropertyListener );
238 			
239 			syncProperties();
240 		}
241 		
242 		notifyPropertyChanged( TARGET_TESTCASE, oldTestCase, testCase );
243 	}
244 	
245 	/***
246 	 * Creates a copy of the underlying WsdlTestCase with all LoadTests removed and configured for LoadTesting
247 	 */
248 	
249 	private WsdlTestCase createTestCase( WsdlTestCase testCase )
250 	{
251 		// clone config and remove and loadtests
252 		TestCaseConfig config = (TestCaseConfig) testCase.getConfig().copy();
253 		config.setLoadTestArray( new LoadTestConfig[0] );
254 		
255 		//	 clone entire testCase
256 		return new WsdlTestCase( testCase.getTestSuite(), config, true );
257 	}
258 
259 	public void addTestPropertyListener( TestPropertyListener listener )
260 	{
261 		propertyHolderSupport.addTestPropertyListener( listener );
262 	}
263 
264 	public Map<String, TestProperty> getProperties()
265 	{
266 		return propertyHolderSupport.getProperties();
267 	}
268 
269 	public PropertiesStepProperty getProperty( String name )
270 	{
271 		return propertyHolderSupport.getProperty( name );
272 	}
273 
274 	public String[] getPropertyNames()
275 	{
276 		return propertyHolderSupport.getPropertyNames();
277 	}
278 
279 	public String getPropertyValue( String name )
280 	{
281 		return propertyHolderSupport.getPropertyValue( name );
282 	}
283 
284 	public boolean hasProperty( String name )
285 	{
286 		return propertyHolderSupport.hasProperty( name );
287 	}
288 
289 	public void removeTestPropertyListener( TestPropertyListener listener )
290 	{
291 		propertyHolderSupport.removeTestPropertyListener( listener );
292 	}
293 
294 	public void setPropertyValue( String name, String value )
295 	{
296 		propertyHolderSupport.setPropertyValue( name, value );
297 	}
298 
299 	private void updateLabelDuringRun()
300 	{
301 		notifyPropertyChanged( WsdlTestStep.LABEL_PROPERTY, currentLabel, getLabel() );
302 		currentLabel = getLabel();
303 	}
304 	
305 	private final class InternalTestPropertyListener extends TestPropertyListenerAdapter
306 	{
307 		@Override
308 		public void propertyAdded( String name )
309 		{
310 			propertyHolderSupport.addProperty( name );
311 		}
312 
313 		@Override
314 		public void propertyRemoved( String name )
315 		{
316 			propertyHolderSupport.removeProperty( name );
317 		}
318 
319 		@Override
320 		public void propertyRenamed( String oldName, String newName )
321 		{
322 			propertyHolderSupport.renameProperty( oldName, newName );
323 		}
324 	}
325 
326 	private final class InternalTestRunListener extends TestRunListenerAdapter
327 	{
328 		@Override
329 		public void beforeRun( TestRunner testRunner, TestRunContext runContext )
330 		{
331 			updateLabelDuringRun();
332 		}
333 
334 		@Override
335 		public void afterRun( TestRunner testRunner, TestRunContext runContext )
336 		{
337 			updateLabelDuringRun();
338 		}
339 
340 		@Override
341 		public void afterStep( TestRunner testRunner, TestRunContext runContext, TestStepResult result )
342 		{
343 			updateLabelDuringRun();
344 		}
345 
346 		@Override
347 		public void beforeStep( TestRunner testRunner, TestRunContext runContext )
348 		{
349 			updateLabelDuringRun();
350 		}
351 	}
352 	
353 	@Override
354 	public void resetConfigOnMove( TestStepConfig config )
355 	{
356 		super.resetConfigOnMove( config );
357 		
358 		stepConfig = (RunTestCaseStepConfig) config.getConfig().changeType(RunTestCaseStepConfig.type);
359 		propertyHolderSupport.resetPropertiesConfig( stepConfig.getProperties() );
360 	}
361 
362 	@Override
363 	public void release()
364 	{
365 		if( targetTestCase != null )
366 		{
367 			targetTestCase.getTestSuite().removeTestSuiteListener( testSuiteListener );
368 			targetTestCase.removeTestPropertyListener( testPropertyListener );
369 		}
370 		
371 		super.release();
372 	}
373 
374 	private final class InternalTestSuiteListener extends TestSuiteListenerAdapter
375 	{
376 		@Override
377 		public void testCaseRemoved( TestCase testCase )
378 		{
379 			setTargetTestCase( findTargetTestCase() );
380 		}
381 	}
382 
383 	public WsdlTestCase getTargetTestCase()
384 	{
385 		return targetTestCase;
386 	}
387 
388 	public void addTestRunListener( TestRunListener listener )
389 	{
390 		testRunListeners.add( listener );
391 	}
392 
393 	public void removeTestRunListener( TestRunListener listener )
394 	{
395 		testRunListeners.remove( listener);
396 	}
397 
398 	public WsdlTestCase getRunningTestCase()
399 	{
400 		return runningTestCase;
401 	}
402 
403 	public WsdlTestCaseRunner getTestCaseRunner()
404 	{
405 		return testCaseRunner;
406 	}
407 }