Merge github.com:grpc/grpc into c++api

pull/501/head
Craig Tiller 10 years ago
commit b00b68716a
  1. 12
      src/csharp/Grpc.sln
  2. 282
      src/csharp/GrpcApi/Empty.cs
  3. 14
      src/csharp/GrpcApi/GrpcApi.csproj
  4. 2
      src/csharp/GrpcApi/MathExamples.cs
  5. 2922
      src/csharp/GrpcApi/Messages.cs
  6. 170
      src/csharp/GrpcApi/TestServiceGrpc.cs
  7. 13
      src/csharp/GrpcApi/proto/empty.proto
  8. 0
      src/csharp/GrpcApi/proto/math.proto
  9. 102
      src/csharp/GrpcApi/proto/messages.proto
  10. 42
      src/csharp/GrpcApi/proto/test.proto
  11. 1
      src/csharp/GrpcCore/GrpcCore.csproj
  12. 50
      src/csharp/GrpcCore/Utils/RecordingQueue.cs
  13. 0
      src/csharp/InteropClient/.gitignore
  14. 303
      src/csharp/InteropClient/Client.cs
  15. 59
      src/csharp/InteropClient/InteropClient.csproj
  16. 22
      src/csharp/InteropClient/Properties/AssemblyInfo.cs
  17. 1
      src/csharp/MathClient/.gitignore
  18. 14
      src/csharp/MathClient/MathClient.cs
  19. 2
      src/csharp/MathClient/MathClient.csproj
  20. 2
      src/csharp/MathClient/Properties/AssemblyInfo.cs
  21. 9
      src/csharp/README.md
  22. 3
      src/node/examples/math_server.js
  23. 14
      src/node/examples/stock.proto
  24. 3
      src/node/examples/stock_client.js
  25. 7
      src/node/examples/stock_server.js
  26. 29
      src/node/ext/event.cc
  27. 8
      src/node/test/call_test.js
  28. 2
      src/ruby/bin/math_client.rb
  29. 11
      src/ruby/ext/grpc/rb_event.c
  30. 1
      src/ruby/lib/grpc/generic/rpc_desc.rb
  31. 8
      src/ruby/spec/call_spec.rb
  32. 5
      src/ruby/spec/client_server_spec.rb
  33. 4
      src/ruby/spec/event_spec.rb
  34. 9
      src/ruby/spec/generic/active_call_spec.rb
  35. 10
      src/ruby/spec/generic/client_stub_spec.rb
  36. 4
      src/ruby/spec/generic/rpc_desc_spec.rb

@ -1,8 +1,6 @@

Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GrpcDemo", "GrpcDemo\GrpcDemo.csproj", "{61ECB8EE-0C96-4F8E-B187-8E4D227417C0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GrpcApi", "GrpcApi\GrpcApi.csproj", "{7DC1433E-3225-42C7-B7EA-546D56E27A4B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GrpcCore", "GrpcCore\GrpcCore.csproj", "{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}"
@ -11,6 +9,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GrpcCoreTests", "GrpcCoreTe
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GrpcApiTests", "GrpcApiTests\GrpcApiTests.csproj", "{143B1C29-C442-4BE0-BF3F-A8F92288AC9F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MathClient", "MathClient\MathClient.csproj", "{61ECB8EE-0C96-4F8E-B187-8E4D227417C0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InteropClient", "InteropClient\InteropClient.csproj", "{C61154BA-DD4A-4838-8420-0162A28925E0}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x86 = Debug|x86
@ -33,12 +35,16 @@ Global
{86EC5CB4-4EA2-40A2-8057-86542A0353BB}.Debug|x86.Build.0 = Debug|Any CPU
{86EC5CB4-4EA2-40A2-8057-86542A0353BB}.Release|x86.ActiveCfg = Release|Any CPU
{86EC5CB4-4EA2-40A2-8057-86542A0353BB}.Release|x86.Build.0 = Release|Any CPU
{C61154BA-DD4A-4838-8420-0162A28925E0}.Debug|x86.ActiveCfg = Debug|x86
{C61154BA-DD4A-4838-8420-0162A28925E0}.Debug|x86.Build.0 = Debug|x86
{C61154BA-DD4A-4838-8420-0162A28925E0}.Release|x86.ActiveCfg = Release|x86
{C61154BA-DD4A-4838-8420-0162A28925E0}.Release|x86.Build.0 = Release|x86
{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}.Debug|x86.ActiveCfg = Debug|Any CPU
{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}.Debug|x86.Build.0 = Debug|Any CPU
{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}.Release|x86.ActiveCfg = Release|Any CPU
{CCC4440E-49F7-4790-B0AF-FEABB0837AE7}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
StartupItem = GrpcDemo\GrpcDemo.csproj
StartupItem = InteropClient\InteropClient.csproj
EndGlobalSection
EndGlobal

@ -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

@ -47,10 +47,13 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Examples.cs" />
<Compile Include="Math.cs" />
<Compile Include="MathGrpc.cs" />
<Compile Include="MathServiceImpl.cs" />
<Compile Include="Empty.cs" />
<Compile Include="Messages.cs" />
<Compile Include="TestServiceGrpc.cs" />
<Compile Include="MathExamples.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>

@ -6,7 +6,7 @@ using Google.GRPC.Core.Utils;
namespace math
{
public class Examples
public static class MathExamples
{
public static void DivExample(MathGrpc.IMathServiceClient stub)
{

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);
}

@ -62,6 +62,7 @@
<Compile Include="ServerServiceDefinition.cs" />
<Compile Include="Utils\RecordingObserver.cs" />
<Compile Include="Utils\PortPicker.cs" />
<Compile Include="Utils\RecordingQueue.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>

@ -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("")]

@ -2,25 +2,23 @@ using System;
using System.Runtime.InteropServices;
using Google.GRPC.Core;
using System.Threading;
using math;
namespace Google.GRPC.Demo
namespace math
{
class MainClass
class MathClient
{
public static void Main (string[] args)
{
using (Channel channel = new Channel("127.0.0.1:23456"))
{
MathGrpc.IMathServiceClient stub = new MathGrpc.MathServiceClientStub(channel);
Examples.DivExample(stub);
MathExamples.DivExample(stub);
Examples.FibExample(stub);
MathExamples.FibExample(stub);
Examples.SumExample(stub);
MathExamples.SumExample(stub);
Examples.DivManyExample(stub);
MathExamples.DivManyExample(stub);
}
GrpcEnvironment.Shutdown();

@ -35,8 +35,8 @@
<Reference Include="System" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="MathClient.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>

@ -3,7 +3,7 @@ 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 ("GrpcDemo")]
[assembly: AssemblyTitle ("MathClient")]
[assembly: AssemblyDescription ("")]
[assembly: AssemblyConfiguration ("")]
[assembly: AssemblyCompany ("")]

@ -47,8 +47,11 @@ CONTENTS
- ext:
The extension library that wraps C API to be more digestible by C#.
- GrpcApi:
API examples for math.proto and testservice.proto
- GrpcCore:
The main gRPC C# library.
- GrpcApi:
API examples for math.proto.
- InteropClient:
Client for interop testing.
- MathClient:
An example client that sends some requests to math server.

@ -128,7 +128,8 @@ var server = new Server({
});
if (require.main === module) {
server.bind('localhost:7070').listen();
server.bind('0.0.0.0:7070');
server.listen();
}
/**

@ -35,28 +35,28 @@ package examples;
message StockRequest {
optional string symbol = 1;
optional int32 num_trades_to_watch = 2 [default=0];
};
}
message StockReply {
optional float price = 1;
optional string symbol = 2;
};
}
// Interface exported by the server
service Stock {
// Simple blocking RPC
rpc GetLastTradePrice(StockRequest) returns (StockReply) {
};
}
// Bidirectional streaming RPC
rpc GetLastTradePriceMultiple(stream StockRequest) returns
(stream StockReply) {
};
}
// Unidirectional server-to-client streaming RPC
rpc WatchFutureTrades(StockRequest) returns (stream StockReply) {
};
}
// Unidirectional client-to-server streaming RPC
rpc GetHighestTradePrice(stream StockRequest) returns (StockReply) {
};
}
};
}

@ -39,5 +39,8 @@ var examples = grpc.load(__dirname + '/stock.proto').examples;
*
* var StockClient = require('stock_client.js');
* var stockClient = new StockClient(server_address);
* stockClient.getLastTradePrice({symbol: 'GOOG'}, function(error, response) {
* console.log(error || response);
* });
*/
module.exports = examples.Stock;

@ -35,7 +35,7 @@ var _ = require('underscore');
var grpc = require('..');
var examples = grpc.load(__dirname + '/stock.proto').examples;
var StockServer = grpc.makeServerConstructor([examples.Stock.service]);
var StockServer = grpc.buildServer([examples.Stock.service]);
function getLastTradePrice(call, callback) {
callback(null, {price: 88});
@ -80,4 +80,9 @@ var stockServer = new StockServer({
}
});
if (require.main === module) {
stockServer.bind('0.0.0.0:8080');
stockServer.listen();
}
exports.module = stockServer;

@ -1,6 +1,6 @@
/*
*
* Copyright 2014, Google Inc.
* Copyright 2015, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -58,11 +58,11 @@ using v8::Value;
Handle<Value> ParseMetadata(grpc_metadata *metadata_elements, size_t length) {
NanEscapableScope();
std::map<char*, size_t> size_map;
std::map<char*, size_t> index_map;
std::map<const char*, size_t> size_map;
std::map<const char*, size_t> index_map;
for (unsigned int i = 0; i < length; i++) {
char *key = metadata_elements[i].key;
const char *key = metadata_elements[i].key;
if (size_map.count(key)) {
size_map[key] += 1;
}
@ -97,8 +97,6 @@ Handle<Value> GetEventData(grpc_event *event) {
switch (event->type) {
case GRPC_READ:
return NanEscapeScope(ByteBufferToBuffer(event->data.read));
case GRPC_INVOKE_ACCEPTED:
return NanEscapeScope(NanNew<Number>(event->data.invoke_accepted));
case GRPC_WRITE_ACCEPTED:
return NanEscapeScope(NanNew<Number>(event->data.write_accepted));
case GRPC_FINISH_ACCEPTED:
@ -124,12 +122,12 @@ Handle<Value> GetEventData(grpc_event *event) {
return NanEscapeScope(NanNull());
}
rpc_new->Set(
NanNew<String, const char *>("method"),
NanNew<String, const char *>(event->data.server_rpc_new.method));
NanNew("method"),
NanNew(event->data.server_rpc_new.method));
rpc_new->Set(
NanNew<String, const char *>("host"),
NanNew<String, const char *>(event->data.server_rpc_new.host));
rpc_new->Set(NanNew<String, const char *>("absolute_deadline"),
NanNew("host"),
NanNew(event->data.server_rpc_new.host));
rpc_new->Set(NanNew("absolute_deadline"),
NanNew<Date>(TimespecToMilliseconds(
event->data.server_rpc_new.deadline)));
count = event->data.server_rpc_new.metadata_count;
@ -137,12 +135,11 @@ Handle<Value> GetEventData(grpc_event *event) {
metadata = NanNew<Array>(static_cast<int>(count));
for (unsigned int i = 0; i < count; i++) {
Handle<Object> item_obj = Object::New();
item_obj->Set(NanNew<String, const char *>("key"),
NanNew<String, char *>(items[i].key));
item_obj->Set(NanNew("key"),
NanNew(items[i].key));
item_obj->Set(
NanNew<String, const char *>("value"),
NanNew<String, char *>(items[i].value,
static_cast<int>(items[i].value_length)));
NanNew("value"),
NanNew(items[i].value, static_cast<int>(items[i].value_length)));
metadata->Set(i, item_obj);
}
rpc_new->Set(NanNew("metadata"), ParseMetadata(items, count));

@ -133,15 +133,13 @@ describe('call', function() {
call.addMetadata(5);
}, TypeError);
});
it('should fail if invoke was already called', function(done) {
it.skip('should fail if invoke was already called', function(done) {
var call = new grpc.Call(channel, 'method', getDeadline(1));
call.invoke(function() {},
function() {done();},
0);
assert.throws(function() {
call.addMetadata({'key': ['value']});
}, function(err) {
return err.code === grpc.callError.ALREADY_INVOKED;
});
// Cancel to speed up the test
call.cancel();
@ -189,12 +187,10 @@ describe('call', function() {
call.serverAccept();
}, TypeError);
});
it('should return an error when called on a client Call', function() {
it.skip('should return an error when called on a client Call', function() {
var call = new grpc.Call(channel, 'method', getDeadline(1));
assert.throws(function() {
call.serverAccept(function() {});
}, function(err) {
return err.code === grpc.callError.NOT_ON_CLIENT;
});
});
});

@ -83,7 +83,7 @@ def do_div_many(stub)
logger.info('-------------')
reqs = []
reqs << Math::DivArgs.new(dividend: 7, divisor: 3)
reqs << Math::Di5AvArgs.new(dividend: 5, divisor: 2)
reqs << Math::DivArgs.new(dividend: 5, divisor: 2)
reqs << Math::DivArgs.new(dividend: 7, divisor: 2)
logger.info("div(7/3), div(5/2), div(7/2): reqs=#{reqs.inspect}")
resp = stub.div_many(reqs, 10)

@ -256,14 +256,6 @@ static VALUE grpc_rb_event_result(VALUE self) {
event->data.finish_accepted);
break;
case GRPC_INVOKE_ACCEPTED:
if (event->data.invoke_accepted == GRPC_OP_OK) {
return Qnil;
}
rb_raise(rb_eEventError, "invoke failed, not sure why (code=%d)",
event->data.invoke_accepted);
break;
case GRPC_WRITE_ACCEPTED:
if (event->data.write_accepted == GRPC_OP_OK) {
return Qnil;
@ -343,9 +335,8 @@ void Init_google_rpc_event() {
rb_define_module_under(rb_mGoogleRpcCore, "CompletionType");
rb_define_const(rb_mCompletionType, "QUEUE_SHUTDOWN",
INT2NUM(GRPC_QUEUE_SHUTDOWN));
rb_define_const(rb_mCompletionType, "OP_COMPLETE", INT2NUM(GRPC_OP_COMPLETE));
rb_define_const(rb_mCompletionType, "READ", INT2NUM(GRPC_READ));
rb_define_const(rb_mCompletionType, "INVOKE_ACCEPTED",
INT2NUM(GRPC_INVOKE_ACCEPTED));
rb_define_const(rb_mCompletionType, "WRITE_ACCEPTED",
INT2NUM(GRPC_WRITE_ACCEPTED));
rb_define_const(rb_mCompletionType, "FINISH_ACCEPTED",

@ -81,7 +81,6 @@ module Google
active_call.run_server_bidi(mth)
end
send_status(active_call, OK, 'OK')
active_call.finished
rescue BadStatus => e
# this is raised by handlers that want GRPC to send an application
# error code and detail message.

@ -75,14 +75,14 @@ describe GRPC::Core::Call do
end
describe '#start_read' do
it 'should fail if called immediately' do
xit 'should fail if called immediately' do
blk = proc { make_test_call.start_read(@tag) }
expect(&blk).to raise_error GRPC::Core::CallError
end
end
describe '#start_write' do
it 'should fail if called immediately' do
xit 'should fail if called immediately' do
bytes = GRPC::Core::ByteBuffer.new('test string')
blk = proc { make_test_call.start_write(bytes, @tag) }
expect(&blk).to raise_error GRPC::Core::CallError
@ -90,14 +90,14 @@ describe GRPC::Core::Call do
end
describe '#start_write_status' do
it 'should fail if called immediately' do
xit 'should fail if called immediately' do
blk = proc { make_test_call.start_write_status(153, 'x', @tag) }
expect(&blk).to raise_error GRPC::Core::CallError
end
end
describe '#writes_done' do
it 'should fail if called immediately' do
xit 'should fail if called immediately' do
blk = proc { make_test_call.writes_done(Object.new) }
expect(&blk).to raise_error GRPC::Core::CallError
end

@ -292,10 +292,10 @@ shared_examples 'GRPC metadata delivery works OK' do
# TODO: update this with the bug number to be resolved
ev = expect_next_event_on(@client_queue, CLIENT_METADATA_READ,
@client_metadata_tag)
expect(ev.result).to eq(':status' => '200')
expect(ev.result).to eq({})
end
it 'sends all the pairs and status:200 when keys and values are valid' do
it 'sends all the pairs when keys and values are valid' do
@valid_metadata.each do |md|
call = new_client_call
call.invoke(@client_queue, @client_metadata_tag, @client_finished_tag)
@ -314,7 +314,6 @@ shared_examples 'GRPC metadata delivery works OK' do
ev = expect_next_event_on(@client_queue, CLIENT_METADATA_READ,
@client_metadata_tag)
replace_symbols = Hash[md.each_pair.collect { |x, y| [x.to_s, y] }]
replace_symbols[':status'] = '200'
expect(ev.result).to eq(replace_symbols)
end
end

@ -33,8 +33,8 @@ describe GRPC::Core::CompletionType do
before(:each) do
@known_types = {
QUEUE_SHUTDOWN: 0,
READ: 1,
INVOKE_ACCEPTED: 2,
OP_COMPLETE: 1,
READ: 2,
WRITE_ACCEPTED: 3,
FINISH_ACCEPTED: 4,
CLIENT_METADATA_READ: 5,

@ -166,7 +166,7 @@ describe GRPC::ActiveCall do
expect(client_call.remote_read).to eq('server_response')
end
it 'saves metadata { status=200 } when the server adds no metadata' do
it 'saves no metadata when the server adds no metadata' do
call = make_test_call
done_tag, meta_tag = ActiveCall.client_invoke(call, @client_queue,
deadline)
@ -180,7 +180,7 @@ describe GRPC::ActiveCall do
server_call.remote_send('ignore me')
expect(client_call.metadata).to be_nil
client_call.remote_read
expect(client_call.metadata).to eq(':status' => '200')
expect(client_call.metadata).to eq({})
end
it 'saves metadata add by the server' do
@ -197,7 +197,7 @@ describe GRPC::ActiveCall do
server_call.remote_send('ignore me')
expect(client_call.metadata).to be_nil
client_call.remote_read
expected = { ':status' => '200', 'k1' => 'v1', 'k2' => 'v2' }
expected = { 'k1' => 'v1', 'k2' => 'v2' }
expect(client_call.metadata).to eq(expected)
end
@ -307,7 +307,6 @@ describe GRPC::ActiveCall do
server_call.remote_send('server_response')
expect(client_call.remote_read).to eq('server_response')
server_call.send_status(OK, 'status code is OK')
expect { server_call.finished }.to_not raise_error
expect { client_call.finished }.to_not raise_error
end
@ -326,7 +325,6 @@ describe GRPC::ActiveCall do
server_call.send_status(OK, 'status code is OK')
expect(client_call.remote_read).to eq('server_response')
expect { client_call.writes_done(false) }.to_not raise_error
expect { server_call.finished }.to_not raise_error
expect { client_call.finished }.to_not raise_error
end
@ -345,7 +343,6 @@ describe GRPC::ActiveCall do
server_call.send_status(OK, 'status code is OK')
expect(client_call.remote_read).to eq('server_response')
expect { client_call.writes_done(true) }.to_not raise_error
expect { server_call.finished }.to_not raise_error
end
end

@ -434,7 +434,7 @@ describe 'ClientStub' do
end
expect(c.remote_read).to eq(expected_input)
replys.each { |r| c.remote_send(r) }
c.send_status(status, status == @pass ? 'OK' : 'NOK', true)
c.send_status(status, status == @pass ? 'OK' : 'NOK')
end
end
@ -444,7 +444,7 @@ describe 'ClientStub' do
c = expect_server_to_be_invoked(mtx, cnd)
expected_inputs.each { |i| expect(c.remote_read).to eq(i) }
replys.each { |r| c.remote_send(r) }
c.send_status(status, status == @pass ? 'OK' : 'NOK', true)
c.send_status(status, status == @pass ? 'OK' : 'NOK')
end
end
@ -460,7 +460,7 @@ describe 'ClientStub' do
expect(c.remote_read).to eq(i)
end
end
c.send_status(status, status == @pass ? 'OK' : 'NOK', true)
c.send_status(status, status == @pass ? 'OK' : 'NOK')
end
end
@ -473,7 +473,7 @@ describe 'ClientStub' do
expect(c.metadata[k.to_s]).to eq(v)
end
c.remote_send(resp)
c.send_status(status, status == @pass ? 'OK' : 'NOK', true)
c.send_status(status, status == @pass ? 'OK' : 'NOK')
end
end
@ -486,7 +486,7 @@ describe 'ClientStub' do
expect(c.metadata[k.to_s]).to eq(v)
end
c.remote_send(resp)
c.send_status(status, status == @pass ? 'OK' : 'NOK', true)
c.send_status(status, status == @pass ? 'OK' : 'NOK')
end
end

@ -94,7 +94,6 @@ describe GRPC::RpcDesc do
expect(@call).to receive(:remote_read).once.and_return(req)
expect(@call).to receive(:remote_send).once.with(@ok_response)
expect(@call).to receive(:send_status).once.with(OK, 'OK')
expect(@call).to receive(:finished).once
@request_response.run_server_method(@call, method(:fake_reqresp))
end
end
@ -135,7 +134,6 @@ describe GRPC::RpcDesc do
it 'sends a response and closes the stream if there no errors' do
expect(@call).to receive(:remote_send).once.with(@ok_response)
expect(@call).to receive(:send_status).once.with(OK, 'OK')
expect(@call).to receive(:finished).once
@client_streamer.run_server_method(@call, method(:fake_clstream))
end
end
@ -180,7 +178,6 @@ describe GRPC::RpcDesc do
expect(@call).to receive(:remote_read).once.and_return(req)
expect(@call).to receive(:remote_send).twice.with(@ok_response)
expect(@call).to receive(:send_status).once.with(OK, 'OK')
expect(@call).to receive(:finished).once
@server_streamer.run_server_method(@call, method(:fake_svstream))
end
end
@ -210,7 +207,6 @@ describe GRPC::RpcDesc do
it 'closes the stream if there no errors' do
expect(@call).to receive(:run_server_bidi)
expect(@call).to receive(:send_status).once.with(OK, 'OK')
expect(@call).to receive(:finished).once
@bidi_streamer.run_server_method(@call, method(:fake_bidistream))
end
end

Loading…
Cancel
Save