blob: 13a758cdf9d1453e9764034e4fd33d3c79a1fdad [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2015 Xored Software Inc and others.
* 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:
* Xored Software Inc - initial API and implementation and/or initial documentation
*******************************************************************************/
package org.eclipse.rcptt.internal.launching;
import static org.eclipse.rcptt.internal.core.RcpttPlugin.createStatus;
import java.io.ByteArrayInputStream;
import java.util.Collections;
import java.util.List;
import java.util.zip.ZipInputStream;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.rcptt.core.Q7;
import org.eclipse.rcptt.core.Q7Features;
import org.eclipse.rcptt.core.ecl.core.model.CreateReport;
import org.eclipse.rcptt.core.ecl.core.model.ExecutionPhase;
import org.eclipse.rcptt.core.ecl.core.model.GetReport;
import org.eclipse.rcptt.core.ecl.core.model.PrepareEnvironment;
import org.eclipse.rcptt.core.ecl.core.model.Q7CoreFactory;
import org.eclipse.rcptt.core.ecl.core.model.ResetVerifications;
import org.eclipse.rcptt.core.ecl.core.model.SetCommandsDelay;
import org.eclipse.rcptt.core.ecl.core.model.SetQ7Features;
import org.eclipse.rcptt.core.model.IQ7NamedElement;
import org.eclipse.rcptt.core.model.ModelException;
import org.eclipse.rcptt.ecl.core.ProcessStatus;
import org.eclipse.rcptt.ecl.core.Sequence;
import org.eclipse.rcptt.ecl.core.util.ECLBinaryResourceImpl;
import org.eclipse.rcptt.ecl.core.util.ScriptletFactory;
import org.eclipse.rcptt.ecl.internal.core.ProcessStatusConverter;
import org.eclipse.rcptt.internal.core.RcpttPlugin;
import org.eclipse.rcptt.internal.launching.ecl.EclScenarioExecutable;
import org.eclipse.rcptt.launching.AutLaunch;
import org.eclipse.rcptt.launching.IExecutable;
import org.eclipse.rcptt.launching.Q7LaunchUtils;
import org.eclipse.rcptt.launching.utils.TestSuiteUtils;
import org.eclipse.rcptt.parameters.ParametersFactory;
import org.eclipse.rcptt.parameters.ResetParams;
import org.eclipse.rcptt.reporting.Q7Info;
import org.eclipse.rcptt.reporting.core.ReportHelper;
import org.eclipse.rcptt.reporting.core.SimpleSeverity;
import org.eclipse.rcptt.sherlock.core.model.sherlock.report.LoggingCategory;
import org.eclipse.rcptt.sherlock.core.model.sherlock.report.Node;
import org.eclipse.rcptt.sherlock.core.model.sherlock.report.Report;
import org.eclipse.rcptt.sherlock.core.model.sherlock.report.ReportContainer;
import org.eclipse.rcptt.sherlock.core.streams.SherlockReportSession;
import org.eclipse.rcptt.tesla.core.TeslaFeatures;
import com.google.common.base.Objects;
import com.google.common.base.Preconditions;
public class PrepareExecutionWrapper extends Executable {
@Override
public void cancel(IStatus status) {
// Handle cancellation caused by child failure.
// Execution view may interrupt execution on first error.
for (final Executable child : getChildren()) {
IStatus childResult = handleChildResult(child.getResultStatus());
if (child.getStatus() == State.COMPLETED && !childResult.isOK()) {
return; // Execution will complete soon and this node will assume error result.
}
}
super.cancel(status);
}
private final AutLaunch launch;
private final Executable executable;
private SherlockReportSession reportSession;
private String resultReportID;
public PrepareExecutionWrapper(AutLaunch launch, Executable executable) throws ModelException {
super(executable.isDebug(), ExecutionPhase.AUTO, true);
this.launch = launch;
this.executable = executable;
Preconditions.checkNotNull(getActualElement());
Preconditions.checkNotNull(getActualElement().getID());
}
public Executable getExecutable() {
return executable;
}
public AutLaunch getAut() {
return launch;
}
@Override
public void startLaunching() {
executable.startLaunching();
}
@Override
public Report getResultReport() {
if (resultReportID != null && reportSession != null) {
return reportSession.getReport(resultReportID);
}
return TestSuiteUtils.generateReport(getActualElement(), getResultStatus());
}
@Override
public IStatus execute() throws InterruptedException {
launch.resetState();
PrepareEnvironment prepareEnvironment = Q7CoreFactory.eINSTANCE
.createPrepareEnvironment();
SetCommandsDelay commandsDelay = Q7CoreFactory.eINSTANCE.createSetCommandsDelay();
commandsDelay.setDelay(Q7.INSTANCE.getCommandsExecutionDelay());
TeslaFeatures.getInstance().getOption(TeslaFeatures.COMMAND_EXECUTION_DELAY)
.setValue(Integer.toString(commandsDelay.getDelay()));
SetQ7Features setQ7Features = Q7CoreFactory.eINSTANCE.createSetQ7Features();
Q7LaunchUtils.setQ7Variable(setQ7Features, Q7LaunchUtils.Q7_CURRENT_TEST_VAR,
getName());
TeslaFeatures.getInstance().storeValues(setQ7Features.getFeatures());
Q7Features.getInstance().storeValues(setQ7Features.getFeatures());
Sequence command = ScriptletFactory.seq(prepareEnvironment, commandsDelay,
setQ7Features);
try {
launch.execute(command);
resetParams();
resetVerifications();
} catch (CoreException e) {
return e.getStatus();
} catch (Exception e) {
return Q7LaunchingPlugin.createStatus(e);
}
try {
createReport();
} catch (CoreException e) {
return e.getStatus();
}
if (executable instanceof GroupExecutable) {
IExecutable rootExecutable = ((GroupExecutable) executable).getRoot();
if (rootExecutable instanceof EclScenarioExecutable) {
EclScenarioExecutable scenario = (EclScenarioExecutable) rootExecutable;
TestEngineManager.getInstance().fireExecutionStarted(scenario);
}
}
return executable.execute();
}
private Report getReport() throws InterruptedException, ModelException {
Report resultReport = null;
final String id = getActualElement().getID();
Preconditions.checkNotNull(id);
try {
GetReport getReport = Q7CoreFactory.eINSTANCE.createGetReport();
Object object = launch.execute(getReport);
if (object instanceof Report) {
resultReport = (Report) object;
} else if (object instanceof ReportContainer) {
ZipInputStream zin = new ZipInputStream(new ByteArrayInputStream(
((ReportContainer) object).getContent()));
try {
// position the stream at the beginning of the entry data
zin.getNextEntry();
Resource res = new ECLBinaryResourceImpl();
res.load(zin, null);
EObject object2 = res.getContents().get(0);
if (object2 instanceof Report) {
resultReport = (Report) object2;
} else {
throw invalidObjectStatus(object2);
}
} catch (Exception e) {
throw new CoreException(Q7LaunchingPlugin.createStatus(e.getMessage(), e));
}
} else if (object == null) {
throw invalidObjectStatus(object);
} else {
throw invalidObjectStatus(object);
}
String reportId = ReportHelper.getInfo(resultReport.getRoot()).getId();
if (!id.equals(reportId)) {
throw new CoreException(createStatus("Expected item id: " + id + ", actual report id: " + reportId));
}
} catch (CoreException e) {
resultReport = generateReport(e.getStatus());
}
Q7Info info = ReportHelper.getInfoOnly(resultReport.getRoot());
if (info != null) {
info.getVariant().clear();
info.getVariant().addAll(getVariantName());
}
return resultReport;
}
private CoreException invalidObjectStatus(Object o) {
String clazz = o == null ? "null" : o.getClass().getName();
return new CoreException(createStatus("Expected: Report object, found: " + clazz));
}
private void resetParams() throws CoreException, InterruptedException {
ResetParams cmd = ParametersFactory.eINSTANCE.createResetParams();
launch.execute(cmd);
}
private void resetVerifications() throws CoreException, InterruptedException {
ResetVerifications cmd = Q7CoreFactory.eINSTANCE.createResetVerifications();
launch.execute(cmd);
}
private void createReport() throws CoreException, InterruptedException {
CreateReport createReport = Q7CoreFactory.eINSTANCE.createCreateReport();
createReport.setName(getName());
createReport.setQ7info(getQ7Info(executable));
launch.execute(createReport);
}
private static Q7Info getQ7Info(Executable executable) throws ModelException {
IQ7NamedElement element = executable.getActualElement();
return TestSuiteUtils.getQ7Info(element);
}
@Override
public Executable[] getChildren() {
return executable.getChildren();
}
public IQ7NamedElement getActualElement() {
return executable.getActualElement();
}
public String getName() {
return executable.getName();
}
public int getType() {
return executable.getType();
}
private static void closeAllNodes(long endTime, Node node) {
if (node.getEndTime() == 0) {
node.setEndTime(endTime);
node.setDuration(node.getEndTime() - node.getStartTime());
}
Q7Info info = ReportHelper.getInfo(node);
for (Node child : node.getChildren()) {
closeAllNodes(endTime, child);
Q7Info childInfo = ReportHelper.getInfo(child);
if (childInfo.getResult() == null) {
ProcessStatus childStatus = RcpttPlugin.createProcessStatus(IStatus.ERROR, "" + child.getName()
+ " result is not set");
childInfo.setResult(childStatus);
if (SimpleSeverity.create(info) == SimpleSeverity.OK)
info.setResult(childStatus);
}
}
}
@Override
public IStatus postExecute(IStatus status) {
IStatus temp = executable.postExecute(status);
if (status.isOK() && !temp.isOK())
status = temp;
Report resultReport = null;
try {
if (status.matches(IStatus.CANCEL)) {
resultReport = generateReport(status);
} else {
// Take report from AUT
resultReport = getReport();
Node root = resultReport.getRoot();
Q7Info rootInfo = ReportHelper.getInfo(root);
assert rootInfo.getResult() == null;
rootInfo.setResult(ProcessStatusConverter.toProcessStatus(status));
closeAllNodes(root.getStartTime() + getTime(), root);
if (status.isOK() && SimpleSeverity.create(rootInfo) != SimpleSeverity.OK) {
status = ProcessStatusConverter.toIStatus(rootInfo.getResult());
}
for (IExecutable ch : getChildren()) {
if (ch instanceof ScenarioExecutable) {
rootInfo.setId(ch.getId());
break;
}
}
assert Objects.equal(rootInfo.getId(), getActualElement().getID());
}
return super.postExecute(status);
} catch (InterruptedException e) {
resultReport = generateReport(createStatus("Interrupted during report acquisition", e));
return Status.CANCEL_STATUS;
} catch (Throwable e) {
RcpttPlugin.log(e);
IStatus rv = RcpttPlugin.createStatus(e);
resultReport = generateReport(rv);
return rv;
} finally {
Preconditions.checkNotNull(resultReport);
if (executable instanceof GroupExecutable) {
IExecutable rootExecutable = ((GroupExecutable) executable).getRoot();
if (rootExecutable instanceof EclScenarioExecutable) {
EclScenarioExecutable scenario = (EclScenarioExecutable) rootExecutable;
TestEngineManager.getInstance().fireExecutionCompleted(scenario, resultReport);
}
}
if (this.reportSession != null) {
resultReportID = this.reportSession.write(resultReport);
}
listeners.updateSessionCounters(this, status);
}
}
private Report generateReport(IStatus status) {
Report report = TestSuiteUtils.generateReport(getActualElement(), status);
Node root = report.getRoot();
root.setEndTime(root.getStartTime() + getTime());
root.setDuration(root.getEndTime() - root.getStartTime());
ReportHelper.appendLog(root, LoggingCategory.NORMAL, getLog());
return report;
}
public void setReportSession(SherlockReportSession reportSession) {
this.reportSession = reportSession;
}
public List<String> getVariantName() {
Executable exx = getExecutable();
if (exx instanceof GroupExecutable) {
IExecutable ex = ((GroupExecutable) exx).getRoot();
if (ex instanceof EclScenarioExecutable)
return ((EclScenarioExecutable) ex).getVariantName();
}
return Collections.emptyList();
}
@Override
public String toString() {
return "Prepare: " + executable.toString();
}
}