-
Notifications
You must be signed in to change notification settings - Fork 468
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add documentation for concurrency helpers #1173
base: master
Are you sure you want to change the base?
Changes from 5 commits
da44202
dd85cff
f495e9d
65b2caa
ec67cd6
b3344cc
05e6d3e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package org.spockframework.docs.utilities.concurrent | ||
|
||
import spock.lang.Specification | ||
import spock.util.concurrent.AsyncConditions | ||
|
||
class AsyncConditionsDocSpec extends Specification { | ||
|
||
// tag::async-conditions-spec[] | ||
def "example of single passing explicit evaluation"() { | ||
def conditions = new AsyncConditions() // <1> | ||
thokari marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
when: | ||
Thread.start { // <2> | ||
conditions.evaluate { //<3> | ||
assert true | ||
} | ||
} | ||
|
||
then: | ||
conditions.await() // <4> | ||
} | ||
|
||
def "example of multiple passing implicit evaluations"() { | ||
AsyncConditions conditions = new AsyncConditions(3) // <5> | ||
|
||
when: | ||
Thread.start { | ||
conditions.evaluate { // <6> | ||
true | ||
true | ||
} | ||
conditions.evaluate { // <6> | ||
true | ||
} | ||
} | ||
|
||
and: | ||
Thread.start { | ||
conditions.evaluate { // <6> | ||
true | ||
} | ||
} | ||
|
||
then: | ||
conditions.await(2.5) // <7> | ||
} | ||
// end::async-conditions-spec[] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
package org.spockframework.docs.utilities.concurrent | ||
|
||
import spock.lang.Specification | ||
import spock.util.concurrent.BlockingVariable | ||
import spock.util.concurrent.BlockingVariables | ||
|
||
class BlockingVariablesDocSpec extends Specification { | ||
|
||
// tag::blocking-variables-spec[] | ||
def "single variable is read before it is written"() { | ||
def list = new BlockingVariable<List<Integer>>() // <1> | ||
|
||
when: | ||
Thread.start { | ||
Thread.sleep(250) // <2> | ||
println "calling set" | ||
list.set([1, 2, 3]) | ||
} | ||
|
||
then: | ||
println "calling get, blocking" | ||
list.get() == [1, 2, 3] // <3> | ||
} | ||
|
||
def "example of multiple variables"() { | ||
def vars = new BlockingVariables(2.0) // <4> | ||
|
||
when: | ||
Thread.start { | ||
Thread.sleep(500) // <5> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please use shorter sleeps as this slows down our overall tests, i.e. 100 or less There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I made some tests, i.e. repeating the specs ~50 times, and it seemed that (on my machine) the sleeps could go as low as about 10ms before the order of execution for some of the statements would be changing. So I chose 25ms and 50ms respectively in the commit I just made. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unfortunately, the CI servers are slower than most PCs so that is why there is a bit of a margin in the However, if the time is not really critical to the test it should be as low possible. In these tests it is just used to visualize a delay, the correctness of |
||
println "setting bar and baz" | ||
vars.bar = 2 | ||
vars.baz = 3 | ||
} | ||
Thread.start { | ||
Thread.sleep(250) // <5> | ||
println "setting foo" | ||
vars.foo = 1 | ||
} | ||
|
||
then: | ||
println "before comparison, blocking" | ||
vars.foo == 1 // <6> | ||
vars.bar == 2 | ||
vars.baz == 3 | ||
} | ||
// end::blocking-variables-spec[] | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
package org.spockframework.docs.utilities.concurrent | ||
|
||
import org.spockframework.runtime.ConditionNotSatisfiedError | ||
import org.spockframework.runtime.SpockTimeoutError | ||
import spock.lang.Specification | ||
import spock.util.concurrent.PollingConditions | ||
|
||
class PollingConditionsDocSpec extends Specification { | ||
// tag::polling-conditions-spec[] | ||
PollingConditions conditions = new PollingConditions() // <1> | ||
|
||
volatile int num = 0 | ||
volatile String str = null | ||
|
||
def "time controls and their default values"() { | ||
expect: | ||
with(conditions) { | ||
timeout == 1 | ||
initialDelay == 0 | ||
delay == 0.1 | ||
factor == 1 | ||
} | ||
} | ||
|
||
def "succeeds if all conditions are eventually satisfied"() { | ||
|
||
when: | ||
Thread.start { | ||
num = 42 | ||
sleep(500) // <2> | ||
str = "hello" | ||
} | ||
|
||
then: | ||
conditions.eventually { // <3> | ||
num == 42 | ||
} | ||
|
||
and: | ||
conditions.eventually { // <3> | ||
str == "hello" | ||
} | ||
|
||
and: | ||
noExceptionThrown() // <4> | ||
} | ||
|
||
def "fails if any condition isn't satisfied in time"() { | ||
|
||
given: | ||
Thread.start { | ||
num = 42 | ||
sleep(500) // milliseconds <2> | ||
str = "hello" | ||
} | ||
|
||
expect: | ||
conditions.within(0.1) { // seconds <5> | ||
num == 42 | ||
} | ||
|
||
when: | ||
conditions.eventually { // <3> | ||
num == 0 | ||
str == "bye" | ||
} | ||
|
||
then: | ||
def error = thrown(SpockTimeoutError) | ||
error.cause.message.contains('num == 0') // <6> | ||
} | ||
// end::polling-conditions-spec[] | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since Spock 2.0 uses Java 8
BlockingVariable
is kind of obsolete as there isCompletableFuture
, we are still debating whether to deprecate it or remove it entirely.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And this should be mentioned in the docs?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, but if the class is going to be deprecated or deleted it does not need to be documented. ;-)