/*
* SoapUI, Copyright (C) 2004-2016 SmartBear Software
*
* Licensed under the EUPL, Version 1.1 or - as soon as they will be approved by the European Commission - subsequent
* versions of the EUPL (the "Licence");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://ec.europa.eu/idabc/eupl
*
* Unless required by applicable law or agreed to in writing, software distributed under the Licence is
* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the Licence for the specific language governing permissions and limitations
* under the Licence.
*/
package com.eviware.soapui.impl.wsdl;
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.support.ModelSupport;
import com.eviware.soapui.model.testsuite.TestCase;
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;
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 java.util.UUID;
/**
* 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";
public static final String ICON_NAME = "/test_suite.png";
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, ICON_NAME);
this.project = project;
if (!config.isSetProperties()) {
config.addNewProperties();
}
setPropertiesConfig(config.getProperties());
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);
}
}
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);
}
@Override
public TestCase getTestCaseById(UUID testCaseId) {
return (WsdlTestCase) getWsdlModelItemById(testCases, testCaseId);
}
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.createNewIds(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.createNewIds(testCase);
}
if (index == -1) {
testCases.add(testCase);
} else {
testCases.add(index, testCase);
}
testCase.afterLoad();
if (createCopy) {
testCase.afterCopy(oldTestCase.getTestSuite(), 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;
}
WsdlTestCase oldTestCase = null;
try {
importTestCaseConfig = TestCaseDocumentConfig.Factory.parse(file).getTestCase();
oldTestCase = buildTestCase(TestCaseDocumentConfig.Factory.parse(file).getTestCase(), false);
} 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.createNewIds(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();
WsdlTestSuite oldTestSuite = oldTestCase==null ? null : oldTestCase.getTestSuite();
newTestCase.afterCopy(oldTestSuite, oldTestCase);
testCases.add(newTestCase);
fireTestCaseAdded(newTestCase);
resolveImportedTestCase(newTestCase);
} else {
UISupport.showErrorMessage("Not valid 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, oldTestCase);
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);
}
}
}