/*
* Copyright Technophobia Ltd 2012
*
* This file is part of Substeps.
*
* Substeps is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Substeps is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Substeps. If not, see <http://www.gnu.org/licenses/>.
*/
package com.technophobia.substeps.execution.node;
import java.util.List;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.technophobia.substeps.execution.MethodExecutor;
import com.technophobia.substeps.runner.INotificationDistributor;
import com.technophobia.substeps.runner.SubstepExecutionFailure;
import com.technophobia.substeps.runner.TagManager;
import com.technophobia.substeps.runner.setupteardown.SetupAndTearDown;
//This isn't thread safe - if we were to run features concurrently we'd need to rectify this.
public class RootNodeExecutionContext {
private static final Logger log = LoggerFactory.getLogger(RootNodeExecutionContext.class);
private boolean testsRun = false;
private final INotificationDistributor notificationDistributor;
private final List<SubstepExecutionFailure> failures;
private final SetupAndTearDown setupAndTeardown;
private final TagManager nonFatalTagmanager;
private final MethodExecutor methodExecutor;
public RootNodeExecutionContext(INotificationDistributor notificationDistributor,
List<SubstepExecutionFailure> failures, SetupAndTearDown setupAndTeardown, TagManager nonFatalTagmanager,
MethodExecutor methodExecutor) {
this.notificationDistributor = notificationDistributor;
this.failures = failures;
this.setupAndTeardown = setupAndTeardown;
this.nonFatalTagmanager = nonFatalTagmanager;
this.methodExecutor = methodExecutor;
}
public INotificationDistributor getNotificationDistributor() {
return notificationDistributor;
}
public List<SubstepExecutionFailure> getFailures() {
return failures;
}
public SetupAndTearDown getSetupAndTeardown() {
return setupAndTeardown;
}
public void addFailure(final SubstepExecutionFailure failure) {
failures.add(failure);
logFailure(failure);
// set the criticality of this failure
if (!failure.isSetupOrTearDown() && this.nonFatalTagmanager != null
&& nonFatalTagmanager.isApplicable(failure.getExeccutionNode())) {
failure.setNonCritical(true);
}
}
/**
* @param failure
*/
private void logFailure(final SubstepExecutionFailure failure) {
// final Throwable failureCause = failure.getCause();
final Throwable here = new Throwable();
final StackTraceElement[] failureTrace = failure.getThrowableInfo().getStackTrace();
final StackTraceElement[] hereTrace = here.getStackTrace();
final int requiredTraceSize = failureTrace.length - hereTrace.length;
if (requiredTraceSize > 0 && requiredTraceSize < failureTrace.length) {
final StringBuilder stackTraceBuilder = new StringBuilder();
stackTraceBuilder.append(failure.getThrowableInfo().getDescription()).append("\n");
for (int i = 0; i < requiredTraceSize; i++) {
stackTraceBuilder.append("\tat ").append(failureTrace[i]).append("\n");
}
log.info("SubstepExecutionFailure @ " + failure.getExeccutionNode().toDebugString() + "\n"
+ stackTraceBuilder.toString());
} else {
// fallback position - just normal logging
log.info("SubstepExecutionFailure @ " + failure.getExeccutionNode().toDebugString(), failure.getThrowableInfo().getThrowable());
}
}
public MethodExecutor getMethodExecutor() {
return methodExecutor;
}
public void setTestsHaveRun() {
testsRun = true;
}
public boolean haveTestsBeenRun() {
return testsRun;
}
}