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;
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 com.eviware.soapui.SoapUI;
23  import com.eviware.soapui.config.LoadTestConfig;
24  import com.eviware.soapui.config.TestCaseConfig;
25  import com.eviware.soapui.config.TestSuiteConfig;
26  import com.eviware.soapui.config.TestSuiteRunTypesConfig;
27  import com.eviware.soapui.config.TestSuiteRunTypesConfig.Enum;
28  import com.eviware.soapui.impl.wsdl.loadtest.WsdlLoadTest;
29  import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase;
30  import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestStep;
31  import com.eviware.soapui.model.ModelItem;
32  import com.eviware.soapui.model.propertyexpansion.DefaultPropertyExpansionContext;
33  import com.eviware.soapui.model.propertyexpansion.PropertyExpansionContext;
34  import com.eviware.soapui.model.testsuite.TestCase;
35  import com.eviware.soapui.model.testsuite.TestSuite;
36  import com.eviware.soapui.model.testsuite.TestSuiteListener;
37  import com.eviware.soapui.support.StringUtils;
38  import com.eviware.soapui.support.scripting.SoapUIScriptEngine;
39  import com.eviware.soapui.support.scripting.SoapUIScriptEngineRegistry;
40  
41  /***
42   * TestSuite implementation for WSDL projects.
43   * 
44   * @author Ole.Matzura
45   */
46  
47  public class WsdlTestSuite extends AbstractTestPropertyHolderWsdlModelItem<TestSuiteConfig> implements TestSuite
48  {
49  	public final static String SETUP_SCRIPT_PROPERTY = WsdlTestSuite.class.getName() + "@setupScript";
50  	public final static String TEARDOWN_SCRIPT_PROPERTY = WsdlTestSuite.class.getName() + "@tearDownScript";
51  	
52     private final WsdlProject project;
53     private List<WsdlTestCase> testCases = new ArrayList<WsdlTestCase>();
54     private Set<TestSuiteListener> testSuiteListeners = new HashSet<TestSuiteListener>();
55  	private SoapUIScriptEngine setupScriptEngine;
56  	private SoapUIScriptEngine tearDownScriptEngine;
57     
58     public WsdlTestSuite(WsdlProject project, TestSuiteConfig config)
59     {
60     	super( config, project, "/testSuite.gif" );
61        this.project = project;
62        
63        List<TestCaseConfig> testCaseConfigs = config.getTestCaseList();
64        for (int i = 0; i < testCaseConfigs.size(); i++)
65        {
66           testCases.add( new WsdlTestCase( this, testCaseConfigs.get(i), false ));
67        }
68        
69        if( !config.isSetRunType() )
70        	config.setRunType( TestSuiteRunTypesConfig.SEQUENTIAL );
71        
72     	for( TestSuiteListener listener : SoapUI.getListenerRegistry().getListeners( TestSuiteListener.class ) )
73  		{
74  			addTestSuiteListener( listener );
75  		}
76     	
77     	if( !config.isSetProperties() )
78     		config.addNewProperties();
79     	
80     	setPropertiesConfig( config.getProperties() );
81     }
82     
83  	public TestSuiteRunType getRunType()
84  	{
85  		Enum runType = getConfig().getRunType();
86  		
87  		if( runType.equals( TestSuiteRunTypesConfig.PARALLELL ))
88  			return TestSuiteRunType.PARALLEL;
89  		else
90  			return TestSuiteRunType.SEQUENTIAL;
91  	}
92  	
93  	public void setRunType( TestSuiteRunType runType )
94  	{
95  		TestSuiteRunType oldRunType = getRunType();
96  		
97  		if( runType == TestSuiteRunType.PARALLEL && oldRunType != TestSuiteRunType.PARALLEL )
98  		{
99  			getConfig().setRunType( TestSuiteRunTypesConfig.PARALLELL );
100 			notifyPropertyChanged( RUNTYPE_PROPERTY, oldRunType, runType );
101 		}
102 		else if( runType == TestSuiteRunType.SEQUENTIAL && oldRunType != TestSuiteRunType.SEQUENTIAL )
103 		{
104 			getConfig().setRunType( TestSuiteRunTypesConfig.SEQUENTIAL );
105 			notifyPropertyChanged( RUNTYPE_PROPERTY, oldRunType, runType );
106 		}
107 	}
108 
109 	public WsdlProject getProject()
110    {
111       return project;
112    }
113 
114    public int getTestCaseCount()
115    {
116       return testCases.size();
117    }
118 
119    public WsdlTestCase getTestCaseAt(int index)
120    {
121       return testCases.get( index );
122    }
123 
124    public WsdlTestCase getTestCaseByName(String testCaseName)
125 	{
126 		return ( WsdlTestCase ) getWsdlModelItemByName( testCases, testCaseName );
127 	}
128 
129 	public WsdlTestCase cloneTestCase( WsdlTestCase testCase, String name )
130    {
131 		testCase.beforeSave();
132    	TestCaseConfig newTestCase = getConfig().addNewTestCase();
133 		newTestCase.set( testCase.getConfig() );
134 		newTestCase.setName( name );
135 		WsdlTestCase newWsdlTestCase = new WsdlTestCase( this, newTestCase, false );
136 		
137       testCases.add( newWsdlTestCase );
138       fireTestCaseAdded( newWsdlTestCase );
139 
140       return newWsdlTestCase;
141    }
142    
143    public WsdlTestCase addNewTestCase( String name )
144    {
145       WsdlTestCase testCase = new WsdlTestCase( this, getConfig().addNewTestCase(), false );
146       testCase.setName( name );
147       testCase.setFailOnError( true );
148       testCase.setSearchProperties( true );
149       testCases.add( testCase );
150       fireTestCaseAdded( testCase );
151 
152       return testCase;
153    }
154    
155    public WsdlTestCase importTestCase( WsdlTestCase testCase, String name, int index, boolean includeLoadTests, boolean createCopy )
156    {
157    	testCase.beforeSave();
158    	 
159    	if( index >= testCases.size() )
160    		index = -1;
161    	
162       TestCaseConfig testCaseConfig = index == -1 ? 
163       	( TestCaseConfig ) getConfig().addNewTestCase().set( testCase.getConfig().copy() ) :
164          ( TestCaseConfig ) getConfig().insertNewTestCase( index ).set( testCase.getConfig().copy() );
165       testCaseConfig.setName( name );
166       if( createCopy && testCaseConfig.isSetId())
167       	testCaseConfig.unsetId();
168       
169       if( !includeLoadTests )
170       	testCaseConfig.setLoadTestArray( new LoadTestConfig[0] );
171      
172 		testCase = new WsdlTestCase( this, testCaseConfig, false );
173 		
174 		if( index == -1 )
175 			testCases.add( testCase );
176 		else
177 			testCases.add( index, testCase );
178 		
179       fireTestCaseAdded( testCase );
180 
181       return testCase;
182    }
183    
184    public void removeTestCase(WsdlTestCase testCase )
185    {
186       int ix = testCases.indexOf( testCase );
187 
188       testCases.remove( ix );
189       try
190       {
191       	fireTestCaseRemoved( testCase );
192       }
193       finally
194       {
195       	testCase.release();
196       	getConfig().removeTestCase( ix );
197       }
198    }
199 
200    public void fireTestCaseAdded( WsdlTestCase testCase )
201    {
202       TestSuiteListener[] a = testSuiteListeners.toArray( new TestSuiteListener[testSuiteListeners.size()] );
203       
204       for (int c = 0; c < a.length; c++ )
205       {
206          a[c].testCaseAdded( testCase );
207       }
208    }
209    
210    public void fireTestCaseRemoved( WsdlTestCase testCase )
211    {
212    	TestSuiteListener[] a = testSuiteListeners.toArray( new TestSuiteListener[testSuiteListeners.size()] );
213       
214       for (int c = 0; c < a.length; c++ )
215       {
216          a[c].testCaseRemoved( testCase );
217       }
218    } 
219    
220    private void fireTestCaseMoved( WsdlTestCase testCase, int ix, int offset )
221 	{
222    	TestSuiteListener[] a = testSuiteListeners.toArray( new TestSuiteListener[testSuiteListeners.size()] );
223       
224       for (int c = 0; c < a.length; c++ )
225       {
226          a[c].testCaseMoved( testCase, ix, offset );
227       }
228 	}
229 
230    public void fireTestStepAdded( WsdlTestStep testStep, int index )
231    {
232    	TestSuiteListener[] a = testSuiteListeners.toArray( new TestSuiteListener[testSuiteListeners.size()] );
233       
234       for (int c = 0; c < a.length; c++ )
235       {
236          a[c].testStepAdded( testStep, index );
237       }
238    }
239    
240    public void fireTestStepRemoved( WsdlTestStep testStep, int ix )
241    {
242    	TestSuiteListener[] a = testSuiteListeners.toArray( new TestSuiteListener[testSuiteListeners.size()] );
243       
244       for (int c = 0; c < a.length; c++ )
245       {
246          a[c].testStepRemoved( testStep, ix );
247       }
248    } 
249    
250    public void fireTestStepMoved( WsdlTestStep testStep, int ix, int offset )
251    {
252    	TestSuiteListener[] a = testSuiteListeners.toArray( new TestSuiteListener[testSuiteListeners.size()] );
253       
254       for (int c = 0; c < a.length; c++ )
255       {
256          a[c].testStepMoved( testStep, ix, offset );
257       }
258    } 
259 
260    public void fireLoadTestAdded( WsdlLoadTest loadTest )
261    {
262    	TestSuiteListener[] a = testSuiteListeners.toArray( new TestSuiteListener[testSuiteListeners.size()] );
263       
264       for (int c = 0; c < a.length; c++ )
265       {
266          a[c].loadTestAdded( loadTest );
267       }
268    }
269    
270    public void fireLoadTestRemoved( WsdlLoadTest loadTest )
271    {
272    	TestSuiteListener[] a = testSuiteListeners.toArray( new TestSuiteListener[testSuiteListeners.size()] );
273       
274       for (int c = 0; c < a.length; c++ )
275       {
276          a[c].loadTestRemoved( loadTest );
277       }
278    } 
279    
280 	public void addTestSuiteListener(TestSuiteListener listener)
281 	{
282 		testSuiteListeners.add( listener );
283 	}
284 
285 	public void removeTestSuiteListener(TestSuiteListener listener)
286 	{
287 		testSuiteListeners.remove( listener );
288 	}
289 
290 	public int getTestCaseIndex(TestCase testCase)
291 	{
292 		return testCases.indexOf( testCase );
293 	}
294 
295 	@Override
296    public void release()
297 	{
298 		super.release();
299 		
300 		for( WsdlTestCase testCase : testCases )
301 			testCase.release();
302 		
303 		testSuiteListeners.clear();
304 		
305 		if( setupScriptEngine != null )
306 			setupScriptEngine.release();
307 		
308 		if( tearDownScriptEngine != null )
309 			tearDownScriptEngine.release();
310 	}
311 
312 	public List<TestCase> getTestCaseList()
313 	{
314 		List<TestCase> result = new ArrayList<TestCase>();
315 		for( WsdlTestCase testCase : testCases )
316 			result.add( testCase );
317 		
318 		return result;
319 	} 
320 	
321 	public Map<String, TestCase> getTestCases()
322 	{
323 		Map<String, TestCase> result = new HashMap<String, TestCase>();
324 		for( TestCase testCase : testCases )
325 			result.put( testCase.getName(), testCase );
326 
327 		return result;
328 	}
329 	
330 	/***
331 	 * Moves a testcase by the specified offset, a bit awkward since xmlbeans doesn't support reordering
332 	 * of arrays, we need to create copies of the contained XmlObjects
333 	 * 
334 	 * @param ix
335 	 * @param offset
336 	 */
337 	
338 	public WsdlTestCase moveTestCase(int ix, int offset)
339 	{
340 		WsdlTestCase testCase = testCases.get( ix );
341 
342 		if( offset == 0 ) 
343 			return testCase;
344 
345 		testCases.remove( ix );
346 		testCases.add( ix+offset, testCase );
347 
348 		TestCaseConfig [] configs = new TestCaseConfig[testCases.size()];
349 		
350 		for( int c = 0; c < testCases.size(); c++ )
351 		{
352 			if( offset > 0 )
353 			{
354 				if( c < ix )
355 					configs[c] = (TestCaseConfig) getConfig().getTestCaseArray(c).copy();
356 				else if( c < (ix+offset))
357 					configs[c] = (TestCaseConfig) getConfig().getTestCaseArray(c+1).copy();
358 				else if( c == ix+offset )
359 					configs[c] = (TestCaseConfig) getConfig().getTestCaseArray(ix).copy();
360 				else
361 					configs[c] = (TestCaseConfig) getConfig().getTestCaseArray(c).copy();
362 			}
363 			else
364 			{
365 				if( c < ix+offset )
366 					configs[c] = (TestCaseConfig) getConfig().getTestCaseArray(c).copy();
367 				else if( c == ix+offset )
368 					configs[c] = (TestCaseConfig) getConfig().getTestCaseArray(ix).copy();
369 				else if( c <= ix )
370 					configs[c] = (TestCaseConfig) getConfig().getTestCaseArray(c-1).copy();
371 				else
372 					configs[c] = (TestCaseConfig) getConfig().getTestCaseArray(c).copy();				
373 			}
374 		}
375 		
376 		getConfig().setTestCaseArray( configs );
377 		for( int c = 0; c < configs.length; c++ )
378 		{
379 			testCases.get( c ).resetConfigOnMove( getConfig().getTestCaseArray( c ) );
380 		}
381 		
382 		fireTestCaseMoved(testCase, ix, offset );
383 		return testCase;
384 	}
385 
386 	public int getIndexOfTestCase( TestCase testCase )
387 	{
388 		return testCases.indexOf( testCase );
389 	}
390 
391 	@Override
392 	public void beforeSave()
393 	{
394 		for( WsdlTestCase testCase : testCases )
395 			testCase.beforeSave();
396 	}
397    
398    public List<? extends ModelItem> getChildren()
399    {
400       return getTestCaseList();
401    }
402    
403    public void setSetupScript( String script )
404 	{
405 		String oldScript = getSetupScript();
406 
407 		if( !getConfig().isSetSetupScript() )
408 			getConfig().addNewSetupScript();
409 
410 		getConfig().getSetupScript().setStringValue( script );
411 		if( setupScriptEngine != null )
412 			setupScriptEngine.setScript( script );
413 		
414 		notifyPropertyChanged( SETUP_SCRIPT_PROPERTY, oldScript, script );
415 	}
416 
417 	public String getSetupScript()
418 	{
419 		return getConfig().isSetSetupScript() ? getConfig().getSetupScript().getStringValue() : null;
420 	}
421 
422 	public void setTearDownScript( String script )
423 	{
424 		String oldScript = getTearDownScript();
425 
426 		if( !getConfig().isSetTearDownScript() )
427 			getConfig().addNewTearDownScript();
428 
429 		getConfig().getTearDownScript().setStringValue( script );
430 		if( tearDownScriptEngine != null )
431 			tearDownScriptEngine.setScript( script );
432 
433 		notifyPropertyChanged( TEARDOWN_SCRIPT_PROPERTY, oldScript, script );
434 	}
435 
436 	public String getTearDownScript()
437 	{
438 		return getConfig().isSetTearDownScript() ? getConfig().getTearDownScript().getStringValue() : null;
439 	}
440 	
441 	public Object runSetupScript( PropertyExpansionContext context ) throws Exception
442 	{
443 		String script = getSetupScript();
444 		if( StringUtils.isNullOrEmpty( script ))
445 			return null;
446 		
447 		if( setupScriptEngine == null )
448 		{
449 			setupScriptEngine = SoapUIScriptEngineRegistry.create( SoapUIScriptEngineRegistry.GROOVY_ID, this );
450 			setupScriptEngine.setScript( script );
451 		}
452 		
453 		if( context == null )
454 			context = new DefaultPropertyExpansionContext( this );
455 		
456 		setupScriptEngine.setVariable( "context", context );
457 		setupScriptEngine.setVariable( "testSuite", this );
458 		setupScriptEngine.setVariable( "log", SoapUI.ensureGroovyLog() );
459 		return setupScriptEngine.run();
460 	}
461 
462 	public Object runTearDownScript( PropertyExpansionContext context ) throws Exception
463 	{
464 		String script = getTearDownScript();
465 		if( StringUtils.isNullOrEmpty( script ))
466 			return null;
467 		
468 		if( tearDownScriptEngine == null )
469 		{
470 			tearDownScriptEngine = SoapUIScriptEngineRegistry.create( SoapUIScriptEngineRegistry.GROOVY_ID, this );
471 			tearDownScriptEngine.setScript( script );
472 		}
473 		
474 		if( context == null )
475 			context = new DefaultPropertyExpansionContext( this );
476 		
477 		tearDownScriptEngine.setVariable( "context", context );
478 		tearDownScriptEngine.setVariable( "testSuite", this );
479 		tearDownScriptEngine.setVariable( "log", SoapUI.ensureGroovyLog() );
480 		return tearDownScriptEngine.run();
481 	}
482 
483 	@Override
484 	public void setName( String name )
485 	{
486 		String oldLabel = getLabel();
487    	
488 		super.setName( name );
489 		
490 		String label = getLabel();
491 		if( oldLabel != null && !oldLabel.equals( label ))
492 		{
493 			notifyPropertyChanged( LABEL_PROPERTY, oldLabel, label );
494 		}
495 	}
496 
497 	public String getLabel()
498 	{
499 		String name = getName();
500 		if( isDisabled() )
501 			return name + " (disabled)";
502 		else
503 			return name;
504 	}
505 
506 	public boolean isDisabled()
507 	{
508 		return getConfig().getDisabled();
509 	}
510 	
511 	public void setDisabled( boolean disabled )
512 	{
513 		String oldLabel = getLabel();
514 		
515 		boolean oldDisabled = isDisabled();
516 		if( oldDisabled == disabled )
517 			return;
518 		
519 		if( disabled )
520 			getConfig().setDisabled( disabled );
521 		else if( getConfig().isSetDisabled() )
522 			getConfig().unsetDisabled();
523 		
524 		notifyPropertyChanged( DISABLED_PROPERTY, oldDisabled, disabled );
525 		
526 		String label = getLabel();
527 		if( !oldLabel.equals( label ))
528 			notifyPropertyChanged( LABEL_PROPERTY, oldLabel, label );
529 	}
530 }