aboutsummaryrefslogtreecommitdiff
path: root/android-interop-testing
diff options
context:
space:
mode:
authorEric Gribkoff <ericgribkoff@google.com>2018-06-13 10:06:43 -0700
committerGitHub <noreply@github.com>2018-06-13 10:06:43 -0700
commit9f023819386f39a635e0999a3894715fd8436031 (patch)
treea78ecf78634a35c172eb731e55424b8c7d3296c8 /android-interop-testing
parent1c5007b866cb7728cb8ba73225975df5428a7a87 (diff)
downloadgrpc-grpc-java-9f023819386f39a635e0999a3894715fd8436031.tar.gz
android-interop-testing,interop-testing: use AbstractInteropTest on Android (#4541)
Diffstat (limited to 'android-interop-testing')
-rw-r--r--android-interop-testing/README.md24
-rw-r--r--android-interop-testing/app/build.gradle63
-rw-r--r--android-interop-testing/app/src/androidTest/java/io/grpc/android/integrationtest/InteropInstrumentationTest.java129
-rw-r--r--android-interop-testing/app/src/androidTest/java/io/grpc/android/integrationtest/InteropTesterTest.java52
-rw-r--r--android-interop-testing/app/src/main/AndroidManifest.xml5
-rw-r--r--android-interop-testing/app/src/main/java/io/grpc/android/integrationtest/InteropTask.java174
-rw-r--r--android-interop-testing/app/src/main/java/io/grpc/android/integrationtest/InteropTester.java771
-rw-r--r--android-interop-testing/app/src/main/java/io/grpc/android/integrationtest/TesterActivity.java71
-rw-r--r--android-interop-testing/app/src/main/java/io/grpc/android/integrationtest/TesterInstrumentation.java105
-rw-r--r--android-interop-testing/app/src/main/java/io/grpc/android/integrationtest/TesterOkHttpChannelBuilder.java22
-rw-r--r--android-interop-testing/app/src/main/proto/grpc/testing/empty.proto30
-rw-r--r--android-interop-testing/app/src/main/proto/grpc/testing/messages.proto122
-rw-r--r--android-interop-testing/app/src/main/proto/grpc/testing/test.proto64
-rw-r--r--android-interop-testing/app/src/main/res/layout/activity_tester.xml12
-rw-r--r--android-interop-testing/build.gradle4
15 files changed, 433 insertions, 1215 deletions
diff --git a/android-interop-testing/README.md b/android-interop-testing/README.md
index 950907b08..c1abcee4d 100644
--- a/android-interop-testing/README.md
+++ b/android-interop-testing/README.md
@@ -35,21 +35,19 @@ $ ../gradlew installDebug
Then manually test it with the UI.
-Commandline test
+Instrumentation tests
----------------
-Run the test with arguments:
-```
-$ adb shell am instrument -w -e server_host <hostname or ip address> -e server_port <port> -e server_host_override foo.test.google.fr -e use_tls true -e use_test_ca true -e test_case all io.grpc.android.integrationtest/.TesterInstrumentation
-```
+Instrumentation tests must be run on a connected device or emulator. Run with the
+following gradle command:
-If the test passed successfully, it will output:
-```
-INSTRUMENTATION_RESULT: grpc test result=Success!
-INSTRUMENTATION_CODE: -1
```
-otherwise, output something like:
-```
-INSTRUMENTATION_RESULT: grpc test result=Failed... : <exception stacktrace if applicable>
-INSTRUMENTATION_CODE: 0
+$ ../gradlew connectedAndroidTest \
+ -Pandroid.testInstrumentationRunnerArguments.server_host=10.0.2.2 \
+ -Pandroid.testInstrumentationRunnerArguments.server_port=8080 \
+ -Pandroid.testInstrumentationRunnerArguments.use_tls=true \
+ -Pandroid.testInstrumentationRunnerArguments.server_host_override=foo.test.google.fr \
+ -Pandroid.testInstrumentationRunnerArguments.use_test_ca=true \
+ -Pandroid.testInstrumentationRunnerArguments.test_case=all
```
+
diff --git a/android-interop-testing/app/build.gradle b/android-interop-testing/app/build.gradle
index 51f7a2103..f20ab5d72 100644
--- a/android-interop-testing/app/build.gradle
+++ b/android-interop-testing/app/build.gradle
@@ -2,6 +2,20 @@ apply plugin: 'com.android.application'
apply plugin: 'com.google.protobuf'
android {
+ sourceSets {
+ main {
+ java {
+ srcDirs += "${projectDir}/../../interop-testing/src/main/java/"
+ setIncludes(["io/grpc/android/integrationtest/**",
+ "io/grpc/testing/integration/AbstractInteropTest.java",
+ "io/grpc/testing/integration/TestServiceImpl.java",
+ "io/grpc/testing/integration/Util.java"])
+ }
+ proto {
+ srcDirs += "${projectDir}/../../interop-testing/src/main/proto/"
+ }
+ }
+ }
compileSdkVersion 26
defaultConfig {
@@ -12,6 +26,7 @@ android {
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+ multiDexEnabled true
}
buildTypes {
debug { minifyEnabled false }
@@ -26,41 +41,47 @@ android {
protobuf {
protoc { artifact = 'com.google.protobuf:protoc:3.5.1-1' }
plugins {
+ javalite { artifact = "com.google.protobuf:protoc-gen-javalite:3.0.0" }
grpc { artifact = 'io.grpc:protoc-gen-grpc-java:1.14.0-SNAPSHOT' // CURRENT_GRPC_VERSION
}
}
generateProtoTasks {
all().each { task ->
- task.builtins {
- javanano {
- // Options added to --javanano_out
- option 'ignore_services=true'
- option 'enum_style=java'
- }
- }
-
task.plugins {
- grpc { // Options added to --grpc_out
- option 'nano' }
+ javalite {}
+ grpc {
+ // Options added to --grpc_out
+ option 'lite'
+ }
}
}
}
}
dependencies {
- compile 'com.android.support:appcompat-v7:26.1.0'
- compile 'com.android.support:support-annotations:27.1.1'
- compile 'com.google.android.gms:play-services-base:12.0.1'
+ implementation 'com.android.support:appcompat-v7:26.1.0'
+ implementation 'com.android.support:multidex:1.0.3'
+ implementation 'com.android.support:support-annotations:27.1.1'
+ implementation 'com.google.android.gms:play-services-base:15.0.1'
+ implementation ('com.google.auth:google-auth-library-oauth2-http:0.9.0') {
+ exclude group: 'org.apache.httpcomponents', module: 'httpclient'
+ }
+ implementation 'com.google.truth:truth:0.36'
+ implementation 'javax.annotation:javax.annotation-api:1.2'
+ implementation 'junit:junit:4.12'
+
// You need to build grpc-java to obtain the grpc libraries below.
- compile 'io.grpc:grpc-protobuf-nano:1.14.0-SNAPSHOT' // CURRENT_GRPC_VERSION
- compile 'io.grpc:grpc-okhttp:1.14.0-SNAPSHOT' // CURRENT_GRPC_VERSION
- compile 'io.grpc:grpc-stub:1.14.0-SNAPSHOT' // CURRENT_GRPC_VERSION
- compile 'io.grpc:grpc-testing:1.14.0-SNAPSHOT' // CURRENT_GRPC_VERSION
- compile 'javax.annotation:javax.annotation-api:1.2'
- compile 'junit:junit:4.12'
+ implementation 'io.grpc:grpc-auth:1.14.0-SNAPSHOT' // CURRENT_GRPC_VERSION
+ implementation 'io.grpc:grpc-okhttp:1.14.0-SNAPSHOT' // CURRENT_GRPC_VERSION
+ implementation 'io.grpc:grpc-protobuf-lite:1.14.0-SNAPSHOT' // CURRENT_GRPC_VERSION
+ implementation 'io.grpc:grpc-stub:1.14.0-SNAPSHOT' // CURRENT_GRPC_VERSION
+ implementation 'io.grpc:grpc-testing:1.14.0-SNAPSHOT' // CURRENT_GRPC_VERSION
+
+ // workaround for https://github.com/google/protobuf/issues/1889
+ protobuf 'com.google.protobuf:protobuf-java:3.0.2'
- androidTestCompile 'com.android.support.test:rules:1.0.1'
- androidTestCompile 'com.android.support.test:runner:1.0.1'
+ androidTestImplementation 'com.android.support.test:rules:1.0.1'
+ androidTestImplementation 'com.android.support.test:runner:1.0.1'
}
gradle.projectsEvaluated {
diff --git a/android-interop-testing/app/src/androidTest/java/io/grpc/android/integrationtest/InteropInstrumentationTest.java b/android-interop-testing/app/src/androidTest/java/io/grpc/android/integrationtest/InteropInstrumentationTest.java
new file mode 100644
index 000000000..a7adf4b2d
--- /dev/null
+++ b/android-interop-testing/app/src/androidTest/java/io/grpc/android/integrationtest/InteropInstrumentationTest.java
@@ -0,0 +1,129 @@
+/*
+ * Copyright 2017 The gRPC Authors
+ *
+ * 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
+ *
+ * http://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 io.grpc.android.integrationtest;
+
+import static junit.framework.Assert.assertEquals;
+
+import android.support.test.InstrumentationRegistry;
+import android.support.test.runner.AndroidJUnit4;
+import android.util.Log;
+import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
+import com.google.android.gms.common.GooglePlayServicesRepairableException;
+import com.google.android.gms.security.ProviderInstaller;
+import com.google.common.util.concurrent.SettableFuture;
+import io.grpc.ClientInterceptor;
+import io.grpc.android.integrationtest.InteropTask.Listener;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.concurrent.TimeUnit;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@RunWith(AndroidJUnit4.class)
+public class InteropInstrumentationTest {
+ private static final int TIMEOUT_SECONDS = 10;
+ private static String LOG_TAG = "GrpcInteropInstrumentationTest";
+
+ private String host;
+ private int port;
+ private boolean useTls;
+ private String serverHostOverride;
+ private boolean useTestCa;
+ private String testCase;
+
+ @Before
+ public void setUp() throws Exception {
+ host = InstrumentationRegistry.getArguments().getString("server_host", "10.0.2.2");
+ port =
+ Integer.parseInt(InstrumentationRegistry.getArguments().getString("server_port", "8080"));
+ useTls =
+ Boolean.parseBoolean(InstrumentationRegistry.getArguments().getString("use_tls", "true"));
+ serverHostOverride = InstrumentationRegistry.getArguments().getString("server_host_override");
+ useTestCa =
+ Boolean.parseBoolean(
+ InstrumentationRegistry.getArguments().getString("use_test_ca", "false"));
+ testCase = InstrumentationRegistry.getArguments().getString("test_case", "all");
+
+ if (useTls) {
+ try {
+ ProviderInstaller.installIfNeeded(InstrumentationRegistry.getTargetContext());
+ } catch (GooglePlayServicesRepairableException e) {
+ // The provider is helpful, but it is possible to succeed without it.
+ // Hope that the system-provided libraries are new enough.
+ Log.i(LOG_TAG, "Failed installing security provider", e);
+ } catch (GooglePlayServicesNotAvailableException e) {
+ // The provider is helpful, but it is possible to succeed without it.
+ // Hope that the system-provided libraries are new enough.
+ Log.i(LOG_TAG, "Failed installing security provider", e);
+ }
+ }
+ }
+
+ @Test
+ public void interopTests() throws Exception {
+ if (testCase.equals("all")) {
+ runTest("empty_unary");
+ runTest("large_unary");
+ runTest("client_streaming");
+ runTest("server_streaming");
+ runTest("ping_pong");
+ runTest("empty_stream");
+ runTest("cancel_after_begin");
+ runTest("cancel_after_first_response");
+ runTest("full_duplex_call_should_succeed");
+ runTest("half_duplex_call_should_succeed");
+ runTest("server_streaming_should_be_flow_controlled");
+ runTest("very_large_request");
+ runTest("very_large_response");
+ runTest("deadline_not_exceeded");
+ runTest("deadline_exceeded");
+ runTest("deadline_exceeded_server_streaming");
+ runTest("unimplemented_method");
+ runTest("timeout_on_sleeping_server");
+ runTest("graceful_shutdown");
+ } else {
+ runTest(testCase);
+ }
+ }
+
+ private void runTest(String testCase) throws Exception {
+ final SettableFuture<String> resultFuture = SettableFuture.create();
+ InteropTask.Listener listener =
+ new Listener() {
+ @Override
+ public void onComplete(String result) {
+
+ resultFuture.set(result);
+ }
+ };
+ InputStream testCa;
+ if (useTestCa) {
+ testCa = InstrumentationRegistry.getTargetContext().getResources().openRawResource(R.raw.ca);
+ } else {
+ testCa = null;
+ }
+ new InteropTask(
+ listener,
+ TesterOkHttpChannelBuilder.build(host, port, serverHostOverride, useTls, testCa),
+ new ArrayList<ClientInterceptor>(),
+ testCase)
+ .execute();
+ String result = resultFuture.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
+ assertEquals(testCase + " failed", result, InteropTask.SUCCESS_MESSAGE);
+ }
+}
diff --git a/android-interop-testing/app/src/androidTest/java/io/grpc/android/integrationtest/InteropTesterTest.java b/android-interop-testing/app/src/androidTest/java/io/grpc/android/integrationtest/InteropTesterTest.java
deleted file mode 100644
index 8f83542de..000000000
--- a/android-interop-testing/app/src/androidTest/java/io/grpc/android/integrationtest/InteropTesterTest.java
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright 2017 The gRPC Authors
- *
- * 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
- *
- * http://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 io.grpc.android.integrationtest;
-
-import static junit.framework.Assert.assertEquals;
-
-import android.support.test.runner.AndroidJUnit4;
-import com.google.common.util.concurrent.SettableFuture;
-import java.util.concurrent.TimeUnit;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(AndroidJUnit4.class)
-public class InteropTesterTest {
- private final int TIMEOUT_SECONDS = 120;
-
- @Test
- public void interopTests() throws Exception {
- final SettableFuture<String> resultFuture = SettableFuture.create();
- new InteropTester(
- "all",
- TesterOkHttpChannelBuilder.build(
- "grpc-test.sandbox.googleapis.com", 443, null, true, null, null),
- new InteropTester.TestListener() {
- @Override
- public void onPreTest() {}
-
- @Override
- public void onPostTest(String result) {
- resultFuture.set(result);
- }
- },
- false)
- .execute();
- String result = resultFuture.get(TIMEOUT_SECONDS, TimeUnit.SECONDS);
- assertEquals(result, InteropTester.SUCCESS_MESSAGE);
- }
-}
diff --git a/android-interop-testing/app/src/main/AndroidManifest.xml b/android-interop-testing/app/src/main/AndroidManifest.xml
index 193d8e01b..4e0409f33 100644
--- a/android-interop-testing/app/src/main/AndroidManifest.xml
+++ b/android-interop-testing/app/src/main/AndroidManifest.xml
@@ -25,9 +25,4 @@
</activity>
</application>
- <instrumentation android:functionalTest="true"
- android:label="@string/app_name"
- android:name=".TesterInstrumentation"
- android:targetPackage="io.grpc.android.integrationtest" />
-
</manifest>
diff --git a/android-interop-testing/app/src/main/java/io/grpc/android/integrationtest/InteropTask.java b/android-interop-testing/app/src/main/java/io/grpc/android/integrationtest/InteropTask.java
new file mode 100644
index 000000000..2ce2b1ab6
--- /dev/null
+++ b/android-interop-testing/app/src/main/java/io/grpc/android/integrationtest/InteropTask.java
@@ -0,0 +1,174 @@
+/*
+ * Copyright 2018 The gRPC Authors
+ *
+ * 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
+ *
+ * http://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 io.grpc.android.integrationtest;
+
+import android.os.AsyncTask;
+import android.util.Log;
+import io.grpc.ClientInterceptor;
+import io.grpc.ManagedChannel;
+import io.grpc.testing.integration.AbstractInteropTest;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.ref.WeakReference;
+import java.util.List;
+import org.junit.AssumptionViolatedException;
+
+/** AsyncTask for interop test cases. */
+final class InteropTask extends AsyncTask<Void, Void, String> {
+ private static final String LOG_TAG = "GrpcInteropTask";
+
+ interface Listener {
+ void onComplete(String result);
+ }
+
+ static final String SUCCESS_MESSAGE = "Success!";
+
+ private final WeakReference<Listener> listenerReference;
+ private final String testCase;
+ private final Tester tester;
+
+ InteropTask(
+ Listener listener,
+ ManagedChannel channel,
+ List<ClientInterceptor> interceptors,
+ String testCase) {
+ this.listenerReference = new WeakReference<Listener>(listener);
+ this.testCase = testCase;
+ this.tester = new Tester(channel, interceptors);
+ }
+
+ @Override
+ protected void onPreExecute() {
+ tester.setUp();
+ }
+
+ @Override
+ protected String doInBackground(Void... ignored) {
+ try {
+ runTest(testCase);
+ return SUCCESS_MESSAGE;
+ } catch (Throwable t) {
+ // Print the stack trace to logcat.
+ t.printStackTrace();
+ // Then print to the error message.
+ StringWriter sw = new StringWriter();
+ t.printStackTrace(new PrintWriter(sw));
+ return "Failed... : " + t.getMessage() + "\n" + sw.toString();
+ } finally {
+ try {
+ tester.tearDown();
+ } catch (RuntimeException ex) {
+ throw ex;
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ }
+
+ private void runTest(String testCase) throws Exception {
+ Log.i(LOG_TAG, "Running test case: " + testCase);
+ if ("empty_unary".equals(testCase)) {
+ tester.emptyUnary();
+ } else if ("large_unary".equals(testCase)) {
+ try {
+ tester.largeUnary();
+ } catch (AssumptionViolatedException e) {
+ // This test case requires more memory than most Android devices have available
+ Log.w(LOG_TAG, "Skipping " + testCase + " due to assumption violation", e);
+ }
+ } else if ("client_streaming".equals(testCase)) {
+ tester.clientStreaming();
+ } else if ("server_streaming".equals(testCase)) {
+ tester.serverStreaming();
+ } else if ("ping_pong".equals(testCase)) {
+ tester.pingPong();
+ } else if ("empty_stream".equals(testCase)) {
+ tester.emptyStream();
+ } else if ("cancel_after_begin".equals(testCase)) {
+ tester.cancelAfterBegin();
+ } else if ("cancel_after_first_response".equals(testCase)) {
+ tester.cancelAfterFirstResponse();
+ } else if ("full_duplex_call_should_succeed".equals(testCase)) {
+ tester.fullDuplexCallShouldSucceed();
+ } else if ("half_duplex_call_should_succeed".equals(testCase)) {
+ tester.halfDuplexCallShouldSucceed();
+ } else if ("server_streaming_should_be_flow_controlled".equals(testCase)) {
+ tester.serverStreamingShouldBeFlowControlled();
+ } else if ("very_large_request".equals(testCase)) {
+ try {
+ tester.veryLargeRequest();
+ } catch (AssumptionViolatedException e) {
+ // This test case requires more memory than most Android devices have available
+ Log.w(LOG_TAG, "Skipping " + testCase + " due to assumption violation", e);
+ }
+ } else if ("very_large_response".equals(testCase)) {
+ try {
+ tester.veryLargeResponse();
+ } catch (AssumptionViolatedException e) {
+ // This test case requires more memory than most Android devices have available
+ Log.w(LOG_TAG, "Skipping " + testCase + " due to assumption violation", e);
+ }
+ } else if ("deadline_not_exceeded".equals(testCase)) {
+ tester.deadlineNotExceeded();
+ } else if ("deadline_exceeded".equals(testCase)) {
+ tester.deadlineExceeded();
+ } else if ("deadline_exceeded_server_streaming".equals(testCase)) {
+ tester.deadlineExceededServerStreaming();
+ } else if ("unimplemented_method".equals(testCase)) {
+ tester.unimplementedMethod();
+ } else if ("timeout_on_sleeping_server".equals(testCase)) {
+ tester.timeoutOnSleepingServer();
+ } else if ("graceful_shutdown".equals(testCase)) {
+ tester.gracefulShutdown();
+ } else {
+ throw new IllegalArgumentException("Unimplemented/Unknown test case: " + testCase);
+ }
+ }
+
+ @Override
+ protected void onPostExecute(String result) {
+ Listener listener = listenerReference.get();
+ if (listener != null) {
+ listener.onComplete(result);
+ }
+ }
+
+ private class Tester extends AbstractInteropTest {
+ private final ManagedChannel channel;
+ private final List<ClientInterceptor> interceptors;
+
+ private Tester(ManagedChannel channel, List<ClientInterceptor> interceptors) {
+ this.channel = channel;
+ this.interceptors = interceptors;
+ }
+
+ @Override
+ protected ManagedChannel createChannel() {
+ return channel;
+ }
+
+ @Override
+ protected ClientInterceptor[] getAdditionalInterceptors() {
+ return interceptors.toArray(new ClientInterceptor[0]);
+ }
+
+ @Override
+ protected boolean metricsExpected() {
+ return false;
+ }
+ }
+}
diff --git a/android-interop-testing/app/src/main/java/io/grpc/android/integrationtest/InteropTester.java b/android-interop-testing/app/src/main/java/io/grpc/android/integrationtest/InteropTester.java
deleted file mode 100644
index e7ea66bcf..000000000
--- a/android-interop-testing/app/src/main/java/io/grpc/android/integrationtest/InteropTester.java
+++ /dev/null
@@ -1,771 +0,0 @@
-/*
- * Copyright 2015 The gRPC Authors
- *
- * 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
- *
- * http://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 io.grpc.android.integrationtest;
-
-import static junit.framework.Assert.assertEquals;
-import static junit.framework.Assert.assertNull;
-import static junit.framework.Assert.assertTrue;
-import static junit.framework.Assert.fail;
-
-import android.os.AsyncTask;
-import android.util.Log;
-import com.google.protobuf.nano.EmptyProtos;
-import com.google.protobuf.nano.MessageNano;
-import io.grpc.CallOptions;
-import io.grpc.Channel;
-import io.grpc.ClientCall;
-import io.grpc.ClientInterceptor;
-import io.grpc.ClientInterceptors;
-import io.grpc.ClientInterceptors.CheckedForwardingClientCall;
-import io.grpc.ManagedChannel;
-import io.grpc.Metadata;
-import io.grpc.MethodDescriptor;
-import io.grpc.StatusRuntimeException;
-import io.grpc.android.integrationtest.nano.Messages;
-import io.grpc.android.integrationtest.nano.Messages.Payload;
-import io.grpc.android.integrationtest.nano.Messages.ResponseParameters;
-import io.grpc.android.integrationtest.nano.Messages.SimpleRequest;
-import io.grpc.android.integrationtest.nano.Messages.SimpleResponse;
-import io.grpc.android.integrationtest.nano.Messages.StreamingInputCallRequest;
-import io.grpc.android.integrationtest.nano.Messages.StreamingInputCallResponse;
-import io.grpc.android.integrationtest.nano.Messages.StreamingOutputCallRequest;
-import io.grpc.android.integrationtest.nano.Messages.StreamingOutputCallResponse;
-import io.grpc.android.integrationtest.nano.TestServiceGrpc;
-import io.grpc.android.integrationtest.nano.UnimplementedServiceGrpc;
-import io.grpc.internal.testing.StreamRecorder;
-import io.grpc.stub.StreamObserver;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.util.Arrays;
-import java.util.List;
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.LinkedBlockingQueue;
-import java.util.concurrent.TimeUnit;
-
-/**
- * Implementation of the integration tests, as an AsyncTask.
- */
-final class InteropTester extends AsyncTask<Void, Void, String> {
- static final String SUCCESS_MESSAGE = "Success!";
- static final String LOG_TAG = "GrpcTest";
-
- private ManagedChannel channel;
- private TestServiceGrpc.TestServiceBlockingStub blockingStub;
- private TestServiceGrpc.TestServiceStub asyncStub;
- private String testCase;
- private TestListener listener;
- private static final int TIMEOUT_MILLIS = 5000;
-
- private static final class ResponseObserver
- implements StreamObserver<Messages.StreamingOutputCallResponse> {
- public LinkedBlockingQueue<Object> responses = new LinkedBlockingQueue<Object>();
- final Object magicTailResponse = new Object();
-
- @Override
- public void onNext(Messages.StreamingOutputCallResponse value) {
- responses.add(value);
- }
-
- @Override
- public void onError(Throwable t) {
- Log.e(LOG_TAG, "Encounter an error", t);
- responses.add(t);
- }
-
- @Override
- public void onCompleted() {
- responses.add(magicTailResponse);
- }
- }
-
-
- public InteropTester(String testCase,
- ManagedChannel channel,
- TestListener listener,
- boolean useGet) {
- this.testCase = testCase;
- this.listener = listener;
- this.channel = channel;
- Channel channelToUse = channel;
- if (useGet) {
- channelToUse = ClientInterceptors.intercept(channel, new SafeMethodChannelInterceptor());
- }
- blockingStub = TestServiceGrpc.newBlockingStub(channelToUse);
- asyncStub = TestServiceGrpc.newStub(channelToUse);
- }
-
- @Override
- protected void onPreExecute() {
- listener.onPreTest();
- }
-
- @Override
- protected String doInBackground(Void... nothing) {
- try {
- runTest(testCase);
- return SUCCESS_MESSAGE;
- } catch (Throwable t) {
- // Print the stack trace to logcat.
- t.printStackTrace();
- // Then print to the error message.
- StringWriter sw = new StringWriter();
- t.printStackTrace(new PrintWriter(sw));
- return "Failed... : " + t.getMessage() + "\n" + sw.toString();
- } finally {
- shutdown();
- }
- }
-
- @Override
- protected void onPostExecute(String result) {
- listener.onPostTest(result);
- }
-
-
- public void shutdown() {
- channel.shutdown();
- }
-
- public void runTest(String testCase) throws Exception {
- Log.i(LOG_TAG, "Running test " + testCase);
- if ("all".equals(testCase)) {
- runTest("empty_unary");
- runTest("large_unary");
- runTest("client_streaming");
- runTest("server_streaming");
- runTest("ping_pong");
- runTest("empty_stream");
- runTest("cancel_after_begin");
- runTest("cancel_after_first_response");
- runTest("full_duplex_call_should_succeed");
- runTest("half_duplex_call_should_succeed");
- runTest("server_streaming_should_be_flow_controlled");
- runTest("very_large_request");
- runTest("very_large_response");
- runTest("deadline_not_exceeded");
- runTest("deadline_exceeded");
- runTest("deadline_exceeded_server_streaming");
- runTest("unimplemented_method");
- runTest("timeout_on_sleeping_server");
- // This has to be the last one, because it will shut down the channel.
- runTest("graceful_shutdown");
- } else if ("empty_unary".equals(testCase)) {
- emptyUnary();
- } else if ("large_unary".equals(testCase)) {
- largeUnary();
- } else if ("client_streaming".equals(testCase)) {
- clientStreaming();
- } else if ("server_streaming".equals(testCase)) {
- serverStreaming();
- } else if ("ping_pong".equals(testCase)) {
- pingPong();
- } else if ("empty_stream".equals(testCase)) {
- emptyStream();
- } else if ("cancel_after_begin".equals(testCase)) {
- cancelAfterBegin();
- } else if ("cancel_after_first_response".equals(testCase)) {
- cancelAfterFirstResponse();
- } else if ("full_duplex_call_should_succeed".equals(testCase)) {
- fullDuplexCallShouldSucceed();
- } else if ("half_duplex_call_should_succeed".equals(testCase)) {
- halfDuplexCallShouldSucceed();
- } else if ("server_streaming_should_be_flow_controlled".equals(testCase)) {
- serverStreamingShouldBeFlowControlled();
- } else if ("very_large_request".equals(testCase)) {
- veryLargeRequest();
- } else if ("very_large_response".equals(testCase)) {
- veryLargeResponse();
- } else if ("deadline_not_exceeded".equals(testCase)) {
- deadlineNotExceeded();
- } else if ("deadline_exceeded".equals(testCase)) {
- deadlineExceeded();
- } else if ("deadline_exceeded_server_streaming".equals(testCase)) {
- deadlineExceededServerStreaming();
- } else if ("unimplemented_method".equals(testCase)) {
- unimplementedMethod();
- } else if ("timeout_on_sleeping_server".equals(testCase)) {
- timeoutOnSleepingServer();
- } else if ("graceful_shutdown".equals(testCase)) {
- gracefulShutdown();
- } else {
- throw new IllegalArgumentException("Unimplemented/Unknown test case: " + testCase);
- }
- }
-
- public void emptyUnary() {
- assertMessageEquals(new EmptyProtos.Empty(), blockingStub.emptyCall(new EmptyProtos.Empty()));
- }
-
- public void largeUnary() {
- if (shouldSkip()) {
- return;
- }
- final Messages.SimpleRequest request = new Messages.SimpleRequest();
- request.responseSize = 314159;
- request.responseType = Messages.PayloadType.COMPRESSABLE;
- request.payload = new Payload();
- request.payload.body = new byte[271828];
-
- final Messages.SimpleResponse goldenResponse = new Messages.SimpleResponse();
- goldenResponse.payload = new Payload();
- goldenResponse.payload.body = new byte[314159];
- Messages.SimpleResponse response = blockingStub.unaryCall(request);
- assertMessageEquals(goldenResponse, response);
- }
-
- public void serverStreaming() throws Exception {
- final Messages.StreamingOutputCallRequest request = new Messages.StreamingOutputCallRequest();
- request.responseType = Messages.PayloadType.COMPRESSABLE;
- request.responseParameters = new Messages.ResponseParameters[4];
- for (int i = 0; i < 4; i++) {
- request.responseParameters[i] = new Messages.ResponseParameters();
- }
- request.responseParameters[0].size = 31415;
- request.responseParameters[1].size = 9;
- request.responseParameters[2].size = 2653;
- request.responseParameters[3].size = 58979;
-
- final Messages.StreamingOutputCallResponse[] goldenResponses =
- new Messages.StreamingOutputCallResponse[4];
- for (int i = 0; i < 4; i++) {
- goldenResponses[i] = new Messages.StreamingOutputCallResponse();
- goldenResponses[i].payload = new Payload();
- goldenResponses[i].payload.type = Messages.PayloadType.COMPRESSABLE;
- }
- goldenResponses[0].payload.body = new byte[31415];
- goldenResponses[1].payload.body = new byte[9];
- goldenResponses[2].payload.body = new byte[2653];
- goldenResponses[3].payload.body = new byte[58979];
-
- StreamRecorder<Messages.StreamingOutputCallResponse> recorder = StreamRecorder.create();
- asyncStub.streamingOutputCall(request, recorder);
- assertTrue(recorder.awaitCompletion(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS));
- assertSuccess(recorder);
- assertMessageEquals(Arrays.asList(goldenResponses), recorder.getValues());
- }
-
- public void clientStreaming() throws Exception {
- final Messages.StreamingInputCallRequest[] requests = new Messages.StreamingInputCallRequest[4];
- for (int i = 0; i < 4; i++) {
- requests[i] = new Messages.StreamingInputCallRequest();
- requests[i].payload = new Payload();
- }
- requests[0].payload.body = new byte[27182];
- requests[1].payload.body = new byte[8];
- requests[2].payload.body = new byte[1828];
- requests[3].payload.body = new byte[45904];
-
- final Messages.StreamingInputCallResponse goldenResponse =
- new Messages.StreamingInputCallResponse();
- goldenResponse.aggregatedPayloadSize = 74922;
-
- StreamRecorder<Messages.StreamingInputCallResponse> responseObserver = StreamRecorder.create();
- StreamObserver<Messages.StreamingInputCallRequest> requestObserver =
- asyncStub.streamingInputCall(responseObserver);
- for (Messages.StreamingInputCallRequest request : requests) {
- requestObserver.onNext(request);
- }
- requestObserver.onCompleted();
- assertMessageEquals(goldenResponse, responseObserver.firstValue().get());
- }
-
- public void pingPong() throws Exception {
- final Messages.StreamingOutputCallRequest[] requests =
- new Messages.StreamingOutputCallRequest[4];
- for (int i = 0; i < 4; i++) {
- requests[i] = new Messages.StreamingOutputCallRequest();
- requests[i].responseParameters = new Messages.ResponseParameters[1];
- requests[i].responseParameters[0] = new Messages.ResponseParameters();
- requests[i].payload = new Payload();
- }
- requests[0].responseParameters[0].size = 31415;
- requests[0].payload.body = new byte[27182];
- requests[1].responseParameters[0].size = 9;
- requests[1].payload.body = new byte[8];
- requests[2].responseParameters[0].size = 2653;
- requests[2].payload.body = new byte[1828];
- requests[3].responseParameters[0].size = 58979;
- requests[3].payload.body = new byte[45904];
-
-
- final Messages.StreamingOutputCallResponse[] goldenResponses =
- new Messages.StreamingOutputCallResponse[4];
- for (int i = 0; i < 4; i++) {
- goldenResponses[i] = new Messages.StreamingOutputCallResponse();
- goldenResponses[i].payload = new Payload();
- goldenResponses[i].payload.type = Messages.PayloadType.COMPRESSABLE;
- }
- goldenResponses[0].payload.body = new byte[31415];
- goldenResponses[1].payload.body = new byte[9];
- goldenResponses[2].payload.body = new byte[2653];
- goldenResponses[3].payload.body = new byte[58979];
-
- ResponseObserver responseObserver = new ResponseObserver();
- StreamObserver<Messages.StreamingOutputCallRequest> requestObserver
- = asyncStub.fullDuplexCall(responseObserver);
- for (int i = 0; i < requests.length; i++) {
- requestObserver.onNext(requests[i]);
- Object response = responseObserver.responses.poll(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
- if (!(response instanceof Messages.StreamingOutputCallResponse)) {
- fail("Unexpected: " + response);
- }
- assertMessageEquals(goldenResponses[i], (Messages.StreamingOutputCallResponse) response);
- assertTrue("More than 1 responses received for ping pong test.",
- responseObserver.responses.isEmpty());
- }
- requestObserver.onCompleted();
- assertEquals(responseObserver.magicTailResponse,
- responseObserver.responses.poll(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS));
- }
-
- public void emptyStream() throws Exception {
- ResponseObserver responseObserver = new ResponseObserver();
- StreamObserver<StreamingOutputCallRequest> requestObserver
- = asyncStub.fullDuplexCall(responseObserver);
- requestObserver.onCompleted();
- assertEquals(responseObserver.magicTailResponse,
- responseObserver.responses.poll(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS));
- }
-
- public void cancelAfterBegin() throws Exception {
- StreamRecorder<StreamingInputCallResponse> responseObserver = StreamRecorder.create();
- StreamObserver<StreamingInputCallRequest> requestObserver =
- asyncStub.streamingInputCall(responseObserver);
- requestObserver.onError(new RuntimeException());
- assertTrue(responseObserver.awaitCompletion(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS));
- assertEquals(Arrays.<StreamingInputCallResponse>asList(), responseObserver.getValues());
- assertCodeEquals(io.grpc.Status.CANCELLED,
- io.grpc.Status.fromThrowable(responseObserver.getError()));
- }
-
- public void cancelAfterFirstResponse() throws Exception {
- final StreamingOutputCallRequest request = new StreamingOutputCallRequest();
- request.responseParameters = new Messages.ResponseParameters[1];
- request.responseParameters[0] = new ResponseParameters();
- request.responseParameters[0].size = 31415;
- request.payload = new Payload();
- request.payload.body = new byte[27182];
- final StreamingOutputCallResponse goldenResponse = new StreamingOutputCallResponse();
- goldenResponse.payload = new Payload();
- goldenResponse.payload.type = Messages.PayloadType.COMPRESSABLE;
- goldenResponse.payload.body = new byte[31415];
-
- ResponseObserver responseObserver = new ResponseObserver();
- StreamObserver<StreamingOutputCallRequest> requestObserver
- = asyncStub.fullDuplexCall(responseObserver);
- requestObserver.onNext(request);
- Object response = responseObserver.responses.poll(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
- if (!(response instanceof Messages.StreamingOutputCallResponse)) {
- fail("Unexpected: " + response);
- }
- assertMessageEquals(goldenResponse, (Messages.StreamingOutputCallResponse) response);
-
- requestObserver.onError(new RuntimeException());
- response = responseObserver.responses.poll(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
- if (!(response instanceof Throwable)) {
- fail("Unexpected: " + response);
- }
- assertCodeEquals(io.grpc.Status.CANCELLED, io.grpc.Status.fromThrowable((Throwable) response));
- }
-
- public void fullDuplexCallShouldSucceed() throws Exception {
- // Build the request.
- Integer[] responseSizes = {50, 100, 150, 200};
- final StreamingOutputCallRequest request = new StreamingOutputCallRequest();
- request.responseParameters = new ResponseParameters[responseSizes.length];
- request.responseType = Messages.PayloadType.COMPRESSABLE;
- for (int i = 0; i < responseSizes.length; ++i) {
- request.responseParameters[i] = new ResponseParameters();
- request.responseParameters[i].size = responseSizes[i];
- request.responseParameters[i].intervalUs = 0;
- }
-
- StreamRecorder<StreamingOutputCallResponse> recorder = StreamRecorder.create();
- StreamObserver<StreamingOutputCallRequest> requestStream =
- asyncStub.fullDuplexCall(recorder);
-
- final int numRequests = 10;
- for (int ix = numRequests; ix > 0; --ix) {
- requestStream.onNext(request);
- }
- requestStream.onCompleted();
- assertTrue(recorder.awaitCompletion(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS));
- assertSuccess(recorder);
- assertEquals(responseSizes.length * numRequests, recorder.getValues().size());
- for (int ix = 0; ix < recorder.getValues().size(); ++ix) {
- StreamingOutputCallResponse response = recorder.getValues().get(ix);
- assertEquals(Messages.PayloadType.COMPRESSABLE, response.payload.type);
- int length = response.payload.body.length;
- int expectedSize = responseSizes[ix % responseSizes.length];
- assertEquals("comparison failed at index " + ix, expectedSize, length);
- }
- }
-
- public void halfDuplexCallShouldSucceed() throws Exception {
- // Build the request.
- Integer[] responseSizes = {50, 100, 150, 200};
- final StreamingOutputCallRequest request = new StreamingOutputCallRequest();
- request.responseParameters = new ResponseParameters[responseSizes.length];
- request.responseType = Messages.PayloadType.COMPRESSABLE;
- for (int i = 0; i < responseSizes.length; ++i) {
- request.responseParameters[i] = new ResponseParameters();
- request.responseParameters[i].size = responseSizes[i];
- request.responseParameters[i].intervalUs = 0;
- }
-
- StreamRecorder<StreamingOutputCallResponse> recorder = StreamRecorder.create();
- StreamObserver<StreamingOutputCallRequest> requestStream = asyncStub.halfDuplexCall(recorder);
-
- final int numRequests = 10;
- for (int ix = numRequests; ix > 0; --ix) {
- requestStream.onNext(request);
- }
- requestStream.onCompleted();
- assertTrue(recorder.awaitCompletion(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS));
- assertSuccess(recorder);
- assertEquals(responseSizes.length * numRequests, recorder.getValues().size());
- for (int ix = 0; ix < recorder.getValues().size(); ++ix) {
- StreamingOutputCallResponse response = recorder.getValues().get(ix);
- assertEquals(Messages.PayloadType.COMPRESSABLE, response.payload.type);
- int length = response.payload.body.length;
- int expectedSize = responseSizes[ix % responseSizes.length];
- assertEquals("comparison failed at index " + ix, expectedSize, length);
- }
- }
-
- public void serverStreamingShouldBeFlowControlled() throws Exception {
- final StreamingOutputCallRequest request = new StreamingOutputCallRequest();
- request.responseType = Messages.PayloadType.COMPRESSABLE;
- request.responseParameters = new ResponseParameters[2];
- request.responseParameters[0] = new ResponseParameters();
- request.responseParameters[0].size = 100000;
- request.responseParameters[1] = new ResponseParameters();
- request.responseParameters[1].size = 100001;
- final StreamingOutputCallResponse[] goldenResponses = new StreamingOutputCallResponse[2];
- goldenResponses[0] = new StreamingOutputCallResponse();
- goldenResponses[0].payload = new Payload();
- goldenResponses[0].payload.type = Messages.PayloadType.COMPRESSABLE;
- goldenResponses[0].payload.body = new byte[100000];
- goldenResponses[1] = new StreamingOutputCallResponse();
- goldenResponses[1].payload = new Payload();
- goldenResponses[1].payload.type = Messages.PayloadType.COMPRESSABLE;
- goldenResponses[1].payload.body = new byte[100001];
-
- long start = System.nanoTime();
-
- final ArrayBlockingQueue<Object> queue = new ArrayBlockingQueue<Object>(10);
- ClientCall<StreamingOutputCallRequest, StreamingOutputCallResponse> call =
- channel.newCall(TestServiceGrpc.getStreamingOutputCallMethod(), CallOptions.DEFAULT);
- call.start(new ClientCall.Listener<StreamingOutputCallResponse>() {
- @Override
- public void onHeaders(Metadata headers) {}
-
- @Override
- public void onMessage(final StreamingOutputCallResponse message) {
- queue.add(message);
- }
-
- @Override
- public void onClose(io.grpc.Status status, Metadata trailers) {
- queue.add(status);
- }
- }, new Metadata());
- call.sendMessage(request);
- call.halfClose();
-
- // Time how long it takes to get the first response.
- call.request(1);
- assertMessageEquals(goldenResponses[0],
- (StreamingOutputCallResponse) queue.poll(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS));
- long firstCallDuration = System.nanoTime() - start;
-
- // Without giving additional flow control, make sure that we don't get another response. We wait
- // until we are comfortable the next message isn't coming. We may have very low nanoTime
- // resolution (like on Windows) or be using a testing, in-process transport where message
- // handling is instantaneous. In both cases, firstCallDuration may be 0, so round up sleep time
- // to at least 1ms.
- assertNull(queue.poll(Math.max(firstCallDuration * 4, 1 * 1000 * 1000), TimeUnit.NANOSECONDS));
-
- // Make sure that everything still completes.
- call.request(1);
- assertMessageEquals(goldenResponses[1],
- (StreamingOutputCallResponse) queue.poll(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS));
- assertCodeEquals(io.grpc.Status.OK,
- (io.grpc.Status) queue.poll(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS));
- }
-
- public void veryLargeRequest() throws Exception {
- if (shouldSkip()) {
- return;
- }
- final SimpleRequest request = new SimpleRequest();
- request.payload = new Payload();
- request.payload.type = Messages.PayloadType.COMPRESSABLE;
- request.payload.body = new byte[unaryPayloadLength()];
- request.responseSize = 10;
- request.responseType = Messages.PayloadType.COMPRESSABLE;
- final SimpleResponse goldenResponse = new SimpleResponse();
- goldenResponse.payload = new Payload();
- goldenResponse.payload.type = Messages.PayloadType.COMPRESSABLE;
- goldenResponse.payload.body = new byte[10];
-
- assertMessageEquals(goldenResponse, blockingStub.unaryCall(request));
- }
-
- public void veryLargeResponse() throws Exception {
- if (shouldSkip()) {
- return;
- }
- final SimpleRequest request = new SimpleRequest();
- request.responseSize = unaryPayloadLength();
- request.responseType = Messages.PayloadType.COMPRESSABLE;
-
- SimpleResponse resp = blockingStub.unaryCall(request);
- final SimpleResponse goldenResponse = new SimpleResponse();
- goldenResponse.payload = new Payload();
- goldenResponse.payload.type = Messages.PayloadType.COMPRESSABLE;
- goldenResponse.payload.body = new byte[unaryPayloadLength()];
-
- assertMessageSizeEquals(goldenResponse, resp);
- }
-
- public void deadlineNotExceeded() {
- // warm up the channel and JVM
- blockingStub.emptyCall(new EmptyProtos.Empty());
- StreamingOutputCallRequest request = new StreamingOutputCallRequest();
- request.responseParameters = new ResponseParameters[1];
- request.responseParameters[0] = new ResponseParameters();
- request.responseParameters[0].intervalUs = 0;
- TestServiceGrpc.newBlockingStub(channel)
- .withDeadlineAfter(10, TimeUnit.SECONDS)
- .streamingOutputCall(request);
- }
-
- public void deadlineExceeded() {
- // warm up the channel and JVM
- blockingStub.emptyCall(new EmptyProtos.Empty());
- TestServiceGrpc.TestServiceBlockingStub stub = TestServiceGrpc.newBlockingStub(channel)
- .withDeadlineAfter(10, TimeUnit.MILLISECONDS);
- StreamingOutputCallRequest request = new StreamingOutputCallRequest();
- request.responseParameters = new ResponseParameters[1];
- request.responseParameters[0] = new ResponseParameters();
- request.responseParameters[0].intervalUs = 20000;
- try {
- stub.streamingOutputCall(request).next();
- fail("Expected deadline to be exceeded");
- } catch (StatusRuntimeException ex) {
- assertCodeEquals(io.grpc.Status.DEADLINE_EXCEEDED, ex.getStatus());
- }
- }
-
- public void deadlineExceededServerStreaming() throws Exception {
- // warm up the channel and JVM
- blockingStub.emptyCall(new EmptyProtos.Empty());
- ResponseParameters responseParameters = new ResponseParameters();
- responseParameters.size = 1;
- responseParameters.intervalUs = 10000;
- StreamingOutputCallRequest request = new StreamingOutputCallRequest();
- request.responseType = Messages.PayloadType.COMPRESSABLE;
- request.responseParameters = new ResponseParameters[4];
- request.responseParameters[0] = responseParameters;
- request.responseParameters[1] = responseParameters;
- request.responseParameters[2] = responseParameters;
- request.responseParameters[3] = responseParameters;
- StreamRecorder<StreamingOutputCallResponse> recorder = StreamRecorder.create();
- TestServiceGrpc.newStub(channel)
- .withDeadlineAfter(30, TimeUnit.MILLISECONDS)
- .streamingOutputCall(request, recorder);
- assertTrue(recorder.awaitCompletion(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS));
- assertCodeEquals(io.grpc.Status.DEADLINE_EXCEEDED,
- io.grpc.Status.fromThrowable(recorder.getError()));
- }
-
- protected int unaryPayloadLength() {
- // 10MiB.
- return 10485760;
- }
-
- public void gracefulShutdown() throws Exception {
- StreamingOutputCallRequest[] requests = new StreamingOutputCallRequest[3];
- requests[0] = new StreamingOutputCallRequest();
- requests[0].responseParameters = new ResponseParameters[1];
- requests[0].responseParameters[0] = new ResponseParameters();
- requests[0].responseParameters[0].size = 3;
- requests[0].payload = new Payload();
- requests[0].payload.body = new byte[2];
- requests[1] = new StreamingOutputCallRequest();
- requests[1].responseParameters = new ResponseParameters[1];
- requests[1].responseParameters[0] = new ResponseParameters();
- requests[1].responseParameters[0].size = 1;
- requests[1].payload = new Payload();
- requests[1].payload.body = new byte[7];
- requests[2] = new StreamingOutputCallRequest();
- requests[2].responseParameters = new ResponseParameters[1];
- requests[2].responseParameters[0] = new ResponseParameters();
- requests[2].responseParameters[0].size = 4;
- requests[2].payload = new Payload();
- requests[2].payload.body = new byte[1];
-
- StreamingOutputCallResponse[] goldenResponses = new StreamingOutputCallResponse[3];
- goldenResponses[0] = new StreamingOutputCallResponse();
- goldenResponses[0].payload = new Payload();
- goldenResponses[0].payload.type = Messages.PayloadType.COMPRESSABLE;
- goldenResponses[0].payload.body = new byte[3];
- goldenResponses[1] = new StreamingOutputCallResponse();
- goldenResponses[1].payload = new Payload();
- goldenResponses[1].payload.type = Messages.PayloadType.COMPRESSABLE;
- goldenResponses[1].payload.body = new byte[1];
- goldenResponses[2] = new StreamingOutputCallResponse();
- goldenResponses[2].payload = new Payload();
- goldenResponses[2].payload.type = Messages.PayloadType.COMPRESSABLE;
- goldenResponses[2].payload.body = new byte[4];
-
-
- ResponseObserver responseObserver = new ResponseObserver();
- StreamObserver<StreamingOutputCallRequest> requestObserver
- = asyncStub.fullDuplexCall(responseObserver);
- requestObserver.onNext(requests[0]);
- Object response = responseObserver.responses.poll(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
- assertTrue(response instanceof Messages.StreamingOutputCallResponse);
- assertMessageEquals(goldenResponses[0], (Messages.StreamingOutputCallResponse) response);
- // Initiate graceful shutdown.
- channel.shutdown();
- // The previous ping-pong could have raced with the shutdown, but this one certainly shouldn't.
- requestObserver.onNext(requests[1]);
- response = responseObserver.responses.poll(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
- assertTrue(response instanceof Messages.StreamingOutputCallResponse);
- assertMessageEquals(goldenResponses[1], (Messages.StreamingOutputCallResponse) response);
- requestObserver.onNext(requests[2]);
- response = responseObserver.responses.poll(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS);
- assertTrue(response instanceof Messages.StreamingOutputCallResponse);
- assertMessageEquals(goldenResponses[2], (Messages.StreamingOutputCallResponse) response);
- requestObserver.onCompleted();
- assertEquals(responseObserver.magicTailResponse,
- responseObserver.responses.poll(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS));
- }
-
- /** Sends an rpc to an unimplemented method on the server. */
- public void unimplementedMethod() {
- UnimplementedServiceGrpc.UnimplementedServiceBlockingStub stub =
- UnimplementedServiceGrpc.newBlockingStub(channel);
- try {
- stub.unimplementedCall(new EmptyProtos.Empty());
- fail();
- } catch (StatusRuntimeException e) {
- assertCodeEquals(io.grpc.Status.UNIMPLEMENTED, e.getStatus());
- }
- }
-
- /** Start a fullDuplexCall which the server will not respond, and verify the deadline expires. */
- public void timeoutOnSleepingServer() throws Exception {
- TestServiceGrpc.TestServiceStub stub = TestServiceGrpc.newStub(channel)
- .withDeadlineAfter(1, TimeUnit.MILLISECONDS);
- StreamRecorder<StreamingOutputCallResponse> recorder = StreamRecorder.create();
- StreamObserver<StreamingOutputCallRequest> requestObserver
- = stub.fullDuplexCall(recorder);
-
- try {
- StreamingOutputCallRequest request = new StreamingOutputCallRequest();
- request.payload = new Messages.Payload();
- request.payload.body = new byte[27182];
- requestObserver.onNext(request);
- } catch (IllegalStateException expected) {
- // This can happen if the stream has already been terminated due to deadline exceeded.
- }
-
- assertTrue(recorder.awaitCompletion(TIMEOUT_MILLIS, TimeUnit.MILLISECONDS));
- assertCodeEquals(io.grpc.Status.DEADLINE_EXCEEDED,
- io.grpc.Status.fromThrowable(recorder.getError()));
- }
-
- public static void assertMessageSizeEquals(MessageNano expected, MessageNano actual) {
- assertEquals(expected.getSerializedSize(), actual.getSerializedSize());
- }
-
-
- private static void assertSuccess(StreamRecorder<?> recorder) {
- if (recorder.getError() != null) {
- throw new AssertionError(recorder.getError());
- }
- }
-
- public static void assertMessageEquals(MessageNano expected, MessageNano actual) {
- if (!MessageNano.messageNanoEquals(expected, actual)) {
- assertEquals(expected.toString(), actual.toString());
- fail("Messages not equal, but assertEquals didn't throw");
- }
- }
-
- public static void assertMessageEquals(List<? extends MessageNano> expected,
- List<? extends MessageNano> actual) {
- if (expected == null || actual == null) {
- assertEquals(expected, actual);
- } else if (expected.size() != actual.size()) {
- assertEquals(expected, actual);
- } else {
- for (int i = 0; i < expected.size(); i++) {
- assertMessageEquals(expected.get(i), actual.get(i));
- }
- }
- }
-
- private static void assertCodeEquals(io.grpc.Status expected, io.grpc.Status actual) {
- if (expected == null) {
- fail("expected should not be null");
- }
- if (actual == null || !expected.getCode().equals(actual.getCode())) {
- assertEquals(expected, actual);
- }
- }
-
- public interface TestListener {
- void onPreTest();
-
- void onPostTest(String result);
- }
-
- /**
- * Some tests run on memory constrained environments. Rather than OOM, just give up. 64 is
- * choosen as a maximum amount of memory a large test would need.
- */
- private static boolean shouldSkip() {
- Runtime r = Runtime.getRuntime();
- long usedMem = r.totalMemory() - r.freeMemory();
- long actuallyFreeMemory = r.maxMemory() - usedMem;
- long wantedFreeMemory = 64 * 1024 * 1024;
- if (actuallyFreeMemory < wantedFreeMemory) {
- Log.i(LOG_TAG, "Skipping due to lack of memory. "
- + "Have: " + actuallyFreeMemory + " Want: " + wantedFreeMemory);
- return true;
- }
- return false;
- }
-
- private static final class SafeMethodChannelInterceptor implements ClientInterceptor {
- @Override
- public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
- MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, Channel next) {
- return new CheckedForwardingClientCall<ReqT, RespT>(
- next.newCall(method.toBuilder().setSafe(true).build(), callOptions)) {
- @Override
- public void checkedStart(Listener<RespT> responseListener, Metadata headers) {
- delegate().start(responseListener, headers);
- }
- };
- }
- }
-}
diff --git a/android-interop-testing/app/src/main/java/io/grpc/android/integrationtest/TesterActivity.java b/android-interop-testing/app/src/main/java/io/grpc/android/integrationtest/TesterActivity.java
index 02013a7e1..cbf63e3ca 100644
--- a/android-interop-testing/app/src/main/java/io/grpc/android/integrationtest/TesterActivity.java
+++ b/android-interop-testing/app/src/main/java/io/grpc/android/integrationtest/TesterActivity.java
@@ -29,16 +29,29 @@ import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.TextView;
import com.google.android.gms.security.ProviderInstaller;
+import io.grpc.CallOptions;
+import io.grpc.Channel;
+import io.grpc.ClientCall;
+import io.grpc.ClientInterceptor;
+import io.grpc.ClientInterceptors.CheckedForwardingClientCall;
+import io.grpc.ManagedChannel;
+import io.grpc.Metadata;
+import io.grpc.MethodDescriptor;
+import java.io.InputStream;
+import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
public class TesterActivity extends AppCompatActivity
- implements ProviderInstaller.ProviderInstallListener {
+ implements ProviderInstaller.ProviderInstallListener, InteropTask.Listener {
+ private static final String LOG_TAG = "GrpcTesterActivity";
+
private List<Button> buttons;
private EditText hostEdit;
private EditText portEdit;
private TextView resultText;
private CheckBox getCheckBox;
+ private CheckBox testCertCheckBox;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -55,6 +68,7 @@ public class TesterActivity extends AppCompatActivity
portEdit = (EditText) findViewById(R.id.port_edit_text);
resultText = (TextView) findViewById(R.id.grpc_response_text);
getCheckBox = (CheckBox) findViewById(R.id.get_checkbox);
+ testCertCheckBox = (CheckBox) findViewById(R.id.test_cert_checkbox);
ProviderInstaller.installIfNeededAsync(this, this);
// Disable buttons until the security provider installing finishes.
@@ -87,28 +101,39 @@ public class TesterActivity extends AppCompatActivity
}
}
+ @Override
+ public void onComplete(String result) {
+ resultText.setText(result);
+ enableButtons(true);
+ }
+
private void startTest(String testCase) {
((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(
hostEdit.getWindowToken(), 0);
enableButtons(false);
+ resultText.setText("Testing...");
+
String host = hostEdit.getText().toString();
String portStr = portEdit.getText().toString();
int port = TextUtils.isEmpty(portStr) ? 8080 : Integer.valueOf(portStr);
- // TODO (madongfly) support server_host_override, useTls and useTestCa in the App UI.
- new InteropTester(testCase,
- TesterOkHttpChannelBuilder.build(host, port, "foo.test.google.fr", true,
- getResources().openRawResource(R.raw.ca), null),
- new InteropTester.TestListener() {
- @Override public void onPreTest() {
- resultText.setText("Testing...");
- }
-
- @Override public void onPostTest(String result) {
- resultText.setText(result);
- enableButtons(true);
- }
- }, getCheckBox.isChecked()).execute();
+ String serverHostOverride;
+ InputStream testCert;
+ if (testCertCheckBox.isChecked()) {
+ serverHostOverride = "foo.test.google.fr";
+ testCert = getResources().openRawResource(R.raw.ca);
+ } else {
+ serverHostOverride = null;
+ testCert = null;
+ }
+ ManagedChannel channel =
+ TesterOkHttpChannelBuilder.build(host, port, serverHostOverride, true, testCert);
+
+ List<ClientInterceptor> interceptors = new ArrayList<ClientInterceptor>();
+ if (getCheckBox.isChecked()) {
+ interceptors.add(new SafeMethodChannelInterceptor());
+ }
+ new InteropTask(this, channel, interceptors, testCase).execute();
}
@Override
@@ -121,7 +146,21 @@ public class TesterActivity extends AppCompatActivity
public void onProviderInstallFailed(int errorCode, Intent recoveryIntent) {
// The provider is helpful, but it is possible to succeed without it.
// Hope that the system-provided libraries are new enough.
- Log.w(InteropTester.LOG_TAG, "Failed installing security provider, error code: " + errorCode);
+ Log.w(LOG_TAG, "Failed installing security provider, error code: " + errorCode);
enableButtons(true);
}
+
+ private static final class SafeMethodChannelInterceptor implements ClientInterceptor {
+ @Override
+ public <ReqT, RespT> ClientCall<ReqT, RespT> interceptCall(
+ MethodDescriptor<ReqT, RespT> method, CallOptions callOptions, Channel next) {
+ return new CheckedForwardingClientCall<ReqT, RespT>(
+ next.newCall(method.toBuilder().setSafe(true).build(), callOptions)) {
+ @Override
+ public void checkedStart(Listener<RespT> responseListener, Metadata headers) {
+ delegate().start(responseListener, headers);
+ }
+ };
+ }
+ }
}
diff --git a/android-interop-testing/app/src/main/java/io/grpc/android/integrationtest/TesterInstrumentation.java b/android-interop-testing/app/src/main/java/io/grpc/android/integrationtest/TesterInstrumentation.java
deleted file mode 100644
index c17bbed0b..000000000
--- a/android-interop-testing/app/src/main/java/io/grpc/android/integrationtest/TesterInstrumentation.java
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Copyright 2015 The gRPC Authors
- *
- * 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
- *
- * http://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 io.grpc.android.integrationtest;
-
-import android.app.Activity;
-import android.app.Instrumentation;
-import android.os.Bundle;
-import android.util.Log;
-import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
-import com.google.android.gms.common.GooglePlayServicesRepairableException;
-import com.google.android.gms.security.ProviderInstaller;
-import java.io.InputStream;
-import java.lang.Throwable;
-
-
-/**
- * The instrumentation used to run the interop test from command line.
- */
-public class TesterInstrumentation extends Instrumentation {
- private String testCase;
- private String host;
- private int port;
- private String serverHostOverride;
- private boolean useTls;
- private boolean useTestCa;
- private String androidSocketFactoryTls;
- private boolean useGet;
-
- @Override
- public void onCreate(Bundle args) {
- super.onCreate(args);
-
- testCase = args.getString("test_case") != null ? args.getString("test_case") : "empty_unary";
- host = args.getString("server_host");
- port = Integer.parseInt(args.getString("server_port"));
- serverHostOverride = args.getString("server_host_override");
- useTls = args.getString("use_tls") != null
- ? Boolean.parseBoolean(args.getString("use_tls")) : true;
- useTestCa = args.getString("use_test_ca") != null
- ? Boolean.parseBoolean(args.getString("use_test_ca")) : false;
- androidSocketFactoryTls = args.getString("android_socket_factory_tls");
- useGet = args.getString("use_get") != null
- ? Boolean.parseBoolean(args.getString("use_get")) : false;
-
- InputStream testCa = null;
- if (useTestCa) {
- testCa = getContext().getResources().openRawResource(R.raw.ca);
- }
-
- if (useTls) {
- try {
- ProviderInstaller.installIfNeeded(getContext());
- } catch (GooglePlayServicesRepairableException e) {
- // The provider is helpful, but it is possible to succeed without it.
- // Hope that the system-provided libraries are new enough.
- Log.w(InteropTester.LOG_TAG, "Failed installing security provider", e);
- } catch (GooglePlayServicesNotAvailableException e) {
- // The provider is helpful, but it is possible to succeed without it.
- // Hope that the system-provided libraries are new enough.
- Log.w(InteropTester.LOG_TAG, "Failed installing security provider", e);
- }
- }
-
- try {
- new InteropTester(testCase,
- TesterOkHttpChannelBuilder.build(host, port, serverHostOverride, useTls, testCa,
- androidSocketFactoryTls),
- new InteropTester.TestListener() {
- @Override
- public void onPreTest() {
- }
-
- @Override
- public void onPostTest(String result) {
- Bundle bundle = new Bundle();
- bundle.putString("grpc test result", result);
- if (InteropTester.SUCCESS_MESSAGE.equals(result)) {
- finish(Activity.RESULT_OK, bundle);
- } else {
- finish(Activity.RESULT_CANCELED, bundle);
- }
- }
- },
- useGet).execute();
- } catch (Throwable t) {
- Bundle bundle = new Bundle();
- bundle.putString("Exception encountered", t.toString());
- finish(Activity.RESULT_CANCELED, bundle);
- }
- }
-}
diff --git a/android-interop-testing/app/src/main/java/io/grpc/android/integrationtest/TesterOkHttpChannelBuilder.java b/android-interop-testing/app/src/main/java/io/grpc/android/integrationtest/TesterOkHttpChannelBuilder.java
index bd719788c..e537eb778 100644
--- a/android-interop-testing/app/src/main/java/io/grpc/android/integrationtest/TesterOkHttpChannelBuilder.java
+++ b/android-interop-testing/app/src/main/java/io/grpc/android/integrationtest/TesterOkHttpChannelBuilder.java
@@ -20,18 +20,14 @@ import android.annotation.TargetApi;
import android.net.SSLCertificateSocketFactory;
import android.os.Build;
import android.support.annotation.Nullable;
-
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
-import io.grpc.okhttp.NegotiationType;
import io.grpc.okhttp.OkHttpChannelBuilder;
-
import java.io.InputStream;
import java.lang.reflect.Method;
import java.security.KeyStore;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
-
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
@@ -42,8 +38,12 @@ import javax.security.auth.x500.X500Principal;
* A helper class to create a OkHttp based channel.
*/
class TesterOkHttpChannelBuilder {
- public static ManagedChannel build(String host, int port, @Nullable String serverHostOverride,
- boolean useTls, @Nullable InputStream testCa, @Nullable String androidSocketFactoryTls) {
+ public static ManagedChannel build(
+ String host,
+ int port,
+ @Nullable String serverHostOverride,
+ boolean useTls,
+ @Nullable InputStream testCa) {
ManagedChannelBuilder<?> channelBuilder = ManagedChannelBuilder.forAddress(host, port)
.maxInboundMessageSize(16 * 1024 * 1024);
if (serverHostOverride != null) {
@@ -52,14 +52,8 @@ class TesterOkHttpChannelBuilder {
}
if (useTls) {
try {
- SSLSocketFactory factory;
- if (androidSocketFactoryTls != null) {
- factory = getSslCertificateSocketFactory(testCa, androidSocketFactoryTls);
- } else {
- factory = getSslSocketFactory(testCa);
- }
- ((OkHttpChannelBuilder) channelBuilder).negotiationType(NegotiationType.TLS);
- ((OkHttpChannelBuilder) channelBuilder).sslSocketFactory(factory);
+ ((OkHttpChannelBuilder) channelBuilder).useTransportSecurity();
+ ((OkHttpChannelBuilder) channelBuilder).sslSocketFactory(getSslSocketFactory(testCa));
} catch (Exception e) {
throw new RuntimeException(e);
}
diff --git a/android-interop-testing/app/src/main/proto/grpc/testing/empty.proto b/android-interop-testing/app/src/main/proto/grpc/testing/empty.proto
deleted file mode 100644
index a5c9dc619..000000000
--- a/android-interop-testing/app/src/main/proto/grpc/testing/empty.proto
+++ /dev/null
@@ -1,30 +0,0 @@
-
-// Copyright 2015 The gRPC Authors
-//
-// 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
-//
-// http://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.
-syntax = "proto2";
-
-package grpc.testing;
-
-option java_package = "com.google.protobuf";
-option java_outer_classname = "EmptyProtos";
-
-// An empty message that you can re-use to avoid defining duplicated empty
-// messages in your project. A typical example is to use it as argument or the
-// return value of a service API. For instance:
-//
-// service Foo {
-// rpc Bar (grpc.testing.Empty) returns (grpc.testing.Empty) { };
-// };
-//
-message Empty {}
diff --git a/android-interop-testing/app/src/main/proto/grpc/testing/messages.proto b/android-interop-testing/app/src/main/proto/grpc/testing/messages.proto
deleted file mode 100644
index 64a10f4f7..000000000
--- a/android-interop-testing/app/src/main/proto/grpc/testing/messages.proto
+++ /dev/null
@@ -1,122 +0,0 @@
-
-// Copyright 2015 The gRPC Authors
-//
-// 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
-//
-// http://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.
-// Message definitions to be used by integration test service definitions.
-
-syntax = "proto3";
-
-package grpc.testing;
-
-option java_package = "io.grpc.android.integrationtest";
-
-// The type of payload that should be returned.
-enum PayloadType {
- // Compressable text format.
- COMPRESSABLE = 0;
-
- // Uncompressable binary format.
- UNCOMPRESSABLE = 1;
-
- // Randomly chosen from all other formats defined in this enum.
- RANDOM = 2;
-}
-
-// A block of data, to simply increase gRPC message size.
-message Payload {
- // The type of data in body.
- PayloadType type = 1;
- // Primary contents of payload.
- bytes body = 2;
-}
-
-// Unary request.
-message SimpleRequest {
- // Desired payload type in the response from the server.
- // If response_type is RANDOM, server randomly chooses one from other formats.
- PayloadType response_type = 1;
-
- // Desired payload size in the response from the server.
- // If response_type is COMPRESSABLE, this denotes the size before compression.
- int32 response_size = 2;
-
- // Optional input payload sent along with the request.
- Payload payload = 3;
-
- // Whether SimpleResponse should include username.
- bool fill_username = 4;
-
- // Whether SimpleResponse should include OAuth scope.
- bool fill_oauth_scope = 5;
-}
-
-// Unary response, as configured by the request.
-message SimpleResponse {
- // Payload to increase message size.
- Payload payload = 1;
- // The user the request came from, for verifying authentication was
- // successful when the client expected it.
- string username = 2;
- // OAuth scope.
- string oauth_scope = 3;
-}
-
-message SimpleContext {
- string value = 1;
-}
-
-// Client-streaming request.
-message StreamingInputCallRequest {
- // Optional input payload sent along with the request.
- Payload payload = 1;
-
- // Not expecting any payload from the response.
-}
-
-// Client-streaming response.
-message StreamingInputCallResponse {
- // Aggregated size of payloads received from the client.
- int32 aggregated_payload_size = 1;
-}
-
-// Configuration for a particular response.
-message ResponseParameters {
- // Desired payload sizes in responses from the server.
- // If response_type is COMPRESSABLE, this denotes the size before compression.
- int32 size = 1;
-
- // Desired interval between consecutive responses in the response stream in
- // microseconds.
- int32 interval_us = 2;
-}
-
-// Server-streaming request.
-message StreamingOutputCallRequest {
- // Desired payload type in the response from the server.
- // If response_type is RANDOM, the payload from each response in the stream
- // might be of different types. This is to simulate a mixed type of payload
- // stream.
- PayloadType response_type = 1;
-
- // Configuration for each expected response message.
- repeated ResponseParameters response_parameters = 2;
-
- // Optional input payload sent along with the request.
- Payload payload = 3;
-}
-
-// Server-streaming response, as configured by the request and parameters.
-message StreamingOutputCallResponse {
- // Payload to increase response size.
- Payload payload = 1;
-}
diff --git a/android-interop-testing/app/src/main/proto/grpc/testing/test.proto b/android-interop-testing/app/src/main/proto/grpc/testing/test.proto
deleted file mode 100644
index 45871ed77..000000000
--- a/android-interop-testing/app/src/main/proto/grpc/testing/test.proto
+++ /dev/null
@@ -1,64 +0,0 @@
-
-// Copyright 2015 The gRPC Authors
-//
-// 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
-//
-// http://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.
-// An integration test service that covers all the method signature permutations
-// of unary/streaming requests/responses.
-syntax = "proto3";
-
-import "grpc/testing/empty.proto";
-import "grpc/testing/messages.proto";
-
-package grpc.testing;
-
-option java_package = "io.grpc.android.integrationtest";
-
-// A simple service to test the various types of RPCs and experiment with
-// performance with various types of payload.
-service TestService {
- // One empty request followed by one empty response.
- rpc EmptyCall(grpc.testing.Empty) returns (grpc.testing.Empty);
-
- // One request followed by one response.
- rpc UnaryCall(SimpleRequest) returns (SimpleResponse);
-
- // One request followed by a sequence of responses (streamed download).
- // The server returns the payload with client desired type and sizes.
- rpc StreamingOutputCall(StreamingOutputCallRequest)
- returns (stream StreamingOutputCallResponse);
-
- // A sequence of requests followed by one response (streamed upload).
- // The server returns the aggregated size of client payload as the result.
- rpc StreamingInputCall(stream StreamingInputCallRequest)
- returns (StreamingInputCallResponse);
-
- // A sequence of requests with each request served by the server immediately.
- // As one request could lead to multiple responses, this interface
- // demonstrates the idea of full duplexing.
- rpc FullDuplexCall(stream StreamingOutputCallRequest)
- returns (stream StreamingOutputCallResponse);
-
- // A sequence of requests followed by a sequence of responses.
- // The server buffers all the client requests and then serves them in order. A
- // stream of responses are returned to the client when the server starts with
- // first request.
- rpc HalfDuplexCall(stream StreamingOutputCallRequest)
- returns (stream StreamingOutputCallResponse);
-}
-
-// A simple service NOT implemented at servers so clients can test for
-// that case.
-service UnimplementedService {
- // A call that no server should implement
- rpc UnimplementedCall(grpc.testing.Empty) returns(grpc.testing.Empty);
-}
diff --git a/android-interop-testing/app/src/main/res/layout/activity_tester.xml b/android-interop-testing/app/src/main/res/layout/activity_tester.xml
index c7cef73b3..1fd55dd83 100644
--- a/android-interop-testing/app/src/main/res/layout/activity_tester.xml
+++ b/android-interop-testing/app/src/main/res/layout/activity_tester.xml
@@ -26,11 +26,23 @@
android:inputType="numberDecimal"
android:hint="Enter Port"
/>
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ >
<CheckBox android:id="@+id/get_checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/use_get"
/>
+ <CheckBox android:id="@+id/test_cert_checkbox"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Use Test Cert"
+ />
</LinearLayout>
<Button
diff --git a/android-interop-testing/build.gradle b/android-interop-testing/build.gradle
index a0baaceb9..5017248dd 100644
--- a/android-interop-testing/build.gradle
+++ b/android-interop-testing/build.gradle
@@ -6,8 +6,8 @@ buildscript {
google()
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.0.1'
- classpath "com.google.protobuf:protobuf-gradle-plugin:0.8.3"
+ classpath 'com.android.tools.build:gradle:3.1.2'
+ classpath "com.google.protobuf:protobuf-gradle-plugin:0.8.5"
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files