2929import java .util .Collections ;
3030import java .util .HashSet ;
3131import java .util .Set ;
32+ import java .util .concurrent .TimeUnit ;
3233import java .util .concurrent .atomic .AtomicLong ;
34+ import java .util .concurrent .locks .LockSupport ;
35+ import java .util .function .BooleanSupplier ;
3336import org .junit .After ;
3437import org .junit .Test ;
3538import org .junit .runner .RunWith ;
@@ -62,6 +65,17 @@ private static String registerAddresses(EndpointLifecycleManager mgr, String...
6265 return finderId ;
6366 }
6467
68+ private static void awaitCondition (String message , BooleanSupplier condition ) {
69+ long deadlineNanos = System .nanoTime () + TimeUnit .SECONDS .toNanos (5 );
70+ while (System .nanoTime () < deadlineNanos ) {
71+ if (condition .getAsBoolean ()) {
72+ return ;
73+ }
74+ LockSupport .parkNanos (TimeUnit .MILLISECONDS .toNanos (10 ));
75+ }
76+ assertTrue (message , condition .getAsBoolean ());
77+ }
78+
6579 @ Test
6680 public void endpointCreationStartsProbing () throws Exception {
6781 KeyRangeCacheTest .FakeEndpointCache cache = new KeyRangeCacheTest .FakeEndpointCache ();
@@ -70,9 +84,8 @@ public void endpointCreationStartsProbing() throws Exception {
7084 cache , /* probeIntervalSeconds= */ 1 , Duration .ofMinutes (30 ), Clock .systemUTC ());
7185
7286 registerAddresses (manager , "server1" );
73-
74- // Wait for background creation on the scheduler thread.
75- Thread .sleep (1000 );
87+ awaitCondition (
88+ "endpoint should be created in background" , () -> cache .getIfPresent ("server1" ) != null );
7689
7790 // Endpoint should be created in the cache.
7891 assertNotNull (cache .getIfPresent ("server1" ));
@@ -95,8 +108,6 @@ public void duplicateRegistrationIsNoop() throws Exception {
95108 manager .updateActiveAddresses (finderId , Collections .singleton ("server1" ));
96109 manager .updateActiveAddresses (finderId , Collections .singleton ("server1" ));
97110
98- Thread .sleep (300 );
99-
100111 assertEquals (1 , manager .managedEndpointCount ());
101112 }
102113
@@ -123,7 +134,12 @@ public void probeTrafficDoesNotUpdateLastRealTrafficAt() throws Exception {
123134
124135 Instant creationTime = clock .instant ();
125136 registerAddresses (manager , "server1" );
126- Thread .sleep (300 );
137+ awaitCondition (
138+ "probe should run after background endpoint creation" ,
139+ () -> {
140+ EndpointLifecycleManager .EndpointState state = manager .getEndpointState ("server1" );
141+ return state != null && state .lastProbeAt != null ;
142+ });
127143
128144 // Probe traffic should not change lastRealTrafficAt.
129145 EndpointLifecycleManager .EndpointState state = manager .getEndpointState ("server1" );
@@ -140,7 +156,6 @@ public void realRoutedTrafficUpdatesLastRealTrafficAt() throws Exception {
140156 cache , /* probeIntervalSeconds= */ 60 , Duration .ofMinutes (30 ), clock );
141157
142158 registerAddresses (manager , "server1" );
143- Thread .sleep (300 );
144159
145160 Instant before = clock .instant ();
146161 clock .advance (Duration .ofMinutes (5 ));
@@ -160,7 +175,8 @@ public void endpointWithOnlyProbeTrafficIsEvictedAfterIdleDuration() throws Exce
160175 new EndpointLifecycleManager (cache , /* probeIntervalSeconds= */ 60 , idleDuration , clock );
161176
162177 registerAddresses (manager , "server1" );
163- Thread .sleep (300 );
178+ awaitCondition (
179+ "endpoint should be created in background" , () -> cache .getIfPresent ("server1" ) != null );
164180
165181 assertTrue (manager .isManaged ("server1" ));
166182
@@ -185,7 +201,6 @@ public void endpointWithRecentRealTrafficIsNotEvicted() throws Exception {
185201 new EndpointLifecycleManager (cache , /* probeIntervalSeconds= */ 60 , idleDuration , clock );
186202
187203 registerAddresses (manager , "server1" );
188- Thread .sleep (300 );
189204
190205 // Record real traffic at 20 minutes.
191206 clock .advance (Duration .ofMinutes (20 ));
@@ -208,7 +223,8 @@ public void evictedEndpointIsRecreatedOnDemand() throws Exception {
208223 new EndpointLifecycleManager (cache , /* probeIntervalSeconds= */ 60 , idleDuration , clock );
209224
210225 registerAddresses (manager , "server1" );
211- Thread .sleep (300 );
226+ awaitCondition (
227+ "endpoint should be created in background" , () -> cache .getIfPresent ("server1" ) != null );
212228
213229 // Evict.
214230 clock .advance (Duration .ofMinutes (31 ));
@@ -217,7 +233,8 @@ public void evictedEndpointIsRecreatedOnDemand() throws Exception {
217233
218234 // Recreate.
219235 manager .requestEndpointRecreation ("server1" );
220- Thread .sleep (500 );
236+ awaitCondition (
237+ "endpoint should be recreated in background" , () -> cache .getIfPresent ("server1" ) != null );
221238
222239 assertTrue (manager .isManaged ("server1" ));
223240 assertNotNull (cache .getIfPresent ("server1" ));
@@ -231,7 +248,6 @@ public void shutdownStopsAllProbing() throws Exception {
231248 cache , /* probeIntervalSeconds= */ 1 , Duration .ofMinutes (30 ), Clock .systemUTC ());
232249
233250 registerAddresses (manager , "server1" , "server2" );
234- Thread .sleep (300 );
235251
236252 assertEquals (2 , manager .managedEndpointCount ());
237253
@@ -275,7 +291,6 @@ public void staleEndpointEvictedWhenNoLongerActive() throws Exception {
275291
276292 // Finder 1 reports server1 and server2.
277293 String finder1 = registerAddresses (manager , "server1" , "server2" );
278- Thread .sleep (300 );
279294 assertEquals (2 , manager .managedEndpointCount ());
280295
281296 // Finder 1 updates: server1 is gone, only server2 remains.
@@ -297,8 +312,7 @@ public void endpointKeptIfReferencedByAnotherFinder() throws Exception {
297312 // Finder 1 reports server1.
298313 String finder1 = registerAddresses (manager , "server1" );
299314 // Finder 2 also reports server1.
300- String finder2 = registerAddresses (manager , "server1" );
301- Thread .sleep (300 );
315+ registerAddresses (manager , "server1" );
302316
303317 // Finder 1 drops server1, but finder 2 still references it.
304318 manager .updateActiveAddresses (finder1 , Collections .emptySet ());
@@ -316,7 +330,6 @@ public void unregisterFinderEvictsEndpointsNoLongerReferenced() throws Exception
316330
317331 String finder1 = registerAddresses (manager , "server1" );
318332 String finder2 = registerAddresses (manager , "server2" );
319- Thread .sleep (300 );
320333
321334 manager .unregisterFinder (finder1 );
322335
0 commit comments