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