/******************************************************************************* * Copyright (c) 2004, 2010 BREDEX GmbH. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * BREDEX GmbH - initial API and implementation and/or initial documentation *******************************************************************************/ package org.eclipse.jubula.app.testexec.core; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.StringWriter; import java.rmi.UnknownHostException; import java.util.Date; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.Timer; import java.util.TimerTask; import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.Validate; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.jubula.app.testexec.i18n.Messages; import org.eclipse.jubula.autagent.AutStarter; import org.eclipse.jubula.autagent.AutStarter.Verbosity; import org.eclipse.jubula.client.cmd.AbstractCmdlineClient; import org.eclipse.jubula.client.cmd.JobConfiguration; import org.eclipse.jubula.client.core.ClientTest; import org.eclipse.jubula.client.core.IClientTest; import org.eclipse.jubula.client.core.agent.AutAgentRegistration; import org.eclipse.jubula.client.core.agent.AutRegistrationEvent; import org.eclipse.jubula.client.core.agent.AutRegistrationEvent.RegistrationStatus; import org.eclipse.jubula.client.core.agent.IAutRegistrationListener; import org.eclipse.jubula.client.core.businessprocess.ExternalTestDataBP; import org.eclipse.jubula.client.core.businessprocess.ITestExecutionEventListener; import org.eclipse.jubula.client.core.businessprocess.TestExecution; import org.eclipse.jubula.client.core.businessprocess.TestExecution.PauseMode; import org.eclipse.jubula.client.core.businessprocess.TestExecutionEvent; import org.eclipse.jubula.client.core.businessprocess.TestResultReportNamer; import org.eclipse.jubula.client.core.businessprocess.compcheck.CompletenessGuard; import org.eclipse.jubula.client.core.businessprocess.problems.IProblem; import org.eclipse.jubula.client.core.businessprocess.problems.ProblemFactory; import org.eclipse.jubula.client.core.constants.TestExecutionConstants; import org.eclipse.jubula.client.core.events.AUTEvent; import org.eclipse.jubula.client.core.events.AUTServerEvent; import org.eclipse.jubula.client.core.events.AutAgentEvent; import org.eclipse.jubula.client.core.events.IAUTEventListener; import org.eclipse.jubula.client.core.events.IAUTServerEventListener; import org.eclipse.jubula.client.core.events.IServerEventListener; import org.eclipse.jubula.client.core.events.ServerEvent; import org.eclipse.jubula.client.core.model.IAUTConfigPO; import org.eclipse.jubula.client.core.model.IAUTMainPO; import org.eclipse.jubula.client.core.model.IAbstractContainerPO; import org.eclipse.jubula.client.core.model.ICapPO; import org.eclipse.jubula.client.core.model.IConditionalStatementPO; import org.eclipse.jubula.client.core.model.IDoWhilePO; import org.eclipse.jubula.client.core.model.IEventExecTestCasePO; import org.eclipse.jubula.client.core.model.IExecStackModificationListener; import org.eclipse.jubula.client.core.model.IExecTestCasePO; import org.eclipse.jubula.client.core.model.IIteratePO; import org.eclipse.jubula.client.core.model.INodePO; import org.eclipse.jubula.client.core.model.IProjectPO; import org.eclipse.jubula.client.core.model.IRefTestSuitePO; import org.eclipse.jubula.client.core.model.ITestSuitePO; import org.eclipse.jubula.client.core.model.IWhileDoPO; import org.eclipse.jubula.client.core.model.ReentryProperty; import org.eclipse.jubula.client.core.persistence.GeneralStorage; import org.eclipse.jubula.client.core.persistence.Persistor; import org.eclipse.jubula.client.core.persistence.ProjectPM; import org.eclipse.jubula.client.core.utils.AbstractNonPostOperatingTreeNodeOperation; import org.eclipse.jubula.client.core.utils.ITreeTraverserContext; import org.eclipse.jubula.client.core.utils.NodeNameUtil; import org.eclipse.jubula.client.core.utils.TreeTraverser; import org.eclipse.jubula.client.internal.AutAgentConnection; import org.eclipse.jubula.toolkit.common.exception.ToolkitPluginException; import org.eclipse.jubula.tools.internal.constants.AutConfigConstants; import org.eclipse.jubula.tools.internal.constants.StringConstants; import org.eclipse.jubula.tools.internal.constants.TimeoutConstants; import org.eclipse.jubula.tools.internal.exception.CommunicationException; import org.eclipse.jubula.tools.internal.exception.JBException; import org.eclipse.jubula.tools.internal.exception.JBVersionException; import org.eclipse.jubula.tools.internal.i18n.I18n; import org.eclipse.jubula.tools.internal.messagehandling.MessageIDs; import org.eclipse.jubula.tools.internal.registration.AutIdentifier; import org.eclipse.jubula.tools.internal.utils.FileUtils; import org.eclipse.jubula.tools.internal.utils.IsAliveThread; import org.eclipse.jubula.tools.internal.utils.NetUtil; import org.eclipse.jubula.tools.internal.utils.TimeUtil; import org.eclipse.osgi.util.NLS; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * This controller offers methods to create batch jobs from file * and to execute jobs. * * @author BREDEX GmbH * @created Mar 29, 2006 */ public class ExecutionController implements IAUTServerEventListener, IServerEventListener, IAUTEventListener, ITestExecutionEventListener, IAutRegistrationListener { /** * @author BREDEX GmbH * @created Oct 16, 2009 */ private final class WatchdogTimer extends IsAliveThread { /** when should the run be finished? */ private long m_stoptime; /** should the time stop */ private boolean m_abort = false; /** * @param timeout Time in seconds the watchdog should wait before * aborting the run. */ public WatchdogTimer(int timeout) { super(Messages.WatchdogTimer); setDaemon(true); m_stoptime = new Date().getTime(); m_stoptime += timeout * 1000; } /** * {@inheritDoc} */ @SuppressWarnings("synthetic-access") @Override public void run() { do { TimeUtil.delay(1000); if (m_abort) { return; } } while (new Date().getTime() < m_stoptime); sysErr(Messages.ExecutionControllerAbort); ClientTest.instance().stopTestExecution(); stopProcessing(); // wait 30 seconds, then exit the whole program TimeUtil.delay(30000); if (!m_abort) { System.exit(1); } } /** * abort this watchdog */ public void abort() { m_abort = true; this.interrupt(); } } /** * @author BREDEX GmbH */ private final class CollectAllErrorsOperation extends AbstractNonPostOperatingTreeNodeOperation<INodePO> { /** the errors to show */ private Set<IProblem> m_errorsToShow = new HashSet<IProblem>(); /** {@inheritDoc} */ public boolean operate(ITreeTraverserContext<INodePO> ctx, INodePO parent, INodePO node, boolean alreadyVisited) { if (ProblemFactory.hasProblem(node)) { for (IProblem problem : node.getProblems()) { if (problem.getStatus().getSeverity() == IStatus.ERROR) { getErrorsToShow().add(problem); } } } return node.isActive(); } /** @return the m_errorsToShow */ public Set<IProblem> getErrorsToShow() { return m_errorsToShow; } } /** * Name of the environment variable that defines the time the client should * wait during AUT startup process. */ private static final String AUT_STARTUP_DELAY_VAR = "TEST_AUT_STARTUP_DELAY"; //$NON-NLS-1$ /** * default time to wait during startup process */ private static final int AUT_STARTUP_DELAY_DEFAULT = 5000; /** the logger */ private static final Logger LOG = LoggerFactory.getLogger(ExecutionController.class); /** instance of controller */ private static ExecutionController instance; /** configuration of desired job */ private JobConfiguration m_job; /** true if client is processing a job */ private boolean m_idle = false; /** true if ITE is currently executing a test suite */ private boolean m_isTestSuiteRunning = false; /** true if this is the first time the AUT is being started for the current test suite */ private boolean m_isFirstAutStart = true; /** true if test should be reported as successful */ private boolean m_noErrorWhileExecution = true; /** true if client sends a shutdown command to end test execution */ private boolean m_shutdown = false; /** * true if fatal error occurred, and processing of the batch process must * be stopped */ private boolean m_stopProcessing = false; /** process for watching test execution */ private TestExecutionWatcher m_progress = new TestExecutionWatcher(); /** the ID of the AUT that was started for test execution */ private AutIdentifier m_startedAutId = null; /** private constructor */ private ExecutionController() { IClientTest clientTest = ClientTest.instance(); clientTest.addAUTServerEventListener(this); clientTest.addAutAgentEventListener(this); clientTest.addTestEventListener(this); clientTest.addTestExecutionEventListener(this); AutAgentRegistration.getInstance().addListener(this); } /** * Method to get the single instance of this class. * @return the instance of this Singleton */ public static ExecutionController getInstance() { if (instance == null) { instance = new ExecutionController(); } return instance; } /** * creates the job passed to command Line client * * @param configFile * File * @throws IOException * Error * @return a job configuration */ public JobConfiguration initJob(File configFile) throws IOException { if (configFile != null) { // Create JobConfiguration from XMl BufferedReader in = null; StringWriter writer = new StringWriter(); try { in = new BufferedReader(new FileReader(configFile)); String line = null; while ((line = in.readLine()) != null) { writer.write(line); } } finally { if (in != null) { in.close(); } } String xml = writer.toString(); m_job = JobConfiguration.readFromXML(xml); } else { // or create an empty JobConfiguration m_job = new JobConfiguration(); } return m_job; } /** * executes the complete test * @throws CommunicationException Error * @return boolean true if all testsuites completed successfully * or if test execution was successful up to specified mode of no-run option */ public boolean executeJob() throws CommunicationException { String noRun = m_job.getNoRunOptMode(); if (AbstractCmdlineClient.isNoRun()) { sysOut(StringConstants.TAB + NLS.bind(Messages.ExecutionControllerNoRunExecutionBegin, TestExecutionConstants.RunSteps.valueOf(noRun. toUpperCase()).getDescription())); } // start the watchdog timer WatchdogTimer timer = null; if (m_job.getTimeout() > 0) { timer = new WatchdogTimer(m_job.getTimeout()); timer.start(); } IClientTest clientTest = ClientTest.instance(); //connection to AUT Agent if (!prepareAUTAgentConnection(clientTest)) { return false; } else if (TestExecution.shouldExecutionStop(noRun, TestExecutionConstants.RunSteps.CAA)) { return true; } // set monitoring report generation clientTest.setGenerateMonitoringReport( m_job.isGenerateMonitoringReport()); clientTest.setScreenshotXMLFlag(m_job.isXMLScreenshot()); //prepare connection to the DB prepareDBConnection(); if (TestExecution.shouldExecutionStop(noRun, TestExecutionConstants.RunSteps.CDB)) { return true; } // load project loadProject(); if (TestExecution.shouldExecutionStop(noRun, TestExecutionConstants.RunSteps.LP)) { return true; } //check the completeness of the test checkTestCompleteness(); if (TestExecution.shouldExecutionStop(noRun, TestExecutionConstants.RunSteps.CC)) { return true; } // start AUT, working will be set false, after AUT started m_idle = true; // ends testexecution if shutdown command was received from the client if (m_shutdown) { sysOut(Messages.ReceivedShutdownCommand); endTestExecution(); } try { //start AUT and check that it was started ensureAutIsStarted(m_job.getActualTestSuite(), m_job.getAutConfig()); if (TestExecution.shouldExecutionStop(noRun, TestExecutionConstants.RunSteps.SA)) { return true; } //start of the test execution doTest(m_job.getTestJob() != null); } catch (ToolkitPluginException e1) { sysErr(NLS.bind(Messages.ExecutionControllerAUT, Messages.ErrorMessageAUT_TOOLKIT_NOT_AVAILABLE)); } if (timer != null) { timer.abort(); } return isNoErrorWhileExecution(); } /** * calls the test job or test suite execution depending on what was given as an testexec option * @param testJobIsSpecified boolean is true if test job option was specified in the command line */ private void doTest(boolean testJobIsSpecified) { if (testJobIsSpecified) { doTestJob(); return; } doTestSuite(); } /** * starts the embedded AUT Agent * @param port the port number of the embedded AUT Agent * @throws CommunicationException in case of failure to connect to embedded AUT Agent * @return true if embedded Agent was started successfully and false otherwise */ private boolean startEmbeddedAutAgent(int port) throws CommunicationException { AutStarter autAgentInstance = AutStarter.getInstance(); if (autAgentInstance.getCommunicator() == null) { // Embedded Agent is not running. We need to start it before // trying to connect to it. try { sysOut(I18n.getString("AUTAgent.EmbeddedAUTAgentStart", //$NON-NLS-1$ new String[] {String.valueOf(port)})); autAgentInstance.start( port, false, Verbosity.QUIET, false); return true; } catch (UnknownHostException uhe) { LOG.error(uhe.getLocalizedMessage(), uhe); sysErr(StringConstants.TAB + NLS.bind( Messages.ExecutionControllerAUTStartUnknownHost, uhe.getLocalizedMessage())); } catch (JBVersionException e) { LOG.error(e.getLocalizedMessage(), e); sysErr(StringConstants.TAB + NLS.bind( Messages.ExecutionControllerAUTStartVersionConflict, e.getErrorMessagesString())); } catch (IOException e) { LOG.error(e.getLocalizedMessage(), e); sysErr(StringConstants.TAB + NLS.bind( Messages.ExecutionControllerAUTStartFailed, e.getMessage())); } } return false; } /** * execute a test suite */ private void doTestSuite() { // executing batch of test suites while (m_job.getActualTestSuite() != null && !m_stopProcessing) { while (m_idle && !m_stopProcessing) { TimeUtil.delay(50); } if (m_job.getActualTestSuite() != null && !m_stopProcessing && !m_idle && !m_isFirstAutStart) { ITestSuitePO ts = m_job.getActualTestSuite(); m_idle = true; sysOut(StringConstants.TAB + NLS.bind(Messages.ExecutionControllerTestSuiteBegin, ts.getName())); ClientTest.instance().startTestSuite( ts, m_startedAutId != null ? m_startedAutId : m_job .getAutId(), m_job.isAutoScreenshot(), m_job.getIterMax(), null, m_job.getNoRunOptMode(), null); } } waitForReportingToFinish(TimeoutConstants .CLIENT_REPORTING_AFTER_FAILURE_TIMEOUT); } /** * run a test job */ private void doTestJob() { String tjName = m_job.getTestJob().getName(); sysOut(NLS.bind(Messages.ExecutionControllerTestJobBegin, tjName)); sysOut(NLS.bind(Messages.ExecutionControllerTestJobExpectedTestSuites, new Object[] { tjName, m_job.getTestJob().getNodeListSize()})); List<INodePO> executedTestSuites = ClientTest.instance().startTestJob( m_job.getTestJob(), m_job.isAutoScreenshot(), m_job.getIterMax(), m_job.getIncompleteTSs(), m_job.getNoRunOptMode()); sysOut(NLS.bind(Messages.ExecutionControllerTestJobExecutedTestSuites, new Object[] { tjName, executedTestSuites.size()})); Iterator<INodePO> tsIterator = m_job.getTestJob().getNodeListIterator(); waitForReportingToFinish(TimeoutConstants .CLIENT_REPORTING_AFTER_FAILURE_TIMEOUT); while (tsIterator.hasNext()) { INodePO testsuite = tsIterator.next(); if (!executedTestSuites.contains(testsuite)) { sysErr(NLS.bind(Messages. ExecutionControllerTestJobUnsuccessfulTestSuites, new Object[] { tjName, testsuite.getName()})); } } } /** * waits for the reporting job to finish. * @param timeout timeout in milliseconds */ private void waitForReportingToFinish(long timeout) { long endtime = System.currentTimeMillis() + timeout; TimeUtil.delay(500); // wait for reporting job to start while (ClientTest.instance().isReportingRunning()) { TimeUtil.delay(250); if (endtime - System.currentTimeMillis() < 0) { return; } } } /** * end processing and notify any waiting CLC service threads */ private void stopProcessing() { m_stopProcessing = true; } /** Prepares the test execution by: * <p> * starting of the AUT Agent * <p> * initializing AUT Agent connection * and checks if these steps were successful * @param clientTest the clientTest instance * @throws CommunicationException Error in case of connection to AUT Agent failure * @return boolean true if connection to the AUT Agent was successful */ private boolean prepareAUTAgentConnection(IClientTest clientTest) throws CommunicationException { int autAgentPortNumber = m_job.getPort(); if (StringUtils.isEmpty(m_job.getServer())) { // if "port" parameter for testexec was not given (in command line and/or in configuration file) // port number equals 0 by default and any free port should be used for embedded AUT Agent in this case if (autAgentPortNumber == 0) { autAgentPortNumber = NetUtil.getFreePort(); } //the "server" parameter (autAgentHostName) for testexec is set to "localhost" m_job.setEmbeddedAutAgentHostName(); if (!startEmbeddedAutAgent(autAgentPortNumber)) { endTestExecution(); return false; } } String autAgentHostName = m_job.getServer(); sysOut(NLS.bind(Messages.ConnectingToAUTAgent, new Object[] { autAgentHostName, autAgentPortNumber })); // init ClientTestImpl clientTest.connectToAutAgent(autAgentHostName, String.valueOf(autAgentPortNumber)); if (!AutAgentConnection.getInstance().isConnected()) { throw new CommunicationException( Messages.ConnectionToAUTAgentFailed, MessageIDs.E_COMMUNICATOR_CONNECTION); } return true; } /** * prepares the test execution by initializing database connection */ private void prepareDBConnection() { // setting LogDir , resource/html must be in classpath setLogDir(); // set data dir for external data ExternalTestDataBP.setDataDir(new File(m_job.getDataDir())); // init Persistor // Persistence (JPA / EclipseLink).properties and mapping files // have to be in classpath Persistor.setDbConnectionName(m_job.getDbscheme()); Persistor.setUser(m_job.getDbuser()); Persistor.setPw(m_job.getDbpw()); Persistor.setUrl(m_job.getDb()); if (!Persistor.init()) { throw new IllegalArgumentException(Messages. ExecutionControllerInvalidDBDataError, null); } } /** * sets the log Directory */ private void setLogDir() { if (StringUtils.isNotEmpty(m_job.getResultDir())) { Validate.isTrue(FileUtils.isValidPath(m_job.getResultDir()), Messages.ExecutionControllerLogPathError); ClientTest.instance().setLogPath(m_job.getResultDir()); } if (StringUtils.isNotBlank(m_job.getFileName())) { String filePath = m_job.getResultDir() + StringConstants.SLASH + m_job.getFileName(); boolean isWritable = FileUtils.isWritableFile(filePath + TestResultReportNamer.FILE_EXTENSION_XML); if (isWritable) { isWritable = FileUtils.isWritableFile(filePath + TestResultReportNamer.FILE_EXTENSION_HTML); } Validate.isTrue(isWritable, Messages.ExecutionControllerResultNameError); ClientTest.instance().setFileName(m_job.getFileName()); } } /** * starts the AUT * @param ts the Test Suite which will be started * @param autConf configuration for this AUT */ private void ensureAutIsStarted(ITestSuitePO ts, IAUTConfigPO autConf) throws ToolkitPluginException { if (ts != null && autConf != null) { final IAUTMainPO aut = ts.getAut(); if (ts != null) { AutIdentifier autToStart = new AutIdentifier(autConf .getConfigMap().get(AutConfigConstants.AUT_ID)); AUTStartListener asl = new AUTStartListener(autToStart); IClientTest clientTest = ClientTest.instance(); clientTest.addTestEventListener(asl); clientTest.addAUTServerEventListener(asl); AutAgentRegistration.getInstance().addListener(asl); sysOut(NLS.bind(Messages.ExecutionControllerAUT, NLS.bind(Messages.ExecutionControllerAUTStart, aut.getName(), autConf.getName()))); clientTest.startAut(aut, autConf); m_startedAutId = autToStart; while (!asl.autStarted() && !asl.hasAutStartFailed()) { TimeUtil.delay(500); } waitExternalTime(); } } else { sysOut(Messages.ExecutionControllerAUTIsPossiblyStarted); // assume that the AUT has already been started via e.g. autrun m_idle = false; m_isFirstAutStart = false; } } /** * this method delays the test execution start during AUT startup */ private void waitExternalTime() { TimeUtil.delayDefaultOrExternalTime(AUT_STARTUP_DELAY_DEFAULT, AUT_STARTUP_DELAY_VAR); } /** * @author BREDEX GmbH * @created 24.08.2009 */ public class AUTStartListener implements IAUTEventListener, IAUTServerEventListener, IAutRegistrationListener { /** flag to indicate that the AUT has been successfully started */ private boolean m_autStarted = false; /** flag to indicate that the AUT start has failed*/ private boolean m_autStartFailed = false; /** timer to set autStartFailed to true after a certain amount of time */ private Timer m_startFailedTimer = new Timer(); /** startup timeout: 5 minutes */ private long m_autStartTimeout = 5 * 60 * 1000; /** ID of the AUT that should be started */ private AutIdentifier m_autToStart; /** * Constructor * * @param autToStart ID of the AUT that should be started. */ public AUTStartListener(AutIdentifier autToStart) { m_autToStart = autToStart; m_startFailedTimer.schedule(new TimerTask() { public void run() { setAutStartFailed(true); removeListener(); } }, m_autStartTimeout); } /** @return the hasBeenNotified */ public synchronized boolean autStarted() { return m_autStarted; } /** {@inheritDoc} */ public synchronized void stateChanged(AUTEvent event) { switch (event.getState()) { case AUTEvent.AUT_STARTED: m_autStarted = true; dispose(); break; default: break; } } /** @return the autStartFailed */ public synchronized boolean hasAutStartFailed() { return m_autStartFailed; } /** {@inheritDoc} */ public void stateChanged(AUTServerEvent event) { switch (event.getState()) { case AUTServerEvent.COMMUNICATION: case AUTServerEvent.COULD_NOT_ACCEPTING: case AUTServerEvent.DOTNET_INSTALL_INVALID: case AUTServerEvent.INVALID_JAR: case AUTServerEvent.INVALID_JAVA: case AUTServerEvent.JDK_INVALID: case AUTServerEvent.NO_MAIN_IN_JAR: case AUTServerEvent.SERVER_NOT_INSTANTIATED: case ServerEvent.CONNECTION_CLOSED: setAutStartFailed(true); dispose(); break; default: break; } } /** * @param autStartFailed the autStartFailed to set */ protected synchronized void setAutStartFailed(boolean autStartFailed) { m_autStartFailed = autStartFailed; } /** dispose this listener and stop all running tasks */ private void dispose () { m_startFailedTimer.cancel(); removeListener(); } /** remove listener */ protected void removeListener() { IClientTest clientTest = ClientTest.instance(); clientTest.removeTestEventListener(this); clientTest.removeAUTServerEventListener(this); AutAgentRegistration.getInstance().removeListener(this); } /** * {@inheritDoc} */ public void handleAutRegistration(AutRegistrationEvent event) { if (event.getAutId().equals(m_autToStart) && event.getStatus() == RegistrationStatus.Register) { m_autStarted = true; dispose(); } } } /** * loads a project */ private void loadProject() { sysOut(Messages.ExecutionControllerDatabase + NLS.bind(Messages.ExecutionControllerLoadingProject, new Object[] { m_job.getProjectName(), m_job.getProjectVersion() })); try { IProjectPO actualProject = ProjectPM.loadProjectByNameAndVersion(m_job.getProjectName(), m_job.getProjectVersion()); if (actualProject != null) { ProjectPM.loadProjectInROSession(actualProject); final IProjectPO currentProject = GeneralStorage.getInstance() .getProject(); m_job.setProject(currentProject); sysOut(Messages.ExecutionControllerDatabase + NLS.bind(Messages.ExecutionControllerProjectLoaded, m_job.getProjectName())); } m_job.checkProjectExistence(); } catch (JBException e1) { /* An exception was thrown while loading data or closing a session * using Persistence (JPA / EclipseLink). The project is never set. This is detected * during job validation (initAndValidate). */ } } /** * checks the completeness of the test */ private void checkTestCompleteness() { sysOut(Messages.ExecutionControllerProjectCompleteness); m_job.initAndValidate(); boolean noErrors = true; Set<ITestSuitePO> distinctListOfTs = new HashSet<ITestSuitePO>(); distinctListOfTs.addAll(m_job.getTestSuites()); for (ITestSuitePO ts : distinctListOfTs) { boolean noError = true; CompletenessGuard.checkAll(ts, new NullProgressMonitor()); sysOut(NLS.bind(Messages.ExecutionControllerTestSuiteCompleteness, ts.getName())); final CollectAllErrorsOperation op = new CollectAllErrorsOperation(); TreeTraverser traverser = new TreeTraverser(ts, op); traverser.traverse(true); for (IProblem problem : op.getErrorsToShow()) { if (problem.hasUserMessage()) { sysOut(problem.getUserMessage()); } noError = false; m_job.removeTestSuites(ts); } if (noError) { sysOut(Messages.ExecutionControllerTestSuiteCompletenessOk); } else { sysOut(Messages.ExecutionControllerTestSuiteCompletenessNOk); noErrors = false; } } if (!noErrors && m_job.isExecuteJobsPartly()) { sysOut(NLS.bind( Messages.ExecutionControllerTestSuiteCompletenessNOkSkipp, StringUtils.join(m_job.getIncompleteTSs(), StringConstants.COMMA + StringConstants.SPACE))); } else { Validate.isTrue(noErrors, Messages.ExecutionControllerProjectCompletenessFailed); } } /** * {@inheritDoc} */ public void stateChanged(AUTServerEvent event) { switch (event.getState()) { case AUTServerEvent.INVALID_JAR: sysErr(Messages.ExecutionControllerInvalidJarError); stopProcessing(); m_idle = false; break; case AUTServerEvent.INVALID_JAVA: sysErr(Messages.ExecutionControllerInvalidJREError); stopProcessing(); m_idle = false; break; case AUTServerEvent.SERVER_NOT_INSTANTIATED: sysErr(Messages.ExecutionControllerServerNotInstantiated); stopProcessing(); m_idle = false; break; case AUTServerEvent.NO_MAIN_IN_JAR: sysErr(Messages.ExecutionControllerInvalidMainError); stopProcessing(); m_idle = false; break; case AUTServerEvent.COMMUNICATION: sysErr(event.toStringWithAdditionalInformation()); stopProcessing(); m_idle = false; break; case AUTServerEvent.COULD_NOT_ACCEPTING: sysErr(Messages.ExecutionControllerAUTStartError); stopProcessing(); m_idle = false; break; case ServerEvent.CONNECTION_CLOSED: stopProcessing(); m_idle = false; break; case AUTServerEvent.DOTNET_INSTALL_INVALID: sysErr(Messages.ExecutionControllerDotNetInstallProblem); stopProcessing(); m_idle = false; break; case AUTServerEvent.JDK_INVALID: sysErr(Messages.ExecutionControllerInvalidJDKError); break; default: break; } } /** * {@inheritDoc} */ public void stateChanged(AutAgentEvent event) { sysOut(NLS.bind(Messages.ExecutionControllerServer, event)); switch (event.getState()) { case ServerEvent.CONNECTION_CLOSED: break; default: break; } } /** * {@inheritDoc} */ public void stateChanged(AUTEvent event) { switch (event.getState()) { case AUTEvent.AUT_STARTED: sysOut(NLS.bind(Messages.ExecutionControllerAUT, Messages.ExecutionControllerAUTConnectionEstablished)); break; case AUTEvent.AUT_CLASS_VERSION_ERROR: case AUTEvent.AUT_MAIN_NOT_FOUND: case AUTEvent.AUT_NOT_FOUND: case AUTEvent.AUT_ABORTED: case AUTEvent.AUT_START_FAILED: sysErr(Messages.ExecutionControllerAUTStartError); stopProcessing(); break; case AUTEvent.AUT_STOPPED: if (m_isTestSuiteRunning) { sysErr(Messages.ExecutionControllerAUTConnectionLost); ClientTest.instance().stopTestExecution(); } else { sysOut(NLS.bind(Messages.ExecutionControllerAUT, Messages.ExecutionControllerAUTDisconnected)); } stopProcessing(); break; case AUTEvent.AUT_RESTARTED: return; default: break; } // generally do not do this, if AUT-Restart-Action is executed! if (m_isFirstAutStart) { m_idle = false; m_isFirstAutStart = false; } } /** * Writes an output to console * * @param text * the text to write */ private void sysOut(String text) { AbstractCmdlineClient.printConsoleLn(text, true); } /** * Writes an output to console * * @param text * the message to log and println to sys.err */ private void sysErr(String text) { AbstractCmdlineClient.printlnConsoleError(text); } /** * {@inheritDoc} */ public void stateChanged(TestExecutionEvent event) { Exception exception = event.getException(); if (exception instanceof JBException) { StringBuilder errorMsgBuilder = new StringBuilder( exception.getMessage()); if (((JBException) exception) .getErrorId() == MessageIDs.E_NO_AUT_CONNECTION_ERROR && m_job.getAutConfig() == null) { errorMsgBuilder.append(StringConstants.NEWLINE); errorMsgBuilder.append(StringConstants.TAB); errorMsgBuilder.append( Messages. ExecutionControllerCouldNotConnectToAUTWithAutrun); } sysErr(errorMsgBuilder.toString()); TestExecution.getInstance().stopExecution(); stopProcessing(); } switch (event.getState()) { case TEST_EXEC_RESULT_TREE_READY: TestExecution.getInstance().getTrav() .addExecStackModificationListener(m_progress); break; case TEST_EXEC_START: case TEST_EXEC_RESTART: m_isTestSuiteRunning = true; break; case TEST_EXEC_FINISHED: sysOut(Messages.ExecutionControllerTestSuiteEnd); m_job.getNextTestSuite(); m_isTestSuiteRunning = false; break; case TEST_EXEC_PAUSED: TestExecution.getInstance().pauseExecution(PauseMode.UNPAUSE); break; case TEST_EXEC_ERROR: case TEST_EXEC_FAILED: case TEST_EXEC_STOP: m_job.getNextTestSuite(); m_isTestSuiteRunning = false; break; default: break; } } /** * {@inheritDoc} */ public void endTestExecution() { m_idle = false; } /** * @author BREDEX GmbH * @created Dec 3, 2010 */ protected class TestExecutionWatcher implements IExecStackModificationListener { /** * {@inheritDoc} */ public void stackIncremented(INodePO node) { String nodeType = StringConstants.EMPTY; String name = String.valueOf(node.getName()); if (node instanceof IEventExecTestCasePO) { IEventExecTestCasePO evPo = (IEventExecTestCasePO)node; if (evPo.getReentryProp() != ReentryProperty.RETRY) { setNoErrorWhileExecution(false); } nodeType = Messages.EventHandler; } else if (node instanceof IRefTestSuitePO) { nodeType = Messages.TestSuite; name = NodeNameUtil.getText((IRefTestSuitePO)node); } else if (node instanceof IExecTestCasePO) { nodeType = Messages.TestCase; name = NodeNameUtil.getText((IExecTestCasePO)node, false); } else if (node instanceof IConditionalStatementPO) { nodeType = Messages.Conditional; } else if (node instanceof IAbstractContainerPO) { nodeType = Messages.Container; } else if (node instanceof IDoWhilePO) { nodeType = Messages.DoWhile; } else if (node instanceof IWhileDoPO) { nodeType = Messages.WhileDo; } else if (node instanceof IIteratePO) { nodeType = Messages.Iterate; } StringBuilder sb = new StringBuilder(nodeType); sb.append(StringConstants.COLON); sb.append(StringConstants.SPACE); sb.append(name); sysOut(sb.toString()); } /** * {@inheritDoc} */ public void stackDecremented() { // do nothing } /** * {@inheritDoc} */ public void nextDataSetIteration() { // do nothing } /** * {@inheritDoc} */ public void nextCap(ICapPO cap) { sysOut(StringConstants.TAB + Messages.Step + StringConstants.COLON + StringConstants.SPACE + String.valueOf(cap.getName())); } /** * {@inheritDoc} */ public void retryCap(ICapPO cap) { sysOut(StringConstants.TAB + Messages.RetryStep + StringConstants.COLON + StringConstants.SPACE + String.valueOf(cap.getName())); } /** {@inheritDoc} */ public void infiniteLoop() { // not relevant } } /** * @param job the job to set */ public void setJob(JobConfiguration job) { m_job = job; } /** * {@inheritDoc} */ public void handleAutRegistration(AutRegistrationEvent event) { if ((event.getAutId().equals(m_startedAutId) || event.getAutId().equals(m_job.getAutId())) && event.getStatus() == RegistrationStatus.Register) { // generally do not do this, if AUT-Restart-Action is executed! if (m_isFirstAutStart) { m_idle = false; m_isFirstAutStart = false; } } } /** * @param noErrorWhileExecution the noErrorWhileExecution to set */ protected void setNoErrorWhileExecution(boolean noErrorWhileExecution) { m_noErrorWhileExecution = noErrorWhileExecution; } /** * @return the noErrorWhileExecution */ protected boolean isNoErrorWhileExecution() { return m_noErrorWhileExecution; } /** * {@inheritDoc} */ public void receiveExecutionNotification(String notification) { LOG.error(notification); AbstractCmdlineClient.printConsoleLn(notification, true); } }