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