mirror of https://github.com/grpc/grpc.git
Merge pull request #423 from jtattermusch/interop_testing
Adding interop client for C#pull/436/head
commit
d2785749f8
21 changed files with 3971 additions and 51 deletions
@ -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 |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,170 @@ |
|||||||
|
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 Marshaller<StreamingOutputCallRequest> streamingOutputCallRequestMarshaller = Marshallers.Create((arg) => arg.ToByteArray(), StreamingOutputCallRequest.ParseFrom); |
||||||
|
readonly static Marshaller<StreamingOutputCallResponse> streamingOutputCallResponseMarshaller = Marshallers.Create((arg) => arg.ToByteArray(), StreamingOutputCallResponse.ParseFrom); |
||||||
|
readonly static Marshaller<StreamingInputCallRequest> streamingInputCallRequestMarshaller = Marshallers.Create((arg) => arg.ToByteArray(), StreamingInputCallRequest.ParseFrom); |
||||||
|
readonly static Marshaller<StreamingInputCallResponse> streamingInputCallResponseMarshaller = Marshallers.Create((arg) => arg.ToByteArray(), StreamingInputCallResponse.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 |
||||||
|
); |
||||||
|
readonly static Method<StreamingOutputCallRequest, StreamingOutputCallResponse> streamingOutputCallMethod = new Method<StreamingOutputCallRequest, StreamingOutputCallResponse>( |
||||||
|
MethodType.ServerStreaming, |
||||||
|
"/grpc.testing.TestService/StreamingOutputCall", |
||||||
|
streamingOutputCallRequestMarshaller, |
||||||
|
streamingOutputCallResponseMarshaller |
||||||
|
); |
||||||
|
readonly static Method<StreamingInputCallRequest, StreamingInputCallResponse> streamingInputCallMethod = new Method<StreamingInputCallRequest, StreamingInputCallResponse>( |
||||||
|
MethodType.ClientStreaming, |
||||||
|
"/grpc.testing.TestService/StreamingInputCall", |
||||||
|
streamingInputCallRequestMarshaller, |
||||||
|
streamingInputCallResponseMarshaller |
||||||
|
); |
||||||
|
readonly static Method<StreamingOutputCallRequest, StreamingOutputCallResponse> fullDuplexCallMethod = new Method<StreamingOutputCallRequest, StreamingOutputCallResponse>( |
||||||
|
MethodType.DuplexStreaming, |
||||||
|
"/grpc.testing.TestService/FullDuplexCall", |
||||||
|
streamingOutputCallRequestMarshaller, |
||||||
|
streamingOutputCallResponseMarshaller |
||||||
|
); |
||||||
|
readonly static Method<StreamingOutputCallRequest, StreamingOutputCallResponse> halfDuplexCallMethod = new Method<StreamingOutputCallRequest, StreamingOutputCallResponse>( |
||||||
|
MethodType.DuplexStreaming, |
||||||
|
"/grpc.testing.TestService/HalfDuplexCall", |
||||||
|
streamingOutputCallRequestMarshaller, |
||||||
|
streamingOutputCallResponseMarshaller |
||||||
|
); |
||||||
|
|
||||||
|
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)); |
||||||
|
|
||||||
|
Task StreamingOutputCall(StreamingOutputCallRequest request, IObserver<StreamingOutputCallResponse> responseObserver, CancellationToken token = default(CancellationToken)); |
||||||
|
|
||||||
|
ClientStreamingAsyncResult<StreamingInputCallRequest, StreamingInputCallResponse> StreamingInputCall(CancellationToken token = default(CancellationToken)); |
||||||
|
|
||||||
|
IObserver<StreamingOutputCallRequest> FullDuplexCall(IObserver<StreamingOutputCallResponse> responseObserver, CancellationToken token = default(CancellationToken)); |
||||||
|
|
||||||
|
IObserver<StreamingOutputCallRequest> HalfDuplexCall(IObserver<StreamingOutputCallResponse> responseObserver, CancellationToken token = default(CancellationToken)); |
||||||
|
} |
||||||
|
|
||||||
|
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); |
||||||
|
} |
||||||
|
|
||||||
|
public Task StreamingOutputCall(StreamingOutputCallRequest request, IObserver<StreamingOutputCallResponse> responseObserver, CancellationToken token = default(CancellationToken)) { |
||||||
|
var call = new Google.GRPC.Core.Call<StreamingOutputCallRequest, StreamingOutputCallResponse>(streamingOutputCallMethod, channel); |
||||||
|
return Calls.AsyncServerStreamingCall(call, request, responseObserver, token); |
||||||
|
} |
||||||
|
|
||||||
|
public ClientStreamingAsyncResult<StreamingInputCallRequest, StreamingInputCallResponse> StreamingInputCall(CancellationToken token = default(CancellationToken)) |
||||||
|
{ |
||||||
|
var call = new Google.GRPC.Core.Call<StreamingInputCallRequest, StreamingInputCallResponse>(streamingInputCallMethod, channel); |
||||||
|
return Calls.AsyncClientStreamingCall(call, token); |
||||||
|
} |
||||||
|
|
||||||
|
public IObserver<StreamingOutputCallRequest> FullDuplexCall(IObserver<StreamingOutputCallResponse> responseObserver, CancellationToken token = default(CancellationToken)) |
||||||
|
{ |
||||||
|
var call = new Google.GRPC.Core.Call<StreamingOutputCallRequest, StreamingOutputCallResponse>(fullDuplexCallMethod, channel); |
||||||
|
return Calls.DuplexStreamingCall(call, responseObserver, token); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
public IObserver<StreamingOutputCallRequest> HalfDuplexCall(IObserver<StreamingOutputCallResponse> responseObserver, CancellationToken token = default(CancellationToken)) |
||||||
|
{ |
||||||
|
var call = new Google.GRPC.Core.Call<StreamingOutputCallRequest, StreamingOutputCallResponse>(halfDuplexCallMethod, channel); |
||||||
|
return Calls.DuplexStreamingCall(call, responseObserver, token); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
// server-side interface |
||||||
|
public interface ITestService |
||||||
|
{ |
||||||
|
void EmptyCall(Empty request, IObserver<Empty> responseObserver); |
||||||
|
|
||||||
|
void UnaryCall(SimpleRequest request, IObserver<SimpleResponse> responseObserver); |
||||||
|
|
||||||
|
void StreamingOutputCall(StreamingOutputCallRequest request, IObserver<StreamingOutputCallResponse> responseObserver); |
||||||
|
|
||||||
|
IObserver<StreamingInputCallRequest> StreamingInputCall(IObserver<StreamingInputCallResponse> responseObserver); |
||||||
|
|
||||||
|
IObserver<StreamingOutputCallRequest> FullDuplexCall(IObserver<StreamingOutputCallResponse> responseObserver); |
||||||
|
|
||||||
|
IObserver<StreamingOutputCallRequest> HalfDuplexCall(IObserver<StreamingOutputCallResponse> responseObserver); |
||||||
|
} |
||||||
|
|
||||||
|
public static ServerServiceDefinition BindService(ITestService serviceImpl) |
||||||
|
{ |
||||||
|
return ServerServiceDefinition.CreateBuilder("/grpc.testing.TestService/") |
||||||
|
.AddMethod(emptyCallMethod, serviceImpl.EmptyCall) |
||||||
|
.AddMethod(unaryCallMethod, serviceImpl.UnaryCall) |
||||||
|
.AddMethod(streamingOutputCallMethod, serviceImpl.StreamingOutputCall) |
||||||
|
.AddMethod(streamingInputCallMethod, serviceImpl.StreamingInputCall) |
||||||
|
.AddMethod(fullDuplexCallMethod, serviceImpl.FullDuplexCall) |
||||||
|
.AddMethod(halfDuplexCallMethod, serviceImpl.HalfDuplexCall) |
||||||
|
.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); |
||||||
|
} |
@ -0,0 +1,50 @@ |
|||||||
|
using System; |
||||||
|
using System.Threading.Tasks; |
||||||
|
using System.Collections.Generic; |
||||||
|
using System.Collections.Concurrent; |
||||||
|
|
||||||
|
namespace Google.GRPC.Core.Utils |
||||||
|
{ |
||||||
|
/// <summary> |
||||||
|
/// Observer that allows us to await incoming messages one-by-one. |
||||||
|
/// The implementation is not ideal and class will be probably replaced |
||||||
|
/// by something more versatile in the future. |
||||||
|
/// </summary> |
||||||
|
public class RecordingQueue<T> : IObserver<T> |
||||||
|
{ |
||||||
|
readonly BlockingCollection<T> queue = new BlockingCollection<T>(); |
||||||
|
TaskCompletionSource<object> tcs = new TaskCompletionSource<object>(); |
||||||
|
|
||||||
|
public void OnCompleted() |
||||||
|
{ |
||||||
|
tcs.SetResult(null); |
||||||
|
} |
||||||
|
|
||||||
|
public void OnError(Exception error) |
||||||
|
{ |
||||||
|
tcs.SetException(error); |
||||||
|
} |
||||||
|
|
||||||
|
public void OnNext(T value) |
||||||
|
{ |
||||||
|
queue.Add(value); |
||||||
|
} |
||||||
|
|
||||||
|
public BlockingCollection<T> Queue |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
return queue; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public Task Finished |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
return tcs.Task; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
@ -0,0 +1,303 @@ |
|||||||
|
using System; |
||||||
|
using System.Collections.Generic; |
||||||
|
using NUnit.Framework; |
||||||
|
using System.Text.RegularExpressions; |
||||||
|
using Google.GRPC.Core; |
||||||
|
using Google.GRPC.Core.Utils; |
||||||
|
using Google.ProtocolBuffers; |
||||||
|
using grpc.testing; |
||||||
|
|
||||||
|
namespace Google.GRPC.Interop |
||||||
|
{ |
||||||
|
class Client |
||||||
|
{ |
||||||
|
private class ClientOptions |
||||||
|
{ |
||||||
|
public bool help; |
||||||
|
public string serverHost; |
||||||
|
public string serverHostOverride; |
||||||
|
public int? serverPort; |
||||||
|
public string testCase; |
||||||
|
public bool useTls; |
||||||
|
public bool useTestCa; |
||||||
|
} |
||||||
|
|
||||||
|
ClientOptions options; |
||||||
|
|
||||||
|
private Client(ClientOptions options) |
||||||
|
{ |
||||||
|
this.options = options; |
||||||
|
} |
||||||
|
|
||||||
|
public static void Main(string[] args) |
||||||
|
{ |
||||||
|
Console.WriteLine("gRPC C# interop testing client"); |
||||||
|
ClientOptions options = ParseArguments(args); |
||||||
|
|
||||||
|
if (options.serverHost == null || !options.serverPort.HasValue || options.testCase == null) |
||||||
|
{ |
||||||
|
Console.WriteLine("Missing required argument."); |
||||||
|
Console.WriteLine(); |
||||||
|
options.help = true; |
||||||
|
} |
||||||
|
|
||||||
|
if (options.help) |
||||||
|
{ |
||||||
|
Console.WriteLine("Usage:"); |
||||||
|
Console.WriteLine(" --server_host=HOSTNAME"); |
||||||
|
Console.WriteLine(" --server_host_override=HOSTNAME"); |
||||||
|
Console.WriteLine(" --server_port=PORT"); |
||||||
|
Console.WriteLine(" --test_case=TESTCASE"); |
||||||
|
Console.WriteLine(" --use_tls=BOOLEAN"); |
||||||
|
Console.WriteLine(" --use_test_ca=BOOLEAN"); |
||||||
|
Console.WriteLine(); |
||||||
|
Environment.Exit(1); |
||||||
|
} |
||||||
|
|
||||||
|
var interopClient = new Client(options); |
||||||
|
interopClient.Run(); |
||||||
|
} |
||||||
|
|
||||||
|
private void Run() |
||||||
|
{ |
||||||
|
string addr = string.Format("{0}:{1}", options.serverHost, options.serverPort); |
||||||
|
using (Channel channel = new Channel(addr)) |
||||||
|
{ |
||||||
|
TestServiceGrpc.ITestServiceClient client = new TestServiceGrpc.TestServiceClientStub(channel); |
||||||
|
|
||||||
|
RunTestCase(options.testCase, client); |
||||||
|
} |
||||||
|
|
||||||
|
GrpcEnvironment.Shutdown(); |
||||||
|
} |
||||||
|
|
||||||
|
private void RunTestCase(string testCase, TestServiceGrpc.ITestServiceClient client) |
||||||
|
{ |
||||||
|
switch (testCase) |
||||||
|
{ |
||||||
|
case "empty_unary": |
||||||
|
RunEmptyUnary(client); |
||||||
|
break; |
||||||
|
case "large_unary": |
||||||
|
RunLargeUnary(client); |
||||||
|
break; |
||||||
|
case "client_streaming": |
||||||
|
RunClientStreaming(client); |
||||||
|
break; |
||||||
|
case "server_streaming": |
||||||
|
RunServerStreaming(client); |
||||||
|
break; |
||||||
|
case "ping_pong": |
||||||
|
RunPingPong(client); |
||||||
|
break; |
||||||
|
case "empty_stream": |
||||||
|
RunEmptyStream(client); |
||||||
|
break; |
||||||
|
default: |
||||||
|
throw new ArgumentException("Unknown test case " + testCase); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void RunEmptyUnary(TestServiceGrpc.ITestServiceClient client) |
||||||
|
{ |
||||||
|
Console.WriteLine("running empty_unary"); |
||||||
|
var response = client.EmptyCall(Empty.DefaultInstance); |
||||||
|
Assert.IsNotNull(response); |
||||||
|
Console.WriteLine("Passed!"); |
||||||
|
} |
||||||
|
|
||||||
|
private void RunLargeUnary(TestServiceGrpc.ITestServiceClient client) |
||||||
|
{ |
||||||
|
Console.WriteLine("running large_unary"); |
||||||
|
var request = SimpleRequest.CreateBuilder() |
||||||
|
.SetResponseType(PayloadType.COMPRESSABLE) |
||||||
|
.SetResponseSize(314159) |
||||||
|
.SetPayload(CreateZerosPayload(271828)) |
||||||
|
.Build(); |
||||||
|
|
||||||
|
var response = client.UnaryCall(request); |
||||||
|
|
||||||
|
Assert.AreEqual(PayloadType.COMPRESSABLE, response.Payload.Type); |
||||||
|
Assert.AreEqual(314159, response.Payload.Body.Length); |
||||||
|
Console.WriteLine("Passed!"); |
||||||
|
} |
||||||
|
|
||||||
|
private void RunClientStreaming(TestServiceGrpc.ITestServiceClient client) |
||||||
|
{ |
||||||
|
Console.WriteLine("running client_streaming"); |
||||||
|
|
||||||
|
var bodySizes = new List<int>{27182, 8, 1828, 45904}; |
||||||
|
|
||||||
|
var context = client.StreamingInputCall(); |
||||||
|
foreach (var size in bodySizes) |
||||||
|
{ |
||||||
|
context.Inputs.OnNext( |
||||||
|
StreamingInputCallRequest.CreateBuilder().SetPayload(CreateZerosPayload(size)).Build()); |
||||||
|
} |
||||||
|
context.Inputs.OnCompleted(); |
||||||
|
|
||||||
|
var response = context.Task.Result; |
||||||
|
Assert.AreEqual(74922, response.AggregatedPayloadSize); |
||||||
|
Console.WriteLine("Passed!"); |
||||||
|
} |
||||||
|
|
||||||
|
private void RunServerStreaming(TestServiceGrpc.ITestServiceClient client) |
||||||
|
{ |
||||||
|
Console.WriteLine("running server_streaming"); |
||||||
|
|
||||||
|
var bodySizes = new List<int>{31415, 9, 2653, 58979}; |
||||||
|
|
||||||
|
var request = StreamingOutputCallRequest.CreateBuilder() |
||||||
|
.SetResponseType(PayloadType.COMPRESSABLE) |
||||||
|
.AddRangeResponseParameters(bodySizes.ConvertAll( |
||||||
|
(size) => ResponseParameters.CreateBuilder().SetSize(size).Build())) |
||||||
|
.Build(); |
||||||
|
|
||||||
|
var recorder = new RecordingObserver<StreamingOutputCallResponse>(); |
||||||
|
client.StreamingOutputCall(request, recorder); |
||||||
|
|
||||||
|
var responseList = recorder.ToList().Result; |
||||||
|
|
||||||
|
foreach (var res in responseList) |
||||||
|
{ |
||||||
|
Assert.AreEqual(PayloadType.COMPRESSABLE, res.Payload.Type); |
||||||
|
} |
||||||
|
CollectionAssert.AreEqual(bodySizes, responseList.ConvertAll((item) => item.Payload.Body.Length)); |
||||||
|
Console.WriteLine("Passed!"); |
||||||
|
} |
||||||
|
|
||||||
|
private void RunPingPong(TestServiceGrpc.ITestServiceClient client) |
||||||
|
{ |
||||||
|
Console.WriteLine("running ping_pong"); |
||||||
|
|
||||||
|
var recorder = new RecordingQueue<StreamingOutputCallResponse>(); |
||||||
|
var inputs = client.FullDuplexCall(recorder); |
||||||
|
|
||||||
|
StreamingOutputCallResponse response; |
||||||
|
|
||||||
|
inputs.OnNext(StreamingOutputCallRequest.CreateBuilder() |
||||||
|
.SetResponseType(PayloadType.COMPRESSABLE) |
||||||
|
.AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(31415)) |
||||||
|
.SetPayload(CreateZerosPayload(27182)).Build()); |
||||||
|
|
||||||
|
response = recorder.Queue.Take(); |
||||||
|
Assert.AreEqual(PayloadType.COMPRESSABLE, response.Payload.Type); |
||||||
|
Assert.AreEqual(31415, response.Payload.Body.Length); |
||||||
|
|
||||||
|
inputs.OnNext(StreamingOutputCallRequest.CreateBuilder() |
||||||
|
.SetResponseType(PayloadType.COMPRESSABLE) |
||||||
|
.AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(9)) |
||||||
|
.SetPayload(CreateZerosPayload(8)).Build()); |
||||||
|
|
||||||
|
response = recorder.Queue.Take(); |
||||||
|
Assert.AreEqual(PayloadType.COMPRESSABLE, response.Payload.Type); |
||||||
|
Assert.AreEqual(9, response.Payload.Body.Length); |
||||||
|
|
||||||
|
inputs.OnNext(StreamingOutputCallRequest.CreateBuilder() |
||||||
|
.SetResponseType(PayloadType.COMPRESSABLE) |
||||||
|
.AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(2635)) |
||||||
|
.SetPayload(CreateZerosPayload(1828)).Build()); |
||||||
|
|
||||||
|
response = recorder.Queue.Take(); |
||||||
|
Assert.AreEqual(PayloadType.COMPRESSABLE, response.Payload.Type); |
||||||
|
Assert.AreEqual(2653, response.Payload.Body.Length); |
||||||
|
|
||||||
|
|
||||||
|
inputs.OnNext(StreamingOutputCallRequest.CreateBuilder() |
||||||
|
.SetResponseType(PayloadType.COMPRESSABLE) |
||||||
|
.AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(58979)) |
||||||
|
.SetPayload(CreateZerosPayload(45904)).Build()); |
||||||
|
|
||||||
|
response = recorder.Queue.Take(); |
||||||
|
Assert.AreEqual(PayloadType.COMPRESSABLE, response.Payload.Type); |
||||||
|
Assert.AreEqual(58979, response.Payload.Body.Length); |
||||||
|
|
||||||
|
recorder.Finished.Wait(); |
||||||
|
Assert.AreEqual(0, recorder.Queue.Count); |
||||||
|
|
||||||
|
Console.WriteLine("Passed!"); |
||||||
|
} |
||||||
|
|
||||||
|
private void RunEmptyStream(TestServiceGrpc.ITestServiceClient client) |
||||||
|
{ |
||||||
|
Console.WriteLine("running empty_stream"); |
||||||
|
|
||||||
|
var recorder = new RecordingObserver<StreamingOutputCallResponse>(); |
||||||
|
var inputs = client.FullDuplexCall(recorder); |
||||||
|
inputs.OnCompleted(); |
||||||
|
|
||||||
|
var responseList = recorder.ToList().Result; |
||||||
|
Assert.AreEqual(0, responseList.Count); |
||||||
|
|
||||||
|
Console.WriteLine("Passed!"); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
private Payload CreateZerosPayload(int size) { |
||||||
|
return Payload.CreateBuilder().SetBody(ByteString.CopyFrom(new byte[size])).Build(); |
||||||
|
} |
||||||
|
|
||||||
|
private static ClientOptions ParseArguments(string[] args) |
||||||
|
{ |
||||||
|
var options = new ClientOptions(); |
||||||
|
foreach(string arg in args) |
||||||
|
{ |
||||||
|
ParseArgument(arg, options); |
||||||
|
if (options.help) |
||||||
|
{ |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
return options; |
||||||
|
} |
||||||
|
|
||||||
|
private static void ParseArgument(string arg, ClientOptions options) |
||||||
|
{ |
||||||
|
Match match; |
||||||
|
match = Regex.Match(arg, "--server_host=(.*)"); |
||||||
|
if (match.Success) |
||||||
|
{ |
||||||
|
options.serverHost = match.Groups[1].Value.Trim(); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
match = Regex.Match(arg, "--server_host_override=(.*)"); |
||||||
|
if (match.Success) |
||||||
|
{ |
||||||
|
options.serverHostOverride = match.Groups[1].Value.Trim(); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
match = Regex.Match(arg, "--server_port=(.*)"); |
||||||
|
if (match.Success) |
||||||
|
{ |
||||||
|
options.serverPort = int.Parse(match.Groups[1].Value.Trim()); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
match = Regex.Match(arg, "--test_case=(.*)"); |
||||||
|
if (match.Success) |
||||||
|
{ |
||||||
|
options.testCase = match.Groups[1].Value.Trim(); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
match = Regex.Match(arg, "--use_tls=(.*)"); |
||||||
|
if (match.Success) |
||||||
|
{ |
||||||
|
options.useTls = bool.Parse(match.Groups[1].Value.Trim()); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
match = Regex.Match(arg, "--use_test_ca=(.*)"); |
||||||
|
if (match.Success) |
||||||
|
{ |
||||||
|
options.useTestCa = bool.Parse(match.Groups[1].Value.Trim()); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
Console.WriteLine(string.Format("Unrecognized argument \"{0}\"", arg)); |
||||||
|
options.help = true; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,59 @@ |
|||||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||||
|
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||||
|
<PropertyGroup> |
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
||||||
|
<Platform Condition=" '$(Platform)' == '' ">x86</Platform> |
||||||
|
<ProductVersion>10.0.0</ProductVersion> |
||||||
|
<SchemaVersion>2.0</SchemaVersion> |
||||||
|
<ProjectGuid>{C61154BA-DD4A-4838-8420-0162A28925E0}</ProjectGuid> |
||||||
|
<OutputType>Exe</OutputType> |
||||||
|
<RootNamespace>InteropClient</RootNamespace> |
||||||
|
<AssemblyName>InteropClient</AssemblyName> |
||||||
|
<StartupObject>Google.GRPC.Interop.Client</StartupObject> |
||||||
|
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion> |
||||||
|
</PropertyGroup> |
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' "> |
||||||
|
<DebugSymbols>true</DebugSymbols> |
||||||
|
<DebugType>full</DebugType> |
||||||
|
<Optimize>false</Optimize> |
||||||
|
<OutputPath>bin\Debug</OutputPath> |
||||||
|
<DefineConstants>DEBUG;</DefineConstants> |
||||||
|
<ErrorReport>prompt</ErrorReport> |
||||||
|
<WarningLevel>4</WarningLevel> |
||||||
|
<Externalconsole>true</Externalconsole> |
||||||
|
<PlatformTarget>x86</PlatformTarget> |
||||||
|
</PropertyGroup> |
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' "> |
||||||
|
<DebugType>full</DebugType> |
||||||
|
<Optimize>true</Optimize> |
||||||
|
<OutputPath>bin\Release</OutputPath> |
||||||
|
<ErrorReport>prompt</ErrorReport> |
||||||
|
<WarningLevel>4</WarningLevel> |
||||||
|
<Externalconsole>true</Externalconsole> |
||||||
|
<PlatformTarget>x86</PlatformTarget> |
||||||
|
</PropertyGroup> |
||||||
|
<ItemGroup> |
||||||
|
<Reference Include="System" /> |
||||||
|
<Reference Include="nunit.framework, Version=2.6.0.0, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77"> |
||||||
|
<Private>False</Private> |
||||||
|
</Reference> |
||||||
|
<Reference Include="Google.ProtocolBuffers"> |
||||||
|
<HintPath>..\lib\Google.ProtocolBuffers.dll</HintPath> |
||||||
|
</Reference> |
||||||
|
</ItemGroup> |
||||||
|
<ItemGroup> |
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" /> |
||||||
|
<Compile Include="Client.cs" /> |
||||||
|
</ItemGroup> |
||||||
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> |
||||||
|
<ItemGroup> |
||||||
|
<ProjectReference Include="..\GrpcCore\GrpcCore.csproj"> |
||||||
|
<Project>{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}</Project> |
||||||
|
<Name>GrpcCore</Name> |
||||||
|
</ProjectReference> |
||||||
|
<ProjectReference Include="..\GrpcApi\GrpcApi.csproj"> |
||||||
|
<Project>{7DC1433E-3225-42C7-B7EA-546D56E27A4B}</Project> |
||||||
|
<Name>GrpcApi</Name> |
||||||
|
</ProjectReference> |
||||||
|
</ItemGroup> |
||||||
|
</Project> |
@ -0,0 +1,22 @@ |
|||||||
|
using System.Reflection; |
||||||
|
using System.Runtime.CompilerServices; |
||||||
|
|
||||||
|
// Information about this assembly is defined by the following attributes. |
||||||
|
// Change them to the values specific to your project. |
||||||
|
[assembly: AssemblyTitle("InteropClient")] |
||||||
|
[assembly: AssemblyDescription("")] |
||||||
|
[assembly: AssemblyConfiguration("")] |
||||||
|
[assembly: AssemblyCompany("")] |
||||||
|
[assembly: AssemblyProduct("")] |
||||||
|
[assembly: AssemblyCopyright("jtattermusch")] |
||||||
|
[assembly: AssemblyTrademark("")] |
||||||
|
[assembly: AssemblyCulture("")] |
||||||
|
// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". |
||||||
|
// The form "{Major}.{Minor}.*" will automatically update the build and revision, |
||||||
|
// and "{Major}.{Minor}.{Build}.*" will update just the revision. |
||||||
|
[assembly: AssemblyVersion("1.0.*")] |
||||||
|
// The following attributes are used to specify the signing key for the assembly, |
||||||
|
// if desired. See the Mono documentation for more information about signing. |
||||||
|
//[assembly: AssemblyDelaySign(false)] |
||||||
|
//[assembly: AssemblyKeyFile("")] |
||||||
|
|
@ -0,0 +1 @@ |
|||||||
|
bin |
Loading…
Reference in new issue