/*******************************************************************************
* 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.client.core.businessprocess;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.nio.charset.IllegalCharsetNameException;
import java.nio.charset.UnsupportedCharsetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.exec.ExecuteException;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.Validate;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.jubula.client.core.Activator;
import org.eclipse.jubula.client.core.ClientTest;
import org.eclipse.jubula.client.core.ClientTestImpl;
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.TestExecutionEvent.State;
import org.eclipse.jubula.client.core.commands.DisplayManualTestStepResponseCommand;
import org.eclipse.jubula.client.core.commands.EndTestExecutionResponseCommand;
import org.eclipse.jubula.client.core.communication.AUTConnection;
import org.eclipse.jubula.client.core.constants.TestExecutionConstants;
import org.eclipse.jubula.client.core.events.AUTEvent;
import org.eclipse.jubula.client.core.i18n.Messages;
import org.eclipse.jubula.client.core.model.IAUTConfigPO.ActivationMethod;
import org.eclipse.jubula.client.core.model.IAUTMainPO;
import org.eclipse.jubula.client.core.model.ICapPO;
import org.eclipse.jubula.client.core.model.ICondStructPO;
import org.eclipse.jubula.client.core.model.IConditionalStatementPO;
import org.eclipse.jubula.client.core.model.IEventStackModificationListener;
import org.eclipse.jubula.client.core.model.IExecStackModificationListener;
import org.eclipse.jubula.client.core.model.INodePO;
import org.eclipse.jubula.client.core.model.IObjectMappingPO;
import org.eclipse.jubula.client.core.model.IParamDescriptionPO;
import org.eclipse.jubula.client.core.model.IProjectPO;
import org.eclipse.jubula.client.core.model.ITDManager;
import org.eclipse.jubula.client.core.model.ITestJobPO;
import org.eclipse.jubula.client.core.model.ITestResultSummaryPO;
import org.eclipse.jubula.client.core.model.ITestSuitePO;
import org.eclipse.jubula.client.core.model.LogicComponentNotManagedException;
import org.eclipse.jubula.client.core.model.ReentryProperty;
import org.eclipse.jubula.client.core.model.ResultTreeBuilder;
import org.eclipse.jubula.client.core.model.ResultTreeTracker;
import org.eclipse.jubula.client.core.model.TestResult;
import org.eclipse.jubula.client.core.model.TestResultNode;
import org.eclipse.jubula.client.core.persistence.GeneralStorage;
import org.eclipse.jubula.client.core.persistence.Persistor;
import org.eclipse.jubula.client.core.rc.commands.AbstractPostExecutionCommand;
import org.eclipse.jubula.client.core.rc.commands.IPostExecutionCommand;
import org.eclipse.jubula.client.core.utils.ExecObject;
import org.eclipse.jubula.client.core.utils.ModelParamValueConverter;
import org.eclipse.jubula.client.core.utils.ParamValueConverter;
import org.eclipse.jubula.client.core.utils.Traverser;
import org.eclipse.jubula.client.internal.AutAgentConnection;
import org.eclipse.jubula.client.internal.BaseConnection;
import org.eclipse.jubula.client.internal.BaseConnection.NotConnectedException;
import org.eclipse.jubula.client.internal.commands.CAPTestResponseCommand;
import org.eclipse.jubula.client.internal.commands.TakeScreenshotAUTAgentResponseCommand;
import org.eclipse.jubula.client.internal.commands.TakeScreenshotResponseCommand;
import org.eclipse.jubula.client.internal.exceptions.ConnectionException;
import org.eclipse.jubula.communication.internal.ICommand;
import org.eclipse.jubula.communication.internal.message.CAPTestMessage;
import org.eclipse.jubula.communication.internal.message.CAPTestResponseMessage;
import org.eclipse.jubula.communication.internal.message.DisplayManualTestStepMessage;
import org.eclipse.jubula.communication.internal.message.EndTestExecutionMessage;
import org.eclipse.jubula.communication.internal.message.InitTestExecutionMessage;
import org.eclipse.jubula.communication.internal.message.Message;
import org.eclipse.jubula.communication.internal.message.MessageCap;
import org.eclipse.jubula.communication.internal.message.MessageParam;
import org.eclipse.jubula.communication.internal.message.NullMessage;
import org.eclipse.jubula.communication.internal.message.PrepareForShutdownMessage;
import org.eclipse.jubula.communication.internal.message.ResetMonitoringDataMessage;
import org.eclipse.jubula.communication.internal.message.RestartAutMessage;
import org.eclipse.jubula.communication.internal.message.TakeScreenshotAUTAgentMessage;
import org.eclipse.jubula.communication.internal.message.TakeScreenshotMessage;
import org.eclipse.jubula.toolkit.common.businessprocess.ToolkitSupportBP;
import org.eclipse.jubula.toolkit.common.xml.businessprocess.ComponentBuilder;
import org.eclipse.jubula.toolkit.internal.CSConstants;
import org.eclipse.jubula.tools.exec.CommandExecutor;
import org.eclipse.jubula.tools.exec.CommandExecutor.Result;
import org.eclipse.jubula.tools.internal.constants.AutConfigConstants;
import org.eclipse.jubula.tools.internal.constants.MonitoringConstants;
import org.eclipse.jubula.tools.internal.constants.StringConstants;
import org.eclipse.jubula.tools.internal.constants.TimeoutConstants;
import org.eclipse.jubula.tools.internal.constants.TimingConstantsClient;
import org.eclipse.jubula.tools.internal.exception.CommunicationException;
import org.eclipse.jubula.tools.internal.exception.InvalidDataException;
import org.eclipse.jubula.tools.internal.exception.JBException;
import org.eclipse.jubula.tools.internal.messagehandling.MessageIDs;
import org.eclipse.jubula.tools.internal.objects.IComponentIdentifier;
import org.eclipse.jubula.tools.internal.objects.event.EventFactory;
import org.eclipse.jubula.tools.internal.objects.event.TestErrorEvent;
import org.eclipse.jubula.tools.internal.registration.AutIdentifier;
import org.eclipse.jubula.tools.internal.utils.ExternalCommandExecutor;
import org.eclipse.jubula.tools.internal.utils.ExternalCommandExecutor.MonitorTask;
import org.eclipse.jubula.tools.internal.utils.StringParsing;
import org.eclipse.jubula.tools.internal.utils.TimeUtil;
import org.eclipse.jubula.tools.internal.xml.businessmodell.Action;
import org.eclipse.jubula.tools.internal.xml.businessmodell.CompSystem;
import org.eclipse.jubula.tools.internal.xml.businessmodell.Component;
import org.eclipse.jubula.tools.internal.xml.businessmodell.ConcreteComponent;
import org.eclipse.jubula.tools.internal.xml.businessmodell.Param;
import org.eclipse.osgi.util.NLS;
import org.osgi.framework.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* This class creates the captestmessage with test data and sends this message
* to the server. Then it waits for an answer of the server and processes the
* answer. Then it sends the next captestmessage.
*
* @author BREDEX GmbH
* @created 03.09.2004
*/
public class TestExecution {
/** <code>EXIT_CODE_ERROR</code> */
protected static final int EXIT_CODE_NORUN_OK = 100;
/** <code>EXIT_CODE_OK</code> */
protected static final int EXIT_CODE_OK = 0;
/**
* @author BREDEX GmbH
* @created Feb 2, 2011
*/
public enum PauseMode {
/**
* <code>TOGGLE</code> between <code>PAUSE</code> and
* <code>UNPAUSE</code>
*/
TOGGLE,
/**
* <code>PAUSE</code>
*/
PAUSE,
/**
* <code>UNPAUSE</code>
*/
UNPAUSE,
/**
* <code>CONTINUE_WITHOUT_EH</code> continue test execution without
* executing the next event handler
*/
CONTINUE_WITHOUT_EH
}
/** The logger */
private static final Logger LOG =
LoggerFactory.getLogger(TestExecution.class);
/**
* Constant for the m_varStore of the last return value of the last
* executed Action
*/
private static final String LAST_ACTION_RETURN = "TEST_LAR"; //$NON-NLS-1$
/**
* Constant for the m_varStore of the last return value of the current
* data set number
*/
private static final String CURRENT_DATASET_NUMBER = "TEST_CDN"; //$NON-NLS-1$
/** Singleton Instance of TestExecution */
private static TestExecution instance = null;
/** The timeout to use for cap-test-requests in MILLISECONDS! */
private int m_requestTimeout =
TimeoutConstants.CLIENT_SERVER_TIMEOUT_DEFAULT_REQUEST;
/** StepSpeed */
private int m_stepSpeed = TimingConstantsClient.MIN_STEP_SPEED;
/**
* is execution paused
*/
private boolean m_paused = false;
/**
* skip the next error
*/
private boolean m_skipError = false;
/**
* is execution stopped ?
*/
private boolean m_stopped = false;
/**
* indicates whether for test error events screenshots should be
* automatically taken
*/
private boolean m_autoScreenshot = true;
/** The maximum number of iterations */
private int m_maxIterateCount = 100;
/** the started Test Job */
private ITestJobPO m_startedTestJob;
/** the started TestSuite */
private ITestSuitePO m_startedTestSuite;
/** the CAP, that is actually executed */
private ICapPO m_currentCap;
/**
* <code>m_trav</code> actual traverser for testexecution tree
*/
private Traverser m_trav;
/**
* responsible for keeping track of the number of test steps executed
* during this test execution
*/
private StepCounter m_stepCounter;
/**
* <code>m_resultTree</code> associated resultTree
*/
private ResultTreeTracker m_resultTreeTracker;
/**
* The business process that performs component name operations.
*/
private CompNamesBP m_compNamesBP = new CompNamesBP();
/** business process for retrieving test data */
private ExternalTestDataBP m_externalTestDataBP;
/** Factory for IPostExecutionCommands */
private PostExecCommandFactory m_postExecCmdFactory;
/** The variable store */
private TDVariableStore m_varStore;
/** The variable store */
private Map<String, Long> m_timerStore;
/**
* the number of test steps that will be executed during this test execution
* iff all of the following conditions are met:
* 1. the test is not stopped prematurely
* 2. the test does not fail prematurely (note that if the test fails
* on the final step, that step is still counted as "executed")
* 3. no steps are executed while in an error state (no event handler
* test steps are executed)
*/
private int m_expectedNumberOfSteps;
/** The last TestResultNode */
private TestResultNode m_testResultNode = null;
/**
* Default constructor
*/
private TestExecution() {
m_varStore = new TDVariableStore();
m_postExecCmdFactory = new PostExecCommandFactory();
setTimerStore(new HashMap<String, Long>());
m_externalTestDataBP = new ExternalTestDataBP();
ClientTest.instance().addTestExecutionEventListener(
new ITestExecutionEventListener() {
/**
* Clears this ExternalTestDataBP (e.g. the caches)
* after TestExecution has finished.
*/
public void endTestExecution() {
m_externalTestDataBP.clearExternalData();
}
/**
* {@inheritDoc}
*/
public void stateChanged(TestExecutionEvent event) {
// nothing
}
@Override
public void receiveExecutionNotification(
String notification) {
// nothing
}
});
}
/**
* Returns the singleton instance of TestExecution
*
* @return singleton instance
*/
public static synchronized TestExecution getInstance() {
if (instance == null) {
instance = new TestExecution();
}
return instance;
}
/**
* This method executes the given Test Suite
*
* @param testSuite
* the TestSuitePO that will be tested
* @param autoScreenshot
* whether screenshots should be automatically taken in case of
* test execution errors
* @param iterMax the maximum number of iterations
* @param autId
* The ID of the Running AUT on which the test will take place.
* @param externalVars
* a map of externally set variables; may be <code>null</code>
* @param summary
* The Test Result Summary for the executed test.
* Must not be <code>null</code>.
* @param monitor the monitor to use
* @param noRunOptMode
* The value of no-run option argument if it was specified, null otherwise
*/
public void executeTestSuite(ITestSuitePO testSuite,
AutIdentifier autId, boolean autoScreenshot, int iterMax,
Map<String, String> externalVars, ITestResultSummaryPO summary,
final IProgressMonitor monitor, String noRunOptMode) {
m_stopped = false;
m_autoScreenshot = autoScreenshot;
m_maxIterateCount = iterMax;
setPaused(false);
Validate.notNull(testSuite, Messages.TestsuiteMustNotBeNull);
m_externalTestDataBP.clearExternalData();
if (TestExecution.shouldExecutionStop (noRunOptMode,
TestExecutionConstants.RunSteps.PTE)) {
monitor.setCanceled(true);
return;
}
if (!prepareTestExecution(testSuite, autId, summary,
monitor, noRunOptMode)) {
return;
}
monitor.subTask(Messages.
StartingTestSuite_resolvingPredefinedVariables);
m_varStore.storeEnvironmentVariables();
storePredefinedVariables(m_varStore, testSuite);
storeExternallyDefinedVariables(m_varStore, externalVars);
if (TestExecution.shouldExecutionStop (noRunOptMode,
TestExecutionConstants.RunSteps.RPV)) {
endTestExecution();
return;
}
startTestSuite(testSuite, monitor, noRunOptMode);
addExecutionFinishedListener();
}
/**
*
* @param testSuite the Test Suite
* @param autId the AUT Id
* @param summary the Summary
* @param monitor the Monitor
* @param noRunOptMode whether
* @return whether to continue the test execution
*/
private boolean prepareTestExecution(ITestSuitePO testSuite,
AutIdentifier autId, ITestResultSummaryPO summary,
final IProgressMonitor monitor, String noRunOptMode) {
try {
IStatus connected = AUTConnection.getInstance().connectToAut(
autId, new SubProgressMonitor(monitor, 0));
if (connected.getCode() == IStatus.OK) {
if (TestExecution.shouldExecutionStop (noRunOptMode,
TestExecutionConstants.RunSteps.CA)) {
endTestExecution();
return false;
}
summary.setAutHostname(
AUTConnection.getInstance().getCommunicator()
.getConnection().getAddress()
.getCanonicalHostName());
summary.setAutAgentName(AutAgentConnection.getInstance()
.getCommunicator().getHostName());
}
} catch (ConnectionException | NullPointerException ex) {
LOG.error(Messages.UnableToConnectToAUT + StringConstants.DOT, ex);
handleNoConnectionToAUT(testSuite, autId);
return false;
}
return true;
}
/**
* Adds a finished listener to the test execution
*/
private void addExecutionFinishedListener() {
final AtomicBoolean testSuiteFinished = new AtomicBoolean();
ClientTest.instance().addTestExecutionEventListener(
new ITestExecutionEventListener() {
public void endTestExecution() {
try {
AUTConnection.getInstance().close();
} catch (ConnectionException e) {
// Do nothing. Connection is already closed.
}
ClientTest.instance()
.removeTestExecutionEventListener(this);
testSuiteFinished.set(true);
}
public void stateChanged(TestExecutionEvent event) {
// Do nothing
}
@Override
public void receiveExecutionNotification(
String notification) {
// Do nothing
}
});
while (!testSuiteFinished.get()) {
TimeUtil.delay(250);
}
}
/**
* @param varStore
* the variable store
* @param externalVars
* a map of variables to add to the var store; may be
* <code>null</code>
*/
private void storeExternallyDefinedVariables(TDVariableStore varStore,
Map<String, String> externalVars) {
if (externalVars != null) {
for (String key : externalVars.keySet()) {
varStore.store(key, externalVars.get(key));
}
}
}
/**
* @param testSuite
* the test suite
* @param autId
* the aut id
*/
private void handleNoConnectionToAUT(ITestSuitePO testSuite,
AutIdentifier autId) {
String autName = autId.getExecutableName();
if (isAutNameSet(autName)) {
// no AUTid for test suite has been set
autName = NLS.bind(Messages.ErrorDetailNO_AUT_ID_FOR_REF_TS_FOUND,
testSuite.getName());
}
ClientTest.instance().fireTestExecutionChanged(
new TestExecutionEvent(State.TEST_EXEC_FAILED,
new JBException(Messages.CouldNotConnectToAUT + autName,
MessageIDs.E_NO_AUT_CONNECTION_ERROR)));
}
/**
* @param autName the AUT Id
* @return whether the AUT name is correctly set
*/
public static boolean isAutNameSet(String autName) {
return String.valueOf(autName).equals("null"); //$NON-NLS-1$
}
/**
* Initializes all pre-defined variables for execution of the given
* test suite.
*
* @param varStore The place to store the variables.
* @param testSuite The test suite that will be executed. Some variables
* have values based on this test suite.
*/
private void storePredefinedVariables(TDVariableStore varStore,
ITestSuitePO testSuite) {
// TEST_testsuite
varStore.store(TDVariableStore.VAR_TS, testSuite.getName());
// TEST_username
varStore.store(TDVariableStore.VAR_USERNAME,
System.getProperty("user.name")); //$NON-NLS-1$
// TEST_dbusername
varStore.store(TDVariableStore.VAR_DBUSERNAME,
Persistor.instance().getCurrentDBUser());
IProjectPO cProject = GeneralStorage.getInstance().getProject();
// TEST_PROJECT_NAME
varStore.store(TDVariableStore.VAR_PROJECT_NAME,
cProject.getName());
// TEST_PROJECT_VERSION
varStore.store(TDVariableStore.VAR_PROJECT_VERSION,
cProject.getVersionString());
try {
AutAgentConnection serverConn = AutAgentConnection.getInstance();
// TEST_autstarter
varStore.store(TDVariableStore.VAR_AUTAGENT,
serverConn.getCommunicator().getHostName());
// TEST_portnumber
varStore.store(TDVariableStore.VAR_PORT,
String.valueOf(serverConn.getCommunicator().getPort()));
} catch (ConnectionException ce) {
// No connection to AutStarter.
// Do nothing.
}
// TEST_aut
varStore.store(TDVariableStore.VAR_AUT, testSuite.getAut().getName());
// TEST_autconfig
Map<String, String> autConfigMap =
getConnectedAUTsConfigMap();
if (autConfigMap != null) {
varStore.store(TDVariableStore.VAR_AUTCONFIG, MapUtils.getString(
autConfigMap, AutConfigConstants.AUT_CONFIG_NAME,
TestresultSummaryBP.AUTRUN));
varStore.store(TDVariableStore.VAR_AUT_ARGUMENTS,
MapUtils.getString(
autConfigMap, AutConfigConstants.AUT_ARGUMENTS,
StringConstants.EMPTY));
} else {
// write constant for AUTs which has been started via autrun
varStore.store(TDVariableStore.VAR_AUTCONFIG,
TestresultSummaryBP.AUTRUN);
}
// TEST_clientVersion
varStore.store(TDVariableStore.VAR_CLIENTVERSION,
Platform.getBundle(
Activator.PLUGIN_ID).getHeaders().get(
Constants.BUNDLE_VERSION));
}
/**
* @return the aut config map of the currently connected aut or null if
* there is no currently connected aut
*/
protected Map<String, String> getConnectedAUTsConfigMap() {
if (TestExecution.getInstance().getConnectedAutId() != null) {
String autID = getConnectedAutId().getExecutableName();
return ClientTest.instance()
.requestAutConfigMapFromAgent(autID);
}
return null;
}
/**
* @param testSuite testSuite
* @param monitor the progress monitor to use
* @param noRunOptMode the value of no-run option argument if it was specified, null otherwise
*/
private void startTestSuite(ITestSuitePO testSuite,
IProgressMonitor monitor, String noRunOptMode) {
Validate.notNull(testSuite, "No testsuite available"); //$NON-NLS-1$
ICapPO firstCap = null;
m_expectedNumberOfSteps = 0;
m_trav = new Traverser(testSuite);
m_trav.setIterMax(m_maxIterateCount);
try {
// build and show result Tree
monitor.subTask(Messages.
StartingTestSuite_resolvingTestStepsToExecute);
monitor.subTask(Messages.
StartingTestSuite_buildingTestExecutionTree);
Traverser copier = new Traverser(testSuite);
copier.setBuilding(true);
ResultTreeBuilder resultTreeBuilder = new ResultTreeBuilder(copier);
copier.addExecStackModificationListener(resultTreeBuilder);
ICapPO iterNode = copier.next();
while (iterNode != null) {
iterNode = copier.next();
m_expectedNumberOfSteps++;
}
Map<String, String> autConfigMap = getConnectedAUTsConfigMap();
resetMonitoringData(autConfigMap, monitor);
if (TestExecution.shouldExecutionStop(noRunOptMode,
TestExecutionConstants.RunSteps.BT)) {
endTestExecution();
return;
}
// end build tree
TestResultBP.getInstance().setResultTestModel(
new TestResult(resultTreeBuilder.getRootNode(),
autConfigMap));
initTestExecutionMessage(autConfigMap, monitor);
m_resultTreeTracker = new ResultTreeTracker(resultTreeBuilder.
getRootNode(), m_externalTestDataBP);
IProgressMonitor subMonitor = new SubProgressMonitor(monitor,
ClientTestImpl.TEST_SUITE_EXECUTION_RELATIVE_WORK_AMOUNT);
subMonitor.beginTask(
NLS.bind(Messages.StartWorkingWithTestSuite,
testSuite.getName()),
m_expectedNumberOfSteps);
m_stepCounter = new StepCounter(subMonitor);
addTestExecutionListener();
// set global delay for each test step
setStepSpeed(testSuite.getStepDelay());
ClientTest.instance().
fireTestExecutionChanged(new TestExecutionEvent(
State.TEST_EXEC_RESULT_TREE_READY));
monitor.subTask(
NLS.bind(Messages.StartingTestSuite,
testSuite.getName()));
firstCap = m_trav.next();
} catch (JBException e) {
LOG.error(e.getLocalizedMessage(), e);
fireError(e);
} catch (Exception e) {
// should properly catch all exceptions,
// fireError finishes all processes properly...
LOG.error(e.getLocalizedMessage(), e);
fireError(e);
}
if (firstCap != null) {
ClientTest.instance().
fireTestExecutionChanged(new TestExecutionEvent(
State.TEST_EXEC_START));
processCap(firstCap);
} else {
endTestExecution();
}
}
/**
* add the listener to the test execution traverser
*/
private void addTestExecutionListener() {
m_trav.addExecStackModificationListener(m_resultTreeTracker);
m_trav.addEventStackModificationListener(m_stepCounter);
m_trav.addExecStackModificationListener(m_stepCounter);
}
/**
* Determines if the given CAP should be skipped.
* @param cap the CAP
* @return <code>true</code> if the CAP should be skipped,
* <code>false</code> otherwise
*/
private boolean shouldSkipCAP(ICapPO cap) {
try {
ITDManager tdManager =
m_externalTestDataBP.getExternalCheckedTDManager(cap);
Iterator<IParamDescriptionPO> params = cap.getParameterListIter();
while (params.hasNext()) {
IParamDescriptionPO param = params.next();
String testData = tdManager.getCell(0, param);
ParamValueConverter converter =
new ModelParamValueConverter(testData, cap, param);
String value = converter.getExecutionString(
new ArrayList<ExecObject>(m_trav.getExecStackAsList()));
if (value.equals(Messages.SkipTestStepParameter)) {
return true;
}
}
} catch (InvalidDataException e) {
// This can be ignored here
} catch (JBException e) {
fireError(e);
}
return false;
}
/**
* Invokes the next step
*
* @param cap cap, which to create the corresponding message for
*
*/
private void processCap(ICapPO cap) {
ICapPO currCap = cap;
MessageCap messageCap = null;
if (currCap == null) {
endTestExecution();
return;
}
try {
if (LOG.isDebugEnabled()) {
LOG.debug(Messages.TestStep + StringConstants.COLON
+ StringConstants.SPACE + currCap.getName());
LOG.debug(Messages.Component + StringConstants.COLON
+ StringConstants.SPACE + currCap.getComponentName());
}
messageCap = buildMessageCap(currCap, false);
if (!m_stopped) {
CAPTestMessage capTestMessage = new CAPTestMessage(messageCap);
// StepSpeed
TimeUtil.delay(m_stepSpeed);
while (isPaused()) {
testConnection();
TimeUtil.delay(100);
}
if (!m_stopped) {
CAPTestResponseMessage clientResponse =
clientExecutionHandling(currCap, capTestMessage);
if (!m_stopped) { // project reload during AUT restart
// may trigger this
if (clientResponse != null) {
// The result of the CAP has already been determined
// by the
// client.
CAPTestResponseCommand responseCommand =
new CAPTestResponseCommand();
responseCommand.setMessage(clientResponse);
responseCommand.setMessageCap(messageCap);
responseCommand.execute();
} else {
final int timeOut =
calculateRequestTimeout(messageCap);
// send message to server
AUTConnection.getInstance().request(capTestMessage,
new CAPTestResponseCommand(), timeOut);
}
}
} else {
endTestExecution();
}
}
} catch (NotConnectedException bnce) {
LOG.error(Messages.AUTConnectionFails, bnce);
} catch (CommunicationException bce) {
LOG.error(Messages.CommunicationWithAUTFails, bce);
fireError(bce);
} catch (LogicComponentNotManagedException blcnme) {
LOG.error(blcnme.getMessage(), blcnme);
fireComponentError();
} catch (InvalidDataException ide) { // NOPMD by al on 3/19/07 1:24 PM
// never happens here, because buildMessageCap(cap, false) is called
// with false!
}
}
/**
* Calculates the request timeout. Important if an action has a higher
* timeout than the standard request timeout.
* @param messageCap the MessageCap
* @return the calculated timeout.
*/
private int calculateRequestTimeout(MessageCap messageCap) {
List<Integer> timeOuts = new ArrayList<Integer>();
IParamDescriptionPO desc1 = m_currentCap.getParameterForUniqueId(
CSConstants.TIMEOUT);
timeOuts.add(m_currentCap.getParameterList().indexOf(desc1));
desc1 = m_currentCap.getParameterForUniqueId("CompSystem.TimeMillSec"); //$NON-NLS-1$
timeOuts.add(m_currentCap.getParameterList().indexOf(desc1));
int timeout = 0;
for (int index : timeOuts) {
if (index > -1) {
final MessageParam param = messageCap
.getMessageParams().get(index);
final String paramTimeOut = param.getValue();
timeout += Integer.parseInt(paramTimeOut);
}
}
// Special handling for Show Text
boolean isShowText = messageCap.getMethod().equals("rcShowText"); //$NON-NLS-1$
if (isShowText) {
int showTextTimeout = calculateShowTextTimeout(messageCap);
if (showTextTimeout != -1) {
timeout += showTextTimeout;
}
}
return m_requestTimeout + timeout;
}
/**
* Handles the client-actions
* @param cap the cap to execute
* @param capTestMessage the CAPTestMessage.
* @return a response if the result of testing the CAP is determined
* entirely by the client. Returns <code>null</code> if the CAP
* message should be sent to the server.
*/
private CAPTestResponseMessage clientExecutionHandling(ICapPO cap,
CAPTestMessage capTestMessage) {
if (shouldSkipCAP(cap)) {
CAPTestResponseMessage response = new CAPTestResponseMessage();
response.setState(CAPTestResponseMessage.TEST_SKIP);
response.setMessageCap(capTestMessage.getMessageCap());
return response;
}
Action action = cap.getMetaAction();
if (!action.isClientAction()) {
return null;
}
if (LOG.isDebugEnabled()) {
LOG.debug(Messages.ExecutingClientAction + StringConstants.COLON
+ StringConstants.SPACE + action.getPostExecutionCommand());
}
final String postExecCommandClass = action.getPostExecutionCommand();
final IPostExecutionCommand command = m_postExecCmdFactory
.createCommand(postExecCommandClass);
TestErrorEvent errorEvent = executePostExecCommand(command);
if (errorEvent != null) {
CAPTestResponseMessage response = new CAPTestResponseMessage();
response.setTestErrorEvent(errorEvent);
response.setMessageCap(capTestMessage.getMessageCap());
return response;
}
return null;
}
/**
* Calculates the timeout for a Show Text Action
*
* @param messageCap The message cap
* @return The timeout to use, or -1 if the timeout cannot be calculated
*/
private int calculateShowTextTimeout(MessageCap messageCap) {
MessageParam textParam =
messageCap.getMessageParams().get(0);
MessageParam timePerWordParam =
messageCap.getMessageParams().get(2);
try {
int numWords = StringParsing.countWords(textParam.getValue());
return Integer.parseInt(timePerWordParam.getValue())
* numWords;
} catch (NumberFormatException e) {
LOG.warn(Messages.ErrorParsingTimeoutParameter + StringConstants.DOT
+ StringConstants.SPACE + Messages.UsingDefaultValue
+ StringConstants.DOT, e);
}
return -1;
}
/**
* Builds the messageCap with the data sending to server
*
* @param cap cap to create the corresponding message cap for
* @param runIncomplete sets this method in "run incomplete"-mode.
* It throws InvalidDataException if missing test data.
* @return MessageCap
* @throws LogicComponentNotManagedException
* if component not found in objectMap.
* if building compSystem fails.
* if component cannot be found.
* @throws InvalidDataException in case of "run incomplete"-mode
* and missing test data.
*/
private MessageCap buildMessageCap(ICapPO cap, boolean runIncomplete)
throws InvalidDataException, LogicComponentNotManagedException {
MessageCap messageCap;
String logicalName = null;
try {
messageCap = new MessageCap();
CompSystem compSystem = ComponentBuilder.getInstance()
.getCompSystem();
m_currentCap = cap;
ITestSuitePO ts = (ITestSuitePO)m_trav.getRoot();
IAUTMainPO aut = ts.getAut();
Component comp = compSystem.findComponent(cap.getComponentType());
// Find the component name. It may be overridden in one or
// more ExecTestCase nodes.
if (!StringUtils.isEmpty(cap.getComponentName())) {
logicalName = m_compNamesBP.findCompName(
m_trav.getExecStackAsNodeList(), cap,
cap.getComponentName(),
CompNameManager.getInstance()).getCompName();
}
messageCap.setResolvedLogicalName(logicalName);
IComponentIdentifier technicalName = null;
technicalName = getTechnicalName(logicalName, aut, comp);
if (comp.isConcrete() && ((ConcreteComponent)comp)
.hasDefaultMapping()) {
messageCap.sethasDefaultMapping(true);
}
if (technicalName == null) {
throw new LogicComponentNotManagedException(
StringConstants.EMPTY,
MessageIDs.E_COMPONENT_NOT_MANAGED);
}
Action action = comp.findAction(cap.getActionName());
messageCap.setAction(action);
messageCap.setMethod(action.getMethod());
messageCap.setPostExecutionCommand(
action.getPostExecutionCommand());
messageCap.setCi(technicalName);
if (cap.getParameterList() != null) {
messageCap = configureMessageCap(cap, messageCap, action,
runIncomplete);
}
return messageCap;
} catch (LogicComponentNotManagedException blcnme) {
throw blcnme;
} catch (InvalidDataException e) {
if (runIncomplete) {
throw e;
}
// Never happens if runIncomplete==false because called method
// handles this exception in this case!
return null;
}
}
/**
*
* @param logicalName
* guid of the logical name for which to find the technical name
* @param aut
* AUT information
* @param comp
* component
* @return a ComponentIdentifier or null
*/
private IComponentIdentifier getTechnicalName(String logicalName,
IAUTMainPO aut, Component comp) {
IObjectMappingPO om = aut.getObjMap();
IComponentIdentifier technicalName;
try {
technicalName = om.getTechnicalName(logicalName);
} catch (LogicComponentNotManagedException e) {
technicalName = null;
}
if (technicalName == null && comp instanceof ConcreteComponent) {
ConcreteComponent cc = ((ConcreteComponent) comp);
String toolkit = aut.getToolkit();
if (cc.hasDefaultMapping() && cc.getComponentClass() != null) {
return ToolkitSupportBP.
getIdentifierOfMostAbstractRealizingComponentInToolkit(
toolkit, cc);
}
}
return technicalName;
}
/**
* sets the properties of messageCap
*
* @param cap cap
* @param messageCap corresponding messageCap
* @param action corresponding action
* @param runIncomplete if true, throws an InvalidDataException
* if missing test data, otherwise it handles the exception itself.
* @throws InvalidDataException in case of missing testdata in
* "run incomplete"-mode.
* @return configured messageCap
*/
private MessageCap configureMessageCap(ICapPO cap, MessageCap messageCap,
Action action, boolean runIncomplete) throws InvalidDataException {
ITDManager tdManager = null;
try {
tdManager = m_externalTestDataBP.getExternalCheckedTDManager(cap);
} catch (JBException gde) {
fireError(gde);
}
if (tdManager != null) {
for (IParamDescriptionPO desc : cap.getParameterList()) {
if (m_stopped) {
// Stop processing parameters if execution has already
// stopped.
return messageCap;
}
MessageParam messageParam = createMessageParam(desc, action);
messageCap.addMessageParam(messageParam);
String date = tdManager.getCell(0, desc);
String value = null;
boolean isMandatoryParameter = !ParamNameBP
.isOptionalParameter(cap, desc.getUniqueId());
if (isMandatoryParameter) {
Validate.notEmpty(date,
NLS.bind(Messages.NoTestdataAvailableForCAP,
new String[]{cap.getName(), desc.getName()}));
}
try {
final int dsNumber = m_trav.getDataSetNumber();
m_varStore.store(CURRENT_DATASET_NUMBER, String.valueOf(
dsNumber + 1)); // 1-based for the user!
ParamValueConverter conv = new ModelParamValueConverter(
date, cap, desc);
List <ExecObject> stackList =
new ArrayList<ExecObject>(m_trav.getExecStackAsList());
value = conv.getExecutionString(stackList);
} catch (InvalidDataException e) {
if (!runIncomplete || !isMandatoryParameter) {
StringBuilder msgbuild = new StringBuilder();
msgbuild.append(Messages.NoValueAvailableForParameter);
msgbuild.append(StringConstants.COLON);
msgbuild.append(StringConstants.SPACE);
msgbuild.append(desc.getName());
msgbuild.append(StringConstants.SPACE);
msgbuild.append(Messages.InNode);
msgbuild.append(StringConstants.COLON);
msgbuild.append(StringConstants.SPACE);
msgbuild.append(cap.getName());
LOG.error(msgbuild.toString(), e);
fireError(e);
} else {
throw e;
}
}
messageParam.setValue(value);
}
}
return messageCap;
}
/**
* creates a messagParam corresponding to CAPParamDescription
*
* @param desc parameter object
* @param action corresponding action to this cap
* @return appropriate MessageParam
*/
private MessageParam createMessageParam(IParamDescriptionPO desc,
Action action) {
Param xmlParam = action.findParam(desc.getUniqueId());
if (LOG.isDebugEnabled()) {
LOG.debug(Messages.Param + StringConstants.COLON
+ StringConstants.SPACE + xmlParam.getName());
}
MessageParam messageParam = new MessageParam();
messageParam.setType(xmlParam.getType());
return messageParam;
}
/**
* A wrapper method to catch all exceptions in the test execution thread
* Uncaught exceptions would result in hanging test executions
* @param msg the response message
*/
public void processServerResponseWrapper(
CAPTestResponseMessage msg) {
try {
processServerResponse(msg);
} catch (Exception e) {
fireError(e);
}
}
/**
* verifies the response of server for execution of a cap
* @param msg The response message.
*/
public void processServerResponse(final CAPTestResponseMessage msg) {
ICapPO nextCap = null;
processPostExecution(msg);
TestResultNode resultNode = m_resultTreeTracker.getEndNode();
m_testResultNode = resultNode;
MessageCap mc = msg.getMessageCap();
resultNode.setComponentName(CompNameManager.getInstance().
getNameByGuid(mc.getResolvedLogicalName()));
IComponentIdentifier ci = mc.getCi();
resultNode.setOmHeuristicEquivalence(ci.getMatchPercentage());
resultNode.setNoOfSimilarComponents(
ci.getNumberOfOtherMatchingComponents());
final boolean testOk = !msg.hasTestErrorEvent();
if (msg.getState() == CAPTestResponseMessage.PAUSE_EXECUTION) {
pauseExecution(PauseMode.PAUSE);
}
if (testOk) {
processResultOk(msg, resultNode);
} else {
processErrorEventOccured(msg, resultNode);
}
while (isPaused()) {
testConnection();
TimeUtil.delay(100);
}
if (!m_stopped) {
try {
nextCap = testOk || m_skipError ? m_trav.next()
: m_trav.next(msg.getTestErrorEvent().getId());
m_skipError = false;
} catch (JBException e) {
LOG.error(Messages.IncompleteTestdata, e);
fireError(e);
}
if (nextCap != null) {
processCap(nextCap);
} else {
if (LOG.isInfoEnabled()) {
LOG.info(Messages.TestsuiteFinished);
}
endTestExecution();
}
}
}
/**
* Sets the result of the given result node depending on whether the CAP was
* actually executed or was skipped
* @param msg the CAPTestResponseMessage of the CAP
* @param resultNode the resultNode of the CAP
*/
private void processResultOk(final CAPTestResponseMessage msg,
TestResultNode resultNode) {
if (msg.getState() == CAPTestResponseMessage.TEST_SKIP) {
resultNode.setResult(TestResultNode.SKIPPED, null);
} else {
resultNode.setResult(m_trav.getSuccessResult(), null);
}
}
/**
* Processes the result if an error event occured.
* @param msg the CAPTestResponseMessage of the CAP
* @param resultNode the resultNode of the CAP
*/
private void processErrorEventOccured(final CAPTestResponseMessage msg,
TestResultNode resultNode) {
// ErrorEvent has occured
TestErrorEvent event = msg.getTestErrorEvent();
if (StringUtils.isEmpty(resultNode.getCommandLog())) {
String commandLogKey = TestErrorEvent.Property.COMMAND_LOG_KEY;
String commandLog = (String) event.getProps().get(commandLogKey);
resultNode.setCommandLog(commandLog);
event.getProps().remove(commandLogKey);
}
ReentryProperty reentry = m_trav.getEventHandlerReentry(
event.getId());
if (reentry.equals(ReentryProperty.RETRY)) {
resultNode.setResult(TestResultNode.RETRYING, event);
} else {
m_stepCounter.incrementNumberOfFailedSteps();
if (reentry.equals(ReentryProperty.CONDITION)) {
if (isNodeWithinCondStatement(resultNode)) {
resultNode.setResult(TestResultNode.CONDITION_FAILED,
event);
}
} else {
resultNode.setResult(TestResultNode.ERROR, event);
if (m_autoScreenshot) {
addScreenshotThroughAgent(false);
}
if (ClientTest.instance()
.isPauseTestExecutionOnError()) {
pauseExecution(PauseMode.PAUSE);
}
}
}
}
/**
* Determines whether a node is contained within a Conditional statement
* @param node the node to check
* @return whether is a descendant of a Conditional Statement
*/
private boolean isNodeWithinCondStatement(TestResultNode node) {
TestResultNode realNode = node;
do {
realNode = realNode.getParent();
} while (realNode.getNode() != null
&& !(realNode.getNode() instanceof ICondStructPO));
return realNode.getNode() instanceof IConditionalStatementPO;
}
/**
* asks the AUT Agent or the AUT to take a screenshot
* @param agent true if we send the request to the AUT Agent, false if to the AUT
*/
private void addScreenshotThroughAgent(boolean agent) {
ICommand command;
Message message;
BaseConnection connect;
if (agent) {
TestResultNode newNode = m_resultTreeTracker.getEndNode();
if (newNode != m_testResultNode && newNode != null) {
m_testResultNode = newNode;
}
if (m_testResultNode == null) {
return;
}
command = new TakeScreenshotAUTAgentResponseCommand(
m_testResultNode);
message = new TakeScreenshotAUTAgentMessage();
} else {
command = new TakeScreenshotResponseCommand(m_testResultNode);
message = new TakeScreenshotMessage();
}
// Send request to AUT (or AUTAgent) and wait for response
try {
if (agent) {
connect = AutAgentConnection.getInstance();
} else {
connect = AUTConnection.getInstance();
}
connect.request(message, command,
TimeoutConstants.CLIENT_SERVER_TIMEOUT_TAKE_SCREENSHOT);
} catch (NotConnectedException nce) {
if (LOG.isErrorEnabled()) {
LOG.error(nce.getLocalizedMessage(), nce);
}
} catch (CommunicationException ce) {
if (LOG.isErrorEnabled()) {
LOG.error(ce.getLocalizedMessage(), ce);
}
}
}
/**
* Processes the post execution of an action
* @param msg the CAPTestResponseMessage.
*/
private void processPostExecution(CAPTestResponseMessage msg) {
m_varStore.store(LAST_ACTION_RETURN, msg.getReturnValue());
final String cmdClassName = msg.getMessageCap()
.getPostExecutionCommand();
if (cmdClassName != null && cmdClassName.length() > 0
&& !m_currentCap.getMetaAction().isClientAction()) {
TestErrorEvent errorEvent = executePostExecCommand(
m_postExecCmdFactory.createCommand(cmdClassName));
if (msg.getTestErrorEvent() == null
&& errorEvent != null) {
msg.setTestErrorEvent(errorEvent);
}
}
}
/**
* Loads, instantiates and executes the given IPostExecutionCommand class
*
* @param cmd
* the IPostExecutionCommand to execute.
* @return a TestErrorEvent representing an error that occurred during
* execution, or <code>null</code> if no such error occurs.
*/
private TestErrorEvent executePostExecCommand(IPostExecutionCommand cmd) {
if (cmd instanceof AbstractPostExecutionCommand) {
AbstractPostExecutionCommand aCmd =
(AbstractPostExecutionCommand) cmd;
aCmd.setCurrentCap(m_currentCap);
aCmd.setExternalTestDataBP(m_externalTestDataBP);
aCmd.setTraverser(m_trav);
}
try {
return cmd.execute();
} catch (JBException e) {
LOG.error(NLS.bind(Messages.ErrorExecutingCommand, cmd.getClass()
.getName(), e.getLocalizedMessage()));
fireError(e);
return null;
}
}
/**
* Tests the connection to server (sends a NullMessage to server)
*
*/
protected void testConnection() {
try {
AUTConnection.getInstance().send(new NullMessage());
} catch (CommunicationException e) {
fireError(new JBException(MessageIDs.getMessage(
MessageIDs.E_INTERRUPTED_CONNECTION),
MessageIDs.E_INTERRUPTED_CONNECTION));
}
}
/**
* Sends a init test execution message
*
* @param autConfigMap
* the config map to use
* @param monitor the monitor to use
*/
private void initTestExecutionMessage(Map<String, String> autConfigMap,
IProgressMonitor monitor) {
try {
InitTestExecutionMessage msg = new InitTestExecutionMessage();
if (autConfigMap != null) {
monitor.subTask(Messages.
StartingTestSuite_activatingAUT);
msg.setDefaultActivationMethod(ActivationMethod
.getRCString(autConfigMap
.get(AutConfigConstants.ACTIVATION_METHOD)));
msg.setErrorHighlighting(Boolean.valueOf(autConfigMap.get(
AutConfigConstants.ERROR_HIGHLIGHT)));
AUTConnection.getInstance().send(msg);
}
} catch (CommunicationException exc) {
fireError(exc);
}
}
/**
* Fires an event if test fails
*
* @param e
* Exception
*/
private void fireError(Exception e) {
ClientTest.instance().fireTestExecutionChanged(
new TestExecutionEvent(State.TEST_EXEC_FAILED, e));
endTestExecution();
}
/**
* Fires an event if test fails, because the component name is wrong.
*/
private void fireComponentError() {
ClientTest.instance().
fireTestExecutionChanged(new TestExecutionEvent(
State.TEST_EXEC_COMPONENT_FAILED));
endTestExecution();
}
/**
*
* @param stepSpeed
* The stepSpeed to set.
*/
public void setStepSpeed(int stepSpeed) {
if (stepSpeed > TimingConstantsClient.MIN_STEP_SPEED) {
m_stepSpeed = stepSpeed;
} else {
m_stepSpeed = TimingConstantsClient.MIN_STEP_SPEED;
}
}
/**
* Stop the test execution
*
*/
public void stopExecution() {
synchronized (this) {
if (!m_stopped) {
m_stopped = true;
setPaused(false);
m_timerStore.clear();
try {
AUTConnection.getInstance().getCommunicator()
.interruptAllTimeouts();
} catch (ConnectionException e) {
fireError(e);
}
if (LOG.isInfoEnabled()) {
LOG.info(Messages.TestsuiteIsStopped);
}
ClientTest.instance().fireEndTestExecution();
try {
AUTConnection.getInstance().close();
} catch (ConnectionException e) {
// Do nothing. Connection already closed.
}
}
}
}
/**
* This method will reset the profiling agent.
*
* @param autConfigMap
* the aut config map to use
* @param monitor the monitor to use
*/
private void resetMonitoringData(Map<String, String> autConfigMap,
IProgressMonitor monitor) {
if (autConfigMap != null) {
String resetString = autConfigMap
.get(MonitoringConstants.RESET_AGENT);
if (resetString != null) {
boolean reset = Boolean.valueOf(resetString);
if (reset) {
try {
monitor.subTask(Messages.
StartingTestSuite_resettingMonitoringData);
ResetMonitoringDataMessage message =
new ResetMonitoringDataMessage(
AUTConnection.getInstance().getConnectedAutId()
.getExecutableName());
AutAgentConnection.getInstance().send(message);
} catch (NotConnectedException nce) {
LOG.error(nce.getLocalizedMessage(), nce);
} catch (CommunicationException ce) {
LOG.error(ce.getLocalizedMessage(), ce);
}
}
}
}
}
/**
* end the test execution normally
*/
public void endTestExecution() {
// Send request to aut starter and wait for response
ICommand command = new EndTestExecutionResponseCommand();
Message message = new EndTestExecutionMessage();
try {
AUTConnection.getInstance().request(message, command,
EndTestExecutionMessage.TIMEOUT);
} catch (NotConnectedException nce) {
if (LOG.isWarnEnabled()) {
LOG.warn(nce.getLocalizedMessage(), nce);
}
stopExecution();
} catch (CommunicationException ce) {
if (LOG.isWarnEnabled()) {
LOG.warn(ce.getLocalizedMessage(), ce);
}
stopExecution();
}
}
/**
* Toggles the pause state of the test execution
* @param pm the pause mode to use
*/
public void pauseExecution(PauseMode pm) {
switch (pm) {
case PAUSE:
if (!isPaused()) {
pauseExecution(PauseMode.TOGGLE);
}
break;
case UNPAUSE:
if (isPaused()) {
pauseExecution(PauseMode.TOGGLE);
}
break;
case TOGGLE:
setPaused(!isPaused());
if (isPaused()) {
if (LOG.isInfoEnabled()) {
LOG.info(Messages.TestsuiteIsPaused);
}
ClientTest.instance().fireTestExecutionChanged(
new TestExecutionEvent(
State.TEST_EXEC_PAUSED));
} else {
if (LOG.isInfoEnabled()) {
LOG.info(Messages.TestexecutionHasResumed);
}
ClientTest.instance().fireTestExecutionChanged(
new TestExecutionEvent(
State.TEST_EXEC_START));
}
break;
case CONTINUE_WITHOUT_EH:
m_skipError = true;
pauseExecution(PauseMode.UNPAUSE);
break;
default:
break;
}
}
/**
* timeout()
*/
public void timeout() {
if (m_autoScreenshot) {
addScreenshotThroughAgent(true);
}
m_resultTreeTracker.getEndNode().setResult(TestResultNode.ABORT, null);
fireError(new JBException(MessageIDs.getMessage(MessageIDs.
E_TIMEOUT_CONNECTION), MessageIDs.E_TIMEOUT_CONNECTION));
}
/**
* @return Returns the actualCap.
*/
public ICapPO getActualCap() {
return m_currentCap;
}
/**
* Traverser for Execution
* @return Traverser
*/
public Traverser getTrav() {
return m_trav;
}
/**
* @return true if Test Suite is paused
*/
protected boolean isPaused() {
return m_paused;
}
/**
* @return the ID of the currently connected Running AUT.
*/
public AutIdentifier getConnectedAutId() {
try {
return AUTConnection.getInstance().getConnectedAutId();
} catch (ConnectionException e) {
// Do nothing. No connection exists, so we'll just end up returning
// null.
}
return null;
}
/**
*
* @return the AUT Definition for the currently connected Running AUT.
*/
public IAUTMainPO getConnectedAut() {
return AutAgentRegistration.getAutForId(getConnectedAutId(),
GeneralStorage.getInstance().getProject());
}
/**
* @return Returns the startedTestSuite.
*/
public ITestSuitePO getStartedTestSuite() {
return m_startedTestSuite;
}
/**
*
* @return the started Test Job, or <code>null</code> if no Test Job is
* currently running.
*/
public ITestJobPO getStartedTestJob() {
return m_startedTestJob;
}
/**
*
* @param startedTestJob The Test Job to set.
*/
public void setStartedTestJob(ITestJobPO startedTestJob) {
m_startedTestJob = startedTestJob;
}
/**
* @param startedTestSuite The startedTestSuite to set.
*/
public void setStartedTestSuite(ITestSuitePO startedTestSuite) {
m_startedTestSuite = startedTestSuite;
}
/**
* @author BREDEX GmbH
* @created 28.07.2006
*/
private class PostExecCommandFactory {
/**
* Cache of instantiated IPostExecutionCommands
* The key is the full qualified name of the
* IPostExecutionCommand class, the value is the instance of the
* class.
*/
private Map<String, IPostExecutionCommand> m_commandCache =
new HashMap<String, IPostExecutionCommand>();
/**
* Instantiates an IPostExecutionCommand of the given class name.
* @param commandClassName IPostExecutionCommand to instantiate
* @return an IPostExecutionCommand instance
*/
public IPostExecutionCommand createCommand(String commandClassName) {
Class cmdClazz = null;
Object cmdInstance = m_commandCache.get(commandClassName);
if (cmdInstance != null) {
return (IPostExecutionCommand)cmdInstance;
}
try {
cmdClazz = Class.forName(commandClassName);
} catch (ClassNotFoundException e) {
LOG.error("ClassNotFoundException", e); //$NON-NLS-1$
fireError(e);
}
Constructor constructor = null;
try {
constructor = cmdClazz.getConstructor(new Class[0]);
cmdInstance = constructor.newInstance(new Object[0]);
} catch (SecurityException e) {
LOG.error("SecurityException", e); //$NON-NLS-1$
fireError(e);
} catch (NoSuchMethodException e) {
try {
// maybe cmdClazz is a non static inner class
// of TestExecution?
constructor = cmdClazz.getConstructor(
new Class[]{TestExecution.this.getClass()});
cmdInstance = constructor.newInstance(
new Object[]{TestExecution.this});
} catch (SecurityException e1) {
LOG.error("SecurityException", e1); //$NON-NLS-1$
fireError(e1);
} catch (NoSuchMethodException e1) {
LOG.error("NoSuchMethodException", e1); //$NON-NLS-1$
fireError(e1);
} catch (IllegalArgumentException e1) {
LOG.error("IllegalArgumentException", e1); //$NON-NLS-1$
fireError(e1);
} catch (InstantiationException e1) {
LOG.error("InstantiationException", e1); //$NON-NLS-1$
fireError(e1);
} catch (IllegalAccessException e1) {
LOG.error("IllegalAccessException", e1); //$NON-NLS-1$
fireError(e1);
} catch (InvocationTargetException e1) {
LOG.error("InvocationTargetException", e1); //$NON-NLS-1$
fireError(e1);
}
} catch (IllegalArgumentException e) {
LOG.error("IllegalArgumentException", e); //$NON-NLS-1$
fireError(e);
} catch (InstantiationException e) {
LOG.error("InstantiationException", e); //$NON-NLS-1$
fireError(e);
} catch (IllegalAccessException e) {
LOG.error("IllegalAccessException", e); //$NON-NLS-1$
fireError(e);
} catch (InvocationTargetException e) {
LOG.error("InvocationTargetException", e); //$NON-NLS-1$
fireError(e);
}
IPostExecutionCommand cmd = (IPostExecutionCommand)cmdInstance;
m_commandCache.put(commandClassName, cmd);
return cmd;
}
}
/**
* IPostExecutionCommand to store a value read
* by Action "CompSystem.ReadValue" in the m_varStore
*
* @author BREDEX GmbH
* @created 24.07.2006
*/
public class VariableStorerCmd extends AbstractPostExecutionCommand {
/**
* Constructor
*/
public VariableStorerCmd() {
super();
}
/**
* {@inheritDoc}
*/
public TestErrorEvent execute() throws JBException {
// FIXME zeb Simply retrieving the first parameter has worked so
// far because all Store/Read actions list Variable Name
// as the first parameter. The first action that does not
// follow this "convention" will result in errors
// (possibly very subtle errors). We need to figure out a
// way to make this generic (ex. as an argument to the
// VariableStorerCmd defined in the
// ComponentConfiguration.xml) in order to prevent
// customers wishing to write extensions (as well as
// ourselves!) from running head-first into this problem.
IParamDescriptionPO desc =
m_currentCap.getParameterList().get(0);
try {
ITDManager tdManager =
m_externalTestDataBP.getExternalCheckedTDManager(
m_currentCap);
String date = tdManager.getCell(0, desc);
String varName = getValueForParam(date, m_currentCap, desc);
m_varStore.store(varName, m_varStore.getValue(
LAST_ACTION_RETURN));
return null;
} catch (IllegalArgumentException e) {
throw new JBException("IllegalArgumentException", e, // //$NON-NLS-1$
MessageIDs.E_STEP_EXEC);
} catch (InvalidDataException e) {
throw new JBException("InvalidDataException", e, // //$NON-NLS-1$
MessageIDs.E_STEP_EXEC);
}
}
}
/**
* IPostExecutionCommand to store properties in the m_varStore
*
* @author BREDEX GmbH
* @created 29.11.2015
*/
public class PropertyStorerCmd extends AbstractPostExecutionCommand {
/**
* Constructor
*/
public PropertyStorerCmd() {
super();
}
/**
* {@inheritDoc}
*/
public TestErrorEvent execute() throws JBException {
try {
String propertyMap = m_varStore.getValue(
LAST_ACTION_RETURN);
Map<String, String> propMap = StringParsing
.convertToMap(propertyMap);
for (String key : propMap.keySet()) {
m_varStore.store(key, propMap.get(key));
}
//Store properties as string in the specified Variable
IParamDescriptionPO desc =
m_currentCap.getParameterList().get(0);
try {
ITDManager tdManager = m_externalTestDataBP
.getExternalCheckedTDManager(m_currentCap);
String date = tdManager.getCell(0, desc);
String varName = getValueForParam(date, m_currentCap, desc);
m_varStore.store(varName,
m_varStore.getValue(LAST_ACTION_RETURN));
return null;
} catch (IllegalArgumentException e) {
throw new JBException("IllegalArgumentException", e, // //$NON-NLS-1$
MessageIDs.E_STEP_EXEC);
} catch (InvalidDataException e) {
throw new JBException("InvalidDataException", e, // //$NON-NLS-1$
MessageIDs.E_STEP_EXEC);
}
} catch (IllegalArgumentException e) {
throw new JBException("IllegalArgumentException", e, // //$NON-NLS-1$
MessageIDs.E_STEP_EXEC);
}
}
}
/**
* abstract class for timer commands
*
* @author BREDEX GmbH
* @created 19.08.2009
*/
public abstract class AbstractTimerCmd
extends AbstractPostExecutionCommand {
/** @return the timer name */
protected String getTimerName() throws JBException {
return getValueForParam(CSConstants.TIMER_NAME);
}
}
/**
* IPostExecutionCommand to start a timer
* by Action "CompSystem.StartTimer"
*
* @author BREDEX GmbH
* @created 19.08.2009
*/
public class StartTimerCmd extends AbstractTimerCmd {
/**
* {@inheritDoc}
*/
public TestErrorEvent execute() throws JBException {
try {
String timerName = getTimerName();
String variableName = getValueForParam(
CSConstants.VARIABLE_TO_STORE_ABSOLUTE_START_TIME);
Long curTimeInMillisecs =
new Long(System.currentTimeMillis());
getTimerStore().put(timerName, curTimeInMillisecs);
m_varStore.store(variableName, curTimeInMillisecs.toString());
} catch (IllegalArgumentException e) {
throw new JBException("IllegalArgumentException", e, //$NON-NLS-1$
MessageIDs.E_STEP_EXEC);
} catch (InvalidDataException e) {
throw new JBException("InvalidDataException", e, // //$NON-NLS-1$
MessageIDs.E_STEP_EXEC);
}
return null;
}
}
/**
* IPostExecutionCommand to read a timer
* by Action "CompSystem.ReadTimer"
*
* @author BREDEX GmbH
* @created 19.08.2009
*/
public class ReadTimerCmd extends AbstractTimerCmd {
/**
* {@inheritDoc}
*/
public TestErrorEvent execute() throws JBException {
try {
String timerName = getTimerName();
String variableName = getValueForParam(
CSConstants.VARIABLE_TO_STORE_TIME_DELTA_SINCE_TIMER_START);
Long timerTimeInMillisecs = getTimerStore().get(timerName);
if (timerTimeInMillisecs == null) {
return EventFactory.createActionError(
TestErrorEvent.TIMER_NOT_FOUND);
}
Long curTimeInMillisecs = new Long(System.currentTimeMillis());
Long timeDelta = curTimeInMillisecs - timerTimeInMillisecs;
m_varStore.store(variableName, timeDelta.toString());
} catch (IllegalArgumentException e) {
throw new JBException("IllegalArgumentException", e, //$NON-NLS-1$
MessageIDs.E_STEP_EXEC);
} catch (InvalidDataException e) {
throw new JBException("InvalidDataException", e, // //$NON-NLS-1$
MessageIDs.E_STEP_EXEC);
}
return null;
}
}
/**
* Implementation for the manual test step
*
* @author BREDEX GmbH
* @created Aug 19, 2010
*/
public class ManualTestStepCmd extends AbstractPostExecutionCommand {
/**
* <code>m_comment</code>
*/
private String m_comment = null;
/**
* <code>m_status</code>
*/
private boolean m_status = false;
/**
* {@inheritDoc}
*/
public TestErrorEvent execute() throws JBException {
try {
String actionToPerform =
getValueForParam(CSConstants.ACTION_TO_PERFOM);
String expectedBehavior =
getValueForParam(CSConstants.EXPECTED_BEHAVIOR);
int timeout = Integer.parseInt(
getValueForParam(CSConstants.TIMEOUT));
Message message = new DisplayManualTestStepMessage(
actionToPerform, expectedBehavior, timeout);
ICommand command =
new DisplayManualTestStepResponseCommand(this);
AutAgentConnection.getInstance()
.request(message, command, timeout);
int waited = 0;
while ((command.getMessage() == null) && (waited <= timeout)) {
try {
Thread.sleep(200);
waited += 200;
} catch (InterruptedException e) {
// Do nothing
}
}
if (!(waited <= timeout)) {
return EventFactory.createActionError(
TestErrorEvent.CONFIRMATION_TIMEOUT);
} else if (!m_status) {
return EventFactory.createVerifyFailed(String
.valueOf(expectedBehavior), String
.valueOf(m_comment));
}
return null;
} catch (IllegalArgumentException e) {
throw new JBException("IllegalArgumentException", e, // //$NON-NLS-1$
MessageIDs.E_STEP_EXEC);
} catch (InvalidDataException e) {
throw new JBException("InvalidDataException", e, // //$NON-NLS-1$
MessageIDs.E_STEP_EXEC);
}
}
/**
* @param comment the comment to set
*/
public void setComment(String comment) {
m_comment = comment;
}
/**
* @return the comment
*/
public String getComment() {
return m_comment;
}
/**
* @param status the status to set
*/
public void setStatus(boolean status) {
m_status = status;
}
/**
* @return the status
*/
public boolean isStatus() {
return m_status;
}
}
/**
* @author BREDEX GmbH
* @created 30.04.2013
*/
private static class AUTTerminationListener
implements IAutRegistrationListener {
/**
* indicates whether the AUT terminated or not
*/
private boolean m_autTerminated = false;
/**
* the AUTs ID to monitor
*/
private AutIdentifier m_autId = null;
/**
* flag indicating that the AUT has been re-started
*/
private AtomicBoolean m_hasAutRestarted = new AtomicBoolean(false);
/**
* @param autID
* the AUTs ID to monitor
*/
public AUTTerminationListener(AutIdentifier autID) {
m_autId = autID;
}
/** {@inheritDoc} */
public void handleAutRegistration(
AutRegistrationEvent event) {
if (m_autId.equals(event.getAutId())) {
if (event.getStatus()
== RegistrationStatus.Deregister) {
setAutTerminated(true);
}
if (hasAutTerminated() && event.getStatus()
== RegistrationStatus.Register) {
hasAutRestarted().set(true);
}
}
}
/**
* @return the isAutRestarted
*/
public AtomicBoolean hasAutRestarted() {
return m_hasAutRestarted;
}
/**
* @return the autTerminated
*/
public boolean hasAutTerminated() {
return m_autTerminated;
}
/**
* @param autTerminated the autTerminated to set
*/
private void setAutTerminated(boolean autTerminated) {
m_autTerminated = autTerminated;
}
}
/**
* @author BREDEX GmbH
* @created 30.04.2013
*/
public class PrepareForShutdownCmd implements IPostExecutionCommand {
/** {@inheritDoc} */
public TestErrorEvent execute() throws JBException {
AUTConnection.getInstance().getCommunicator()
.send(new PrepareForShutdownMessage(false, m_stepSpeed));
return null;
}
}
/**
* @author BREDEX GmbH
* @created 30.04.2013
*/
public class SyncShutdownAndRestartCmd extends AbstractRestartCmd {
@Override
protected int getTerminationTimeout() throws JBException {
String timeout = getValueForParam(CSConstants.TIMEOUT);
int parseInt = 0;
try {
parseInt = Integer.parseInt(timeout);
} catch (NumberFormatException nfe) {
LOG.error(nfe.getLocalizedMessage(), nfe);
}
return parseInt;
}
}
/**
* @author BREDEX GmbH
* @created 30.04.2013
*/
public abstract class AbstractRestartCmd
extends AbstractPostExecutionCommand {
/**
* timeout constant for using not timeout and force the AUTs restart
*/
protected static final int NO_TIMEOUT__FORCE_RESTART = 0;
/**
* {@inheritDoc}
*/
public final TestErrorEvent execute() throws JBException {
final AutIdentifier autId = getConnectedAutId();
AUTTerminationListener registrationListener =
new AUTTerminationListener(autId);
try {
TimeUtil.delay(2000);
if (LOG.isDebugEnabled()) {
LOG.debug(Messages.RequestingAUTAgentToCloseAUTConnection);
}
AUTConnection.getInstance().getCommunicator().
getConnectionManager().remove(
AUTConnection.getInstance()
.getCommunicator().getConnection());
AUTConnection.getInstance().reset();
AUTConnection.getInstance().close();
boolean wasInterrupted = Thread.interrupted();
AutAgentRegistration.getInstance().addListener(
registrationListener);
IClientTest clientTest = ClientTest.instance();
clientTest.fireAUTStateChanged(new AUTEvent(
AUTEvent.AUT_ABOUT_TO_TERMINATE));
final int initialTerminationTimeout = getTerminationTimeout();
final int terminationTimeout = initialTerminationTimeout
+ TimeoutConstants.AUT_KEEP_ALIVE_DELAY_DEFAULT;
final long startTime = System.currentTimeMillis();
long endTime = 0;
AutAgentConnection.getInstance().send(
new RestartAutMessage(autId, terminationTimeout));
while (!registrationListener.hasAutRestarted().get()) {
// wait for AUT registration
try {
if (endTime == 0 && registrationListener
.hasAutTerminated()) {
endTime = System.currentTimeMillis();
}
Thread.sleep(250);
} catch (InterruptedException e) {
// nothing
wasInterrupted = true;
}
}
// reconnect
AUTConnection.getInstance().connectToAut(
autId, new NullProgressMonitor());
if (wasInterrupted) {
Thread.currentThread().interrupt();
}
initTestExecutionMessage(getConnectedAUTsConfigMap(),
new NullProgressMonitor());
long terminationDuration = endTime - startTime;
if (initialTerminationTimeout > NO_TIMEOUT__FORCE_RESTART
&& terminationDuration > terminationTimeout) {
return EventFactory.createActionError(
TestErrorEvent.TIMEOUT_EXPIRED);
}
return null;
} finally {
AutAgentRegistration.getInstance().removeListener(
registrationListener);
if (LOG.isDebugEnabled()) {
LOG.debug(Messages.ContinueTestExecution);
}
if (!m_stopped) { // the AUT/TS may be stopped by a project load
ClientTest.instance().fireTestExecutionChanged(
new TestExecutionEvent(
State.TEST_EXEC_RESTART));
} else {
if (LOG.isDebugEnabled()) {
LOG.debug(Messages.CantContinueTSIsStopped);
}
}
}
}
/**
* @return the timeout used to restart the AUT
* @throws JBException
* in case of data retrieval problems
*/
protected abstract int getTerminationTimeout() throws JBException;
}
/**
* @author BREDEX GmbH
* @created Aug 22, 2006
*/
public class RestartCmd extends AbstractRestartCmd {
@Override
protected int getTerminationTimeout() {
return NO_TIMEOUT__FORCE_RESTART;
}
}
/**
* Class for keeping track of the number of steps executed during a test.
*
* @author BREDEX GmbH
* @created Aug 6, 2008
*/
private static class StepCounter
implements IExecStackModificationListener,
IEventStackModificationListener {
/** total number of steps executed */
private int m_totalSteps = 0;
/** number of steps executed from within an event handler */
private int m_eventHandlerSteps = 0;
/**
* number of steps that fulfill the following criteria:
* a. marked as retried
* b. not executed from an event handler
*
*/
private int m_retriedSteps = 0;
/** number of failed test steps */
private int m_failedSteps = 0;
/**
* The current depth of the event handling stack. This is needed
* in order to determine whether the test is currently handling an
* "error" state.
*/
private int m_currentEventStackDepth = 0;
/**
* <code>m_monitor</code> the progress monitor
*/
private IProgressMonitor m_monitor;
/**
* @param monitor the progress monitor to use
*/
public StepCounter(IProgressMonitor monitor) {
m_monitor = monitor;
}
/**
* {@inheritDoc}
*/
public void nextCap(ICapPO cap) {
if (m_currentEventStackDepth > 0) {
m_eventHandlerSteps++;
} else {
m_monitor.worked(1);
}
m_totalSteps++;
}
/**
* {@inheritDoc}
*/
public void nextDataSetIteration() {
// Do nothing
}
/**
* {@inheritDoc}
*/
public void retryCap(ICapPO cap) {
if (m_currentEventStackDepth <= 0) {
m_retriedSteps++;
} else {
m_eventHandlerSteps++;
}
m_totalSteps++;
}
/**
* {@inheritDoc}
*/
public void stackDecremented() {
// Do nothing
}
/**
* {@inheritDoc}
*/
public void stackIncremented(INodePO node) {
// Do nothing
}
/**
* {@inheritDoc}
*/
public void eventStackDecremented() {
m_currentEventStackDepth--;
}
/**
* {@inheritDoc}
*/
public void eventStackIncremented() {
m_currentEventStackDepth++;
}
/**
* @return the total number of steps executed
*/
public int getTotalSteps() {
return m_totalSteps;
}
/**
* @return the number of steps executed within event handlers
*/
public int getEventHandlerSteps() {
return m_eventHandlerSteps;
}
/**
* @return the number of retried steps
*/
public int getRetriedSteps() {
return m_retriedSteps;
}
/**
* @return the failedSteps
*/
public int getFailedSteps() {
return m_failedSteps;
}
/** increment the number of failed steps */
public void incrementNumberOfFailedSteps() {
m_failedSteps++;
}
/** {@inheritDoc} */
public void infiniteLoop() {
// do nothing
}
}
/**
* IPostExecutionCommand to execute an external command
* if "CompSystem.RunLocal" is <code>true</code>.
*
* @author BREDEX GmbH
* @created Sep 11, 2007
*/
@Deprecated
public class CommandExecutorCmd extends AbstractPostExecutionCommand {
/**
* Constructor
*/
public CommandExecutorCmd() {
super();
}
/**
* {@inheritDoc}
*/
public TestErrorEvent execute() throws JBException {
IParamDescriptionPO desc =
m_currentCap.getParameterForUniqueId(CSConstants.RUN_LOCAL);
try {
ITDManager tdManager =
m_externalTestDataBP.getExternalCheckedTDManager(
m_currentCap);
String date = tdManager.getCell(0, desc);
String runLocal = this.getValueForParam(date, m_currentCap,
desc);
TestResultNode resultNode = m_resultTreeTracker.getEndNode();
if (Boolean.valueOf(runLocal)) {
// Execute script
desc = m_currentCap.getParameterForUniqueId(
CSConstants.COMMAND);
date = tdManager.getCell(0, desc);
String cmd = this.getValueForParam(date, m_currentCap,
desc);
desc = m_currentCap
.getParameterForUniqueId(CSConstants.TIMEOUT);
date =
tdManager.getCell(0, desc);
int timeout = Integer.parseInt(
this.getValueForParam(date, m_currentCap,
desc));
desc =
m_currentCap.getParameterForUniqueId(
CSConstants.EXPECTED_EXIT_CODE);
date =
tdManager.getCell(0, desc);
int expectedExitCode = Integer.parseInt(
this.getValueForParam(date, m_currentCap,
desc));
File dataDir = ExternalTestDataBP.getDataDir();
MonitorTask mt =
new ExternalCommandExecutor().executeCommand(
dataDir, cmd, timeout);
if (!mt.wasCmdValid()) {
return EventFactory.createActionError(
TestErrorEvent.NO_SUCH_COMMAND);
}
resultNode.setCommandLog(mt.getOutput());
if (mt.hasTimeoutOccurred()) {
return EventFactory.createActionError(
TestErrorEvent.CONFIRMATION_TIMEOUT);
}
int actualExitValue = mt.getExitCode();
if (actualExitValue != expectedExitCode) {
return EventFactory.createVerifyFailed(
String.valueOf(expectedExitCode),
String.valueOf(actualExitValue));
}
} else {
String sysOutAndErr =
m_varStore.getValue(LAST_ACTION_RETURN);
resultNode.setCommandLog(sysOutAndErr);
}
} catch (IllegalArgumentException e) {
throw new JBException("IllegalArgumentException", e, //$NON-NLS-1$
MessageIDs.E_STEP_EXEC);
} catch (InvalidDataException e) {
throw new JBException("InvalidDataException", e, //$NON-NLS-1$
MessageIDs.E_STEP_EXEC);
}
return null;
}
}
/**
* IPostExecutionCommand to execute an external command
* if execution environment is ITE.
*
* @author BREDEX GmbH
*/
public class CommandExecCmd extends AbstractPostExecutionCommand {
/** Constructor */
public CommandExecCmd() {
super();
}
/** {@inheritDoc} */
public TestErrorEvent execute() throws JBException {
try {
String runLocal = getValueForParam(CSConstants.EXEC_CONTEXT);
TestResultNode resultNode = m_resultTreeTracker.getEndNode();
if (CSConstants.EXEC_CONTEXT_ITE.equals(runLocal)) {
String exec = getValueForParam(CSConstants.EXECUTABLE);
String args = getValueForParam(CSConstants.EXEC_RAW_ARGS);
boolean newEnvironment = Boolean.valueOf(
getValueForParam(CSConstants.NEW_ENVIRONMENT));
String splitCharValue = getValueForParam(
CSConstants.RAW_ARG_SPLIT_CHAR);
splitCharValue = StringUtils
.defaultIfEmpty(splitCharValue, null);
Character splitChar = (splitCharValue == null)
? null : splitCharValue.charAt(0);
String encoding = getValueForParam(
CSConstants.OUTPUT_ENCODING);
String dir = getValueForParam(CSConstants.DIR);
long timeout = Long.parseLong(getValueForParam(
CSConstants.TIMEOUT));
int expectedExitCode = Integer.parseInt(getValueForParam(
CSConstants.EXPECTED_EXIT_CODE));
Result result = CommandExecutor.exec(
dir, exec, args, splitChar,
timeout, encoding, newEnvironment);
resultNode.setCommandLog(result.getCombinedOutput());
int exitCode = result.getReturnValue();
if (exitCode != expectedExitCode) {
TestErrorEvent event = EventFactory.createVerifyFailed(
String.valueOf(expectedExitCode),
String.valueOf(exitCode));
event.addProp(
TestErrorEvent.Property.COMMAND_LOG_KEY,
result.getCombinedOutput());
return event;
}
} else {
String sysOutAndErr = m_varStore
.getValue(LAST_ACTION_RETURN);
resultNode.setCommandLog(sysOutAndErr);
}
} catch (IllegalCharsetNameException e) {
return EventFactory.createActionError();
} catch (UnsupportedCharsetException e) {
return EventFactory.createActionError();
} catch (ExecuteException e) {
return EventFactory.createActionError();
} catch (IOException e) {
return EventFactory.createActionError();
} catch (InterruptedException e) {
return EventFactory.createActionError();
} catch (TimeoutException e) {
TestErrorEvent event = EventFactory.createActionError(
TestErrorEvent.CONFIRMATION_TIMEOUT);
event.addProp(TestErrorEvent.Property.COMMAND_LOG_KEY,
e.getMessage());
return event;
} catch (IllegalArgumentException e) {
throw new JBException("IllegalArgumentException", e, //$NON-NLS-1$
MessageIDs.E_STEP_EXEC);
} catch (InvalidDataException e) {
throw new JBException("InvalidDataException", e, //$NON-NLS-1$
MessageIDs.E_STEP_EXEC);
}
return null;
}
}
/**
* @return variableStore
*/
public TDVariableStore getVariableStore() {
return m_varStore;
}
/**
*
* @return the number of test steps that have been executed during this
* test.
*/
public int getNumberOfTestedSteps() {
return m_stepCounter.getTotalSteps();
}
/**
*
* @return the number of test steps that would be executed during this test
* provided the test does not end prematurely and no event handler
* test steps are executed.
*/
public int getExpectedNumberOfSteps() {
return m_expectedNumberOfSteps;
}
/**
*
* @return the number of test steps that have been executed from within an
* event handler during this test.
*/
public int getNumberOfEventHandlerSteps() {
return m_stepCounter.getEventHandlerSteps();
}
/**
*
* @return the number of test steps that have been retried during
* this test.
*/
public int getNumberOfRetriedSteps() {
return m_stepCounter.getRetriedSteps();
}
/**
*
* @return the number of test steps that have failed
*/
public int getNumberOfFailedSteps() {
return m_stepCounter.getFailedSteps();
}
/**
* @param timerStore the timerStore to set
*/
public void setTimerStore(Map<String, Long> timerStore) {
m_timerStore = timerStore;
}
/**
* @return the timerStore
*/
public Map<String, Long> getTimerStore() {
return m_timerStore;
}
/**
* @param paused the paused to set
*/
private void setPaused(boolean paused) {
m_paused = paused;
}
/**
* @param noRunMode String noRun option mode
* @param step current step of noRun execution
* @return true is no run execution must be finished
* return false if test run without no-run option
* or the last step of no run execution is not jet reached
*/
public static boolean shouldExecutionStop(String noRunMode,
TestExecutionConstants.RunSteps step) {
if (StringUtils.isEmpty(noRunMode)) {
return false;
}
return noRunMode.equals(step.getStepValue());
}
}