11package org .testcontainers .containers .wait .strategy ;
22
3- import static org .mockito .ArgumentMatchers .*;
4- import static org .mockito .Mockito .*;
5- import static org .rnorth .visibleassertions .VisibleAssertions .*;
6-
7- import java .time .Duration ;
8- import java .util .concurrent .CompletableFuture ;
9- import java .util .concurrent .ExecutionException ;
10- import java .util .concurrent .TimeUnit ;
11-
123import org .junit .Before ;
134import org .junit .Test ;
145import org .mockito .InOrder ;
178import org .rnorth .ducttape .TimeoutException ;
189import org .testcontainers .containers .GenericContainer ;
1910
20- import com .google .common .util .concurrent .Uninterruptibles ;
11+ import java .time .Duration ;
12+
13+ import static org .mockito .ArgumentMatchers .any ;
14+ import static org .mockito .ArgumentMatchers .eq ;
15+ import static org .mockito .Mockito .*;
16+ import static org .rnorth .visibleassertions .VisibleAssertions .*;
2117
2218public class WaitAllStrategyTest {
2319
@@ -35,80 +31,78 @@ public void setUp() {
3531 MockitoAnnotations .initMocks (this );
3632 }
3733
34+ /*
35+ * Dummy-based tests, to check that timeout values are propagated correctly, without involving actual timing-sensitive code
36+ */
3837 @ Test
39- public void simpleTest () {
40-
41- final WaitStrategy underTest = new WaitAllStrategy ()
42- .withStrategy (strategy1 )
43- .withStrategy (strategy2 );
44-
45- doNothing ().when (strategy1 ).waitUntilReady (eq (container ));
46- doNothing ().when (strategy2 ).waitUntilReady (eq (container ));
47-
48- underTest .waitUntilReady (container );
49-
50- InOrder inOrder = inOrder (strategy1 , strategy2 );
51- inOrder .verify (strategy1 ).waitUntilReady (any ());
52- inOrder .verify (strategy2 ).waitUntilReady (any ());
53- }
38+ public void parentTimeoutApplies () {
5439
55- @ Test
56- public void maxTimeOutApplies () {
40+ DummyStrategy child1 = new DummyStrategy ( Duration . ofMillis ( 10 ));
41+ child1 . withStartupTimeout ( Duration . ofMillis ( 20 ));
5742
58- WaitStrategy child1 = new SleepingStrategy (Duration .ofMinutes (30 ))
59- .withStartupTimeout (Duration .ofHours (1 ));
43+ assertEquals ("withStartupTimeout directly sets the timeout" , 20L , child1 .startupTimeout .toMillis ());
6044
61- final WaitStrategy underTest = new WaitAllStrategy ()
45+ new WaitAllStrategy ()
6246 .withStrategy (child1 )
63- .withStartupTimeout (Duration .ofMillis (10 ));
47+ .withStartupTimeout (Duration .ofMillis (30 ));
6448
65- assertThrows ("The outer strategy timeout applies" , TimeoutException .class , () -> {
66- underTest .waitUntilReady (container );
67- });
49+ assertEquals ("WaitAllStrategy overrides a child's timeout" , 30L , child1 .startupTimeout .toMillis ());
6850 }
6951
7052 @ Test
71- public void appliesOuterTimeoutTooLittleTime () {
53+ public void parentTimeoutAppliesToMultipleChildren () {
7254
7355 Duration defaultInnerWait = Duration .ofMillis (2 );
7456 Duration outerWait = Duration .ofMillis (6 );
7557
76- WaitStrategy child1 = new SleepingStrategy (defaultInnerWait );
77- WaitStrategy child2 = new SleepingStrategy (defaultInnerWait );
58+ DummyStrategy child1 = new DummyStrategy (defaultInnerWait );
59+ DummyStrategy child2 = new DummyStrategy (defaultInnerWait );
7860
79- final WaitStrategy underTest = new WaitAllStrategy ()
61+ new WaitAllStrategy ()
8062 .withStrategy (child1 )
8163 .withStrategy (child2 )
8264 .withStartupTimeout (outerWait );
8365
84- assertThrows ("The outer strategy timeout applies" , TimeoutException .class , () -> {
85- underTest .waitUntilReady (container );
86- });
66+ assertEquals ("WaitAllStrategy overrides a child's timeout (1st)" , 6L , child1 .startupTimeout .toMillis ());
67+ assertEquals ("WaitAllStrategy overrides a child's timeout (2nd)" , 6L , child2 .startupTimeout .toMillis ());
8768 }
8869
8970 @ Test
90- public void appliesOuterTimeoutEnoughTime () {
71+ public void parentTimeoutAppliesToAdditionalChildren () {
9172
9273 Duration defaultInnerWait = Duration .ofMillis (2 );
9374 Duration outerWait = Duration .ofMillis (20 );
9475
95- WaitStrategy child1 = new SleepingStrategy (defaultInnerWait );
96- WaitStrategy child2 = new SleepingStrategy (defaultInnerWait );
76+ DummyStrategy child1 = new DummyStrategy (defaultInnerWait );
77+ DummyStrategy child2 = new DummyStrategy (defaultInnerWait );
9778
98- final WaitStrategy underTest = new WaitAllStrategy ()
79+ new WaitAllStrategy ()
9980 .withStrategy (child1 )
100- .withStrategy ( child2 )
101- .withStartupTimeout ( outerWait );
81+ .withStartupTimeout ( outerWait )
82+ .withStrategy ( child2 );
10283
103- try {
104- underTest .waitUntilReady (container );
105- } catch (Exception e ) {
106- if (e .getCause () instanceof CaughtTimeoutException )
107- fail ("The timeout wasn't applied to inner strategies." );
108- else {
109- fail (e .getMessage ());
110- }
111- }
84+ assertEquals ("WaitAllStrategy overrides a child's timeout (1st)" , 20L , child1 .startupTimeout .toMillis ());
85+ assertEquals ("WaitAllStrategy overrides a child's timeout (2nd, additional)" , 20L , child2 .startupTimeout .toMillis ());
86+ }
87+
88+ /*
89+ * Mock-based tests to check overall behaviour, without involving timing-sensitive code
90+ */
91+ @ Test
92+ public void childExecutionTest () {
93+
94+ final WaitStrategy underTest = new WaitAllStrategy ()
95+ .withStrategy (strategy1 )
96+ .withStrategy (strategy2 );
97+
98+ doNothing ().when (strategy1 ).waitUntilReady (eq (container ));
99+ doNothing ().when (strategy2 ).waitUntilReady (eq (container ));
100+
101+ underTest .waitUntilReady (container );
102+
103+ InOrder inOrder = inOrder (strategy1 , strategy2 );
104+ inOrder .verify (strategy1 ).waitUntilReady (any ());
105+ inOrder .verify (strategy2 ).waitUntilReady (any ());
112106 }
113107
114108 @ Test
@@ -145,7 +139,7 @@ public void timeoutChangeShouldNotBePossibleWithIndividualTimeoutMode() {
145139 @ Test
146140 public void shouldNotMessWithIndividualTimeouts () {
147141
148- final WaitStrategy underTest = new WaitAllStrategy (WaitAllStrategy .Mode .WITH_INDIVIDUAL_TIMEOUTS_ONLY )
142+ new WaitAllStrategy (WaitAllStrategy .Mode .WITH_INDIVIDUAL_TIMEOUTS_ONLY )
149143 .withStrategy (strategy1 )
150144 .withStrategy (strategy2 );
151145
@@ -157,7 +151,7 @@ public void shouldNotMessWithIndividualTimeouts() {
157151 public void shouldOverwriteIndividualTimeouts () {
158152
159153 Duration someSeconds = Duration .ofSeconds (23 );
160- final WaitStrategy underTest = new WaitAllStrategy ()
154+ new WaitAllStrategy ()
161155 .withStartupTimeout (someSeconds )
162156 .withStrategy (strategy1 )
163157 .withStrategy (strategy2 );
@@ -166,59 +160,14 @@ public void shouldOverwriteIndividualTimeouts() {
166160 verify (strategy1 ).withStartupTimeout (someSeconds );
167161 }
168162
169- @ Test
170- public void appliesOuterTimeoutOnAdditionalChildren () {
171-
172- Duration defaultInnerWait = Duration .ofMillis (2 );
173- Duration outerWait = Duration .ofMillis (20 );
174-
175- WaitStrategy child1 = new SleepingStrategy (defaultInnerWait );
176- WaitStrategy child2 = new SleepingStrategy (defaultInnerWait );
177-
178- final WaitStrategy underTest = new WaitAllStrategy ()
179- .withStrategy (child1 )
180- .withStartupTimeout (outerWait )
181- .withStrategy (child2 );
182-
183- try {
184- underTest .waitUntilReady (container );
185- } catch (Exception e ) {
186- if (e .getCause () instanceof CaughtTimeoutException )
187- fail ("The timeout wasn't applied to inner strategies." );
188- else {
189- fail (e .getMessage ());
190- }
191- }
192- }
193-
194- static class CaughtTimeoutException extends RuntimeException {
195-
196- CaughtTimeoutException (String message ) {
197- super (message );
198- }
199- }
200-
201- static class SleepingStrategy extends AbstractWaitStrategy {
202-
203- private final long sleepingDuration ;
204-
205- SleepingStrategy (Duration defaultInnerWait ) {
163+ static class DummyStrategy extends AbstractWaitStrategy {
164+ DummyStrategy (Duration defaultInnerWait ) {
206165 super .startupTimeout = defaultInnerWait ;
207- // Always oversleep by default
208- this .sleepingDuration = defaultInnerWait .multipliedBy (2 ).toMillis ();
209166 }
210167
211168 @ Override
212169 protected void waitUntilReady () {
213- try {
214- // Don't use ducttape, make sure we don't catch the wrong TimeoutException later on.
215- CompletableFuture .runAsync (
216- () -> Uninterruptibles .sleepUninterruptibly (this .sleepingDuration , TimeUnit .MILLISECONDS )
217- ).get ((int ) startupTimeout .toMillis (), TimeUnit .MILLISECONDS );
218- } catch (InterruptedException | ExecutionException e ) {
219- } catch (java .util .concurrent .TimeoutException e ) {
220- throw new CaughtTimeoutException ("Inner wait timed out, outer strategy didn't apply." );
221- }
170+ // no-op
222171 }
223172 }
224173}
0 commit comments