@@ -52,6 +52,17 @@ protected SubscriberWhiteboxVerification(TestEnvironment env) {
52
52
*/
53
53
public abstract Publisher <T > createHelperPublisher (long elements );
54
54
55
+ /**
56
+ * Used to break possibly infinite wait-loops.
57
+ * Some Rules use the "eventually stop signalling" wording, which requires the test to spin accepting {@code onNext}
58
+ * signals until no more are signalled. In these tests, this value will be used as upper bound on the number of spin iterations.
59
+ *
60
+ * Override this method in case your implementation synchronously signals very large batches before reacting to cancellation (for example).
61
+ */
62
+ public long maxOnNextSignalsInTest () {
63
+ return 100 ;
64
+ }
65
+
55
66
////////////////////// TEST ENV CLEANUP /////////////////////////////////////
56
67
57
68
@ BeforeMethod
@@ -437,8 +448,33 @@ public void spec312_cancelMustRequestThePublisherToEventuallyStopSignaling() thr
437
448
subscriberTest (new TestStageTestRun () {
438
449
@ Override
439
450
public void run (WhiteboxTestStage stage ) throws InterruptedException {
451
+ final int requestedElements = 5 ;
452
+
453
+ stage .puppet ().triggerRequest (requestedElements );
454
+ stage .expectRequest ();
455
+ stage .signalNext ();
456
+
457
+ // cancelling is NOT REQUIRED to stop the stream immediatly, example: there may be signals in flight
440
458
stage .puppet ().signalCancel ();
441
- stage .expectCancelling ();
459
+
460
+ stage .probe ().expectNext ();
461
+ long onNextSignals = 1 ;
462
+
463
+ boolean stillBeingSignalled ;
464
+ do {
465
+ // depends on Rule 3.6 https://github.com/reactive-streams/reactive-streams#3.12
466
+ // requesting from a cancelled subscription MUST be a NOPs
467
+ stage .puppet ().triggerRequest (1 );
468
+ stage .signalNext (); // signalling will stop, since Subscription cancelled
469
+
470
+ try {
471
+ stage .probe ().expectNone ();
472
+ stillBeingSignalled = false ;
473
+ } catch (Throwable th ) {
474
+ onNextSignals += 1 ;
475
+ stillBeingSignalled = true ;
476
+ }
477
+ } while (stillBeingSignalled && onNextSignals < maxOnNextSignalsInTest ());
442
478
443
479
stage .verifyNoAsyncErrors ();
444
480
}
@@ -518,7 +554,7 @@ public void subscriberTestWithoutSetup(TestStageTestRun body) throws Throwable {
518
554
519
555
public class WhiteboxTestStage extends ManualPublisher <T > {
520
556
public Publisher <T > pub ;
521
- public ManualSubscriber <T > tees ; // gives us access to an infinite stream of T values
557
+ public ManualSubscriber <T > tees ; // gives us access to a stream T values
522
558
public WhiteboxSubscriberProbe <T > probe ;
523
559
524
560
public T lastT = null ;
@@ -546,6 +582,10 @@ public SubscriberPuppet puppet() {
546
582
return probe .puppet ();
547
583
}
548
584
585
+ public WhiteboxSubscriberProbe <T > probe () {
586
+ return probe ;
587
+ }
588
+
549
589
public Publisher <T > createHelperPublisher (long elements ) {
550
590
return SubscriberWhiteboxVerification .this .createHelperPublisher (elements );
551
591
}
0 commit comments