1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.teststeps;
14
15 import java.util.HashSet;
16 import java.util.List;
17 import java.util.Map;
18 import java.util.Set;
19
20 import com.eviware.soapui.SoapUI;
21 import com.eviware.soapui.config.LoadTestConfig;
22 import com.eviware.soapui.config.RunTestCaseRunModeTypeConfig;
23 import com.eviware.soapui.config.RunTestCaseStepConfig;
24 import com.eviware.soapui.config.TestCaseConfig;
25 import com.eviware.soapui.config.TestStepConfig;
26 import com.eviware.soapui.config.RunTestCaseRunModeTypeConfig.Enum;
27 import com.eviware.soapui.impl.wsdl.WsdlTestSuite;
28 import com.eviware.soapui.impl.wsdl.support.XmlBeansPropertiesTestPropertyHolder;
29 import com.eviware.soapui.impl.wsdl.support.XmlBeansPropertiesTestPropertyHolder.PropertiesStepProperty;
30 import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase;
31 import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCaseRunner;
32 import com.eviware.soapui.model.propertyexpansion.PropertyExpander;
33 import com.eviware.soapui.model.support.ModelSupport;
34 import com.eviware.soapui.model.support.TestPropertyListenerAdapter;
35 import com.eviware.soapui.model.support.TestRunListenerAdapter;
36 import com.eviware.soapui.model.support.TestSuiteListenerAdapter;
37 import com.eviware.soapui.model.testsuite.MessageExchangeTestStepResult;
38 import com.eviware.soapui.model.testsuite.TestCase;
39 import com.eviware.soapui.model.testsuite.TestCaseRunContext;
40 import com.eviware.soapui.model.testsuite.TestCaseRunner;
41 import com.eviware.soapui.model.testsuite.TestProperty;
42 import com.eviware.soapui.model.testsuite.TestPropertyListener;
43 import com.eviware.soapui.model.testsuite.TestRunContext;
44 import com.eviware.soapui.model.testsuite.TestRunListener;
45 import com.eviware.soapui.model.testsuite.TestRunner;
46 import com.eviware.soapui.model.testsuite.TestStep;
47 import com.eviware.soapui.model.testsuite.TestStepResult;
48 import com.eviware.soapui.model.testsuite.TestStepResult.TestStepStatus;
49 import com.eviware.soapui.support.StringUtils;
50 import com.eviware.soapui.support.UISupport;
51 import com.eviware.soapui.support.resolver.ChooseAnotherTestCase;
52 import com.eviware.soapui.support.resolver.CreateNewEmptyTestCase;
53 import com.eviware.soapui.support.resolver.ResolveContext;
54 import com.eviware.soapui.support.resolver.RunTestCaseRemoveResolver;
55 import com.eviware.soapui.support.types.StringList;
56 import com.eviware.soapui.support.types.StringToObjectMap;
57
58 public class WsdlRunTestCaseTestStep extends WsdlTestStep
59 {
60 public static final String TARGET_TESTCASE = WsdlRunTestCaseTestStep.class.getName() + "@target_testcase";
61
62 private RunTestCaseStepConfig stepConfig;
63 private WsdlTestCaseRunner testCaseRunner;
64 private XmlBeansPropertiesTestPropertyHolder propertyHolderSupport;
65 private String currentLabel;
66 private WsdlTestCase targetTestCase;
67 private InternalTestSuiteListener testSuiteListener = new InternalTestSuiteListener();
68 private InternalTestRunListener testRunListener = new InternalTestRunListener();
69 private InternalTestPropertyListener testPropertyListener = new InternalTestPropertyListener();
70 private Set<TestRunListener> testRunListeners = new HashSet<TestRunListener>();
71 private WsdlTestCase runningTestCase;
72
73 public WsdlRunTestCaseTestStep( WsdlTestCase testCase, TestStepConfig config, boolean forLoadTest )
74 {
75 super( testCase, config, true, forLoadTest );
76
77 if( config.getConfig() == null )
78 {
79 stepConfig = ( RunTestCaseStepConfig )config.addNewConfig().changeType( RunTestCaseStepConfig.type );
80 stepConfig.addNewProperties();
81 stepConfig.addNewReturnProperties();
82 }
83 else
84 {
85 stepConfig = ( RunTestCaseStepConfig )config.getConfig().changeType( RunTestCaseStepConfig.type );
86 }
87
88 if( stepConfig.getRunMode() == null )
89 {
90 stepConfig.setRunMode( RunTestCaseRunModeTypeConfig.PARALLELL );
91 }
92
93 setIcon( UISupport.createImageIcon( "/run_testcase_step.gif" ) );
94
95 propertyHolderSupport = new XmlBeansPropertiesTestPropertyHolder( this, stepConfig.getProperties() );
96 }
97
98 /***
99 * We need to check that we are not pointing at testcase in original
100 * testsuite
101 */
102
103 public void afterCopy( WsdlTestSuite oldTestSuite, WsdlTestCase oldTestCase )
104 {
105 super.afterCopy( oldTestSuite, oldTestCase );
106
107 if( targetTestCase != null && oldTestSuite == targetTestCase.getTestSuite() )
108 {
109 setTargetTestCase( getTestCase().getTestSuite().getTestCaseByName( targetTestCase.getName() ) );
110 }
111 }
112
113 @Override
114 public void afterLoad()
115 {
116 setTargetTestCase( findTargetTestCase() );
117
118 super.afterLoad();
119 }
120
121 private void syncProperties()
122 {
123 for( String name : propertyHolderSupport.getPropertyNames() )
124 {
125 if( !targetTestCase.hasProperty( name ) )
126 propertyHolderSupport.removeProperty( name );
127 }
128
129 for( String name : targetTestCase.getPropertyNames() )
130 {
131 if( !propertyHolderSupport.hasProperty( name ) )
132 propertyHolderSupport.addProperty( name );
133 }
134 }
135
136 private WsdlTestCase findTargetTestCase()
137 {
138 return ModelSupport.findModelItemById( getTestCaseId(), getTestCase().getTestSuite().getProject() );
139 }
140
141 public StringList getReturnProperties()
142 {
143 return new StringList( stepConfig.getReturnProperties().getEntryList() );
144 }
145
146 public void setReturnProperties( StringList returnProperties )
147 {
148 stepConfig.getReturnProperties().setEntryArray( returnProperties.toStringArray() );
149 }
150
151 public TestStepResult run( TestCaseRunner testRunner, TestCaseRunContext testRunContext )
152 {
153 WsdlMessageExchangeTestStepResult result = new WsdlMessageExchangeTestStepResult( this );
154
155 testCaseRunner = null;
156
157 if( targetTestCase != null )
158 {
159 Enum runMode = getRunMode();
160
161 if( runMode == RunTestCaseRunModeTypeConfig.PARALLELL )
162 {
163 runningTestCase = createTestCase( targetTestCase );
164 }
165 else
166 {
167 runningTestCase = targetTestCase;
168
169 TestCaseRunner targetTestRunner = SoapUI.getTestMonitor().getTestRunner( targetTestCase );
170 if( targetTestRunner != null && targetTestRunner.getStatus() == TestRunner.Status.RUNNING )
171 {
172 if( runMode == RunTestCaseRunModeTypeConfig.SINGLETON_AND_FAIL )
173 {
174 result.setStatus( TestStepStatus.FAILED );
175 result.addMessage( "Target TestCase is already running" );
176 result.stopTimer();
177 runningTestCase = null;
178 }
179 else
180 {
181 targetTestRunner.waitUntilFinished();
182 }
183 }
184 }
185
186 if( runningTestCase != null )
187 {
188 synchronized( runningTestCase )
189 {
190 for( TestRunListener listener : testRunListeners )
191 runningTestCase.addTestRunListener( listener );
192
193 StringList returnProperties = getReturnProperties();
194 Map<String, TestProperty> props = getProperties();
195 for( String key : props.keySet() )
196 {
197 if( runningTestCase.hasProperty( key ) && !returnProperties.contains( key ) )
198 {
199 String value = PropertyExpander.expandProperties( testRunContext, props.get( key ).getValue() );
200 if( StringUtils.hasContent( value ) || !isIgnoreEmptyProperties() )
201 runningTestCase.setPropertyValue( key, value );
202 }
203 }
204
205 currentLabel = getLabel();
206 runningTestCase.addTestRunListener( testRunListener );
207
208
209
210
211
212 result.startTimer();
213 StringToObjectMap properties = new StringToObjectMap();
214
215 if( isCopyLoadTestProperties() && properties.containsKey( TestRunContext.LOAD_TEST_CONTEXT ) )
216 {
217 properties
218 .put( TestRunContext.THREAD_INDEX, testRunContext.getProperty( TestRunContext.THREAD_INDEX ) );
219 properties.put( TestRunContext.TOTAL_RUN_COUNT, testRunContext
220 .getProperty( TestRunContext.TOTAL_RUN_COUNT ) );
221 properties.put( TestRunContext.LOAD_TEST_CONTEXT, testRunContext
222 .getProperty( TestRunContext.LOAD_TEST_CONTEXT ) );
223 properties.put( TestRunContext.LOAD_TEST_RUNNER, testRunContext
224 .getProperty( TestRunContext.LOAD_TEST_RUNNER ) );
225 properties.put( TestRunContext.RUN_COUNT, testRunContext.getProperty( TestRunContext.RUN_COUNT ) );
226 }
227
228 if( isCopyHttpSession() && properties.containsKey( TestRunContext.HTTP_STATE_PROPERTY ) )
229 {
230 properties.put( TestRunContext.HTTP_STATE_PROPERTY, testRunContext
231 .getProperty( TestRunContext.HTTP_STATE_PROPERTY ) );
232 }
233
234 properties.put( TestRunContext.INTERACTIVE, testRunContext.getProperty( TestRunContext.INTERACTIVE ) );
235
236 properties.put( "#CallingRunTestCaseStep#", this );
237 properties.put( "#CallingTestCaseRunner#", testRunner );
238 properties.put( "#CallingTestRunContext#", testRunContext );
239
240 testCaseRunner = runningTestCase.run( properties, true );
241 testCaseRunner.waitUntilFinished();
242 result.stopTimer();
243
244 for( String key : returnProperties )
245 {
246 if( runningTestCase.hasProperty( key ) )
247 setPropertyValue( key, runningTestCase.getPropertyValue( key ) );
248 }
249
250
251 for( TestStepResult testStepResult : testCaseRunner.getResults() )
252 {
253 result.addMessage( testStepResult.getTestStep().getName() + " - " + testStepResult.getStatus()
254 + " - " + testStepResult.getTimeTaken() );
255 for( String msg : testStepResult.getMessages() )
256 {
257 result.addMessage( "- " + msg );
258 }
259
260 if( testStepResult instanceof MessageExchangeTestStepResult )
261 {
262 result.addMessages( ( ( MessageExchangeTestStepResult )testStepResult ).getMessageExchanges() );
263 }
264 }
265
266 switch( testCaseRunner.getStatus() )
267 {
268 case CANCELED :
269 result.setStatus( TestStepStatus.CANCELED );
270 break;
271 case FAILED :
272 result.setStatus( TestStepStatus.FAILED );
273 break;
274 case FINISHED :
275 result.setStatus( TestStepStatus.OK );
276 break;
277 default :
278 result.setStatus( TestStepStatus.UNKNOWN );
279 break;
280 }
281
282 for( TestRunListener listener : testRunListeners )
283 runningTestCase.removeTestRunListener( listener );
284
285 if( runMode == RunTestCaseRunModeTypeConfig.PARALLELL )
286 runningTestCase.release();
287
288 runningTestCase.removeTestRunListener( testRunListener );
289
290 runningTestCase = null;
291 testCaseRunner = null;
292 }
293 }
294 }
295 else
296 {
297 result.setStatus( TestStepStatus.FAILED );
298 result.addMessage( "Missing testCase in project" );
299 result.stopTimer();
300 }
301
302 return result;
303 }
304
305 @Override
306 public String getLabel()
307 {
308 String name = getName();
309
310 if( testCaseRunner != null )
311 {
312 name += " - [" + testCaseRunner.getStatus() + "]";
313 }
314
315 if( isDisabled() )
316 return name + " (disabled)";
317 else
318 return name;
319 }
320
321 @Override
322 public boolean cancel()
323 {
324 if( testCaseRunner != null )
325 {
326 testCaseRunner.cancel( "Canceled by calling TestCase" );
327 }
328
329 return true;
330 }
331
332 private String getTestCaseId()
333 {
334 return stepConfig.getTargetTestCase();
335 }
336
337 public void setTargetTestCase( WsdlTestCase testCase )
338 {
339 if( targetTestCase != null )
340 {
341 targetTestCase.getTestSuite().removeTestSuiteListener( testSuiteListener );
342 targetTestCase.removeTestPropertyListener( testPropertyListener );
343 }
344
345 WsdlTestCase oldTestCase = this.targetTestCase;
346 this.targetTestCase = testCase;
347
348 if( testCase != null )
349 {
350 stepConfig.setTargetTestCase( testCase.getId() );
351
352 targetTestCase.getTestSuite().addTestSuiteListener( testSuiteListener );
353 targetTestCase.addTestPropertyListener( testPropertyListener );
354
355 syncProperties();
356 }
357
358 notifyPropertyChanged( TARGET_TESTCASE, oldTestCase, testCase );
359 }
360
361 public boolean isCopyHttpSession()
362 {
363 return stepConfig.getCopyHttpSession();
364 }
365
366 public boolean isCopyLoadTestProperties()
367 {
368 return stepConfig.getCopyLoadTestProperties();
369 }
370
371 public boolean isIgnoreEmptyProperties()
372 {
373 return stepConfig.getIgnoreEmptyProperties();
374 }
375
376 public void setCopyHttpSession( boolean arg0 )
377 {
378 if( arg0 == isCopyHttpSession() )
379 return;
380
381 stepConfig.setCopyHttpSession( arg0 );
382 notifyPropertyChanged( "copyHttpSession", !arg0, arg0 );
383 }
384
385 public void setCopyLoadTestProperties( boolean arg0 )
386 {
387 if( arg0 == isCopyLoadTestProperties() )
388 return;
389
390 stepConfig.setCopyLoadTestProperties( arg0 );
391 notifyPropertyChanged( "copyLoadTestProperties", !arg0, arg0 );
392 }
393
394 public void setIgnoreEmptyProperties( boolean arg0 )
395 {
396 if( arg0 == isIgnoreEmptyProperties() )
397 return;
398
399 stepConfig.setIgnoreEmptyProperties( arg0 );
400 notifyPropertyChanged( "ignoreEmptyProperties", !arg0, arg0 );
401 }
402
403 /***
404 * Creates a copy of the underlying WsdlTestCase with all LoadTests removed
405 * and configured for LoadTesting
406 */
407
408 private WsdlTestCase createTestCase( WsdlTestCase testCase )
409 {
410
411 testCase.beforeSave();
412
413 try
414 {
415 TestCaseConfig config = TestCaseConfig.Factory.parse( testCase.getConfig().xmlText() );
416 config.setLoadTestArray( new LoadTestConfig[0] );
417
418
419 WsdlTestCase wsdlTestCase = testCase.getTestSuite().buildTestCase( config, true );
420 wsdlTestCase.afterLoad();
421 return wsdlTestCase;
422 }
423 catch( Throwable e )
424 {
425 SoapUI.logError( e );
426 }
427
428 return null;
429 }
430
431 public void addTestPropertyListener( TestPropertyListener listener )
432 {
433 propertyHolderSupport.addTestPropertyListener( listener );
434 }
435
436 public Map<String, TestProperty> getProperties()
437 {
438 return propertyHolderSupport.getProperties();
439 }
440
441 public PropertiesStepProperty getProperty( String name )
442 {
443 return propertyHolderSupport.getProperty( name );
444 }
445
446 public String[] getPropertyNames()
447 {
448 return propertyHolderSupport.getPropertyNames();
449 }
450
451 public List<TestProperty> getPropertyList()
452 {
453 return propertyHolderSupport.getPropertyList();
454 }
455
456 public String getPropertyValue( String name )
457 {
458 return propertyHolderSupport.getPropertyValue( name );
459 }
460
461 public boolean hasProperty( String name )
462 {
463 return propertyHolderSupport.hasProperty( name );
464 }
465
466 public void removeTestPropertyListener( TestPropertyListener listener )
467 {
468 propertyHolderSupport.removeTestPropertyListener( listener );
469 }
470
471 public void setPropertyValue( String name, String value )
472 {
473 propertyHolderSupport.setPropertyValue( name, value );
474 }
475
476 private void updateLabelDuringRun()
477 {
478 notifyPropertyChanged( WsdlTestStep.LABEL_PROPERTY, currentLabel, getLabel() );
479 currentLabel = getLabel();
480 }
481
482 private final class InternalTestPropertyListener extends TestPropertyListenerAdapter
483 {
484 @Override
485 public void propertyAdded( String name )
486 {
487 propertyHolderSupport.addProperty( name );
488 }
489
490 @Override
491 public void propertyRemoved( String name )
492 {
493 propertyHolderSupport.removeProperty( name );
494 }
495
496 @Override
497 public void propertyRenamed( String oldName, String newName )
498 {
499 propertyHolderSupport.renameProperty( oldName, newName );
500 }
501
502 @Override
503 public void propertyMoved( String name, int oldIndex, int newIndex )
504 {
505 propertyHolderSupport.moveProperty( name, newIndex );
506 }
507 }
508
509 private final class InternalTestRunListener extends TestRunListenerAdapter
510 {
511 @Override
512 public void beforeRun( TestCaseRunner testRunner, TestCaseRunContext runContext )
513 {
514 updateLabelDuringRun();
515 }
516
517 @Override
518 public void afterRun( TestCaseRunner testRunner, TestCaseRunContext runContext )
519 {
520 updateLabelDuringRun();
521 }
522
523 @Override
524 public void afterStep( TestCaseRunner testRunner, TestCaseRunContext runContext, TestStepResult result )
525 {
526 updateLabelDuringRun();
527 }
528
529 @Override
530 public void beforeStep( TestCaseRunner testRunner, TestCaseRunContext runContext, TestStep testStep )
531 {
532 updateLabelDuringRun();
533 }
534 }
535
536 @Override
537 public void resetConfigOnMove( TestStepConfig config )
538 {
539 super.resetConfigOnMove( config );
540
541 stepConfig = ( RunTestCaseStepConfig )config.getConfig().changeType( RunTestCaseStepConfig.type );
542 propertyHolderSupport.resetPropertiesConfig( stepConfig.getProperties() );
543 }
544
545 @Override
546 public void release()
547 {
548 if( targetTestCase != null )
549 {
550 targetTestCase.getTestSuite().removeTestSuiteListener( testSuiteListener );
551 targetTestCase.removeTestPropertyListener( testPropertyListener );
552 }
553
554 super.release();
555 }
556
557 private final class InternalTestSuiteListener extends TestSuiteListenerAdapter
558 {
559 @Override
560 public void testCaseRemoved( TestCase testCase )
561 {
562 setTargetTestCase( findTargetTestCase() );
563 }
564 }
565
566 public WsdlTestCase getTargetTestCase()
567 {
568 return targetTestCase;
569 }
570
571 public void addTestRunListener( TestRunListener listener )
572 {
573 testRunListeners.add( listener );
574 }
575
576 public void removeTestRunListener( TestRunListener listener )
577 {
578 testRunListeners.remove( listener );
579 }
580
581 public WsdlTestCase getRunningTestCase()
582 {
583 return runningTestCase;
584 }
585
586 public WsdlTestCaseRunner getTestCaseRunner()
587 {
588 return testCaseRunner;
589 }
590
591 public RunTestCaseRunModeTypeConfig.Enum getRunMode()
592 {
593 return stepConfig.getRunMode();
594 }
595
596 public void setRunMode( RunTestCaseRunModeTypeConfig.Enum runMode )
597 {
598 stepConfig.setRunMode( runMode );
599 }
600
601 public TestProperty getPropertyAt( int index )
602 {
603 return propertyHolderSupport.getPropertyAt( index );
604 }
605
606 public int getPropertyCount()
607 {
608 return propertyHolderSupport.getPropertyCount();
609 }
610
611 @Override
612 public void resolve( ResolveContext<?> context )
613 {
614 super.resolve( context );
615
616 if( targetTestCase == null )
617 {
618 if( context.hasThisModelItem( this, "Missing Test Case", getTestStepTitle() + "/"
619 + stepConfig.getTargetTestCase() ) )
620 return;
621 context
622 .addPathToResolve( this, "Missing Test Case", getTestStepTitle() + "/" + stepConfig.getTargetTestCase() )
623 .addResolvers( new RunTestCaseRemoveResolver( this ), new ChooseAnotherTestCase( this ),
624 new CreateNewEmptyTestCase( this ) );
625 }
626 else
627 {
628 targetTestCase.resolve( context );
629 if( context.hasThisModelItem( this, "Missing Test Case", getTestStepTitle() + "/"
630 + stepConfig.getTargetTestCase() ) )
631 {
632 context.getPath( this, "Missing Test Case", getTestStepTitle() + "/" + stepConfig.getTargetTestCase() )
633 .setSolved( true );
634 }
635 }
636 }
637 }