/*
* soapUI, copyright (C) 2004-2011 eviware.com
*
* soapUI is free software; you can redistribute it and/or modify it under the
* terms of version 2.1 of the GNU Lesser General Public License as published by
* the Free Software Foundation.
*
* soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details at gnu.org.
*/
package com.eviware.soapui.impl.wsdl;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.eviware.soapui.SoapUI;
import com.eviware.soapui.config.LoadTestConfig;
import com.eviware.soapui.config.SecurityTestConfig;
import com.eviware.soapui.config.TestCaseConfig;
import com.eviware.soapui.config.TestCaseDocumentConfig;
import com.eviware.soapui.config.TestStepSecurityTestConfig;
import com.eviware.soapui.config.TestSuiteConfig;
import com.eviware.soapui.config.TestSuiteRunTypesConfig;
import com.eviware.soapui.config.TestSuiteRunTypesConfig.Enum;
import com.eviware.soapui.impl.wsdl.loadtest.WsdlLoadTest;
import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase;
import com.eviware.soapui.impl.wsdl.testcase.WsdlTestSuiteRunner;
import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestStep;
import com.eviware.soapui.model.ModelItem;
import com.eviware.soapui.model.security.SecurityScan;
import com.eviware.soapui.model.support.ModelSupport;
import com.eviware.soapui.model.testsuite.TestCase;
import com.eviware.soapui.model.testsuite.TestStep;
import com.eviware.soapui.model.testsuite.TestSuite;
import com.eviware.soapui.model.testsuite.TestSuiteListener;
import com.eviware.soapui.model.testsuite.TestSuiteRunContext;
import com.eviware.soapui.model.testsuite.TestSuiteRunListener;
import com.eviware.soapui.model.testsuite.TestSuiteRunner;
import com.eviware.soapui.security.SecurityTest;
import com.eviware.soapui.support.StringUtils;
import com.eviware.soapui.support.UISupport;
import com.eviware.soapui.support.resolver.ResolveDialog;
import com.eviware.soapui.support.scripting.SoapUIScriptEngine;
import com.eviware.soapui.support.scripting.SoapUIScriptEngineRegistry;
import com.eviware.soapui.support.types.StringToObjectMap;
/**
* TestSuite implementation for WSDL projects.
*
* @author Ole.Matzura
*/
public class WsdlTestSuite extends AbstractTestPropertyHolderWsdlModelItem<TestSuiteConfig> implements TestSuite
{
public final static String SETUP_SCRIPT_PROPERTY = WsdlTestSuite.class.getName() + "@setupScript";
public final static String TEARDOWN_SCRIPT_PROPERTY = WsdlTestSuite.class.getName() + "@tearDownScript";
private final WsdlProject project;
private List<WsdlTestCase> testCases = new ArrayList<WsdlTestCase>();
private Set<TestSuiteListener> testSuiteListeners = new HashSet<TestSuiteListener>();
private Set<TestSuiteRunListener> testSuiteRunListeners = new HashSet<TestSuiteRunListener>();
private SoapUIScriptEngine setupScriptEngine;
private SoapUIScriptEngine tearDownScriptEngine;
public WsdlTestSuite( WsdlProject project, TestSuiteConfig config )
{
super( config, project, "/testSuite.gif" );
this.project = project;
List<TestCaseConfig> testCaseConfigs = config.getTestCaseList();
for( int i = 0; i < testCaseConfigs.size(); i++ )
{
testCases.add( buildTestCase( testCaseConfigs.get( i ), false ) );
}
if( !config.isSetRunType() )
config.setRunType( TestSuiteRunTypesConfig.SEQUENTIAL );
for( TestSuiteListener listener : SoapUI.getListenerRegistry().getListeners( TestSuiteListener.class ) )
{
addTestSuiteListener( listener );
}
for( TestSuiteRunListener listener : SoapUI.getListenerRegistry().getListeners( TestSuiteRunListener.class ) )
{
addTestSuiteRunListener( listener );
}
if( !config.isSetProperties() )
config.addNewProperties();
setPropertiesConfig( config.getProperties() );
}
public WsdlTestCase buildTestCase( TestCaseConfig testCaseConfig, boolean forLoadTest )
{
return new WsdlTestCase( this, testCaseConfig, forLoadTest );
}
public TestSuiteRunType getRunType()
{
Enum runType = getConfig().getRunType();
if( runType.equals( TestSuiteRunTypesConfig.PARALLELL ) )
return TestSuiteRunType.PARALLEL;
else
return TestSuiteRunType.SEQUENTIAL;
}
public void setRunType( TestSuiteRunType runType )
{
TestSuiteRunType oldRunType = getRunType();
if( runType == TestSuiteRunType.PARALLEL && oldRunType != TestSuiteRunType.PARALLEL )
{
getConfig().setRunType( TestSuiteRunTypesConfig.PARALLELL );
notifyPropertyChanged( RUNTYPE_PROPERTY, oldRunType, runType );
}
else if( runType == TestSuiteRunType.SEQUENTIAL && oldRunType != TestSuiteRunType.SEQUENTIAL )
{
getConfig().setRunType( TestSuiteRunTypesConfig.SEQUENTIAL );
notifyPropertyChanged( RUNTYPE_PROPERTY, oldRunType, runType );
}
}
public WsdlProject getProject()
{
return project;
}
public int getTestCaseCount()
{
return testCases.size();
}
public WsdlTestCase getTestCaseAt( int index )
{
return testCases.get( index );
}
public WsdlTestCase getTestCaseByName( String testCaseName )
{
return ( WsdlTestCase )getWsdlModelItemByName( testCases, testCaseName );
}
public WsdlTestCase cloneTestCase( WsdlTestCase testCase, String name )
{
testCase.beforeSave();
TestCaseConfig newTestCase = getConfig().addNewTestCase();
newTestCase.set( testCase.getConfig() );
newTestCase.setName( name );
WsdlTestCase newWsdlTestCase = buildTestCase( newTestCase, false );
ModelSupport.unsetIds( newWsdlTestCase );
newWsdlTestCase.afterLoad();
testCases.add( newWsdlTestCase );
fireTestCaseAdded( newWsdlTestCase );
return newWsdlTestCase;
}
public WsdlTestCase addNewTestCase( String name )
{
WsdlTestCase testCase = buildTestCase( getConfig().addNewTestCase(), false );
testCase.setName( name );
testCase.setFailOnError( true );
testCase.setSearchProperties( true );
testCases.add( testCase );
fireTestCaseAdded( testCase );
return testCase;
}
public WsdlTestCase importTestCase( WsdlTestCase testCase, String name, int index, boolean includeLoadTests,
boolean includeSecurityTests, boolean createCopy )
{
testCase.beforeSave();
if( index >= testCases.size() )
index = -1;
TestCaseConfig testCaseConfig = index == -1 ? ( TestCaseConfig )getConfig().addNewTestCase().set(
testCase.getConfig().copy() ) : ( TestCaseConfig )getConfig().insertNewTestCase( index ).set(
testCase.getConfig().copy() );
testCaseConfig.setName( name );
if( !includeLoadTests )
testCaseConfig.setLoadTestArray( new LoadTestConfig[0] );
if( createCopy )
testCaseConfig.setSecurityTestArray( new SecurityTestConfig[0] );
WsdlTestCase oldTestCase = testCase;
testCase = buildTestCase( testCaseConfig, false );
if( createCopy )
{
ModelSupport.unsetIds( testCase );
}
if( index == -1 )
testCases.add( testCase );
else
testCases.add( index, testCase );
testCase.afterLoad();
if( createCopy )
{
testCase.afterCopy( null, oldTestCase );
if( includeSecurityTests )
{
testCase.importSecurityTests( null, oldTestCase );
}
}
fireTestCaseAdded( testCase );
resolveImportedTestCase( testCase );
return testCase;
}
public void removeTestCase( WsdlTestCase testCase )
{
int ix = testCases.indexOf( testCase );
testCases.remove( ix );
try
{
fireTestCaseRemoved( testCase );
}
finally
{
testCase.release();
getConfig().removeTestCase( ix );
}
}
public void fireTestCaseAdded( WsdlTestCase testCase )
{
TestSuiteListener[] a = testSuiteListeners.toArray( new TestSuiteListener[testSuiteListeners.size()] );
for( int c = 0; c < a.length; c++ )
{
a[c].testCaseAdded( testCase );
}
}
public void fireTestCaseRemoved( WsdlTestCase testCase )
{
TestSuiteListener[] a = testSuiteListeners.toArray( new TestSuiteListener[testSuiteListeners.size()] );
for( int c = 0; c < a.length; c++ )
{
a[c].testCaseRemoved( testCase );
}
}
private void fireTestCaseMoved( WsdlTestCase testCase, int ix, int offset )
{
TestSuiteListener[] a = testSuiteListeners.toArray( new TestSuiteListener[testSuiteListeners.size()] );
for( int c = 0; c < a.length; c++ )
{
a[c].testCaseMoved( testCase, ix, offset );
}
}
public void fireTestStepAdded( WsdlTestStep testStep, int index )
{
TestSuiteListener[] a = testSuiteListeners.toArray( new TestSuiteListener[testSuiteListeners.size()] );
for( int c = 0; c < a.length; c++ )
{
a[c].testStepAdded( testStep, index );
}
}
public void fireTestStepRemoved( WsdlTestStep testStep, int ix )
{
TestSuiteListener[] a = testSuiteListeners.toArray( new TestSuiteListener[testSuiteListeners.size()] );
for( int c = 0; c < a.length; c++ )
{
a[c].testStepRemoved( testStep, ix );
}
}
public void fireTestStepMoved( WsdlTestStep testStep, int ix, int offset )
{
TestSuiteListener[] a = testSuiteListeners.toArray( new TestSuiteListener[testSuiteListeners.size()] );
for( int c = 0; c < a.length; c++ )
{
a[c].testStepMoved( testStep, ix, offset );
}
}
public void fireLoadTestAdded( WsdlLoadTest loadTest )
{
TestSuiteListener[] a = testSuiteListeners.toArray( new TestSuiteListener[testSuiteListeners.size()] );
for( int c = 0; c < a.length; c++ )
{
a[c].loadTestAdded( loadTest );
}
}
public void fireLoadTestRemoved( WsdlLoadTest loadTest )
{
TestSuiteListener[] a = testSuiteListeners.toArray( new TestSuiteListener[testSuiteListeners.size()] );
for( int c = 0; c < a.length; c++ )
{
a[c].loadTestRemoved( loadTest );
}
}
public void addTestSuiteListener( TestSuiteListener listener )
{
testSuiteListeners.add( listener );
}
public void removeTestSuiteListener( TestSuiteListener listener )
{
testSuiteListeners.remove( listener );
}
public void addTestSuiteRunListener( TestSuiteRunListener listener )
{
testSuiteRunListeners.add( listener );
}
public void removeTestSuiteRunListener( TestSuiteRunListener listener )
{
testSuiteRunListeners.remove( listener );
}
public int getTestCaseIndex( TestCase testCase )
{
return testCases.indexOf( testCase );
}
@Override
public void release()
{
super.release();
for( WsdlTestCase testCase : testCases )
testCase.release();
testSuiteListeners.clear();
if( setupScriptEngine != null )
setupScriptEngine.release();
if( tearDownScriptEngine != null )
tearDownScriptEngine.release();
}
public List<TestCase> getTestCaseList()
{
List<TestCase> result = new ArrayList<TestCase>();
for( WsdlTestCase testCase : testCases )
result.add( testCase );
return result;
}
public Map<String, TestCase> getTestCases()
{
Map<String, TestCase> result = new HashMap<String, TestCase>();
for( TestCase testCase : testCases )
result.put( testCase.getName(), testCase );
return result;
}
/**
* Moves a testcase by the specified offset, a bit awkward since xmlbeans
* doesn't support reordering of arrays, we need to create copies of the
* contained XmlObjects
*
* @param ix
* @param offset
*/
public WsdlTestCase moveTestCase( int ix, int offset )
{
WsdlTestCase testCase = testCases.get( ix );
if( offset == 0 )
return testCase;
testCases.remove( ix );
testCases.add( ix + offset, testCase );
TestCaseConfig[] configs = new TestCaseConfig[testCases.size()];
for( int c = 0; c < testCases.size(); c++ )
{
if( offset > 0 )
{
if( c < ix )
configs[c] = ( TestCaseConfig )getConfig().getTestCaseArray( c ).copy();
else if( c < ( ix + offset ) )
configs[c] = ( TestCaseConfig )getConfig().getTestCaseArray( c + 1 ).copy();
else if( c == ix + offset )
configs[c] = ( TestCaseConfig )getConfig().getTestCaseArray( ix ).copy();
else
configs[c] = ( TestCaseConfig )getConfig().getTestCaseArray( c ).copy();
}
else
{
if( c < ix + offset )
configs[c] = ( TestCaseConfig )getConfig().getTestCaseArray( c ).copy();
else if( c == ix + offset )
configs[c] = ( TestCaseConfig )getConfig().getTestCaseArray( ix ).copy();
else if( c <= ix )
configs[c] = ( TestCaseConfig )getConfig().getTestCaseArray( c - 1 ).copy();
else
configs[c] = ( TestCaseConfig )getConfig().getTestCaseArray( c ).copy();
}
}
getConfig().setTestCaseArray( configs );
for( int c = 0; c < configs.length; c++ )
{
testCases.get( c ).resetConfigOnMove( getConfig().getTestCaseArray( c ) );
}
fireTestCaseMoved( testCase, ix, offset );
return testCase;
}
public int getIndexOfTestCase( TestCase testCase )
{
return testCases.indexOf( testCase );
}
public List<? extends ModelItem> getChildren()
{
return getTestCaseList();
}
public void setSetupScript( String script )
{
String oldScript = getSetupScript();
if( !getConfig().isSetSetupScript() )
getConfig().addNewSetupScript();
getConfig().getSetupScript().setStringValue( script );
if( setupScriptEngine != null )
setupScriptEngine.setScript( script );
notifyPropertyChanged( SETUP_SCRIPT_PROPERTY, oldScript, script );
}
public String getSetupScript()
{
return getConfig().isSetSetupScript() ? getConfig().getSetupScript().getStringValue() : null;
}
public void setTearDownScript( String script )
{
String oldScript = getTearDownScript();
if( !getConfig().isSetTearDownScript() )
getConfig().addNewTearDownScript();
getConfig().getTearDownScript().setStringValue( script );
if( tearDownScriptEngine != null )
tearDownScriptEngine.setScript( script );
notifyPropertyChanged( TEARDOWN_SCRIPT_PROPERTY, oldScript, script );
}
public String getTearDownScript()
{
return getConfig().isSetTearDownScript() ? getConfig().getTearDownScript().getStringValue() : null;
}
public Object runSetupScript( TestSuiteRunContext context, TestSuiteRunner runner ) throws Exception
{
String script = getSetupScript();
if( StringUtils.isNullOrEmpty( script ) )
return null;
if( setupScriptEngine == null )
{
setupScriptEngine = SoapUIScriptEngineRegistry.create( this );
setupScriptEngine.setScript( script );
}
setupScriptEngine.setVariable( "runner", runner );
setupScriptEngine.setVariable( "context", context );
setupScriptEngine.setVariable( "testSuite", this );
setupScriptEngine.setVariable( "log", SoapUI.ensureGroovyLog() );
return setupScriptEngine.run();
}
public Object runTearDownScript( TestSuiteRunContext context, TestSuiteRunner runner ) throws Exception
{
String script = getTearDownScript();
if( StringUtils.isNullOrEmpty( script ) )
return null;
if( tearDownScriptEngine == null )
{
tearDownScriptEngine = SoapUIScriptEngineRegistry.create( this );
tearDownScriptEngine.setScript( script );
}
tearDownScriptEngine.setVariable( "runner", runner );
tearDownScriptEngine.setVariable( "context", context );
tearDownScriptEngine.setVariable( "testSuite", this );
tearDownScriptEngine.setVariable( "log", SoapUI.ensureGroovyLog() );
return tearDownScriptEngine.run();
}
@Override
public void setName( String name )
{
String oldLabel = getLabel();
super.setName( name );
String label = getLabel();
if( oldLabel != null && !oldLabel.equals( label ) )
{
notifyPropertyChanged( LABEL_PROPERTY, oldLabel, label );
}
}
public String getLabel()
{
String name = getName();
if( isDisabled() )
return name + " (disabled)";
else
return name;
}
public boolean isFailOnErrors()
{
return getConfig().getFailOnErrors();
}
public void setFailOnErrors( boolean failOnErrors )
{
getConfig().setFailOnErrors( failOnErrors );
}
public boolean isAbortOnError()
{
return getConfig().getAbortOnError();
}
public void setAbortOnError( boolean abortOnError )
{
getConfig().setAbortOnError( abortOnError );
}
public long getTimeout()
{
return getConfig().getTimeout();
}
public void setTimeout( long timeout )
{
getConfig().setTimeout( timeout );
}
public boolean isDisabled()
{
return getConfig().getDisabled();
}
public void setDisabled( boolean disabled )
{
String oldLabel = getLabel();
boolean oldDisabled = isDisabled();
if( oldDisabled == disabled )
return;
if( disabled )
getConfig().setDisabled( disabled );
else if( getConfig().isSetDisabled() )
getConfig().unsetDisabled();
notifyPropertyChanged( DISABLED_PROPERTY, oldDisabled, disabled );
String label = getLabel();
if( !oldLabel.equals( label ) )
notifyPropertyChanged( LABEL_PROPERTY, oldLabel, label );
}
public void replace( WsdlTestCase testCase, TestCaseConfig newTestCase )
{
int ix = testCases.indexOf( testCase );
testCases.remove( ix );
try
{
fireTestCaseRemoved( testCase );
}
finally
{
testCase.release();
getConfig().removeTestCase( ix );
}
TestCaseConfig newConfig = ( TestCaseConfig )getConfig().insertNewTestCase( ix ).set( newTestCase ).changeType(
TestCaseConfig.type );
testCase = buildTestCase( newConfig, false );
testCases.add( ix, testCase );
testCase.afterLoad();
fireTestCaseAdded( testCase );
resolveImportedTestCase( testCase );
}
public void importTestCase( File file )
{
TestCaseConfig importTestCaseConfig = null;
if( !file.exists() )
{
UISupport.showErrorMessage( "Error loading test case " );
return;
}
try
{
importTestCaseConfig = TestCaseDocumentConfig.Factory.parse( file ).getTestCase();
}
catch( Exception e )
{
SoapUI.logError( e );
}
if( importTestCaseConfig != null )
{
TestCaseConfig newConfig = ( TestCaseConfig )getConfig().addNewTestCase().set( importTestCaseConfig )
.changeType( TestCaseConfig.type );
WsdlTestCase newTestCase = buildTestCase( newConfig, false );
ModelSupport.unsetIds( newTestCase );
/*
* security test keeps reference to test step by id, which gets changed
* during importing, so old values needs to be rewritten to new ones.
*
* Create tarnsition table ( old id , new id ) and use it to replace
* all old ids in new imported test case.
*/
LinkedHashMap<String, String> oldNewIds = new LinkedHashMap<String, String>();
for( int cnt = 0; cnt < importTestCaseConfig.getTestStepList().size(); cnt++ )
oldNewIds.put( importTestCaseConfig.getTestStepList().get( cnt ).getId(), newTestCase.getTestStepList()
.get( cnt ).getId() );
for( SecurityTest scan : newTestCase.getSecurityTests().values() )
for( TestStepSecurityTestConfig secStepConfig : scan.getConfig().getTestStepSecurityTestList() )
if( oldNewIds.containsKey( secStepConfig.getTestStepId() ) )
secStepConfig.setTestStepId( oldNewIds.get( secStepConfig.getTestStepId() ) );
newTestCase.afterLoad();
testCases.add( newTestCase );
fireTestCaseAdded( newTestCase );
resolveImportedTestCase( newTestCase );
}
else
{
UISupport.showErrorMessage( "Not valild test case xml" );
}
}
private void resolveImportedTestCase( WsdlTestCase newTestCase )
{
ResolveDialog resolver = new ResolveDialog( "Validate TestCase", "Checks TestCase for inconsistencies", null );
resolver.setShowOkMessage( false );
resolver.resolve( newTestCase );
}
public void export( File file )
{
try
{
this.getConfig().newCursor().save( file );
}
catch( IOException e )
{
e.printStackTrace();
}
}
public void afterCopy( WsdlTestSuite oldTestSuite )
{
for( int i = 0; i < testCases.size(); i++ )
{
WsdlTestCase testCase = getTestCaseAt( i );
WsdlTestCase oldTestCase = oldTestSuite.getTestCaseAt( i );
testCase.afterCopy( oldTestSuite, null );
testCase.importSecurityTests( oldTestSuite, oldTestCase );
}
}
public WsdlTestSuiteRunner run( StringToObjectMap context, boolean async )
{
WsdlTestSuiteRunner testSuiteRunner = new WsdlTestSuiteRunner( this, context );
testSuiteRunner.start( async );
return testSuiteRunner;
}
public TestSuiteRunListener[] getTestSuiteRunListeners()
{
return testSuiteRunListeners.toArray( new TestSuiteRunListener[testSuiteRunListeners.size()] );
}
public void resetConfigOnMove( TestSuiteConfig testSuiteConfig )
{
setConfig( testSuiteConfig );
List<TestCaseConfig> configs = getConfig().getTestCaseList();
for( int c = 0; c < configs.size(); c++ )
{
testCases.get( c ).resetConfigOnMove( configs.get( c ) );
}
setPropertiesConfig( testSuiteConfig.getProperties() );
}
public void fireSecurityTestAdded( SecurityTest securityTest )
{
TestSuiteListener[] a = testSuiteListeners.toArray( new TestSuiteListener[testSuiteListeners.size()] );
for( int c = 0; c < a.length; c++ )
{
a[c].securityTestAdded( securityTest );
}
}
public void fireSecurityTestRemoved( SecurityTest securityTest )
{
TestSuiteListener[] a = testSuiteListeners.toArray( new TestSuiteListener[testSuiteListeners.size()] );
for( int c = 0; c < a.length; c++ )
{
a[c].securityTestRemoved( securityTest );
}
}
}