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