@@ -84,7 +84,23 @@ public class ServerCallImplTest {
8484
8585 private static final MethodDescriptor <Long , Long > CLIENT_STREAMING_METHOD =
8686 MethodDescriptor .<Long , Long >newBuilder ()
87- .setType (MethodType .UNARY )
87+ .setType (MethodType .CLIENT_STREAMING )
88+ .setFullMethodName ("service/method" )
89+ .setRequestMarshaller (new LongMarshaller ())
90+ .setResponseMarshaller (new LongMarshaller ())
91+ .build ();
92+
93+ private static final MethodDescriptor <Long , Long > BIDI_STREAMING_METHOD =
94+ MethodDescriptor .<Long , Long >newBuilder ()
95+ .setType (MethodType .BIDI_STREAMING )
96+ .setFullMethodName ("service/method" )
97+ .setRequestMarshaller (new LongMarshaller ())
98+ .setResponseMarshaller (new LongMarshaller ())
99+ .build ();
100+
101+ private static final MethodDescriptor <Long , Long > SERVER_STREAMING_METHOD =
102+ MethodDescriptor .<Long , Long >newBuilder ()
103+ .setType (MethodType .SERVER_STREAMING )
88104 .setFullMethodName ("service/method" )
89105 .setRequestMarshaller (new LongMarshaller ())
90106 .setResponseMarshaller (new LongMarshaller ())
@@ -456,40 +472,97 @@ public void streamListener_onReady_onlyOnce() {
456472 }
457473
458474 @ Test
459- public void streamListener_messageRead () {
475+ public void streamListener_messageRead_unary_delayed () {
460476 ServerStreamListenerImpl <Long > streamListener =
461477 new ServerCallImpl .ServerStreamListenerImpl <>(call , callListener , context );
462478 streamListener .messagesAvailable (new SingleMessageProducer (UNARY_METHOD .streamRequest (1234L )));
463479
480+ // Message should not be delivered yet
481+ verify (callListener , never ()).onMessage (any (Long .class ));
482+
483+ streamListener .halfClosed ();
484+
485+ // Now it should be delivered
464486 verify (callListener ).onMessage (1234L );
487+ verify (callListener ).onHalfClose ();
465488 }
466489
467490 @ Test
468- public void streamListener_messageRead_onlyOnce () {
491+ public void streamListener_messageRead_serverStreaming_delayed () {
492+ call = new ServerCallImpl <>(stream , SERVER_STREAMING_METHOD , requestHeaders , context ,
493+ DecompressorRegistry .getDefaultInstance (), CompressorRegistry .getDefaultInstance (),
494+ serverCallTracer , PerfMark .createTag ());
495+ ServerStreamListenerImpl <Long > streamListener =
496+ new ServerCallImpl .ServerStreamListenerImpl <>(call , callListener , context );
497+ streamListener .messagesAvailable (new SingleMessageProducer (SERVER_STREAMING_METHOD .streamRequest (1234L )));
498+
499+ // Message should not be delivered yet
500+ verify (callListener , never ()).onMessage (any (Long .class ));
501+
502+ streamListener .halfClosed ();
503+
504+ // Now it should be delivered
505+ verify (callListener ).onMessage (1234L );
506+ verify (callListener ).onHalfClose ();
507+ }
508+
509+ @ Test
510+ public void streamListener_messageRead_bidi_notDelayed () {
511+ call = new ServerCallImpl <>(stream , BIDI_STREAMING_METHOD , requestHeaders , context ,
512+ DecompressorRegistry .getDefaultInstance (), CompressorRegistry .getDefaultInstance (),
513+ serverCallTracer , PerfMark .createTag ());
514+ ServerStreamListenerImpl <Long > streamListener =
515+ new ServerCallImpl .ServerStreamListenerImpl <>(call , callListener , context );
516+ streamListener .messagesAvailable (new SingleMessageProducer (BIDI_STREAMING_METHOD .streamRequest (1234L )));
517+
518+ // Message should be delivered immediately
519+ verify (callListener ).onMessage (1234L );
520+ verify (callListener , never ()).onHalfClose ();
521+ }
522+
523+ @ Test
524+ public void streamListener_messageRead_unary_tooManyRequests () {
469525 ServerStreamListenerImpl <Long > streamListener =
470526 new ServerCallImpl .ServerStreamListenerImpl <>(call , callListener , context );
471527 streamListener .messagesAvailable (new SingleMessageProducer (UNARY_METHOD .streamRequest (1234L )));
472- // canceling the call should short circuit future halfClosed() calls.
473- streamListener .closed (Status .CANCELLED );
474528
529+ // Sending second message should fail
530+ streamListener .messagesAvailable (new SingleMessageProducer (UNARY_METHOD .streamRequest (5678L )));
531+
532+ verify (stream ).close (any (Status .class ), any (Metadata .class ));
533+ verify (callListener , never ()).onMessage (any (Long .class ));
534+ }
535+
536+ @ Test
537+ public void streamListener_messageRead_onlyOnce_unary () {
538+ ServerStreamListenerImpl <Long > streamListener =
539+ new ServerCallImpl .ServerStreamListenerImpl <>(call , callListener , context );
475540 streamListener .messagesAvailable (new SingleMessageProducer (UNARY_METHOD .streamRequest (1234L )));
541+
542+ // canceling the call should clean up and prevent delivery
543+ streamListener .closed (Status .CANCELLED );
476544
477- verify (callListener ).onMessage (1234L );
545+ streamListener .halfClosed ();
546+
547+ verify (callListener , never ()).onMessage (any (Long .class ));
478548 }
479549
480550 @ Test
481- public void streamListener_unexpectedRuntimeException () {
551+ public void streamListener_unexpectedRuntimeException_unary () {
482552 ServerStreamListenerImpl <Long > streamListener =
483553 new ServerCallImpl .ServerStreamListenerImpl <>(call , callListener , context );
484554 doThrow (new RuntimeException ("unexpected exception" ))
485555 .when (callListener )
486556 .onMessage (any (Long .class ));
487557
488- InputStream inputStream = UNARY_METHOD .streamRequest (1234L );
558+ streamListener .messagesAvailable (new SingleMessageProducer (UNARY_METHOD .streamRequest (1234L )));
559+
560+ // Exception should not be thrown yet because deserialization/delivery is delayed
561+ verify (callListener , never ()).onMessage (any (Long .class ));
489562
490- SingleMessageProducer producer = new SingleMessageProducer ( inputStream );
563+ // It should be thrown during halfClosed
491564 RuntimeException e = assertThrows (RuntimeException .class ,
492- () -> streamListener .messagesAvailable ( producer ));
565+ () -> streamListener .halfClosed ( ));
493566 assertThat (e ).hasMessageThat ().isEqualTo ("unexpected exception" );
494567 }
495568
0 commit comments