Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion java.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"id": "java",
"version": "0.11.4",
"version": "0.12.0",
"description": "Java support for gauge",
"install": {
"windows": [],
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<name>gauge-java</name>
<groupId>com.thoughtworks.gauge</groupId>
<artifactId>gauge-java</artifactId>
<version>0.11.4</version>
<version>0.12.0</version>
<description>Java plugin for Gauge</description>
<url>https://github.com/getgauge/gauge-java</url>
<dependencyManagement>
Expand Down
12 changes: 12 additions & 0 deletions src/main/java/com/thoughtworks/gauge/SkipScenarioException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.thoughtworks.gauge;

public class SkipScenarioException extends RuntimeException {
public SkipScenarioException(String message) {
super(message);
}

@SuppressWarnings("unused")
public SkipScenarioException(String message, Throwable cause) {
super(message, cause);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@ public Spec.ProtoExecutionResult executeNext(Spec.ProtoExecutionResult previousS
protected Spec.ProtoExecutionResult mergeExecResults(Spec.ProtoExecutionResult previousStageResult, Spec.ProtoExecutionResult execResult) {
long execTime = execResult.getExecutionTime() + previousStageResult.getExecutionTime();
boolean failed = execResult.getFailed() | previousStageResult.getFailed();
boolean skipped = execResult.getSkipScenario() | previousStageResult.getSkipScenario();

Spec.ProtoExecutionResult.Builder builder = Spec.ProtoExecutionResult.newBuilder();
builder.setExecutionTime(execTime);
builder.setFailed(failed);
builder.setSkipScenario(skipped);
if (previousStageResult.getFailed()) {
builder.setErrorMessage(previousStageResult.getErrorMessage());
builder.setErrorType(previousStageResult.getErrorType());
Expand Down
43 changes: 22 additions & 21 deletions src/main/java/com/thoughtworks/gauge/execution/MethodExecutor.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@

import com.thoughtworks.gauge.ClassInstanceManager;
import com.thoughtworks.gauge.ContinueOnFailure;
import com.thoughtworks.gauge.SkipScenarioException;
import com.thoughtworks.gauge.Util;
import com.thoughtworks.gauge.screenshot.ScreenshotFactory;
import gauge.messages.Spec;

import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Method;
import java.util.Set;
import java.util.Optional;

public class MethodExecutor {
private final ClassInstanceManager instanceManager;
Expand All @@ -31,25 +32,37 @@ public Spec.ProtoExecutionResult execute(Method method, Object... args) {
long endTime = System.currentTimeMillis();
return Spec.ProtoExecutionResult.newBuilder().setFailed(false).setExecutionTime(endTime - startTime).build();
} catch (Throwable e) {
boolean recoverable = method.isAnnotationPresent(ContinueOnFailure.class);
Class[] continuableExceptions = new Class[]{};
if (recoverable) {
continuableExceptions = method.getAnnotation(ContinueOnFailure.class).value();
long execTime = System.currentTimeMillis() - startTime;

if (e.getCause() instanceof SkipScenarioException) {
return createSkippedExecResult(execTime, (SkipScenarioException) e.getCause());
}
long endTime = System.currentTimeMillis();
return createFailureExecResult(endTime - startTime, e, recoverable, continuableExceptions);

Class<?>[] continuableExceptions = Optional.ofNullable(method.getAnnotation(ContinueOnFailure.class))
.map(ContinueOnFailure::value).
orElseGet(() -> new Class<?>[]{});

return createFailureExecResult(execTime, e, method.isAnnotationPresent(ContinueOnFailure.class), continuableExceptions);
}
}

private Spec.ProtoExecutionResult createFailureExecResult(long execTime, Throwable e, boolean recoverable, Class[] continuableExceptions) {
private Spec.ProtoExecutionResult createSkippedExecResult(long execTime, SkipScenarioException cause) {
return Spec.ProtoExecutionResult.newBuilder()
.setSkipScenario(true)
.addMessage(Optional.ofNullable(cause.getMessage()).orElse("SKIPPED"))
.setExecutionTime(execTime)
.build();
}

private Spec.ProtoExecutionResult createFailureExecResult(long execTime, Throwable e, boolean recoverable, Class<?>[] continuableExceptions) {
Spec.ProtoExecutionResult.Builder builder = Spec.ProtoExecutionResult.newBuilder().setFailed(true);
if (Util.shouldTakeFailureScreenshot()) {
String screenshotFileName = new ScreenshotFactory(instanceManager).getScreenshotBytes();
builder.setFailureScreenshotFile(screenshotFileName);
}
if (e.getCause() != null) {
builder.setRecoverableError(false);
for (Class c : continuableExceptions) {
for (Class<?> c : continuableExceptions) {
if (c.isAssignableFrom(e.getCause().getClass()) && recoverable) {
builder.setRecoverableError(true);
break;
Expand All @@ -74,16 +87,4 @@ private String formatStackTrace(Throwable t) {
t.printStackTrace(new PrintWriter(out));
return out.toString();
}

public Spec.ProtoExecutionResult executeMethods(Set<Method> methods, Object... args) {
long totalExecutionTime = 0;
for (Method method : methods) {
Spec.ProtoExecutionResult result = execute(method, args);
totalExecutionTime += result.getExecutionTime();
if (result.getFailed()) {
return result;
}
}
return Spec.ProtoExecutionResult.newBuilder().setFailed(false).setExecutionTime(totalExecutionTime).build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package com.thoughtworks.gauge.execution;

import gauge.messages.Spec;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;
Expand All @@ -21,94 +22,141 @@ public void testMergingSimpleResultsBothPassing() throws Exception {
assertEquals(2100, result.getExecutionTime());
}

@Test
public void testMergingResultsPreviousFailing() throws Exception {
String screenShot = "1";

Spec.ProtoExecutionResult previous = Spec.ProtoExecutionResult.newBuilder().setFailed(true).
setExecutionTime(100).
setRecoverableError(false).
setErrorMessage("Previous failed").
setStackTrace("Previous stacktrace").
setFailureScreenshotFile(screenShot).build();
Spec.ProtoExecutionResult current = Spec.ProtoExecutionResult.newBuilder().setFailed(false).setExecutionTime(1100).build();
Spec.ProtoExecutionResult result = new TestExecutionStage().mergeExecResults(previous, current);
@Nested
public class Failing {

@Test
public void testMergingResultsPreviousFailing() throws Exception {
String screenShot = "1";

Spec.ProtoExecutionResult previous = Spec.ProtoExecutionResult.newBuilder().setFailed(true)
.setExecutionTime(100)
.setRecoverableError(false)
.setErrorMessage("Previous failed")
.setStackTrace("Previous stacktrace")
.setFailureScreenshotFile(screenShot).build();
Spec.ProtoExecutionResult current = Spec.ProtoExecutionResult.newBuilder().setFailed(false).setExecutionTime(1100).build();
Spec.ProtoExecutionResult result = new TestExecutionStage().mergeExecResults(previous, current);

assertTrue(result.getFailed());
assertEquals(1200, result.getExecutionTime());
assertEquals("Previous failed", result.getErrorMessage());
assertEquals("Previous stacktrace", result.getStackTrace());
assertFalse(result.getRecoverableError());
assertEquals(screenShot, result.getFailureScreenshotFile());
}

assertTrue(result.getFailed());
assertEquals(1200, result.getExecutionTime());
assertEquals("Previous failed", result.getErrorMessage());
assertEquals("Previous stacktrace", result.getStackTrace());
assertFalse(result.getRecoverableError());
assertEquals(screenShot, result.getFailureScreenshotFile());
}
@Test
public void testMergingResultsCurrentFailing() throws Exception {
String screenShot = "2";

Spec.ProtoExecutionResult previous = Spec.ProtoExecutionResult.newBuilder().setFailed(false).setExecutionTime(100).build();
Spec.ProtoExecutionResult current = Spec.ProtoExecutionResult.newBuilder().setFailed(true)
.setExecutionTime(100)
.setRecoverableError(false)
.setErrorMessage("current failed")
.setStackTrace("current stacktrace")
.setFailureScreenshotFile(screenShot).build();
Spec.ProtoExecutionResult result = new TestExecutionStage().mergeExecResults(previous, current);

assertTrue(result.getFailed());
assertEquals(200, result.getExecutionTime());
assertEquals("current failed", result.getErrorMessage());
assertEquals("current stacktrace", result.getStackTrace());
assertFalse(result.getRecoverableError());
assertEquals(screenShot, result.getFailureScreenshotFile());
}

@Test
public void testMergingResultsCurrentFailing() throws Exception {
String screenShot = "2";

Spec.ProtoExecutionResult previous = Spec.ProtoExecutionResult.newBuilder().setFailed(false).setExecutionTime(100).build();
Spec.ProtoExecutionResult current = Spec.ProtoExecutionResult.newBuilder().setFailed(true).
setExecutionTime(100).
setRecoverableError(false).
setErrorMessage("current failed").
setStackTrace("current stacktrace").
setFailureScreenshotFile(screenShot).build();
Spec.ProtoExecutionResult result = new TestExecutionStage().mergeExecResults(previous, current);
@Test
public void testMergingResultsBothFailing() throws Exception {
String screenShotPrevious = "2";
String screenShotCurrent = "hello";

Spec.ProtoExecutionResult previous = Spec.ProtoExecutionResult.newBuilder().setFailed(true)
.setExecutionTime(1001)
.setRecoverableError(true)
.setErrorMessage("previous failed")
.setStackTrace("previous stacktrace")
.setFailureScreenshotFile(screenShotPrevious).build();
Spec.ProtoExecutionResult current = Spec.ProtoExecutionResult.newBuilder().setFailed(true)
.setExecutionTime(1002)
.setRecoverableError(false)
.setErrorMessage("current failed")
.setStackTrace("current stacktrace")
.setFailureScreenshotFile(screenShotCurrent).build();
Spec.ProtoExecutionResult result = new TestExecutionStage().mergeExecResults(previous, current);

assertTrue(result.getFailed());
assertEquals(2003, result.getExecutionTime());
assertEquals("previous failed", result.getErrorMessage());
assertEquals("previous stacktrace", result.getStackTrace());
assertFalse(result.getRecoverableError());
assertEquals(screenShotPrevious, result.getFailureScreenshotFile());
}

assertTrue(result.getFailed());
assertEquals(200, result.getExecutionTime());
assertEquals("current failed", result.getErrorMessage());
assertEquals("current stacktrace", result.getStackTrace());
assertFalse(result.getRecoverableError());
assertEquals(screenShot, result.getFailureScreenshotFile());
@Test
public void testMergingResultsCurrentFailingAndIsRecoverable() throws Exception {
String screenShotCurrent = "screenShotCurrent.png";

Spec.ProtoExecutionResult previous = Spec.ProtoExecutionResult.newBuilder().setFailed(false).setExecutionTime(1001).build();
Spec.ProtoExecutionResult current = Spec.ProtoExecutionResult.newBuilder().setFailed(true)
.setExecutionTime(1002)
.setRecoverableError(true)
.setErrorMessage("current failed")
.setStackTrace("current stacktrace")
.setFailureScreenshotFile(screenShotCurrent).build();
Spec.ProtoExecutionResult result = new TestExecutionStage().mergeExecResults(previous, current);

assertTrue(result.getFailed());
assertEquals(2003, result.getExecutionTime());
assertEquals("current failed", result.getErrorMessage());
assertEquals("current stacktrace", result.getStackTrace());
assertTrue(result.getRecoverableError());
assertEquals(screenShotCurrent, result.getFailureScreenshotFile());
}
}

@Test
public void testMergingResultsBothFailing() throws Exception {
String screenShotPrevious = "2";
String screenShotCurrent = "hello";

Spec.ProtoExecutionResult previous = Spec.ProtoExecutionResult.newBuilder().setFailed(true).
setExecutionTime(1001).
setRecoverableError(true).
setErrorMessage("previous failed").
setStackTrace("previous stacktrace").
setFailureScreenshotFile(screenShotPrevious).build();
Spec.ProtoExecutionResult current = Spec.ProtoExecutionResult.newBuilder().setFailed(true).
setExecutionTime(1002).
setRecoverableError(false).
setErrorMessage("current failed").
setStackTrace("current stacktrace").
setFailureScreenshotFile(screenShotCurrent).build();
Spec.ProtoExecutionResult result = new TestExecutionStage().mergeExecResults(previous, current);
@Nested
public class Skipped {

assertTrue(result.getFailed());
assertEquals(2003, result.getExecutionTime());
assertEquals("previous failed", result.getErrorMessage());
assertEquals("previous stacktrace", result.getStackTrace());
assertFalse(result.getRecoverableError());
assertEquals(screenShotPrevious, result.getFailureScreenshotFile());
}
@Test
public void testMergingResultsPreviousSkipped() throws Exception {
Spec.ProtoExecutionResult previous = Spec.ProtoExecutionResult.newBuilder().setSkipScenario(true)
.setExecutionTime(100)
.build();
Spec.ProtoExecutionResult current = Spec.ProtoExecutionResult.newBuilder().setSkipScenario(false).setExecutionTime(1100).build();
Spec.ProtoExecutionResult result = new TestExecutionStage().mergeExecResults(previous, current);

@Test
public void testMergingResultsCurrentFailingAndIsRecoverable() throws Exception {
String screenShotCurrent = "screenShotCurrent.png";

Spec.ProtoExecutionResult previous = Spec.ProtoExecutionResult.newBuilder().setFailed(false).setExecutionTime(1001).build();
Spec.ProtoExecutionResult current = Spec.ProtoExecutionResult.newBuilder().setFailed(true).
setExecutionTime(1002).
setRecoverableError(true).
setErrorMessage("current failed").
setStackTrace("current stacktrace").
setFailureScreenshotFile(screenShotCurrent).build();
Spec.ProtoExecutionResult result = new TestExecutionStage().mergeExecResults(previous, current);
assertTrue(result.getSkipScenario());
assertEquals(1200, result.getExecutionTime());
}

@Test
public void testMergingResultsCurrentSkipped() throws Exception {
Spec.ProtoExecutionResult previous = Spec.ProtoExecutionResult.newBuilder().setSkipScenario(false).setExecutionTime(100).build();
Spec.ProtoExecutionResult current = Spec.ProtoExecutionResult.newBuilder().setSkipScenario(true)
.setExecutionTime(100)
.build();
Spec.ProtoExecutionResult result = new TestExecutionStage().mergeExecResults(previous, current);

assertTrue(result.getSkipScenario());
assertEquals(200, result.getExecutionTime());
}

@Test
public void testMergingResultsBothSkipped() throws Exception {
Spec.ProtoExecutionResult previous = Spec.ProtoExecutionResult.newBuilder().setSkipScenario(true)
.setExecutionTime(1001)
.build();
Spec.ProtoExecutionResult current = Spec.ProtoExecutionResult.newBuilder().setSkipScenario(true)
.setExecutionTime(1002)
.build();
Spec.ProtoExecutionResult result = new TestExecutionStage().mergeExecResults(previous, current);

assertTrue(result.getSkipScenario());
assertEquals(2003, result.getExecutionTime());
}

assertTrue(result.getFailed());
assertEquals(2003, result.getExecutionTime());
assertEquals("current failed", result.getErrorMessage());
assertEquals("current stacktrace", result.getStackTrace());
assertTrue(result.getRecoverableError());
assertEquals(screenShotCurrent, result.getFailureScreenshotFile());
}

private static class TestExecutionStage extends AbstractExecutionStage {
Expand Down
Loading
Loading