001/************************************************************************ 002 * Licensed under Public Domain (CC0) * 003 * * 004 * To the extent possible under law, the person who associated CC0 with * 005 * this code has waived all copyright and related or neighboring * 006 * rights to this code. * 007 * * 008 * You should have received a copy of the CC0 legalcode along with this * 009 * work. If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.* 010 ************************************************************************/ 011 012package org.reactivestreams.tck.flow.support; 013 014/** 015 * Internal TCK use only. 016 * Add / Remove tests for PublisherVerification here to make sure that they arre added/removed in the other places. 017 */ 018public interface PublisherVerificationRules { 019 /** 020 * Validates that the override of {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} 021 * returns a non-negative value. 022 */ 023 void required_validate_maxElementsFromPublisher() throws Exception; 024 /** 025 * Validates that the override of {@link org.reactivestreams.tck.PublisherVerification#boundedDepthOfOnNextAndRequestRecursion()} 026 * returns a positive value. 027 */ 028 void required_validate_boundedDepthOfOnNextAndRequestRecursion() throws Exception; 029 /** 030 * Asks for a {@code Publisher} that should emit exactly one item and complete (both within a 031 * timeout specified by {@link org.reactivestreams.tck.TestEnvironment#defaultTimeoutMillis()}) 032 * in response to a request(1). 033 * <p> 034 * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} returns zero. 035 * If this test fails, the following could be checked within the {@code Publisher} implementation: 036 * <ul> 037 * <li>the {@code Publisher.subscribe(Subscriber)} method has actual implementation,</li> 038 * <li>in the {@code Publisher.subscribe(Subscriber)} method, if there is an upstream {@code Publisher}, 039 * that {@code Publisher} is actually subscribed to,</li> 040 * <li>if the {@code Publisher} is part of a chain, all elements actually issue a {@code request()} call 041 * in response to the test subscriber or by default to their upstream,</li> 042 * <li>in the {@code Publisher.subscribe(Subscriber)} method, the {@code Subscriber.onSubscribe} is called 043 * as part of the preparation process (usually before subscribing to other {@code Publisher}s),</li> 044 * <li>if the {@code Publisher} implementation works for a consumer that calls {@code request(1)},</li> 045 * <li>if the {@code Publisher} implementation is able to emit an {@code onComplete} without requests,</li> 046 * <li>that the {@code Publisher} implementation does not emit more than the allowed elements (exactly one).</li> 047 * </ul> 048 */ 049 void required_createPublisher1MustProduceAStreamOfExactly1Element() throws Throwable; 050 /** 051 * Asks for a {@code Publisher} that should emit exactly three items and complete (all within a 052 * timeout specified by {@link org.reactivestreams.tck.TestEnvironment#defaultTimeoutMillis()}). 053 * <p> 054 * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 3. 055 * <p> 056 * The tests requests one-by-one and verifies each single response item arrives in time. 057 * <p> 058 * If this test fails, the following could be checked within the {@code Publisher} implementation: 059 * <ul> 060 * <li>the {@code Publisher.subscribe(Subscriber)} method has actual implementation,</li> 061 * <li>in the {@code Publisher.subscribe(Subscriber)} method, if there is an upstream {@code Publisher}, 062 * that {@code Publisher} is actually subscribed to,</li> 063 * <li>if the {@code Publisher} is part of a chain, all elements actually issue a {@code request()} call 064 * in response to the test subscriber or by default to their upstream,</li> 065 * <li>in the {@code Publisher.subscribe(Subscriber)} method, the {@code Subscriber.onSubscribe} is called 066 * as part of the preparation process (usually before subscribing to other {@code Publisher}s),</li> 067 * <li>if the {@code Publisher} implementation works for a subscriber that calls {@code request(1)} after consuming an item,</li> 068 * <li>if the {@code Publisher} implementation is able to emit an {@code onComplete} without requests.</li> 069 * </ul> 070 */ 071 void required_createPublisher3MustProduceAStreamOfExactly3Elements() throws Throwable; 072 /** 073 * Asks for a {@code Publisher} that responds to a request pattern of 0 (not requesting upfront), 1, 1 and 2 074 * in a timely manner. 075 * <p> 076 * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.1'>1.1</a> 077 * <p> 078 * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 5. 079 * <p> 080 * This test ensures that the {@code Publisher} implementation correctly responds to {@code request()} calls that in 081 * total are less than the number of elements this {@code Publisher} could emit (thus the completion event won't be emitted). 082 * <p> 083 * If this test fails, the following could be checked within the {@code Publisher} implementation: 084 * <ul> 085 * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li> 086 * <li>make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,</li> 087 * <li>if the {@code Publisher} implementation considers the cumulative request amount it receives,</li> 088 * <li>if the {@code Publisher} doesn't lose any {@code request()} signal and the state transition from idle -> emitting or emitting -> keep emitting works properly.</li> 089 * </ul> 090 */ 091 void required_spec101_subscriptionRequestMustResultInTheCorrectNumberOfProducedElements() throws Throwable; 092 /** 093 * Asks for a short {@code Publisher} and verifies that requesting once and with more than the length (but bounded) results in the 094 * correct number of items to be emitted (i.e., length 3 and request 10) followed by an {@code onComplete} signal. 095 * <p> 096 * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.2'>1.2</a> 097 * <p> 098 * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 3. 099 * <p> 100 * This test ensures that the {@code Publisher} implementation can deal with larger requests than the number of items it can produce. 101 * <p> 102 * If this test fails, the following could be checked within the {@code Publisher} implementation: 103 * <ul> 104 * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li> 105 * <li>make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass.</li> 106 * </ul> 107 */ 108 void required_spec102_maySignalLessThanRequestedAndTerminateSubscription() throws Throwable; 109 /** 110 * Asks for a short {@code Publisher} (i.e., length 10), repeatedly subscribes to this {@code Publisher}, requests items 111 * one by one and verifies the {@code Publisher} calls the {@code onXXX} methods non-overlappingly. 112 * <p> 113 * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.3'>1.3</a> 114 * <p> 115 * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 10. 116 * <p> 117 * Note that this test is probabilistic, that is, may not capture any concurrent invocation in a {code Publisher} implementation. 118 * Note also that this test is sensitive to cases when a {@code request()} call in {@code onSubscribe()} triggers an asynchronous 119 * call to the other {@code onXXX} methods. In contrast, the test allows synchronous call chain of 120 * {@code onSubscribe -> request -> onNext}. 121 * <p> 122 * If this test fails, the following could be checked within the {@code Publisher} implementation: 123 * <ul> 124 * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li> 125 * <li>make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,</li> 126 * <li>if a {@code request()} call from {@code onSubscribe()} could trigger an asynchronous call to {@code onNext()} and if so, make sure 127 * such {@code request()} calls are deferred until the call to {@code onSubscribe()} returns normally.</li> 128 * </ul> 129 */ 130 void stochastic_spec103_mustSignalOnMethodsSequentially() throws Throwable; 131 /** 132 * Asks for an error {@code Publisher} that should call {@code onSubscribe} exactly once 133 * followed by a single call to {@code onError()} without receiving any requests and otherwise 134 * not throwing any exception. 135 * <p> 136 * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.4'>1.4</a> 137 * <p> 138 * The test is not executed if {@code PublisherVerification.createErrorPublisher()} returns null. 139 * <p> 140 * If this test fails, the following could be checked within the error {@code Publisher} implementation: 141 * <ul> 142 * <li>the {@code Publisher.subscribe(Subscriber)} method has actual implementation,</li> 143 * <li>in the {@code Publisher.subscribe(Subscriber)} method, if there is an upstream {@code Publisher}, 144 * that {@code Publisher} is actually subscribed to,</li> 145 * <li>if the {@code Publisher} implementation does signal an {@code onSubscribe} before signalling {@code onError},</li> 146 * <li>if the {@code Publisher} implementation is able to emit an {@code onError} without requests,</li> 147 * <li>if the {@code Publisher} is non-empty as this test requires a {@code Publisher} to signal an 148 * {@code onError} eagerly.</li> 149 * </ul> 150 */ 151 void optional_spec104_mustSignalOnErrorWhenFails() throws Throwable; 152 /** 153 * Asks for a short {@code Publisher} (i.e., length 3) and verifies, after requesting one by one, the sequence 154 * completes normally. 155 * <p> 156 * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.5'>1.5</a> 157 * <p> 158 * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 3. 159 * <p> 160 * Note that the tests requests 1 after the items have been received and before expecting an {@code onComplete} signal. 161 * <p> 162 * If this test fails, the following could be checked within the {@code Publisher} implementation: 163 * <ul> 164 * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li> 165 * <li>make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,</li> 166 * </ul> 167 */ 168 void required_spec105_mustSignalOnCompleteWhenFiniteStreamTerminates() throws Throwable; 169 /** 170 * Asks for an empty {@code Publisher} (i.e., length 0) and verifies it completes in a timely manner. 171 * <p> 172 * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.5'>1.5</a> 173 * <p> 174 * Note that the tests requests 1 before expecting an {@code onComplete} signal. 175 * <p> 176 * If this test fails, the following could be checked within the {@code Publisher} implementation: 177 * <ul> 178 * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li> 179 * <li>if the {@code Publisher} is non-empty as this test requires a {@code Publisher} without items.</li> 180 * </ul> 181 */ 182 void optional_spec105_emptyStreamMustTerminateBySignallingOnComplete() throws Throwable; 183 /** 184 * Currently, this test is skipped because it is unclear this rule can be effectively checked 185 * on a {@code Publisher} instance without looking into or hooking into the implementation of it. 186 * <p> 187 * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.6'>1.6</a> 188 */ 189 void untested_spec106_mustConsiderSubscriptionCancelledAfterOnErrorOrOnCompleteHasBeenCalled() throws Throwable; 190 /** 191 * Asks for a single-element {@code Publisher} and checks if requesting after the terminal event doesn't 192 * lead to more items or terminal signals to be emitted. 193 * <p> 194 * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.7'>1.7</a> 195 * <p> 196 * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 1. 197 * <p> 198 * The tests requests more items than the expected {@code Publisher} length upfront and some more items after its completion. 199 * <p> 200 * If this test fails, the following could be checked within the {@code Publisher} implementation: 201 * <ul> 202 * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li> 203 * <li>the indication for the terminal state is properly persisted and a request call can't trigger emission of more items or another 204 * terminal signal.</li> 205 * </ul> 206 */ 207 void required_spec107_mustNotEmitFurtherSignalsOnceOnCompleteHasBeenSignalled() throws Throwable; 208 /** 209 * Currently, this test is skipped, although it is possible to validate an error {@code Publisher} along 210 * the same lines as {@link #required_spec107_mustNotEmitFurtherSignalsOnceOnCompleteHasBeenSignalled()}. 211 * <p> 212 * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.7'>1.7</a> 213 */ 214 void untested_spec107_mustNotEmitFurtherSignalsOnceOnErrorHasBeenSignalled() throws Throwable; 215 /** 216 * Currently, this test is skipped because there was no agreement on how to verify its "eventually" requirement. 217 * <p> 218 * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.8'>1.8</a> 219 */ 220 void untested_spec108_possiblyCanceledSubscriptionShouldNotReceiveOnErrorOrOnCompleteSignals() throws Throwable; 221 /** 222 * Asks for an empty {@code Publisher} and verifies if {@code onSubscribe} signal was emitted before 223 * any other {@code onNext}, {@code onError} or {@code onComplete} signal. 224 * <p> 225 * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.9'>1.9</a> 226 * <p> 227 * Note that this test doesn't request anything, however, an {@code onNext} is not considered as a failure. 228 * <p> 229 * If this test fails, the following could be checked within the {@code Publisher} implementation: 230 * <ul> 231 * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li> 232 * <li>the {@code Publisher.subscribe(Subscriber)} method has actual implementation,</li> 233 * <li>in the {@code Publisher.subscribe(Subscriber)} method, if there is an upstream {@code Publisher}, 234 * that {@code Publisher} is actually subscribed to,</li> 235 * <li>in the {@code Publisher.subscribe(Subscriber)} method, the {@code Subscriber.onSubscribe} is called 236 * as part of the preparation process (usually before subscribing to other {@code Publisher}s).</li> 237 * </ul> 238 */ 239 void required_spec109_mustIssueOnSubscribeForNonNullSubscriber() throws Throwable; 240 /** 241 * Currently, this test is skipped because there is no common agreement on what is to be considered a fatal exception and 242 * besides, {@code Publisher.subscribe} is only allowed throw a {@code NullPointerException} and any other 243 * exception would require looking into or hooking into the implementation of the {@code Publisher}. 244 * <p> 245 * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.9'>1.9</a> 246 */ 247 void untested_spec109_subscribeShouldNotThrowNonFatalThrowable() throws Throwable; 248 /** 249 * Asks for an empty {@code Publisher} and calls {@code subscribe} on it with {@code null} that should result in 250 * a {@code NullPointerException} to be thrown. 251 * <p> 252 * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.9'>1.9</a> 253 * <p> 254 * If this test fails, check if the {@code subscribe()} implementation has an explicit null check (or a method dereference 255 * on the {@code Subscriber}), especially if the incoming {@code Subscriber} is wrapped or stored to be used later. 256 */ 257 void required_spec109_subscribeThrowNPEOnNullSubscriber() throws Throwable; 258 /** 259 * Asks for an error {@code Publisher} that should call {@code onSubscribe} exactly once 260 * followed by a single call to {@code onError()} without receiving any requests. 261 * <p> 262 * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.9'>1.9</a> 263 * <p> 264 * The test is not executed if {@code PublisherVerification.createErrorPublisher()} returns null. 265 * <p> 266 * The difference between this test and {@link #optional_spec104_mustSignalOnErrorWhenFails()} is that there is 267 * no explicit verification if exceptions were thrown in addition to the regular {@code onSubscribe+onError} signal pair. 268 * <p> 269 * If this test fails, the following could be checked within the error {@code Publisher} implementation: 270 * <ul> 271 * <li>the {@code Publisher.subscribe(Subscriber)} method has actual implementation,</li> 272 * <li>in the {@code Publisher.subscribe(Subscriber)} method, if there is an upstream {@code Publisher}, 273 * that {@code Publisher} is actually subscribed to,</li> 274 * <li>if the {@code Publisher} implementation is able to emit an {@code onError} without requests,</li> 275 * <li>if the {@code Publisher} is non-empty as this test expects a {@code Publisher} without items.</li> 276 * </ul> 277 */ 278 void required_spec109_mayRejectCallsToSubscribeIfPublisherIsUnableOrUnwillingToServeThemRejectionMustTriggerOnErrorAfterOnSubscribe() throws Throwable; 279 /** 280 * Currently, this test is skipped because enforcing rule ยง1.10 requires unlimited retention and reference-equal checks on 281 * all incoming {@code Subscriber} which is generally infeasible, plus reusing the same {@code Subscriber} instance is 282 * better detected (or ignored) inside {@code Subscriber.onSubscribe} when the method is called multiple times. 283 * <p> 284 * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.10'>1.10</a> 285 */ 286 void untested_spec110_rejectASubscriptionRequestIfTheSameSubscriberSubscribesTwice() throws Throwable; 287 /** 288 * Asks for a single-element {@code Publisher} and subscribes to it twice, without consuming with either 289 * {@code Subscriber} instance 290 * (i.e., no requests are issued). 291 * <p> 292 * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.11'>1.11</a> 293 * <p> 294 * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 1. 295 * <p> 296 * Note that this test ignores what signals the {@code Publisher} emits. Any exception thrown through non-regular 297 * means will indicate a skipped test. 298 */ 299 void optional_spec111_maySupportMultiSubscribe() throws Throwable; 300 /** 301 * Asks for a single-element {@code Publisher} and subscribes to it twice. 302 * Each {@code Subscriber} requests for 1 element and checks if onNext or onComplete signals was received. 303 * <p> 304 * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.11'>1.11</a>, 305 * and depends on valid implementation of rule <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.5'>1.5</a> 306 * in order to verify this. 307 * <p> 308 * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 1. 309 * <p> 310 * Any exception thrown through non-regular means will indicate a skipped test. 311 */ 312 void optional_spec111_registeredSubscribersMustReceiveOnNextOrOnCompleteSignals() throws Throwable; 313 /** 314 * Asks for a short {@code Publisher} (length 5), subscribes 3 {@code Subscriber}s to it, requests with different 315 * patterns and checks if all 3 received the same events in the same order. 316 * <p> 317 * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.11'>1.11</a> 318 * <p> 319 * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 5. 320 * <p> 321 * The request pattern for the first {@code Subscriber} is (1, 1, 2, 1); for the second is (2, 3) and for the third is (3, 1, 1). 322 * <p> 323 * Note that this test requires a {@code Publisher} that always emits the same signals to any {@code Subscriber}, regardless of 324 * when they subscribe and how they request elements. I.e., a "live" {@code Publisher} emitting the current time would not pass this test. 325 * <p> 326 * Note that this test is optional and may appear skipped even if the behavior should be actually supported by the {@code Publisher}, 327 * see the skip message for an indication of this. 328 * <p> 329 * If this test fails, the following could be checked within the {@code Publisher} implementation: 330 * <ul> 331 * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li> 332 * <li>make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,</li> 333 * <li>if the {@code Publisher} implementation considers the cumulative request amount it receives,</li> 334 * <li>if the {@code Publisher} doesn't lose any {@code request()} signal and the state transition from idle -> emitting or emitting -> keep emitting works properly.</li> 335 * </ul> 336 */ 337 void optional_spec111_multicast_mustProduceTheSameElementsInTheSameSequenceToAllOfItsSubscribersWhenRequestingOneByOne() throws Throwable; 338 /** 339 * Asks for a short {@code Publisher} (length 3), subscribes 3 {@code Subscriber}s to it, requests more than the length items 340 * upfront with each and verifies they all received the same items in the same order (but does not verify they all complete). 341 * <p> 342 * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.11'>1.11</a> 343 * <p> 344 * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 3. 345 * <p> 346 * Note that this test requires a {@code Publisher} that always emits the same signals to any {@code Subscriber}, regardless of 347 * when they subscribe and how they request elements. I.e., a "live" {@code Publisher} emitting the current time would not pass this test. 348 * <p> 349 * Note that this test is optional and may appear skipped even if the behavior should be actually supported by the {@code Publisher}, 350 * see the skip message for an indication of this. 351 * <p> 352 * If this test fails, the following could be checked within the {@code Publisher} implementation: 353 * <ul> 354 * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li> 355 * <li>make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,</li> 356 * <li>if the {@code Publisher} implementation considers the cumulative request amount it receives,</li> 357 * <li>if the {@code Publisher} doesn't lose any {@code request()} signal and the state transition from idle -> emitting or emitting -> keep emitting works properly.</li> 358 * </ul> 359 */ 360 void optional_spec111_multicast_mustProduceTheSameElementsInTheSameSequenceToAllOfItsSubscribersWhenRequestingManyUpfront() throws Throwable; 361 /** 362 * Asks for a short {@code Publisher} (length 3), subscribes 3 {@code Subscriber}s to it, requests more than the length items 363 * upfront with each and verifies they all received the same items in the same order followed by an {@code onComplete} signal. 364 * <p> 365 * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#1.11'>1.11</a> 366 * <p> 367 * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 3. 368 * <p> 369 * Note that this test requires a {@code Publisher} that always emits the same signals to any {@code Subscriber}, regardless of 370 * when they subscribe and how they request elements. I.e., a "live" {@code Publisher} emitting the current time would not pass this test. 371 * <p> 372 * Note that this test is optional and may appear skipped even if the behavior should be actually supported by the {@code Publisher}, 373 * see the skip message for an indication of this. 374 * <p> 375 * If this test fails, the following could be checked within the {@code Publisher} implementation: 376 * <ul> 377 * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li> 378 * <li>make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,</li> 379 * <li>if the {@code Publisher} implementation considers the cumulative request amount it receives,</li> 380 * <li>if the {@code Publisher} doesn't lose any {@code request()} signal and the state transition from idle -> emitting or emitting -> keep emitting works properly.</li> 381 * </ul> 382 */ 383 void optional_spec111_multicast_mustProduceTheSameElementsInTheSameSequenceToAllOfItsSubscribersWhenRequestingManyUpfrontAndCompleteAsExpected() throws Throwable; 384 /** 385 * Asks for a short {@code Publisher} (length 6), requests several times from within {@code onSubscribe} and then requests 386 * one-by-one from {@code onNext}. 387 * <p> 388 * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#3.2'>3.2</a> 389 * <p> 390 * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 6. 391 * <p> 392 * The request pattern is 3 x 1 from within {@code onSubscribe} and one from within each {@code onNext} invocation. 393 * <p> 394 * The test consumes the {@code Publisher} but otherwise doesn't verify the {@code Publisher} completes (however, it checks 395 * for errors). 396 * <p> 397 * If this test fails, the following could be checked within the {@code Publisher} implementation: 398 * <ul> 399 * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li> 400 * <li>make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,</li> 401 * <li>if the {@code Publisher} implementation considers the cumulative request amount it receives,</li> 402 * <li>if the {@code Publisher} doesn't lose any {@code request()} signal and the state transition from idle -> emitting or emitting -> keep emitting works properly.</li> 403 * </ul> 404 */ 405 void required_spec302_mustAllowSynchronousRequestCallsFromOnNextAndOnSubscribe() throws Throwable; 406 /** 407 * Asks for a {@code Publisher} with length equal to the value returned by {@link #required_validate_boundedDepthOfOnNextAndRequestRecursion()} plus 1, 408 * calls {@code request(1)} externally and then from within {@code onNext} and checks if the stack depth did not increase beyond the 409 * amount permitted by {@link #required_validate_boundedDepthOfOnNextAndRequestRecursion()}. 410 * <p> 411 * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#3.3'>3.3</a> 412 * <p> 413 * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 414 * {@link #required_validate_boundedDepthOfOnNextAndRequestRecursion()} plus 1. 415 * <p> 416 * If this test fails, the following could be checked within the {@code Publisher} implementation: 417 * <ul> 418 * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li> 419 * <li>make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,</li> 420 * <li>the implementation doesn't allow unbounded recursion when {@code request()} is called from within {@code onNext}, i.e., the lack of 421 * reentrant-safe state machine around the request amount (such as a for loop with a bound on the parameter {@code n} that calls {@code onNext}). 422 * </ul> 423 */ 424 void required_spec303_mustNotAllowUnboundedRecursion() throws Throwable; 425 /** 426 * Currently, this test is skipped because a {@code request} could enter into a synchronous computation via {@code onNext} 427 * legally and otherwise there is no common agreement how to detect such heavy computation reliably. 428 * <p> 429 * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#3.4'>3.4</a> 430 */ 431 void untested_spec304_requestShouldNotPerformHeavyComputations() throws Exception; 432 /** 433 * Currently, this test is skipped because there is no reliable agreed upon way to detect a heavy computation. 434 * <p> 435 * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#3.5'>3.5</a> 436 */ 437 void untested_spec305_cancelMustNotSynchronouslyPerformHeavyComputation() throws Exception; 438 /** 439 * Asks for a short {@code Publisher} (length 3) and verifies that cancelling without requesting anything, then requesting 440 * items should result in no signals to be emitted. 441 * <p> 442 * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#3.6'>3.6</a> 443 * <p> 444 * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 3. 445 * <p> 446 * The post-cancellation request pattern is (1, 1, 1). 447 * <p> 448 * If this test fails, the following could be checked within the {@code Publisher} implementation: 449 * <ul> 450 * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li> 451 * <li>make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,</li> 452 * <li>the cancellation indicator flag is properly persisted (may require volatile) and checked as part of the signal emission process.</li> 453 * </ul> 454 */ 455 void required_spec306_afterSubscriptionIsCancelledRequestMustBeNops() throws Throwable; 456 /** 457 * Asks for a single-element {@code Publisher} and verifies that without requesting anything, cancelling the sequence 458 * multiple times should result in no signals to be emitted and should result in an thrown exception. 459 * <p> 460 * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#3.7'>3.7</a> 461 * <p> 462 * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 1. 463 * <p> 464 * If this test fails, the following could be checked within the {@code Publisher} implementation: 465 * <ul> 466 * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li> 467 * <li>make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,</li> 468 * <li>the cancellation indicator flag is properly persisted (may require volatile) and checked as part of the signal emission process.</li> 469 * </ul> 470 */ 471 void required_spec307_afterSubscriptionIsCancelledAdditionalCancelationsMustBeNops() throws Throwable; 472 /** 473 * Asks for a short {@code Publisher} (length 10) and issues a {@code request(0)} which should trigger an {@code onError} call 474 * with an {@code IllegalArgumentException}. 475 * <p> 476 * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#3.9'>3.9</a> 477 * <p> 478 * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 10. 479 * <p> 480 * Note that this test expects the {@code IllegalArgumentException} being signalled through {@code onError}, not by 481 * throwing from {@code request()} (which is also forbidden) or signalling the error by any other means (i.e., through the 482 * {@code Thread.currentThread().getUncaughtExceptionHandler()} for example). 483 * <p> 484 * Note also that requesting and emission may happen concurrently and honoring this rule may require extra coordination within 485 * the {@code Publisher}. 486 * <p> 487 * If this test fails, the following could be checked within the {@code Publisher} implementation: 488 * <ul> 489 * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li> 490 * <li>make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,</li> 491 * <li>the {@code Publisher} can emit an {@code onError} in this particular case, even if there was no prior and legal 492 * {@code request} call and even if the {@code Publisher} would like to emit items first before emitting an {@code onError} 493 * in general. 494 * </ul> 495 */ 496 void required_spec309_requestZeroMustSignalIllegalArgumentException() throws Throwable; 497 /** 498 * Asks for a short {@code Publisher} (length 10) and issues a random, negative {@code request()} call which should 499 * trigger an {@code onError} call with an {@code IllegalArgumentException}. 500 * <p> 501 * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#3.9'>3.9</a> 502 * <p> 503 * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 10. 504 * <p> 505 * Note that this test expects the {@code IllegalArgumentException} being signalled through {@code onError}, not by 506 * throwing from {@code request()} (which is also forbidden) or signalling the error by any other means (i.e., through the 507 * {@code Thread.currentThread().getUncaughtExceptionHandler()} for example). 508 * <p> 509 * Note also that requesting and emission may happen concurrently and honoring this rule may require extra coordination within 510 * the {@code Publisher}. 511 * <p> 512 * If this test fails, the following could be checked within the {@code Publisher} implementation: 513 * <ul> 514 * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li> 515 * <li>make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,</li> 516 * <li>the {@code Publisher} can emit an {@code onError} in this particular case, even if there was no prior and legal 517 * {@code request} call and even if the {@code Publisher} would like to emit items first before emitting an {@code onError} 518 * in general. 519 * </ul> 520 */ 521 void required_spec309_requestNegativeNumberMustSignalIllegalArgumentException() throws Throwable; 522 /** 523 * Asks for a short {@code Publisher} (length 10) and issues a random, negative {@code request()} call which should 524 * trigger an {@code onError} call with an {@code IllegalArgumentException}. 525 * <p> 526 * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#3.9'>3.9</a> 527 * <p> 528 * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 10. 529 * <p> 530 * Note that this test expects the {@code IllegalArgumentException} being signalled through {@code onError}, not by 531 * throwing from {@code request()} (which is also forbidden) or signalling the error by any other means (i.e., through the 532 * {@code Thread.currentThread().getUncaughtExceptionHandler()} for example). 533 * <p> 534 * Note also that requesting and emission may happen concurrently and honoring this rule may require extra coordination within 535 * the {@code Publisher}. 536 * <p> 537 * If this test fails, the following could be checked within the {@code Publisher} implementation: 538 * <ul> 539 * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li> 540 * <li>make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,</li> 541 * <li>the {@code Publisher} can emit an {@code onError} in this particular case, even if there was no prior and legal 542 * {@code request} call and even if the {@code Publisher} would like to emit items first before emitting an {@code onError} 543 * in general. 544 * </ul> 545 */ 546 void optional_spec309_requestNegativeNumberMaySignalIllegalArgumentExceptionWithSpecificMessage() throws Throwable; 547 /** 548 * Asks for a short {@code Publisher} (length 20), requests some items (less than the length), consumes one item then 549 * cancels the sequence and verifies the publisher emitted at most the requested amount and stopped emitting (or terminated). 550 * <p> 551 * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#3.12'>3.12</a> 552 * <p> 553 * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 20. 554 * <p> 555 * If this test fails, the following could be checked within the {@code Publisher} implementation: 556 * <ul> 557 * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li> 558 * <li>make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,</li> 559 * <li>the cancellation indicator flag is properly persisted (may require volatile) and checked as part of the signal emission process.</li> 560 * </ul> 561 */ 562 void required_spec312_cancelMustMakeThePublisherToEventuallyStopSignaling() throws Throwable; 563 /** 564 * Asks for a short {@code Publisher} (length 3) requests and consumes one element from it, cancels the {@code Subscription} 565 * , calls {@code System.gc()} and then checks if all references to the test {@code Subscriber} has been dropped (by checking 566 * the {@code WeakReference} has been emptied). 567 * <p> 568 * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#3.13'>3.13</a> 569 * <p> 570 * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 3. 571 * <p> 572 * If this test fails, the following could be checked within the {@code Publisher} implementation: 573 * <ul> 574 * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li> 575 * <li>make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,</li> 576 * <li>the cancellation indicator flag is properly persisted (may require volatile) and checked as part of the signal emission process.</li> 577 * <li>the {@code Publisher} stores the {@code Subscriber} reference somewhere which is then not cleaned up when the {@code Subscriber} is cancelled. 578 * Note that this may happen on many code paths in a {@code Publisher}, for example in an emission loop that terminates because of the 579 * {@code cancel} signal or because reaching a terminal state. Note also that eagerly nulling {@code Subscriber} references may not be necessary 580 * for this test to pass in case there is a self-contained chain of them (i.e., {@code Publisher.subscribe()} creates a chain of fresh 581 * {@code Subscriber} instances where each of them only references their downstream {@code Subscriber} thus the chain can get GC'd 582 * when the reference to the final {@code Subscriber} is dropped). 583 * </ul> 584 */ 585 void required_spec313_cancelMustMakeThePublisherEventuallyDropAllReferencesToTheSubscriber() throws Throwable; 586 /** 587 * Asks for a short {@code Publisher} (length 3) and requests {@code Long.MAX_VALUE} from it, verifying that the 588 * {@code Publisher} emits all of its items and completes normally 589 * and does not keep spinning attempting to fulfill the {@code Long.MAX_VALUE} demand by some means. 590 * <p> 591 * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#3.17'>3.17</a> 592 * <p> 593 * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 3. 594 * <p> 595 * If this test fails, the following could be checked within the {@code Publisher} implementation: 596 * <ul> 597 * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li> 598 * <li>make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,</li> 599 * <li>if the {@code Publisher} implementation considers the cumulative request amount it receives,</li> 600 * <li>if the {@code Publisher} doesn't lose any {@code request()} signal and the state transition from idle -> emitting or emitting -> keep emitting works properly.</li> 601 * </ul> 602 */ 603 void required_spec317_mustSupportAPendingElementCountUpToLongMaxValue() throws Throwable; 604 /** 605 * Asks for a short {@code Publisher} (length 3) and requests {@code Long.MAX_VALUE} from it in total (split across 606 * two {@code Long.MAX_VALUE / 2} and one {@code request(1)}), verifying that the 607 * {@code Publisher} emits all of its items and completes normally. 608 * <p> 609 * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#3.17'>3.17</a> 610 * <p> 611 * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than 3. 612 * <p> 613 * If this test fails, the following could be checked within the {@code Publisher} implementation: 614 * <ul> 615 * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li> 616 * <li>make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,</li> 617 * <li>if the {@code Publisher} implementation considers the cumulative request amount it receives,</li> 618 * <li>if the {@code Publisher} implements adding individual request amounts together properly (not overflowing into zero or negative pending request amounts) 619 * or not properly deducing the number of emitted items from the pending amount,</li> 620 * <li>if the {@code Publisher} doesn't lose any {@code request()} signal and the state transition from idle -> emitting or emitting -> keep emitting works properly.</li> 621 * </ul> 622 */ 623 void required_spec317_mustSupportACumulativePendingElementCountUpToLongMaxValue() throws Throwable; 624 /** 625 * Asks for a very long {@code Publisher} (up to {@code Integer.MAX_VALUE}), requests {@code Long.MAX_VALUE - 1} after 626 * each received item and expects no failure due to a potential overflow in the pending emission count while consuming 627 * 10 items and cancelling the sequence. 628 * <p> 629 * <b>Verifies rule:</b> <a href='https://github.com/reactive-streams/reactive-streams-jvm#3.17'>3.17</a> 630 * <p> 631 * The test is not executed if {@link org.reactivestreams.tck.PublisherVerification#maxElementsFromPublisher()} is less than {@code Integer.MAX_VALUE}. 632 * <p> 633 * The request pattern is one {@code request(1)} upfront and ten {@code request(Long.MAX_VALUE - 1)} after. 634 * <p> 635 * If this test fails, the following could be checked within the {@code Publisher} implementation: 636 * <ul> 637 * <li>the {@code TestEnvironment} has large enough timeout specified in case the {@code Publisher} has some time-delay behavior,</li> 638 * <li>make sure the {@link #required_createPublisher1MustProduceAStreamOfExactly1Element()} and {@link #required_createPublisher3MustProduceAStreamOfExactly3Elements()} tests pass,</li> 639 * <li>if the {@code Publisher} implementation considers the cumulative request amount it receives,</li> 640 * <li>if the {@code Publisher} implements adding individual request amounts together properly (not overflowing into zero or negative pending request amounts) 641 * or not properly deducing the number of emitted items from the pending amount,</li> 642 * <li>if the {@code Publisher} doesn't lose any {@code request()} signal and the state transition from idle -> emitting or emitting -> keep emitting works properly.</li> 643 * </ul> 644 */ 645 void required_spec317_mustNotSignalOnErrorWhenPendingAboveLongMaxValue() throws Throwable; 646}