22
33import static java .util .Objects .requireNonNull ;
44
5+ import java .io .IOException ;
56import java .util .ArrayList ;
67import java .util .Collections ;
78import java .util .List ;
@@ -57,7 +58,7 @@ public class BatchContextTest {
5758 private static final int MAX_SIZE_BYTES = 2 * 1024 ;
5859 private static final int BATCH_SIZE = 10 ;
5960 private static final int QUEUE_SIZE = 1 ;
60- private static final int MAX_RECONNECT_RETRIES = 2 ;
61+ private static final int MAX_RECONNECT_RETRIES = 1 ;
6162
6263 private CompletableStreamFactory factory ;
6364 private MockServer server ;
@@ -390,6 +391,41 @@ public void test_closeAfterStreamHangup() throws Exception {
390391 server .hangup ();
391392 }
392393
394+ @ Test
395+ public void test_maxReconnectRetries () throws Exception {
396+ server .expectMessage (WeaviateProtoBatch .BatchStreamRequest .MessageCase .START );
397+
398+ // Drop the connection several times until the client exhausts its reconnect attempts.
399+ int retries = 0 ;
400+ while (retries < MAX_RECONNECT_RETRIES ) {
401+ server .hangup ();
402+ server .expectMessage (WeaviateProtoBatch .BatchStreamRequest .MessageCase .START );
403+ retries ++;
404+ }
405+
406+ Future <?> fatalHangup = server .hangup ();
407+ try {
408+ fatalHangup .get ();
409+ } catch (InterruptedException ignored ) {
410+ // BatchContext#shutdownNow might interrupt the parent thread.
411+ }
412+
413+ Assertions .assertThatThrownBy (() -> context .close ())
414+ .isInstanceOf (IOException .class )
415+ .hasMessageContaining ("Server unavailable" );
416+
417+ // Cleanup: unset the context and factory to prevent test teardown code
418+ // from tripping on it while trying to close the context.
419+ context = null ;
420+
421+ try {
422+ factory .close ();
423+ } catch (InterruptedException ignored ) {
424+ } finally {
425+ factory = null ;
426+ }
427+ }
428+
393429 @ Test (expected = IllegalStateException .class )
394430 public void test_add_closed () throws Exception {
395431 server .expectMessage (WeaviateProtoBatch .BatchStreamRequest .MessageCase .START );
@@ -465,12 +501,7 @@ public MockServer(
465501 BlockingQueue <WeaviateProtoBatch .BatchStreamRequest > requestQueue ) {
466502 this .eventStream = requireNonNull (eventStream , "eventStream is null" );
467503 this .requestQueue = requireNonNull (requestQueue , "requestQueue is null" );
468- this .eventExecutor = eventExecutor ;
469- }
470-
471- /** Wait until the next request arrives. */
472- WeaviateProtoBatch .BatchStreamRequest recv () throws InterruptedException {
473- return requestQueue .take ();
504+ this .eventExecutor = requireNonNull (eventExecutor , "eventExecutor is null" );
474505 }
475506
476507 Future <?> emitEvent (Event event ) {
@@ -492,8 +523,8 @@ Future<?> emitEvent(Event event) {
492523 }
493524
494525 /** Terminate the server-side of the stream abruptly. */
495- void hangup () {
496- emitEvent (new Event .StreamHangup (new RuntimeException ("whaam!" )));
526+ Future <?> hangup () {
527+ return emitEvent (new Event .StreamHangup (new RuntimeException ("whaam!" )));
497528 }
498529
499530 /**
0 commit comments