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.testcase;
14  
15  import java.util.ArrayList;
16  import java.util.HashMap;
17  import java.util.HashSet;
18  import java.util.List;
19  import java.util.Map;
20  import java.util.Set;
21  
22  import org.apache.log4j.Logger;
23  
24  import com.eviware.soapui.SoapUI;
25  import com.eviware.soapui.config.LoadTestConfig;
26  import com.eviware.soapui.config.TestCaseConfig;
27  import com.eviware.soapui.config.TestStepConfig;
28  import com.eviware.soapui.impl.wsdl.AbstractTestPropertyHolderWsdlModelItem;
29  import com.eviware.soapui.impl.wsdl.WsdlTestSuite;
30  import com.eviware.soapui.impl.wsdl.loadtest.LoadTestAssertion;
31  import com.eviware.soapui.impl.wsdl.loadtest.WsdlLoadTest;
32  import com.eviware.soapui.impl.wsdl.loadtest.assertions.TestStepStatusAssertion;
33  import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestStep;
34  import com.eviware.soapui.impl.wsdl.teststeps.registry.WsdlTestStepFactory;
35  import com.eviware.soapui.impl.wsdl.teststeps.registry.WsdlTestStepRegistry;
36  import com.eviware.soapui.model.ModelItem;
37  import com.eviware.soapui.model.testsuite.LoadTest;
38  import com.eviware.soapui.model.testsuite.TestCase;
39  import com.eviware.soapui.model.testsuite.TestRunContext;
40  import com.eviware.soapui.model.testsuite.TestRunListener;
41  import com.eviware.soapui.model.testsuite.TestRunner;
42  import com.eviware.soapui.model.testsuite.TestStep;
43  import com.eviware.soapui.support.StringUtils;
44  import com.eviware.soapui.support.UISupport;
45  import com.eviware.soapui.support.action.swing.ActionList;
46  import com.eviware.soapui.support.action.swing.DefaultActionList;
47  import com.eviware.soapui.support.scripting.SoapUIScriptEngine;
48  import com.eviware.soapui.support.scripting.SoapUIScriptEngineRegistry;
49  import com.eviware.soapui.support.types.StringToObjectMap;
50  
51  /***
52   * TestCase implementation for WSDL projects
53   * 
54   * @author Ole.Matzura
55   */
56  
57  public class WsdlTestCase extends AbstractTestPropertyHolderWsdlModelItem<TestCaseConfig> implements TestCase
58  {
59  	private final static Logger logger = Logger.getLogger( WsdlTestCase.class );
60  	public final static String KEEP_SESSION_PROPERTY = WsdlTestCase.class.getName() + "@keepSession";
61  	public final static String FAIL_ON_ERROR_PROPERTY = WsdlTestCase.class.getName() + "@failOnError";
62  	public final static String FAIL_ON_ERRORS_PROPERTY = WsdlTestCase.class.getName() + "@failOnErrors";
63  	public final static String DISCARD_OK_RESULTS = WsdlTestCase.class.getName() + "@discardOkResults";
64  	public final static String SETUP_SCRIPT_PROPERTY = WsdlTestCase.class.getName() + "@setupScript";
65  	public final static String TEARDOWN_SCRIPT_PROPERTY = WsdlTestCase.class.getName() + "@tearDownScript";
66  	public static final String TIMEOUT_PROPERTY = WsdlTestCase.class.getName() + "@timeout";
67  	public static final String SEARCH_PROPERTIES_PROPERTY = WsdlTestCase.class.getName() + "@searchProperties";
68  
69  	private final WsdlTestSuite testSuite;
70  	private List<WsdlTestStep> testSteps = new ArrayList<WsdlTestStep>();
71  	private List<WsdlLoadTest> loadTests = new ArrayList<WsdlLoadTest>();
72  	private Set<TestRunListener> testRunListeners = new HashSet<TestRunListener>();
73  	private DefaultActionList createActions;
74  	private final boolean forLoadTest;
75  	private SoapUIScriptEngine setupScriptEngine;
76  	private SoapUIScriptEngine tearDownScriptEngine;
77  
78  	public WsdlTestCase( WsdlTestSuite testSuite, TestCaseConfig config, boolean forLoadTest )
79  	{
80  		super( config, testSuite, "/testCase.gif" );
81  
82  		this.testSuite = testSuite;
83  		this.forLoadTest = forLoadTest;
84  
85  		List<TestStepConfig> testStepConfigs = config.getTestStepList();
86  		for( TestStepConfig tsc : testStepConfigs )
87  		{
88  			WsdlTestStep testStep = createTestStepFromConfig( tsc );
89  			if( testStep != null )
90  			{
91  				ensureUniqueName( testStep );
92  				testSteps.add( testStep );
93  			}
94  		}
95  
96  		if( !forLoadTest )
97  		{
98  			List<LoadTestConfig> loadTestConfigs = config.getLoadTestList();
99  			for( LoadTestConfig tsc : loadTestConfigs )
100 			{
101 				WsdlLoadTest loadTest = new WsdlLoadTest( this, tsc );
102 				loadTests.add( loadTest );
103 			}
104 		}
105 
106 		// init default configs
107 		if( !config.isSetFailOnError() )
108 			config.setFailOnError( true );
109 
110 		if( !config.isSetFailTestCaseOnErrors() )
111 			config.setFailTestCaseOnErrors( true );
112 
113 		if( !config.isSetKeepSession() )
114 			config.setKeepSession( false );
115 
116 		for( TestRunListener listener : SoapUI.getListenerRegistry().getListeners( TestRunListener.class ) )
117 		{
118 			addTestRunListener( listener );
119 		}
120 
121 		if( !getConfig().isSetProperties() )
122 			getConfig().addNewProperties();
123 
124 		setPropertiesConfig( getConfig().getProperties() );
125 
126 //		for( TestStep step : testSteps )
127 //		{
128 //			WsdlTestStep testStep = ( WsdlTestStep ) step;
129 //			try
130 //			{
131 //				testStep.afterLoad();
132 //			}
133 //			catch( Exception e )
134 //			{
135 //				e.printStackTrace();
136 //			}
137 //		}
138 	}
139 
140 	public boolean getKeepSession()
141 	{
142 		return getConfig().getKeepSession();
143 	}
144 
145 	public void setKeepSession( boolean keepSession )
146 	{
147 		boolean old = getKeepSession();
148 		if( old != keepSession )
149 		{
150 			getConfig().setKeepSession( keepSession );
151 			notifyPropertyChanged( KEEP_SESSION_PROPERTY, old, keepSession );
152 		}
153 	}
154 
155 	public void setSetupScript( String script )
156 	{
157 		String oldScript = getSetupScript();
158 
159 		if( !getConfig().isSetSetupScript() )
160 			getConfig().addNewSetupScript();
161 
162 		getConfig().getSetupScript().setStringValue( script );
163 		if( setupScriptEngine != null )
164 			setupScriptEngine.setScript( script );
165 
166 		notifyPropertyChanged( SETUP_SCRIPT_PROPERTY, oldScript, script );
167 	}
168 
169 	public String getSetupScript()
170 	{
171 		return getConfig().isSetSetupScript() ? getConfig().getSetupScript().getStringValue() : null;
172 	}
173 
174 	public void setTearDownScript( String script )
175 	{
176 		String oldScript = getTearDownScript();
177 
178 		if( !getConfig().isSetTearDownScript() )
179 			getConfig().addNewTearDownScript();
180 
181 		getConfig().getTearDownScript().setStringValue( script );
182 		if( tearDownScriptEngine != null )
183 			tearDownScriptEngine.setScript( script );
184 
185 		notifyPropertyChanged( TEARDOWN_SCRIPT_PROPERTY, oldScript, script );
186 	}
187 
188 	public String getTearDownScript()
189 	{
190 		return getConfig().isSetTearDownScript() ? getConfig().getTearDownScript().getStringValue() : null;
191 	}
192 
193 	public boolean getFailOnError()
194 	{
195 		return getConfig().getFailOnError();
196 	}
197 
198 	public boolean getFailTestCaseOnErrors()
199 	{
200 		return getConfig().getFailTestCaseOnErrors();
201 	}
202 
203 	public void setFailOnError( boolean failOnError )
204 	{
205 		boolean old = getFailOnError();
206 		if( old != failOnError )
207 		{
208 			getConfig().setFailOnError( failOnError );
209 			notifyPropertyChanged( FAIL_ON_ERROR_PROPERTY, old, failOnError );
210 		}
211 	}
212 
213 	public void setFailTestCaseOnErrors( boolean failTestCaseOnErrors )
214 	{
215 		boolean old = getFailTestCaseOnErrors();
216 		if( old != failTestCaseOnErrors )
217 		{
218 			getConfig().setFailTestCaseOnErrors( failTestCaseOnErrors );
219 			notifyPropertyChanged( FAIL_ON_ERRORS_PROPERTY, old, failTestCaseOnErrors );
220 		}
221 	}
222 
223 	public boolean getSearchProperties()
224 	{
225 		return getConfig().getSearchProperties();
226 	}
227 
228 	public void setSearchProperties( boolean searchProperties )
229 	{
230 		boolean old = getSearchProperties();
231 		if( old != searchProperties )
232 		{
233 			getConfig().setSearchProperties( searchProperties );
234 			notifyPropertyChanged( SEARCH_PROPERTIES_PROPERTY, old, searchProperties );
235 		}
236 	}
237 
238 	public boolean getDiscardOkResults()
239 	{
240 		return getConfig().getDiscardOkResults();
241 	}
242 
243 	public void setDiscardOkResults( boolean discardOkResults )
244 	{
245 		boolean old = getDiscardOkResults();
246 		if( old != discardOkResults )
247 		{
248 			getConfig().setDiscardOkResults( discardOkResults );
249 			notifyPropertyChanged( DISCARD_OK_RESULTS, old, discardOkResults );
250 		}
251 	}
252 
253 	private WsdlTestStep createTestStepFromConfig( TestStepConfig tsc )
254 	{
255 		WsdlTestStepFactory factory = WsdlTestStepRegistry.getInstance().getFactory( tsc.getType() );
256 		if( factory != null )
257 		{
258 			WsdlTestStep testStep = factory.buildTestStep( this, tsc, forLoadTest );
259 			return testStep;
260 		}
261 		else
262 		{
263 			logger.error( "Failed to create test step for [" + tsc.getName() + "]" );
264 			return null;
265 		}
266 	}
267 
268 	private boolean ensureUniqueName( WsdlTestStep testStep )
269 	{
270 		String name = testStep.getName();
271 		while( name == null || getTestStepByName( name ) != null )
272 		{
273 			if( name == null )
274 				name = testStep.getName();
275 			else
276 			{
277 				int cnt = 0;
278 
279 				while( getTestStepByName( name ) != null )
280 				{
281 					cnt++;
282 					name = testStep.getName() + " " + cnt;
283 				}
284 
285 				if( cnt == 0 )
286 					break;
287 			}
288 
289 			name = UISupport.prompt( "TestStep name must be unique, please specify new name for step\n" + "["
290 						+ testStep.getName() + "] in TestCase [" + getTestSuite().getProject().getName() + "->"
291 						+ getTestSuite().getName() + "->" + getName() + "]", "Change TestStep name", name );
292 
293 			if( name == null )
294 				return false;
295 		}
296 
297 		if( !name.equals( testStep.getName() ) )
298 			testStep.setName( name );
299 
300 		return true;
301 	}
302 
303 	public WsdlLoadTest addNewLoadTest( String name )
304 	{
305 		WsdlLoadTest loadTest = new WsdlLoadTest( this, getConfig().addNewLoadTest() );
306 		loadTest.setStartDelay( 0 );
307 		loadTest.setName( name );
308 		loadTests.add( loadTest );
309 
310 		loadTest.addAssertion( TestStepStatusAssertion.STEP_STATUS_TYPE, LoadTestAssertion.ANY_TEST_STEP, false );
311 
312 		( getTestSuite() ).fireLoadTestAdded( loadTest );
313 
314 		return loadTest;
315 	}
316 
317 	public void removeLoadTest( WsdlLoadTest loadTest )
318 	{
319 		int ix = loadTests.indexOf( loadTest );
320 
321 		loadTests.remove( ix );
322 
323 		try
324 		{
325 			( getTestSuite() ).fireLoadTestRemoved( loadTest );
326 		}
327 		finally
328 		{
329 			loadTest.release();
330 			getConfig().removeLoadTest( ix );
331 		}
332 	}
333 
334 	public WsdlTestSuite getTestSuite()
335 	{
336 		return testSuite;
337 	}
338 
339 	public WsdlTestStep cloneStep( WsdlTestStep testStep, String name )
340 	{
341 		return testStep.clone( this, name );
342 	}
343 
344 	public WsdlTestStep getTestStepAt( int index )
345 	{
346 		return testSteps.get( index );
347 	}
348 
349 	public int getTestStepCount()
350 	{
351 		return testSteps.size();
352 	}
353 
354 	public WsdlLoadTest getLoadTestAt( int index )
355 	{
356 		return loadTests.get( index );
357 	}
358 
359 	public LoadTest getLoadTestByName( String loadTestName )
360 	{
361 		return ( LoadTest ) getWsdlModelItemByName( loadTests, loadTestName );
362 	}
363 
364 	public int getLoadTestCount()
365 	{
366 		return loadTests.size();
367 	}
368 
369 	public WsdlTestStep addTestStep( TestStepConfig stepConfig )
370 	{
371 		return insertTestStep( stepConfig, -1 );
372 	}
373 
374 	public WsdlTestStep addTestStep( String type, String name )
375 	{
376 		TestStepConfig newStepConfig = WsdlTestStepRegistry.getInstance().getFactory( type ).createNewTestStep( this,
377 					name );
378 		if( newStepConfig != null )
379 		{
380 			return addTestStep( newStepConfig );
381 		}
382 		else
383 			return null;
384 	}
385 
386 	public WsdlTestStep insertTestStep( String type, String name, int index )
387 	{
388 		TestStepConfig newStepConfig = WsdlTestStepRegistry.getInstance().getFactory( type ).createNewTestStep( this,
389 					name );
390 		if( newStepConfig != null )
391 		{
392 			return insertTestStep( newStepConfig, index );
393 		}
394 		else
395 			return null;
396 	}
397 
398 	public WsdlTestStep importTestStep( WsdlTestStep testStep, String name, int index, boolean createCopy )
399 	{
400 		testStep.beforeSave();
401 		TestStepConfig newStepConfig = ( TestStepConfig ) testStep.getConfig().copy();
402 		newStepConfig.setName( name );
403 		if( createCopy && newStepConfig.isSetId() )
404 			newStepConfig.unsetId();
405 
406 		return insertTestStep( newStepConfig, index );
407 	}
408 
409 	public WsdlTestStep[] importTestSteps( WsdlTestStep[] testSteps, int index, boolean createCopies )
410 	{
411 		TestStepConfig[] newStepConfigs = new TestStepConfig[testSteps.length];
412 
413 		for( int c = 0; c < testSteps.length; c++ )
414 		{
415 			testSteps[c].beforeSave();
416 			newStepConfigs[c] = ( TestStepConfig ) testSteps[c].getConfig().copy();
417 			if( createCopies && newStepConfigs[c].isSetId() )
418 				newStepConfigs[c].unsetId();
419 		}
420 
421 		return insertTestSteps( newStepConfigs, index );
422 	}
423 
424 	public WsdlTestStep insertTestStep( TestStepConfig stepConfig, int ix )
425 	{
426 		TestStepConfig newStepConfig = ix == -1 ? getConfig().addNewTestStep() : getConfig().insertNewTestStep( ix );
427 		newStepConfig.set( stepConfig );
428 		WsdlTestStep testStep = createTestStepFromConfig( newStepConfig );
429 
430 		if( !ensureUniqueName( testStep ) )
431 			return null;
432 
433 		if( ix == -1 )
434 			testSteps.add( testStep );
435 		else
436 			testSteps.add( ix, testStep );
437 
438 		testStep.afterLoad();
439 
440 		if( getTestSuite() != null )
441 			( getTestSuite() ).fireTestStepAdded( testStep, ix == -1 ? testSteps.size() - 1 : ix );
442 
443 		return testStep;
444 	}
445 
446 	public WsdlTestStep[] insertTestSteps( TestStepConfig[] stepConfig, int ix )
447 	{
448 		WsdlTestStep[] result = new WsdlTestStep[stepConfig.length];
449 
450 		for( int c = 0; c < stepConfig.length; c++ )
451 		{
452 			TestStepConfig newStepConfig = ix == -1 ? getConfig().addNewTestStep() : getConfig()
453 						.insertNewTestStep( ix + c );
454 			newStepConfig.set( stepConfig[c] );
455 			WsdlTestStep testStep = createTestStepFromConfig( newStepConfig );
456 
457 			if( !ensureUniqueName( testStep ) )
458 				return null;
459 
460 			if( ix == -1 )
461 				testSteps.add( testStep );
462 			else
463 				testSteps.add( ix + c, testStep );
464 
465 			result[c] = testStep;
466 		}
467 
468 		for( int c = 0; c < result.length; c++ )
469 		{
470 			result[c].afterLoad();
471 
472 			if( getTestSuite() != null )
473 				( getTestSuite() ).fireTestStepAdded( result[c], getIndexOfTestStep( result[c] ) );
474 		}
475 
476 		return result;
477 	}
478 
479 	public void removeTestStep( WsdlTestStep testStep )
480 	{
481 		int ix = testSteps.indexOf( testStep );
482 		if( ix == -1 )
483 		{
484 			logger.error( "TestStep [" + testStep.getName() + "] passed to removeTestStep in testCase [" + getName()
485 						+ "] not found" );
486 			return;
487 		}
488 
489 		testSteps.remove( ix );
490 
491 		try
492 		{
493 			( getTestSuite() ).fireTestStepRemoved( testStep, ix );
494 		}
495 		finally
496 		{
497 			testStep.release();
498 
499 			for( int c = 0; c < getConfig().sizeOfTestStepArray(); c++ )
500 			{
501 				if( testStep.getConfig() == getConfig().getTestStepArray( c ) )
502 				{
503 					getConfig().removeTestStep( c );
504 					break;
505 				}
506 			}
507 		}
508 	}
509 
510 	public WsdlTestCaseRunner run( StringToObjectMap properties, boolean async )
511 	{
512 		WsdlTestCaseRunner runner = new WsdlTestCaseRunner( this, properties );
513 		runner.start( async );
514 		return runner;
515 	}
516 
517 	public void addTestRunListener( TestRunListener listener )
518 	{
519 		if( listener == null )
520 			throw new RuntimeException( "listener must not be null" );
521 
522 		testRunListeners.add( listener );
523 	}
524 
525 	public void removeTestRunListener( TestRunListener listener )
526 	{
527 		testRunListeners.remove( listener );
528 	}
529 
530 	public TestRunListener[] getTestRunListeners()
531 	{
532 		return testRunListeners.toArray( new TestRunListener[testRunListeners.size()] );
533 	}
534 
535 	public Map<String, TestStep> getTestSteps()
536 	{
537 		Map<String, TestStep> result = new HashMap<String, TestStep>();
538 		for( TestStep testStep : testSteps )
539 			result.put( testStep.getName(), testStep );
540 
541 		return result;
542 	}
543 
544 	public Map<String, LoadTest> getLoadTests()
545 	{
546 		Map<String, LoadTest> result = new HashMap<String, LoadTest>();
547 		for( LoadTest loadTest : loadTests )
548 			result.put( loadTest.getName(), loadTest );
549 
550 		return result;
551 	}
552 
553 	public int getIndexOfTestStep( TestStep step )
554 	{
555 		return testSteps.indexOf( step );
556 	}
557 
558 	/***
559 	 * Moves a step by the specified offset, a bit awkward since xmlbeans doesn't
560 	 * support reordering of arrays, we need to create copies of the contained
561 	 * XmlObjects
562 	 * 
563 	 * @param ix
564 	 * @param offset
565 	 */
566 
567 	public void moveTestStep( int ix, int offset )
568 	{
569 		if( offset == 0 )
570 			return;
571 		WsdlTestStep step = testSteps.get( ix );
572 
573 		if( ix + offset >= testSteps.size() )
574 			offset = testSteps.size() - ix - 1;
575 
576 		testSteps.remove( ix );
577 		testSteps.add( ix + offset, step );
578 
579 		TestStepConfig[] configs = new TestStepConfig[testSteps.size()];
580 
581 		TestCaseConfig conf = getConfig();
582 		for( int c = 0; c < testSteps.size(); c++ )
583 		{
584 			if( offset > 0 )
585 			{
586 				if( c < ix )
587 					configs[c] = ( TestStepConfig ) conf.getTestStepArray( c ).copy();
588 				else if( c < ( ix + offset ) )
589 					configs[c] = ( TestStepConfig ) conf.getTestStepArray( c + 1 ).copy();
590 				else if( c == ix + offset )
591 					configs[c] = ( TestStepConfig ) conf.getTestStepArray( ix ).copy();
592 				else
593 					configs[c] = ( TestStepConfig ) conf.getTestStepArray( c ).copy();
594 			}
595 			else
596 			{
597 				if( c < ix + offset )
598 					configs[c] = ( TestStepConfig ) conf.getTestStepArray( c ).copy();
599 				else if( c == ix + offset )
600 					configs[c] = ( TestStepConfig ) conf.getTestStepArray( ix ).copy();
601 				else if( c <= ix )
602 					configs[c] = ( TestStepConfig ) conf.getTestStepArray( c - 1 ).copy();
603 				else
604 					configs[c] = ( TestStepConfig ) conf.getTestStepArray( c ).copy();
605 			}
606 		}
607 
608 		conf.setTestStepArray( configs );
609 		for( int c = 0; c < configs.length; c++ )
610 		{
611 			( testSteps.get( c ) ).resetConfigOnMove( conf.getTestStepArray( c ) );
612 		}
613 
614 		( getTestSuite() ).fireTestStepMoved( step, ix, offset );
615 	}
616 
617 	public int getIndexOfLoadTest( LoadTest loadTest )
618 	{
619 		return loadTests.indexOf( loadTest );
620 	}
621 
622 	public int getTestStepIndexByName( String stepName )
623 	{
624 		for( int c = 0; c < testSteps.size(); c++ )
625 		{
626 			if( testSteps.get( c ).getName().equals( stepName ) )
627 				return c;
628 		}
629 
630 		return -1;
631 	}
632 
633 	public TestStep findPreviousStepOfType( TestStep referenceStep, Class stepClass )
634 	{
635 		int currentStepIndex = getIndexOfTestStep( referenceStep );
636 		int ix = currentStepIndex - 1;
637 		while( ix >= 0 && !getTestStepAt( ix ).getClass().equals( stepClass ) )
638 		{
639 			ix--;
640 		}
641 
642 		return ix < 0 ? null : getTestStepAt( ix );
643 	}
644 
645 	public TestStep findNextStepOfType( TestStep referenceStep, Class stepClass )
646 	{
647 		int currentStepIndex = getIndexOfTestStep( referenceStep );
648 		int ix = currentStepIndex + 1;
649 		while( ix < getTestStepCount() && !getTestStepAt( ix ).getClass().equals( stepClass ) )
650 		{
651 			ix++;
652 		}
653 
654 		return ix >= getTestStepCount() ? null : getTestStepAt( ix );
655 	}
656 
657 	public List<TestStep> getTestStepList()
658 	{
659 		List<TestStep> result = new ArrayList<TestStep>();
660 		for( TestStep step : testSteps )
661 			result.add( step );
662 
663 		return result;
664 	}
665 
666 	@SuppressWarnings( "unchecked" )
667 	public <T extends TestStep> List<T> getTestStepsOfType( Class<T> stepType )
668 	{
669 		List<T> result = new ArrayList<T>();
670 		for( TestStep step : testSteps )
671 			if( step.getClass().isAssignableFrom( stepType ) )
672 				result.add( ( T ) step );
673 
674 		return result;
675 	}
676 
677 	public WsdlTestStep getTestStepByName( String stepName )
678 	{
679 		return ( WsdlTestStep ) getWsdlModelItemByName( testSteps, stepName );
680 	}
681 
682 	public WsdlLoadTest cloneLoadTest( WsdlLoadTest loadTest, String name )
683 	{
684 		loadTest.beforeSave();
685 
686 		LoadTestConfig loadTestConfig = getConfig().addNewLoadTest();
687 		loadTestConfig.set( loadTest.getConfig().copy() );
688 
689 		WsdlLoadTest newLoadTest = new WsdlLoadTest( this, loadTestConfig );
690 		newLoadTest.setName( name );
691 		loadTests.add( newLoadTest );
692 
693 		( getTestSuite() ).fireLoadTestAdded( newLoadTest );
694 
695 		return newLoadTest;
696 	}
697 
698 	@Override
699    public void release()
700 	{
701 		super.release();
702 
703 		for( WsdlTestStep testStep : testSteps )
704 			testStep.release();
705 
706 		for( WsdlLoadTest loadTest : loadTests )
707 			loadTest.release();
708 
709 		testRunListeners.clear();
710 		
711 		if( setupScriptEngine != null )
712 			setupScriptEngine.release();
713 		
714 		if( tearDownScriptEngine != null )
715 			tearDownScriptEngine.release();
716 	}
717 
718 	public ActionList getCreateActions()
719 	{
720 		return createActions;
721 	}
722 
723 	public void resetConfigOnMove( TestCaseConfig testCaseArray )
724 	{
725 		setConfig( testCaseArray );
726 		int mod = 0;
727 
728 		List<TestStepConfig> configs = getConfig().getTestStepList();
729 		for( int c = 0; c < configs.size(); c++ )
730 		{
731 			if( WsdlTestStepRegistry.getInstance().hasFactory( configs.get( c ) ) )
732 			{
733 				( testSteps.get( c - mod ) ).resetConfigOnMove( configs.get( c ) );
734 			}
735 			else
736 				mod++;
737 		}
738 
739 		List<LoadTestConfig> loadTestConfigs = getConfig().getLoadTestList();
740 		for( int c = 0; c < loadTestConfigs.size(); c++ )
741 		{
742 			loadTests.get( c ).resetConfigOnMove( loadTestConfigs.get( c ) );
743 		}
744 	}
745 
746 	@Override
747 	public void beforeSave()
748 	{
749 		for( WsdlTestStep testStep : testSteps )
750 			testStep.beforeSave();
751 
752 		for( WsdlLoadTest loadTest : loadTests )
753 			loadTest.beforeSave();
754 	}
755 
756 	public List<LoadTest> getLoadTestList()
757 	{
758 		List<LoadTest> result = new ArrayList<LoadTest>();
759 		for( LoadTest loadTest : loadTests )
760 			result.add( loadTest );
761 
762 		return result;
763 	}
764 
765 	public Object runSetupScript( TestRunContext runContext, TestRunner runner ) throws Exception
766 	{
767 		String script = getSetupScript();
768 		if( StringUtils.isNullOrEmpty( script ))
769 			return null;
770 		
771 		if( setupScriptEngine == null )
772 		{
773 			setupScriptEngine = SoapUIScriptEngineRegistry.create( SoapUIScriptEngineRegistry.GROOVY_ID, this );
774 			setupScriptEngine.setScript( script );
775 		}
776 		
777 		setupScriptEngine.setVariable( "context", runContext );
778 		setupScriptEngine.setVariable( "testRunner", runner );
779 		setupScriptEngine.setVariable( "log", SoapUI.ensureGroovyLog() );
780 		return setupScriptEngine.run();
781 	}
782 
783 	public Object runTearDownScript( TestRunContext runContext, TestRunner runner ) throws Exception
784 	{
785 		String script = getTearDownScript();
786 		if( StringUtils.isNullOrEmpty( script ))
787 			return null;
788 		
789 		if( tearDownScriptEngine == null )
790 		{
791 			tearDownScriptEngine = SoapUIScriptEngineRegistry.create( SoapUIScriptEngineRegistry.GROOVY_ID, this );
792 			tearDownScriptEngine.setScript( script );
793 		}
794 		
795 		tearDownScriptEngine.setVariable( "context", runContext );
796 		tearDownScriptEngine.setVariable( "testRunner", runner );
797 		tearDownScriptEngine.setVariable( "log", SoapUI.ensureGroovyLog() );
798 		return tearDownScriptEngine.run();
799 	}
800 
801 	public List<? extends ModelItem> getChildren()
802    {
803       return getTestStepList();
804    }
805 	
806 	@Override
807 	public void setName( String name )
808 	{
809 		String oldLabel = getLabel();
810    	
811 		super.setName( name );
812 		
813 		String label = getLabel();
814 		if( oldLabel != null && !oldLabel.equals( label ))
815 		{
816 			notifyPropertyChanged( LABEL_PROPERTY, oldLabel, label );
817 		}
818 	}
819 
820 	public String getLabel()
821 	{
822 		String name = getName();
823 		if( isDisabled() )
824 			return name + " (disabled)";
825 		else
826 			return name;
827 	}
828 
829 	public boolean isDisabled()
830 	{
831 		return getConfig().getDisabled();
832 	}
833 	
834 	public void setDisabled( boolean disabled )
835 	{
836 		String oldLabel = getLabel();
837 		
838 		boolean oldDisabled = isDisabled();
839 		if( oldDisabled == disabled )
840 			return;
841 		
842 		if( disabled )
843 			getConfig().setDisabled( disabled );
844 		else if( getConfig().isSetDisabled() )
845 			getConfig().unsetDisabled();
846 		
847 		notifyPropertyChanged( DISABLED_PROPERTY, oldDisabled, disabled );
848 		
849 		String label = getLabel();
850 		if( !oldLabel.equals( label ))
851 			notifyPropertyChanged( LABEL_PROPERTY, oldLabel, label );
852 	}
853 	
854 	public long getTimeout()
855 	{
856 		return getConfig().getTimeout();
857 	}
858 	
859 	public void setTimeout( long timeout )
860 	{
861 		long old = getTimeout();
862 		getConfig().setTimeout( timeout );
863 		notifyPropertyChanged( TIMEOUT_PROPERTY, old, timeout );
864 	}
865 }