/*
* 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.testcase;
import com.eviware.soapui.SoapUI;
import com.eviware.soapui.impl.wsdl.WsdlTestSuite;
import com.eviware.soapui.impl.wsdl.support.AbstractTestRunner;
import com.eviware.soapui.model.propertyexpansion.DefaultPropertyExpansionContext;
import com.eviware.soapui.model.support.TestRunListenerAdapter;
import com.eviware.soapui.model.testsuite.TestCase;
import com.eviware.soapui.model.testsuite.TestCaseRunContext;
import com.eviware.soapui.model.testsuite.TestCaseRunner;
import com.eviware.soapui.model.testsuite.TestRunListener;
import com.eviware.soapui.model.testsuite.TestSuite;
import com.eviware.soapui.model.testsuite.TestSuite.TestSuiteRunType;
import com.eviware.soapui.model.testsuite.TestSuiteRunListener;
import com.eviware.soapui.model.testsuite.TestSuiteRunner;
import com.eviware.soapui.support.types.StringToObjectMap;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* WSDL TestCase Runner - runs all steps in a testcase and collects performance
* data
*
* @author Ole.Matzura
*/
public class WsdlTestSuiteRunner extends AbstractTestRunner<WsdlTestSuite, WsdlTestSuiteRunContext> implements
TestSuiteRunner {
private TestSuiteRunListener[] listeners;
private Set<TestCaseRunner> finishedRunners = new HashSet<TestCaseRunner>();
private Set<TestCaseRunner> activeRunners = new HashSet<TestCaseRunner>();
private int currentTestCaseIndex;
private WsdlTestCase currentTestCase;
private TestRunListener parallellTestRunListener = new ParallellTestRunListener();
public WsdlTestSuiteRunner(WsdlTestSuite testSuite, StringToObjectMap properties) {
super(testSuite, properties);
}
public WsdlTestSuiteRunContext createContext(StringToObjectMap properties) {
return new WsdlTestSuiteRunContext(this, properties);
}
public void onCancel(String reason) {
for (TestCaseRunner runner : activeRunners.toArray(new TestCaseRunner[activeRunners.size()])) {
runner.cancel(reason);
}
}
public void onFail(String reason) {
for (TestCaseRunner runner : activeRunners.toArray(new TestCaseRunner[activeRunners.size()])) {
runner.fail(reason);
}
}
public void internalRun(WsdlTestSuiteRunContext runContext) throws Exception {
WsdlTestSuite testSuite = getTestRunnable();
listeners = testSuite.getTestSuiteRunListeners();
testSuite.runSetupScript(runContext, this);
if (!isRunning()) {
return;
}
if (testSuite.getTimeout() > 0) {
startTimeoutTimer(testSuite.getTimeout());
}
notifyBeforeRun();
if (!isRunning()) {
return;
}
if (testSuite.getRunType() == TestSuiteRunType.SEQUENTIAL) {
runSequential(testSuite, runContext);
} else if (testSuite.getRunType() == TestSuiteRunType.PARALLEL) {
runParallel(testSuite, runContext);
}
}
private void runParallel(WsdlTestSuite testSuite, WsdlTestSuiteRunContext runContext) {
currentTestCaseIndex = -1;
currentTestCase = null;
for (TestCase testCase : testSuite.getTestCaseList()) {
if (!testCase.isDisabled()) {
testCase.addTestRunListener(parallellTestRunListener);
notifyBeforeRunTestCase(testCase);
runTestCase((WsdlTestCase) testCase, true);
}
}
try {
synchronized (activeRunners) {
activeRunners.wait();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private void runSequential(WsdlTestSuite testSuite, WsdlTestSuiteRunContext runContext) {
currentTestCaseIndex = 0;
for (; isRunning() && currentTestCaseIndex < testSuite.getTestCaseCount(); currentTestCaseIndex++) {
currentTestCase = testSuite.getTestCaseAt(currentTestCaseIndex);
if (!currentTestCase.isDisabled()) {
notifyBeforeRunTestCase(currentTestCase);
TestCaseRunner testCaseRunner = runTestCase(currentTestCase, false);
activeRunners.remove(testCaseRunner);
finishedRunners.add(testCaseRunner);
notifyAfterRunTestCase(testCaseRunner);
}
}
updateStatus();
}
private void updateStatus() {
for (TestCaseRunner runner : finishedRunners) {
if (runner.getStatus() == Status.FAILED) {
setStatus(Status.FAILED);
break;
}
}
}
private TestCaseRunner runTestCase(WsdlTestCase testCaseAt, boolean async) {
DefaultPropertyExpansionContext properties = (DefaultPropertyExpansionContext) getRunContext().getProperties();
properties.put("#TestSuiteRunner#", this);
TestCaseRunner currentRunner = testCaseAt.run(properties, true);
activeRunners.add(currentRunner);
if (!async) {
currentRunner.waitUntilFinished();
}
return currentRunner;
}
protected void internalFinally(WsdlTestSuiteRunContext runContext) {
WsdlTestSuite testSuite = getTestRunnable();
try {
testSuite.runTearDownScript(runContext, this);
} catch (Exception e) {
SoapUI.logError(e);
}
notifyAfterRun();
runContext.clear();
listeners = null;
}
private void notifyAfterRun() {
if (listeners == null || listeners.length == 0) {
return;
}
for (int i = 0; i < listeners.length; i++) {
listeners[i].afterRun(this, getRunContext());
}
}
private void notifyBeforeRun() {
if (listeners == null || listeners.length == 0) {
return;
}
for (int i = 0; i < listeners.length; i++) {
listeners[i].beforeRun(this, getRunContext());
}
}
private void notifyAfterRunTestCase(TestCaseRunner testCaseRunner) {
if (listeners == null || listeners.length == 0) {
return;
}
for (int i = 0; i < listeners.length; i++) {
listeners[i].afterTestCase(this, getRunContext(), testCaseRunner);
}
}
private void notifyBeforeRunTestCase(TestCase testCase) {
if (listeners == null || listeners.length == 0) {
return;
}
for (int i = 0; i < listeners.length; i++) {
listeners[i].beforeTestCase(this, getRunContext(), testCase);
}
}
public TestSuite getTestSuite() {
return getTestRunnable();
}
public List<TestCaseRunner> getResults() {
return Arrays.asList(finishedRunners.toArray(new TestCaseRunner[finishedRunners.size()]));
}
public int getCurrentTestCaseIndex() {
return currentTestCaseIndex;
}
public WsdlTestCase getCurrentTestCase() {
return currentTestCase;
}
private class ParallellTestRunListener extends TestRunListenerAdapter {
@Override
public void afterRun(TestCaseRunner testRunner, TestCaseRunContext runContext) {
notifyAfterRunTestCase(testRunner);
activeRunners.remove(testRunner);
finishedRunners.add(testRunner);
testRunner.getTestCase().removeTestRunListener(parallellTestRunListener);
if (activeRunners.isEmpty()) {
updateStatus();
synchronized (activeRunners) {
activeRunners.notify();
}
}
}
}
}