From f88779e4220bfd5ef19979e511f07719af8b1891 Mon Sep 17 00:00:00 2001 From: Xudong Ma Date: Wed, 10 Jun 2015 17:36:55 -0700 Subject: [PATCH] Add the Android interop test App. So far, it is built separately from the other gRpc components. --- .gitignore | 1 + android-interop-testing/README.md | 46 + android-interop-testing/app/build.gradle | 34 + .../app/proguard-rules.pro | 17 + .../app/src/main/AndroidManifest.xml | 32 + .../android/integrationtest/EmptyProtos.java | 64 ++ .../android/integrationtest/Messages.java | 980 ++++++++++++++++++ .../integrationtest/TestServiceGrpc.java | 457 ++++++++ .../integrationtest/InteropTester.java | 350 +++++++ .../integrationtest/TesterActivity.java | 141 +++ .../TesterInstrumentation.java | 104 ++ .../src/main/res/layout/activity_tester.xml | 98 ++ .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 3418 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 2206 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 4842 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 7718 bytes .../app/src/main/res/raw/ca.pem | 15 + .../app/src/main/res/values/strings.xml | 3 + android-interop-testing/build.gradle | 20 + android-interop-testing/settings.gradle | 1 + android-interop-testing/start-emulator.sh | 13 + android-interop-testing/wait-for-emulator.sh | 16 + 22 files changed, 2392 insertions(+) create mode 100644 android-interop-testing/README.md create mode 100644 android-interop-testing/app/build.gradle create mode 100644 android-interop-testing/app/proguard-rules.pro create mode 100644 android-interop-testing/app/src/main/AndroidManifest.xml create mode 100644 android-interop-testing/app/src/main/java/generated/io/grpc/android/integrationtest/EmptyProtos.java create mode 100644 android-interop-testing/app/src/main/java/generated/io/grpc/android/integrationtest/Messages.java create mode 100644 android-interop-testing/app/src/main/java/generated/io/grpc/android/integrationtest/TestServiceGrpc.java create mode 100644 android-interop-testing/app/src/main/java/io/grpc/android/integrationtest/InteropTester.java create mode 100644 android-interop-testing/app/src/main/java/io/grpc/android/integrationtest/TesterActivity.java create mode 100644 android-interop-testing/app/src/main/java/io/grpc/android/integrationtest/TesterInstrumentation.java create mode 100644 android-interop-testing/app/src/main/res/layout/activity_tester.xml create mode 100644 android-interop-testing/app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 android-interop-testing/app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 android-interop-testing/app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 android-interop-testing/app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 android-interop-testing/app/src/main/res/raw/ca.pem create mode 100644 android-interop-testing/app/src/main/res/values/strings.xml create mode 100644 android-interop-testing/build.gradle create mode 100644 android-interop-testing/settings.gradle create mode 100755 android-interop-testing/start-emulator.sh create mode 100755 android-interop-testing/wait-for-emulator.sh diff --git a/.gitignore b/.gitignore index 89e2e50d39..e47cc81484 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ build gradle.properties .gradle +local.properties # IntelliJ IDEA .idea diff --git a/android-interop-testing/README.md b/android-interop-testing/README.md new file mode 100644 index 0000000000..47cc5066ab --- /dev/null +++ b/android-interop-testing/README.md @@ -0,0 +1,46 @@ +gRPC Android test App +======================= + +Implements gRPC integration tests in an Android App. + +TODO(madongfly) integrate this App into the gRPC-Java build system. + +In order to build this app, you need a local.properties file under this directory which specifies +the location of your android sdk: +``` +sdk.dir=/somepath/somepath/sdk +``` + +Connect your Android device or start the emulator: +``` +$ ./start-emulator.sh & ./wait-for-emulator.sh +``` + +Manually test +------------- + +Install the App by: +``` +$ ../gradlew installDebug +``` +Then manually test it with the UI. + + +Commandline test +---------------- + +Run the test with arguments: +``` +$ adb shell am instrument -w -e server_host -e server_port 8030 -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 +``` + +If the test passed successfully, it will output: +``` +INSTRUMENTATION_RESULT: grpc test result=Succeed!!! +INSTRUMENTATION_CODE: 0 +``` +otherwise, output something like: +``` +INSTRUMENTATION_RESULT: grpc test result=Failed... : +INSTRUMENTATION_CODE: 1 +``` diff --git a/android-interop-testing/app/build.gradle b/android-interop-testing/app/build.gradle new file mode 100644 index 0000000000..3a6f85dfac --- /dev/null +++ b/android-interop-testing/app/build.gradle @@ -0,0 +1,34 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 22 + buildToolsVersion '22.0.1' + + defaultConfig { + applicationId "io.grpc.android.integrationtest" + minSdkVersion 18 + targetSdkVersion 22 + versionCode 1 + versionName "1.0" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + compile 'com.android.support:appcompat-v7:22.1.1' + compile 'com.google.android.gms:play-services-base:7.3.0' + compile 'com.google.code.findbugs:jsr305:3.0.0' + compile 'com.google.guava:guava:18.0' + compile 'com.squareup.okhttp:okhttp:2.2.0' + testCompile 'junit:junit:4.12' + // You need to build grpc-java to obtain these libraries below. + compile 'io.grpc:grpc-core:0.8.0-SNAPSHOT' + compile 'io.grpc:grpc-protobuf-nano:0.8.0-SNAPSHOT' + compile 'io.grpc:grpc-okhttp:0.8.0-SNAPSHOT' + compile 'io.grpc:grpc-stub:0.8.0-SNAPSHOT' +} diff --git a/android-interop-testing/app/proguard-rules.pro b/android-interop-testing/app/proguard-rules.pro new file mode 100644 index 0000000000..3e659b91f3 --- /dev/null +++ b/android-interop-testing/app/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /Users/thagikura/android-sdk/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/android-interop-testing/app/src/main/AndroidManifest.xml b/android-interop-testing/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000000..8bb746cb31 --- /dev/null +++ b/android-interop-testing/app/src/main/AndroidManifest.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/android-interop-testing/app/src/main/java/generated/io/grpc/android/integrationtest/EmptyProtos.java b/android-interop-testing/app/src/main/java/generated/io/grpc/android/integrationtest/EmptyProtos.java new file mode 100644 index 0000000000..7c482e7439 --- /dev/null +++ b/android-interop-testing/app/src/main/java/generated/io/grpc/android/integrationtest/EmptyProtos.java @@ -0,0 +1,64 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! + +package io.grpc.android.integrationtest; + +@SuppressWarnings("hiding") +public interface EmptyProtos { + + public static final class Empty extends + com.google.protobuf.nano.MessageNano { + + private static volatile Empty[] _emptyArray; + public static Empty[] emptyArray() { + // Lazily initializes the empty array + if (_emptyArray == null) { + synchronized ( + com.google.protobuf.nano.InternalNano.LAZY_INIT_LOCK) { + if (_emptyArray == null) { + _emptyArray = new Empty[0]; + } + } + } + return _emptyArray; + } + + public Empty() { + clear(); + } + + public Empty clear() { + cachedSize = -1; + return this; + } + + @Override + public Empty mergeFrom( + com.google.protobuf.nano.CodedInputByteBufferNano input) + throws java.io.IOException { + while (true) { + int tag = input.readTag(); + switch (tag) { + case 0: + return this; + default: { + if (!com.google.protobuf.nano.WireFormatNano.parseUnknownField(input, tag)) { + return this; + } + break; + } + } + } + } + + public static Empty parseFrom(byte[] data) + throws com.google.protobuf.nano.InvalidProtocolBufferNanoException { + return com.google.protobuf.nano.MessageNano.mergeFrom(new Empty(), data); + } + + public static Empty parseFrom( + com.google.protobuf.nano.CodedInputByteBufferNano input) + throws java.io.IOException { + return new Empty().mergeFrom(input); + } + } +} diff --git a/android-interop-testing/app/src/main/java/generated/io/grpc/android/integrationtest/Messages.java b/android-interop-testing/app/src/main/java/generated/io/grpc/android/integrationtest/Messages.java new file mode 100644 index 0000000000..f0ecfc0e0a --- /dev/null +++ b/android-interop-testing/app/src/main/java/generated/io/grpc/android/integrationtest/Messages.java @@ -0,0 +1,980 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! + +package io.grpc.android.integrationtest; + +@SuppressWarnings("hiding") +public interface Messages { + + // enum PayloadType + public static final int COMPRESSABLE = 0; + public static final int UNCOMPRESSABLE = 1; + public static final int RANDOM = 2; + + public static final class Payload extends + com.google.protobuf.nano.MessageNano { + + private static volatile Payload[] _emptyArray; + public static Payload[] emptyArray() { + // Lazily initializes the empty array + if (_emptyArray == null) { + synchronized ( + com.google.protobuf.nano.InternalNano.LAZY_INIT_LOCK) { + if (_emptyArray == null) { + _emptyArray = new Payload[0]; + } + } + } + return _emptyArray; + } + + // optional .grpc.testing.PayloadType type = 1; + public int type; + + // optional bytes body = 2; + public byte[] body; + + public Payload() { + clear(); + } + + public Payload clear() { + type = io.grpc.android.integrationtest.Messages.COMPRESSABLE; + body = com.google.protobuf.nano.WireFormatNano.EMPTY_BYTES; + cachedSize = -1; + return this; + } + + @Override + public void writeTo(com.google.protobuf.nano.CodedOutputByteBufferNano output) + throws java.io.IOException { + if (this.type != io.grpc.android.integrationtest.Messages.COMPRESSABLE) { + output.writeInt32(1, this.type); + } + if (!java.util.Arrays.equals(this.body, com.google.protobuf.nano.WireFormatNano.EMPTY_BYTES)) { + output.writeBytes(2, this.body); + } + super.writeTo(output); + } + + @Override + protected int computeSerializedSize() { + int size = super.computeSerializedSize(); + if (this.type != io.grpc.android.integrationtest.Messages.COMPRESSABLE) { + size += com.google.protobuf.nano.CodedOutputByteBufferNano + .computeInt32Size(1, this.type); + } + if (!java.util.Arrays.equals(this.body, com.google.protobuf.nano.WireFormatNano.EMPTY_BYTES)) { + size += com.google.protobuf.nano.CodedOutputByteBufferNano + .computeBytesSize(2, this.body); + } + return size; + } + + @Override + public Payload mergeFrom( + com.google.protobuf.nano.CodedInputByteBufferNano input) + throws java.io.IOException { + while (true) { + int tag = input.readTag(); + switch (tag) { + case 0: + return this; + default: { + if (!com.google.protobuf.nano.WireFormatNano.parseUnknownField(input, tag)) { + return this; + } + break; + } + case 8: { + int value = input.readInt32(); + switch (value) { + case io.grpc.android.integrationtest.Messages.COMPRESSABLE: + case io.grpc.android.integrationtest.Messages.UNCOMPRESSABLE: + case io.grpc.android.integrationtest.Messages.RANDOM: + this.type = value; + break; + } + break; + } + case 18: { + this.body = input.readBytes(); + break; + } + } + } + } + + public static Payload parseFrom(byte[] data) + throws com.google.protobuf.nano.InvalidProtocolBufferNanoException { + return com.google.protobuf.nano.MessageNano.mergeFrom(new Payload(), data); + } + + public static Payload parseFrom( + com.google.protobuf.nano.CodedInputByteBufferNano input) + throws java.io.IOException { + return new Payload().mergeFrom(input); + } + } + + public static final class SimpleRequest extends + com.google.protobuf.nano.MessageNano { + + private static volatile SimpleRequest[] _emptyArray; + public static SimpleRequest[] emptyArray() { + // Lazily initializes the empty array + if (_emptyArray == null) { + synchronized ( + com.google.protobuf.nano.InternalNano.LAZY_INIT_LOCK) { + if (_emptyArray == null) { + _emptyArray = new SimpleRequest[0]; + } + } + } + return _emptyArray; + } + + // optional .grpc.testing.PayloadType response_type = 1; + public int responseType; + + // optional int32 response_size = 2; + public int responseSize; + + // optional .grpc.testing.Payload payload = 3; + public io.grpc.android.integrationtest.Messages.Payload payload; + + // optional bool fill_username = 4; + public boolean fillUsername; + + // optional bool fill_oauth_scope = 5; + public boolean fillOauthScope; + + public SimpleRequest() { + clear(); + } + + public SimpleRequest clear() { + responseType = io.grpc.android.integrationtest.Messages.COMPRESSABLE; + responseSize = 0; + payload = null; + fillUsername = false; + fillOauthScope = false; + cachedSize = -1; + return this; + } + + @Override + public void writeTo(com.google.protobuf.nano.CodedOutputByteBufferNano output) + throws java.io.IOException { + if (this.responseType != io.grpc.android.integrationtest.Messages.COMPRESSABLE) { + output.writeInt32(1, this.responseType); + } + if (this.responseSize != 0) { + output.writeInt32(2, this.responseSize); + } + if (this.payload != null) { + output.writeMessage(3, this.payload); + } + if (this.fillUsername != false) { + output.writeBool(4, this.fillUsername); + } + if (this.fillOauthScope != false) { + output.writeBool(5, this.fillOauthScope); + } + super.writeTo(output); + } + + @Override + protected int computeSerializedSize() { + int size = super.computeSerializedSize(); + if (this.responseType != io.grpc.android.integrationtest.Messages.COMPRESSABLE) { + size += com.google.protobuf.nano.CodedOutputByteBufferNano + .computeInt32Size(1, this.responseType); + } + if (this.responseSize != 0) { + size += com.google.protobuf.nano.CodedOutputByteBufferNano + .computeInt32Size(2, this.responseSize); + } + if (this.payload != null) { + size += com.google.protobuf.nano.CodedOutputByteBufferNano + .computeMessageSize(3, this.payload); + } + if (this.fillUsername != false) { + size += com.google.protobuf.nano.CodedOutputByteBufferNano + .computeBoolSize(4, this.fillUsername); + } + if (this.fillOauthScope != false) { + size += com.google.protobuf.nano.CodedOutputByteBufferNano + .computeBoolSize(5, this.fillOauthScope); + } + return size; + } + + @Override + public SimpleRequest mergeFrom( + com.google.protobuf.nano.CodedInputByteBufferNano input) + throws java.io.IOException { + while (true) { + int tag = input.readTag(); + switch (tag) { + case 0: + return this; + default: { + if (!com.google.protobuf.nano.WireFormatNano.parseUnknownField(input, tag)) { + return this; + } + break; + } + case 8: { + int value = input.readInt32(); + switch (value) { + case io.grpc.android.integrationtest.Messages.COMPRESSABLE: + case io.grpc.android.integrationtest.Messages.UNCOMPRESSABLE: + case io.grpc.android.integrationtest.Messages.RANDOM: + this.responseType = value; + break; + } + break; + } + case 16: { + this.responseSize = input.readInt32(); + break; + } + case 26: { + if (this.payload == null) { + this.payload = new io.grpc.android.integrationtest.Messages.Payload(); + } + input.readMessage(this.payload); + break; + } + case 32: { + this.fillUsername = input.readBool(); + break; + } + case 40: { + this.fillOauthScope = input.readBool(); + break; + } + } + } + } + + public static SimpleRequest parseFrom(byte[] data) + throws com.google.protobuf.nano.InvalidProtocolBufferNanoException { + return com.google.protobuf.nano.MessageNano.mergeFrom(new SimpleRequest(), data); + } + + public static SimpleRequest parseFrom( + com.google.protobuf.nano.CodedInputByteBufferNano input) + throws java.io.IOException { + return new SimpleRequest().mergeFrom(input); + } + } + + public static final class SimpleResponse extends + com.google.protobuf.nano.MessageNano { + + private static volatile SimpleResponse[] _emptyArray; + public static SimpleResponse[] emptyArray() { + // Lazily initializes the empty array + if (_emptyArray == null) { + synchronized ( + com.google.protobuf.nano.InternalNano.LAZY_INIT_LOCK) { + if (_emptyArray == null) { + _emptyArray = new SimpleResponse[0]; + } + } + } + return _emptyArray; + } + + // optional .grpc.testing.Payload payload = 1; + public io.grpc.android.integrationtest.Messages.Payload payload; + + // optional string username = 2; + public java.lang.String username; + + // optional string oauth_scope = 3; + public java.lang.String oauthScope; + + public SimpleResponse() { + clear(); + } + + public SimpleResponse clear() { + payload = null; + username = ""; + oauthScope = ""; + cachedSize = -1; + return this; + } + + @Override + public void writeTo(com.google.protobuf.nano.CodedOutputByteBufferNano output) + throws java.io.IOException { + if (this.payload != null) { + output.writeMessage(1, this.payload); + } + if (!this.username.equals("")) { + output.writeString(2, this.username); + } + if (!this.oauthScope.equals("")) { + output.writeString(3, this.oauthScope); + } + super.writeTo(output); + } + + @Override + protected int computeSerializedSize() { + int size = super.computeSerializedSize(); + if (this.payload != null) { + size += com.google.protobuf.nano.CodedOutputByteBufferNano + .computeMessageSize(1, this.payload); + } + if (!this.username.equals("")) { + size += com.google.protobuf.nano.CodedOutputByteBufferNano + .computeStringSize(2, this.username); + } + if (!this.oauthScope.equals("")) { + size += com.google.protobuf.nano.CodedOutputByteBufferNano + .computeStringSize(3, this.oauthScope); + } + return size; + } + + @Override + public SimpleResponse mergeFrom( + com.google.protobuf.nano.CodedInputByteBufferNano input) + throws java.io.IOException { + while (true) { + int tag = input.readTag(); + switch (tag) { + case 0: + return this; + default: { + if (!com.google.protobuf.nano.WireFormatNano.parseUnknownField(input, tag)) { + return this; + } + break; + } + case 10: { + if (this.payload == null) { + this.payload = new io.grpc.android.integrationtest.Messages.Payload(); + } + input.readMessage(this.payload); + break; + } + case 18: { + this.username = input.readString(); + break; + } + case 26: { + this.oauthScope = input.readString(); + break; + } + } + } + } + + public static SimpleResponse parseFrom(byte[] data) + throws com.google.protobuf.nano.InvalidProtocolBufferNanoException { + return com.google.protobuf.nano.MessageNano.mergeFrom(new SimpleResponse(), data); + } + + public static SimpleResponse parseFrom( + com.google.protobuf.nano.CodedInputByteBufferNano input) + throws java.io.IOException { + return new SimpleResponse().mergeFrom(input); + } + } + + public static final class SimpleContext extends + com.google.protobuf.nano.MessageNano { + + private static volatile SimpleContext[] _emptyArray; + public static SimpleContext[] emptyArray() { + // Lazily initializes the empty array + if (_emptyArray == null) { + synchronized ( + com.google.protobuf.nano.InternalNano.LAZY_INIT_LOCK) { + if (_emptyArray == null) { + _emptyArray = new SimpleContext[0]; + } + } + } + return _emptyArray; + } + + // optional string value = 1; + public java.lang.String value; + + public SimpleContext() { + clear(); + } + + public SimpleContext clear() { + value = ""; + cachedSize = -1; + return this; + } + + @Override + public void writeTo(com.google.protobuf.nano.CodedOutputByteBufferNano output) + throws java.io.IOException { + if (!this.value.equals("")) { + output.writeString(1, this.value); + } + super.writeTo(output); + } + + @Override + protected int computeSerializedSize() { + int size = super.computeSerializedSize(); + if (!this.value.equals("")) { + size += com.google.protobuf.nano.CodedOutputByteBufferNano + .computeStringSize(1, this.value); + } + return size; + } + + @Override + public SimpleContext mergeFrom( + com.google.protobuf.nano.CodedInputByteBufferNano input) + throws java.io.IOException { + while (true) { + int tag = input.readTag(); + switch (tag) { + case 0: + return this; + default: { + if (!com.google.protobuf.nano.WireFormatNano.parseUnknownField(input, tag)) { + return this; + } + break; + } + case 10: { + this.value = input.readString(); + break; + } + } + } + } + + public static SimpleContext parseFrom(byte[] data) + throws com.google.protobuf.nano.InvalidProtocolBufferNanoException { + return com.google.protobuf.nano.MessageNano.mergeFrom(new SimpleContext(), data); + } + + public static SimpleContext parseFrom( + com.google.protobuf.nano.CodedInputByteBufferNano input) + throws java.io.IOException { + return new SimpleContext().mergeFrom(input); + } + } + + public static final class StreamingInputCallRequest extends + com.google.protobuf.nano.MessageNano { + + private static volatile StreamingInputCallRequest[] _emptyArray; + public static StreamingInputCallRequest[] emptyArray() { + // Lazily initializes the empty array + if (_emptyArray == null) { + synchronized ( + com.google.protobuf.nano.InternalNano.LAZY_INIT_LOCK) { + if (_emptyArray == null) { + _emptyArray = new StreamingInputCallRequest[0]; + } + } + } + return _emptyArray; + } + + // optional .grpc.testing.Payload payload = 1; + public io.grpc.android.integrationtest.Messages.Payload payload; + + public StreamingInputCallRequest() { + clear(); + } + + public StreamingInputCallRequest clear() { + payload = null; + cachedSize = -1; + return this; + } + + @Override + public void writeTo(com.google.protobuf.nano.CodedOutputByteBufferNano output) + throws java.io.IOException { + if (this.payload != null) { + output.writeMessage(1, this.payload); + } + super.writeTo(output); + } + + @Override + protected int computeSerializedSize() { + int size = super.computeSerializedSize(); + if (this.payload != null) { + size += com.google.protobuf.nano.CodedOutputByteBufferNano + .computeMessageSize(1, this.payload); + } + return size; + } + + @Override + public StreamingInputCallRequest mergeFrom( + com.google.protobuf.nano.CodedInputByteBufferNano input) + throws java.io.IOException { + while (true) { + int tag = input.readTag(); + switch (tag) { + case 0: + return this; + default: { + if (!com.google.protobuf.nano.WireFormatNano.parseUnknownField(input, tag)) { + return this; + } + break; + } + case 10: { + if (this.payload == null) { + this.payload = new io.grpc.android.integrationtest.Messages.Payload(); + } + input.readMessage(this.payload); + break; + } + } + } + } + + public static StreamingInputCallRequest parseFrom(byte[] data) + throws com.google.protobuf.nano.InvalidProtocolBufferNanoException { + return com.google.protobuf.nano.MessageNano.mergeFrom(new StreamingInputCallRequest(), data); + } + + public static StreamingInputCallRequest parseFrom( + com.google.protobuf.nano.CodedInputByteBufferNano input) + throws java.io.IOException { + return new StreamingInputCallRequest().mergeFrom(input); + } + } + + public static final class StreamingInputCallResponse extends + com.google.protobuf.nano.MessageNano { + + private static volatile StreamingInputCallResponse[] _emptyArray; + public static StreamingInputCallResponse[] emptyArray() { + // Lazily initializes the empty array + if (_emptyArray == null) { + synchronized ( + com.google.protobuf.nano.InternalNano.LAZY_INIT_LOCK) { + if (_emptyArray == null) { + _emptyArray = new StreamingInputCallResponse[0]; + } + } + } + return _emptyArray; + } + + // optional int32 aggregated_payload_size = 1; + public int aggregatedPayloadSize; + + public StreamingInputCallResponse() { + clear(); + } + + public StreamingInputCallResponse clear() { + aggregatedPayloadSize = 0; + cachedSize = -1; + return this; + } + + @Override + public void writeTo(com.google.protobuf.nano.CodedOutputByteBufferNano output) + throws java.io.IOException { + if (this.aggregatedPayloadSize != 0) { + output.writeInt32(1, this.aggregatedPayloadSize); + } + super.writeTo(output); + } + + @Override + protected int computeSerializedSize() { + int size = super.computeSerializedSize(); + if (this.aggregatedPayloadSize != 0) { + size += com.google.protobuf.nano.CodedOutputByteBufferNano + .computeInt32Size(1, this.aggregatedPayloadSize); + } + return size; + } + + @Override + public StreamingInputCallResponse mergeFrom( + com.google.protobuf.nano.CodedInputByteBufferNano input) + throws java.io.IOException { + while (true) { + int tag = input.readTag(); + switch (tag) { + case 0: + return this; + default: { + if (!com.google.protobuf.nano.WireFormatNano.parseUnknownField(input, tag)) { + return this; + } + break; + } + case 8: { + this.aggregatedPayloadSize = input.readInt32(); + break; + } + } + } + } + + public static StreamingInputCallResponse parseFrom(byte[] data) + throws com.google.protobuf.nano.InvalidProtocolBufferNanoException { + return com.google.protobuf.nano.MessageNano.mergeFrom(new StreamingInputCallResponse(), data); + } + + public static StreamingInputCallResponse parseFrom( + com.google.protobuf.nano.CodedInputByteBufferNano input) + throws java.io.IOException { + return new StreamingInputCallResponse().mergeFrom(input); + } + } + + public static final class ResponseParameters extends + com.google.protobuf.nano.MessageNano { + + private static volatile ResponseParameters[] _emptyArray; + public static ResponseParameters[] emptyArray() { + // Lazily initializes the empty array + if (_emptyArray == null) { + synchronized ( + com.google.protobuf.nano.InternalNano.LAZY_INIT_LOCK) { + if (_emptyArray == null) { + _emptyArray = new ResponseParameters[0]; + } + } + } + return _emptyArray; + } + + // optional int32 size = 1; + public int size; + + // optional int32 interval_us = 2; + public int intervalUs; + + public ResponseParameters() { + clear(); + } + + public ResponseParameters clear() { + size = 0; + intervalUs = 0; + cachedSize = -1; + return this; + } + + @Override + public void writeTo(com.google.protobuf.nano.CodedOutputByteBufferNano output) + throws java.io.IOException { + if (this.size != 0) { + output.writeInt32(1, this.size); + } + if (this.intervalUs != 0) { + output.writeInt32(2, this.intervalUs); + } + super.writeTo(output); + } + + @Override + protected int computeSerializedSize() { + int size = super.computeSerializedSize(); + if (this.size != 0) { + size += com.google.protobuf.nano.CodedOutputByteBufferNano + .computeInt32Size(1, this.size); + } + if (this.intervalUs != 0) { + size += com.google.protobuf.nano.CodedOutputByteBufferNano + .computeInt32Size(2, this.intervalUs); + } + return size; + } + + @Override + public ResponseParameters mergeFrom( + com.google.protobuf.nano.CodedInputByteBufferNano input) + throws java.io.IOException { + while (true) { + int tag = input.readTag(); + switch (tag) { + case 0: + return this; + default: { + if (!com.google.protobuf.nano.WireFormatNano.parseUnknownField(input, tag)) { + return this; + } + break; + } + case 8: { + this.size = input.readInt32(); + break; + } + case 16: { + this.intervalUs = input.readInt32(); + break; + } + } + } + } + + public static ResponseParameters parseFrom(byte[] data) + throws com.google.protobuf.nano.InvalidProtocolBufferNanoException { + return com.google.protobuf.nano.MessageNano.mergeFrom(new ResponseParameters(), data); + } + + public static ResponseParameters parseFrom( + com.google.protobuf.nano.CodedInputByteBufferNano input) + throws java.io.IOException { + return new ResponseParameters().mergeFrom(input); + } + } + + public static final class StreamingOutputCallRequest extends + com.google.protobuf.nano.MessageNano { + + private static volatile StreamingOutputCallRequest[] _emptyArray; + public static StreamingOutputCallRequest[] emptyArray() { + // Lazily initializes the empty array + if (_emptyArray == null) { + synchronized ( + com.google.protobuf.nano.InternalNano.LAZY_INIT_LOCK) { + if (_emptyArray == null) { + _emptyArray = new StreamingOutputCallRequest[0]; + } + } + } + return _emptyArray; + } + + // optional .grpc.testing.PayloadType response_type = 1; + public int responseType; + + // repeated .grpc.testing.ResponseParameters response_parameters = 2; + public io.grpc.android.integrationtest.Messages.ResponseParameters[] responseParameters; + + // optional .grpc.testing.Payload payload = 3; + public io.grpc.android.integrationtest.Messages.Payload payload; + + public StreamingOutputCallRequest() { + clear(); + } + + public StreamingOutputCallRequest clear() { + responseType = io.grpc.android.integrationtest.Messages.COMPRESSABLE; + responseParameters = io.grpc.android.integrationtest.Messages.ResponseParameters.emptyArray(); + payload = null; + cachedSize = -1; + return this; + } + + @Override + public void writeTo(com.google.protobuf.nano.CodedOutputByteBufferNano output) + throws java.io.IOException { + if (this.responseType != io.grpc.android.integrationtest.Messages.COMPRESSABLE) { + output.writeInt32(1, this.responseType); + } + if (this.responseParameters != null && this.responseParameters.length > 0) { + for (int i = 0; i < this.responseParameters.length; i++) { + io.grpc.android.integrationtest.Messages.ResponseParameters element = this.responseParameters[i]; + if (element != null) { + output.writeMessage(2, element); + } + } + } + if (this.payload != null) { + output.writeMessage(3, this.payload); + } + super.writeTo(output); + } + + @Override + protected int computeSerializedSize() { + int size = super.computeSerializedSize(); + if (this.responseType != io.grpc.android.integrationtest.Messages.COMPRESSABLE) { + size += com.google.protobuf.nano.CodedOutputByteBufferNano + .computeInt32Size(1, this.responseType); + } + if (this.responseParameters != null && this.responseParameters.length > 0) { + for (int i = 0; i < this.responseParameters.length; i++) { + io.grpc.android.integrationtest.Messages.ResponseParameters element = this.responseParameters[i]; + if (element != null) { + size += com.google.protobuf.nano.CodedOutputByteBufferNano + .computeMessageSize(2, element); + } + } + } + if (this.payload != null) { + size += com.google.protobuf.nano.CodedOutputByteBufferNano + .computeMessageSize(3, this.payload); + } + return size; + } + + @Override + public StreamingOutputCallRequest mergeFrom( + com.google.protobuf.nano.CodedInputByteBufferNano input) + throws java.io.IOException { + while (true) { + int tag = input.readTag(); + switch (tag) { + case 0: + return this; + default: { + if (!com.google.protobuf.nano.WireFormatNano.parseUnknownField(input, tag)) { + return this; + } + break; + } + case 8: { + int value = input.readInt32(); + switch (value) { + case io.grpc.android.integrationtest.Messages.COMPRESSABLE: + case io.grpc.android.integrationtest.Messages.UNCOMPRESSABLE: + case io.grpc.android.integrationtest.Messages.RANDOM: + this.responseType = value; + break; + } + break; + } + case 18: { + int arrayLength = com.google.protobuf.nano.WireFormatNano + .getRepeatedFieldArrayLength(input, 18); + int i = this.responseParameters == null ? 0 : this.responseParameters.length; + io.grpc.android.integrationtest.Messages.ResponseParameters[] newArray = + new io.grpc.android.integrationtest.Messages.ResponseParameters[i + arrayLength]; + if (i != 0) { + java.lang.System.arraycopy(this.responseParameters, 0, newArray, 0, i); + } + for (; i < newArray.length - 1; i++) { + newArray[i] = new io.grpc.android.integrationtest.Messages.ResponseParameters(); + input.readMessage(newArray[i]); + input.readTag(); + } + // Last one without readTag. + newArray[i] = new io.grpc.android.integrationtest.Messages.ResponseParameters(); + input.readMessage(newArray[i]); + this.responseParameters = newArray; + break; + } + case 26: { + if (this.payload == null) { + this.payload = new io.grpc.android.integrationtest.Messages.Payload(); + } + input.readMessage(this.payload); + break; + } + } + } + } + + public static StreamingOutputCallRequest parseFrom(byte[] data) + throws com.google.protobuf.nano.InvalidProtocolBufferNanoException { + return com.google.protobuf.nano.MessageNano.mergeFrom(new StreamingOutputCallRequest(), data); + } + + public static StreamingOutputCallRequest parseFrom( + com.google.protobuf.nano.CodedInputByteBufferNano input) + throws java.io.IOException { + return new StreamingOutputCallRequest().mergeFrom(input); + } + } + + public static final class StreamingOutputCallResponse extends + com.google.protobuf.nano.MessageNano { + + private static volatile StreamingOutputCallResponse[] _emptyArray; + public static StreamingOutputCallResponse[] emptyArray() { + // Lazily initializes the empty array + if (_emptyArray == null) { + synchronized ( + com.google.protobuf.nano.InternalNano.LAZY_INIT_LOCK) { + if (_emptyArray == null) { + _emptyArray = new StreamingOutputCallResponse[0]; + } + } + } + return _emptyArray; + } + + // optional .grpc.testing.Payload payload = 1; + public io.grpc.android.integrationtest.Messages.Payload payload; + + public StreamingOutputCallResponse() { + clear(); + } + + public StreamingOutputCallResponse clear() { + payload = null; + cachedSize = -1; + return this; + } + + @Override + public void writeTo(com.google.protobuf.nano.CodedOutputByteBufferNano output) + throws java.io.IOException { + if (this.payload != null) { + output.writeMessage(1, this.payload); + } + super.writeTo(output); + } + + @Override + protected int computeSerializedSize() { + int size = super.computeSerializedSize(); + if (this.payload != null) { + size += com.google.protobuf.nano.CodedOutputByteBufferNano + .computeMessageSize(1, this.payload); + } + return size; + } + + @Override + public StreamingOutputCallResponse mergeFrom( + com.google.protobuf.nano.CodedInputByteBufferNano input) + throws java.io.IOException { + while (true) { + int tag = input.readTag(); + switch (tag) { + case 0: + return this; + default: { + if (!com.google.protobuf.nano.WireFormatNano.parseUnknownField(input, tag)) { + return this; + } + break; + } + case 10: { + if (this.payload == null) { + this.payload = new io.grpc.android.integrationtest.Messages.Payload(); + } + input.readMessage(this.payload); + break; + } + } + } + } + + public static StreamingOutputCallResponse parseFrom(byte[] data) + throws com.google.protobuf.nano.InvalidProtocolBufferNanoException { + return com.google.protobuf.nano.MessageNano.mergeFrom(new StreamingOutputCallResponse(), data); + } + + public static StreamingOutputCallResponse parseFrom( + com.google.protobuf.nano.CodedInputByteBufferNano input) + throws java.io.IOException { + return new StreamingOutputCallResponse().mergeFrom(input); + } + } +} diff --git a/android-interop-testing/app/src/main/java/generated/io/grpc/android/integrationtest/TestServiceGrpc.java b/android-interop-testing/app/src/main/java/generated/io/grpc/android/integrationtest/TestServiceGrpc.java new file mode 100644 index 0000000000..38d13ad19a --- /dev/null +++ b/android-interop-testing/app/src/main/java/generated/io/grpc/android/integrationtest/TestServiceGrpc.java @@ -0,0 +1,457 @@ +package io.grpc.android.integrationtest; + +import static io.grpc.stub.ClientCalls.createMethodDescriptor; +import static io.grpc.stub.ClientCalls.asyncUnaryCall; +import static io.grpc.stub.ClientCalls.asyncServerStreamingCall; +import static io.grpc.stub.ClientCalls.asyncClientStreamingCall; +import static io.grpc.stub.ClientCalls.duplexStreamingCall; +import static io.grpc.stub.ClientCalls.blockingUnaryCall; +import static io.grpc.stub.ClientCalls.blockingServerStreamingCall; +import static io.grpc.stub.ClientCalls.unaryFutureCall; +import static io.grpc.stub.ServerCalls.createMethodDefinition; +import static io.grpc.stub.ServerCalls.asyncUnaryRequestCall; +import static io.grpc.stub.ServerCalls.asyncStreamingRequestCall; + +import java.io.IOException; + +//@javax.annotation.Generated("by gRPC proto compiler") +public class TestServiceGrpc { + + private static final io.grpc.stub.Method METHOD_EMPTY_CALL = + io.grpc.stub.Method.create( + io.grpc.MethodType.UNARY, "EmptyCall", + io.grpc.protobuf.nano.NanoUtils.marshaller( + new io.grpc.protobuf.nano.Parser() { + @Override + public io.grpc.android.integrationtest.EmptyProtos.Empty parse(com.google.protobuf.nano.CodedInputByteBufferNano input) throws IOException { + return io.grpc.android.integrationtest.EmptyProtos.Empty.parseFrom(input); + } + }), + io.grpc.protobuf.nano.NanoUtils.marshaller( + new io.grpc.protobuf.nano.Parser() { + @Override + public io.grpc.android.integrationtest.EmptyProtos.Empty parse(com.google.protobuf.nano.CodedInputByteBufferNano input) throws IOException { + return io.grpc.android.integrationtest.EmptyProtos.Empty.parseFrom(input); + } + })); + private static final io.grpc.stub.Method METHOD_UNARY_CALL = + io.grpc.stub.Method.create( + io.grpc.MethodType.UNARY, "UnaryCall", + io.grpc.protobuf.nano.NanoUtils.marshaller( + new io.grpc.protobuf.nano.Parser() { + @Override + public io.grpc.android.integrationtest.Messages.SimpleRequest parse(com.google.protobuf.nano.CodedInputByteBufferNano input) throws IOException { + return io.grpc.android.integrationtest.Messages.SimpleRequest.parseFrom(input); + } + }), + io.grpc.protobuf.nano.NanoUtils.marshaller( + new io.grpc.protobuf.nano.Parser() { + @Override + public io.grpc.android.integrationtest.Messages.SimpleResponse parse(com.google.protobuf.nano.CodedInputByteBufferNano input) throws IOException { + return io.grpc.android.integrationtest.Messages.SimpleResponse.parseFrom(input); + } + })); + private static final io.grpc.stub.Method METHOD_STREAMING_OUTPUT_CALL = + io.grpc.stub.Method.create( + io.grpc.MethodType.SERVER_STREAMING, "StreamingOutputCall", + io.grpc.protobuf.nano.NanoUtils.marshaller( + new io.grpc.protobuf.nano.Parser() { + @Override + public io.grpc.android.integrationtest.Messages.StreamingOutputCallRequest parse(com.google.protobuf.nano.CodedInputByteBufferNano input) throws IOException { + return io.grpc.android.integrationtest.Messages.StreamingOutputCallRequest.parseFrom(input); + } + }), + io.grpc.protobuf.nano.NanoUtils.marshaller( + new io.grpc.protobuf.nano.Parser() { + @Override + public io.grpc.android.integrationtest.Messages.StreamingOutputCallResponse parse(com.google.protobuf.nano.CodedInputByteBufferNano input) throws IOException { + return io.grpc.android.integrationtest.Messages.StreamingOutputCallResponse.parseFrom(input); + } + })); + private static final io.grpc.stub.Method METHOD_STREAMING_INPUT_CALL = + io.grpc.stub.Method.create( + io.grpc.MethodType.CLIENT_STREAMING, "StreamingInputCall", + io.grpc.protobuf.nano.NanoUtils.marshaller( + new io.grpc.protobuf.nano.Parser() { + @Override + public io.grpc.android.integrationtest.Messages.StreamingInputCallRequest parse(com.google.protobuf.nano.CodedInputByteBufferNano input) throws IOException { + return io.grpc.android.integrationtest.Messages.StreamingInputCallRequest.parseFrom(input); + } + }), + io.grpc.protobuf.nano.NanoUtils.marshaller( + new io.grpc.protobuf.nano.Parser() { + @Override + public io.grpc.android.integrationtest.Messages.StreamingInputCallResponse parse(com.google.protobuf.nano.CodedInputByteBufferNano input) throws IOException { + return io.grpc.android.integrationtest.Messages.StreamingInputCallResponse.parseFrom(input); + } + })); + private static final io.grpc.stub.Method METHOD_FULL_DUPLEX_CALL = + io.grpc.stub.Method.create( + io.grpc.MethodType.DUPLEX_STREAMING, "FullDuplexCall", + io.grpc.protobuf.nano.NanoUtils.marshaller( + new io.grpc.protobuf.nano.Parser() { + @Override + public io.grpc.android.integrationtest.Messages.StreamingOutputCallRequest parse(com.google.protobuf.nano.CodedInputByteBufferNano input) throws IOException { + return io.grpc.android.integrationtest.Messages.StreamingOutputCallRequest.parseFrom(input); + } + }), + io.grpc.protobuf.nano.NanoUtils.marshaller( + new io.grpc.protobuf.nano.Parser() { + @Override + public io.grpc.android.integrationtest.Messages.StreamingOutputCallResponse parse(com.google.protobuf.nano.CodedInputByteBufferNano input) throws IOException { + return io.grpc.android.integrationtest.Messages.StreamingOutputCallResponse.parseFrom(input); + } + })); + private static final io.grpc.stub.Method METHOD_HALF_DUPLEX_CALL = + io.grpc.stub.Method.create( + io.grpc.MethodType.DUPLEX_STREAMING, "HalfDuplexCall", + io.grpc.protobuf.nano.NanoUtils.marshaller( + new io.grpc.protobuf.nano.Parser() { + @Override + public io.grpc.android.integrationtest.Messages.StreamingOutputCallRequest parse(com.google.protobuf.nano.CodedInputByteBufferNano input) throws IOException { + return io.grpc.android.integrationtest.Messages.StreamingOutputCallRequest.parseFrom(input); + } + }), + io.grpc.protobuf.nano.NanoUtils.marshaller( + new io.grpc.protobuf.nano.Parser() { + @Override + public io.grpc.android.integrationtest.Messages.StreamingOutputCallResponse parse(com.google.protobuf.nano.CodedInputByteBufferNano input) throws IOException { + return io.grpc.android.integrationtest.Messages.StreamingOutputCallResponse.parseFrom(input); + } + })); + + public static TestServiceStub newStub(io.grpc.Channel channel) { + return new TestServiceStub(channel, CONFIG); + } + + public static TestServiceBlockingStub newBlockingStub( + io.grpc.Channel channel) { + return new TestServiceBlockingStub(channel, CONFIG); + } + + public static TestServiceFutureStub newFutureStub( + io.grpc.Channel channel) { + return new TestServiceFutureStub(channel, CONFIG); + } + + public static final TestServiceServiceDescriptor CONFIG = + new TestServiceServiceDescriptor(); + + @javax.annotation.concurrent.Immutable + public static class TestServiceServiceDescriptor extends + io.grpc.stub.AbstractServiceDescriptor { + public final io.grpc.MethodDescriptor emptyCall; + public final io.grpc.MethodDescriptor unaryCall; + public final io.grpc.MethodDescriptor streamingOutputCall; + public final io.grpc.MethodDescriptor streamingInputCall; + public final io.grpc.MethodDescriptor fullDuplexCall; + public final io.grpc.MethodDescriptor halfDuplexCall; + + private TestServiceServiceDescriptor() { + emptyCall = createMethodDescriptor( + "grpc.testing.TestService", METHOD_EMPTY_CALL); + unaryCall = createMethodDescriptor( + "grpc.testing.TestService", METHOD_UNARY_CALL); + streamingOutputCall = createMethodDescriptor( + "grpc.testing.TestService", METHOD_STREAMING_OUTPUT_CALL); + streamingInputCall = createMethodDescriptor( + "grpc.testing.TestService", METHOD_STREAMING_INPUT_CALL); + fullDuplexCall = createMethodDescriptor( + "grpc.testing.TestService", METHOD_FULL_DUPLEX_CALL); + halfDuplexCall = createMethodDescriptor( + "grpc.testing.TestService", METHOD_HALF_DUPLEX_CALL); + } + + @SuppressWarnings("unchecked") + private TestServiceServiceDescriptor( + java.util.Map> methodMap) { + emptyCall = (io.grpc.MethodDescriptor) methodMap.get( + CONFIG.emptyCall.getName()); + unaryCall = (io.grpc.MethodDescriptor) methodMap.get( + CONFIG.unaryCall.getName()); + streamingOutputCall = (io.grpc.MethodDescriptor) methodMap.get( + CONFIG.streamingOutputCall.getName()); + streamingInputCall = (io.grpc.MethodDescriptor) methodMap.get( + CONFIG.streamingInputCall.getName()); + fullDuplexCall = (io.grpc.MethodDescriptor) methodMap.get( + CONFIG.fullDuplexCall.getName()); + halfDuplexCall = (io.grpc.MethodDescriptor) methodMap.get( + CONFIG.halfDuplexCall.getName()); + } + + @java.lang.Override + protected TestServiceServiceDescriptor build( + java.util.Map> methodMap) { + return new TestServiceServiceDescriptor(methodMap); + } + + @java.lang.Override + public com.google.common.collect.ImmutableList> methods() { + return com.google.common.collect.ImmutableList.>of( + emptyCall, + unaryCall, + streamingOutputCall, + streamingInputCall, + fullDuplexCall, + halfDuplexCall); + } + } + + public static interface TestService { + + public void emptyCall(io.grpc.android.integrationtest.EmptyProtos.Empty request, + io.grpc.stub.StreamObserver responseObserver); + + public void unaryCall(io.grpc.android.integrationtest.Messages.SimpleRequest request, + io.grpc.stub.StreamObserver responseObserver); + + public void streamingOutputCall(io.grpc.android.integrationtest.Messages.StreamingOutputCallRequest request, + io.grpc.stub.StreamObserver responseObserver); + + public io.grpc.stub.StreamObserver streamingInputCall( + io.grpc.stub.StreamObserver responseObserver); + + public io.grpc.stub.StreamObserver fullDuplexCall( + io.grpc.stub.StreamObserver responseObserver); + + public io.grpc.stub.StreamObserver halfDuplexCall( + io.grpc.stub.StreamObserver responseObserver); + } + + public static interface TestServiceBlockingClient { + + public io.grpc.android.integrationtest.EmptyProtos.Empty emptyCall(io.grpc.android.integrationtest.EmptyProtos.Empty request); + + public io.grpc.android.integrationtest.Messages.SimpleResponse unaryCall(io.grpc.android.integrationtest.Messages.SimpleRequest request); + + public java.util.Iterator streamingOutputCall( + io.grpc.android.integrationtest.Messages.StreamingOutputCallRequest request); + } + + public static interface TestServiceFutureClient { + + public com.google.common.util.concurrent.ListenableFuture emptyCall( + io.grpc.android.integrationtest.EmptyProtos.Empty request); + + public com.google.common.util.concurrent.ListenableFuture unaryCall( + io.grpc.android.integrationtest.Messages.SimpleRequest request); + } + + public static class TestServiceStub extends + io.grpc.stub.AbstractStub + implements TestService { + private TestServiceStub(io.grpc.Channel channel, + TestServiceServiceDescriptor config) { + super(channel, config); + } + + @java.lang.Override + protected TestServiceStub build(io.grpc.Channel channel, + TestServiceServiceDescriptor config) { + return new TestServiceStub(channel, config); + } + + @java.lang.Override + public void emptyCall(io.grpc.android.integrationtest.EmptyProtos.Empty request, + io.grpc.stub.StreamObserver responseObserver) { + asyncUnaryCall( + channel.newCall(config.emptyCall), request, responseObserver); + } + + @java.lang.Override + public void unaryCall(io.grpc.android.integrationtest.Messages.SimpleRequest request, + io.grpc.stub.StreamObserver responseObserver) { + asyncUnaryCall( + channel.newCall(config.unaryCall), request, responseObserver); + } + + @java.lang.Override + public void streamingOutputCall(io.grpc.android.integrationtest.Messages.StreamingOutputCallRequest request, + io.grpc.stub.StreamObserver responseObserver) { + asyncServerStreamingCall( + channel.newCall(config.streamingOutputCall), request, responseObserver); + } + + @java.lang.Override + public io.grpc.stub.StreamObserver streamingInputCall( + io.grpc.stub.StreamObserver responseObserver) { + return asyncClientStreamingCall( + channel.newCall(config.streamingInputCall), responseObserver); + } + + @java.lang.Override + public io.grpc.stub.StreamObserver fullDuplexCall( + io.grpc.stub.StreamObserver responseObserver) { + return duplexStreamingCall( + channel.newCall(config.fullDuplexCall), responseObserver); + } + + @java.lang.Override + public io.grpc.stub.StreamObserver halfDuplexCall( + io.grpc.stub.StreamObserver responseObserver) { + return duplexStreamingCall( + channel.newCall(config.halfDuplexCall), responseObserver); + } + } + + public static class TestServiceBlockingStub extends + io.grpc.stub.AbstractStub + implements TestServiceBlockingClient { + private TestServiceBlockingStub(io.grpc.Channel channel, + TestServiceServiceDescriptor config) { + super(channel, config); + } + + @java.lang.Override + protected TestServiceBlockingStub build(io.grpc.Channel channel, + TestServiceServiceDescriptor config) { + return new TestServiceBlockingStub(channel, config); + } + + @java.lang.Override + public io.grpc.android.integrationtest.EmptyProtos.Empty emptyCall(io.grpc.android.integrationtest.EmptyProtos.Empty request) { + return blockingUnaryCall( + channel.newCall(config.emptyCall), request); + } + + @java.lang.Override + public io.grpc.android.integrationtest.Messages.SimpleResponse unaryCall(io.grpc.android.integrationtest.Messages.SimpleRequest request) { + return blockingUnaryCall( + channel.newCall(config.unaryCall), request); + } + + @java.lang.Override + public java.util.Iterator streamingOutputCall( + io.grpc.android.integrationtest.Messages.StreamingOutputCallRequest request) { + return blockingServerStreamingCall( + channel.newCall(config.streamingOutputCall), request); + } + } + + public static class TestServiceFutureStub extends + io.grpc.stub.AbstractStub + implements TestServiceFutureClient { + private TestServiceFutureStub(io.grpc.Channel channel, + TestServiceServiceDescriptor config) { + super(channel, config); + } + + @java.lang.Override + protected TestServiceFutureStub build(io.grpc.Channel channel, + TestServiceServiceDescriptor config) { + return new TestServiceFutureStub(channel, config); + } + + @java.lang.Override + public com.google.common.util.concurrent.ListenableFuture emptyCall( + io.grpc.android.integrationtest.EmptyProtos.Empty request) { + return unaryFutureCall( + channel.newCall(config.emptyCall), request); + } + + @java.lang.Override + public com.google.common.util.concurrent.ListenableFuture unaryCall( + io.grpc.android.integrationtest.Messages.SimpleRequest request) { + return unaryFutureCall( + channel.newCall(config.unaryCall), request); + } + } + + public static io.grpc.ServerServiceDefinition bindService( + final TestService serviceImpl) { + return io.grpc.ServerServiceDefinition.builder("grpc.testing.TestService") + .addMethod(createMethodDefinition( + METHOD_EMPTY_CALL, + asyncUnaryRequestCall( + new io.grpc.stub.ServerCalls.UnaryRequestMethod< + io.grpc.android.integrationtest.EmptyProtos.Empty, + io.grpc.android.integrationtest.EmptyProtos.Empty>() { + @java.lang.Override + public void invoke( + io.grpc.android.integrationtest.EmptyProtos.Empty request, + io.grpc.stub.StreamObserver responseObserver) { + serviceImpl.emptyCall(request, responseObserver); + } + }))) + .addMethod(createMethodDefinition( + METHOD_UNARY_CALL, + asyncUnaryRequestCall( + new io.grpc.stub.ServerCalls.UnaryRequestMethod< + io.grpc.android.integrationtest.Messages.SimpleRequest, + io.grpc.android.integrationtest.Messages.SimpleResponse>() { + @java.lang.Override + public void invoke( + io.grpc.android.integrationtest.Messages.SimpleRequest request, + io.grpc.stub.StreamObserver responseObserver) { + serviceImpl.unaryCall(request, responseObserver); + } + }))) + .addMethod(createMethodDefinition( + METHOD_STREAMING_OUTPUT_CALL, + asyncUnaryRequestCall( + new io.grpc.stub.ServerCalls.UnaryRequestMethod< + io.grpc.android.integrationtest.Messages.StreamingOutputCallRequest, + io.grpc.android.integrationtest.Messages.StreamingOutputCallResponse>() { + @java.lang.Override + public void invoke( + io.grpc.android.integrationtest.Messages.StreamingOutputCallRequest request, + io.grpc.stub.StreamObserver responseObserver) { + serviceImpl.streamingOutputCall(request, responseObserver); + } + }))) + .addMethod(createMethodDefinition( + METHOD_STREAMING_INPUT_CALL, + asyncStreamingRequestCall( + new io.grpc.stub.ServerCalls.StreamingRequestMethod< + io.grpc.android.integrationtest.Messages.StreamingInputCallRequest, + io.grpc.android.integrationtest.Messages.StreamingInputCallResponse>() { + @java.lang.Override + public io.grpc.stub.StreamObserver invoke( + io.grpc.stub.StreamObserver responseObserver) { + return serviceImpl.streamingInputCall(responseObserver); + } + }))) + .addMethod(createMethodDefinition( + METHOD_FULL_DUPLEX_CALL, + asyncStreamingRequestCall( + new io.grpc.stub.ServerCalls.StreamingRequestMethod< + io.grpc.android.integrationtest.Messages.StreamingOutputCallRequest, + io.grpc.android.integrationtest.Messages.StreamingOutputCallResponse>() { + @java.lang.Override + public io.grpc.stub.StreamObserver invoke( + io.grpc.stub.StreamObserver responseObserver) { + return serviceImpl.fullDuplexCall(responseObserver); + } + }))) + .addMethod(createMethodDefinition( + METHOD_HALF_DUPLEX_CALL, + asyncStreamingRequestCall( + new io.grpc.stub.ServerCalls.StreamingRequestMethod< + io.grpc.android.integrationtest.Messages.StreamingOutputCallRequest, + io.grpc.android.integrationtest.Messages.StreamingOutputCallResponse>() { + @java.lang.Override + public io.grpc.stub.StreamObserver invoke( + io.grpc.stub.StreamObserver responseObserver) { + return serviceImpl.halfDuplexCall(responseObserver); + } + }))).build(); + } +} 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 new file mode 100644 index 0000000000..3479b9ca84 --- /dev/null +++ b/android-interop-testing/app/src/main/java/io/grpc/android/integrationtest/InteropTester.java @@ -0,0 +1,350 @@ +/* + * Copyright 2015, Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.grpc.android.integrationtest; + +import com.google.protobuf.nano.MessageNano; + +import android.os.AsyncTask; +import android.support.annotation.Nullable; +import android.util.Log; + +import io.grpc.ChannelImpl; +import io.grpc.stub.StreamObserver; +import io.grpc.stub.StreamRecorder; +import io.grpc.transport.okhttp.OkHttpChannelBuilder; + +import junit.framework.Assert; + +import java.io.InputStream; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.security.KeyStore; +import java.security.cert.CertificateFactory; +import java.security.cert.X509Certificate; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.TimeUnit; + +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.security.auth.x500.X500Principal; + +/** + * Implementation of the integration tests, as an AsyncTask. + */ +public final class InteropTester extends AsyncTask { + final static String SUCCESS_MESSAGE = "Succeed!!!"; + + private ChannelImpl channel; + private TestServiceGrpc.TestServiceBlockingStub blockingStub; + private TestServiceGrpc.TestService asyncStub; + private String testCase; + private TestListener listener; + + public InteropTester(String testCase, + String host, + int port, + @Nullable String serverHostOverride, + boolean useTls, + @Nullable InputStream testCa, + TestListener listener) { + this.testCase = testCase; + this.listener = listener; + + OkHttpChannelBuilder channelBuilder = OkHttpChannelBuilder.forAddress(host, port); + if (serverHostOverride != null) { + // Force the hostname to match the cert the server uses. + channelBuilder.overrideHostForAuthority(serverHostOverride); + } + if (useTls) { + try { + channelBuilder.sslSocketFactory(getSslSocketFactory(testCa)); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + channel = channelBuilder.build(); + blockingStub = TestServiceGrpc.newBlockingStub(channel); + asyncStub = TestServiceGrpc.newStub(channel); + } + + @Override + protected void onPreExecute() { + listener.onPreTest(); + } + + @Override + protected String doInBackground(Void... nothing) { + try { + runTest(testCase); + return SUCCESS_MESSAGE; + } catch (Exception | AssertionError e) { + // Print the stack trace to logcat. + e.printStackTrace(); + // Then print to the error message. + StringWriter sw = new StringWriter(); + e.printStackTrace(new PrintWriter(sw)); + return "Failed... : " + e.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 { + if ("all".equals(testCase)) { + emptyUnary(); + largeUnary(); + clientStreaming(); + serverStreaming(); + pingPong(); + } 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 { + throw new IllegalArgumentException("Unimplemented/Unknown test case: " + testCase); + } + } + + public void emptyUnary() { + assertEquals(new EmptyProtos.Empty(), blockingStub.emptyCall(new EmptyProtos.Empty())); + } + + public void largeUnary() { + final Messages.SimpleRequest request = new Messages.SimpleRequest(); + request.responseSize = 314159; + request.responseType = Messages.COMPRESSABLE; + request.payload = new Messages.Payload(); + request.payload.body = new byte[271828]; + + final Messages.SimpleResponse goldenResponse = new Messages.SimpleResponse(); + goldenResponse.payload = new Messages.Payload(); + goldenResponse.payload.body = new byte[314159]; + Messages.SimpleResponse response = blockingStub.unaryCall(request); + assertEquals(goldenResponse, response); + } + + public void serverStreaming() throws Exception { + final Messages.StreamingOutputCallRequest request = new Messages.StreamingOutputCallRequest(); + request.responseType = Messages.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 Messages.Payload(); + goldenResponses[i].payload.type = Messages.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 recorder = StreamRecorder.create(); + asyncStub.streamingOutputCall(request, recorder); + recorder.awaitCompletion(); + assertSuccess(recorder); + assertEquals(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 Messages.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 responseObserver = StreamRecorder.create(); + StreamObserver requestObserver = + asyncStub.streamingInputCall(responseObserver); + for (Messages.StreamingInputCallRequest request : requests) { + requestObserver.onValue(request); + } + requestObserver.onCompleted(); + assertEquals(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 Messages.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 Messages.Payload(); + goldenResponses[i].payload.type = Messages.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]; + + final LinkedBlockingQueue responses = new LinkedBlockingQueue<>(); + final Object magicTailResponse = new Object(); + @SuppressWarnings("unchecked") + StreamObserver responseObserver = + new StreamObserver() { + + @Override + public void onValue(Messages.StreamingOutputCallResponse value) { + responses.add(value); + } + + @Override + public void onError(Throwable t) { + Log.e(TesterActivity.LOG_TAG, "Encounter an error", t); + responses.add(t); + } + + @Override + public void onCompleted() { + responses.add(magicTailResponse); + } + }; + StreamObserver requestObserver + = asyncStub.fullDuplexCall(responseObserver); + for (int i = 0; i < requests.length; i++) { + requestObserver.onValue(requests[i]); + Object response = responses.poll(5, TimeUnit.SECONDS); + if (!(response instanceof Messages.StreamingOutputCallResponse)) { + Assert.fail("Unexpected: " + response); + } + assertEquals(goldenResponses[i], (Messages.StreamingOutputCallResponse) response); + Assert.assertTrue("More than 1 responses received for ping pong test.", responses.isEmpty()); + } + requestObserver.onCompleted(); + Assert.assertEquals(magicTailResponse, responses.poll(5, TimeUnit.SECONDS)); + } + + public static void assertEquals(MessageNano expected, MessageNano actual) { + if (!MessageNano.messageNanoEquals(expected, actual)) { + Assert.assertEquals(expected.toString(), actual.toString()); + Assert.fail("Messages not equal, but assertEquals didn't throw"); + } + } + + private static void assertSuccess(StreamRecorder recorder) { + if (recorder.getError() != null) { + throw new AssertionError(recorder.getError()); + } + } + + public static void assertEquals(List expected, + List actual) { + if (expected == null || actual == null) { + Assert.assertEquals(expected, actual); + } else if (expected.size() != actual.size()) { + Assert.assertEquals(expected, actual); + } else { + for (int i = 0; i < expected.size(); i++) { + assertEquals(expected.get(i), actual.get(i)); + } + } + } + + private SSLSocketFactory getSslSocketFactory(@Nullable InputStream testCa) throws Exception { + if (testCa == null) { + return (SSLSocketFactory) SSLSocketFactory.getDefault(); + } + KeyStore ks = KeyStore.getInstance("AndroidKeyStore"); + ks.load(null); + CertificateFactory cf = CertificateFactory.getInstance("X.509"); + X509Certificate cert = (X509Certificate) cf.generateCertificate(testCa); + X500Principal principal = cert.getSubjectX500Principal(); + ks.setCertificateEntry(principal.getName("RFC2253"), cert); + // Set up trust manager factory to use our key store. + TrustManagerFactory trustManagerFactory = + TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + trustManagerFactory.init(ks); + SSLContext context = SSLContext.getInstance("TLS"); + context.init(null, trustManagerFactory.getTrustManagers() , null); + return context.getSocketFactory(); + } + + public interface TestListener { + void onPreTest(); + + void onPostTest(String result); + } +} 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 new file mode 100644 index 0000000000..5ecc0317fb --- /dev/null +++ b/android-interop-testing/app/src/main/java/io/grpc/android/integrationtest/TesterActivity.java @@ -0,0 +1,141 @@ +/* + * Copyright 2015, Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +package io.grpc.android.integrationtest; + +import com.google.android.gms.security.ProviderInstaller; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.text.TextUtils; +import android.util.Log; +import android.view.View; +import android.view.inputmethod.InputMethodManager; +import android.widget.Button; +import android.widget.EditText; +import android.widget.TextView; + +import java.util.LinkedList; +import java.util.List; + +public class TesterActivity extends AppCompatActivity + implements ProviderInstaller.ProviderInstallListener { + final static String LOG_TAG = "GrpcTest"; + private List