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    public List<? extends ModelItem> getChildren()
396    {
397       return getTestCaseList();
398    }
399 
400    public void setSetupScript( String script )
401    {
402       String oldScript = getSetupScript();
403 
404       if( !getConfig().isSetSetupScript() )
405          getConfig().addNewSetupScript();
406 
407       getConfig().getSetupScript().setStringValue( script );
408       if( setupScriptEngine != null )
409          setupScriptEngine.setScript( script );
410 
411       notifyPropertyChanged( SETUP_SCRIPT_PROPERTY, oldScript, script );
412    }
413 
414    public String getSetupScript()
415    {
416       return getConfig().isSetSetupScript() ? getConfig().getSetupScript().getStringValue() : null;
417    }
418 
419    public void setTearDownScript( String script )
420    {
421       String oldScript = getTearDownScript();
422 
423       if( !getConfig().isSetTearDownScript() )
424          getConfig().addNewTearDownScript();
425 
426       getConfig().getTearDownScript().setStringValue( script );
427       if( tearDownScriptEngine != null )
428          tearDownScriptEngine.setScript( script );
429 
430       notifyPropertyChanged( TEARDOWN_SCRIPT_PROPERTY, oldScript, script );
431    }
432 
433    public String getTearDownScript()
434    {
435       return getConfig().isSetTearDownScript() ? getConfig().getTearDownScript().getStringValue() : null;
436    }
437 
438    public Object runSetupScript( PropertyExpansionContext context ) throws Exception
439    {
440       String script = getSetupScript();
441       if( StringUtils.isNullOrEmpty( script ) )
442          return null;
443 
444       if( setupScriptEngine == null )
445       {
446          setupScriptEngine = SoapUIScriptEngineRegistry.create( SoapUIScriptEngineRegistry.GROOVY_ID, this );
447          setupScriptEngine.setScript( script );
448       }
449 
450       if( context == null )
451          context = new DefaultPropertyExpansionContext( this );
452 
453       setupScriptEngine.setVariable( "context", context );
454       setupScriptEngine.setVariable( "testSuite", this );
455       setupScriptEngine.setVariable( "log", SoapUI.ensureGroovyLog() );
456       return setupScriptEngine.run();
457    }
458 
459    public Object runTearDownScript( PropertyExpansionContext context ) throws Exception
460    {
461       String script = getTearDownScript();
462       if( StringUtils.isNullOrEmpty( script ) )
463          return null;
464 
465       if( tearDownScriptEngine == null )
466       {
467          tearDownScriptEngine = SoapUIScriptEngineRegistry.create( SoapUIScriptEngineRegistry.GROOVY_ID, this );
468          tearDownScriptEngine.setScript( script );
469       }
470 
471       if( context == null )
472          context = new DefaultPropertyExpansionContext( this );
473 
474       tearDownScriptEngine.setVariable( "context", context );
475       tearDownScriptEngine.setVariable( "testSuite", this );
476       tearDownScriptEngine.setVariable( "log", SoapUI.ensureGroovyLog() );
477       return tearDownScriptEngine.run();
478    }
479 
480    @Override
481    public void setName( String name )
482    {
483       String oldLabel = getLabel();
484 
485       super.setName( name );
486 
487       String label = getLabel();
488       if( oldLabel != null && !oldLabel.equals( label ) )
489       {
490          notifyPropertyChanged( LABEL_PROPERTY, oldLabel, label );
491       }
492    }
493 
494    public String getLabel()
495    {
496       String name = getName();
497       if( isDisabled() )
498          return name + " (disabled)";
499       else
500          return name;
501    }
502 
503    public boolean isDisabled()
504    {
505       return getConfig().getDisabled();
506    }
507 
508    public void setDisabled( boolean disabled )
509    {
510       String oldLabel = getLabel();
511 
512       boolean oldDisabled = isDisabled();
513       if( oldDisabled == disabled )
514          return;
515 
516       if( disabled )
517          getConfig().setDisabled( disabled );
518       else if( getConfig().isSetDisabled() )
519          getConfig().unsetDisabled();
520 
521       notifyPropertyChanged( DISABLED_PROPERTY, oldDisabled, disabled );
522 
523       String label = getLabel();
524       if( !oldLabel.equals( label ) )
525          notifyPropertyChanged( LABEL_PROPERTY, oldLabel, label );
526    }
527 
528    public void replace( WsdlTestCase testCase, TestCaseConfig newTestCase )
529    {
530 
531       int ix = testCases.indexOf( testCase );
532 
533       testCases.remove( ix );
534       try
535       {
536          fireTestCaseRemoved( testCase );
537       }
538       finally
539       {
540          testCase.release();
541          getConfig().removeTestCase( ix );
542       }
543 
544       TestCaseConfig newConfig = (TestCaseConfig) getConfig().insertNewTestCase( ix ).set( newTestCase ).changeType(
545               TestCaseConfig.type );
546       testCase = new WsdlTestCase( this, newConfig, false );
547       testCases.add( ix, testCase );
548       testCase.afterLoad();
549       fireTestCaseAdded( testCase );
550 
551       resolveImportedTestCase( testCase );
552    }
553 
554    public void importTestCase( File file )
555    {
556       TestCaseConfig testCaseNewConfig = null;
557 
558       if( !file.exists() )
559       {
560          UISupport.showErrorMessage( "Error loading test case " );
561          return;
562       }
563 
564       try
565       {
566          testCaseNewConfig = TestCaseDocumentConfig.Factory.parse( file ).getTestCase();
567       }
568       catch( Exception e )
569       {
570          SoapUI.logError( e );
571       }
572 
573       if( testCaseNewConfig != null )
574       {
575          TestCaseConfig newConfig = (TestCaseConfig) getConfig().addNewTestCase().set( testCaseNewConfig ).changeType(
576                  TestCaseConfig.type );
577          WsdlTestCase newTestCase = new WsdlTestCase( this, newConfig, false );
578          newTestCase.afterLoad();
579          testCases.add( newTestCase );
580          fireTestCaseAdded( newTestCase );
581 
582          resolveImportedTestCase( newTestCase );
583       }
584       else
585       {
586          UISupport.showErrorMessage( "Not valild test case xml" );
587       }
588    }
589 
590    private void resolveImportedTestCase( WsdlTestCase newTestCase )
591    {
592       ResolveDialog resolver = new ResolveDialog( "Validate TestCase", "Checks TestCase for inconsistencies", null );
593       resolver.setShowOkMessage( false );
594       resolver.resolve( newTestCase );
595    }
596 
597    public void export( File file )
598    {
599       try
600       {
601          this.getConfig().newCursor().save( file );
602       }
603       catch( IOException e )
604       {
605          e.printStackTrace();
606       }
607    }
608 }