AbstractStream implements Stream { @VisibleForTesting Phase verifyNextPhase(Phase currentPhase, Phase nextPhase) { if (nextPhase.ordinal() < currentPhase.ordinal()) { throw new IllegalStateException( String.format("Cannot transition phase from %s to %s", currentPhase, nextPhase)); } return nextPhase; } AbstractStream(WritableBufferAllocator bufferAllocator, int maxMessageSize); @VisibleForTesting  AbstractStream(MessageFramer framer, MessageDeframer deframer); @Nullable abstract IdT id(); int getOnReadyThreshold(); @Override void writeMessage(InputStream message); @Override final void setMessageCompression(boolean enable); @Override final void flush(); @Override boolean isReady(); void dispose(); @Override final void setCompressor(Compressor compressor); @Override final void setDecompressor(Decompressor decompressor); boolean canReceive(); boolean canSend(); @VisibleForTesting boolean isClosed(); @Override String toString(); static final int DEFAULT_ONREADY_THRESHOLD; }
@Test public void validPhaseTransitions() { AbstractStream<Object> stream = new AbstractStreamBase<Object>(null); Multimap<Phase, Phase> validTransitions = ImmutableMultimap.<Phase, Phase>builder() .put(Phase.HEADERS, Phase.HEADERS) .put(Phase.HEADERS, Phase.MESSAGE) .put(Phase.HEADERS, Phase.STATUS) .put(Phase.MESSAGE, Phase.MESSAGE) .put(Phase.MESSAGE, Phase.STATUS) .put(Phase.STATUS, Phase.STATUS) .build(); for (Phase startPhase : Phase.values()) { for (Phase endPhase : Phase.values()) { if (validTransitions.containsEntry(startPhase, endPhase)) { stream.verifyNextPhase(startPhase, endPhase); } else { try { stream.verifyNextPhase(startPhase, endPhase); fail(); } catch (IllegalStateException expected) { } } } } }