Added simplified TestService for interop testing

pull/423/head
Jan Tattermusch 10 years ago
parent 8a7424ad90
commit a4b63bfc6b
  1. 282
      src/csharp/GrpcApi/Empty.cs
  2. 12
      src/csharp/GrpcApi/GrpcApi.csproj
  3. 2922
      src/csharp/GrpcApi/Messages.cs
  4. 103
      src/csharp/GrpcApi/TestServiceGrpc.cs
  5. 13
      src/csharp/GrpcApi/proto/empty.proto
  6. 0
      src/csharp/GrpcApi/proto/math.proto
  7. 102
      src/csharp/GrpcApi/proto/messages.proto
  8. 42
      src/csharp/GrpcApi/proto/test.proto

@ -0,0 +1,282 @@
// Generated by ProtoGen, Version=2.4.1.521, Culture=neutral, PublicKeyToken=17b3b1f090c3ea48. DO NOT EDIT!
#pragma warning disable 1591, 0612, 3021
#region Designer generated code
using pb = global::Google.ProtocolBuffers;
using pbc = global::Google.ProtocolBuffers.Collections;
using pbd = global::Google.ProtocolBuffers.Descriptors;
using scg = global::System.Collections.Generic;
namespace grpc.testing {
namespace Proto {
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public static partial class Empty {
#region Extension registration
public static void RegisterAllExtensions(pb::ExtensionRegistry registry) {
}
#endregion
#region Static variables
internal static pbd::MessageDescriptor internal__static_grpc_testing_Empty__Descriptor;
internal static pb::FieldAccess.FieldAccessorTable<global::grpc.testing.Empty, global::grpc.testing.Empty.Builder> internal__static_grpc_testing_Empty__FieldAccessorTable;
#endregion
#region Descriptor
public static pbd::FileDescriptor Descriptor {
get { return descriptor; }
}
private static pbd::FileDescriptor descriptor;
static Empty() {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
"CgtlbXB0eS5wcm90bxIMZ3JwYy50ZXN0aW5nIgcKBUVtcHR5"));
pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {
descriptor = root;
internal__static_grpc_testing_Empty__Descriptor = Descriptor.MessageTypes[0];
internal__static_grpc_testing_Empty__FieldAccessorTable =
new pb::FieldAccess.FieldAccessorTable<global::grpc.testing.Empty, global::grpc.testing.Empty.Builder>(internal__static_grpc_testing_Empty__Descriptor,
new string[] { });
return null;
};
pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
new pbd::FileDescriptor[] {
}, assigner);
}
#endregion
}
}
#region Messages
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class Empty : pb::GeneratedMessage<Empty, Empty.Builder> {
private Empty() { }
private static readonly Empty defaultInstance = new Empty().MakeReadOnly();
private static readonly string[] _emptyFieldNames = new string[] { };
private static readonly uint[] _emptyFieldTags = new uint[] { };
public static Empty DefaultInstance {
get { return defaultInstance; }
}
public override Empty DefaultInstanceForType {
get { return DefaultInstance; }
}
protected override Empty ThisMessage {
get { return this; }
}
public static pbd::MessageDescriptor Descriptor {
get { return global::grpc.testing.Proto.Empty.internal__static_grpc_testing_Empty__Descriptor; }
}
protected override pb::FieldAccess.FieldAccessorTable<Empty, Empty.Builder> InternalFieldAccessors {
get { return global::grpc.testing.Proto.Empty.internal__static_grpc_testing_Empty__FieldAccessorTable; }
}
public override bool IsInitialized {
get {
return true;
}
}
public override void WriteTo(pb::ICodedOutputStream output) {
int size = SerializedSize;
string[] field_names = _emptyFieldNames;
UnknownFields.WriteTo(output);
}
private int memoizedSerializedSize = -1;
public override int SerializedSize {
get {
int size = memoizedSerializedSize;
if (size != -1) return size;
size = 0;
size += UnknownFields.SerializedSize;
memoizedSerializedSize = size;
return size;
}
}
public static Empty ParseFrom(pb::ByteString data) {
return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
}
public static Empty ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
}
public static Empty ParseFrom(byte[] data) {
return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
}
public static Empty ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
}
public static Empty ParseFrom(global::System.IO.Stream input) {
return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
}
public static Empty ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
}
public static Empty ParseDelimitedFrom(global::System.IO.Stream input) {
return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
}
public static Empty ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
}
public static Empty ParseFrom(pb::ICodedInputStream input) {
return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
}
public static Empty ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
}
private Empty MakeReadOnly() {
return this;
}
public static Builder CreateBuilder() { return new Builder(); }
public override Builder ToBuilder() { return CreateBuilder(this); }
public override Builder CreateBuilderForType() { return new Builder(); }
public static Builder CreateBuilder(Empty prototype) {
return new Builder(prototype);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public sealed partial class Builder : pb::GeneratedBuilder<Empty, Builder> {
protected override Builder ThisBuilder {
get { return this; }
}
public Builder() {
result = DefaultInstance;
resultIsReadOnly = true;
}
internal Builder(Empty cloneFrom) {
result = cloneFrom;
resultIsReadOnly = true;
}
private bool resultIsReadOnly;
private Empty result;
private Empty PrepareBuilder() {
if (resultIsReadOnly) {
Empty original = result;
result = new Empty();
resultIsReadOnly = false;
MergeFrom(original);
}
return result;
}
public override bool IsInitialized {
get { return result.IsInitialized; }
}
protected override Empty MessageBeingBuilt {
get { return PrepareBuilder(); }
}
public override Builder Clear() {
result = DefaultInstance;
resultIsReadOnly = true;
return this;
}
public override Builder Clone() {
if (resultIsReadOnly) {
return new Builder(result);
} else {
return new Builder().MergeFrom(result);
}
}
public override pbd::MessageDescriptor DescriptorForType {
get { return global::grpc.testing.Empty.Descriptor; }
}
public override Empty DefaultInstanceForType {
get { return global::grpc.testing.Empty.DefaultInstance; }
}
public override Empty BuildPartial() {
if (resultIsReadOnly) {
return result;
}
resultIsReadOnly = true;
return result.MakeReadOnly();
}
public override Builder MergeFrom(pb::IMessage other) {
if (other is Empty) {
return MergeFrom((Empty) other);
} else {
base.MergeFrom(other);
return this;
}
}
public override Builder MergeFrom(Empty other) {
if (other == global::grpc.testing.Empty.DefaultInstance) return this;
PrepareBuilder();
this.MergeUnknownFields(other.UnknownFields);
return this;
}
public override Builder MergeFrom(pb::ICodedInputStream input) {
return MergeFrom(input, pb::ExtensionRegistry.Empty);
}
public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
PrepareBuilder();
pb::UnknownFieldSet.Builder unknownFields = null;
uint tag;
string field_name;
while (input.ReadTag(out tag, out field_name)) {
if(tag == 0 && field_name != null) {
int field_ordinal = global::System.Array.BinarySearch(_emptyFieldNames, field_name, global::System.StringComparer.Ordinal);
if(field_ordinal >= 0)
tag = _emptyFieldTags[field_ordinal];
else {
if (unknownFields == null) {
unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
}
ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
continue;
}
}
switch (tag) {
case 0: {
throw pb::InvalidProtocolBufferException.InvalidTag();
}
default: {
if (pb::WireFormat.IsEndGroupTag(tag)) {
if (unknownFields != null) {
this.UnknownFields = unknownFields.Build();
}
return this;
}
if (unknownFields == null) {
unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
}
ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
break;
}
}
}
if (unknownFields != null) {
this.UnknownFields = unknownFields.Build();
}
return this;
}
}
static Empty() {
object.ReferenceEquals(global::grpc.testing.Proto.Empty.Descriptor, null);
}
}
#endregion
}
#endregion Designer generated code

@ -51,6 +51,9 @@
<Compile Include="Math.cs" />
<Compile Include="MathGrpc.cs" />
<Compile Include="MathServiceImpl.cs" />
<Compile Include="Empty.cs" />
<Compile Include="Messages.cs" />
<Compile Include="TestServiceGrpc.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>
@ -59,4 +62,13 @@
<Name>GrpcCore</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="proto\math.proto" />
<None Include="proto\empty.proto" />
<None Include="proto\messages.proto" />
<None Include="proto\test.proto" />
</ItemGroup>
<ItemGroup>
<Folder Include="proto\" />
</ItemGroup>
</Project>

File diff suppressed because it is too large Load Diff

@ -0,0 +1,103 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Reactive.Linq;
using Google.GRPC.Core;
namespace grpc.testing
{
/// <summary>
/// TestService (this is handwritten version of code that will normally be generated).
/// </summary>
public class TestServiceGrpc
{
readonly static Marshaller<Empty> emptyMarshaller = Marshallers.Create((arg) => arg.ToByteArray(), Empty.ParseFrom);
readonly static Marshaller<SimpleRequest> simpleRequestMarshaller = Marshallers.Create((arg) => arg.ToByteArray(), SimpleRequest.ParseFrom);
readonly static Marshaller<SimpleResponse> simpleResponseMarshaller = Marshallers.Create((arg) => arg.ToByteArray(), SimpleResponse.ParseFrom);
readonly static Method<Empty, Empty> emptyCallMethod = new Method<Empty, Empty>(
MethodType.Unary,
"/grpc.testing.TestService/EmptyCall",
emptyMarshaller,
emptyMarshaller
);
readonly static Method<SimpleRequest, SimpleResponse> unaryCallMethod = new Method<SimpleRequest, SimpleResponse>(
MethodType.Unary,
"/grpc.testing.TestService/UnaryCall",
simpleRequestMarshaller,
simpleResponseMarshaller
);
public interface ITestServiceClient
{
Empty EmptyCall(Empty request, CancellationToken token = default(CancellationToken));
Task<Empty> EmptyCallAsync(Empty request, CancellationToken token = default(CancellationToken));
SimpleResponse UnaryCall(SimpleRequest request, CancellationToken token = default(CancellationToken));
Task<SimpleResponse> UnaryCallAsync(SimpleRequest request, CancellationToken token = default(CancellationToken));
// TODO: StreamingOutputCall
// TODO: StreamingInputCall
// TODO: FullDuplexCall
// TODO: HalfDuplexCall
}
public class TestServiceClientStub : ITestServiceClient
{
readonly Channel channel;
public TestServiceClientStub(Channel channel)
{
this.channel = channel;
}
public Empty EmptyCall(Empty request, CancellationToken token = default(CancellationToken))
{
var call = new Google.GRPC.Core.Call<Empty, Empty>(emptyCallMethod, channel);
return Calls.BlockingUnaryCall(call, request, token);
}
public Task<Empty> EmptyCallAsync(Empty request, CancellationToken token = default(CancellationToken))
{
var call = new Google.GRPC.Core.Call<Empty, Empty>(emptyCallMethod, channel);
return Calls.AsyncUnaryCall(call, request, token);
}
public SimpleResponse UnaryCall(SimpleRequest request, CancellationToken token = default(CancellationToken))
{
var call = new Google.GRPC.Core.Call<SimpleRequest, SimpleResponse>(unaryCallMethod, channel);
return Calls.BlockingUnaryCall(call, request, token);
}
public Task<SimpleResponse> UnaryCallAsync(SimpleRequest request, CancellationToken token = default(CancellationToken))
{
var call = new Google.GRPC.Core.Call<SimpleRequest, SimpleResponse>(unaryCallMethod, channel);
return Calls.AsyncUnaryCall(call, request, token);
}
}
// server-side interface
public interface ITestService
{
void EmptyCall(Empty request, IObserver<Empty> responseObserver);
void UnaryCall(SimpleRequest request, IObserver<SimpleResponse> responseObserver);
}
public static ServerServiceDefinition BindService(ITestService serviceImpl)
{
return ServerServiceDefinition.CreateBuilder("/grpc.testing.TestService/")
.AddMethod(emptyCallMethod, serviceImpl.EmptyCall)
.AddMethod(unaryCallMethod, serviceImpl.UnaryCall)
.Build();
}
public static ITestServiceClient NewStub(Channel channel)
{
return new TestServiceClientStub(channel);
}
}
}

@ -0,0 +1,13 @@
syntax = "proto2";
package grpc.testing;
// 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 {}

@ -0,0 +1,102 @@
// Message definitions to be used by integration test service definitions.
syntax = "proto2";
package grpc.testing;
// 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.
optional PayloadType type = 1;
// Primary contents of payload.
optional 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.
optional PayloadType response_type = 1;
// Desired payload size in the response from the server.
// If response_type is COMPRESSABLE, this denotes the size before compression.
optional int32 response_size = 2;
// Optional input payload sent along with the request.
optional Payload payload = 3;
// Whether SimpleResponse should include username.
optional bool fill_username = 4;
// Whether SimpleResponse should include OAuth scope.
optional bool fill_oauth_scope = 5;
}
// Unary response, as configured by the request.
message SimpleResponse {
// Payload to increase message size.
optional Payload payload = 1;
// The user the request came from, for verifying authentication was
// successful when the client expected it.
optional string username = 2;
// OAuth scope.
optional string oauth_scope = 3;
}
// Client-streaming request.
message StreamingInputCallRequest {
// Optional input payload sent along with the request.
optional Payload payload = 1;
// Not expecting any payload from the response.
}
// Client-streaming response.
message StreamingInputCallResponse {
// Aggregated size of payloads received from the client.
optional 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.
optional int32 size = 1;
// Desired interval between consecutive responses in the response stream in
// microseconds.
optional 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.
optional PayloadType response_type = 1;
// Configuration for each expected response message.
repeated ResponseParameters response_parameters = 2;
// Optional input payload sent along with the request.
optional Payload payload = 3;
}
// Server-streaming response, as configured by the request and parameters.
message StreamingOutputCallResponse {
// Payload to increase response size.
optional Payload payload = 1;
}

@ -0,0 +1,42 @@
// An integration test service that covers all the method signature permutations
// of unary/streaming requests/responses.
syntax = "proto2";
import "empty.proto";
import "messages.proto";
package grpc.testing;
// 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.
// The server returns the client payload as-is.
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);
}
Loading…
Cancel
Save