3636import java .util .concurrent .Executors ;
3737import java .util .function .Function ;
3838import java .util .function .Supplier ;
39+ import java .util .stream .IntStream ;
3940import java .util .stream .Stream ;
4041import org .junit .jupiter .api .DisplayName ;
42+ import org .junit .jupiter .api .RepeatedTest ;
4143import org .junit .jupiter .api .Test ;
4244import org .junit .jupiter .api .Timeout ;
4345import org .junit .jupiter .api .parallel .Execution ;
4446import org .junit .jupiter .api .parallel .ExecutionMode ;
47+ import org .junit .jupiter .api .parallel .Isolated ;
4548import org .junit .jupiter .params .ParameterizedTest ;
4649import org .junit .jupiter .params .provider .Arguments ;
4750import org .junit .jupiter .params .provider .MethodSource ;
48- import org .junit .jupiter .params .provider .ValueSource ;
4951
5052/**
5153 * {@link Lazy} tests.
5254 *
5355 * @author Ashley Scopes
5456 */
5557@ DisplayName ("Lazy tests" )
56- @ Execution (ExecutionMode .CONCURRENT )
58+ @ Execution (ExecutionMode .SAME_THREAD )
59+ @ Isolated ("Time-sensitive tests" )
5760@ SuppressWarnings ("unchecked" )
5861class LazyTest {
5962
60- @ DisplayName ("Initializing with a null supplier throws a NullPointerException" )
63+ @ DisplayName ("Initialising with a null supplier throws a NullPointerException" )
6164 @ Test
62- void initializingWithNullSupplierThrowsNullPointerException () {
65+ @ Timeout (15 )
66+ void initialisingWithNullSupplierThrowsNullPointerException () {
6367 thenCode (() -> new Lazy <>(null ))
6468 .isInstanceOf (NullPointerException .class );
6569 }
6670
6771 @ DisplayName ("access() returns the cached result" )
68- @ Test
72+ @ RepeatedTest (5 )
73+ @ Timeout (15 )
6974 void accessReturnsTheCachedResult () {
7075 // Given
7176 var value = new Object ();
@@ -88,9 +93,9 @@ void accessReturnsTheCachedResult() {
8893 }
8994
9095 @ DisplayName ("access() synchronizes correctly on initial accesses" )
91- @ ValueSource ( ints = { 2 , 4 , 10 , 100 } )
96+ @ MethodSource ( "concurrentRepeatCases" )
9297 @ ParameterizedTest (name = "for {0} concurrent read(s)" )
93- @ Timeout (30 )
98+ @ Timeout (15 )
9499 void accessSynchronizesCorrectlyOnInitialAccesses (int concurrency ) {
95100 // This is closeable in Java 19, but not before.
96101 @ SuppressWarnings ("resource" )
@@ -142,9 +147,9 @@ void accessSynchronizesCorrectlyOnInitialAccesses(int concurrency) {
142147 }
143148
144149 @ DisplayName ("access() synchronizes correctly on subsequent accesses" )
145- @ ValueSource ( ints = { 2 , 4 , 10 , 100 } )
150+ @ MethodSource ( "concurrentRepeatCases" )
146151 @ ParameterizedTest (name = "for {0} concurrent read(s)" )
147- @ Timeout (30 )
152+ @ Timeout (15 )
148153 void accessSynchronizesCorrectlyOnSubsequentAccesses (int concurrency ) {
149154 // This is closeable in Java 19, but not before.
150155 @ SuppressWarnings ("resource" )
@@ -189,8 +194,9 @@ void accessSynchronizesCorrectlyOnSubsequentAccesses(int concurrency) {
189194 }
190195 }
191196
192- @ DisplayName ("access returns a new value when the lazy is destroyed" )
193- @ Test
197+ @ DisplayName ("access() returns a new value when the lazy is destroyed" )
198+ @ RepeatedTest (5 )
199+ @ Timeout (15 )
194200 void accessReturnsNewValueWhenLazyIsDestroyed () {
195201 // Given
196202 final var firstValue = new Object ();
@@ -217,8 +223,9 @@ void accessReturnsNewValueWhenLazyIsDestroyed() {
217223 }
218224
219225 @ DisplayName ("toString() returns the expected values when initialized" )
220- @ MethodSource ("toStringInitializedCases " )
226+ @ MethodSource ("toStringInitialisedCases " )
221227 @ ParameterizedTest (name = "with \" {0}\" expected to return \" {1}\" " )
228+ @ Timeout (15 )
222229 void toStringReturnsExpectedValuesWhenInitialized (Object value , String expected ) {
223230 // Given
224231 var supplier = (Supplier <Object >) mock (Supplier .class );
@@ -234,7 +241,8 @@ void toStringReturnsExpectedValuesWhenInitialized(Object value, String expected)
234241 }
235242
236243 @ DisplayName ("toString() returns the expected values when uninitialized" )
237- @ Test
244+ @ RepeatedTest (5 )
245+ @ Timeout (15 )
238246 void toStringReturnsExpectedValuesWhenUninitialized () {
239247 // Given
240248 var supplier = (Supplier <Object >) mock (Supplier .class );
@@ -250,7 +258,8 @@ void toStringReturnsExpectedValuesWhenUninitialized() {
250258 }
251259
252260 @ DisplayName ("ifInitialized() calls the callable when initialized" )
253- @ Test
261+ @ RepeatedTest (5 )
262+ @ Timeout (15 )
254263 void ifInitializedCallsTheCallableWhenInitialized () {
255264 // Given
256265 var initializer = (Supplier <Object >) mock (Supplier .class );
@@ -267,9 +276,9 @@ void ifInitializedCallsTheCallableWhenInitialized() {
267276 }
268277
269278 @ DisplayName ("ifInitialized() handles race conditions" )
270- @ ValueSource ( ints = { 5 , 10 , 50 , 100 } )
279+ @ MethodSource ( "concurrentRepeatCases" )
271280 @ ParameterizedTest (name = "for concurrency = {0}" )
272- @ Timeout (30 )
281+ @ Timeout (15 )
273282 void ifInitializedHandlesRaceConditionsCorrectly (int concurrency ) {
274283 // Given
275284 var initializer = (Supplier <Object >) mock (Supplier .class );
@@ -301,7 +310,8 @@ void ifInitializedHandlesRaceConditionsCorrectly(int concurrency) {
301310 }
302311
303312 @ DisplayName ("ifInitialized() propagates exceptions when initialized" )
304- @ Test
313+ @ RepeatedTest (5 )
314+ @ Timeout (15 )
305315 void ifInitializedPropagatesExceptions () {
306316 // Given
307317 var initializer = (Supplier <Object >) mock (Supplier .class );
@@ -321,7 +331,8 @@ void ifInitializedPropagatesExceptions() {
321331 }
322332
323333 @ DisplayName ("ifInitialized() does not call the callable when not initialized" )
324- @ Test
334+ @ RepeatedTest (5 )
335+ @ Timeout (15 )
325336 void ifInitializedDoesNotCallTheCallableWhenNotInitialized () {
326337 // Given
327338 var initializer = (Supplier <Object >) mock (Supplier .class );
@@ -338,13 +349,17 @@ void ifInitializedDoesNotCallTheCallableWhenNotInitialized() {
338349 verifyNoInteractions (callback );
339350 }
340351
341- static Stream <Arguments > toStringInitializedCases () {
352+ static Stream <Arguments > toStringInitialisedCases () {
342353 return Stream .of (
343354 Arguments .of (new Something (), "Lazy{data=Something{}}" ),
344355 Arguments .of ("Hello, World!" , "Lazy{data=\" Hello, World!\" }" )
345356 );
346357 }
347358
359+ static IntStream concurrentRepeatCases () {
360+ return IntStream .of (2 , 3 , 5 , 10 , 20 , 30 );
361+ }
362+
348363 static class Something {
349364
350365 @ Override
0 commit comments