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.HashSet;
17  import java.util.List;
18  import java.util.Set;
19  
20  import org.apache.log4j.Logger;
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.TestStepConfig;
26  import com.eviware.soapui.impl.wsdl.AbstractWsdlModelItem;
27  import com.eviware.soapui.impl.wsdl.WsdlTestSuite;
28  import com.eviware.soapui.impl.wsdl.loadtest.LoadTestAssertion;
29  import com.eviware.soapui.impl.wsdl.loadtest.WsdlLoadTest;
30  import com.eviware.soapui.impl.wsdl.loadtest.assertions.TestStepStatusAssertion;
31  import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestStep;
32  import com.eviware.soapui.impl.wsdl.teststeps.registry.WsdlTestStepFactory;
33  import com.eviware.soapui.impl.wsdl.teststeps.registry.WsdlTestStepRegistry;
34  import com.eviware.soapui.model.support.PropertiesMap;
35  import com.eviware.soapui.model.testsuite.LoadTest;
36  import com.eviware.soapui.model.testsuite.TestCase;
37  import com.eviware.soapui.model.testsuite.TestRunListener;
38  import com.eviware.soapui.model.testsuite.TestStep;
39  import com.eviware.soapui.support.UISupport;
40  import com.eviware.soapui.support.action.swing.ActionList;
41  import com.eviware.soapui.support.action.swing.DefaultActionList;
42  
43  /***
44   * TestCase implementation for WSDL projects
45   *  
46   * @author Ole.Matzura
47   */
48  
49  public class WsdlTestCase extends AbstractWsdlModelItem<TestCaseConfig> implements TestCase
50  {
51     private final static Logger logger = Logger.getLogger( WsdlTestCase.class );
52     public final static String KEEP_SESSION_PROPERTY = WsdlTestCase.class.getName() + "@keepSession";
53     public final static String FAIL_ON_ERROR_PROPERTY = WsdlTestCase.class.getName() + "@failOnError";
54     public final static String FAIL_ON_ERRORS_PROPERTY = WsdlTestCase.class.getName() + "@failOnErrors";
55     public final static String DISCARD_OK_RESULTS = WsdlTestCase.class.getName() + "@discardOkResults";
56  	private static final String SEARCH_PROPERTIES_PROPERTY = WsdlTestCase.class.getName() + "@searchProperties";
57  	
58  	private final WsdlTestSuite testSuite;
59     private List<WsdlTestStep> testSteps = new ArrayList<WsdlTestStep>();
60     private List<WsdlLoadTest> loadTests = new ArrayList<WsdlLoadTest>();
61     private Set<TestRunListener> testRunListeners = new HashSet<TestRunListener>();
62  	private DefaultActionList createActions;
63  	private final boolean forLoadTest;
64  	
65     public WsdlTestCase(WsdlTestSuite testSuite, TestCaseConfig config, boolean forLoadTest )
66     {
67     	super( config, testSuite, "/testCase.gif" );
68     	
69        this.testSuite = testSuite;
70  		this.forLoadTest = forLoadTest;
71        
72        List<TestStepConfig> testStepConfigs = config.getTestStepList();
73        for (TestStepConfig tsc : testStepConfigs )
74        {
75           WsdlTestStep testStep = createTestStepFromConfig(tsc);
76           if( testStep != null )
77           {
78              ensureUniqueName( testStep );
79           	testSteps.add( testStep );
80           }
81        }
82        
83        for( TestStep step : testSteps )
84        {
85        	WsdlTestStep testStep = (WsdlTestStep) step;
86        	testStep.postInit( testStep.getConfig() );
87        }
88        
89        if( !forLoadTest )
90        {
91  	      List<LoadTestConfig> loadTestConfigs = config.getLoadTestList();
92  	      for (LoadTestConfig tsc : loadTestConfigs)
93  	      {
94  	         WsdlLoadTest loadTest = new WsdlLoadTest( this, tsc );
95  				loadTests.add( loadTest);
96  	      }
97        }
98        
99        // init default configs
100       if( !config.isSetFailOnError() )
101       	config.setFailOnError( true );
102       
103       if( !config.isSetFailTestCaseOnErrors() )
104       	config.setFailTestCaseOnErrors( true );
105 
106       if( !config.isSetKeepSession() )
107       	config.setKeepSession( false );
108       
109       for (TestRunListener listener : SoapUI.getListenerRegistry().getListeners( TestRunListener.class ))
110       {
111           addTestRunListener(listener);
112       }
113    }
114 
115    public boolean getKeepSession()
116    {
117    	return getConfig().getKeepSession();
118    }
119    
120    public void setKeepSession( boolean keepSession )
121    {
122    	boolean old = getKeepSession();
123    	if( old != keepSession )
124    	{
125    		getConfig().setKeepSession( keepSession );
126    		notifyPropertyChanged( KEEP_SESSION_PROPERTY, old, keepSession );
127    	}
128    }
129    
130    public boolean getFailOnError()
131    {
132    	return getConfig().getFailOnError();
133    }
134    
135    public boolean getFailTestCaseOnErrors()
136    {
137    	return getConfig().getFailTestCaseOnErrors();
138    }
139    
140    public void setFailOnError( boolean failOnError )
141    {
142    	boolean old = getFailOnError();
143    	if( old != failOnError )
144    	{
145    		getConfig().setFailOnError( failOnError );
146    		notifyPropertyChanged( FAIL_ON_ERROR_PROPERTY, old, failOnError );
147    	}
148    }
149    
150    public void setFailTestCaseOnErrors( boolean failTestCaseOnErrors )
151    {
152    	boolean old = getFailTestCaseOnErrors();
153    	if( old != failTestCaseOnErrors )
154    	{
155    		getConfig().setFailTestCaseOnErrors( failTestCaseOnErrors );
156    		notifyPropertyChanged( FAIL_ON_ERRORS_PROPERTY, old, failTestCaseOnErrors );
157    	}
158    }
159    
160    public boolean getSearchProperties()
161    {
162    	return getConfig().getSearchProperties();
163    }
164    
165    public void setSearchProperties( boolean searchProperties )
166    {
167    	boolean old = getSearchProperties();
168    	if( old != searchProperties )
169    	{
170    		getConfig().setSearchProperties( searchProperties );
171    		notifyPropertyChanged( SEARCH_PROPERTIES_PROPERTY, old, searchProperties );
172    	}
173    }
174    
175    public boolean getDiscardOkResults()
176    {
177    	return getConfig().getDiscardOkResults();
178    }
179    
180    public void setDiscardOkResults( boolean discardOkResults )
181    {
182    	boolean old = getDiscardOkResults();
183    	if( old != discardOkResults )
184    	{
185    		getConfig().setDiscardOkResults( discardOkResults );
186    		notifyPropertyChanged( DISCARD_OK_RESULTS, old, discardOkResults );
187    	}
188    }
189    
190 	private WsdlTestStep createTestStepFromConfig(TestStepConfig tsc )
191 	{
192 		WsdlTestStepFactory factory = WsdlTestStepRegistry.getInstance().getFactory( tsc.getType() );
193 		if( factory != null )
194 		{
195 			WsdlTestStep testStep = factory.buildTestStep( this, tsc, forLoadTest );
196 			return testStep;
197 		}
198 		else 
199 		{
200 			logger.error( "Failed to create test step for [" + tsc.getName() + "]" );
201 			return null;
202 		}
203 	}
204 
205 	private boolean ensureUniqueName(WsdlTestStep testStep)
206 	{
207 		String name = testStep.getName();
208 		while( name == null || getTestStepByName( name ) != null )
209 		{
210 			if( name == null )
211 				name = testStep.getName();
212 			else
213 			{
214 				int cnt = 0;
215 				
216 				while( getTestStepByName( name ) != null )
217 				{
218 					cnt++;
219 					name = testStep.getName() + " " + cnt;
220 				}
221 				
222 				if( cnt == 0 )
223 					break;
224 			}
225 			
226 			name = UISupport.prompt( "TestStep name must be unique, please specify new name for step\n" +
227 					"[" + testStep.getName() + "] in TestCase [" + getTestSuite().getProject().getName() + "->" +
228 					getTestSuite().getName() + "->" + getName() + "]", 
229 					"Change TestStep name", name);
230 			
231 			if( name == null )
232 				return false;
233 		}
234 		
235 		if( !name.equals( testStep.getName() ))
236 			testStep.setName( name );
237 		
238 		return true;
239 	}
240 
241    public WsdlLoadTest addNewLoadTest( String name )
242    {
243       WsdlLoadTest loadTest = new WsdlLoadTest( this, getConfig().addNewLoadTest());
244       loadTest.setStartDelay( 0 );
245       loadTest.setName( name );
246       loadTests.add( loadTest );
247       
248       loadTest.addAssertion( TestStepStatusAssertion.STEP_STATUS_TYPE, 
249       		LoadTestAssertion.ANY_TEST_STEP, false );
250 
251       ((WsdlTestSuite)getTestSuite()).fireLoadTestAdded( loadTest );
252       
253       return loadTest;
254    }
255    
256 	public void removeLoadTest(WsdlLoadTest loadTest)
257 	{
258 		int ix = loadTests.indexOf( loadTest );
259 
260 		loadTests.remove( ix );
261 		
262 		try
263 		{
264 			((WsdlTestSuite)getTestSuite()).fireLoadTestRemoved( loadTest );
265 		}
266 		finally
267 		{
268 			loadTest.release();
269 			getConfig().removeLoadTest( ix );
270 		}
271 	} 
272 
273    public WsdlTestSuite getTestSuite()
274    {
275       return testSuite;
276    }
277 
278    public WsdlTestStep cloneStep( WsdlTestStep testStep, String name )
279    {
280    	return testStep.clone( this, name );
281    }
282    
283    public WsdlTestStep getTestStepAt(int index)
284    {
285       return testSteps.get( index );
286    }
287 
288    public int getTestStepCount()
289    {
290       return testSteps.size();
291    }
292 
293    public WsdlLoadTest getLoadTestAt(int index)
294    {
295       return loadTests.get( index );
296    }
297 
298    public LoadTest getLoadTestByName(String loadTestName)
299 	{
300 		return (LoadTest) getWsdlModelItemByName( loadTests, loadTestName );
301 	}
302 
303 	public int getLoadTestCount()
304    {
305       return loadTests.size();
306    }
307    
308    public WsdlTestStep addTestStep( TestStepConfig stepConfig )
309    {
310    	return insertTestStep( stepConfig, -1 );
311    }
312    
313    public WsdlTestStep addTestStep( String type, String name  )
314    {
315    	TestStepConfig newStepConfig = WsdlTestStepRegistry.getInstance().getFactory( type ).createNewTestStep( this, name );
316    	if( newStepConfig != null ) 
317    	{
318    		return addTestStep( newStepConfig);
319   		}
320    	else return null;
321    }
322    
323    public WsdlTestStep insertTestStep( String type, String name, int index  )
324    {
325    	TestStepConfig newStepConfig = WsdlTestStepRegistry.getInstance().getFactory( type ).createNewTestStep( this, name );
326    	if( newStepConfig != null )
327    	{
328    		return insertTestStep( newStepConfig, index );
329    	}
330    	else return null;
331    }
332    
333    public WsdlTestStep importTestStep( WsdlTestStep testStep, String name, int index  )
334    {
335    	testStep.onSave();
336    	TestStepConfig newStepConfig = ( TestStepConfig ) testStep.getConfig().copy();
337 		newStepConfig.setName( name );
338 		return insertTestStep( newStepConfig, index );
339    }
340    
341    public WsdlTestStep [] importTestSteps( WsdlTestStep [] testSteps, int index  )
342    {
343    	TestStepConfig [] newStepConfigs = new TestStepConfig[testSteps.length];
344    	
345    	for( int c = 0; c < testSteps.length; c++ )
346    	{
347    		testSteps[c].onSave();
348    		newStepConfigs[c] = ( TestStepConfig ) testSteps[c].getConfig().copy();
349    	}
350    	
351    	return insertTestSteps( newStepConfigs, index );
352    }
353    
354    public WsdlTestStep insertTestStep( TestStepConfig stepConfig, int ix )
355    {
356    	TestStepConfig newStepConfig = ix == -1 ? getConfig().addNewTestStep() : getConfig().insertNewTestStep( ix );
357    	newStepConfig.set( stepConfig );
358    	WsdlTestStep testStep = createTestStepFromConfig( newStepConfig );
359    	
360    	if( !ensureUniqueName( testStep ))
361    		return null;
362    	
363       if( ix == -1 )
364       	testSteps.add( testStep );
365       else
366       	testSteps.add( ix, testStep );
367       
368       testStep.postInit( testStep.getConfig() );
369       
370       if( getTestSuite() != null )
371       	((WsdlTestSuite)getTestSuite()).fireTestStepAdded( testStep, ix == -1 ? testSteps.size()-1 : ix  );
372       
373       return testStep;
374    }
375    
376    public WsdlTestStep [] insertTestSteps( TestStepConfig [] stepConfig, int ix )
377    {
378    	WsdlTestStep [] result = new WsdlTestStep[stepConfig.length];
379    	
380    	for( int c = 0; c < stepConfig.length; c++ )
381    	{
382    		TestStepConfig newStepConfig = ix == -1 ? getConfig().addNewTestStep() : getConfig().insertNewTestStep( ix+c );
383    		newStepConfig.set( stepConfig[c] );
384    		WsdlTestStep testStep = createTestStepFromConfig( newStepConfig );
385    	
386 	   	if( !ensureUniqueName( testStep ))
387 	   		return null;
388 	   	
389 	      if( ix == -1 )
390 	      	testSteps.add( testStep );
391 	      else
392 	      	testSteps.add( ix+c, testStep );
393 	      
394 	      result[c] = testStep;
395    	}
396       
397    	for( int c = 0; c < result.length; c++ )
398    	{
399    		result[c].postInit( result[c].getConfig() );
400 	      
401 	      if( getTestSuite() != null )
402 	      	((WsdlTestSuite)getTestSuite()).fireTestStepAdded( result[c], getIndexOfTestStep( result[c] ));
403    	}
404       
405       return result;
406    }
407    
408    public void removeTestStep(WsdlTestStep testStep)
409    {
410       int ix = testSteps.indexOf( testStep );
411       if( ix == -1 )
412       {
413          logger.error( "TestStep [" + testStep.getName() + "] passed to removeTestStep in testCase [" + 
414                getName() + "] not found" );
415          return;
416       }
417       
418       testSteps.remove( ix );
419 
420       try
421       {
422       	((WsdlTestSuite)getTestSuite()).fireTestStepRemoved( testStep, ix );
423       }
424       finally
425       {
426       	testStep.release();
427       
428 	      for( int c = 0; c < getConfig().sizeOfTestStepArray(); c++ ) 
429 	      {
430 	      	if( testStep.getConfig() == getConfig().getTestStepArray( c ))
431 	      	{
432 	      		getConfig().removeTestStep( c );
433 	      		break;
434 	      	}
435 	      }
436       }
437    }
438    
439    public WsdlTestCaseRunner run( PropertiesMap properties, boolean async ) 
440    {
441    	WsdlTestCaseRunner runner = new WsdlTestCaseRunner( this, properties );
442    	runner.start( async );
443    	return runner;
444 	}
445 
446 	public void addTestRunListener(TestRunListener listener) {
447 		if( listener == null )
448 			throw new RuntimeException( "listener must not be null" );
449 		
450 		testRunListeners.add( listener );
451 	}
452 
453 	public void removeTestRunListener(TestRunListener listener) {
454 		testRunListeners.remove( listener );
455 	}
456 	
457 	public TestRunListener [] getTestRunListeners()
458 	{
459 		return testRunListeners.toArray( new TestRunListener[testRunListeners.size()]);
460 	}
461 
462 	WsdlTestStep[] getTestSteps() 
463 	{
464 		return testSteps.toArray( new WsdlTestStep[testSteps.size()] );
465  	}
466 
467 	public int getIndexOfTestStep(TestStep step)
468 	{
469 		return testSteps.indexOf( step );
470 	}
471 	
472 	/***
473 	 * Moves a step by the specified offset, a bit awkward since xmlbeans doesn't support reordering
474 	 * of arrays, we need to create copies of the contained XmlObjects
475 	 * 
476 	 * @param ix
477 	 * @param offset
478 	 */
479 	
480 	public void moveTestStep(int ix, int offset)
481 	{
482 		if( offset == 0 ) return;
483 		WsdlTestStep step = (WsdlTestStep) testSteps.get( ix );
484 
485 		if( ix + offset >= testSteps.size() )
486 			offset = testSteps.size()-ix-1;
487 		
488 		testSteps.remove( ix );
489 		testSteps.add( ix+offset, step );
490 
491 		TestStepConfig [] configs = new TestStepConfig[testSteps.size()];
492 		
493 		TestCaseConfig conf = getConfig();
494 		for( int c = 0; c < testSteps.size(); c++ )
495 		{
496 			if( offset > 0 )
497 			{
498 				if( c < ix )
499 					configs[c] = (TestStepConfig) conf.getTestStepArray(c).copy();
500 				else if( c < (ix+offset))
501 					configs[c] = (TestStepConfig) conf.getTestStepArray(c+1).copy();
502 				else if( c == ix+offset )
503 					configs[c] = (TestStepConfig) conf.getTestStepArray(ix).copy();
504 				else
505 					configs[c] = (TestStepConfig) conf.getTestStepArray(c).copy();
506 			}
507 			else
508 			{
509 				if( c < ix+offset )
510 					configs[c] = (TestStepConfig) conf.getTestStepArray(c).copy();
511 				else if( c == ix+offset )
512 					configs[c] = (TestStepConfig) conf.getTestStepArray(ix).copy();
513 				else if( c <= ix )
514 					configs[c] = (TestStepConfig) conf.getTestStepArray(c-1).copy();
515 				else
516 					configs[c] = (TestStepConfig) conf.getTestStepArray(c).copy();				
517 			}
518 		}
519 		
520 		conf.setTestStepArray( configs );
521 		for( int c = 0; c < configs.length; c++ )
522 		{
523 			((WsdlTestStep) testSteps.get( c )).resetConfigOnMove( conf.getTestStepArray( c ));
524 		}
525 		
526 		((WsdlTestSuite)getTestSuite()).fireTestStepMoved(step, ix, offset );
527 	}
528 	
529 	public int getIndexOfLoadTest( LoadTest loadTest )
530 	{
531 		return loadTests.indexOf( loadTest );
532 	}
533 
534 
535 	public int getTestStepIndexByName(String stepName)
536 	{
537 		for( int c = 0; c < testSteps.size(); c++ )
538 		{
539 			if( testSteps.get( c ).getName().equals( stepName ))
540 				return c;
541 		}
542 		
543 		return -1;
544 	}
545 	
546 	public TestStep findPreviousStepOfType( TestStep referenceStep, Class stepClass )
547 	{
548 		int currentStepIndex = getIndexOfTestStep( referenceStep );
549 		int ix = currentStepIndex - 1 ;
550 		while( ix >= 0 && !getTestStepAt( ix ).getClass().equals( stepClass ))
551 		{
552 			ix--;
553 		}
554 		
555 		return ix < 0 ? null : getTestStepAt( ix );
556 	}
557 	
558 	public TestStep findNextStepOfType( TestStep referenceStep, Class stepClass )
559 	{
560 		int currentStepIndex = getIndexOfTestStep( referenceStep );
561 		int ix = currentStepIndex + 1 ;
562 		while( ix < getTestStepCount() && !getTestStepAt( ix ).getClass().equals( stepClass ))
563 		{
564 			ix++;
565 		}
566 		
567 		return ix >= getTestStepCount() ? null : getTestStepAt( ix );
568 	}
569 
570 	public List<TestStep> getTestStepList()
571 	{
572 		List<TestStep> result = new ArrayList<TestStep>();
573 		for( TestStep step : testSteps )
574 			result.add( step );
575 			
576 		return result;
577 	}
578 	
579 	@SuppressWarnings("unchecked")
580 	public <T extends TestStep> List<T> getTestStepsOfType( Class<T> stepType )
581 	{
582 		List<T> result = new ArrayList<T>();
583 		for( TestStep step : testSteps )
584 			if( step.getClass().isAssignableFrom( stepType ) )
585 				result.add( ( T ) step );
586 			
587 		return result;
588 	}
589 
590 	public WsdlTestStep getTestStepByName(String stepName)
591 	{
592 		return (WsdlTestStep)getWsdlModelItemByName( testSteps, stepName );
593 	}
594 
595 	public WsdlLoadTest cloneLoadTest(WsdlLoadTest loadTest, String name)
596 	{
597 		loadTest.onSave();
598 		
599 		LoadTestConfig loadTestConfig = getConfig().addNewLoadTest();
600 		loadTestConfig.set( loadTest.getConfig().copy());
601 		
602 		WsdlLoadTest newLoadTest = new WsdlLoadTest( this, loadTestConfig );
603 		newLoadTest.setName( name );
604 	   loadTests.add( newLoadTest );
605 
606 	   ((WsdlTestSuite)getTestSuite()).fireLoadTestAdded( newLoadTest );
607 	      
608 	   return newLoadTest;
609 	}
610 
611 	public void release()
612 	{
613 		super.release();
614 		
615 		for( WsdlTestStep testStep : testSteps )
616 			testStep.release();
617 		
618 		for( WsdlLoadTest loadTest : loadTests )
619 			loadTest.release();
620 		
621 		testRunListeners.clear();
622 	}
623 	
624 	public ActionList getCreateActions()
625 	{
626 		return createActions;
627 	}
628 
629 	public void resetConfigOnMove( TestCaseConfig testCaseArray )
630 	{
631 		setConfig( testCaseArray );
632 		int mod = 0;
633 		
634 		List<TestStepConfig> configs = getConfig().getTestStepList();
635 		for( int c = 0; c < configs.size(); c++ )
636 		{
637 			if( WsdlTestStepRegistry.getInstance().hasFactory( configs.get( c ) ))
638 			{
639 				((WsdlTestStep) testSteps.get( c-mod )).resetConfigOnMove( configs.get( c ));
640 			}
641 			else mod++;
642 		}
643 		
644 		List<LoadTestConfig> loadTestConfigs = getConfig().getLoadTestList();
645 		for( int c = 0; c < loadTestConfigs.size(); c++ )
646 		{
647 			loadTests.get( c ).resetConfigOnMove( loadTestConfigs.get( c ));
648 		}
649 	}
650 
651 	@Override
652 	public void onSave()
653 	{
654 		for( WsdlTestStep testStep : testSteps )
655 			testStep.onSave();
656 		
657 		for( WsdlLoadTest loadTest : loadTests )
658 			loadTest.onSave();
659 	}
660 
661 	public List<LoadTest> getLoadTestList()
662 	{
663 		List<LoadTest> result = new ArrayList<LoadTest>();
664 		for( LoadTest loadTest : loadTests )
665 			result.add( loadTest );
666 			
667 		return result;
668 	}
669 }