@@ -330,6 +330,75 @@ public void readObject(
330330 }
331331 }
332332
333+ @ Test
334+ public void logsWarning_whenReceivingMoreBytesThanRequested ()
335+ throws IOException , ExecutionException , InterruptedException , TimeoutException {
336+ ReadObjectRequest reqWithLimit =
337+ ReadObjectRequest .newBuilder ()
338+ .setObject (objectName )
339+ .setReadOffset (0 )
340+ .setReadLimit (10 )
341+ .build ();
342+
343+ StorageGrpc .StorageImplBase fakeStorage =
344+ new StorageGrpc .StorageImplBase () {
345+ @ Override
346+ public void readObject (
347+ ReadObjectRequest request , StreamObserver <ReadObjectResponse > responseObserver ) {
348+ responseObserver .onNext (resp1 ); // sends 10 bytes
349+ responseObserver .onNext (resp2 ); // sends another 10 bytes (total 20 > limit 10)
350+ responseObserver .onCompleted ();
351+ }
352+ };
353+
354+ java .util .logging .Logger logger =
355+ java .util .logging .Logger .getLogger (GapicUnbufferedReadableByteChannel .class .getName ());
356+ java .util .List <java .util .logging .LogRecord > records = new java .util .ArrayList <>();
357+ java .util .logging .Handler handler =
358+ new java .util .logging .Handler () {
359+ @ Override
360+ public void publish (java .util .logging .LogRecord record ) {
361+ records .add (record );
362+ }
363+
364+ @ Override
365+ public void flush () {}
366+
367+ @ Override
368+ public void close () throws SecurityException {}
369+ };
370+ logger .addHandler (handler );
371+
372+ try (FakeServer server = FakeServer .of (fakeStorage );
373+ StorageClient storageClient = StorageClient .create (server .storageSettings ())) {
374+ Retrier retrier = TestUtils .retrierFromStorageOptions (server .getGrpcStorageOptions ());
375+
376+ UnbufferedReadableByteChannelSession <Object > session =
377+ new UnbufferedReadSession <>(
378+ ApiFutures .immediateFuture (reqWithLimit ),
379+ (start , resultFuture ) ->
380+ new GapicUnbufferedReadableByteChannel (
381+ resultFuture ,
382+ new ZeroCopyServerStreamingCallable <>(
383+ storageClient .readObjectCallable (),
384+ ResponseContentLifecycleManager .noop ()),
385+ start ,
386+ Hasher .noop (),
387+ retrier ,
388+ retryOnly (DataLossException .class )));
389+ byte [] actualBytes = new byte [15 ];
390+ try (UnbufferedReadableByteChannel c = session .open ()) {
391+ c .read (ByteBuffer .wrap (actualBytes ));
392+ }
393+
394+ boolean warningLogged =
395+ records .stream ().anyMatch (r -> r .getMessage ().contains ("more bytes than requested" ));
396+ assertThat (warningLogged ).isTrue ();
397+ } finally {
398+ logger .removeHandler (handler );
399+ }
400+ }
401+
333402 private static <E extends ApiException > ResultRetryAlgorithm <?> retryOnly (Class <E > c ) {
334403 return new BasicResultRetryAlgorithm <java .lang .Object >() {
335404 @ Override
0 commit comments