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