Skip to content

Commit abdf79b

Browse files
jsalinaspolojordi9
andcommitted
Throw an exception when during polling conditions there is an exception invoking the closure.
Co-authored-by: jordi9 <[email protected]>
1 parent 761f88e commit abdf79b

File tree

4 files changed

+42
-10
lines changed

4 files changed

+42
-10
lines changed

Diff for: spock-core/src/main/java/spock/lang/Retry.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ enum Mode {
103103
ITERATION,
104104

105105
/**
106-
* Retry the the feature together with the setup and cleanup methods.
106+
* Retry the feature together with the setup and cleanup methods.
107107
*/
108108
SETUP_FEATURE_CLEANUP
109109
}

Diff for: spock-core/src/main/java/spock/util/concurrent/PollingConditions.java

+15-4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.spockframework.lang.ConditionBlock;
2020
import org.spockframework.runtime.GroovyRuntimeUtil;
2121
import org.spockframework.runtime.SpockTimeoutError;
22+
import org.spockframework.runtime.UnallowedExceptionThrownError;
2223
import org.spockframework.util.Beta;
2324

2425
/**
@@ -47,6 +48,7 @@ public class PollingConditions {
4748
private double initialDelay = 0;
4849
private double delay = 0.1;
4950
private double factor = 1.0;
51+
private boolean strict = false;
5052

5153
/**
5254
* Returns the timeout (in seconds) until which the conditions have to be satisfied.
@@ -122,11 +124,18 @@ public void setFactor(double factor) {
122124
this.factor = factor;
123125
}
124126

127+
/**
128+
* Returns if is strict mode. If strict mode is enabled, will fail if any exception rather than {@link AssertionError} is thrown.
129+
* Defaults to {@code false}
130+
*/
131+
public boolean isStrict() {
132+
return strict;
133+
}
134+
125135
/**
126136
* Repeatedly evaluates the specified conditions until they are satisfied or the timeout has elapsed.
127137
*
128138
* @param conditions the conditions to evaluate
129-
*
130139
* @throws InterruptedException if evaluation is interrupted
131140
*/
132141
@ConditionBlock
@@ -138,11 +147,10 @@ public void eventually(Closure<?> conditions) throws InterruptedException {
138147
* Repeatedly evaluates the specified conditions until they are satisfied or the specified timeout (in seconds) has elapsed.
139148
*
140149
* @param conditions the conditions to evaluate
141-
*
142150
* @throws InterruptedException if evaluation is interrupted
143151
*/
144152
@ConditionBlock
145-
public void within(double seconds, Closure<?> conditions) throws InterruptedException {
153+
public void within(double seconds, Closure<?> conditions) throws InterruptedException {
146154
long timeoutMillis = toMillis(seconds);
147155
long start = System.currentTimeMillis();
148156
long lastAttempt = 0;
@@ -151,13 +159,16 @@ public void within(double seconds, Closure<?> conditions) throws InterruptedExce
151159
long currDelay = toMillis(delay);
152160
int attempts = 0;
153161

154-
while(true) {
162+
while (true) {
155163
try {
156164
attempts++;
157165
lastAttempt = System.currentTimeMillis();
158166
GroovyRuntimeUtil.invokeClosure(conditions);
159167
return;
160168
} catch (Throwable e) {
169+
if (strict && !(e instanceof AssertionError)) {
170+
throw new UnallowedExceptionThrownError(e.getClass(), e);
171+
}
161172
long elapsedTime = lastAttempt - start;
162173
if (elapsedTime >= timeoutMillis) {
163174
String msg = String.format("Condition not satisfied after %1.2f seconds and %d attempts", elapsedTime / 1000d, attempts);

Diff for: spock-specs/specs.gradle

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ configurations {
1010
}
1111

1212
dependencies {
13-
testCompile project(":spock-core")
14-
testCompile project(":spock-junit4")
13+
testImplementation project(":spock-core")
14+
testImplementation project(":spock-junit4")
1515

1616
testRuntime libs.asm
1717
testRuntime libs.bytebuddy
@@ -30,7 +30,7 @@ targetCompatibility = javaVersion
3030
// necessary to make @NotYetImplemented transform work (transform that ships
3131
// with Groovy and statically references third-party class junit.framwork.AssertionFailedError)
3232
tasks.withType(GroovyCompile) {
33-
groovyClasspath += configurations.junit
33+
groovyClasspath += configurations.junit
3434
}
3535

3636
ext.spockLogFileDir = file("$buildDir/spock/logFiles")

Diff for: spock-specs/src/test/groovy/spock/util/concurrent/PollingConditionsSpec.groovy

+23-2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ package spock.util.concurrent
1616

1717
import org.spockframework.runtime.ConditionNotSatisfiedError
1818
import org.spockframework.runtime.SpockTimeoutError
19+
import org.spockframework.runtime.UnallowedExceptionThrownError
1920
import spock.lang.Issue
2021
import spock.lang.Specification
2122

@@ -126,12 +127,32 @@ class PollingConditionsSpec extends Specification {
126127
then:
127128
condition.eventually {
128129
try {
129-
sleep 200;
130-
assert secondAttempt;
130+
sleep 200
131+
assert secondAttempt
131132
} finally {
132133
secondAttempt = true
133134
}
134135
}
135136
}
137+
138+
def "fails if an exception is thrown while polling"() {
139+
given:
140+
def iteration = 0
141+
142+
when:
143+
new PollingConditions(strict: true).eventually {
144+
try {
145+
if (iteration < 2) {
146+
throw new IllegalStateException("An exception is thrown")
147+
}
148+
assert true
149+
} finally {
150+
iteration++
151+
}
152+
}
153+
then:
154+
def ex = thrown(UnallowedExceptionThrownError)
155+
ex.unallowed == IllegalStateException
156+
}
136157
}
137158

0 commit comments

Comments
 (0)