Skip to content

Commit bd70b9b

Browse files
committed
=tck general tck/readme.md cleanup so it matches current code / spec
Resolves reactive-streams#99 Depends on reactive-streams#241
1 parent b33420a commit bd70b9b

File tree

1 file changed

+53
-17
lines changed

1 file changed

+53
-17
lines changed

tck/README.md

+53-17
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ not possible (or viable) to construct automated tests, thus the TCK does not cla
1313
The TCK is split up into 4 files JUnit 4 test classes which should be extended by implementers, providing their `Publisher` / `Subscriber` implementations for the test harness to validate them. The tests are split in the following way:
1414

1515
* `PublisherVerification`
16-
* `SubscriberBlackboxVerification`
1716
* `SubscriberWhiteboxVerification`
17+
* `SubscriberBlackboxVerification`
1818
* `IdentityProcessorVerification`
1919

2020
The next sections include examples on how these can be used and describe the various configuration options.
@@ -38,8 +38,9 @@ Since the TCK is aimed at Reactive Stream implementers, looking into the sources
3838
and should help during a libraries implementation cycle.
3939

4040
In order to make mapping between test cases and Specification rules easier, each test case covering a specific
41-
Specification rule abides the following naming convention: `spec###_DESC` where:
41+
Specification rule abides the following naming convention: `TYPE_spec###_DESC` where:
4242

43+
* `TYPE` is one of: `required`, `optional`, `stochastic` or `untested` which describe if this test is covering a Rule that MUST or SHOULD be implemented. The specific words are explained in detail below.
4344
* `###` is the Rule number (`1.xx` Rules are about Publishers, `2.xx` Rules are about Subscribers etc.)
4445
* `DESC` is a short explanation of what exactly is being tested in this test case, as sometimes one Rule may have multiple test cases in order to cover the entire Rule.
4546

@@ -66,7 +67,7 @@ Explanations:
6667
@Test public void optional_spec104_mustSignalOnErrorWhenFails() throws Throwable
6768
```
6869

69-
... means that this test case is optional, it covers a *MAY* or *SHOULD* Rule of the Specification. This prefix is also used if more configuration is needed in order to run it, e.g. `@Additional(implement = "createErrorStatePublisher") @Test` signals the implementer that in order to include this test case in his test runs, (s)he must implement the `Publisher<T> createErrorStatePublisher()` method.
70+
... means that this test case is optional, it covers a *MAY* or *SHOULD* Rule of the Specification. This prefix is also used if more configuration is needed in order to run it, e.g. `@Additional(implement = "createFailedPublisher") @Test` signals the implementer that in order to include this test case in his test runs, (s)he must implement the `Publisher<T> createFailedPublisher()` method.
7071

7172
```java
7273
@Test public void stochastic_spec103_mustSignalOnMethodsSequentially() throws Throwable
@@ -142,7 +143,7 @@ public class RangePublisherTest extends PublisherVerification<Integer> {
142143
}
143144

144145
@Override
145-
public Publisher<Integer> createErrorStatePublisher() {
146+
public Publisher<Integer> createFailedPublisher() {
146147
return new Publisher<Integer>() {
147148
@Override
148149
public void subscribe(Subscriber<Integer> s) {
@@ -375,7 +376,7 @@ public class MySubscriberTest extends BlackboxSubscriberVerification<Integer> {
375376
public static final long DEFAULT_TIMEOUT_MILLIS = 300L;
376377

377378
public RangePublisherTest() {
378-
super(new MySubscriberTest(DEFAULT_TIMEOUT_MILLIS));
379+
super(new TestEnvironment(DEFAULT_TIMEOUT_MILLIS));
379380
}
380381

381382
// ...
@@ -427,12 +428,14 @@ public class MyIdentityProcessorVerificationTest extends IdentityProcessorVerifi
427428
// ENABLE ADDITIONAL TESTS
428429

429430
@Override
430-
public Publisher<Integer> createErrorStatePublisher() {
431-
// return error state Publisher instead of null to run additional tests
431+
public Publisher<Integer> createFailedPublisher() {
432+
// return Publisher that just signals onError instead of null to run additional tests
433+
// see this methods JavaDocs for more details on how the returned Publisher should work.
432434
return null;
433435
}
434436

435437
// OPTIONAL CONFIGURATION OVERRIDES
438+
// override these only if you understand why you'd need to do so for your impl.
436439

437440
@Override
438441
public long maxElementsFromPublisher() {
@@ -456,32 +459,65 @@ Since you inherit these tests instead of defining them yourself it's not possibl
456459
to skip tests inherited from the TCK's base classes:
457460

458461
```java
459-
package com.example.streams;
462+
package com.example;
460463

464+
import org.reactivestreams.Processor;
465+
import org.reactivestreams.Publisher;
466+
import org.reactivestreams.Subscriber;
467+
import org.reactivestreams.Subscription;
461468
import org.reactivestreams.tck.IdentityProcessorVerification;
469+
import org.reactivestreams.tck.TestEnvironment;
470+
import org.testng.annotations.AfterClass;
471+
import org.testng.annotations.BeforeClass;
472+
473+
import java.util.concurrent.ExecutorService;
474+
import java.util.concurrent.Executors;
475+
476+
public class MyIdentityProcessorTest extends IdentityProcessorVerification<Integer> {
477+
478+
private ExecutorService e;
462479

463-
public class SkippingIdentityProcessorTest extends IdentityProcessorVerification<Integer> {
480+
@BeforeClass
481+
public void before() { e = Executors.newFixedThreadPool(4); }
482+
483+
@AfterClass
484+
public void after() { if (e != null) e.shutdown(); }
464485

465486
public SkippingIdentityProcessorTest() {
466-
super(new TestEnvironment(500, true), 1000);
487+
super(new TestEnvironment());
488+
}
489+
490+
@Override
491+
public ExecutorService publisherExecutorService() {
492+
return e;
493+
}
494+
495+
@Override
496+
public Integer createElement(int element) {
497+
return element;
467498
}
468499

469500
@Override
470501
public Processor<Integer, Integer> createIdentityProcessor(int bufferSize) {
471-
return /* ... */;
502+
return new MyProcessor<Integer, Integer>(); // return your implementation
472503
}
473504

474-
@Override // override the test method, and provide a reason on why you're doing so in the notVerified() message
475-
public void spec999_mustDoVeryCrazyThings() throws Throwable {
476-
notVerified("Unable to implement test because ...");
505+
@Override
506+
public Publisher<Integer> createFailedPublisher() {
507+
return null; // skip error publisher tests
477508
}
478509

479510
}
480511
```
481512

482-
## Upgrade story
513+
## Upgrading the TCK to newer versions
514+
While we do not expect the Reactive Streams specification to change in the forseeable future,
515+
it may happen that some semantics may need changing in the future. In this case you should expect test
516+
methods being phased out in terms of deprecation or removal, new tests may also be added over time.
483517

484-
**TODO** - What is our story about updating the TCK? How do we make sure that implementations don't accidentally miss some change in the spec, if the TCK is unable to fail verify the new behavior? Comments are very welcome, discussion about this is under-way in [Issue #99 – TCK Upgrade Story](https://github.com/reactive-streams/reactive-streams/issues/99).
518+
In general this should not be of much concern to you, unless you override test methods in your test suite.
519+
We ask implementers who find the need of overriding provided test methods to reach out via opening tickets
520+
on the `reactive-streams/reactive-streams-jvm` project, so we can discuss the use case and, most likely, improve the TCK.
485521

486522
## Using the TCK from other languages
487523

@@ -504,7 +540,7 @@ class IterablePublisherTest(env: TestEnvironment, publisherShutdownTimeout: Long
504540
def createPublisher(elements: Long): Publisher[Int] = ???
505541

506542
// example error state publisher implementation
507-
override def createErrorStatePublisher(): Publisher[Int] =
543+
override def createFailedPublisher(): Publisher[Int] =
508544
new Publisher[Int] {
509545
override def subscribe(s: Subscriber[Int]): Unit = {
510546
s.onError(new Exception("Unable to serve subscribers right now!"))

0 commit comments

Comments
 (0)