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 		newWsdlTestCase.afterLoad();
137 		
138       testCases.add( newWsdlTestCase );
139       fireTestCaseAdded( newWsdlTestCase );
140 
141       return newWsdlTestCase;
142    }
143    
144    public WsdlTestCase addNewTestCase( String name )
145    {
146       WsdlTestCase testCase = new WsdlTestCase( this, getConfig().addNewTestCase(), false );
147       testCase.setName( name );
148       testCase.setFailOnError( true );
149       testCase.setSearchProperties( true );
150       testCases.add( testCase );
151       fireTestCaseAdded( testCase );
152 
153       return testCase;
154    }
155    
156    public WsdlTestCase importTestCase( WsdlTestCase testCase, String name, int index, boolean includeLoadTests, boolean createCopy )
157    {
158    	testCase.beforeSave();
159    	 
160    	if( index >= testCases.size() )
161    		index = -1;
162    	
163       TestCaseConfig testCaseConfig = index == -1 ? 
164       	( TestCaseConfig ) getConfig().addNewTestCase().set( testCase.getConfig().copy() ) :
165          ( TestCaseConfig ) getConfig().insertNewTestCase( index ).set( testCase.getConfig().copy() );
166       testCaseConfig.setName( name );
167       if( createCopy && testCaseConfig.isSetId())
168       	testCaseConfig.unsetId();
169       
170       if( !includeLoadTests )
171       	testCaseConfig.setLoadTestArray( new LoadTestConfig[0] );
172      
173 		testCase = new WsdlTestCase( this, testCaseConfig, false );
174 		
175 		if( index == -1 )
176 			testCases.add( testCase );
177 		else
178 			testCases.add( index, testCase );
179 		
180 		testCase.afterLoad();
181       fireTestCaseAdded( testCase );
182 
183       return testCase;
184    }
185    
186    public void removeTestCase(WsdlTestCase testCase )
187    {
188       int ix = testCases.indexOf( testCase );
189 
190       testCases.remove( ix );
191       try
192       {
193       	fireTestCaseRemoved( testCase );
194       }
195       finally
196       {
197       	testCase.release();
198       	getConfig().removeTestCase( ix );
199       }
200    }
201 
202    public void fireTestCaseAdded( WsdlTestCase testCase )
203    {
204       TestSuiteListener[] a = testSuiteListeners.toArray( new TestSuiteListener[testSuiteListeners.size()] );
205       
206       for (int c = 0; c < a.length; c++ )
207       {
208          a[c].testCaseAdded( testCase );
209       }
210    }
211    
212    public void fireTestCaseRemoved( WsdlTestCase testCase )
213    {
214    	TestSuiteListener[] a = testSuiteListeners.toArray( new TestSuiteListener[testSuiteListeners.size()] );
215       
216       for (int c = 0; c < a.length; c++ )
217       {
218          a[c].testCaseRemoved( testCase );
219       }
220    } 
221    
222    private void fireTestCaseMoved( WsdlTestCase testCase, int ix, int offset )
223 	{
224    	TestSuiteListener[] a = testSuiteListeners.toArray( new TestSuiteListener[testSuiteListeners.size()] );
225       
226       for (int c = 0; c < a.length; c++ )
227       {
228          a[c].testCaseMoved( testCase, ix, offset );
229       }
230 	}
231 
232    public void fireTestStepAdded( WsdlTestStep testStep, int index )
233    {
234    	TestSuiteListener[] a = testSuiteListeners.toArray( new TestSuiteListener[testSuiteListeners.size()] );
235       
236       for (int c = 0; c < a.length; c++ )
237       {
238          a[c].testStepAdded( testStep, index );
239       }
240    }
241    
242    public void fireTestStepRemoved( WsdlTestStep testStep, int ix )
243    {
244    	TestSuiteListener[] a = testSuiteListeners.toArray( new TestSuiteListener[testSuiteListeners.size()] );
245       
246       for (int c = 0; c < a.length; c++ )
247       {
248          a[c].testStepRemoved( testStep, ix );
249       }
250    } 
251    
252    public void fireTestStepMoved( WsdlTestStep testStep, int ix, int offset )
253    {
254    	TestSuiteListener[] a = testSuiteListeners.toArray( new TestSuiteListener[testSuiteListeners.size()] );
255       
256       for (int c = 0; c < a.length; c++ )
257       {
258          a[c].testStepMoved( testStep, ix, offset );
259       }
260    } 
261 
262    public void fireLoadTestAdded( WsdlLoadTest loadTest )
263    {
264    	TestSuiteListener[] a = testSuiteListeners.toArray( new TestSuiteListener[testSuiteListeners.size()] );
265       
266       for (int c = 0; c < a.length; c++ )
267       {
268          a[c].loadTestAdded( loadTest );
269       }
270    }
271    
272    public void fireLoadTestRemoved( WsdlLoadTest loadTest )
273    {
274    	TestSuiteListener[] a = testSuiteListeners.toArray( new TestSuiteListener[testSuiteListeners.size()] );
275       
276       for (int c = 0; c < a.length; c++ )
277       {
278          a[c].loadTestRemoved( loadTest );
279       }
280    } 
281    
282 	public void addTestSuiteListener(TestSuiteListener listener)
283 	{
284 		testSuiteListeners.add( listener );
285 	}
286 
287 	public void removeTestSuiteListener(TestSuiteListener listener)
288 	{
289 		testSuiteListeners.remove( listener );
290 	}
291 
292 	public int getTestCaseIndex(TestCase testCase)
293 	{
294 		return testCases.indexOf( testCase );
295 	}
296 
297 	@Override
298    public void release()
299 	{
300 		super.release();
301 		
302 		for( WsdlTestCase testCase : testCases )
303 			testCase.release();
304 		
305 		testSuiteListeners.clear();
306 		
307 		if( setupScriptEngine != null )
308 			setupScriptEngine.release();
309 		
310 		if( tearDownScriptEngine != null )
311 			tearDownScriptEngine.release();
312 	}
313 
314 	public List<TestCase> getTestCaseList()
315 	{
316 		List<TestCase> result = new ArrayList<TestCase>();
317 		for( WsdlTestCase testCase : testCases )
318 			result.add( testCase );
319 		
320 		return result;
321 	} 
322 	
323 	public Map<String, TestCase> getTestCases()
324 	{
325 		Map<String, TestCase> result = new HashMap<String, TestCase>();
326 		for( TestCase testCase : testCases )
327 			result.put( testCase.getName(), testCase );
328 
329 		return result;
330 	}
331 	
332 	/***
333 	 * Moves a testcase by the specified offset, a bit awkward since xmlbeans doesn't support reordering
334 	 * of arrays, we need to create copies of the contained XmlObjects
335 	 * 
336 	 * @param ix
337 	 * @param offset
338 	 */
339 	
340 	public WsdlTestCase moveTestCase(int ix, int offset)
341 	{
342 		WsdlTestCase testCase = testCases.get( ix );
343 
344 		if( offset == 0 ) 
345 			return testCase;
346 
347 		testCases.remove( ix );
348 		testCases.add( ix+offset, testCase );
349 
350 		TestCaseConfig [] configs = new TestCaseConfig[testCases.size()];
351 		
352 		for( int c = 0; c < testCases.size(); c++ )
353 		{
354 			if( offset > 0 )
355 			{
356 				if( c < ix )
357 					configs[c] = (TestCaseConfig) getConfig().getTestCaseArray(c).copy();
358 				else if( c < (ix+offset))
359 					configs[c] = (TestCaseConfig) getConfig().getTestCaseArray(c+1).copy();
360 				else if( c == ix+offset )
361 					configs[c] = (TestCaseConfig) getConfig().getTestCaseArray(ix).copy();
362 				else
363 					configs[c] = (TestCaseConfig) getConfig().getTestCaseArray(c).copy();
364 			}
365 			else
366 			{
367 				if( c < ix+offset )
368 					configs[c] = (TestCaseConfig) getConfig().getTestCaseArray(c).copy();
369 				else if( c == ix+offset )
370 					configs[c] = (TestCaseConfig) getConfig().getTestCaseArray(ix).copy();
371 				else if( c <= ix )
372 					configs[c] = (TestCaseConfig) getConfig().getTestCaseArray(c-1).copy();
373 				else
374 					configs[c] = (TestCaseConfig) getConfig().getTestCaseArray(c).copy();				
375 			}
376 		}
377 		
378 		getConfig().setTestCaseArray( configs );
379 		for( int c = 0; c < configs.length; c++ )
380 		{
381 			testCases.get( c ).resetConfigOnMove( getConfig().getTestCaseArray( c ) );
382 		}
383 		
384 		fireTestCaseMoved(testCase, ix, offset );
385 		return testCase;
386 	}
387 
388 	public int getIndexOfTestCase( TestCase testCase )
389 	{
390 		return testCases.indexOf( testCase );
391 	}
392 
393 	@Override
394 	public void beforeSave()
395 	{
396 		for( WsdlTestCase testCase : testCases )
397 			testCase.beforeSave();
398 	}
399    
400    public List<? extends ModelItem> getChildren()
401    {
402       return getTestCaseList();
403    }
404    
405    public void setSetupScript( String script )
406 	{
407 		String oldScript = getSetupScript();
408 
409 		if( !getConfig().isSetSetupScript() )
410 			getConfig().addNewSetupScript();
411 
412 		getConfig().getSetupScript().setStringValue( script );
413 		if( setupScriptEngine != null )
414 			setupScriptEngine.setScript( script );
415 		
416 		notifyPropertyChanged( SETUP_SCRIPT_PROPERTY, oldScript, script );
417 	}
418 
419 	public String getSetupScript()
420 	{
421 		return getConfig().isSetSetupScript() ? getConfig().getSetupScript().getStringValue() : null;
422 	}
423 
424 	public void setTearDownScript( String script )
425 	{
426 		String oldScript = getTearDownScript();
427 
428 		if( !getConfig().isSetTearDownScript() )
429 			getConfig().addNewTearDownScript();
430 
431 		getConfig().getTearDownScript().setStringValue( script );
432 		if( tearDownScriptEngine != null )
433 			tearDownScriptEngine.setScript( script );
434 
435 		notifyPropertyChanged( TEARDOWN_SCRIPT_PROPERTY, oldScript, script );
436 	}
437 
438 	public String getTearDownScript()
439 	{
440 		return getConfig().isSetTearDownScript() ? getConfig().getTearDownScript().getStringValue() : null;
441 	}
442 	
443 	public Object runSetupScript( PropertyExpansionContext context ) throws Exception
444 	{
445 		String script = getSetupScript();
446 		if( StringUtils.isNullOrEmpty( script ))
447 			return null;
448 		
449 		if( setupScriptEngine == null )
450 		{
451 			setupScriptEngine = SoapUIScriptEngineRegistry.create( SoapUIScriptEngineRegistry.GROOVY_ID, this );
452 			setupScriptEngine.setScript( script );
453 		}
454 		
455 		if( context == null )
456 			context = new DefaultPropertyExpansionContext( this );
457 		
458 		setupScriptEngine.setVariable( "context", context );
459 		setupScriptEngine.setVariable( "testSuite", this );
460 		setupScriptEngine.setVariable( "log", SoapUI.ensureGroovyLog() );
461 		return setupScriptEngine.run();
462 	}
463 
464 	public Object runTearDownScript( PropertyExpansionContext context ) throws Exception
465 	{
466 		String script = getTearDownScript();
467 		if( StringUtils.isNullOrEmpty( script ))
468 			return null;
469 		
470 		if( tearDownScriptEngine == null )
471 		{
472 			tearDownScriptEngine = SoapUIScriptEngineRegistry.create( SoapUIScriptEngineRegistry.GROOVY_ID, this );
473 			tearDownScriptEngine.setScript( script );
474 		}
475 		
476 		if( context == null )
477 			context = new DefaultPropertyExpansionContext( this );
478 		
479 		tearDownScriptEngine.setVariable( "context", context );
480 		tearDownScriptEngine.setVariable( "testSuite", this );
481 		tearDownScriptEngine.setVariable( "log", SoapUI.ensureGroovyLog() );
482 		return tearDownScriptEngine.run();
483 	}
484 
485 	@Override
486 	public void setName( String name )
487 	{
488 		String oldLabel = getLabel();
489    	
490 		super.setName( name );
491 		
492 		String label = getLabel();
493 		if( oldLabel != null && !oldLabel.equals( label ))
494 		{
495 			notifyPropertyChanged( LABEL_PROPERTY, oldLabel, label );
496 		}
497 	}
498 
499 	public String getLabel()
500 	{
501 		String name = getName();
502 		if( isDisabled() )
503 			return name + " (disabled)";
504 		else
505 			return name;
506 	}
507 
508 	public boolean isDisabled()
509 	{
510 		return getConfig().getDisabled();
511 	}
512 	
513 	public void setDisabled( boolean disabled )
514 	{
515 		String oldLabel = getLabel();
516 		
517 		boolean oldDisabled = isDisabled();
518 		if( oldDisabled == disabled )
519 			return;
520 		
521 		if( disabled )
522 			getConfig().setDisabled( disabled );
523 		else if( getConfig().isSetDisabled() )
524 			getConfig().unsetDisabled();
525 		
526 		notifyPropertyChanged( DISABLED_PROPERTY, oldDisabled, disabled );
527 		
528 		String label = getLabel();
529 		if( !oldLabel.equals( label ))
530 			notifyPropertyChanged( LABEL_PROPERTY, oldLabel, label );
531 	}
532 }