|
33 | 33 | import io.rsocket.util.EmptyPayload;
|
34 | 34 | import java.time.Duration;
|
35 | 35 | import java.util.List;
|
| 36 | +import java.util.concurrent.CancellationException; |
36 | 37 | import java.util.concurrent.atomic.AtomicReference;
|
37 | 38 | import org.assertj.core.api.Assertions;
|
38 | 39 | import org.junit.Rule;
|
@@ -287,6 +288,46 @@ public void requestChannelCase_StreamIsTerminatedAfterBothSidesSentCompletion2()
|
287 | 288 | requesterPublisher, requesterSubscriber, responderPublisher, responderSubscriber);
|
288 | 289 | }
|
289 | 290 |
|
| 291 | + @Test |
| 292 | + public void requestChannelCase_ErrorFromResponderShouldTerminatesStreamsOnBothSides() { |
| 293 | + TestPublisher<Payload> requesterPublisher = TestPublisher.create(); |
| 294 | + AssertSubscriber<Payload> requesterSubscriber = new AssertSubscriber<>(0); |
| 295 | + |
| 296 | + AssertSubscriber<Payload> responderSubscriber = new AssertSubscriber<>(0); |
| 297 | + TestPublisher<Payload> responderPublisher = TestPublisher.create(); |
| 298 | + |
| 299 | + initRequestChannelCase( |
| 300 | + requesterPublisher, requesterSubscriber, responderPublisher, responderSubscriber); |
| 301 | + |
| 302 | + nextFromResponderPublisher(responderPublisher, requesterSubscriber); |
| 303 | + |
| 304 | + nextFromRequesterPublisher(requesterPublisher, responderSubscriber); |
| 305 | + |
| 306 | + // ensures both sides are terminated |
| 307 | + errorFromResponderPublisher( |
| 308 | + requesterPublisher, requesterSubscriber, responderPublisher, responderSubscriber); |
| 309 | + } |
| 310 | + |
| 311 | + @Test |
| 312 | + public void requestChannelCase_ErrorFromRequesterShouldTerminatesStreamsOnBothSides() { |
| 313 | + TestPublisher<Payload> requesterPublisher = TestPublisher.create(); |
| 314 | + AssertSubscriber<Payload> requesterSubscriber = new AssertSubscriber<>(0); |
| 315 | + |
| 316 | + AssertSubscriber<Payload> responderSubscriber = new AssertSubscriber<>(0); |
| 317 | + TestPublisher<Payload> responderPublisher = TestPublisher.create(); |
| 318 | + |
| 319 | + initRequestChannelCase( |
| 320 | + requesterPublisher, requesterSubscriber, responderPublisher, responderSubscriber); |
| 321 | + |
| 322 | + nextFromResponderPublisher(responderPublisher, requesterSubscriber); |
| 323 | + |
| 324 | + nextFromRequesterPublisher(requesterPublisher, responderSubscriber); |
| 325 | + |
| 326 | + // ensures both sides are terminated |
| 327 | + errorFromRequesterPublisher( |
| 328 | + requesterPublisher, requesterSubscriber, responderPublisher, responderSubscriber); |
| 329 | + } |
| 330 | + |
290 | 331 | void initRequestChannelCase(
|
291 | 332 | TestPublisher<Payload> requesterPublisher,
|
292 | 333 | AssertSubscriber<Payload> requesterSubscriber,
|
@@ -405,6 +446,48 @@ void cancelFromRequesterSubscriber(
|
405 | 446 | requesterPublisher.assertNoSubscribers();
|
406 | 447 | }
|
407 | 448 |
|
| 449 | + static final CustomRSocketException EXCEPTION = new CustomRSocketException(123456, "test"); |
| 450 | + |
| 451 | + void errorFromResponderPublisher( |
| 452 | + TestPublisher<Payload> requesterPublisher, |
| 453 | + AssertSubscriber<Payload> requesterSubscriber, |
| 454 | + TestPublisher<Payload> responderPublisher, |
| 455 | + AssertSubscriber<Payload> responderSubscriber) { |
| 456 | + // ensures that after sending cancel the whole requestChannel is terminated |
| 457 | + responderPublisher.error(EXCEPTION); |
| 458 | + // error should be propagated |
| 459 | + responderSubscriber.assertTerminated().assertError(CancellationException.class); |
| 460 | + requesterSubscriber |
| 461 | + .assertTerminated() |
| 462 | + .assertError(CustomRSocketException.class) |
| 463 | + .assertErrorMessage("test"); |
| 464 | + // ensures that cancellation is propagated to the actual upstream |
| 465 | + requesterPublisher.assertWasCancelled(); |
| 466 | + requesterPublisher.assertNoSubscribers(); |
| 467 | + } |
| 468 | + |
| 469 | + void errorFromRequesterPublisher( |
| 470 | + TestPublisher<Payload> requesterPublisher, |
| 471 | + AssertSubscriber<Payload> requesterSubscriber, |
| 472 | + TestPublisher<Payload> responderPublisher, |
| 473 | + AssertSubscriber<Payload> responderSubscriber) { |
| 474 | + // ensures that after sending cancel the whole requestChannel is terminated |
| 475 | + requesterPublisher.error(EXCEPTION); |
| 476 | + // error should be propagated |
| 477 | + responderSubscriber |
| 478 | + .assertTerminated() |
| 479 | + .assertError(CustomRSocketException.class) |
| 480 | + .assertErrorMessage("test"); |
| 481 | + requesterSubscriber |
| 482 | + .assertTerminated() |
| 483 | + .assertError(CustomRSocketException.class) |
| 484 | + .assertErrorMessage("test"); |
| 485 | + |
| 486 | + // ensures that cancellation is propagated to the actual upstream |
| 487 | + responderPublisher.assertWasCancelled(); |
| 488 | + responderPublisher.assertNoSubscribers(); |
| 489 | + } |
| 490 | + |
408 | 491 | public static class SocketRule extends ExternalResource {
|
409 | 492 |
|
410 | 493 | DirectProcessor<ByteBuf> serverProcessor;
|
|
0 commit comments