@Test
    void abortedStreamCallOnErrorAfterCloseIsCalled() throws InterruptedException {
        final StreamWriter<HttpData> stream = new DefaultStreamMessage<>();
        final ByteBuf buf = PooledByteBufAllocator.DEFAULT.buffer().writeByte(0);
        stream.write(HttpData.wrap(buf).withEndOfStream());
        stream.close();

        final AtomicReference<Throwable> throwableCaptor = new AtomicReference<>();
        stream.subscribe(new Subscriber<HttpData>() {
            @Override
            public void onSubscribe(Subscription s) {}

            @Override
            public void onNext(HttpData o) {}

            @Override
            public void onError(Throwable t) {
                throwableCaptor.set(t);
            }

            @Override
            public void onComplete() {
                fail();
            }
        }, ImmediateEventExecutor.INSTANCE);

        stream.abort();
        assertThat(throwableCaptor.get()).isInstanceOf(AbortedStreamException.class);
        assertThat(buf.refCnt()).isZero();
    }
Makes sure {@link Subscriber#onComplete()} is always invoked after
{@link Subscriber#onSubscribe(Subscription)} even if
{@link StreamMessage#subscribe(Subscriber, EventExecutor, SubscriptionOption...)}
is called from non-{@link EventLoop}.
core/src/test/java/com/linecorp/armeria/common/stream/DefaultStreamMessageTest.java