package hudson.plugins.sctmexecutor;
import hudson.plugins.sctmexecutor.exceptions.SCTMException;
import hudson.plugins.sctmexecutor.service.ISCTMService;
import java.io.PrintStream;
import java.text.MessageFormat;
import java.util.Collection;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.borland.sctm.ws.execution.entities.ExecutionHandle;
import com.borland.sctm.ws.execution.entities.ExecutionResult;
final class ExecutionRunnable implements Runnable {
private static final int MAX_SLEEP = 60;
private static final Logger LOGGER = Logger.getLogger("hudson.plugins.sctmexecutor"); //$NON-NLS-1$
private final int buildNumber;
private final int execDefId;
private final ISCTMService service;
private final ITestResultWriter writer;
private final PrintStream consolenLogger;
private long resultCollectingDelay;
private String execDefName;
ExecutionRunnable(final ISCTMService service, final int execDefId, final int buildNumber, final ITestResultWriter writer, final PrintStream logger) {
this.resultCollectingDelay = 5; // in seconds
this.consolenLogger = logger;
this.execDefId = execDefId;
this.writer = writer;
this.service = service;
this.buildNumber = buildNumber;
}
/**
* used only to make unit testing quicker
*
* @param sleep
*/
void setResultCollectingDelay(long sleep) {
resultCollectingDelay = sleep;
}
@Override
public void run() {
Collection<ExecutionHandle> handles;
try {
execDefName = service.getExecDefinitionName(execDefId);
this.consolenLogger.println(MessageFormat.format(Messages.getString("ExecutionRunnable.msg.startExecDef"), execDefName, this.execDefId)); //$NON-NLS-1$
if (this.buildNumber <= 0) // don't care about a build number
handles = service.start(this.execDefId);
else {
handles = service.start(this.execDefId, String.valueOf(this.buildNumber));
}
if (writer != null) { // continue without collecting results
for (ExecutionHandle executionHandle : handles) {
collectExecutionResult(executionHandle);
}
}
} catch (SCTMException e) {
this.consolenLogger.println(MessageFormat.format(
Messages.getString("ExecutionRunnable.err.startExecDefFailed"), execDefName, this.execDefId, e.getMessage())); //$NON-NLS-1$
}
}
private void collectExecutionResult(ExecutionHandle handle) {
ExecutionResult result = null;
try {
consolenLogger.println(MessageFormat.format(Messages.getString("ExecutionRunnable.msg.waitForResult"), execDefName, handle //$NON-NLS-1$
.getExecDefId()));
do {
Thread.sleep(resultCollectingDelay * 1000);
// because sometimes SCTM is too slow and the run is not created when we ask for a result
if (service.isFinished(handle)) {
result = service.getExecutionResult(handle);
consolenLogger.println(MessageFormat.format(
Messages.getString("ExecutionRunnable.log.resultReceived"), execDefName, handle.getExecDefId())); //$NON-NLS-1$
} else if (resultCollectingDelay < MAX_SLEEP) {
resultCollectingDelay *= 2;
if (resultCollectingDelay > MAX_SLEEP)
resultCollectingDelay = MAX_SLEEP;
}
} while (result == null);
this.writer.write(result);
} catch (SCTMException e) {
LOGGER.log(Level.SEVERE, e.getMessage());
if (e.getMessage().contains("Logon failed.")) //$NON-NLS-1$
consolenLogger.println(MessageFormat.format(Messages.getString("ExecutionRunnable.err.sessionLost"), e.getMessage())); //$NON-NLS-1$
else
consolenLogger.println(MessageFormat.format(Messages.getString("ExecutionRunnable.err.collectingResultsFailed"), execDefName, handle.getExecDefId(), e.getMessage())); //$NON-NLS-1$
} catch (InterruptedException e) {
consolenLogger.println(MessageFormat.format(Messages.getString("ExecutionRunnable.warn.abortCollectingResults"), //$NON-NLS-1$
execDefName, handle.getExecDefId()));
LOGGER.log(Level.INFO, e.getMessage());
}
}
}