2929import com .google .api .gax .batching .BatchingSettings ;
3030import com .google .api .gax .batching .FlowControlSettings ;
3131import com .google .api .gax .rpc .ClientContext ;
32+ import com .google .api .gax .rpc .NotFoundException ;
3233import com .google .api .gax .rpc .ResponseObserver ;
3334import com .google .api .gax .rpc .StreamController ;
3435import com .google .api .gax .tracing .SpanName ;
7273import java .util .concurrent .atomic .AtomicBoolean ;
7374import java .util .concurrent .atomic .AtomicInteger ;
7475import org .junit .After ;
76+ import org .junit .Assert ;
7577import org .junit .Before ;
7678import org .junit .Rule ;
7779import org .junit .Test ;
@@ -91,6 +93,8 @@ public class BuiltinMetricsTracerTest {
9193 private static final String INSTANCE_ID = "fake-instance" ;
9294 private static final String APP_PROFILE_ID = "default" ;
9395 private static final String TABLE_ID = "fake-table" ;
96+
97+ private static final String BAD_TABLE_ID = "non-exist-table" ;
9498 private static final String ZONE = "us-west-1" ;
9599 private static final String CLUSTER = "cluster-0" ;
96100 private static final long FAKE_SERVER_TIMING = 50 ;
@@ -438,6 +442,35 @@ public void testClientBlockingLatencies() throws InterruptedException {
438442 }
439443 }
440444
445+ @ Test
446+ public void testPermanentFailure () {
447+ when (mockFactory .newTracer (any (), any (), any ()))
448+ .thenReturn (
449+ new BuiltinMetricsTracer (
450+ OperationType .ServerStreaming ,
451+ SpanName .of ("Bigtable" , "ReadRows" ),
452+ statsRecorderWrapper ));
453+
454+ try {
455+ Lists .newArrayList (stub .readRowsCallable ().call (Query .create (BAD_TABLE_ID )).iterator ());
456+ Assert .fail ("Request should throw not found error" );
457+ } catch (NotFoundException e ) {
458+ }
459+
460+ ArgumentCaptor <Long > attemptLatency = ArgumentCaptor .forClass (Long .class );
461+ ArgumentCaptor <Long > operationLatency = ArgumentCaptor .forClass (Long .class );
462+
463+ verify (statsRecorderWrapper , timeout (50 )).putAttemptLatencies (attemptLatency .capture ());
464+ verify (statsRecorderWrapper , timeout (50 )).putOperationLatencies (operationLatency .capture ());
465+ verify (statsRecorderWrapper , timeout (50 ))
466+ .recordAttempt (status .capture (), tableId .capture (), zone .capture (), cluster .capture ());
467+
468+ assertThat (status .getValue ()).isEqualTo ("NOT_FOUND" );
469+ assertThat (tableId .getValue ()).isEqualTo (BAD_TABLE_ID );
470+ assertThat (cluster .getValue ()).isEqualTo ("unspecified" );
471+ assertThat (zone .getValue ()).isEqualTo ("global" );
472+ }
473+
441474 private static class FakeService extends BigtableGrpc .BigtableImplBase {
442475
443476 static List <ReadRowsResponse > createFakeResponse () {
@@ -468,6 +501,10 @@ static List<ReadRowsResponse> createFakeResponse() {
468501 @ Override
469502 public void readRows (
470503 ReadRowsRequest request , StreamObserver <ReadRowsResponse > responseObserver ) {
504+ if (request .getTableName ().contains (BAD_TABLE_ID )) {
505+ responseObserver .onError (new StatusRuntimeException (Status .NOT_FOUND ));
506+ return ;
507+ }
471508 final AtomicBoolean done = new AtomicBoolean ();
472509 final ServerCallStreamObserver <ReadRowsResponse > target =
473510 (ServerCallStreamObserver <ReadRowsResponse >) responseObserver ;
0 commit comments