|
35 | 35 | import java.util.List; |
36 | 36 | import java.util.Map; |
37 | 37 | import java.util.TreeMap; |
38 | | -import java.util.concurrent.atomic.AtomicInteger; |
| 38 | +import java.util.concurrent.CountDownLatch; |
| 39 | +import java.util.concurrent.Future; |
| 40 | +import java.util.concurrent.TimeUnit; |
39 | 41 | import java.util.logging.Logger; |
40 | 42 | import java.util.stream.StreamSupport; |
41 | 43 | import org.junit.jupiter.api.AfterAll; |
|
44 | 46 | import org.openqa.selenium.BuildInfo; |
45 | 47 | import org.openqa.selenium.Platform; |
46 | 48 | import org.openqa.selenium.TimeoutException; |
| 49 | +import org.openqa.selenium.WebDriverException; |
47 | 50 | import org.openqa.selenium.environment.webserver.AppServer; |
48 | 51 | import org.openqa.selenium.environment.webserver.NettyAppServer; |
49 | 52 | import org.openqa.selenium.json.Json; |
@@ -234,32 +237,89 @@ public void shouldAllowConfigurationFromSystemProperties() { |
234 | 237 | } |
235 | 238 | } |
236 | 239 |
|
237 | | - @Test |
238 | | - public void shouldStopRequestAfterTimeout() throws InterruptedException { |
239 | | - AtomicInteger counter = new AtomicInteger(); |
| 240 | + private ClientConfig prepareShouldStopTest( |
| 241 | + CountDownLatch executing, CountDownLatch interrupted, int timeout) { |
| 242 | + CountDownLatch unlock = new CountDownLatch(1); |
240 | 243 |
|
241 | 244 | delegate = |
242 | 245 | req -> { |
243 | | - counter.incrementAndGet(); |
244 | 246 | try { |
245 | | - Thread.sleep(1600); |
| 247 | + unlock.await(20, TimeUnit.SECONDS); |
246 | 248 | } catch (InterruptedException ex) { |
247 | 249 | Thread.currentThread().interrupt(); |
| 250 | + throw new RuntimeException(ex); |
248 | 251 | } |
249 | | - HttpResponse response = new HttpResponse(); |
250 | | - response.setStatus(302); |
251 | | - response.addHeader("Location", "/"); |
252 | | - return response; |
| 252 | + |
| 253 | + return new HttpResponse(); |
253 | 254 | }; |
254 | | - ClientConfig clientConfig = ClientConfig.defaultConfig().readTimeout(Duration.ofMillis(800)); |
| 255 | + |
| 256 | + return ClientConfig.defaultConfig() |
| 257 | + .withFilter( |
| 258 | + (handler) -> |
| 259 | + (request) -> { |
| 260 | + try { |
| 261 | + executing.countDown(); |
| 262 | + return handler.execute(request); |
| 263 | + } catch (WebDriverException ex) { |
| 264 | + if (ex.getCause() instanceof InterruptedException) { |
| 265 | + interrupted.countDown(); |
| 266 | + } |
| 267 | + |
| 268 | + throw ex; |
| 269 | + } finally { |
| 270 | + unlock.countDown(); |
| 271 | + } |
| 272 | + }) |
| 273 | + .readTimeout(Duration.ofMillis(timeout)); |
| 274 | + } |
| 275 | + |
| 276 | + @Test |
| 277 | + public void shouldStopRequestAfterTimeout() throws InterruptedException { |
| 278 | + CountDownLatch executing = new CountDownLatch(1); |
| 279 | + CountDownLatch interrupted = new CountDownLatch(1); |
| 280 | + ClientConfig clientConfig = prepareShouldStopTest(executing, interrupted, 400); |
255 | 281 |
|
256 | 282 | try (HttpClient client = |
257 | 283 | createFactory().createClient(clientConfig.baseUri(URI.create(server.whereIs("/"))))) { |
258 | 284 | HttpRequest request = new HttpRequest(GET, "/delayed"); |
| 285 | + |
259 | 286 | assertThatExceptionOfType(TimeoutException.class).isThrownBy(() -> client.execute(request)); |
260 | | - Thread.sleep(4200); |
| 287 | + assertThat(interrupted.await(800, TimeUnit.MILLISECONDS)).isTrue(); |
| 288 | + } |
| 289 | + } |
| 290 | + |
| 291 | + @Test |
| 292 | + public void shouldStopAsyncRequestAfterTimeout() throws InterruptedException { |
| 293 | + CountDownLatch executing = new CountDownLatch(1); |
| 294 | + CountDownLatch interrupted = new CountDownLatch(1); |
| 295 | + ClientConfig clientConfig = prepareShouldStopTest(executing, interrupted, 400); |
| 296 | + |
| 297 | + try (HttpClient client = |
| 298 | + createFactory().createClient(clientConfig.baseUri(URI.create(server.whereIs("/"))))) { |
| 299 | + HttpRequest request = new HttpRequest(GET, "/delayed"); |
| 300 | + // does intentionally not read the future |
| 301 | + client.executeAsync(request); |
| 302 | + assertThat(interrupted.await(800, TimeUnit.MILLISECONDS)).isTrue(); |
| 303 | + } |
| 304 | + } |
| 305 | + |
| 306 | + @Test |
| 307 | + public void shouldStopRequestOnCancel() throws InterruptedException { |
| 308 | + CountDownLatch executing = new CountDownLatch(1); |
| 309 | + CountDownLatch interrupted = new CountDownLatch(1); |
| 310 | + CountDownLatch unlock = new CountDownLatch(1); |
| 311 | + ClientConfig clientConfig = prepareShouldStopTest(executing, interrupted, 4000); |
| 312 | + |
| 313 | + try (HttpClient client = |
| 314 | + createFactory().createClient(clientConfig.baseUri(URI.create(server.whereIs("/"))))) { |
| 315 | + HttpRequest request = new HttpRequest(GET, "/delayed"); |
| 316 | + |
| 317 | + Future<?> future = client.executeAsync(request); |
261 | 318 |
|
262 | | - assertThat(counter.get()).isEqualTo(1); |
| 319 | + assertThat(executing.await(800, TimeUnit.MILLISECONDS)).isTrue(); |
| 320 | + assertThat(future.cancel(true)).isTrue(); |
| 321 | + assertThat(interrupted.await(800, TimeUnit.MILLISECONDS)).isTrue(); |
| 322 | + unlock.countDown(); |
263 | 323 | } |
264 | 324 | } |
265 | 325 |
|
|
0 commit comments