View Javadoc

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