/* * 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.WsdlProject; import com.eviware.soapui.impl.wsdl.WsdlTestSuite; import com.eviware.soapui.impl.wsdl.support.AbstractTestRunner; import com.eviware.soapui.model.project.Project; import com.eviware.soapui.model.propertyexpansion.DefaultPropertyExpansionContext; import com.eviware.soapui.model.support.TestSuiteRunListenerAdapter; import com.eviware.soapui.model.testsuite.ProjectRunListener; import com.eviware.soapui.model.testsuite.ProjectRunner; import com.eviware.soapui.model.testsuite.TestSuite; import com.eviware.soapui.model.testsuite.TestSuite.TestSuiteRunType; 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.support.types.StringToObjectMap; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Set; public class WsdlProjectRunner extends AbstractTestRunner<WsdlProject, WsdlProjectRunContext> implements ProjectRunner { private ProjectRunListener[] listeners; private Set<TestSuiteRunner> finishedRunners = new HashSet<TestSuiteRunner>(); private Set<TestSuiteRunner> activeRunners = new HashSet<TestSuiteRunner>(); private int currentTestSuiteIndex; private WsdlTestSuite currentTestSuite; private TestSuiteRunListener internalTestRunListener = new InternalTestSuiteRunListener(); public WsdlProjectRunner(WsdlProject project, StringToObjectMap properties) { super(project, properties); } public WsdlProjectRunContext createContext(StringToObjectMap properties) { return new WsdlProjectRunContext(this, properties); } public void onCancel(String reason) { for (TestSuiteRunner runner : activeRunners.toArray(new TestSuiteRunner[activeRunners.size()])) { runner.cancel(reason); } } public void onFail(String reason) { for (TestSuiteRunner runner : activeRunners.toArray(new TestSuiteRunner[activeRunners.size()])) { runner.fail(reason); } } public void internalRun(WsdlProjectRunContext runContext) throws Exception { WsdlProject project = getTestRunnable(); listeners = project.getProjectRunListeners(); project.runBeforeRunScript(runContext, this); if (!isRunning()) { return; } if (project.getTimeout() > 0) { startTimeoutTimer(project.getTimeout()); } notifyBeforeRun(); if (!isRunning()) { return; } if (project.getRunType() == TestSuiteRunType.SEQUENTIAL) { runSequential(project, runContext); } else if (project.getRunType() == TestSuiteRunType.PARALLEL) { runParallel(project, runContext); } } private void runParallel(WsdlProject project, WsdlProjectRunContext runContext) { currentTestSuiteIndex = -1; currentTestSuite = null; for (TestSuite testSuite : project.getTestSuiteList()) { if (!testSuite.isDisabled()) { testSuite.addTestSuiteRunListener(internalTestRunListener); notifyBeforeRunTestSuite(testSuite); runTestSuite((WsdlTestSuite) testSuite, true); } } try { synchronized (activeRunners) { activeRunners.wait(); } } catch (InterruptedException e) { e.printStackTrace(); } } private void runSequential(WsdlProject project, WsdlProjectRunContext runContext) { currentTestSuiteIndex = 0; for (; isRunning() && currentTestSuiteIndex < project.getTestSuiteCount(); currentTestSuiteIndex++) { currentTestSuite = (WsdlTestSuite) project.getTestSuiteAt(currentTestSuiteIndex); if (!currentTestSuite.isDisabled()) { notifyBeforeRunTestSuite(currentTestSuite); WsdlTestSuiteRunner testSuiteRunner = runTestSuite(currentTestSuite, false); activeRunners.remove(testSuiteRunner); finishedRunners.add(testSuiteRunner); notifyAfterRunTestSuite(testSuiteRunner); } } updateStatus(); } private void updateStatus() { for (TestSuiteRunner runner : finishedRunners) { if (runner.getStatus() == Status.FAILED) { setStatus(Status.FAILED); break; } } } private WsdlTestSuiteRunner runTestSuite(WsdlTestSuite testSuite, boolean async) { DefaultPropertyExpansionContext properties = (DefaultPropertyExpansionContext) getRunContext().getProperties(); properties.put("#ProjectRunner#", this); // this is here for backwards compatibility, should be removed eventually properties.put("#TestSuiteRunner#", this); WsdlTestSuiteRunner currentRunner = testSuite.run(properties, true); activeRunners.add(currentRunner); if (!async) { currentRunner.waitUntilFinished(); } return currentRunner; } protected void internalFinally(WsdlProjectRunContext runContext) { WsdlProject project = getTestRunnable(); try { project.runAfterRunScript(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 notifyAfterRunTestSuite(TestSuiteRunner testSuiteRunner) { if (listeners == null || listeners.length == 0) { return; } for (int i = 0; i < listeners.length; i++) { listeners[i].afterTestSuite(this, getRunContext(), testSuiteRunner); } } private void notifyBeforeRunTestSuite(TestSuite testSuite) { if (listeners == null || listeners.length == 0) { return; } for (int i = 0; i < listeners.length; i++) { listeners[i].beforeTestSuite(this, getRunContext(), testSuite); } } public List<TestSuiteRunner> getResults() { return Arrays.asList(finishedRunners.toArray(new TestSuiteRunner[finishedRunners.size()])); } protected void finishRunner(TestSuiteRunner testRunner) { notifyAfterRunTestSuite(testRunner); activeRunners.remove(testRunner); finishedRunners.add(testRunner); testRunner.getTestSuite().removeTestSuiteRunListener(internalTestRunListener); if (activeRunners.isEmpty()) { updateStatus(); synchronized (activeRunners) { activeRunners.notify(); } } } private class InternalTestSuiteRunListener extends TestSuiteRunListenerAdapter { @Override public void afterRun(TestSuiteRunner testRunner, TestSuiteRunContext runContext) { finishRunner(testRunner); } } public Project getProject() { return getTestRunnable(); } }