diff options
author | Craig Tiller <ctiller@google.com> | 2016-02-19 13:07:39 -0800 |
---|---|---|
committer | Craig Tiller <ctiller@google.com> | 2016-02-19 13:07:39 -0800 |
commit | 04239b90454fc7821efe98ad61507b179cec9ea8 (patch) | |
tree | ae1b0d0bd9269d5bcf8dbd35c8f45ac92c0c0cef | |
parent | 8d8246ecc6407f617e6aac20040e5884b974f8fb (diff) | |
parent | 8e92ce40625b221a63574922d9ff7298a4bf486e (diff) |
Merge github.com:grpc/grpc into cleaner-posix2
54 files changed, 580 insertions, 201 deletions
@@ -3164,6 +3164,7 @@ LIBGRPC++_TEST_UTIL_SRC = \ test/cpp/util/create_test_channel.cc \ test/cpp/util/string_ref_helper.cc \ test/cpp/util/subprocess.cc \ + test/cpp/util/test_credentials_provider.cc \ LIBGRPC++_TEST_UTIL_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_TEST_UTIL_SRC)))) @@ -3214,6 +3215,7 @@ $(OBJDIR)/$(CONFIG)/test/cpp/util/cli_call.o: $(GENDIR)/src/proto/grpc/testing/e $(OBJDIR)/$(CONFIG)/test/cpp/util/create_test_channel.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(OBJDIR)/$(CONFIG)/test/cpp/util/string_ref_helper.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc $(OBJDIR)/$(CONFIG)/test/cpp/util/subprocess.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc +$(OBJDIR)/$(CONFIG)/test/cpp/util/test_credentials_provider.o: $(GENDIR)/src/proto/grpc/testing/echo_messages.pb.cc $(GENDIR)/src/proto/grpc/testing/echo_messages.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.pb.cc $(GENDIR)/src/proto/grpc/testing/echo.grpc.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.pb.cc $(GENDIR)/src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.cc LIBGRPC++_UNSECURE_SRC = \ @@ -13017,6 +13019,7 @@ test/cpp/util/create_test_channel.cc: $(OPENSSL_DEP) test/cpp/util/string_ref_helper.cc: $(OPENSSL_DEP) test/cpp/util/subprocess.cc: $(OPENSSL_DEP) test/cpp/util/test_config.cc: $(OPENSSL_DEP) +test/cpp/util/test_credentials_provider.cc: $(OPENSSL_DEP) endif .PHONY: all strip tools dep_error openssl_dep_error openssl_dep_message git_update stop buildtests buildtests_c buildtests_cxx test test_c test_cxx install install_c install_cxx install-headers install-headers_c install-headers_cxx install-shared install-shared_c install-shared_cxx install-static install-static_c install-static_cxx strip strip-shared strip-static strip_c strip-shared_c strip-static_c strip_cxx strip-shared_cxx strip-static_cxx dep_c dep_cxx bins_dep_c bins_dep_cxx clean diff --git a/build.yaml b/build.yaml index e59bd8e733..acbc8de4ea 100644 --- a/build.yaml +++ b/build.yaml @@ -717,6 +717,7 @@ libs: - test/cpp/util/create_test_channel.h - test/cpp/util/string_ref_helper.h - test/cpp/util/subprocess.h + - test/cpp/util/test_credentials_provider.h src: - src/proto/grpc/testing/echo_messages.proto - src/proto/grpc/testing/echo.proto @@ -727,6 +728,7 @@ libs: - test/cpp/util/create_test_channel.cc - test/cpp/util/string_ref_helper.cc - test/cpp/util/subprocess.cc + - test/cpp/util/test_credentials_provider.cc deps: - grpc++ - grpc_test_util diff --git a/doc/load-balancing.md b/doc/load-balancing.md new file mode 100644 index 0000000000..681be02a72 --- /dev/null +++ b/doc/load-balancing.md @@ -0,0 +1,97 @@ +Load Balancing in gRPC +======================= + +# Objective + +To design a load balancing API between a gRPC client and a Load Balancer to +instruct the client how to send load to multiple backend servers. + +# Background + +Prior to any gRPC specifics, we explore some usual ways to approach load +balancing. + +### Proxy Model + +Using a proxy provides a solid trustable client that can report load to the load +balancing system. Proxies typically require more resources to operate since they +have temporary copies of the RPC request and response. This model also increases +latency to the RPCs. + +The proxy model was deemed inefficient when considering request heavy services +like storage. + +### Balancing-aware Client + +This thicker client places more of the load balancing logic in the client. For +example, the client could contain many load balancing policies (Round Robin, +Random, etc) used to select servers from a list. In this model, a list of +servers would be either statically configured in the client, provided by the +name resolution system, an external load balancer, etc. In any case, the client +is responsible for choosing the preferred server from the list. + +One of the drawbacks of this approach is writing and maintaining the load +balancing policies in multiple languages and/or versions of the clients. These +policies can be fairly complicated. Some of the algorithms also require client +to server communication so the client would need to get thicker to support +additional RPCs to get health or load information in addition to sending RPCs +for user requests. + +It would also significantly complicate the client's code: the new design hides +the load balancing complexity of multiple layers and presents it as a simple +list of servers to the client. + +### External Load Balancing Service + +The client load balancing code is kept simple and portable, implementing +well-known algorithms (ie, Round Robin) for server selection. +Complex load balancing algorithms are instead provided by the load balancer. The +client relies on the load balancer to provide _load balancing configuration_ and +_the list of servers_ to which the client should send requests. The balancer +updates the server list as needed to balance the load as well as handle server +unavailability or health issues. The load balancer will make any necessary +complex decisions and inform the client. The load balancer may communicate with +the backend servers to collect load and health information. + +# Proposed Architecture + +The gRPC load balancing approach follows the third approach, by having an +external load balancer which provides simple clients with a list of servers. + +## Client + +When establishing a gRPC stream to the balancer, the client will send an initial +request to the load balancer (via a regular gRPC message). The load balancer +will respond with client config (including, for example, settings for flow +control, RPC deadlines, etc.) or a redirect to another load balancer. If the +balancer did not redirect the client, it will then send a list of servers to the +client. The client will contain simple load balancing logic for choosing the +next server when it needs to send a request. + +## Load Balancer + +The Load Balancer is responsible for providing the client with a list of servers +and client RPC parameters. The balancer chooses when to update the list of +servers and can decide whether to provide a complete list, a subset, or a +specific list of “picked” servers in a particular order. The balancer can +optionally provide an expiration interval after which the server list should no +longer be trusted and should be updated by the balancer. + +The load balancer may open reporting streams to each server contained in the +server list. These streams are primarily used for load reporting. For example, +Weighted Round Robin requires that the servers report utilization to the load +balancer in order to compute the next list of servers. + +## Server + +The gRPC Server is responsible for answering RPC requests and providing +responses to the client. The server will also report load to the load balancer +if a reporting stream was opened for this purpose. + +### Security + +The load balancer may be separate from the actual server backends and a +compromise of the load balancer should only lead to a compromise of the +loadbalancing functionality. In other words, a compromised load balancer should +not be able to cause a client to trust a (potentially malicious) backend server +any more than in a comparable situation without loadbalancing. diff --git a/src/csharp/Grpc.Auth/GoogleAuthInterceptors.cs b/src/csharp/Grpc.Auth/GoogleAuthInterceptors.cs index f77e9c6573..1837f5c74b 100644 --- a/src/csharp/Grpc.Auth/GoogleAuthInterceptors.cs +++ b/src/csharp/Grpc.Auth/GoogleAuthInterceptors.cs @@ -1,6 +1,6 @@ #region Copyright notice and license -// Copyright 2015, Google Inc. +// Copyright 2015-2016, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -71,7 +71,7 @@ namespace Grpc.Auth /// <returns>The interceptor.</returns> public static AsyncAuthInterceptor FromAccessToken(string accessToken) { - Preconditions.CheckNotNull(accessToken); + GrpcPreconditions.CheckNotNull(accessToken); return new AsyncAuthInterceptor(async (context, metadata) => { metadata.Add(CreateBearerTokenHeader(accessToken)); diff --git a/src/csharp/Grpc.Core/AsyncAuthInterceptor.cs b/src/csharp/Grpc.Core/AsyncAuthInterceptor.cs index 5c9ab04812..5ba06d6509 100644 --- a/src/csharp/Grpc.Core/AsyncAuthInterceptor.cs +++ b/src/csharp/Grpc.Core/AsyncAuthInterceptor.cs @@ -1,6 +1,6 @@ #region Copyright notice and license -// Copyright 2015, Google Inc. +// Copyright 2015-2016, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -61,8 +61,8 @@ namespace Grpc.Core /// </summary> public AuthInterceptorContext(string serviceUrl, string methodName) { - this.serviceUrl = Preconditions.CheckNotNull(serviceUrl); - this.methodName = Preconditions.CheckNotNull(methodName); + this.serviceUrl = GrpcPreconditions.CheckNotNull(serviceUrl); + this.methodName = GrpcPreconditions.CheckNotNull(methodName); } /// <summary> diff --git a/src/csharp/Grpc.Core/CallCredentials.cs b/src/csharp/Grpc.Core/CallCredentials.cs index a71c8904fe..7cd41d0480 100644 --- a/src/csharp/Grpc.Core/CallCredentials.cs +++ b/src/csharp/Grpc.Core/CallCredentials.cs @@ -1,6 +1,6 @@ #region Copyright notice and license -// Copyright 2015, Google Inc. +// Copyright 2015-2016, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -87,7 +87,7 @@ namespace Grpc.Core /// <param name="interceptor">authentication interceptor</param> public MetadataCredentials(AsyncAuthInterceptor interceptor) { - this.interceptor = Preconditions.CheckNotNull(interceptor); + this.interceptor = GrpcPreconditions.CheckNotNull(interceptor); } internal override CallCredentialsSafeHandle ToNativeCredentials() @@ -111,7 +111,7 @@ namespace Grpc.Core /// <param name="credentials">credentials to compose</param> public CompositeCallCredentials(params CallCredentials[] credentials) { - Preconditions.CheckArgument(credentials.Length >= 2, "Composite credentials object can only be created from 2 or more credentials."); + GrpcPreconditions.CheckArgument(credentials.Length >= 2, "Composite credentials object can only be created from 2 or more credentials."); this.credentials = new List<CallCredentials>(credentials); } diff --git a/src/csharp/Grpc.Core/CallInvocationDetails.cs b/src/csharp/Grpc.Core/CallInvocationDetails.cs index 8228b8f317..52bfbe6edb 100644 --- a/src/csharp/Grpc.Core/CallInvocationDetails.cs +++ b/src/csharp/Grpc.Core/CallInvocationDetails.cs @@ -1,6 +1,6 @@ #region Copyright notice and license -// Copyright 2015, Google Inc. +// Copyright 2015-2016, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -85,11 +85,11 @@ namespace Grpc.Core /// <param name="options">Call options.</param> public CallInvocationDetails(Channel channel, string method, string host, Marshaller<TRequest> requestMarshaller, Marshaller<TResponse> responseMarshaller, CallOptions options) { - this.channel = Preconditions.CheckNotNull(channel, "channel"); - this.method = Preconditions.CheckNotNull(method, "method"); + this.channel = GrpcPreconditions.CheckNotNull(channel, "channel"); + this.method = GrpcPreconditions.CheckNotNull(method, "method"); this.host = host; - this.requestMarshaller = Preconditions.CheckNotNull(requestMarshaller, "requestMarshaller"); - this.responseMarshaller = Preconditions.CheckNotNull(responseMarshaller, "responseMarshaller"); + this.requestMarshaller = GrpcPreconditions.CheckNotNull(requestMarshaller, "requestMarshaller"); + this.responseMarshaller = GrpcPreconditions.CheckNotNull(responseMarshaller, "responseMarshaller"); this.options = options; } diff --git a/src/csharp/Grpc.Core/CallOptions.cs b/src/csharp/Grpc.Core/CallOptions.cs index 1fda80cb90..7bd95d4ba8 100644 --- a/src/csharp/Grpc.Core/CallOptions.cs +++ b/src/csharp/Grpc.Core/CallOptions.cs @@ -1,6 +1,6 @@ #region Copyright notice and license -// Copyright 2015, Google Inc. +// Copyright 2015-2016, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -176,13 +176,13 @@ namespace Grpc.Core { if (propagationToken.Options.IsPropagateDeadline) { - Preconditions.CheckArgument(!newOptions.deadline.HasValue, + GrpcPreconditions.CheckArgument(!newOptions.deadline.HasValue, "Cannot propagate deadline from parent call. The deadline has already been set explicitly."); newOptions.deadline = propagationToken.ParentDeadline; } if (propagationToken.Options.IsPropagateCancellation) { - Preconditions.CheckArgument(!newOptions.cancellationToken.CanBeCanceled, + GrpcPreconditions.CheckArgument(!newOptions.cancellationToken.CanBeCanceled, "Cannot propagate cancellation token from parent call. The cancellation token has already been set to a non-default value."); newOptions.cancellationToken = propagationToken.ParentCancellationToken; } diff --git a/src/csharp/Grpc.Core/Channel.cs b/src/csharp/Grpc.Core/Channel.cs index d8d43c7998..d7a482d86f 100644 --- a/src/csharp/Grpc.Core/Channel.cs +++ b/src/csharp/Grpc.Core/Channel.cs @@ -1,5 +1,5 @@ #region Copyright notice and license -// Copyright 2015, Google Inc. +// Copyright 2015-2016, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -68,7 +68,7 @@ namespace Grpc.Core /// <param name="options">Channel options.</param> public Channel(string target, ChannelCredentials credentials, IEnumerable<ChannelOption> options = null) { - this.target = Preconditions.CheckNotNull(target, "target"); + this.target = GrpcPreconditions.CheckNotNull(target, "target"); this.options = CreateOptionsDictionary(options); EnsureUserAgentChannelOption(this.options); this.environment = GrpcEnvironment.AddRef(); @@ -117,7 +117,7 @@ namespace Grpc.Core /// </summary> public Task WaitForStateChangedAsync(ChannelState lastObservedState, DateTime? deadline = null) { - Preconditions.CheckArgument(lastObservedState != ChannelState.FatalFailure, + GrpcPreconditions.CheckArgument(lastObservedState != ChannelState.FatalFailure, "FatalFailure is a terminal state. No further state changes can occur."); var tcs = new TaskCompletionSource<object>(); var deadlineTimespec = deadline.HasValue ? Timespec.FromDateTime(deadline.Value) : Timespec.InfFuture; @@ -184,7 +184,7 @@ namespace Grpc.Core { lock (myLock) { - Preconditions.CheckState(!shutdownRequested); + GrpcPreconditions.CheckState(!shutdownRequested); shutdownRequested = true; } @@ -221,7 +221,7 @@ namespace Grpc.Core bool success = false; handle.DangerousAddRef(ref success); - Preconditions.CheckState(success); + GrpcPreconditions.CheckState(success); } internal void RemoveCallReference(object call) diff --git a/src/csharp/Grpc.Core/ChannelCredentials.cs b/src/csharp/Grpc.Core/ChannelCredentials.cs index 5d96958e7c..03cda28400 100644 --- a/src/csharp/Grpc.Core/ChannelCredentials.cs +++ b/src/csharp/Grpc.Core/ChannelCredentials.cs @@ -1,6 +1,6 @@ #region Copyright notice and license -// Copyright 2015, Google Inc. +// Copyright 2015-2016, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -183,9 +183,9 @@ namespace Grpc.Core /// <param name="callCredentials">channelCredentials to compose</param> public CompositeChannelCredentials(ChannelCredentials channelCredentials, CallCredentials callCredentials) { - this.channelCredentials = Preconditions.CheckNotNull(channelCredentials); - this.callCredentials = Preconditions.CheckNotNull(callCredentials); - Preconditions.CheckArgument(channelCredentials.IsComposable, "Supplied channel credentials do not allow composition."); + this.channelCredentials = GrpcPreconditions.CheckNotNull(channelCredentials); + this.callCredentials = GrpcPreconditions.CheckNotNull(callCredentials); + GrpcPreconditions.CheckArgument(channelCredentials.IsComposable, "Supplied channel credentials do not allow composition."); } internal override ChannelCredentialsSafeHandle ToNativeCredentials() diff --git a/src/csharp/Grpc.Core/ChannelOptions.cs b/src/csharp/Grpc.Core/ChannelOptions.cs index d70673cf78..65e15e21e9 100644 --- a/src/csharp/Grpc.Core/ChannelOptions.cs +++ b/src/csharp/Grpc.Core/ChannelOptions.cs @@ -1,5 +1,5 @@ #region Copyright notice and license -// Copyright 2015, Google Inc. +// Copyright 2015-2016, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -73,8 +73,8 @@ namespace Grpc.Core public ChannelOption(string name, string stringValue) { this.type = OptionType.String; - this.name = Preconditions.CheckNotNull(name, "name"); - this.stringValue = Preconditions.CheckNotNull(stringValue, "stringValue"); + this.name = GrpcPreconditions.CheckNotNull(name, "name"); + this.stringValue = GrpcPreconditions.CheckNotNull(stringValue, "stringValue"); } /// <summary> @@ -85,7 +85,7 @@ namespace Grpc.Core public ChannelOption(string name, int intValue) { this.type = OptionType.Integer; - this.name = Preconditions.CheckNotNull(name, "name"); + this.name = GrpcPreconditions.CheckNotNull(name, "name"); this.intValue = intValue; } @@ -118,7 +118,7 @@ namespace Grpc.Core { get { - Preconditions.CheckState(type == OptionType.Integer); + GrpcPreconditions.CheckState(type == OptionType.Integer); return intValue; } } @@ -130,7 +130,7 @@ namespace Grpc.Core { get { - Preconditions.CheckState(type == OptionType.String); + GrpcPreconditions.CheckState(type == OptionType.String); return stringValue; } } diff --git a/src/csharp/Grpc.Core/ContextPropagationToken.cs b/src/csharp/Grpc.Core/ContextPropagationToken.cs index 1d899b97fd..c0f638f837 100644 --- a/src/csharp/Grpc.Core/ContextPropagationToken.cs +++ b/src/csharp/Grpc.Core/ContextPropagationToken.cs @@ -1,6 +1,6 @@ #region Copyright notice and license -// Copyright 2015, Google Inc. +// Copyright 2015-2016, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -68,7 +68,7 @@ namespace Grpc.Core internal ContextPropagationToken(CallSafeHandle parentCall, DateTime deadline, CancellationToken cancellationToken, ContextPropagationOptions options) { - this.parentCall = Preconditions.CheckNotNull(parentCall); + this.parentCall = GrpcPreconditions.CheckNotNull(parentCall); this.deadline = deadline; this.cancellationToken = cancellationToken; this.options = options ?? ContextPropagationOptions.Default; diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj index 8d7d2cae0d..3189835ccd 100644 --- a/src/csharp/Grpc.Core/Grpc.Core.csproj +++ b/src/csharp/Grpc.Core/Grpc.Core.csproj @@ -39,8 +39,7 @@ </PropertyGroup> <ItemGroup> <Reference Include="System" /> - <Reference Include="System.Interactive.Async, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> - <SpecificVersion>False</SpecificVersion> + <Reference Include="System.Interactive.Async"> <HintPath>..\packages\Ix-Async.1.2.5\lib\net45\System.Interactive.Async.dll</HintPath> </Reference> </ItemGroup> @@ -91,7 +90,6 @@ <Compile Include="Internal\AsyncCallBase.cs" /> <Compile Include="Internal\AsyncCallServer.cs" /> <Compile Include="Internal\AsyncCall.cs" /> - <Compile Include="Utils\Preconditions.cs" /> <Compile Include="Internal\ServerCredentialsSafeHandle.cs" /> <Compile Include="ServerCredentials.cs" /> <Compile Include="Metadata.cs" /> @@ -130,6 +128,7 @@ <Compile Include="Profiling\IProfiler.cs" /> <Compile Include="Profiling\Profilers.cs" /> <Compile Include="Internal\DefaultSslRootsOverride.cs" /> + <Compile Include="Utils\GrpcPreconditions.cs" /> </ItemGroup> <ItemGroup> <None Include="Grpc.Core.nuspec" /> diff --git a/src/csharp/Grpc.Core/GrpcEnvironment.cs b/src/csharp/Grpc.Core/GrpcEnvironment.cs index f3aa3d79de..86b37b8660 100644 --- a/src/csharp/Grpc.Core/GrpcEnvironment.cs +++ b/src/csharp/Grpc.Core/GrpcEnvironment.cs @@ -83,7 +83,7 @@ namespace Grpc.Core { lock (staticLock) { - Preconditions.CheckState(refCount > 0); + GrpcPreconditions.CheckState(refCount > 0); refCount--; if (refCount == 0) { @@ -118,7 +118,7 @@ namespace Grpc.Core /// </summary> public static void SetLogger(ILogger customLogger) { - Preconditions.CheckNotNull(customLogger, "customLogger"); + GrpcPreconditions.CheckNotNull(customLogger, "customLogger"); logger = customLogger; } diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs index 7dc4490281..2caba260b3 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs @@ -99,7 +99,7 @@ namespace Grpc.Core.Internal lock (myLock) { - Preconditions.CheckState(!started); + GrpcPreconditions.CheckState(!started); started = true; Initialize(cq); @@ -141,7 +141,7 @@ namespace Grpc.Core.Internal { lock (myLock) { - Preconditions.CheckState(!started); + GrpcPreconditions.CheckState(!started); started = true; Initialize(environment.CompletionQueue); @@ -168,7 +168,7 @@ namespace Grpc.Core.Internal { lock (myLock) { - Preconditions.CheckState(!started); + GrpcPreconditions.CheckState(!started); started = true; Initialize(environment.CompletionQueue); @@ -192,7 +192,7 @@ namespace Grpc.Core.Internal { lock (myLock) { - Preconditions.CheckState(!started); + GrpcPreconditions.CheckState(!started); started = true; Initialize(environment.CompletionQueue); @@ -217,7 +217,7 @@ namespace Grpc.Core.Internal { lock (myLock) { - Preconditions.CheckState(!started); + GrpcPreconditions.CheckState(!started); started = true; Initialize(environment.CompletionQueue); @@ -257,7 +257,7 @@ namespace Grpc.Core.Internal { lock (myLock) { - Preconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null"); + GrpcPreconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null"); CheckSendingAllowed(); call.StartSendCloseFromClient(HandleHalfclosed); @@ -297,7 +297,7 @@ namespace Grpc.Core.Internal { lock (myLock) { - Preconditions.CheckState(finishedStatus.HasValue, "Status can only be accessed once the call has finished."); + GrpcPreconditions.CheckState(finishedStatus.HasValue, "Status can only be accessed once the call has finished."); return finishedStatus.Value.Status; } } @@ -310,7 +310,7 @@ namespace Grpc.Core.Internal { lock (myLock) { - Preconditions.CheckState(finishedStatus.HasValue, "Trailers can only be accessed once the call has finished."); + GrpcPreconditions.CheckState(finishedStatus.HasValue, "Trailers can only be accessed once the call has finished."); return finishedStatus.Value.Trailers; } } diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs index 81a9a40fcc..45d4c3e078 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs @@ -79,9 +79,9 @@ namespace Grpc.Core.Internal public AsyncCallBase(Func<TWrite, byte[]> serializer, Func<byte[], TRead> deserializer, GrpcEnvironment environment) { - this.serializer = Preconditions.CheckNotNull(serializer); - this.deserializer = Preconditions.CheckNotNull(deserializer); - this.environment = Preconditions.CheckNotNull(environment); + this.serializer = GrpcPreconditions.CheckNotNull(serializer); + this.deserializer = GrpcPreconditions.CheckNotNull(deserializer); + this.environment = GrpcPreconditions.CheckNotNull(environment); } /// <summary> @@ -91,7 +91,7 @@ namespace Grpc.Core.Internal { lock (myLock) { - Preconditions.CheckState(started); + GrpcPreconditions.CheckState(started); cancelRequested = true; if (!disposed) @@ -135,7 +135,7 @@ namespace Grpc.Core.Internal lock (myLock) { - Preconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null"); + GrpcPreconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null"); CheckSendingAllowed(); call.StartSendMessage(HandleSendFinished, payload, writeFlags, !initialMetadataSent); @@ -154,7 +154,7 @@ namespace Grpc.Core.Internal { lock (myLock) { - Preconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null"); + GrpcPreconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null"); CheckReadingAllowed(); call.StartReceiveMessage(HandleReadFinished); @@ -204,22 +204,22 @@ namespace Grpc.Core.Internal protected void CheckSendingAllowed() { - Preconditions.CheckState(started); + GrpcPreconditions.CheckState(started); CheckNotCancelled(); - Preconditions.CheckState(!disposed); + GrpcPreconditions.CheckState(!disposed); - Preconditions.CheckState(!halfcloseRequested, "Already halfclosed."); - Preconditions.CheckState(!finished, "Already finished."); - Preconditions.CheckState(sendCompletionDelegate == null, "Only one write can be pending at a time"); + GrpcPreconditions.CheckState(!halfcloseRequested, "Already halfclosed."); + GrpcPreconditions.CheckState(!finished, "Already finished."); + GrpcPreconditions.CheckState(sendCompletionDelegate == null, "Only one write can be pending at a time"); } protected virtual void CheckReadingAllowed() { - Preconditions.CheckState(started); - Preconditions.CheckState(!disposed); + GrpcPreconditions.CheckState(started); + GrpcPreconditions.CheckState(!disposed); - Preconditions.CheckState(!readingDone, "Stream has already been closed."); - Preconditions.CheckState(readCompletionDelegate == null, "Only one read can be pending at a time"); + GrpcPreconditions.CheckState(!readingDone, "Stream has already been closed."); + GrpcPreconditions.CheckState(readCompletionDelegate == null, "Only one read can be pending at a time"); } protected void CheckNotCancelled() diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs b/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs index 6752d3fab3..b72cbd795f 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs @@ -53,7 +53,7 @@ namespace Grpc.Core.Internal public AsyncCallServer(Func<TResponse, byte[]> serializer, Func<byte[], TRequest> deserializer, GrpcEnvironment environment, Server server) : base(serializer, deserializer, environment) { - this.server = Preconditions.CheckNotNull(server); + this.server = GrpcPreconditions.CheckNotNull(server); } public void Initialize(CallSafeHandle call) @@ -71,7 +71,7 @@ namespace Grpc.Core.Internal { lock (myLock) { - Preconditions.CheckNotNull(call); + GrpcPreconditions.CheckNotNull(call); started = true; @@ -108,14 +108,14 @@ namespace Grpc.Core.Internal { lock (myLock) { - Preconditions.CheckNotNull(headers, "metadata"); - Preconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null"); + GrpcPreconditions.CheckNotNull(headers, "metadata"); + GrpcPreconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null"); - Preconditions.CheckState(!initialMetadataSent, "Response headers can only be sent once per call."); - Preconditions.CheckState(streamingWritesCounter == 0, "Response headers can only be sent before the first write starts."); + GrpcPreconditions.CheckState(!initialMetadataSent, "Response headers can only be sent once per call."); + GrpcPreconditions.CheckState(streamingWritesCounter == 0, "Response headers can only be sent before the first write starts."); CheckSendingAllowed(); - Preconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null"); + GrpcPreconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null"); using (var metadataArray = MetadataArraySafeHandle.Create(headers)) { @@ -136,7 +136,7 @@ namespace Grpc.Core.Internal { lock (myLock) { - Preconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null"); + GrpcPreconditions.CheckNotNull(completionDelegate, "Completion delegate cannot be null"); CheckSendingAllowed(); using (var metadataArray = MetadataArraySafeHandle.Create(trailers)) @@ -177,7 +177,7 @@ namespace Grpc.Core.Internal protected override void CheckReadingAllowed() { base.CheckReadingAllowed(); - Preconditions.CheckArgument(!cancelRequested); + GrpcPreconditions.CheckArgument(!cancelRequested); } protected override void OnAfterReleaseResources() diff --git a/src/csharp/Grpc.Core/Internal/CompletionQueueSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CompletionQueueSafeHandle.cs index 9d7a990c42..5c75b52e23 100644 --- a/src/csharp/Grpc.Core/Internal/CompletionQueueSafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/CompletionQueueSafeHandle.cs @@ -101,7 +101,7 @@ namespace Grpc.Core.Internal { bool success = false; shutdownRefcount.IncrementIfNonzero(ref success); - Preconditions.CheckState(success, "Shutdown has already been called"); + GrpcPreconditions.CheckState(success, "Shutdown has already been called"); } private void EndOp() diff --git a/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs b/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs index 2796c959a3..3a293e1626 100644 --- a/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs +++ b/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs @@ -1,6 +1,6 @@ #region Copyright notice and license -// Copyright 2015, Google Inc. +// Copyright 2015-2016, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -59,7 +59,7 @@ namespace Grpc.Core.Internal public void Register(IntPtr key, OpCompletionDelegate callback) { environment.DebugStats.PendingBatchCompletions.Increment(); - Preconditions.CheckState(dict.TryAdd(key, callback)); + GrpcPreconditions.CheckState(dict.TryAdd(key, callback)); } public void RegisterBatchCompletion(BatchContextSafeHandle ctx, BatchCompletionDelegate callback) @@ -71,7 +71,7 @@ namespace Grpc.Core.Internal public OpCompletionDelegate Extract(IntPtr key) { OpCompletionDelegate value; - Preconditions.CheckState(dict.TryRemove(key, out value)); + GrpcPreconditions.CheckState(dict.TryRemove(key, out value)); environment.DebugStats.PendingBatchCompletions.Decrement(); return value; } diff --git a/src/csharp/Grpc.Core/Internal/Enums.cs b/src/csharp/Grpc.Core/Internal/Enums.cs index b0eab2001b..098e7c0e99 100644 --- a/src/csharp/Grpc.Core/Internal/Enums.cs +++ b/src/csharp/Grpc.Core/Internal/Enums.cs @@ -1,6 +1,6 @@ #region Copyright notice and license -// Copyright 2015, Google Inc. +// Copyright 2015-2016, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -72,7 +72,7 @@ namespace Grpc.Core.Internal /// </summary> public static void CheckOk(this GRPCCallError callError) { - Preconditions.CheckState(callError == GRPCCallError.OK, "Call error: " + callError); + GrpcPreconditions.CheckState(callError == GRPCCallError.OK, "Call error: " + callError); } } diff --git a/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs b/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs index 36b865c09c..e810ffcdd0 100644 --- a/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs +++ b/src/csharp/Grpc.Core/Internal/NativeMetadataCredentialsPlugin.cs @@ -53,7 +53,7 @@ namespace Grpc.Core.Internal public NativeMetadataCredentialsPlugin(AsyncAuthInterceptor interceptor) { - this.interceptor = Preconditions.CheckNotNull(interceptor, "interceptor"); + this.interceptor = GrpcPreconditions.CheckNotNull(interceptor, "interceptor"); this.nativeInterceptor = NativeMetadataInterceptorHandler; // Make sure the callback doesn't get garbage collected until it is destroyed. diff --git a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs index de66759b94..ccf144de2d 100644 --- a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs +++ b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs @@ -1,6 +1,6 @@ #region Copyright notice and license -// Copyright 2015, Google Inc. +// Copyright 2015-2016, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -78,10 +78,10 @@ namespace Grpc.Core.Internal var context = HandlerUtils.NewContext(newRpc, asyncCall.Peer, responseStream, asyncCall.CancellationToken); try { - Preconditions.CheckArgument(await requestStream.MoveNext().ConfigureAwait(false)); + GrpcPreconditions.CheckArgument(await requestStream.MoveNext().ConfigureAwait(false)); var request = requestStream.Current; // TODO(jtattermusch): we need to read the full stream so that native callhandle gets deallocated. - Preconditions.CheckArgument(!await requestStream.MoveNext().ConfigureAwait(false)); + GrpcPreconditions.CheckArgument(!await requestStream.MoveNext().ConfigureAwait(false)); var result = await handler(request, context).ConfigureAwait(false); status = context.Status; await responseStream.WriteAsync(result).ConfigureAwait(false); @@ -134,10 +134,10 @@ namespace Grpc.Core.Internal var context = HandlerUtils.NewContext(newRpc, asyncCall.Peer, responseStream, asyncCall.CancellationToken); try { - Preconditions.CheckArgument(await requestStream.MoveNext().ConfigureAwait(false)); + GrpcPreconditions.CheckArgument(await requestStream.MoveNext().ConfigureAwait(false)); var request = requestStream.Current; // TODO(jtattermusch): we need to read the full stream so that native callhandle gets deallocated. - Preconditions.CheckArgument(!await requestStream.MoveNext().ConfigureAwait(false)); + GrpcPreconditions.CheckArgument(!await requestStream.MoveNext().ConfigureAwait(false)); await handler(request, responseStream, context).ConfigureAwait(false); status = context.Status; } diff --git a/src/csharp/Grpc.Core/Internal/ServerCredentialsSafeHandle.cs b/src/csharp/Grpc.Core/Internal/ServerCredentialsSafeHandle.cs index a1d080c7f1..a50f357990 100644 --- a/src/csharp/Grpc.Core/Internal/ServerCredentialsSafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/ServerCredentialsSafeHandle.cs @@ -49,7 +49,7 @@ namespace Grpc.Core.Internal public static ServerCredentialsSafeHandle CreateSslCredentials(string pemRootCerts, string[] keyCertPairCertChainArray, string[] keyCertPairPrivateKeyArray, bool forceClientAuth) { - Preconditions.CheckArgument(keyCertPairCertChainArray.Length == keyCertPairPrivateKeyArray.Length); + GrpcPreconditions.CheckArgument(keyCertPairCertChainArray.Length == keyCertPairPrivateKeyArray.Length); return Native.grpcsharp_ssl_server_credentials_create(pemRootCerts, keyCertPairCertChainArray, keyCertPairPrivateKeyArray, new UIntPtr((ulong)keyCertPairCertChainArray.Length), diff --git a/src/csharp/Grpc.Core/Internal/Timespec.cs b/src/csharp/Grpc.Core/Internal/Timespec.cs index 148d877da5..754be4e035 100644 --- a/src/csharp/Grpc.Core/Internal/Timespec.cs +++ b/src/csharp/Grpc.Core/Internal/Timespec.cs @@ -141,8 +141,8 @@ namespace Grpc.Core.Internal /// </summary> public DateTime ToDateTime() { - Preconditions.CheckState(tv_nsec >= 0 && tv_nsec < NanosPerSecond); - Preconditions.CheckState(clock_type == GPRClockType.Realtime); + GrpcPreconditions.CheckState(tv_nsec >= 0 && tv_nsec < NanosPerSecond); + GrpcPreconditions.CheckState(clock_type == GPRClockType.Realtime); // fast path for InfFuture if (this.Equals(InfFuture)) @@ -195,7 +195,7 @@ namespace Grpc.Core.Internal return Timespec.InfPast; } - Preconditions.CheckArgument(dateTime.Kind == DateTimeKind.Utc, "dateTime needs of kind DateTimeKind.Utc or be equal to DateTime.MaxValue or DateTime.MinValue."); + GrpcPreconditions.CheckArgument(dateTime.Kind == DateTimeKind.Utc, "dateTime needs of kind DateTimeKind.Utc or be equal to DateTime.MaxValue or DateTime.MinValue."); try { diff --git a/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs b/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs index 95a8797e3e..e763c15025 100644 --- a/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs +++ b/src/csharp/Grpc.Core/Internal/UnmanagedLibrary.cs @@ -65,7 +65,7 @@ namespace Grpc.Core.Internal public UnmanagedLibrary(string libraryPath) { - this.libraryPath = Preconditions.CheckNotNull(libraryPath); + this.libraryPath = GrpcPreconditions.CheckNotNull(libraryPath); if (!File.Exists(this.libraryPath)) { diff --git a/src/csharp/Grpc.Core/KeyCertificatePair.cs b/src/csharp/Grpc.Core/KeyCertificatePair.cs index 6f691975e9..0fb6817986 100644 --- a/src/csharp/Grpc.Core/KeyCertificatePair.cs +++ b/src/csharp/Grpc.Core/KeyCertificatePair.cs @@ -1,6 +1,6 @@ #region Copyright notice and license -// Copyright 2015, Google Inc. +// Copyright 2015-2016, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -54,8 +54,8 @@ namespace Grpc.Core /// <param name="privateKey">PEM encoded private key.</param> public KeyCertificatePair(string certificateChain, string privateKey) { - this.certificateChain = Preconditions.CheckNotNull(certificateChain, "certificateChain"); - this.privateKey = Preconditions.CheckNotNull(privateKey, "privateKey"); + this.certificateChain = GrpcPreconditions.CheckNotNull(certificateChain, "certificateChain"); + this.privateKey = GrpcPreconditions.CheckNotNull(privateKey, "privateKey"); } /// <summary> diff --git a/src/csharp/Grpc.Core/Marshaller.cs b/src/csharp/Grpc.Core/Marshaller.cs index 3493d2d38f..5847248c1a 100644 --- a/src/csharp/Grpc.Core/Marshaller.cs +++ b/src/csharp/Grpc.Core/Marshaller.cs @@ -1,6 +1,6 @@ #region Copyright notice and license -// Copyright 2015, Google Inc. +// Copyright 2015-2016, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -51,8 +51,8 @@ namespace Grpc.Core /// <param name="deserializer">Function that will be used to deserialize messages.</param> public Marshaller(Func<T, byte[]> serializer, Func<byte[], T> deserializer) { - this.serializer = Preconditions.CheckNotNull(serializer, "serializer"); - this.deserializer = Preconditions.CheckNotNull(deserializer, "deserializer"); + this.serializer = GrpcPreconditions.CheckNotNull(serializer, "serializer"); + this.deserializer = GrpcPreconditions.CheckNotNull(deserializer, "deserializer"); } /// <summary> diff --git a/src/csharp/Grpc.Core/Metadata.cs b/src/csharp/Grpc.Core/Metadata.cs index 21bdf4f114..aa22f840d6 100644 --- a/src/csharp/Grpc.Core/Metadata.cs +++ b/src/csharp/Grpc.Core/Metadata.cs @@ -1,5 +1,5 @@ #region Copyright notice and license -// Copyright 2015, Google Inc. +// Copyright 2015-2016, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -179,7 +179,7 @@ namespace Grpc.Core private void CheckWriteable() { - Preconditions.CheckState(!readOnly, "Object is read only"); + GrpcPreconditions.CheckState(!readOnly, "Object is read only"); } #endregion @@ -211,10 +211,10 @@ namespace Grpc.Core public Entry(string key, byte[] valueBytes) { this.key = NormalizeKey(key); - Preconditions.CheckArgument(this.key.EndsWith(BinaryHeaderSuffix), + GrpcPreconditions.CheckArgument(this.key.EndsWith(BinaryHeaderSuffix), "Key for binary valued metadata entry needs to have suffix indicating binary value."); this.value = null; - Preconditions.CheckNotNull(valueBytes, "valueBytes"); + GrpcPreconditions.CheckNotNull(valueBytes, "valueBytes"); this.valueBytes = new byte[valueBytes.Length]; Buffer.BlockCopy(valueBytes, 0, this.valueBytes, 0, valueBytes.Length); // defensive copy to guarantee immutability } @@ -227,9 +227,9 @@ namespace Grpc.Core public Entry(string key, string value) { this.key = NormalizeKey(key); - Preconditions.CheckArgument(!this.key.EndsWith(BinaryHeaderSuffix), + GrpcPreconditions.CheckArgument(!this.key.EndsWith(BinaryHeaderSuffix), "Key for ASCII valued metadata entry cannot have suffix indicating binary value."); - this.value = Preconditions.CheckNotNull(value, "value"); + this.value = GrpcPreconditions.CheckNotNull(value, "value"); this.valueBytes = null; } @@ -270,7 +270,7 @@ namespace Grpc.Core { get { - Preconditions.CheckState(!IsBinary, "Cannot access string value of a binary metadata entry"); + GrpcPreconditions.CheckState(!IsBinary, "Cannot access string value of a binary metadata entry"); return value ?? Encoding.GetString(valueBytes); } } @@ -323,8 +323,8 @@ namespace Grpc.Core private static string NormalizeKey(string key) { - var normalized = Preconditions.CheckNotNull(key, "key").ToLower(CultureInfo.InvariantCulture); - Preconditions.CheckArgument(ValidKeyRegex.IsMatch(normalized), + var normalized = GrpcPreconditions.CheckNotNull(key, "key").ToLower(CultureInfo.InvariantCulture); + GrpcPreconditions.CheckArgument(ValidKeyRegex.IsMatch(normalized), "Metadata entry key not valid. Keys can only contain lowercase alphanumeric characters, underscores and hyphens."); return normalized; } diff --git a/src/csharp/Grpc.Core/Method.cs b/src/csharp/Grpc.Core/Method.cs index 99162a7d5d..3870076f7f 100644 --- a/src/csharp/Grpc.Core/Method.cs +++ b/src/csharp/Grpc.Core/Method.cs @@ -1,6 +1,6 @@ #region Copyright notice and license -// Copyright 2015, Google Inc. +// Copyright 2015-2016, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -106,10 +106,10 @@ namespace Grpc.Core public Method(MethodType type, string serviceName, string name, Marshaller<TRequest> requestMarshaller, Marshaller<TResponse> responseMarshaller) { this.type = type; - this.serviceName = Preconditions.CheckNotNull(serviceName, "serviceName"); - this.name = Preconditions.CheckNotNull(name, "name"); - this.requestMarshaller = Preconditions.CheckNotNull(requestMarshaller, "requestMarshaller"); - this.responseMarshaller = Preconditions.CheckNotNull(responseMarshaller, "responseMarshaller"); + this.serviceName = GrpcPreconditions.CheckNotNull(serviceName, "serviceName"); + this.name = GrpcPreconditions.CheckNotNull(name, "name"); + this.requestMarshaller = GrpcPreconditions.CheckNotNull(requestMarshaller, "requestMarshaller"); + this.responseMarshaller = GrpcPreconditions.CheckNotNull(responseMarshaller, "responseMarshaller"); this.fullName = GetFullName(serviceName, name); } diff --git a/src/csharp/Grpc.Core/Server.cs b/src/csharp/Grpc.Core/Server.cs index d120f95fdf..5d0fc6b1f0 100644 --- a/src/csharp/Grpc.Core/Server.cs +++ b/src/csharp/Grpc.Core/Server.cs @@ -1,6 +1,6 @@ #region Copyright notice and license -// Copyright 2015, Google Inc. +// Copyright 2015-2016, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -125,7 +125,7 @@ namespace Grpc.Core { lock (myLock) { - Preconditions.CheckState(!startRequested); + GrpcPreconditions.CheckState(!startRequested); startRequested = true; handle.Start(); @@ -142,8 +142,8 @@ namespace Grpc.Core { lock (myLock) { - Preconditions.CheckState(startRequested); - Preconditions.CheckState(!shutdownRequested); + GrpcPreconditions.CheckState(startRequested); + GrpcPreconditions.CheckState(!shutdownRequested); shutdownRequested = true; } @@ -162,8 +162,8 @@ namespace Grpc.Core { lock (myLock) { - Preconditions.CheckState(startRequested); - Preconditions.CheckState(!shutdownRequested); + GrpcPreconditions.CheckState(startRequested); + GrpcPreconditions.CheckState(!shutdownRequested); shutdownRequested = true; } @@ -181,7 +181,7 @@ namespace Grpc.Core bool success = false; handle.DangerousAddRef(ref success); - Preconditions.CheckState(success); + GrpcPreconditions.CheckState(success); } internal void RemoveCallReference(object call) @@ -197,7 +197,7 @@ namespace Grpc.Core { lock (myLock) { - Preconditions.CheckState(!startRequested); + GrpcPreconditions.CheckState(!startRequested); foreach (var entry in serviceDefinition.CallHandlers) { callHandlers.Add(entry.Key, entry.Value); @@ -213,8 +213,8 @@ namespace Grpc.Core { lock (myLock) { - Preconditions.CheckNotNull(serverPort.Credentials, "serverPort"); - Preconditions.CheckState(!startRequested); + GrpcPreconditions.CheckNotNull(serverPort.Credentials, "serverPort"); + GrpcPreconditions.CheckState(!startRequested); var address = string.Format("{0}:{1}", serverPort.Host, serverPort.Port); int boundPort; using (var nativeCredentials = serverPort.Credentials.ToNativeCredentials()) diff --git a/src/csharp/Grpc.Core/ServerCredentials.cs b/src/csharp/Grpc.Core/ServerCredentials.cs index 3c6703d30e..456d331c9c 100644 --- a/src/csharp/Grpc.Core/ServerCredentials.cs +++ b/src/csharp/Grpc.Core/ServerCredentials.cs @@ -1,6 +1,6 @@ #region Copyright notice and license -// Copyright 2015, Google Inc. +// Copyright 2015-2016, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -90,11 +90,11 @@ namespace Grpc.Core public SslServerCredentials(IEnumerable<KeyCertificatePair> keyCertificatePairs, string rootCertificates, bool forceClientAuth) { this.keyCertificatePairs = new List<KeyCertificatePair>(keyCertificatePairs).AsReadOnly(); - Preconditions.CheckArgument(this.keyCertificatePairs.Count > 0, + GrpcPreconditions.CheckArgument(this.keyCertificatePairs.Count > 0, "At least one KeyCertificatePair needs to be provided."); if (forceClientAuth) { - Preconditions.CheckNotNull(rootCertificates, + GrpcPreconditions.CheckNotNull(rootCertificates, "Cannot force client authentication unless you provide rootCertificates."); } this.rootCertificates = rootCertificates; diff --git a/src/csharp/Grpc.Core/ServerPort.cs b/src/csharp/Grpc.Core/ServerPort.cs index 598404d045..10ddcb782f 100644 --- a/src/csharp/Grpc.Core/ServerPort.cs +++ b/src/csharp/Grpc.Core/ServerPort.cs @@ -1,6 +1,6 @@ #region Copyright notice and license -// Copyright 2015, Google Inc. +// Copyright 2015-2016, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -62,9 +62,9 @@ namespace Grpc.Core /// <param name="credentials">credentials to use to secure this port.</param> public ServerPort(string host, int port, ServerCredentials credentials) { - this.host = Preconditions.CheckNotNull(host, "host"); + this.host = GrpcPreconditions.CheckNotNull(host, "host"); this.port = port; - this.credentials = Preconditions.CheckNotNull(credentials, "credentials"); + this.credentials = GrpcPreconditions.CheckNotNull(credentials, "credentials"); } /// <summary> diff --git a/src/csharp/Grpc.Core/Utils/Preconditions.cs b/src/csharp/Grpc.Core/Utils/GrpcPreconditions.cs index a8ab603391..76bf04ce8b 100644 --- a/src/csharp/Grpc.Core/Utils/Preconditions.cs +++ b/src/csharp/Grpc.Core/Utils/GrpcPreconditions.cs @@ -1,6 +1,6 @@ #region Copyright notice and license -// Copyright 2015, Google Inc. +// Copyright 2015-2016, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -38,7 +38,7 @@ namespace Grpc.Core.Utils /// <summary> /// Utility methods to simplify checking preconditions in the code. /// </summary> - public static class Preconditions + public static class GrpcPreconditions { /// <summary> /// Throws <see cref="ArgumentException"/> if condition is false. diff --git a/src/csharp/Grpc.HealthCheck/HealthServiceImpl.cs b/src/csharp/Grpc.HealthCheck/HealthServiceImpl.cs index 26c6445c35..e2ad1a834b 100644 --- a/src/csharp/Grpc.HealthCheck/HealthServiceImpl.cs +++ b/src/csharp/Grpc.HealthCheck/HealthServiceImpl.cs @@ -1,5 +1,5 @@ #region Copyright notice and license -// Copyright 2015, Google Inc. +// Copyright 2015-2016, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -127,8 +127,8 @@ namespace Grpc.HealthCheck { public Key(string host, string service) { - this.Host = Preconditions.CheckNotNull(host); - this.Service = Preconditions.CheckNotNull(service); + this.Host = GrpcPreconditions.CheckNotNull(host); + this.Service = GrpcPreconditions.CheckNotNull(service); } readonly string Host; diff --git a/src/csharp/Grpc.IntegrationTesting/ClientRunners.cs b/src/csharp/Grpc.IntegrationTesting/ClientRunners.cs index e9e659cb1f..c4016012cb 100644 --- a/src/csharp/Grpc.IntegrationTesting/ClientRunners.cs +++ b/src/csharp/Grpc.IntegrationTesting/ClientRunners.cs @@ -1,6 +1,6 @@ #region Copyright notice and license -// Copyright 2015, Google Inc. +// Copyright 2015-2016, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -58,7 +58,7 @@ namespace Grpc.IntegrationTesting public static IClientRunner CreateStarted(ClientConfig config) { string target = config.ServerTargets.Single(); - Grpc.Core.Utils.Preconditions.CheckArgument(config.LoadParams.LoadCase == LoadParams.LoadOneofCase.ClosedLoop); + GrpcPreconditions.CheckArgument(config.LoadParams.LoadCase == LoadParams.LoadOneofCase.ClosedLoop); var credentials = config.SecurityParams != null ? TestCredentials.CreateSslCredentials() : ChannelCredentials.Insecure; var channel = new Channel(target, credentials); @@ -95,7 +95,7 @@ namespace Grpc.IntegrationTesting public SyncUnaryClientRunner(Channel channel, int payloadSize, HistogramParams histogramParams) { - this.channel = Grpc.Core.Utils.Preconditions.CheckNotNull(channel); + this.channel = GrpcPreconditions.CheckNotNull(channel); this.payloadSize = payloadSize; this.histogram = new Histogram(histogramParams.Resolution, histogramParams.MaxPossible); diff --git a/src/csharp/Grpc.IntegrationTesting/Histogram.cs b/src/csharp/Grpc.IntegrationTesting/Histogram.cs index 7e7cb2c4de..08a674d817 100644 --- a/src/csharp/Grpc.IntegrationTesting/Histogram.cs +++ b/src/csharp/Grpc.IntegrationTesting/Histogram.cs @@ -1,6 +1,6 @@ #region Copyright notice and license -// Copyright 2015, Google Inc. +// Copyright 2015-2016, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -66,8 +66,8 @@ namespace Grpc.IntegrationTesting public Histogram(double resolution, double maxPossible) { - Grpc.Core.Utils.Preconditions.CheckArgument(resolution > 0); - Grpc.Core.Utils.Preconditions.CheckArgument(maxPossible > 0); + GrpcPreconditions.CheckArgument(resolution > 0); + GrpcPreconditions.CheckArgument(maxPossible > 0); this.maxPossible = maxPossible; this.multiplier = 1.0 + resolution; this.oneOnLogMultiplier = 1.0 / Math.Log(1.0 + resolution); diff --git a/src/csharp/Grpc.IntegrationTesting/ServerRunners.cs b/src/csharp/Grpc.IntegrationTesting/ServerRunners.cs index e8be7758ce..9b09b9bdd3 100644 --- a/src/csharp/Grpc.IntegrationTesting/ServerRunners.cs +++ b/src/csharp/Grpc.IntegrationTesting/ServerRunners.cs @@ -1,6 +1,6 @@ #region Copyright notice and license -// Copyright 2015, Google Inc. +// Copyright 2015-2016, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -57,7 +57,7 @@ namespace Grpc.IntegrationTesting /// </summary> public static IServerRunner CreateStarted(ServerConfig config) { - Grpc.Core.Utils.Preconditions.CheckArgument(config.ServerType == ServerType.ASYNC_SERVER); + GrpcPreconditions.CheckArgument(config.ServerType == ServerType.ASYNC_SERVER); var credentials = config.SecurityParams != null ? TestCredentials.CreateSslServerCredentials() : ServerCredentials.Insecure; // TODO: qps_driver needs to setup payload properly... @@ -83,7 +83,7 @@ namespace Grpc.IntegrationTesting public ServerRunnerImpl(Server server) { - this.server = Grpc.Core.Utils.Preconditions.CheckNotNull(server); + this.server = GrpcPreconditions.CheckNotNull(server); } public int BoundPort diff --git a/src/csharp/Grpc.IntegrationTesting/WorkerServiceImpl.cs b/src/csharp/Grpc.IntegrationTesting/WorkerServiceImpl.cs index bb2918bf46..59ecebf5a2 100644 --- a/src/csharp/Grpc.IntegrationTesting/WorkerServiceImpl.cs +++ b/src/csharp/Grpc.IntegrationTesting/WorkerServiceImpl.cs @@ -1,6 +1,6 @@ #region Copyright notice and license -// Copyright 2015, Google Inc. +// Copyright 2015-2016, Google Inc. // All rights reserved. // // Redistribution and use in source and binary forms, with or without @@ -49,7 +49,7 @@ namespace Grpc.Testing { public async Task RunServer(IAsyncStreamReader<ServerArgs> requestStream, IServerStreamWriter<ServerStatus> responseStream, ServerCallContext context) { - Grpc.Core.Utils.Preconditions.CheckState(await requestStream.MoveNext()); + GrpcPreconditions.CheckState(await requestStream.MoveNext()); var serverConfig = requestStream.Current.Setup; var runner = ServerRunners.CreateStarted(serverConfig); @@ -73,7 +73,7 @@ namespace Grpc.Testing public async Task RunClient(IAsyncStreamReader<ClientArgs> requestStream, IServerStreamWriter<ClientStatus> responseStream, ServerCallContext context) { - Grpc.Core.Utils.Preconditions.CheckState(await requestStream.MoveNext()); + GrpcPreconditions.CheckState(await requestStream.MoveNext()); var clientConfig = requestStream.Current.Setup; var runner = ClientRunners.CreateStarted(clientConfig); diff --git a/src/node/index.js b/src/node/index.js index 7eacdc67b1..1c197729d7 100644 --- a/src/node/index.js +++ b/src/node/index.js @@ -56,17 +56,18 @@ var grpc = require('./src/grpc_extension'); /** * Load a gRPC object from an existing ProtoBuf.Reflect object. * @param {ProtoBuf.Reflect.Namespace} value The ProtoBuf object to load. + * @param {Object=} options Options to apply to the loaded object * @return {Object<string, *>} The resulting gRPC object */ -exports.loadObject = function loadObject(value) { +exports.loadObject = function loadObject(value, options) { var result = {}; if (value.className === 'Namespace') { _.each(value.children, function(child) { - result[child.name] = loadObject(child); + result[child.name] = loadObject(child, options); }); return result; } else if (value.className === 'Service') { - return client.makeProtobufClientConstructor(value); + return client.makeProtobufClientConstructor(value, options); } else if (value.className === 'Message' || value.className === 'Enum') { return value.build(); } else { @@ -77,28 +78,45 @@ exports.loadObject = function loadObject(value) { var loadObject = exports.loadObject; /** - * Load a gRPC object from a .proto file. - * @param {string} filename The file to load + * Load a gRPC object from a .proto file. The options object can provide the + * following options: + * - convertFieldsToCamelCase: Loads this file with that option on protobuf.js + * set as specified. See + * https://github.com/dcodeIO/protobuf.js/wiki/Advanced-options for details + * - binaryAsBase64: deserialize bytes values as base64 strings instead of + * Buffers. Defaults to false + * - longsAsStrings: deserialize long values as strings instead of objects. + * Defaults to true + * @param {string|{root: string, file: string}} filename The file to load * @param {string=} format The file format to expect. Must be either 'proto' or * 'json'. Defaults to 'proto' + * @param {Object=} options Options to apply to the loaded file * @return {Object<string, *>} The resulting gRPC object */ -exports.load = function load(filename, format) { +exports.load = function load(filename, format, options) { if (!format) { format = 'proto'; } + var convertFieldsToCamelCaseOriginal = ProtoBuf.convertFieldsToCamelCase; + if(options && options.hasOwnProperty('convertFieldsToCamelCase')) { + ProtoBuf.convertFieldsToCamelCase = options.convertFieldsToCamelCase; + } var builder; - switch(format) { - case 'proto': - builder = ProtoBuf.loadProtoFile(filename); - break; - case 'json': - builder = ProtoBuf.loadJsonFile(filename); - break; - default: - throw new Error('Unrecognized format "' + format + '"'); + try { + switch(format) { + case 'proto': + builder = ProtoBuf.loadProtoFile(filename); + break; + case 'json': + builder = ProtoBuf.loadJsonFile(filename); + break; + default: + throw new Error('Unrecognized format "' + format + '"'); + } + } finally { + ProtoBuf.convertFieldsToCamelCase = convertFieldsToCamelCaseOriginal; } - return loadObject(builder.ns); + return loadObject(builder.ns, options); }; /** diff --git a/src/node/src/client.js b/src/node/src/client.js index b5247a69ee..c02c44730e 100644 --- a/src/node/src/client.js +++ b/src/node/src/client.js @@ -698,13 +698,16 @@ exports.waitForClientReady = function(client, deadline, callback) { * Creates a constructor for clients for the given service * @param {ProtoBuf.Reflect.Service} service The service to generate a client * for + * @param {Object=} options Options to apply to the client * @return {function(string, Object)} New client constructor */ -exports.makeProtobufClientConstructor = function(service) { - var method_attrs = common.getProtobufServiceAttrs(service, service.name); +exports.makeProtobufClientConstructor = function(service, options) { + var method_attrs = common.getProtobufServiceAttrs(service, service.name, + options); var Client = exports.makeClientConstructor( method_attrs, common.fullyQualifiedName(service)); Client.service = service; + Client.service.grpc_options = options; return Client; }; diff --git a/src/node/src/common.js b/src/node/src/common.js index 2e6c01c4d7..e5217608ec 100644 --- a/src/node/src/common.js +++ b/src/node/src/common.js @@ -44,9 +44,20 @@ var _ = require('lodash'); /** * Get a function that deserializes a specific type of protobuf. * @param {function()} cls The constructor of the message type to deserialize + * @param {bool=} binaryAsBase64 Deserialize bytes fields as base64 strings + * instead of Buffers. Defaults to false + * @param {bool=} longsAsStrings Deserialize long values as strings instead of + * objects. Defaults to true * @return {function(Buffer):cls} The deserialization function */ -exports.deserializeCls = function deserializeCls(cls) { +exports.deserializeCls = function deserializeCls(cls, binaryAsBase64, + longsAsStrings) { + if (binaryAsBase64 === undefined || binaryAsBase64 === null) { + binaryAsBase64 = false; + } + if (longsAsStrings === undefined || longsAsStrings === null) { + longsAsStrings = true; + } /** * Deserialize a buffer to a message object * @param {Buffer} arg_buf The buffer to deserialize @@ -55,7 +66,7 @@ exports.deserializeCls = function deserializeCls(cls) { return function deserialize(arg_buf) { // Convert to a native object with binary fields as Buffers (first argument) // and longs as strings (second argument) - return cls.decode(arg_buf).toRaw(false, true); + return cls.decode(arg_buf).toRaw(binaryAsBase64, longsAsStrings); }; }; @@ -119,19 +130,28 @@ exports.wrapIgnoreNull = function wrapIgnoreNull(func) { /** * Return a map from method names to method attributes for the service. * @param {ProtoBuf.Reflect.Service} service The service to get attributes for + * @param {Object=} options Options to apply to these attributes * @return {Object} The attributes map */ -exports.getProtobufServiceAttrs = function getProtobufServiceAttrs(service) { +exports.getProtobufServiceAttrs = function getProtobufServiceAttrs(service, + options) { var prefix = '/' + fullyQualifiedName(service) + '/'; + var binaryAsBase64, longsAsStrings; + if (options) { + binaryAsBase64 = options.binaryAsBase64; + longsAsStrings = options.longsAsStrings; + } return _.object(_.map(service.children, function(method) { return [_.camelCase(method.name), { path: prefix + method.name, requestStream: method.requestStream, responseStream: method.responseStream, requestSerialize: serializeCls(method.resolvedRequestType.build()), - requestDeserialize: deserializeCls(method.resolvedRequestType.build()), + requestDeserialize: deserializeCls(method.resolvedRequestType.build(), + binaryAsBase64, longsAsStrings), responseSerialize: serializeCls(method.resolvedResponseType.build()), - responseDeserialize: deserializeCls(method.resolvedResponseType.build()) + responseDeserialize: deserializeCls(method.resolvedResponseType.build(), + binaryAsBase64, longsAsStrings) }]; })); }; diff --git a/src/node/src/server.js b/src/node/src/server.js index e5aadcd565..0cf7ba3424 100644 --- a/src/node/src/server.js +++ b/src/node/src/server.js @@ -737,7 +737,12 @@ Server.prototype.addService = function(service, implementation) { * method implementation for the provided service. */ Server.prototype.addProtoService = function(service, implementation) { - this.addService(common.getProtobufServiceAttrs(service), implementation); + var options; + if (service.grpc_options) { + options = service.grpc_options; + } + this.addService(common.getProtobufServiceAttrs(service, options), + implementation); }; /** diff --git a/src/node/test/common_test.js b/src/node/test/common_test.js index 08ba429ed7..66a4205f82 100644 --- a/src/node/test/common_test.js +++ b/src/node/test/common_test.js @@ -1,6 +1,6 @@ /* * - * Copyright 2015, Google Inc. + * Copyright 2015-2016, Google Inc. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -42,7 +42,7 @@ var ProtoBuf = require('protobufjs'); var messages_proto = ProtoBuf.loadProtoFile( __dirname + '/test_messages.proto').build(); -describe('Proto message serialize and deserialize', function() { +describe('Proto message long int serialize and deserialize', function() { var longSerialize = common.serializeCls(messages_proto.LongValues); var longDeserialize = common.deserializeCls(messages_proto.LongValues); var pos_value = '314159265358979'; @@ -87,4 +87,52 @@ describe('Proto message serialize and deserialize', function() { assert.strictEqual(longDeserialize(serialized).sfixed_64.toString(), neg_value); }); + it('should deserialize as a number with the right option set', function() { + var longNumDeserialize = common.deserializeCls(messages_proto.LongValues, + false, false); + var serialized = longSerialize({int_64: pos_value}); + assert.strictEqual(typeof longDeserialize(serialized).int_64, 'string'); + /* With the longsAsStrings option disabled, long values are represented as + * objects with 3 keys: low, high, and unsigned */ + assert.strictEqual(typeof longNumDeserialize(serialized).int_64, 'object'); + }); +}); +describe('Proto message bytes serialize and deserialize', function() { + var sequenceSerialize = common.serializeCls(messages_proto.SequenceValues); + var sequenceDeserialize = common.deserializeCls( + messages_proto.SequenceValues); + var sequenceBase64Deserialize = common.deserializeCls( + messages_proto.SequenceValues, true); + var buffer_val = new Buffer([0x69, 0xb7]); + var base64_val = 'abc='; + it('should preserve a buffer', function() { + var serialized = sequenceSerialize({bytes_field: buffer_val}); + var deserialized = sequenceDeserialize(serialized); + assert.strictEqual(deserialized.bytes_field.compare(buffer_val), 0); + }); + it('should accept base64 encoded strings', function() { + var serialized = sequenceSerialize({bytes_field: base64_val}); + var deserialized = sequenceDeserialize(serialized); + assert.strictEqual(deserialized.bytes_field.compare(buffer_val), 0); + }); + it('should output base64 encoded strings with an option set', function() { + var serialized = sequenceSerialize({bytes_field: base64_val}); + var deserialized = sequenceBase64Deserialize(serialized); + assert.strictEqual(deserialized.bytes_field, base64_val); + }); + /* The next two tests are specific tests to verify that issue + * https://github.com/grpc/grpc/issues/5174 has been fixed. They are skipped + * because they will not pass until a protobuf.js release has been published + * with a fix for https://github.com/dcodeIO/protobuf.js/issues/390 */ + it.skip('should serialize a repeated field as packed by default', function() { + var expected_serialize = new Buffer([0x12, 0x01, 0x01, 0x0a]); + var serialized = sequenceSerialize({repeated_field: [10]}); + assert.strictEqual(expected_serialize.compare(serialized), 0); + }); + it.skip('should deserialize packed or unpacked repeated', function() { + var serialized = new Buffer([0x12, 0x01, 0x01, 0x0a]); + assert.doesNotThrow(function() { + sequenceDeserialize(serialized); + }); + }); }); diff --git a/src/node/test/test_messages.proto b/src/node/test/test_messages.proto index c77a937d3f..9b8cb875ee 100644 --- a/src/node/test/test_messages.proto +++ b/src/node/test/test_messages.proto @@ -36,3 +36,8 @@ message LongValues { fixed64 fixed_64 = 4; sfixed64 sfixed_64 = 5; } + +message SequenceValues { + bytes bytes_field = 1; + repeated int32 repeated_field = 2; +} diff --git a/summerofcode/ideas.md b/summerofcode/ideas.md new file mode 100644 index 0000000000..073262339b --- /dev/null +++ b/summerofcode/ideas.md @@ -0,0 +1,4 @@ +Google Summer of Code 2016 gRPC Ideas +===================================== + +(Skeleton for now.) diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index c8523847ab..ce8e4d2a10 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -51,11 +51,11 @@ #include "src/core/security/credentials.h" #include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h" #include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/end2end/data/ssl_test_data.h" #include "test/core/util/port.h" #include "test/core/util/test_config.h" #include "test/cpp/end2end/test_service_impl.h" #include "test/cpp/util/string_ref_helper.h" +#include "test/cpp/util/test_credentials_provider.h" using grpc::testing::EchoRequest; using grpc::testing::EchoResponse; @@ -191,12 +191,14 @@ class TestServiceImplDupPkg class TestScenario { public: - TestScenario(bool proxy, bool tls) : use_proxy(proxy), use_tls(tls) {} + TestScenario(bool proxy, const grpc::string& creds_type) + : use_proxy(proxy), credentials_type(creds_type) {} void Log() const { - gpr_log(GPR_INFO, "Scenario: proxy %d, tls %d", use_proxy, use_tls); + gpr_log(GPR_INFO, "Scenario: proxy %d, credentials %s", use_proxy, + credentials_type.c_str()); } bool use_proxy; - bool use_tls; + const grpc::string credentials_type; }; class End2endTest : public ::testing::TestWithParam<TestScenario> { @@ -220,14 +222,8 @@ class End2endTest : public ::testing::TestWithParam<TestScenario> { server_address_ << "127.0.0.1:" << port; // Setup server ServerBuilder builder; - auto server_creds = InsecureServerCredentials(); - if (GetParam().use_tls) { - SslServerCredentialsOptions::PemKeyCertPair pkcp = {test_server1_key, - test_server1_cert}; - SslServerCredentialsOptions ssl_opts; - ssl_opts.pem_root_certs = ""; - ssl_opts.pem_key_cert_pairs.push_back(pkcp); - server_creds = SslServerCredentials(ssl_opts); + auto server_creds = GetServerCredentials(GetParam().credentials_type); + if (GetParam().credentials_type != kInsecureCredentialsType) { server_creds->SetAuthMetadataProcessor(processor); } builder.AddListeningPort(server_address_.str(), server_creds); @@ -246,12 +242,8 @@ class End2endTest : public ::testing::TestWithParam<TestScenario> { } EXPECT_TRUE(is_server_started_); ChannelArguments args; - auto channel_creds = InsecureChannelCredentials(); - if (GetParam().use_tls) { - SslCredentialsOptions ssl_opts = {test_root_cert, "", ""}; - args.SetSslTargetNameOverride("foo.test.google.fr"); - channel_creds = SslCredentials(ssl_opts); - } + auto channel_creds = + GetChannelCredentials(GetParam().credentials_type, &args); if (!user_agent_prefix_.empty()) { args.SetUserAgentPrefix(user_agent_prefix_); } @@ -941,7 +933,7 @@ TEST_P(End2endTest, ChannelState) { // Takes 10s. TEST_P(End2endTest, ChannelStateTimeout) { - if (GetParam().use_tls) { + if (GetParam().credentials_type != kInsecureCredentialsType) { return; } int port = grpc_pick_unused_port_or_die(); @@ -1150,7 +1142,7 @@ class SecureEnd2endTest : public End2endTest { protected: SecureEnd2endTest() { GPR_ASSERT(!GetParam().use_proxy); - GPR_ASSERT(GetParam().use_tls); + GPR_ASSERT(GetParam().credentials_type != kInsecureCredentialsType); } }; @@ -1373,21 +1365,42 @@ TEST_P(SecureEnd2endTest, ClientAuthContext) { EXPECT_EQ("*.test.youtube.com", ToString(auth_ctx->GetPeerIdentity()[2])); } +std::vector<TestScenario> CreateTestScenarios(bool use_proxy, + bool test_insecure, + bool test_secure) { + std::vector<TestScenario> scenarios; + std::vector<grpc::string> credentials_types; + if (test_secure) { + credentials_types = GetSecureCredentialsTypeList(); + } + if (test_insecure) { + credentials_types.push_back(kInsecureCredentialsType); + } + for (auto it = credentials_types.begin(); it != credentials_types.end(); + ++it) { + scenarios.push_back(TestScenario(false, *it)); + if (use_proxy) { + scenarios.push_back(TestScenario(true, *it)); + } + } + return scenarios; +} + INSTANTIATE_TEST_CASE_P(End2end, End2endTest, - ::testing::Values(TestScenario(false, false), - TestScenario(false, true))); + ::testing::ValuesIn(CreateTestScenarios(false, true, + true))); INSTANTIATE_TEST_CASE_P(End2endServerTryCancel, End2endServerTryCancelTest, - ::testing::Values(TestScenario(false, false))); + ::testing::ValuesIn(CreateTestScenarios(false, true, + false))); INSTANTIATE_TEST_CASE_P(ProxyEnd2end, ProxyEnd2endTest, - ::testing::Values(TestScenario(false, false), - TestScenario(false, true), - TestScenario(true, false), - TestScenario(true, true))); + ::testing::ValuesIn(CreateTestScenarios(true, true, + true))); INSTANTIATE_TEST_CASE_P(SecureEnd2end, SecureEnd2endTest, - ::testing::Values(TestScenario(false, true))); + ::testing::ValuesIn(CreateTestScenarios(false, false, + true))); } // namespace } // namespace testing diff --git a/test/cpp/util/test_credentials_provider.cc b/test/cpp/util/test_credentials_provider.cc new file mode 100644 index 0000000000..1086e14258 --- /dev/null +++ b/test/cpp/util/test_credentials_provider.cc @@ -0,0 +1,82 @@ + +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "test/cpp/util/test_credentials_provider.h" + +#include "test/core/end2end/data/ssl_test_data.h" + +namespace grpc { +namespace testing { + +const char kTlsCredentialsType[] = "TLS_CREDENTIALS"; + +std::shared_ptr<ChannelCredentials> GetChannelCredentials( + const grpc::string& type, ChannelArguments* args) { + if (type == kInsecureCredentialsType) { + return InsecureChannelCredentials(); + } else if (type == kTlsCredentialsType) { + SslCredentialsOptions ssl_opts = {test_root_cert, "", ""}; + args->SetSslTargetNameOverride("foo.test.google.fr"); + return SslCredentials(ssl_opts); + } else { + gpr_log(GPR_ERROR, "Unsupported credentials type %s.", type.c_str()); + } + return nullptr; +} + +std::shared_ptr<ServerCredentials> GetServerCredentials( + const grpc::string& type) { + if (type == kInsecureCredentialsType) { + return InsecureServerCredentials(); + } else if (type == kTlsCredentialsType) { + SslServerCredentialsOptions::PemKeyCertPair pkcp = {test_server1_key, + test_server1_cert}; + SslServerCredentialsOptions ssl_opts; + ssl_opts.pem_root_certs = ""; + ssl_opts.pem_key_cert_pairs.push_back(pkcp); + return SslServerCredentials(ssl_opts); + } else { + gpr_log(GPR_ERROR, "Unsupported credentials type %s.", type.c_str()); + } + return nullptr; +} + +std::vector<grpc::string> GetSecureCredentialsTypeList() { + std::vector<grpc::string> types; + types.push_back(kTlsCredentialsType); + return types; +} + +} // namespace testing +} // namespace grpc diff --git a/test/cpp/util/test_credentials_provider.h b/test/cpp/util/test_credentials_provider.h new file mode 100644 index 0000000000..f7253051a9 --- /dev/null +++ b/test/cpp/util/test_credentials_provider.h @@ -0,0 +1,63 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPC_TEST_CPP_UTIL_TEST_CREDENTIALS_PROVIDER_H +#define GRPC_TEST_CPP_UTIL_TEST_CREDENTIALS_PROVIDER_H + +#include <memory> + +#include <grpc++/security/credentials.h> +#include <grpc++/security/server_credentials.h> +#include <grpc++/support/channel_arguments.h> + +namespace grpc { +namespace testing { + +const char kInsecureCredentialsType[] = "INSECURE_CREDENTIALS"; + +// Provide channel credentials according to the given type. Alter the channel +// arguments if needed. +std::shared_ptr<ChannelCredentials> GetChannelCredentials( + const grpc::string& type, ChannelArguments* args); + +// Provide server credentials according to the given type. +std::shared_ptr<ServerCredentials> GetServerCredentials( + const grpc::string& type); + +// Provide a list of secure credentials type. +std::vector<grpc::string> GetSecureCredentialsTypeList(); + +} // namespace testing +} // namespace grpc + +#endif // GRPC_TEST_CPP_UTIL_TEST_CREDENTIALS_PROVIDER_H diff --git a/tools/run_tests/run_node.bat b/tools/run_tests/run_node.bat index f5cf01f095..ad9ca14b8b 100644 --- a/tools/run_tests/run_node.bat +++ b/tools/run_tests/run_node.bat @@ -29,4 +29,4 @@ set JUNIT_REPORT_PATH=src\node\reports.xml set JUNIT_REPORT_STACK=1 -.\node_modules\.bin\mocha.cmd --reporter mocha-jenkins-reporter src\node\test
\ No newline at end of file +.\node_modules\.bin\mocha.cmd --reporter mocha-jenkins-reporter --timeout 8000 src\node\test
\ No newline at end of file diff --git a/tools/run_tests/run_node.sh b/tools/run_tests/run_node.sh index 40f61d77cc..178584ae8e 100755 --- a/tools/run_tests/run_node.sh +++ b/tools/run_tests/run_node.sh @@ -41,10 +41,13 @@ cd $(dirname $0)/../.. root=`pwd` +test_directory='src/node/test' +timeout=8000 + if [ "$CONFIG" = "gcov" ] then ./node_modules/.bin/istanbul cover --dir reports/node_coverage \ - -x **/interop/* ./node_modules/.bin/_mocha -- --timeout 8000 src/node/test + -x **/interop/* ./node_modules/.bin/_mocha -- --timeout $timeout $test_directory cd build gcov Release/obj.target/grpc/ext/*.o lcov --base-directory . --directory . -c -o coverage.info @@ -55,5 +58,7 @@ then echo '<html><head><meta http-equiv="refresh" content="0;URL=lcov-report/index.html"></head></html>' > \ ../reports/node_coverage/index.html else - JUNIT_REPORT_PATH=src/node/reports.xml JUNIT_REPORT_STACK=1 ./node_modules/.bin/mocha --reporter mocha-jenkins-reporter src/node/test + JUNIT_REPORT_PATH=src/node/reports.xml JUNIT_REPORT_STACK=1 \ + ./node_modules/.bin/mocha --timeout $timeout \ + --reporter mocha-jenkins-reporter $test_directory fi diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index de3716bc88..0b3efa29e3 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -334,13 +334,14 @@ class RubyLanguage(object): def test_specs(self, config, args): return [config.job_spec(['tools/run_tests/run_ruby.sh'], None, + timeout_seconds=10*60, environ=_FORCE_ENVIRON_FOR_WRAPPERS)] def pre_build_steps(self): return [['tools/run_tests/pre_build_ruby.sh']] def make_targets(self, test_regex): - return ['static_c'] + return [] def make_options(self): return [] @@ -1197,4 +1198,3 @@ else: if BuildAndRunError.POST_TEST in errors: exit_code |= 4 sys.exit(exit_code) - diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index 560379b645..160d06ad64 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -4188,7 +4188,8 @@ "test/cpp/util/cli_call.h", "test/cpp/util/create_test_channel.h", "test/cpp/util/string_ref_helper.h", - "test/cpp/util/subprocess.h" + "test/cpp/util/subprocess.h", + "test/cpp/util/test_credentials_provider.h" ], "language": "c++", "name": "grpc++_test_util", @@ -4204,7 +4205,9 @@ "test/cpp/util/string_ref_helper.cc", "test/cpp/util/string_ref_helper.h", "test/cpp/util/subprocess.cc", - "test/cpp/util/subprocess.h" + "test/cpp/util/subprocess.h", + "test/cpp/util/test_credentials_provider.cc", + "test/cpp/util/test_credentials_provider.h" ] }, { diff --git a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj index 3d353716a9..33860af620 100644 --- a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj +++ b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj @@ -153,6 +153,7 @@ <ClInclude Include="$(SolutionDir)\..\test\cpp\util\create_test_channel.h" /> <ClInclude Include="$(SolutionDir)\..\test\cpp\util\string_ref_helper.h" /> <ClInclude Include="$(SolutionDir)\..\test\cpp\util\subprocess.h" /> + <ClInclude Include="$(SolutionDir)\..\test\cpp\util\test_credentials_provider.h" /> </ItemGroup> <ItemGroup> <ClCompile Include="$(SolutionDir)\..\src\proto\grpc\testing\echo_messages.pb.cc"> @@ -191,6 +192,8 @@ </ClCompile> <ClCompile Include="$(SolutionDir)\..\test\cpp\util\subprocess.cc"> </ClCompile> + <ClCompile Include="$(SolutionDir)\..\test\cpp\util\test_credentials_provider.cc"> + </ClCompile> </ItemGroup> <ItemGroup> <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++\grpc++.vcxproj"> diff --git a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters index 27ac6751b9..b35ba1fd91 100644 --- a/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters +++ b/vsprojects/vcxproj/grpc++_test_util/grpc++_test_util.vcxproj.filters @@ -28,6 +28,9 @@ <ClCompile Include="$(SolutionDir)\..\test\cpp\util\subprocess.cc"> <Filter>test\cpp\util</Filter> </ClCompile> + <ClCompile Include="$(SolutionDir)\..\test\cpp\util\test_credentials_provider.cc"> + <Filter>test\cpp\util</Filter> + </ClCompile> </ItemGroup> <ItemGroup> <ClInclude Include="$(SolutionDir)\..\test\cpp\end2end\test_service_impl.h"> @@ -48,6 +51,9 @@ <ClInclude Include="$(SolutionDir)\..\test\cpp\util\subprocess.h"> <Filter>test\cpp\util</Filter> </ClInclude> + <ClInclude Include="$(SolutionDir)\..\test\cpp\util\test_credentials_provider.h"> + <Filter>test\cpp\util</Filter> + </ClInclude> </ItemGroup> <ItemGroup> |