test: Add BIDI streaming showcase test. (#1604)

diff --git a/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITBidiStreaming.java b/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITBidiStreaming.java
new file mode 100644
index 0000000..ad90efc
--- /dev/null
+++ b/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITBidiStreaming.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2023 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.showcase.v1beta1.it;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.api.core.SettableApiFuture;
+import com.google.api.gax.rpc.ClientStream;
+import com.google.api.gax.rpc.ResponseObserver;
+import com.google.api.gax.rpc.StreamController;
+import com.google.showcase.v1beta1.EchoClient;
+import com.google.showcase.v1beta1.EchoRequest;
+import com.google.showcase.v1beta1.EchoResponse;
+import com.google.showcase.v1beta1.it.util.TestClientInitializer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class ITBidiStreaming {
+
+  private EchoClient grpcClient;
+
+  @Before
+  public void setUp() throws Exception {
+    // Create gRPC Echo Client
+    grpcClient = TestClientInitializer.createGrpcEchoClient();
+  }
+
+  // The current implementation of BIDI streaming on Echo showcase server is that it would echo the
+  // request content back on every request, so this test verifies that the response content is
+  // exactly the same as request content.
+  // Ideally we should make the BIDI streaming server more generic, e.g. only respond when there are
+  // three requests, respond twice for every request etc. If that happens, the response content may
+  // not be exactly the same as request content.
+  @Test
+  public void testGrpc_splitCall_shouldListensToResponse() throws Exception {
+    // given
+    List<String> expected = Arrays.asList("The rain in Spain stays mainly on the plain".split(" "));
+    TestResponseObserver responseObserver = new TestResponseObserver();
+
+    // when
+    ClientStream<EchoRequest> clientStream = grpcClient.chatCallable().splitCall(responseObserver);
+    expected.forEach(
+        requestContent -> {
+          EchoRequest request = EchoRequest.newBuilder().setContent(requestContent).build();
+          clientStream.send(request);
+        });
+    clientStream.closeSend();
+
+    // then
+    List<String> actual = responseObserver.getFuture().get();
+    assertThat(actual).containsExactlyElementsIn(expected).inOrder();
+  }
+
+  private static class TestResponseObserver implements ResponseObserver<EchoResponse> {
+    private final List<String> responses = new ArrayList<>();
+    private final SettableApiFuture<List<String>> future = SettableApiFuture.create();
+
+    @Override
+    public void onStart(StreamController controller) {
+      // no-op
+    }
+
+    @Override
+    public void onResponse(EchoResponse response) {
+      responses.add(response.getContent());
+    }
+
+    @Override
+    public void onError(Throwable t) {
+      // no-op
+    }
+
+    @Override
+    public void onComplete() {
+      future.set(responses);
+    }
+
+    public SettableApiFuture<List<String>> getFuture() {
+      return future;
+    }
+  }
+
+  @After
+  public void tearDown() throws Exception {
+    grpcClient.close();
+  }
+}
diff --git a/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITClientSideStreaming.java b/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITClientSideStreaming.java
index 27d4f92..93ddd87 100644
--- a/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITClientSideStreaming.java
+++ b/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITClientSideStreaming.java
@@ -20,7 +20,6 @@
 import static org.junit.Assert.assertThrows;
 
 import com.google.api.core.SettableApiFuture;
-import com.google.api.gax.core.NoCredentialsProvider;
 import com.google.api.gax.rpc.ApiStreamObserver;
 import com.google.api.gax.rpc.CancelledException;
 import com.google.api.gax.rpc.StatusCode;
@@ -28,9 +27,7 @@
 import com.google.showcase.v1beta1.EchoClient;
 import com.google.showcase.v1beta1.EchoRequest;
 import com.google.showcase.v1beta1.EchoResponse;
-import com.google.showcase.v1beta1.EchoSettings;
-import io.grpc.ManagedChannelBuilder;
-import java.io.IOException;
+import com.google.showcase.v1beta1.it.util.TestClientInitializer;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.concurrent.ExecutionException;
@@ -43,17 +40,9 @@
   private EchoClient grpcClient;
 
   @Before
-  public void createClients() throws IOException {
+  public void createClients() throws Exception {
     // Create gRPC Echo Client
-    EchoSettings grpcEchoSettings =
-        EchoSettings.newBuilder()
-            .setCredentialsProvider(NoCredentialsProvider.create())
-            .setTransportChannelProvider(
-                EchoSettings.defaultGrpcTransportProviderBuilder()
-                    .setChannelConfigurator(ManagedChannelBuilder::usePlaintext)
-                    .build())
-            .build();
-    grpcClient = EchoClient.create(grpcEchoSettings);
+    grpcClient = TestClientInitializer.createGrpcEchoClient();
   }
 
   @After
diff --git a/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITServerSideStreaming.java b/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITServerSideStreaming.java
index 1bba4f9..e0dc152 100644
--- a/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITServerSideStreaming.java
+++ b/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITServerSideStreaming.java
@@ -19,8 +19,6 @@
 import static com.google.common.truth.Truth.assertThat;
 import static org.junit.Assert.assertThrows;
 
-import com.google.api.client.http.javanet.NetHttpTransport;
-import com.google.api.gax.core.NoCredentialsProvider;
 import com.google.api.gax.rpc.CancelledException;
 import com.google.api.gax.rpc.ServerStream;
 import com.google.api.gax.rpc.StatusCode;
@@ -28,11 +26,8 @@
 import com.google.rpc.Status;
 import com.google.showcase.v1beta1.EchoClient;
 import com.google.showcase.v1beta1.EchoResponse;
-import com.google.showcase.v1beta1.EchoSettings;
 import com.google.showcase.v1beta1.ExpandRequest;
-import io.grpc.ManagedChannelBuilder;
-import java.io.IOException;
-import java.security.GeneralSecurityException;
+import com.google.showcase.v1beta1.it.util.TestClientInitializer;
 import java.util.ArrayList;
 import java.util.Iterator;
 import org.junit.After;
@@ -46,29 +41,11 @@
   private EchoClient httpjsonClient;
 
   @Before
-  public void createClients() throws IOException, GeneralSecurityException {
+  public void createClients() throws Exception {
     // Create gRPC Echo Client
-    EchoSettings grpcEchoSettings =
-        EchoSettings.newBuilder()
-            .setCredentialsProvider(NoCredentialsProvider.create())
-            .setTransportChannelProvider(
-                EchoSettings.defaultGrpcTransportProviderBuilder()
-                    .setChannelConfigurator(ManagedChannelBuilder::usePlaintext)
-                    .build())
-            .build();
-    grpcClient = EchoClient.create(grpcEchoSettings);
+    grpcClient = TestClientInitializer.createGrpcEchoClient();
     // Create Http JSON Echo Client
-    EchoSettings httpJsonEchoSettings =
-        EchoSettings.newHttpJsonBuilder()
-            .setCredentialsProvider(NoCredentialsProvider.create())
-            .setTransportChannelProvider(
-                EchoSettings.defaultHttpJsonTransportProviderBuilder()
-                    .setHttpTransport(
-                        new NetHttpTransport.Builder().doNotValidateCertificate().build())
-                    .setEndpoint("http://localhost:7469")
-                    .build())
-            .build();
-    httpjsonClient = EchoClient.create(httpJsonEchoSettings);
+    httpjsonClient = TestClientInitializer.createHttpJsonEchoClient();
   }
 
   @After
diff --git a/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITUnaryCallable.java b/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITUnaryCallable.java
index 35167a8..52bfddc 100644
--- a/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITUnaryCallable.java
+++ b/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/ITUnaryCallable.java
@@ -19,8 +19,6 @@
 import static com.google.common.truth.Truth.assertThat;
 import static org.junit.Assert.assertThrows;
 
-import com.google.api.client.http.javanet.NetHttpTransport;
-import com.google.api.gax.core.NoCredentialsProvider;
 import com.google.api.gax.grpc.GrpcStatusCode;
 import com.google.api.gax.rpc.CancelledException;
 import com.google.api.gax.rpc.StatusCode;
@@ -28,10 +26,7 @@
 import com.google.showcase.v1beta1.EchoClient;
 import com.google.showcase.v1beta1.EchoRequest;
 import com.google.showcase.v1beta1.EchoResponse;
-import com.google.showcase.v1beta1.EchoSettings;
-import io.grpc.ManagedChannelBuilder;
-import java.io.IOException;
-import java.security.GeneralSecurityException;
+import com.google.showcase.v1beta1.it.util.TestClientInitializer;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
@@ -43,30 +38,11 @@
   private EchoClient httpJsonClient;
 
   @Before
-  public void createClients() throws IOException, GeneralSecurityException {
+  public void createClients() throws Exception {
     // Create gRPC Echo Client
-    EchoSettings grpcEchoSettings =
-        EchoSettings.newBuilder()
-            .setCredentialsProvider(NoCredentialsProvider.create())
-            .setTransportChannelProvider(
-                EchoSettings.defaultGrpcTransportProviderBuilder()
-                    .setChannelConfigurator(ManagedChannelBuilder::usePlaintext)
-                    .build())
-            .build();
-    grpcClient = EchoClient.create(grpcEchoSettings);
-
+    grpcClient = TestClientInitializer.createGrpcEchoClient();
     // Create Http JSON Echo Client
-    EchoSettings httpJsonEchoSettings =
-        EchoSettings.newHttpJsonBuilder()
-            .setCredentialsProvider(NoCredentialsProvider.create())
-            .setTransportChannelProvider(
-                EchoSettings.defaultHttpJsonTransportProviderBuilder()
-                    .setHttpTransport(
-                        new NetHttpTransport.Builder().doNotValidateCertificate().build())
-                    .setEndpoint("http://localhost:7469")
-                    .build())
-            .build();
-    httpJsonClient = EchoClient.create(httpJsonEchoSettings);
+    httpJsonClient = TestClientInitializer.createHttpJsonEchoClient();
   }
 
   @After
diff --git a/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/util/TestClientInitializer.java b/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/util/TestClientInitializer.java
new file mode 100644
index 0000000..e2248ff
--- /dev/null
+++ b/showcase/gapic-showcase/src/test/java/com/google/showcase/v1beta1/it/util/TestClientInitializer.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2023 Google LLC
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.showcase.v1beta1.it.util;
+
+import com.google.api.client.http.javanet.NetHttpTransport;
+import com.google.api.gax.core.NoCredentialsProvider;
+import com.google.showcase.v1beta1.EchoClient;
+import com.google.showcase.v1beta1.EchoSettings;
+import io.grpc.ManagedChannelBuilder;
+
+public class TestClientInitializer {
+
+    public static EchoClient createGrpcEchoClient() throws Exception {
+        EchoSettings grpcEchoSettings =
+                EchoSettings.newBuilder()
+                        .setCredentialsProvider(NoCredentialsProvider.create())
+                        .setTransportChannelProvider(
+                                EchoSettings.defaultGrpcTransportProviderBuilder()
+                                        .setChannelConfigurator(ManagedChannelBuilder::usePlaintext)
+                                        .build())
+
+                        .build();
+        return EchoClient.create(grpcEchoSettings);
+    }
+
+    public static EchoClient createHttpJsonEchoClient() throws Exception{
+        EchoSettings httpJsonEchoSettings =
+                EchoSettings.newHttpJsonBuilder()
+                        .setCredentialsProvider(NoCredentialsProvider.create())
+                        .setTransportChannelProvider(
+                                EchoSettings.defaultHttpJsonTransportProviderBuilder()
+                                        .setHttpTransport(
+                                                new NetHttpTransport.Builder().doNotValidateCertificate().build())
+                                        .setEndpoint("http://localhost:7469")
+                                        .build())
+                        .build();
+        return EchoClient.create(httpJsonEchoSettings);
+    }
+}