From 7f43eaf365334f2c394e5e5c2b6e0777c72beaaa Mon Sep 17 00:00:00 2001 From: David Klempner Date: Wed, 18 Feb 2015 17:00:31 -0800 Subject: [PATCH 01/75] Ensure there is no concurrent poller for unary->multipoll The race here is: Initially unary poller has one FD, FD_1 Thread 1 adds FD_2, promoting to multipoll, entailing epoll_ctl on FD_1 and FD_2. Concurrently, Thread 2 returns from unary poll and executes one of FD_1's callbacks, which ultimately leads to a close(FD_1) which races with the epoll_ctl by thread 1. The solution is to ensure that we don't concurrently poll and promote, which requires a bit of extra care. --- src/core/iomgr/pollset_posix.c | 65 +++++++++++++++++++++++++++++++++- 1 file changed, 64 insertions(+), 1 deletion(-) diff --git a/src/core/iomgr/pollset_posix.c b/src/core/iomgr/pollset_posix.c index 05b78adeb61..00a22e7ae37 100644 --- a/src/core/iomgr/pollset_posix.c +++ b/src/core/iomgr/pollset_posix.c @@ -201,11 +201,43 @@ static void become_empty_pollset(grpc_pollset *pollset) { * via poll() */ -static void unary_poll_pollset_add_fd(grpc_pollset *pollset, grpc_fd *fd) { + +typedef struct grpc_unary_promote_args { + const grpc_pollset_vtable *original_vtable; + grpc_pollset *pollset; + grpc_fd *fd; +} grpc_unary_promote_args; + +static void unary_poll_do_promote(void *args, int success) { + grpc_unary_promote_args *up_args = args; + const grpc_pollset_vtable *original_vtable = up_args->original_vtable; + grpc_pollset *pollset = up_args->pollset; + grpc_fd *fd = up_args->fd; grpc_fd *fds[2]; + gpr_free(up_args); + + gpr_mu_lock(&pollset->mu); + /* First we need to ensure that nobody is polling concurrently */ + while (pollset->counter != 0 && pollset->vtable == original_vtable) { + grpc_pollset_kick(pollset); + gpr_cv_wait(&pollset->cv, &pollset->mu, gpr_inf_future); + } + /* At this point the pollset may no longer be a unary poller. In that case + * we should just call the right add function and be done. */ + /* TODO(klempner): If we're not careful this could cause infinite recursion. + * That's not a problem for now because empty_pollset has a trivial poller + * and we don't have any mechanism to unbecome multipoller. */ + if (pollset->vtable != original_vtable) { + pollset->vtable->add_fd(pollset, fd); + gpr_cv_broadcast(&pollset->cv); + gpr_mu_unlock(&pollset->mu); + return; + } + if (fd == pollset->data.ptr) return; fds[0] = pollset->data.ptr; fds[1] = fd; + if (!grpc_fd_is_orphaned(fds[0])) { grpc_platform_become_multipoller(pollset, fds, GPR_ARRAY_SIZE(fds)); grpc_fd_unref(fds[0]); @@ -216,6 +248,37 @@ static void unary_poll_pollset_add_fd(grpc_pollset *pollset, grpc_fd *fd) { pollset->data.ptr = fd; grpc_fd_ref(fd); } + + gpr_cv_broadcast(&pollset->cv); + gpr_mu_unlock(&pollset->mu); + + /* Matching ref in unary_poll_pollset_add_fd */ + grpc_fd_unref(fd); +} + +static void unary_poll_pollset_add_fd(grpc_pollset *pollset, grpc_fd *fd) { + grpc_unary_promote_args *up_args; + if (fd == pollset->data.ptr) return; + + if (grpc_fd_is_orphaned(pollset->data.ptr)) { + /* old fd is orphaned and we haven't cleaned it up until now, so remain a + * unary poller */ + grpc_fd_unref(pollset->data.ptr); + pollset->data.ptr = fd; + grpc_fd_ref(fd); + return; + } + + /* Now we need to promote. This needs to happen when we're not polling. Since + * this may be called from poll, the wait needs to happen asynchronously. */ + grpc_fd_ref(fd); + up_args = gpr_malloc(sizeof(*up_args)); + up_args->pollset = pollset; + up_args->fd = fd; + up_args->original_vtable = pollset->vtable; + grpc_iomgr_add_callback(unary_poll_do_promote, up_args); + + grpc_pollset_kick(pollset); } static void unary_poll_pollset_del_fd(grpc_pollset *pollset, grpc_fd *fd) { From 50faa8f78b210a9922644f624d3c0a36b4e2a2db Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Sat, 21 Feb 2015 17:51:52 -0800 Subject: [PATCH 02/75] Added support for true synchronous unary call and added some performance tests. --- .../Grpc.Core.Tests/ClientServerTest.cs | 11 +- .../Grpc.Core.Tests/Grpc.Core.Tests.csproj | 1 + src/csharp/Grpc.Core.Tests/PInvokeTest.cs | 139 ++++++++++++++++++ src/csharp/Grpc.Core/Calls.cs | 27 ++-- src/csharp/Grpc.Core/Grpc.Core.csproj | 1 + src/csharp/Grpc.Core/Internal/AsyncCall.cs | 25 ++++ .../Grpc.Core/Internal/CallSafeHandle.cs | 10 ++ src/csharp/Grpc.Core/Utils/BenchmarkUtil.cs | 68 +++++++++ src/csharp/Grpc.IntegrationTesting/Client.cs | 11 ++ src/csharp/ext/grpc_csharp_ext.c | 25 ++++ 10 files changed, 297 insertions(+), 21 deletions(-) create mode 100644 src/csharp/Grpc.Core.Tests/PInvokeTest.cs create mode 100644 src/csharp/Grpc.Core/Utils/BenchmarkUtil.cs diff --git a/src/csharp/Grpc.Core.Tests/ClientServerTest.cs b/src/csharp/Grpc.Core.Tests/ClientServerTest.cs index 7e564a2fba5..39be35c2190 100644 --- a/src/csharp/Grpc.Core.Tests/ClientServerTest.cs +++ b/src/csharp/Grpc.Core.Tests/ClientServerTest.cs @@ -101,15 +101,8 @@ namespace Grpc.Core.Tests using (Channel channel = new Channel(host + ":" + port)) { var call = new Call(unaryEchoStringMethod, channel); - - var stopwatch = new Stopwatch(); - stopwatch.Start(); - for (int i = 0; i < 1000; i++) - { - Calls.BlockingUnaryCall(call, "ABC", default(CancellationToken)); - } - stopwatch.Stop(); - Console.WriteLine("Elapsed time: " + stopwatch.ElapsedMilliseconds + "ms"); + BenchmarkUtil.RunBenchmark(100, 1000, + () => { Calls.BlockingUnaryCall(call, "ABC", default(CancellationToken)); }); } server.ShutdownAsync().Wait(); diff --git a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj index 687be3c0cb6..a365320f052 100644 --- a/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj +++ b/src/csharp/Grpc.Core.Tests/Grpc.Core.Tests.csproj @@ -41,6 +41,7 @@ + diff --git a/src/csharp/Grpc.Core.Tests/PInvokeTest.cs b/src/csharp/Grpc.Core.Tests/PInvokeTest.cs new file mode 100644 index 00000000000..b78609ccf08 --- /dev/null +++ b/src/csharp/Grpc.Core.Tests/PInvokeTest.cs @@ -0,0 +1,139 @@ +#region Copyright notice and license + +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; +using System.Diagnostics; +using System.Threading; +using System.Threading.Tasks; +using Grpc.Core; +using Grpc.Core.Internal; +using Grpc.Core.Utils; +using NUnit.Framework; +using System.Runtime.InteropServices; + +namespace Grpc.Core.Tests +{ + public class PInvokeTest + { + int counter; + + [DllImport("grpc_csharp_ext.dll")] + static extern GRPCCallError grpcsharp_test_callback([MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate callback); + + [DllImport("grpc_csharp_ext.dll")] + static extern IntPtr grpcsharp_test_nop(IntPtr ptr); + + [TestFixtureSetUp] + public void Init() + { + GrpcEnvironment.Initialize(); + } + + [TestFixtureTearDown] + public void Cleanup() + { + GrpcEnvironment.Shutdown(); + } + + [Test] + public void CompletionQueueCreateDestroyBenchmark() + { + BenchmarkUtil.RunBenchmark( + 100000, 1000000, + () => { + CompletionQueueSafeHandle cq = CompletionQueueSafeHandle.Create(); + cq.Dispose(); + } + ); + } + + + /// + /// Approximate results: + /// (mono ~80ns) + /// + [Test] + public void NativeCallbackBenchmark() + { + CompletionCallbackDelegate handler = Handler; + + counter = 0; + BenchmarkUtil.RunBenchmark( + 1000000, 10000000, + () => { + grpcsharp_test_callback(handler); + } + ); + Assert.AreNotEqual(0, counter); + } + + /// + /// Creating a new native-to-managed callback has significant overhead + /// compared to using an existing one. We need to be aware of this. + /// (~50us on mono) + /// + [Test] + public void NewNativeCallbackBenchmark() + { + counter = 0; + BenchmarkUtil.RunBenchmark( + 10000, 10000, + () => { + grpcsharp_test_callback(new CompletionCallbackDelegate(Handler)); + } + ); + Assert.AreNotEqual(0, counter); + } + + /// + /// Tests overhead of a simple PInvoke call. + /// + [Test] + public void NopPInvokeBenchmark() + { + CompletionCallbackDelegate handler = Handler; + + BenchmarkUtil.RunBenchmark( + 1000000, 100000000, + () => { + grpcsharp_test_nop(IntPtr.Zero); + } + ); + } + + private void Handler(GRPCOpError op, IntPtr ptr) { + counter ++; + } + } +} + diff --git a/src/csharp/Grpc.Core/Calls.cs b/src/csharp/Grpc.Core/Calls.cs index b67332676ac..c0973234e2a 100644 --- a/src/csharp/Grpc.Core/Calls.cs +++ b/src/csharp/Grpc.Core/Calls.cs @@ -47,19 +47,22 @@ namespace Grpc.Core { public static TResponse BlockingUnaryCall(Call call, TRequest req, CancellationToken token) { + var asyncCall = new AsyncCall(call.RequestSerializer, call.ResponseDeserializer); + return asyncCall.UnaryCall(call.Channel, call.MethodName, req); + //TODO: implement this in real synchronous style. - try { - return AsyncUnaryCall(call, req, token).Result; - } catch(AggregateException ae) { - foreach (var e in ae.InnerExceptions) - { - if (e is RpcException) - { - throw e; - } - } - throw; - } +// try { +// return AsyncUnaryCall(call, req, token).Result; +// } catch(AggregateException ae) { +// foreach (var e in ae.InnerExceptions) +// { +// if (e is RpcException) +// { +// throw e; +// } +// } +// throw; +// } } public static async Task AsyncUnaryCall(Call call, TRequest req, CancellationToken token) diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj index 4ad32e10e43..664d534dc29 100644 --- a/src/csharp/Grpc.Core/Grpc.Core.csproj +++ b/src/csharp/Grpc.Core/Grpc.Core.csproj @@ -62,6 +62,7 @@ + diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs index 5e96092e270..7c40661cf4b 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs @@ -112,6 +112,31 @@ namespace Grpc.Core.Internal InitializeInternal(call, true); } + public TRead UnaryCall(Channel channel, String methodName, TWrite msg) + { + using(CompletionQueueSafeHandle cq = CompletionQueueSafeHandle.Create()) + { + // TODO: handle serialization error... + byte[] payload = serializer(msg); + + unaryResponseTcs = new TaskCompletionSource(); + + lock (myLock) + { + Initialize(channel, cq, methodName); + started = true; + halfcloseRequested = true; + readingDone = true; + } + call.BlockingUnary(cq, payload, unaryResponseHandler); + + // task should be finished once BlockingUnary returns. + return unaryResponseTcs.Task.Result; + + // TODO: unwrap aggregate exception... + } + } + public Task UnaryCallAsync(TWrite msg) { lock (myLock) diff --git a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs index 659a383b4bd..1c0bc98f062 100644 --- a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs @@ -62,6 +62,11 @@ namespace Grpc.Core.Internal [MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate callback, byte[] send_buffer, UIntPtr send_buffer_len); + [DllImport("grpc_csharp_ext.dll")] + static extern void grpcsharp_call_blocking_unary(CallSafeHandle call, CompletionQueueSafeHandle dedicatedCq, + [MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate callback, + byte[] send_buffer, UIntPtr send_buffer_len); + [DllImport("grpc_csharp_ext.dll")] static extern GRPCCallError grpcsharp_call_start_client_streaming(CallSafeHandle call, [MarshalAs(UnmanagedType.FunctionPtr)] CompletionCallbackDelegate callback); @@ -113,6 +118,11 @@ namespace Grpc.Core.Internal AssertCallOk(grpcsharp_call_start_unary(this, callback, payload, new UIntPtr((ulong) payload.Length))); } + public void BlockingUnary(CompletionQueueSafeHandle dedicatedCq, byte[] payload, CompletionCallbackDelegate callback) + { + grpcsharp_call_blocking_unary(this, dedicatedCq, callback, payload, new UIntPtr((ulong) payload.Length)); + } + public void StartClientStreaming(CompletionCallbackDelegate callback) { AssertCallOk(grpcsharp_call_start_client_streaming(this, callback)); diff --git a/src/csharp/Grpc.Core/Utils/BenchmarkUtil.cs b/src/csharp/Grpc.Core/Utils/BenchmarkUtil.cs new file mode 100644 index 00000000000..3f0dae84cf8 --- /dev/null +++ b/src/csharp/Grpc.Core/Utils/BenchmarkUtil.cs @@ -0,0 +1,68 @@ +#region Copyright notice and license + +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; +using System.Threading.Tasks; +using System.Collections.Generic; +using System.Collections.Concurrent; +using System.Diagnostics; + +namespace Grpc.Core.Utils +{ + public static class BenchmarkUtil + { + /// + /// Runs a simple benchmark preceded by warmup phase. + /// + public static void RunBenchmark(int warmupIterations, int benchmarkIterations, Action action) + { + Console.WriteLine("Warmup iterations: " + warmupIterations); + for (int i = 0; i < warmupIterations; i++) + { + action(); + } + + Console.WriteLine("Benchmark iterations: " + benchmarkIterations); + var stopwatch = new Stopwatch(); + stopwatch.Start(); + for (int i = 0; i < benchmarkIterations; i++) + { + action(); + } + stopwatch.Stop(); + Console.WriteLine("Elapsed time: " + stopwatch.ElapsedMilliseconds + "ms"); + Console.WriteLine("Ops per second: " + (int) ((double) benchmarkIterations * 1000 / stopwatch.ElapsedMilliseconds)); + } + } +} + diff --git a/src/csharp/Grpc.IntegrationTesting/Client.cs b/src/csharp/Grpc.IntegrationTesting/Client.cs index bb650a112de..0c70744cea5 100644 --- a/src/csharp/Grpc.IntegrationTesting/Client.cs +++ b/src/csharp/Grpc.IntegrationTesting/Client.cs @@ -33,7 +33,9 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Text.RegularExpressions; +using System.Threading.Tasks; using Google.ProtocolBuffers; using Grpc.Core; using Grpc.Core.Utils; @@ -128,6 +130,9 @@ namespace Grpc.IntegrationTesting case "empty_stream": RunEmptyStream(client); break; + case "benchmark_empty_unary": + RunBenchmarkEmptyUnary(client); + break; default: throw new ArgumentException("Unknown test case " + testCase); } @@ -267,6 +272,12 @@ namespace Grpc.IntegrationTesting Console.WriteLine("Passed!"); } + // This is not an official interop test, but it's useful. + private void RunBenchmarkEmptyUnary(TestServiceGrpc.ITestServiceClient client) + { + BenchmarkUtil.RunBenchmark(10000, 10000, + () => { client.EmptyCall(Empty.DefaultInstance);}); + } private Payload CreateZerosPayload(int size) { return Payload.CreateBuilder().SetBody(ByteString.CopyFrom(new byte[size])).Build(); diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c index 5f9f22cab10..18e0431e3b2 100644 --- a/src/csharp/ext/grpc_csharp_ext.c +++ b/src/csharp/ext/grpc_csharp_ext.c @@ -343,6 +343,18 @@ grpcsharp_call_start_unary(grpc_call *call, callback_funcptr callback, return grpc_call_start_batch(call, ops, sizeof(ops) / sizeof(ops[0]), ctx); } +/* Synchronous unary call */ +GPR_EXPORT void GPR_CALLTYPE +grpcsharp_call_blocking_unary(grpc_call *call, grpc_completion_queue *dedicated_cq, callback_funcptr callback, + const char *send_buffer, size_t send_buffer_len) { + GPR_ASSERT(grpcsharp_call_start_unary(call, callback, send_buffer, send_buffer_len) == GRPC_CALL_OK); + + /* TODO: we would like to use pluck, but we don't know the tag */ + GPR_ASSERT(grpcsharp_completion_queue_next_with_callback(dedicated_cq) == GRPC_OP_COMPLETE); + grpc_completion_queue_shutdown(dedicated_cq); + GPR_ASSERT(grpcsharp_completion_queue_next_with_callback(dedicated_cq) == GRPC_QUEUE_SHUTDOWN); +} + GPR_EXPORT grpc_call_error GPR_CALLTYPE grpcsharp_call_start_client_streaming(grpc_call *call, callback_funcptr callback) { @@ -566,3 +578,16 @@ grpcsharp_server_request_call(grpc_server *server, grpc_completion_queue *cq, server, &(ctx->server_rpc_new.call), &(ctx->server_rpc_new.call_details), &(ctx->server_rpc_new.request_metadata), cq, ctx); } + + +/* For testing */ +GPR_EXPORT void GPR_CALLTYPE +grpcsharp_test_callback(callback_funcptr callback) { + callback(GRPC_OP_OK, NULL); +} + +/* For testing */ +GPR_EXPORT void *GPR_CALLTYPE +grpcsharp_test_nop(void *ptr) { + return ptr; +} From 4d703268adb6769b835070d3222a39c7fa399303 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 23 Feb 2015 11:33:44 -0800 Subject: [PATCH 03/75] Fix exception unwrapping for unary call --- src/csharp/Grpc.Core/Calls.cs | 14 ----- src/csharp/Grpc.Core/Grpc.Core.csproj | 1 + src/csharp/Grpc.Core/Internal/AsyncCall.cs | 14 +++-- src/csharp/Grpc.Core/RpcException.cs | 3 +- src/csharp/Grpc.Core/ServerCallHandler.cs | 2 + src/csharp/Grpc.Core/Utils/ExceptionHelper.cs | 57 +++++++++++++++++++ 6 files changed, 72 insertions(+), 19 deletions(-) create mode 100644 src/csharp/Grpc.Core/Utils/ExceptionHelper.cs diff --git a/src/csharp/Grpc.Core/Calls.cs b/src/csharp/Grpc.Core/Calls.cs index c0973234e2a..ee2208e5c25 100644 --- a/src/csharp/Grpc.Core/Calls.cs +++ b/src/csharp/Grpc.Core/Calls.cs @@ -49,20 +49,6 @@ namespace Grpc.Core { var asyncCall = new AsyncCall(call.RequestSerializer, call.ResponseDeserializer); return asyncCall.UnaryCall(call.Channel, call.MethodName, req); - - //TODO: implement this in real synchronous style. -// try { -// return AsyncUnaryCall(call, req, token).Result; -// } catch(AggregateException ae) { -// foreach (var e in ae.InnerExceptions) -// { -// if (e is RpcException) -// { -// throw e; -// } -// } -// throw; -// } } public static async Task AsyncUnaryCall(Call call, TRequest req, CancellationToken token) diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj index 664d534dc29..135ce26cbd2 100644 --- a/src/csharp/Grpc.Core/Grpc.Core.csproj +++ b/src/csharp/Grpc.Core/Grpc.Core.csproj @@ -63,6 +63,7 @@ + diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs index 7c40661cf4b..dadc9ab76cf 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs @@ -38,6 +38,7 @@ using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; using Grpc.Core.Internal; +using Grpc.Core.Utils; namespace Grpc.Core.Internal { @@ -130,10 +131,15 @@ namespace Grpc.Core.Internal } call.BlockingUnary(cq, payload, unaryResponseHandler); - // task should be finished once BlockingUnary returns. - return unaryResponseTcs.Task.Result; - - // TODO: unwrap aggregate exception... + try + { + // Once the blocking call returns, the result should be available synchronously. + return unaryResponseTcs.Task.Result; + } + catch (AggregateException ae) + { + throw ExceptionHelper.UnwrapRpcException(ae); + } } } diff --git a/src/csharp/Grpc.Core/RpcException.cs b/src/csharp/Grpc.Core/RpcException.cs index 5a9d0039bc9..e1cf64ca56a 100644 --- a/src/csharp/Grpc.Core/RpcException.cs +++ b/src/csharp/Grpc.Core/RpcException.cs @@ -49,7 +49,8 @@ namespace Grpc.Core this.status = status; } - public Status Status { + public Status Status + { get { return status; diff --git a/src/csharp/Grpc.Core/ServerCallHandler.cs b/src/csharp/Grpc.Core/ServerCallHandler.cs index 1296947f34d..289f97aecee 100644 --- a/src/csharp/Grpc.Core/ServerCallHandler.cs +++ b/src/csharp/Grpc.Core/ServerCallHandler.cs @@ -111,6 +111,8 @@ namespace Grpc.Core var finishedTask = asyncCall.ServerSideStreamingRequestCallAsync(new NullObserver()); + // TODO: this makes the call finish before all reads can be done which causes trouble + // in AsyncCall.HandleReadFinished callback. Revisit this. asyncCall.SendStatusFromServerAsync(new Status(StatusCode.Unimplemented, "No such method.")).Wait(); finishedTask.Wait(); diff --git a/src/csharp/Grpc.Core/Utils/ExceptionHelper.cs b/src/csharp/Grpc.Core/Utils/ExceptionHelper.cs new file mode 100644 index 00000000000..18702e1cc42 --- /dev/null +++ b/src/csharp/Grpc.Core/Utils/ExceptionHelper.cs @@ -0,0 +1,57 @@ +#region Copyright notice and license + +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; + +namespace Grpc.Core.Utils +{ + public static class ExceptionHelper + { + /// + /// If inner exceptions contain RpcException, rethrows it. + /// Otherwise, rethrows the original aggregate exception. + /// Always throws, the exception return type is here only to make the. + /// + public static Exception UnwrapRpcException(AggregateException ae) { + foreach (var e in ae.InnerExceptions) + { + if (e is RpcException) + { + throw e; + } + } + throw ae; + } + } +} + From 597a4f2273f9dda0dbac45b021706ce8b715f93c Mon Sep 17 00:00:00 2001 From: Julien Boeuf Date: Mon, 23 Feb 2015 15:57:14 -0800 Subject: [PATCH 04/75] Verifying the peer name on the X509 Certs correctly. - The SANs take precedence over the CN. - The CN is only checked if there are no SANs. - Fixing the tests as the test cert did not list *.test.google.com in the SANs. Will fix the test cert another time... --- src/core/tsi/ssl_transport_security.c | 32 ++++++++++++------- src/node/test/interop_sanity_test.js | 2 +- src/php/tests/interop/interop_client.php | 2 +- .../tests/unit_tests/SecureEndToEndTest.php | 2 +- src/ruby/bin/interop/interop_client.rb | 2 +- src/ruby/bin/math_client.rb | 2 +- src/ruby/bin/noproto_client.rb | 2 +- src/ruby/spec/client_server_spec.rb | 2 +- src/ruby/spec/generic/client_stub_spec.rb | 2 +- test/core/end2end/dualstack_socket_test.c | 4 +-- .../fixtures/chttp2_simple_ssl_fullstack.c | 2 +- .../chttp2_simple_ssl_with_oauth2_fullstack.c | 2 +- test/core/end2end/tests/cancel_after_accept.c | 2 +- .../cancel_after_accept_and_writes_closed.c | 4 +-- ...el_after_accept_and_writes_closed_legacy.c | 4 +-- .../tests/cancel_after_accept_legacy.c | 4 +-- test/core/end2end/tests/cancel_after_invoke.c | 2 +- .../tests/cancel_after_invoke_legacy.c | 2 +- .../core/end2end/tests/cancel_before_invoke.c | 2 +- .../tests/cancel_before_invoke_legacy.c | 2 +- test/core/end2end/tests/cancel_in_a_vacuum.c | 2 +- .../end2end/tests/cancel_in_a_vacuum_legacy.c | 2 +- .../end2end/tests/census_simple_request.c | 4 +-- .../tests/census_simple_request_legacy.c | 4 +-- test/core/end2end/tests/disappearing_server.c | 4 +-- .../tests/disappearing_server_legacy.c | 4 +-- ..._server_shutdown_finishes_inflight_calls.c | 4 +-- ..._shutdown_finishes_inflight_calls_legacy.c | 4 +-- test/core/end2end/tests/empty_batch.c | 2 +- .../end2end/tests/graceful_server_shutdown.c | 4 +-- .../tests/graceful_server_shutdown_legacy.c | 4 +-- .../core/end2end/tests/invoke_large_request.c | 4 +-- .../tests/invoke_large_request_legacy.c | 4 +-- .../end2end/tests/max_concurrent_streams.c | 12 +++---- .../tests/max_concurrent_streams_legacy.c | 12 +++---- test/core/end2end/tests/ping_pong_streaming.c | 4 +-- .../tests/ping_pong_streaming_legacy.c | 4 +-- ...esponse_with_binary_metadata_and_payload.c | 4 +-- ..._with_binary_metadata_and_payload_legacy.c | 4 +-- ...quest_response_with_metadata_and_payload.c | 4 +-- ...esponse_with_metadata_and_payload_legacy.c | 4 +-- .../tests/request_response_with_payload.c | 4 +-- .../request_response_with_payload_legacy.c | 4 +-- ...ponse_with_trailing_metadata_and_payload.c | 4 +-- ...ith_trailing_metadata_and_payload_legacy.c | 4 +-- .../tests/request_with_large_metadata.c | 4 +-- .../request_with_large_metadata_legacy.c | 4 +-- .../core/end2end/tests/request_with_payload.c | 4 +-- .../tests/request_with_payload_legacy.c | 4 +-- .../end2end/tests/simple_delayed_request.c | 4 +-- .../tests/simple_delayed_request_legacy.c | 4 +-- test/core/end2end/tests/simple_request.c | 4 +-- .../end2end/tests/simple_request_legacy.c | 8 ++--- test/core/end2end/tests/thread_stress.c | 2 +- .../core/end2end/tests/thread_stress_legacy.c | 2 +- .../writes_done_hangs_with_pending_read.c | 4 +-- ...ites_done_hangs_with_pending_read_legacy.c | 4 +-- test/cpp/interop/client.cc | 2 +- test/cpp/util/create_test_channel.cc | 2 +- 59 files changed, 124 insertions(+), 116 deletions(-) diff --git a/src/core/tsi/ssl_transport_security.c b/src/core/tsi/ssl_transport_security.c index 92fcb96dd23..f1a52746d24 100644 --- a/src/core/tsi/ssl_transport_security.c +++ b/src/core/tsi/ssl_transport_security.c @@ -1282,25 +1282,18 @@ tsi_result tsi_create_ssl_server_handshaker_factory( int tsi_ssl_peer_matches_name(const tsi_peer* peer, const char* name) { size_t i = 0; - const tsi_peer_property* property = tsi_peer_get_property_by_name( - peer, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY); - if (property == NULL || property->type != TSI_PEER_PROPERTY_TYPE_STRING) { - gpr_log(GPR_ERROR, "Invalid x509 subject common name property."); - return 0; - } - if (does_entry_match_name(property->value.string.data, - property->value.string.length, name)) { - return 1; - } + size_t san_count = 0; - property = tsi_peer_get_property_by_name( + /* Check the SAN first. */ + const tsi_peer_property* property = tsi_peer_get_property_by_name( peer, TSI_X509_SUBJECT_ALTERNATIVE_NAMES_PEER_PROPERTY); if (property == NULL || property->type != TSI_PEER_PROPERTY_TYPE_LIST) { gpr_log(GPR_ERROR, "Invalid x509 subject alternative names property."); return 0; } - for (i = 0; i < property->value.list.child_count; i++) { + san_count = property->value.list.child_count; + for (i = 0; i < san_count; i++) { const tsi_peer_property* alt_name_property = &property->value.list.children[i]; if (alt_name_property->type != TSI_PEER_PROPERTY_TYPE_STRING) { @@ -1312,5 +1305,20 @@ int tsi_ssl_peer_matches_name(const tsi_peer* peer, const char* name) { return 1; } } + + /* If there's no SAN, try the CN. */ + if (san_count == 0) { + property = tsi_peer_get_property_by_name( + peer, TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY); + if (property == NULL || property->type != TSI_PEER_PROPERTY_TYPE_STRING) { + gpr_log(GPR_ERROR, "Invalid x509 subject common name property."); + return 0; + } + if (does_entry_match_name(property->value.string.data, + property->value.string.length, name)) { + return 1; + } + } + return 0; /* Not found. */ } diff --git a/src/node/test/interop_sanity_test.js b/src/node/test/interop_sanity_test.js index 8dc933eac56..6b3aa3dd842 100644 --- a/src/node/test/interop_sanity_test.js +++ b/src/node/test/interop_sanity_test.js @@ -40,7 +40,7 @@ var server; var port; -var name_override = 'foo.test.google.com'; +var name_override = 'foo.test.google.fr'; describe('Interop tests', function() { before(function(done) { diff --git a/src/php/tests/interop/interop_client.php b/src/php/tests/interop/interop_client.php index 5a09fc7d78c..82ca4381690 100755 --- a/src/php/tests/interop/interop_client.php +++ b/src/php/tests/interop/interop_client.php @@ -215,7 +215,7 @@ $stub = new grpc\testing\TestServiceClient( new Grpc\BaseStub( $server_address, [ - 'grpc.ssl_target_name_override' => 'foo.test.google.com', + 'grpc.ssl_target_name_override' => 'foo.test.google.fr', 'credentials' => $credentials ])); diff --git a/src/php/tests/unit_tests/SecureEndToEndTest.php b/src/php/tests/unit_tests/SecureEndToEndTest.php index b19ac80ddd4..c23dd791acf 100755 --- a/src/php/tests/unit_tests/SecureEndToEndTest.php +++ b/src/php/tests/unit_tests/SecureEndToEndTest.php @@ -47,7 +47,7 @@ class SecureEndToEndTest extends PHPUnit_Framework_TestCase{ $this->channel = new Grpc\Channel( 'localhost:' . $port, [ - 'grpc.ssl_target_name_override' => 'foo.test.google.com', + 'grpc.ssl_target_name_override' => 'foo.test.google.fr', 'credentials' => $credentials ]); } diff --git a/src/ruby/bin/interop/interop_client.rb b/src/ruby/bin/interop/interop_client.rb index 76402b7c894..380ceb11df0 100755 --- a/src/ruby/bin/interop/interop_client.rb +++ b/src/ruby/bin/interop/interop_client.rb @@ -291,7 +291,7 @@ Args = Struct.new(:default_service_account, :host, :host_override, # validates the the command line options, returning them as a Hash. def parse_args args = Args.new - args.host_override = 'foo.test.google.com' + args.host_override = 'foo.test.google.fr' OptionParser.new do |opts| opts.on('--oauth_scope scope', 'Scope for OAuth tokens') { |v| args['oauth_scope'] = v } diff --git a/src/ruby/bin/math_client.rb b/src/ruby/bin/math_client.rb index cb085d4d429..db254efb002 100755 --- a/src/ruby/bin/math_client.rb +++ b/src/ruby/bin/math_client.rb @@ -127,7 +127,7 @@ def main if options['secure'] stub_opts = { :creds => test_creds, - GRPC::Core::Channel::SSL_TARGET => 'foo.test.google.com' + GRPC::Core::Channel::SSL_TARGET => 'foo.test.google.fr' } p stub_opts p options['host'] diff --git a/src/ruby/bin/noproto_client.rb b/src/ruby/bin/noproto_client.rb index 44710520d29..f3fd1103478 100755 --- a/src/ruby/bin/noproto_client.rb +++ b/src/ruby/bin/noproto_client.rb @@ -89,7 +89,7 @@ def main if options['secure'] stub_opts = { :creds => test_creds, - GRPC::Core::Channel::SSL_TARGET => 'foo.test.google.com' + GRPC::Core::Channel::SSL_TARGET => 'foo.test.google.fr' } p stub_opts p options['host'] diff --git a/src/ruby/spec/client_server_spec.rb b/src/ruby/spec/client_server_spec.rb index 52c985786a8..030ff328f21 100644 --- a/src/ruby/spec/client_server_spec.rb +++ b/src/ruby/spec/client_server_spec.rb @@ -353,7 +353,7 @@ describe 'the secure http client/server' do @server = GRPC::Core::Server.new(@server_queue, nil, server_creds) server_port = @server.add_http2_port(server_host, true) @server.start - args = { Channel::SSL_TARGET => 'foo.test.google.com' } + args = { Channel::SSL_TARGET => 'foo.test.google.fr' } @ch = Channel.new("0.0.0.0:#{server_port}", args, GRPC::Core::Credentials.new(certs[0], nil, nil)) end diff --git a/src/ruby/spec/generic/client_stub_spec.rb b/src/ruby/spec/generic/client_stub_spec.rb index 297a1338313..adf354f4eef 100644 --- a/src/ruby/spec/generic/client_stub_spec.rb +++ b/src/ruby/spec/generic/client_stub_spec.rb @@ -116,7 +116,7 @@ describe 'ClientStub' do host = FAKE_HOST blk = proc do opts = { - GRPC::Core::Channel::SSL_TARGET => 'foo.test.google.com', + GRPC::Core::Channel::SSL_TARGET => 'foo.test.google.fr', a_channel_arg: 'an_arg', creds: GRPC::Core::Credentials.new(certs[0], nil, nil) } diff --git a/test/core/end2end/dualstack_socket_test.c b/test/core/end2end/dualstack_socket_test.c index 2c4c3b77462..62676d01e09 100644 --- a/test/core/end2end/dualstack_socket_test.c +++ b/test/core/end2end/dualstack_socket_test.c @@ -112,7 +112,7 @@ void test_connect(const char *server_host, const char *client_host, int port, } /* Send a trivial request. */ - c = grpc_channel_create_call_old(client, "/foo", "foo.test.google.com", + c = grpc_channel_create_call_old(client, "/foo", "foo.test.google.fr", deadline); GPR_ASSERT(c); @@ -126,7 +126,7 @@ void test_connect(const char *server_host, const char *client_host, int port, GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(server, tag(100))); cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", - "foo.test.google.com", deadline, NULL); + "foo.test.google.fr", deadline, NULL); cq_verify(v_server); GPR_ASSERT(GRPC_CALL_OK == diff --git a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c index 1db9e727b86..9343eb5a427 100644 --- a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c +++ b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c @@ -105,7 +105,7 @@ static void chttp2_init_client_simple_ssl_secure_fullstack( grpc_ssl_credentials_create(NULL, NULL); grpc_arg ssl_name_override = {GRPC_ARG_STRING, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, - {"foo.test.google.com"}}; + {"foo.test.google.fr"}}; grpc_channel_args *new_client_args = grpc_channel_args_copy_and_add(client_args, &ssl_name_override); chttp2_init_client_secure_fullstack(f, new_client_args, ssl_creds); diff --git a/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c b/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c index 35e022c4947..9fb95c95d9d 100644 --- a/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c +++ b/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c @@ -107,7 +107,7 @@ static void chttp2_init_client_simple_ssl_with_oauth2_secure_fullstack( grpc_composite_credentials_create(ssl_creds, oauth2_creds); grpc_arg ssl_name_override = {GRPC_ARG_STRING, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, - {"foo.test.google.com"}}; + {"foo.test.google.fr"}}; grpc_channel_args *new_client_args = grpc_channel_args_copy_and_add(client_args, &ssl_name_override); chttp2_init_client_secure_fullstack(f, new_client_args, ssl_oauth2_creds); diff --git a/test/core/end2end/tests/cancel_after_accept.c b/test/core/end2end/tests/cancel_after_accept.c index faaa14727c9..1aeb723553a 100644 --- a/test/core/end2end/tests/cancel_after_accept.c +++ b/test/core/end2end/tests/cancel_after_accept.c @@ -132,7 +132,7 @@ static void test_cancel_after_accept(grpc_end2end_test_config config, int was_cancelled = 2; c = grpc_channel_create_call(f.client, f.client_cq, "/foo", - "foo.test.google.com", deadline); + "foo.test.google.fr", deadline); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); diff --git a/test/core/end2end/tests/cancel_after_accept_and_writes_closed.c b/test/core/end2end/tests/cancel_after_accept_and_writes_closed.c index c6fb8b3ea2e..a69f86a3271 100644 --- a/test/core/end2end/tests/cancel_after_accept_and_writes_closed.c +++ b/test/core/end2end/tests/cancel_after_accept_and_writes_closed.c @@ -113,7 +113,7 @@ static void test_cancel_after_accept_and_writes_closed( cq_verifier *v_client = cq_verifier_create(f.client_cq); cq_verifier *v_server = cq_verifier_create(f.server_cq); - c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com", + c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr", deadline); GPR_ASSERT(c); @@ -122,7 +122,7 @@ static void test_cancel_after_accept_and_writes_closed( GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", - "foo.test.google.com", deadline, NULL); + "foo.test.google.fr", deadline, NULL); cq_verify(v_server); GPR_ASSERT(GRPC_CALL_OK == diff --git a/test/core/end2end/tests/cancel_after_accept_and_writes_closed_legacy.c b/test/core/end2end/tests/cancel_after_accept_and_writes_closed_legacy.c index 85b7599b195..6a3a6528b90 100644 --- a/test/core/end2end/tests/cancel_after_accept_and_writes_closed_legacy.c +++ b/test/core/end2end/tests/cancel_after_accept_and_writes_closed_legacy.c @@ -113,7 +113,7 @@ static void test_cancel_after_accept_and_writes_closed( cq_verifier *v_client = cq_verifier_create(f.client_cq); cq_verifier *v_server = cq_verifier_create(f.server_cq); - c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com", + c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr", deadline); GPR_ASSERT(c); @@ -121,7 +121,7 @@ static void test_cancel_after_accept_and_writes_closed( grpc_call_invoke_old(c, f.client_cq, tag(2), tag(3), 0)); GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); - cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com", + cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr", deadline, NULL); cq_verify(v_server); diff --git a/test/core/end2end/tests/cancel_after_accept_legacy.c b/test/core/end2end/tests/cancel_after_accept_legacy.c index 345c31d31f8..15338b5c7ad 100644 --- a/test/core/end2end/tests/cancel_after_accept_legacy.c +++ b/test/core/end2end/tests/cancel_after_accept_legacy.c @@ -113,7 +113,7 @@ static void test_cancel_after_accept(grpc_end2end_test_config config, cq_verifier *v_client = cq_verifier_create(f.client_cq); cq_verifier *v_server = cq_verifier_create(f.server_cq); - c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com", + c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr", deadline); GPR_ASSERT(c); @@ -121,7 +121,7 @@ static void test_cancel_after_accept(grpc_end2end_test_config config, grpc_call_invoke_old(c, f.client_cq, tag(2), tag(3), 0)); GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); - cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com", + cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr", deadline, NULL); cq_verify(v_server); diff --git a/test/core/end2end/tests/cancel_after_invoke.c b/test/core/end2end/tests/cancel_after_invoke.c index 3c75024922b..71d241ffee9 100644 --- a/test/core/end2end/tests/cancel_after_invoke.c +++ b/test/core/end2end/tests/cancel_after_invoke.c @@ -125,7 +125,7 @@ static void test_cancel_after_invoke(grpc_end2end_test_config config, grpc_byte_buffer_create(&request_payload_slice, 1); c = grpc_channel_create_call(f.client, f.client_cq, "/foo", - "foo.test.google.com", deadline); + "foo.test.google.fr", deadline); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); diff --git a/test/core/end2end/tests/cancel_after_invoke_legacy.c b/test/core/end2end/tests/cancel_after_invoke_legacy.c index 64af7cd3db2..092b35d0a9a 100644 --- a/test/core/end2end/tests/cancel_after_invoke_legacy.c +++ b/test/core/end2end/tests/cancel_after_invoke_legacy.c @@ -111,7 +111,7 @@ static void test_cancel_after_invoke(grpc_end2end_test_config config, gpr_timespec deadline = five_seconds_time(); cq_verifier *v_client = cq_verifier_create(f.client_cq); - c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com", + c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr", deadline); GPR_ASSERT(c); diff --git a/test/core/end2end/tests/cancel_before_invoke.c b/test/core/end2end/tests/cancel_before_invoke.c index bee6dd2e7b9..0ab9ac6c2f2 100644 --- a/test/core/end2end/tests/cancel_before_invoke.c +++ b/test/core/end2end/tests/cancel_before_invoke.c @@ -123,7 +123,7 @@ static void test_cancel_before_invoke(grpc_end2end_test_config config, int test_ grpc_byte_buffer_create(&request_payload_slice, 1); c = grpc_channel_create_call(f.client, f.client_cq, "/foo", - "foo.test.google.com", deadline); + "foo.test.google.fr", deadline); GPR_ASSERT(c); GPR_ASSERT(GRPC_CALL_OK == grpc_call_cancel(c)); diff --git a/test/core/end2end/tests/cancel_before_invoke_legacy.c b/test/core/end2end/tests/cancel_before_invoke_legacy.c index 23e82cf2683..0c308acde03 100644 --- a/test/core/end2end/tests/cancel_before_invoke_legacy.c +++ b/test/core/end2end/tests/cancel_before_invoke_legacy.c @@ -109,7 +109,7 @@ static void test_cancel_before_invoke(grpc_end2end_test_config config) { gpr_timespec deadline = five_seconds_time(); cq_verifier *v_client = cq_verifier_create(f.client_cq); - c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com", + c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr", deadline); GPR_ASSERT(c); diff --git a/test/core/end2end/tests/cancel_in_a_vacuum.c b/test/core/end2end/tests/cancel_in_a_vacuum.c index 8228353b09b..6cb87525d00 100644 --- a/test/core/end2end/tests/cancel_in_a_vacuum.c +++ b/test/core/end2end/tests/cancel_in_a_vacuum.c @@ -110,7 +110,7 @@ static void test_cancel_in_a_vacuum(grpc_end2end_test_config config, cq_verifier *v_client = cq_verifier_create(f.client_cq); c = grpc_channel_create_call(f.client, f.client_cq, "/foo", - "foo.test.google.com", deadline); + "foo.test.google.fr", deadline); GPR_ASSERT(c); GPR_ASSERT(GRPC_CALL_OK == mode.initiate_cancel(c)); diff --git a/test/core/end2end/tests/cancel_in_a_vacuum_legacy.c b/test/core/end2end/tests/cancel_in_a_vacuum_legacy.c index 869f091180c..cc6297b1337 100644 --- a/test/core/end2end/tests/cancel_in_a_vacuum_legacy.c +++ b/test/core/end2end/tests/cancel_in_a_vacuum_legacy.c @@ -109,7 +109,7 @@ static void test_cancel_in_a_vacuum(grpc_end2end_test_config config, gpr_timespec deadline = five_seconds_time(); cq_verifier *v_client = cq_verifier_create(f.client_cq); - c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com", + c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr", deadline); GPR_ASSERT(c); diff --git a/test/core/end2end/tests/census_simple_request.c b/test/core/end2end/tests/census_simple_request.c index 003a8bef9b7..98244db5412 100644 --- a/test/core/end2end/tests/census_simple_request.c +++ b/test/core/end2end/tests/census_simple_request.c @@ -106,7 +106,7 @@ static void test_body(grpc_end2end_test_fixture f) { cq_verifier *v_client = cq_verifier_create(f.client_cq); cq_verifier *v_server = cq_verifier_create(f.server_cq); - c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com", + c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr", deadline); GPR_ASSERT(c); tag(1); @@ -118,7 +118,7 @@ static void test_body(grpc_end2end_test_fixture f) { cq_verify(v_client); GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); - cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com", + cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr", deadline, NULL); cq_verify(v_server); diff --git a/test/core/end2end/tests/census_simple_request_legacy.c b/test/core/end2end/tests/census_simple_request_legacy.c index 003a8bef9b7..98244db5412 100644 --- a/test/core/end2end/tests/census_simple_request_legacy.c +++ b/test/core/end2end/tests/census_simple_request_legacy.c @@ -106,7 +106,7 @@ static void test_body(grpc_end2end_test_fixture f) { cq_verifier *v_client = cq_verifier_create(f.client_cq); cq_verifier *v_server = cq_verifier_create(f.server_cq); - c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com", + c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr", deadline); GPR_ASSERT(c); tag(1); @@ -118,7 +118,7 @@ static void test_body(grpc_end2end_test_fixture f) { cq_verify(v_client); GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); - cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com", + cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr", deadline, NULL); cq_verify(v_server); diff --git a/test/core/end2end/tests/disappearing_server.c b/test/core/end2end/tests/disappearing_server.c index 611589678f4..d5d1550f903 100644 --- a/test/core/end2end/tests/disappearing_server.c +++ b/test/core/end2end/tests/disappearing_server.c @@ -97,7 +97,7 @@ static void do_request_and_shutdown_server(grpc_end2end_test_fixture *f, grpc_call *s; gpr_timespec deadline = five_seconds_time(); - c = grpc_channel_create_call_old(f->client, "/foo", "foo.test.google.com", + c = grpc_channel_create_call_old(f->client, "/foo", "foo.test.google.fr", deadline); GPR_ASSERT(c); @@ -110,7 +110,7 @@ static void do_request_and_shutdown_server(grpc_end2end_test_fixture *f, GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f->server, tag(100))); cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", - "foo.test.google.com", deadline, NULL); + "foo.test.google.fr", deadline, NULL); cq_verify(v_server); GPR_ASSERT(GRPC_CALL_OK == diff --git a/test/core/end2end/tests/disappearing_server_legacy.c b/test/core/end2end/tests/disappearing_server_legacy.c index ff8832a231e..7dd6804b380 100644 --- a/test/core/end2end/tests/disappearing_server_legacy.c +++ b/test/core/end2end/tests/disappearing_server_legacy.c @@ -97,7 +97,7 @@ static void do_request_and_shutdown_server(grpc_end2end_test_fixture *f, grpc_call *s; gpr_timespec deadline = five_seconds_time(); - c = grpc_channel_create_call_old(f->client, "/foo", "foo.test.google.com", + c = grpc_channel_create_call_old(f->client, "/foo", "foo.test.google.fr", deadline); GPR_ASSERT(c); @@ -109,7 +109,7 @@ static void do_request_and_shutdown_server(grpc_end2end_test_fixture *f, cq_verify(v_client); GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f->server, tag(100))); - cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com", + cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr", deadline, NULL); cq_verify(v_server); diff --git a/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls.c b/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls.c index 49ec4715cc4..d65617c4735 100644 --- a/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls.c +++ b/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls.c @@ -111,7 +111,7 @@ static void test_early_server_shutdown_finishes_inflight_calls( cq_verifier *v_client = cq_verifier_create(f.client_cq); cq_verifier *v_server = cq_verifier_create(f.server_cq); - c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com", + c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr", deadline); GPR_ASSERT(c); @@ -124,7 +124,7 @@ static void test_early_server_shutdown_finishes_inflight_calls( GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", - "foo.test.google.com", deadline, NULL); + "foo.test.google.fr", deadline, NULL); cq_verify(v_server); GPR_ASSERT(GRPC_CALL_OK == diff --git a/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls_legacy.c b/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls_legacy.c index 2e3a05e6692..09ddfc1671a 100644 --- a/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls_legacy.c +++ b/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls_legacy.c @@ -111,7 +111,7 @@ static void test_early_server_shutdown_finishes_inflight_calls( cq_verifier *v_client = cq_verifier_create(f.client_cq); cq_verifier *v_server = cq_verifier_create(f.server_cq); - c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com", + c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr", deadline); GPR_ASSERT(c); @@ -123,7 +123,7 @@ static void test_early_server_shutdown_finishes_inflight_calls( cq_verify(v_client); GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); - cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com", + cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr", deadline, NULL); cq_verify(v_server); diff --git a/test/core/end2end/tests/empty_batch.c b/test/core/end2end/tests/empty_batch.c index 7faeeaa889b..de22518301b 100644 --- a/test/core/end2end/tests/empty_batch.c +++ b/test/core/end2end/tests/empty_batch.c @@ -111,7 +111,7 @@ static void empty_batch_body(grpc_end2end_test_fixture f) { grpc_op *op = NULL; c = grpc_channel_create_call(f.client, f.client_cq, "/foo", - "foo.test.google.com", deadline); + "foo.test.google.fr", deadline); GPR_ASSERT(c); GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(c, op, 0, tag(1))); diff --git a/test/core/end2end/tests/graceful_server_shutdown.c b/test/core/end2end/tests/graceful_server_shutdown.c index ab9792e40ab..9227d3bd463 100644 --- a/test/core/end2end/tests/graceful_server_shutdown.c +++ b/test/core/end2end/tests/graceful_server_shutdown.c @@ -110,7 +110,7 @@ static void test_early_server_shutdown_finishes_inflight_calls( cq_verifier *v_client = cq_verifier_create(f.client_cq); cq_verifier *v_server = cq_verifier_create(f.server_cq); - c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com", + c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr", deadline); GPR_ASSERT(c); @@ -123,7 +123,7 @@ static void test_early_server_shutdown_finishes_inflight_calls( GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", - "foo.test.google.com", deadline, NULL); + "foo.test.google.fr", deadline, NULL); cq_verify(v_server); GPR_ASSERT(GRPC_CALL_OK == diff --git a/test/core/end2end/tests/graceful_server_shutdown_legacy.c b/test/core/end2end/tests/graceful_server_shutdown_legacy.c index 852a153accd..19c895eaa28 100644 --- a/test/core/end2end/tests/graceful_server_shutdown_legacy.c +++ b/test/core/end2end/tests/graceful_server_shutdown_legacy.c @@ -110,7 +110,7 @@ static void test_early_server_shutdown_finishes_inflight_calls( cq_verifier *v_client = cq_verifier_create(f.client_cq); cq_verifier *v_server = cq_verifier_create(f.server_cq); - c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com", + c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr", deadline); GPR_ASSERT(c); @@ -122,7 +122,7 @@ static void test_early_server_shutdown_finishes_inflight_calls( cq_verify(v_client); GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); - cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com", + cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr", deadline, NULL); cq_verify(v_server); diff --git a/test/core/end2end/tests/invoke_large_request.c b/test/core/end2end/tests/invoke_large_request.c index 2a302e2b137..86a0fbdb70d 100644 --- a/test/core/end2end/tests/invoke_large_request.c +++ b/test/core/end2end/tests/invoke_large_request.c @@ -122,7 +122,7 @@ static void test_invoke_large_request(grpc_end2end_test_config config) { GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); - c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com", + c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr", deadline); GPR_ASSERT(c); @@ -139,7 +139,7 @@ static void test_invoke_large_request(grpc_end2end_test_config config) { cq_verify_empty(v_client); cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", - "foo.test.google.com", deadline, NULL); + "foo.test.google.fr", deadline, NULL); cq_verify(v_server); GPR_ASSERT(GRPC_CALL_OK == diff --git a/test/core/end2end/tests/invoke_large_request_legacy.c b/test/core/end2end/tests/invoke_large_request_legacy.c index 875458e7f80..d0a1cebfcb4 100644 --- a/test/core/end2end/tests/invoke_large_request_legacy.c +++ b/test/core/end2end/tests/invoke_large_request_legacy.c @@ -122,7 +122,7 @@ static void test_invoke_large_request(grpc_end2end_test_config config) { GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); - c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com", + c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr", deadline); GPR_ASSERT(c); @@ -138,7 +138,7 @@ static void test_invoke_large_request(grpc_end2end_test_config config) { request (as this request is very large) */ cq_verify_empty(v_client); - cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com", + cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr", deadline, NULL); cq_verify(v_server); diff --git a/test/core/end2end/tests/max_concurrent_streams.c b/test/core/end2end/tests/max_concurrent_streams.c index 85369b5aac4..743048881d7 100644 --- a/test/core/end2end/tests/max_concurrent_streams.c +++ b/test/core/end2end/tests/max_concurrent_streams.c @@ -109,7 +109,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) { cq_verifier *v_client = cq_verifier_create(f.client_cq); cq_verifier *v_server = cq_verifier_create(f.server_cq); - c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com", + c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr", deadline); GPR_ASSERT(c); @@ -122,7 +122,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) { GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", - "foo.test.google.com", deadline, NULL); + "foo.test.google.fr", deadline, NULL); cq_verify(v_server); GPR_ASSERT(GRPC_CALL_OK == @@ -182,10 +182,10 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) { /* start two requests - ensuring that the second is not accepted until the first completes */ deadline = five_seconds_time(); - c1 = grpc_channel_create_call_old(f.client, "/alpha", "foo.test.google.com", + c1 = grpc_channel_create_call_old(f.client, "/alpha", "foo.test.google.fr", deadline); GPR_ASSERT(c1); - c2 = grpc_channel_create_call_old(f.client, "/beta", "foo.test.google.com", + c2 = grpc_channel_create_call_old(f.client, "/beta", "foo.test.google.fr", deadline); GPR_ASSERT(c1); @@ -211,7 +211,7 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) { cq_expect_server_rpc_new(v_server, &s1, tag(100), live_call == 300 ? "/alpha" : "/beta", - "foo.test.google.com", deadline, NULL); + "foo.test.google.fr", deadline, NULL); cq_verify(v_server); GPR_ASSERT(GRPC_CALL_OK == @@ -237,7 +237,7 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) { GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(200))); cq_expect_server_rpc_new(v_server, &s2, tag(200), live_call == 300 ? "/alpha" : "/beta", - "foo.test.google.com", deadline, NULL); + "foo.test.google.fr", deadline, NULL); cq_verify(v_server); GPR_ASSERT(GRPC_CALL_OK == diff --git a/test/core/end2end/tests/max_concurrent_streams_legacy.c b/test/core/end2end/tests/max_concurrent_streams_legacy.c index 0cb118d7950..8bf11543878 100644 --- a/test/core/end2end/tests/max_concurrent_streams_legacy.c +++ b/test/core/end2end/tests/max_concurrent_streams_legacy.c @@ -109,7 +109,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) { cq_verifier *v_client = cq_verifier_create(f.client_cq); cq_verifier *v_server = cq_verifier_create(f.server_cq); - c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com", + c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr", deadline); GPR_ASSERT(c); @@ -121,7 +121,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) { cq_verify(v_client); GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); - cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com", + cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr", deadline, NULL); cq_verify(v_server); @@ -182,10 +182,10 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) { /* start two requests - ensuring that the second is not accepted until the first completes */ deadline = five_seconds_time(); - c1 = grpc_channel_create_call_old(f.client, "/alpha", "foo.test.google.com", + c1 = grpc_channel_create_call_old(f.client, "/alpha", "foo.test.google.fr", deadline); GPR_ASSERT(c1); - c2 = grpc_channel_create_call_old(f.client, "/beta", "foo.test.google.com", + c2 = grpc_channel_create_call_old(f.client, "/beta", "foo.test.google.fr", deadline); GPR_ASSERT(c1); @@ -211,7 +211,7 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) { cq_expect_server_rpc_new(v_server, &s1, tag(100), live_call == 300 ? "/alpha" : "/beta", - "foo.test.google.com", deadline, NULL); + "foo.test.google.fr", deadline, NULL); cq_verify(v_server); GPR_ASSERT(GRPC_CALL_OK == @@ -237,7 +237,7 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) { GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(200))); cq_expect_server_rpc_new(v_server, &s2, tag(200), live_call == 300 ? "/alpha" : "/beta", - "foo.test.google.com", deadline, NULL); + "foo.test.google.fr", deadline, NULL); cq_verify(v_server); GPR_ASSERT(GRPC_CALL_OK == diff --git a/test/core/end2end/tests/ping_pong_streaming.c b/test/core/end2end/tests/ping_pong_streaming.c index 2930ba61430..06a029eb650 100644 --- a/test/core/end2end/tests/ping_pong_streaming.c +++ b/test/core/end2end/tests/ping_pong_streaming.c @@ -118,7 +118,7 @@ static void test_pingpong_streaming(grpc_end2end_test_config config, cq_verifier *v_server = cq_verifier_create(f.server_cq); gpr_log(GPR_INFO, "testing with %d message pairs.", messages); - c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com", + c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr", deadline); GPR_ASSERT(c); @@ -128,7 +128,7 @@ static void test_pingpong_streaming(grpc_end2end_test_config config, GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", - "foo.test.google.com", deadline, NULL); + "foo.test.google.fr", deadline, NULL); cq_verify(v_server); GPR_ASSERT(GRPC_CALL_OK == grpc_call_server_accept_old(s, f.server_cq, tag(102))); diff --git a/test/core/end2end/tests/ping_pong_streaming_legacy.c b/test/core/end2end/tests/ping_pong_streaming_legacy.c index b2764e9f858..b4175b4d095 100644 --- a/test/core/end2end/tests/ping_pong_streaming_legacy.c +++ b/test/core/end2end/tests/ping_pong_streaming_legacy.c @@ -118,7 +118,7 @@ static void test_pingpong_streaming(grpc_end2end_test_config config, cq_verifier *v_server = cq_verifier_create(f.server_cq); gpr_log(GPR_INFO, "testing with %d message pairs.", messages); - c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com", + c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr", deadline); GPR_ASSERT(c); @@ -127,7 +127,7 @@ static void test_pingpong_streaming(grpc_end2end_test_config config, GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); - cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com", + cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr", deadline, NULL); cq_verify(v_server); GPR_ASSERT(GRPC_CALL_OK == diff --git a/test/core/end2end/tests/request_response_with_binary_metadata_and_payload.c b/test/core/end2end/tests/request_response_with_binary_metadata_and_payload.c index 843e9db9edd..45b2ea3e823 100644 --- a/test/core/end2end/tests/request_response_with_binary_metadata_and_payload.c +++ b/test/core/end2end/tests/request_response_with_binary_metadata_and_payload.c @@ -140,7 +140,7 @@ static void test_request_response_with_metadata_and_payload( int was_cancelled = 2; c = grpc_channel_create_call(f.client, f.client_cq, "/foo", - "foo.test.google.com", deadline); + "foo.test.google.fr", deadline); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -210,7 +210,7 @@ static void test_request_response_with_metadata_and_payload( GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); GPR_ASSERT(0 == strcmp(details, "xyz")); GPR_ASSERT(0 == strcmp(call_details.method, "/foo")); - GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.com")); + GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr")); GPR_ASSERT(was_cancelled == 0); GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world")); GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, "hello you")); diff --git a/test/core/end2end/tests/request_response_with_binary_metadata_and_payload_legacy.c b/test/core/end2end/tests/request_response_with_binary_metadata_and_payload_legacy.c index 9c09e516fae..be74e8bdce9 100644 --- a/test/core/end2end/tests/request_response_with_binary_metadata_and_payload_legacy.c +++ b/test/core/end2end/tests/request_response_with_binary_metadata_and_payload_legacy.c @@ -137,7 +137,7 @@ static void test_request_response_with_metadata_and_payload( gpr_slice_unref(request_payload_slice); gpr_slice_unref(response_payload_slice); - c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com", + c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr", deadline); GPR_ASSERT(c); @@ -157,7 +157,7 @@ static void test_request_response_with_metadata_and_payload( cq_verify(v_client); cq_expect_server_rpc_new( - v_server, &s, tag(100), "/foo", "foo.test.google.com", deadline, "key1-bin", + v_server, &s, tag(100), "/foo", "foo.test.google.fr", deadline, "key1-bin", "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc", "key2-bin", "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d", NULL); cq_verify(v_server); diff --git a/test/core/end2end/tests/request_response_with_metadata_and_payload.c b/test/core/end2end/tests/request_response_with_metadata_and_payload.c index 7f7b594d807..1675a9e5377 100644 --- a/test/core/end2end/tests/request_response_with_metadata_and_payload.c +++ b/test/core/end2end/tests/request_response_with_metadata_and_payload.c @@ -133,7 +133,7 @@ static void test_request_response_with_metadata_and_payload( int was_cancelled = 2; c = grpc_channel_create_call(f.client, f.client_cq, "/foo", - "foo.test.google.com", deadline); + "foo.test.google.fr", deadline); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -203,7 +203,7 @@ static void test_request_response_with_metadata_and_payload( GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); GPR_ASSERT(0 == strcmp(details, "xyz")); GPR_ASSERT(0 == strcmp(call_details.method, "/foo")); - GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.com")); + GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr")); GPR_ASSERT(was_cancelled == 0); GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world")); GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, "hello you")); diff --git a/test/core/end2end/tests/request_response_with_metadata_and_payload_legacy.c b/test/core/end2end/tests/request_response_with_metadata_and_payload_legacy.c index ba330d5f5f8..5c0b9d5b12f 100644 --- a/test/core/end2end/tests/request_response_with_metadata_and_payload_legacy.c +++ b/test/core/end2end/tests/request_response_with_metadata_and_payload_legacy.c @@ -128,7 +128,7 @@ static void test_request_response_with_metadata_and_payload( gpr_slice_unref(request_payload_slice); gpr_slice_unref(response_payload_slice); - c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com", + c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr", deadline); GPR_ASSERT(c); @@ -147,7 +147,7 @@ static void test_request_response_with_metadata_and_payload( cq_expect_write_accepted(v_client, tag(4), GRPC_OP_OK); cq_verify(v_client); - cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com", + cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr", deadline, "key1", "val1", "key2", "val2", NULL); cq_verify(v_server); diff --git a/test/core/end2end/tests/request_response_with_payload.c b/test/core/end2end/tests/request_response_with_payload.c index a0dc0331f4e..16f07c7107b 100644 --- a/test/core/end2end/tests/request_response_with_payload.c +++ b/test/core/end2end/tests/request_response_with_payload.c @@ -128,7 +128,7 @@ static void request_response_with_payload(grpc_end2end_test_fixture f) { int was_cancelled = 2; c = grpc_channel_create_call(f.client, f.client_cq, "/foo", - "foo.test.google.com", deadline); + "foo.test.google.fr", deadline); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -196,7 +196,7 @@ static void request_response_with_payload(grpc_end2end_test_fixture f) { GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); GPR_ASSERT(0 == strcmp(details, "xyz")); GPR_ASSERT(0 == strcmp(call_details.method, "/foo")); - GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.com")); + GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr")); GPR_ASSERT(was_cancelled == 0); GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world")); GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, "hello you")); diff --git a/test/core/end2end/tests/request_response_with_payload_legacy.c b/test/core/end2end/tests/request_response_with_payload_legacy.c index be562748994..37ce89b29a5 100644 --- a/test/core/end2end/tests/request_response_with_payload_legacy.c +++ b/test/core/end2end/tests/request_response_with_payload_legacy.c @@ -121,7 +121,7 @@ static void request_response_with_payload(grpc_end2end_test_fixture f) { GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); - c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com", + c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr", deadline); GPR_ASSERT(c); @@ -136,7 +136,7 @@ static void request_response_with_payload(grpc_end2end_test_fixture f) { cq_expect_write_accepted(v_client, tag(4), GRPC_OP_OK); cq_verify(v_client); - cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com", + cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr", deadline, NULL); cq_verify(v_server); diff --git a/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload.c b/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload.c index bf3b19b62d4..fa0d313f490 100644 --- a/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload.c +++ b/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload.c @@ -134,7 +134,7 @@ static void test_request_response_with_metadata_and_payload( int was_cancelled = 2; c = grpc_channel_create_call(f.client, f.client_cq, "/foo", - "foo.test.google.com", deadline); + "foo.test.google.fr", deadline); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -205,7 +205,7 @@ static void test_request_response_with_metadata_and_payload( GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); GPR_ASSERT(0 == strcmp(details, "xyz")); GPR_ASSERT(0 == strcmp(call_details.method, "/foo")); - GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.com")); + GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr")); GPR_ASSERT(was_cancelled == 1); GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world")); GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, "hello you")); diff --git a/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload_legacy.c b/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload_legacy.c index 0ed0f985ec8..5bce89a3fa6 100644 --- a/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload_legacy.c +++ b/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload_legacy.c @@ -130,7 +130,7 @@ static void test_request_response_with_metadata_and_payload( gpr_slice_unref(request_payload_slice); gpr_slice_unref(response_payload_slice); - c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com", + c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr", deadline); GPR_ASSERT(c); @@ -149,7 +149,7 @@ static void test_request_response_with_metadata_and_payload( cq_expect_write_accepted(v_client, tag(4), GRPC_OP_OK); cq_verify(v_client); - cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com", + cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr", deadline, "key1", "val1", "key2", "val2", NULL); cq_verify(v_server); diff --git a/test/core/end2end/tests/request_with_large_metadata.c b/test/core/end2end/tests/request_with_large_metadata.c index 75341040188..7908493565d 100644 --- a/test/core/end2end/tests/request_with_large_metadata.c +++ b/test/core/end2end/tests/request_with_large_metadata.c @@ -128,7 +128,7 @@ static void test_request_with_large_metadata(grpc_end2end_test_config config) { const int large_size = 64 * 1024; c = grpc_channel_create_call(f.client, f.client_cq, "/foo", - "foo.test.google.com", deadline); + "foo.test.google.fr", deadline); GPR_ASSERT(c); meta.key = "key"; @@ -197,7 +197,7 @@ static void test_request_with_large_metadata(grpc_end2end_test_config config) { GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); GPR_ASSERT(0 == strcmp(details, "xyz")); GPR_ASSERT(0 == strcmp(call_details.method, "/foo")); - GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.com")); + GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr")); GPR_ASSERT(was_cancelled == 0); GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world")); GPR_ASSERT(contains_metadata(&request_metadata_recv, "key", meta.value)); diff --git a/test/core/end2end/tests/request_with_large_metadata_legacy.c b/test/core/end2end/tests/request_with_large_metadata_legacy.c index bc3b3800139..85926aac149 100644 --- a/test/core/end2end/tests/request_with_large_metadata_legacy.c +++ b/test/core/end2end/tests/request_with_large_metadata_legacy.c @@ -121,7 +121,7 @@ static void test_request_with_large_metadata(grpc_end2end_test_config config) { ((char*)meta.value)[large_size] = 0; meta.value_length = large_size; - c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com", + c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr", deadline); GPR_ASSERT(c); @@ -131,7 +131,7 @@ static void test_request_with_large_metadata(grpc_end2end_test_config config) { GPR_ASSERT(GRPC_CALL_OK == grpc_call_invoke_old(c, f.client_cq, tag(2), tag(3), 0)); - cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com", + cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr", deadline, "key", meta.value, NULL); cq_verify(v_server); diff --git a/test/core/end2end/tests/request_with_payload.c b/test/core/end2end/tests/request_with_payload.c index bb13512ad42..72614a0bf80 100644 --- a/test/core/end2end/tests/request_with_payload.c +++ b/test/core/end2end/tests/request_with_payload.c @@ -126,7 +126,7 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { int was_cancelled = 2; c = grpc_channel_create_call(f.client, f.client_cq, "/foo", - "foo.test.google.com", deadline); + "foo.test.google.fr", deadline); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -188,7 +188,7 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); GPR_ASSERT(0 == strcmp(details, "xyz")); GPR_ASSERT(0 == strcmp(call_details.method, "/foo")); - GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.com")); + GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr")); GPR_ASSERT(was_cancelled == 0); GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, "hello world")); diff --git a/test/core/end2end/tests/request_with_payload_legacy.c b/test/core/end2end/tests/request_with_payload_legacy.c index b56e08cf1fc..b71e682b9d9 100644 --- a/test/core/end2end/tests/request_with_payload_legacy.c +++ b/test/core/end2end/tests/request_with_payload_legacy.c @@ -116,7 +116,7 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { /* byte buffer holds the slice, we can unref it already */ gpr_slice_unref(payload_slice); - c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com", + c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr", deadline); GPR_ASSERT(c); @@ -132,7 +132,7 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { cq_expect_write_accepted(v_client, tag(4), GRPC_OP_OK); cq_verify(v_client); - cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com", + cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr", deadline, NULL); cq_verify(v_server); diff --git a/test/core/end2end/tests/simple_delayed_request.c b/test/core/end2end/tests/simple_delayed_request.c index 0a3eb7c7b79..83b065b59eb 100644 --- a/test/core/end2end/tests/simple_delayed_request.c +++ b/test/core/end2end/tests/simple_delayed_request.c @@ -114,7 +114,7 @@ static void simple_delayed_request_body(grpc_end2end_test_config config, config.init_client(f, client_args); c = grpc_channel_create_call(f->client, f->client_cq, "/foo", - "foo.test.google.com", deadline); + "foo.test.google.fr", deadline); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -172,7 +172,7 @@ static void simple_delayed_request_body(grpc_end2end_test_config config, GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); GPR_ASSERT(0 == strcmp(details, "xyz")); GPR_ASSERT(0 == strcmp(call_details.method, "/foo")); - GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.com")); + GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr")); GPR_ASSERT(was_cancelled == 0); gpr_free(details); diff --git a/test/core/end2end/tests/simple_delayed_request_legacy.c b/test/core/end2end/tests/simple_delayed_request_legacy.c index 3c94de548ea..325261449af 100644 --- a/test/core/end2end/tests/simple_delayed_request_legacy.c +++ b/test/core/end2end/tests/simple_delayed_request_legacy.c @@ -103,7 +103,7 @@ static void simple_delayed_request_body(grpc_end2end_test_config config, config.init_client(f, client_args); - c = grpc_channel_create_call_old(f->client, "/foo", "foo.test.google.com", + c = grpc_channel_create_call_old(f->client, "/foo", "foo.test.google.fr", deadline); GPR_ASSERT(c); @@ -119,7 +119,7 @@ static void simple_delayed_request_body(grpc_end2end_test_config config, cq_verify(v_client); GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f->server, tag(100))); - cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com", + cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr", deadline, NULL); cq_verify(v_server); diff --git a/test/core/end2end/tests/simple_request.c b/test/core/end2end/tests/simple_request.c index 591bc52dc5b..dac82535be7 100644 --- a/test/core/end2end/tests/simple_request.c +++ b/test/core/end2end/tests/simple_request.c @@ -122,7 +122,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) { int was_cancelled = 2; c = grpc_channel_create_call(f.client, f.client_cq, "/foo", - "foo.test.google.com", deadline); + "foo.test.google.fr", deadline); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -178,7 +178,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) { GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); GPR_ASSERT(0 == strcmp(details, "xyz")); GPR_ASSERT(0 == strcmp(call_details.method, "/foo")); - GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.com")); + GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr")); GPR_ASSERT(was_cancelled == 0); gpr_free(details); diff --git a/test/core/end2end/tests/simple_request_legacy.c b/test/core/end2end/tests/simple_request_legacy.c index 2e30d101e18..52dd6b08451 100644 --- a/test/core/end2end/tests/simple_request_legacy.c +++ b/test/core/end2end/tests/simple_request_legacy.c @@ -110,7 +110,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) { cq_verifier *v_client = cq_verifier_create(f.client_cq); cq_verifier *v_server = cq_verifier_create(f.server_cq); - c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com", + c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr", deadline); GPR_ASSERT(c); @@ -122,7 +122,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) { cq_verify(v_client); GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); - cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com", + cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr", deadline, NULL); cq_verify(v_server); @@ -157,7 +157,7 @@ static void simple_request_body2(grpc_end2end_test_fixture f) { cq_verifier *v_client = cq_verifier_create(f.client_cq); cq_verifier *v_server = cq_verifier_create(f.server_cq); - c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com", + c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr", deadline); GPR_ASSERT(c); @@ -169,7 +169,7 @@ static void simple_request_body2(grpc_end2end_test_fixture f) { cq_verify(v_client); GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); - cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.com", + cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr", deadline, NULL); cq_verify(v_server); diff --git a/test/core/end2end/tests/thread_stress.c b/test/core/end2end/tests/thread_stress.c index c10b3737441..996229c2282 100644 --- a/test/core/end2end/tests/thread_stress.c +++ b/test/core/end2end/tests/thread_stress.c @@ -109,7 +109,7 @@ static void start_request(void) { gpr_slice slice = gpr_slice_malloc(100); grpc_byte_buffer *buf; grpc_call *call = grpc_channel_create_call_old( - g_fixture.client, "/Foo", "foo.test.google.com", g_test_end_time); + g_fixture.client, "/Foo", "foo.test.google.fr", g_test_end_time); memset(GPR_SLICE_START_PTR(slice), 1, GPR_SLICE_LENGTH(slice)); buf = grpc_byte_buffer_create(&slice, 1); diff --git a/test/core/end2end/tests/thread_stress_legacy.c b/test/core/end2end/tests/thread_stress_legacy.c index c10b3737441..996229c2282 100644 --- a/test/core/end2end/tests/thread_stress_legacy.c +++ b/test/core/end2end/tests/thread_stress_legacy.c @@ -109,7 +109,7 @@ static void start_request(void) { gpr_slice slice = gpr_slice_malloc(100); grpc_byte_buffer *buf; grpc_call *call = grpc_channel_create_call_old( - g_fixture.client, "/Foo", "foo.test.google.com", g_test_end_time); + g_fixture.client, "/Foo", "foo.test.google.fr", g_test_end_time); memset(GPR_SLICE_START_PTR(slice), 1, GPR_SLICE_LENGTH(slice)); buf = grpc_byte_buffer_create(&slice, 1); diff --git a/test/core/end2end/tests/writes_done_hangs_with_pending_read.c b/test/core/end2end/tests/writes_done_hangs_with_pending_read.c index 5f8b9974d68..0189762b5eb 100644 --- a/test/core/end2end/tests/writes_done_hangs_with_pending_read.c +++ b/test/core/end2end/tests/writes_done_hangs_with_pending_read.c @@ -124,7 +124,7 @@ static void test_writes_done_hangs_with_pending_read( gpr_slice_unref(request_payload_slice); gpr_slice_unref(response_payload_slice); - c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com", + c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr", deadline); GPR_ASSERT(c); @@ -141,7 +141,7 @@ static void test_writes_done_hangs_with_pending_read( GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", - "foo.test.google.com", deadline, NULL); + "foo.test.google.fr", deadline, NULL); cq_verify(v_server); GPR_ASSERT(GRPC_CALL_OK == diff --git a/test/core/end2end/tests/writes_done_hangs_with_pending_read_legacy.c b/test/core/end2end/tests/writes_done_hangs_with_pending_read_legacy.c index 5f8b9974d68..0189762b5eb 100644 --- a/test/core/end2end/tests/writes_done_hangs_with_pending_read_legacy.c +++ b/test/core/end2end/tests/writes_done_hangs_with_pending_read_legacy.c @@ -124,7 +124,7 @@ static void test_writes_done_hangs_with_pending_read( gpr_slice_unref(request_payload_slice); gpr_slice_unref(response_payload_slice); - c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.com", + c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr", deadline); GPR_ASSERT(c); @@ -141,7 +141,7 @@ static void test_writes_done_hangs_with_pending_read( GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", - "foo.test.google.com", deadline, NULL); + "foo.test.google.fr", deadline, NULL); cq_verify(v_server); GPR_ASSERT(GRPC_CALL_OK == diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc index 78f2063c45b..acfaa87ec8b 100644 --- a/test/cpp/interop/client.cc +++ b/test/cpp/interop/client.cc @@ -57,7 +57,7 @@ DEFINE_bool(enable_ssl, false, "Whether to use ssl/tls."); DEFINE_bool(use_prod_roots, false, "True to use SSL roots for google"); DEFINE_int32(server_port, 0, "Server port."); DEFINE_string(server_host, "127.0.0.1", "Server host to connect to"); -DEFINE_string(server_host_override, "foo.test.google.com", +DEFINE_string(server_host_override, "foo.test.google.fr", "Override the server host which is sent in HTTP header"); DEFINE_string(test_case, "large_unary", "Configure different test cases. Valid options are: " diff --git a/test/cpp/util/create_test_channel.cc b/test/cpp/util/create_test_channel.cc index 66a9a7b7c40..99b3c2ecd47 100644 --- a/test/cpp/util/create_test_channel.cc +++ b/test/cpp/util/create_test_channel.cc @@ -93,7 +93,7 @@ std::shared_ptr CreateTestChannel( // Shortcut for end2end and interop tests. std::shared_ptr CreateTestChannel(const grpc::string& server, bool enable_ssl) { - return CreateTestChannel(server, "foo.test.google.com", enable_ssl, false); + return CreateTestChannel(server, "foo.test.google.fr", enable_ssl, false); } } // namespace grpc From a0fcfcc1fac262eae219c2585c587968f67ed00c Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 23 Feb 2015 20:26:50 -0800 Subject: [PATCH 05/75] Fixed formatting --- src/csharp/Grpc.Core.Tests/GrpcEnvironmentTest.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/csharp/Grpc.Core.Tests/GrpcEnvironmentTest.cs b/src/csharp/Grpc.Core.Tests/GrpcEnvironmentTest.cs index 8d3aef946a6..596918c231c 100644 --- a/src/csharp/Grpc.Core.Tests/GrpcEnvironmentTest.cs +++ b/src/csharp/Grpc.Core.Tests/GrpcEnvironmentTest.cs @@ -41,14 +41,16 @@ namespace Grpc.Core.Tests public class GrpcEnvironmentTest { [Test] - public void InitializeAndShutdownGrpcEnvironment() { + public void InitializeAndShutdownGrpcEnvironment() + { GrpcEnvironment.Initialize(); Assert.IsNotNull(GrpcEnvironment.ThreadPool.CompletionQueue); GrpcEnvironment.Shutdown(); } [Test] - public void SubsequentInvocations() { + public void SubsequentInvocations() + { GrpcEnvironment.Initialize(); GrpcEnvironment.Initialize(); GrpcEnvironment.Shutdown(); @@ -56,7 +58,8 @@ namespace Grpc.Core.Tests } [Test] - public void InitializeAfterShutdown() { + public void InitializeAfterShutdown() + { GrpcEnvironment.Initialize(); var tp1 = GrpcEnvironment.ThreadPool; GrpcEnvironment.Shutdown(); From 5b141669e6e2cf8f93ee2150cc60fcb154ac54c0 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 23 Feb 2015 20:28:30 -0800 Subject: [PATCH 06/75] Added some measurement numbers to comments. --- src/csharp/Grpc.Core.Tests/PInvokeTest.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/csharp/Grpc.Core.Tests/PInvokeTest.cs b/src/csharp/Grpc.Core.Tests/PInvokeTest.cs index b78609ccf08..282d521ba37 100644 --- a/src/csharp/Grpc.Core.Tests/PInvokeTest.cs +++ b/src/csharp/Grpc.Core.Tests/PInvokeTest.cs @@ -65,6 +65,9 @@ namespace Grpc.Core.Tests GrpcEnvironment.Shutdown(); } + /// + /// (~1.26us .NET Windows) + /// [Test] public void CompletionQueueCreateDestroyBenchmark() { @@ -80,7 +83,8 @@ namespace Grpc.Core.Tests /// /// Approximate results: - /// (mono ~80ns) + /// (~80ns Mono Linux) + /// (~110ns .NET Windows) /// [Test] public void NativeCallbackBenchmark() @@ -100,7 +104,8 @@ namespace Grpc.Core.Tests /// /// Creating a new native-to-managed callback has significant overhead /// compared to using an existing one. We need to be aware of this. - /// (~50us on mono) + /// (~50us on Mono Linux!!!) + /// (~1.1us on .NET Windows) /// [Test] public void NewNativeCallbackBenchmark() @@ -117,6 +122,7 @@ namespace Grpc.Core.Tests /// /// Tests overhead of a simple PInvoke call. + /// (~46ns .NET Windows) /// [Test] public void NopPInvokeBenchmark() From b505661b1ae833154deebb689c2c1ba415bc1c11 Mon Sep 17 00:00:00 2001 From: David Klempner Date: Tue, 24 Feb 2015 14:22:50 -0800 Subject: [PATCH 07/75] Add a shutdown API to pollset This allows us to safely asynchronously add FDs in the possibly-promoting unary add case. Also fix the unary add async path to properly handle more of the extra cases it needs to handle. --- src/core/iomgr/pollset.h | 5 ++ src/core/iomgr/pollset_posix.c | 122 ++++++++++++++++++++++------ src/core/iomgr/pollset_posix.h | 4 + src/core/iomgr/pollset_windows.c | 6 ++ src/core/surface/completion_queue.c | 9 +- 5 files changed, 117 insertions(+), 29 deletions(-) diff --git a/src/core/iomgr/pollset.h b/src/core/iomgr/pollset.h index 9d04b014ba7..c26947f37cb 100644 --- a/src/core/iomgr/pollset.h +++ b/src/core/iomgr/pollset.h @@ -52,9 +52,14 @@ #include "src/core/iomgr/pollset_windows.h" #endif + void grpc_pollset_init(grpc_pollset *pollset); +void grpc_pollset_shutdown(grpc_pollset *pollset, + void (*shutdown_done)(void *arg), + void *shutdown_done_arg); void grpc_pollset_destroy(grpc_pollset *pollset); + /* Do some work on a pollset. May involve invoking asynchronous callbacks, or actually polling file descriptors. diff --git a/src/core/iomgr/pollset_posix.c b/src/core/iomgr/pollset_posix.c index 39945ff3cb7..f0a8453fd77 100644 --- a/src/core/iomgr/pollset_posix.c +++ b/src/core/iomgr/pollset_posix.c @@ -55,6 +55,7 @@ static grpc_pollset g_backup_pollset; static int g_shutdown_backup_poller; static gpr_event g_backup_poller_done; +static gpr_event g_backup_pollset_shutdown_done; static void backup_poller(void *p) { gpr_timespec delta = gpr_time_from_millis(100); @@ -104,9 +105,14 @@ void grpc_pollset_global_init(void) { /* start the backup poller thread */ g_shutdown_backup_poller = 0; gpr_event_init(&g_backup_poller_done); + gpr_event_init(&g_backup_pollset_shutdown_done); gpr_thd_new(&id, backup_poller, NULL, NULL); } +static void on_backup_pollset_shutdown_done(void *arg) { + gpr_event_set(&g_backup_pollset_shutdown_done, (void *)1); +} + void grpc_pollset_global_shutdown(void) { /* terminate the backup poller thread */ gpr_mu_lock(&g_backup_pollset.mu); @@ -114,6 +120,10 @@ void grpc_pollset_global_shutdown(void) { gpr_mu_unlock(&g_backup_pollset.mu); gpr_event_wait(&g_backup_poller_done, gpr_inf_future); + grpc_pollset_shutdown(&g_backup_pollset, on_backup_pollset_shutdown_done, + NULL); + gpr_event_wait(&g_backup_pollset_shutdown_done, gpr_inf_future); + /* destroy the backup pollset */ grpc_pollset_destroy(&g_backup_pollset); @@ -130,6 +140,8 @@ void grpc_pollset_init(grpc_pollset *pollset) { gpr_mu_init(&pollset->mu); gpr_cv_init(&pollset->cv); grpc_pollset_kick_init(&pollset->kick_state); + pollset->in_flight_cbs = 0; + pollset->shutting_down = 0; become_empty_pollset(pollset); } @@ -163,7 +175,24 @@ int grpc_pollset_work(grpc_pollset *pollset, gpr_timespec deadline) { return pollset->vtable->maybe_work(pollset, deadline, now, 1); } +void grpc_pollset_shutdown(grpc_pollset *pollset, + void (*shutdown_done)(void *arg), + void *shutdown_done_arg) { + int in_flight_cbs; + gpr_mu_lock(&pollset->mu); + pollset->shutting_down = 1; + in_flight_cbs = pollset->in_flight_cbs; + pollset->shutdown_done_cb = shutdown_done; + pollset->shutdown_done_arg = shutdown_done_arg; + gpr_mu_unlock(&pollset->mu); + if (in_flight_cbs == 0) { + shutdown_done(shutdown_done_arg); + } +} + void grpc_pollset_destroy(grpc_pollset *pollset) { + GPR_ASSERT(pollset->shutting_down); + GPR_ASSERT(pollset->in_flight_cbs == 0); pollset->vtable->destroy(pollset); grpc_pollset_kick_destroy(&pollset->kick_state); gpr_mu_destroy(&pollset->mu); @@ -213,12 +242,21 @@ static void unary_poll_do_promote(void *args, int success) { const grpc_pollset_vtable *original_vtable = up_args->original_vtable; grpc_pollset *pollset = up_args->pollset; grpc_fd *fd = up_args->fd; - grpc_fd *fds[2]; + int do_shutdown_cb = 0; gpr_free(up_args); + /* + * This is quite tricky. There are a number of cases to keep in mind here: + * 1. fd may have been orphaned + * 2. The pollset may no longer be a unary poller (and we can't let case #1 + * leak to other pollset types!) + * 3. pollset's fd (which may have changed) may have been orphaned + * 4. The pollset may be shutting down. + */ + gpr_mu_lock(&pollset->mu); /* First we need to ensure that nobody is polling concurrently */ - while (pollset->counter != 0 && pollset->vtable == original_vtable) { + while (pollset->counter != 0) { grpc_pollset_kick(pollset); gpr_cv_wait(&pollset->cv, &pollset->mu, gpr_inf_future); } @@ -227,31 +265,44 @@ static void unary_poll_do_promote(void *args, int success) { /* TODO(klempner): If we're not careful this could cause infinite recursion. * That's not a problem for now because empty_pollset has a trivial poller * and we don't have any mechanism to unbecome multipoller. */ - if (pollset->vtable != original_vtable) { + pollset->in_flight_cbs--; + if (pollset->shutting_down) { + gpr_log(GPR_INFO, "Shutting down"); + /* We don't care about this pollset anymore. */ + if (pollset->in_flight_cbs == 0) { + do_shutdown_cb = 1; + } + } else if (grpc_fd_is_orphaned(fd)) { + /* Don't try to add it to anything, we'll drop our ref on it below */ + } else if (pollset->vtable != original_vtable) { + gpr_log(GPR_INFO, "Not original vtable"); pollset->vtable->add_fd(pollset, fd); - gpr_cv_broadcast(&pollset->cv); - gpr_mu_unlock(&pollset->mu); - return; - } - - if (fd == pollset->data.ptr) return; - fds[0] = pollset->data.ptr; - fds[1] = fd; - - if (!grpc_fd_is_orphaned(fds[0])) { - grpc_platform_become_multipoller(pollset, fds, GPR_ARRAY_SIZE(fds)); - grpc_fd_unref(fds[0]); - } else { - /* old fd is orphaned and we haven't cleaned it up until now, so remain a - * unary poller */ - grpc_fd_unref(fds[0]); - pollset->data.ptr = fd; - grpc_fd_ref(fd); + } else if (fd != pollset->data.ptr) { + grpc_fd *fds[2]; + fds[0] = pollset->data.ptr; + fds[1] = fd; + + if (!grpc_fd_is_orphaned(fds[0])) { + grpc_platform_become_multipoller(pollset, fds, GPR_ARRAY_SIZE(fds)); + grpc_fd_unref(fds[0]); + } else { + /* old fd is orphaned and we haven't cleaned it up until now, so remain a + * unary poller */ + /* Note that it is possible that fds[1] is also orphaned at this point. + * That's okay, we'll correct it at the next add or poll. */ + grpc_fd_unref(fds[0]); + pollset->data.ptr = fd; + grpc_fd_ref(fd); + } } gpr_cv_broadcast(&pollset->cv); gpr_mu_unlock(&pollset->mu); + if (do_shutdown_cb) { + pollset->shutdown_done_cb(pollset->shutdown_done_arg); + } + /* Matching ref in unary_poll_pollset_add_fd */ grpc_fd_unref(fd); } @@ -260,18 +311,31 @@ static void unary_poll_pollset_add_fd(grpc_pollset *pollset, grpc_fd *fd) { grpc_unary_promote_args *up_args; if (fd == pollset->data.ptr) return; - if (grpc_fd_is_orphaned(pollset->data.ptr)) { - /* old fd is orphaned and we haven't cleaned it up until now, so remain a - * unary poller */ - grpc_fd_unref(pollset->data.ptr); - pollset->data.ptr = fd; - grpc_fd_ref(fd); + if (!pollset->counter) { + /* Fast path -- no in flight cbs */ + /* TODO(klempner): Comment this out and fix any test failures or establish + * they are due to timing issues */ + grpc_fd *fds[2]; + fds[0] = pollset->data.ptr; + fds[1] = fd; + + if (!grpc_fd_is_orphaned(fds[0])) { + grpc_platform_become_multipoller(pollset, fds, GPR_ARRAY_SIZE(fds)); + grpc_fd_unref(fds[0]); + } else { + /* old fd is orphaned and we haven't cleaned it up until now, so remain a + * unary poller */ + grpc_fd_unref(fds[0]); + pollset->data.ptr = fd; + grpc_fd_ref(fd); + } return; } /* Now we need to promote. This needs to happen when we're not polling. Since * this may be called from poll, the wait needs to happen asynchronously. */ grpc_fd_ref(fd); + pollset->in_flight_cbs++; up_args = gpr_malloc(sizeof(*up_args)); up_args->pollset = pollset; up_args->fd = fd; @@ -301,6 +365,10 @@ static int unary_poll_pollset_maybe_work(grpc_pollset *pollset, if (pollset->counter) { return 0; } + if (pollset->in_flight_cbs) { + /* Give do_promote priority so we don't starve it out */ + return 0; + } fd = pollset->data.ptr; if (grpc_fd_is_orphaned(fd)) { grpc_fd_unref(fd); diff --git a/src/core/iomgr/pollset_posix.h b/src/core/iomgr/pollset_posix.h index 03b4c775b7f..86b6c9f20e8 100644 --- a/src/core/iomgr/pollset_posix.h +++ b/src/core/iomgr/pollset_posix.h @@ -55,6 +55,10 @@ typedef struct grpc_pollset { gpr_cv cv; grpc_pollset_kick_state kick_state; int counter; + int in_flight_cbs; + int shutting_down; + void (*shutdown_done_cb)(void *arg); + void *shutdown_done_arg; union { int fd; void *ptr; diff --git a/src/core/iomgr/pollset_windows.c b/src/core/iomgr/pollset_windows.c index d21072b2832..bea67116116 100644 --- a/src/core/iomgr/pollset_windows.c +++ b/src/core/iomgr/pollset_windows.c @@ -46,6 +46,12 @@ void grpc_pollset_init(grpc_pollset *pollset) { gpr_cv_init(&pollset->cv); } +void grpc_pollset_shutdown(grpc_pollset *pollset, + void (*shutdown_done)(void *arg), + void *shutdown_done_arg) { + shutdown_done(shutdown_done_arg); +} + void grpc_pollset_destroy(grpc_pollset *pollset) { gpr_mu_destroy(&pollset->mu); gpr_cv_destroy(&pollset->cv); diff --git a/src/core/surface/completion_queue.c b/src/core/surface/completion_queue.c index 2efc084d7b3..c4b8d60782f 100644 --- a/src/core/surface/completion_queue.c +++ b/src/core/surface/completion_queue.c @@ -389,12 +389,17 @@ void grpc_completion_queue_shutdown(grpc_completion_queue *cc) { } } -void grpc_completion_queue_destroy(grpc_completion_queue *cc) { - GPR_ASSERT(cc->queue == NULL); +static void on_pollset_destroy_done(void *arg) { + grpc_completion_queue *cc = arg; grpc_pollset_destroy(&cc->pollset); gpr_free(cc); } +void grpc_completion_queue_destroy(grpc_completion_queue *cc) { + GPR_ASSERT(cc->queue == NULL); + grpc_pollset_shutdown(&cc->pollset, on_pollset_destroy_done, cc); +} + void grpc_event_finish(grpc_event *base) { event *ev = (event *)base; ev->on_finish(ev->on_finish_user_data, GRPC_OP_OK); From d50e565cda3c5527499bb13003d8accaa08d8797 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 24 Feb 2015 16:46:22 -0800 Subject: [PATCH 08/75] Add HTTP2 header tracing HPACK makes headers on the wire very difficult to read. Add a trace facility to print them on the receive path. Later this will be expanded no doubt for sending headers, stream creation, etc... --- src/core/debug/trace.c | 2 ++ src/core/debug/trace.h | 3 ++- src/core/transport/chttp2_transport.c | 26 +++++++++++++++++++------- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/core/debug/trace.c b/src/core/debug/trace.c index 92acbe924db..b8eb755bffc 100644 --- a/src/core/debug/trace.c +++ b/src/core/debug/trace.c @@ -81,6 +81,8 @@ static void parse(const char *s) { grpc_trace_bits |= GRPC_TRACE_TCP; } else if (0 == strcmp(s, "secure_endpoint")) { grpc_trace_bits |= GRPC_TRACE_SECURE_ENDPOINT; + } else if (0 == strcmp(s, "http")) { + grpc_trace_bits |= GRPC_TRACE_HTTP; } else if (0 == strcmp(s, "all")) { grpc_trace_bits = -1; } else { diff --git a/src/core/debug/trace.h b/src/core/debug/trace.h index 167ef3c6ea6..bf9b8a3642c 100644 --- a/src/core/debug/trace.h +++ b/src/core/debug/trace.h @@ -45,7 +45,8 @@ typedef enum { GRPC_TRACE_SURFACE = 1 << 0, GRPC_TRACE_CHANNEL = 1 << 1, GRPC_TRACE_TCP = 1 << 2, - GRPC_TRACE_SECURE_ENDPOINT = 1 << 3 + GRPC_TRACE_SECURE_ENDPOINT = 1 << 3, + GRPC_TRACE_HTTP = 1 << 4 } grpc_trace_bit_value; #if GRPC_ENABLE_TRACING diff --git a/src/core/transport/chttp2_transport.c b/src/core/transport/chttp2_transport.c index ccd8d0c3764..e9f1cd7842d 100644 --- a/src/core/transport/chttp2_transport.c +++ b/src/core/transport/chttp2_transport.c @@ -37,6 +37,7 @@ #include #include +#include "src/core/debug/trace.h" #include "src/core/support/string.h" #include "src/core/transport/chttp2/frame_data.h" #include "src/core/transport/chttp2/frame_goaway.h" @@ -66,6 +67,12 @@ typedef struct transport transport; typedef struct stream stream; +#define IF_TRACING(stmt) \ + if (!(grpc_trace_bits & GRPC_TRACE_HTTP)) \ + ; \ + else \ + stmt + /* streams are kept in various linked lists depending on what things need to happen to them... this enum labels each list */ typedef enum { @@ -552,7 +559,7 @@ static int init_stream(grpc_transport *gt, grpc_stream *gs, lock(t); s->id = 0; } else { - s->id = (gpr_uint32)(gpr_uintptr)server_data; + s->id = (gpr_uint32)(gpr_uintptr) server_data; t->incoming_stream = s; grpc_chttp2_stream_map_add(&t->stream_map, s->id, s); } @@ -1206,6 +1213,11 @@ static void on_header(void *tp, grpc_mdelem *md) { stream *s = t->incoming_stream; GPR_ASSERT(s); + + IF_TRACING(gpr_log(GPR_INFO, "HTTP:%d:HDR: %s: %s", s->id, + grpc_mdstr_as_c_string(md->key), + grpc_mdstr_as_c_string(md->value))); + stream_list_join(t, s, PENDING_CALLBACKS); if (md->key == t->str_grpc_timeout) { gpr_timespec *cached_timeout = grpc_mdelem_get_user_data(md, free_timeout); @@ -1269,7 +1281,7 @@ static int init_header_frame_parser(transport *t, int is_continuation) { t->incoming_stream = NULL; /* if stream is accepted, we set incoming_stream in init_stream */ t->cb->accept_stream(t->cb_user_data, &t->base, - (void *)(gpr_uintptr)t->incoming_stream_id); + (void *)(gpr_uintptr) t->incoming_stream_id); s = t->incoming_stream; if (!s) { gpr_log(GPR_ERROR, "stream not accepted"); @@ -1534,8 +1546,8 @@ static int process_read(transport *t, gpr_slice slice) { "Connect string mismatch: expected '%c' (%d) got '%c' (%d) " "at byte %d", CLIENT_CONNECT_STRING[t->deframe_state], - (int)(gpr_uint8)CLIENT_CONNECT_STRING[t->deframe_state], *cur, - (int)*cur, t->deframe_state); + (int)(gpr_uint8) CLIENT_CONNECT_STRING[t->deframe_state], + *cur, (int)*cur, t->deframe_state); drop_connection(t); return 0; } @@ -1765,9 +1777,9 @@ static void add_to_pollset(grpc_transport *gt, grpc_pollset *pollset) { */ static const grpc_transport_vtable vtable = { - sizeof(stream), init_stream, send_batch, set_allow_window_updates, - add_to_pollset, destroy_stream, abort_stream, goaway, close_transport, - send_ping, destroy_transport}; + sizeof(stream), init_stream, send_batch, set_allow_window_updates, + add_to_pollset, destroy_stream, abort_stream, goaway, + close_transport, send_ping, destroy_transport}; void grpc_create_chttp2_transport(grpc_transport_setup_callback setup, void *arg, From 9fff77e4f8175cc26619a167192c8fba1b4b0dd8 Mon Sep 17 00:00:00 2001 From: Julien Boeuf Date: Tue, 24 Feb 2015 16:50:35 -0800 Subject: [PATCH 09/75] Addressing comments. --- Makefile | 36 ++- build.json | 14 ++ src/core/tsi/ssl_transport_security.c | 72 +++++- src/core/tsi/ssl_transport_security.h | 7 +- test/core/tsi/transport_security_test.c | 303 ++++++++++++++++++++++++ tools/run_tests/tests.json | 4 + vsprojects/vs2013/Grpc.mak | 12 +- 7 files changed, 436 insertions(+), 12 deletions(-) create mode 100644 test/core/tsi/transport_security_test.c diff --git a/Makefile b/Makefile index 278824a59aa..7b662e575ca 100644 --- a/Makefile +++ b/Makefile @@ -509,6 +509,7 @@ time_averaged_stats_test: $(BINDIR)/$(CONFIG)/time_averaged_stats_test time_test: $(BINDIR)/$(CONFIG)/time_test timeout_encoding_test: $(BINDIR)/$(CONFIG)/timeout_encoding_test transport_metadata_test: $(BINDIR)/$(CONFIG)/transport_metadata_test +transport_security_test: $(BINDIR)/$(CONFIG)/transport_security_test async_end2end_test: $(BINDIR)/$(CONFIG)/async_end2end_test channel_arguments_test: $(BINDIR)/$(CONFIG)/channel_arguments_test credentials_test: $(BINDIR)/$(CONFIG)/credentials_test @@ -930,7 +931,7 @@ privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/ buildtests: buildtests_c buildtests_cxx -buildtests_c: privatelibs_c $(BINDIR)/$(CONFIG)/alarm_heap_test $(BINDIR)/$(CONFIG)/alarm_list_test $(BINDIR)/$(CONFIG)/alarm_test $(BINDIR)/$(CONFIG)/alpn_test $(BINDIR)/$(CONFIG)/bin_encoder_test $(BINDIR)/$(CONFIG)/census_hash_table_test $(BINDIR)/$(CONFIG)/census_statistics_multiple_writers_circular_buffer_test $(BINDIR)/$(CONFIG)/census_statistics_multiple_writers_test $(BINDIR)/$(CONFIG)/census_statistics_performance_test $(BINDIR)/$(CONFIG)/census_statistics_quick_test $(BINDIR)/$(CONFIG)/census_statistics_small_log_test $(BINDIR)/$(CONFIG)/census_stub_test $(BINDIR)/$(CONFIG)/census_window_stats_test $(BINDIR)/$(CONFIG)/chttp2_status_conversion_test $(BINDIR)/$(CONFIG)/chttp2_stream_encoder_test $(BINDIR)/$(CONFIG)/chttp2_stream_map_test $(BINDIR)/$(CONFIG)/chttp2_transport_end2end_test $(BINDIR)/$(CONFIG)/dualstack_socket_test $(BINDIR)/$(CONFIG)/echo_client $(BINDIR)/$(CONFIG)/echo_server $(BINDIR)/$(CONFIG)/echo_test $(BINDIR)/$(CONFIG)/fd_posix_test $(BINDIR)/$(CONFIG)/fling_client $(BINDIR)/$(CONFIG)/fling_server $(BINDIR)/$(CONFIG)/fling_stream_test $(BINDIR)/$(CONFIG)/fling_test $(BINDIR)/$(CONFIG)/gpr_cancellable_test $(BINDIR)/$(CONFIG)/gpr_cmdline_test $(BINDIR)/$(CONFIG)/gpr_env_test $(BINDIR)/$(CONFIG)/gpr_file_test $(BINDIR)/$(CONFIG)/gpr_histogram_test $(BINDIR)/$(CONFIG)/gpr_host_port_test $(BINDIR)/$(CONFIG)/gpr_log_test $(BINDIR)/$(CONFIG)/gpr_slice_buffer_test $(BINDIR)/$(CONFIG)/gpr_slice_test $(BINDIR)/$(CONFIG)/gpr_string_test $(BINDIR)/$(CONFIG)/gpr_sync_test $(BINDIR)/$(CONFIG)/gpr_thd_test $(BINDIR)/$(CONFIG)/gpr_time_test $(BINDIR)/$(CONFIG)/gpr_useful_test $(BINDIR)/$(CONFIG)/grpc_base64_test $(BINDIR)/$(CONFIG)/grpc_byte_buffer_reader_test $(BINDIR)/$(CONFIG)/grpc_channel_stack_test $(BINDIR)/$(CONFIG)/grpc_completion_queue_test $(BINDIR)/$(CONFIG)/grpc_credentials_test $(BINDIR)/$(CONFIG)/grpc_json_token_test $(BINDIR)/$(CONFIG)/grpc_stream_op_test $(BINDIR)/$(CONFIG)/hpack_parser_test $(BINDIR)/$(CONFIG)/hpack_table_test $(BINDIR)/$(CONFIG)/httpcli_format_request_test $(BINDIR)/$(CONFIG)/httpcli_parser_test $(BINDIR)/$(CONFIG)/httpcli_test $(BINDIR)/$(CONFIG)/json_rewrite $(BINDIR)/$(CONFIG)/json_rewrite_test $(BINDIR)/$(CONFIG)/json_test $(BINDIR)/$(CONFIG)/lame_client_test $(BINDIR)/$(CONFIG)/message_compress_test $(BINDIR)/$(CONFIG)/metadata_buffer_test $(BINDIR)/$(CONFIG)/multi_init_test $(BINDIR)/$(CONFIG)/murmur_hash_test $(BINDIR)/$(CONFIG)/no_server_test $(BINDIR)/$(CONFIG)/poll_kick_posix_test $(BINDIR)/$(CONFIG)/resolve_address_test $(BINDIR)/$(CONFIG)/secure_endpoint_test $(BINDIR)/$(CONFIG)/sockaddr_utils_test $(BINDIR)/$(CONFIG)/tcp_client_posix_test $(BINDIR)/$(CONFIG)/tcp_posix_test $(BINDIR)/$(CONFIG)/tcp_server_posix_test $(BINDIR)/$(CONFIG)/time_averaged_stats_test $(BINDIR)/$(CONFIG)/time_test $(BINDIR)/$(CONFIG)/timeout_encoding_test $(BINDIR)/$(CONFIG)/transport_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_no_op_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_no_op_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_no_op_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_no_op_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_legacy_test +buildtests_c: privatelibs_c $(BINDIR)/$(CONFIG)/alarm_heap_test $(BINDIR)/$(CONFIG)/alarm_list_test $(BINDIR)/$(CONFIG)/alarm_test $(BINDIR)/$(CONFIG)/alpn_test $(BINDIR)/$(CONFIG)/bin_encoder_test $(BINDIR)/$(CONFIG)/census_hash_table_test $(BINDIR)/$(CONFIG)/census_statistics_multiple_writers_circular_buffer_test $(BINDIR)/$(CONFIG)/census_statistics_multiple_writers_test $(BINDIR)/$(CONFIG)/census_statistics_performance_test $(BINDIR)/$(CONFIG)/census_statistics_quick_test $(BINDIR)/$(CONFIG)/census_statistics_small_log_test $(BINDIR)/$(CONFIG)/census_stub_test $(BINDIR)/$(CONFIG)/census_window_stats_test $(BINDIR)/$(CONFIG)/chttp2_status_conversion_test $(BINDIR)/$(CONFIG)/chttp2_stream_encoder_test $(BINDIR)/$(CONFIG)/chttp2_stream_map_test $(BINDIR)/$(CONFIG)/chttp2_transport_end2end_test $(BINDIR)/$(CONFIG)/dualstack_socket_test $(BINDIR)/$(CONFIG)/echo_client $(BINDIR)/$(CONFIG)/echo_server $(BINDIR)/$(CONFIG)/echo_test $(BINDIR)/$(CONFIG)/fd_posix_test $(BINDIR)/$(CONFIG)/fling_client $(BINDIR)/$(CONFIG)/fling_server $(BINDIR)/$(CONFIG)/fling_stream_test $(BINDIR)/$(CONFIG)/fling_test $(BINDIR)/$(CONFIG)/gpr_cancellable_test $(BINDIR)/$(CONFIG)/gpr_cmdline_test $(BINDIR)/$(CONFIG)/gpr_env_test $(BINDIR)/$(CONFIG)/gpr_file_test $(BINDIR)/$(CONFIG)/gpr_histogram_test $(BINDIR)/$(CONFIG)/gpr_host_port_test $(BINDIR)/$(CONFIG)/gpr_log_test $(BINDIR)/$(CONFIG)/gpr_slice_buffer_test $(BINDIR)/$(CONFIG)/gpr_slice_test $(BINDIR)/$(CONFIG)/gpr_string_test $(BINDIR)/$(CONFIG)/gpr_sync_test $(BINDIR)/$(CONFIG)/gpr_thd_test $(BINDIR)/$(CONFIG)/gpr_time_test $(BINDIR)/$(CONFIG)/gpr_useful_test $(BINDIR)/$(CONFIG)/grpc_base64_test $(BINDIR)/$(CONFIG)/grpc_byte_buffer_reader_test $(BINDIR)/$(CONFIG)/grpc_channel_stack_test $(BINDIR)/$(CONFIG)/grpc_completion_queue_test $(BINDIR)/$(CONFIG)/grpc_credentials_test $(BINDIR)/$(CONFIG)/grpc_json_token_test $(BINDIR)/$(CONFIG)/grpc_stream_op_test $(BINDIR)/$(CONFIG)/hpack_parser_test $(BINDIR)/$(CONFIG)/hpack_table_test $(BINDIR)/$(CONFIG)/httpcli_format_request_test $(BINDIR)/$(CONFIG)/httpcli_parser_test $(BINDIR)/$(CONFIG)/httpcli_test $(BINDIR)/$(CONFIG)/json_rewrite $(BINDIR)/$(CONFIG)/json_rewrite_test $(BINDIR)/$(CONFIG)/json_test $(BINDIR)/$(CONFIG)/lame_client_test $(BINDIR)/$(CONFIG)/message_compress_test $(BINDIR)/$(CONFIG)/metadata_buffer_test $(BINDIR)/$(CONFIG)/multi_init_test $(BINDIR)/$(CONFIG)/murmur_hash_test $(BINDIR)/$(CONFIG)/no_server_test $(BINDIR)/$(CONFIG)/poll_kick_posix_test $(BINDIR)/$(CONFIG)/resolve_address_test $(BINDIR)/$(CONFIG)/secure_endpoint_test $(BINDIR)/$(CONFIG)/sockaddr_utils_test $(BINDIR)/$(CONFIG)/tcp_client_posix_test $(BINDIR)/$(CONFIG)/tcp_posix_test $(BINDIR)/$(CONFIG)/tcp_server_posix_test $(BINDIR)/$(CONFIG)/time_averaged_stats_test $(BINDIR)/$(CONFIG)/time_test $(BINDIR)/$(CONFIG)/timeout_encoding_test $(BINDIR)/$(CONFIG)/transport_metadata_test $(BINDIR)/$(CONFIG)/transport_security_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_no_op_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_no_op_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_no_op_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_no_op_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_legacy_test buildtests_cxx: privatelibs_cxx $(BINDIR)/$(CONFIG)/async_end2end_test $(BINDIR)/$(CONFIG)/channel_arguments_test $(BINDIR)/$(CONFIG)/credentials_test $(BINDIR)/$(CONFIG)/end2end_test $(BINDIR)/$(CONFIG)/interop_client $(BINDIR)/$(CONFIG)/interop_server $(BINDIR)/$(CONFIG)/interop_test $(BINDIR)/$(CONFIG)/pubsub_client $(BINDIR)/$(CONFIG)/pubsub_publisher_test $(BINDIR)/$(CONFIG)/pubsub_subscriber_test $(BINDIR)/$(CONFIG)/qps_client $(BINDIR)/$(CONFIG)/qps_server $(BINDIR)/$(CONFIG)/status_test $(BINDIR)/$(CONFIG)/thread_pool_test @@ -1069,6 +1070,8 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/timeout_encoding_test || ( echo test timeout_encoding_test failed ; exit 1 ) $(E) "[RUN] Testing transport_metadata_test" $(Q) $(BINDIR)/$(CONFIG)/transport_metadata_test || ( echo test transport_metadata_test failed ; exit 1 ) + $(E) "[RUN] Testing transport_security_test" + $(Q) $(BINDIR)/$(CONFIG)/transport_security_test || ( echo test transport_security_test failed ; exit 1 ) $(E) "[RUN] Testing chttp2_fake_security_cancel_after_accept_test" $(Q) $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_test || ( echo test chttp2_fake_security_cancel_after_accept_test failed ; exit 1 ) $(E) "[RUN] Testing chttp2_fake_security_cancel_after_accept_and_writes_closed_test" @@ -7429,6 +7432,37 @@ endif endif +TRANSPORT_SECURITY_TEST_SRC = \ + test/core/tsi/transport_security_test.c \ + +TRANSPORT_SECURITY_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(TRANSPORT_SECURITY_TEST_SRC)))) + +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL with ALPN. + +$(BINDIR)/$(CONFIG)/transport_security_test: openssl_dep_error + +else + +$(BINDIR)/$(CONFIG)/transport_security_test: $(TRANSPORT_SECURITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LD) $(LDFLAGS) $(TRANSPORT_SECURITY_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/transport_security_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/tsi/transport_security_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_transport_security_test: $(TRANSPORT_SECURITY_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(TRANSPORT_SECURITY_TEST_OBJS:.o=.dep) +endif +endif + + ASYNC_END2END_TEST_SRC = \ test/cpp/end2end/async_end2end_test.cc \ diff --git a/build.json b/build.json index 3e9d2a7584c..7a030ea888a 100644 --- a/build.json +++ b/build.json @@ -1579,6 +1579,20 @@ "gpr" ] }, + { + "name": "transport_security_test", + "build": "test", + "language": "c", + "src": [ + "test/core/tsi/transport_security_test.c" + ], + "deps": [ + "grpc_test_util", + "grpc", + "gpr_test_util", + "gpr" + ] + }, { "name": "async_end2end_test", "build": "test", diff --git a/src/core/tsi/ssl_transport_security.c b/src/core/tsi/ssl_transport_security.c index f1a52746d24..bda28e90016 100644 --- a/src/core/tsi/ssl_transport_security.c +++ b/src/core/tsi/ssl_transport_security.c @@ -180,6 +180,28 @@ static void ssl_info_callback(const SSL* ssl, int where, int ret) { ssl_log_where_info(ssl, where, SSL_CB_HANDSHAKE_DONE, "HANDSHAKE DONE"); } +/* Returns 1 if name looks like an IP address, 0 otherwise. */ +static int looks_like_ip_address(const char *name) { + size_t i; + size_t dot_count = 0; + size_t num_size = 0; + for (i = 0; i < strlen(name); i++) { + if (name[i] >= '0' && name[i] <= '9') { + if (num_size > 3) return 0; + num_size++; + } else if (name[i] == '.') { + if (dot_count > 3 || num_size == 0) return 0; + dot_count++; + num_size = 0; + } else { + return 0; + } + } + if (dot_count < 3 || num_size == 0) return 0; + return 1; +} + + /* Gets the subject CN from an X509 cert. */ static tsi_result ssl_get_x509_common_name(X509* cert, unsigned char** utf8, size_t* utf8_size) { @@ -226,10 +248,18 @@ static tsi_result peer_property_from_x509_common_name( size_t common_name_size; tsi_result result = ssl_get_x509_common_name(cert, &common_name, &common_name_size); - if (result != TSI_OK) return result; + if (result != TSI_OK) { + if (result == TSI_NOT_FOUND) { + common_name = NULL; + common_name_size = 0; + } else { + return result; + } + } result = tsi_construct_string_peer_property( - TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY, (const char*)common_name, - common_name_size, property); + TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY, + common_name == NULL ? "" : (const char*)common_name, common_name_size, + property); OPENSSL_free(common_name); return result; } @@ -1036,9 +1066,22 @@ static void ssl_server_handshaker_factory_destroy( static int does_entry_match_name(const char* entry, size_t entry_length, const char* name) { + const char *dot; const char* name_subdomain = NULL; + size_t name_length = strlen(name); + size_t name_subdomain_length; if (entry_length == 0) return 0; - if (!strncmp(name, entry, entry_length) && (strlen(name) == entry_length)) { + + /* Take care of '.' terminations. */ + if (name[name_length - 1] == '.') { + name_length--; + } + if (entry[entry_length - 1] == '.') { + entry_length--; + } + + if ((entry_length > 0) && (name_length == entry_length) && + !strncmp(name, entry, entry_length)) { return 1; /* Perfect match. */ } if (entry[0] != '*') return 0; @@ -1053,14 +1096,23 @@ static int does_entry_match_name(const char* entry, size_t entry_length, name_subdomain++; /* Starts after the dot. */ entry += 2; /* Remove *. */ entry_length -= 2; - return (!strncmp(entry, name_subdomain, entry_length) && - (strlen(name_subdomain) == entry_length)); + name_subdomain_length = strlen(name_subdomain); + dot = strchr(name_subdomain, '.'); + if ((dot == NULL) || (dot == &name_subdomain[name_subdomain_length - 1])) { + gpr_log(GPR_ERROR, "Invalid toplevel subdomain: %s", name_subdomain); + return 0; + } + if (name_subdomain[name_subdomain_length - 1] == '.') { + name_subdomain_length--; + } + return ((entry_length > 0) && (name_subdomain_length == entry_length) && + !strncmp(entry, name_subdomain, entry_length)); } static int ssl_server_handshaker_factory_servername_callback(SSL* ssl, int* ap, void* arg) { tsi_ssl_server_handshaker_factory* impl = - (tsi_ssl_server_handshaker_factory*)arg; + (tsi_ssl_server_handshaker_factory*)arg; size_t i = 0; const char* servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name); if (servername == NULL || strlen(servername) == 0) { @@ -1283,9 +1335,13 @@ tsi_result tsi_create_ssl_server_handshaker_factory( int tsi_ssl_peer_matches_name(const tsi_peer* peer, const char* name) { size_t i = 0; size_t san_count = 0; + const tsi_peer_property* property = NULL; + + /* For now reject what looks like an IP address. */ + if (looks_like_ip_address(name)) return 0; /* Check the SAN first. */ - const tsi_peer_property* property = tsi_peer_get_property_by_name( + property = tsi_peer_get_property_by_name( peer, TSI_X509_SUBJECT_ALTERNATIVE_NAMES_PEER_PROPERTY); if (property == NULL || property->type != TSI_PEER_PROPERTY_TYPE_LIST) { gpr_log(GPR_ERROR, "Invalid x509 subject alternative names property."); diff --git a/src/core/tsi/ssl_transport_security.h b/src/core/tsi/ssl_transport_security.h index 3c1c4c01a2a..eecf2d7c2d6 100644 --- a/src/core/tsi/ssl_transport_security.h +++ b/src/core/tsi/ssl_transport_security.h @@ -158,7 +158,12 @@ tsi_result tsi_ssl_handshaker_factory_create_handshaker( while handshakers created with this factory are still in use. */ void tsi_ssl_handshaker_factory_destroy(tsi_ssl_handshaker_factory* self); -/* Util that checks that an ssl peer matches a specific name. */ +/* Util that checks that an ssl peer matches a specific name. + Still TODO(jboeuf): + - handle mixed case. + - handle %encoded chars. + - handle public suffix wildchar more strictly (e.g. *.co.uk) + - handle IP addresses in SAN. */ int tsi_ssl_peer_matches_name(const tsi_peer* peer, const char* name); #ifdef __cplusplus diff --git a/test/core/tsi/transport_security_test.c b/test/core/tsi/transport_security_test.c new file mode 100644 index 00000000000..597b390c9b9 --- /dev/null +++ b/test/core/tsi/transport_security_test.c @@ -0,0 +1,303 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "src/core/tsi/transport_security.h" + +#include + +#include +#include +#include + +#include "src/core/support/string.h" +#include "src/core/tsi/ssl_transport_security.h" +#include "test/core/util/test_config.h" + +typedef struct { + /* 1 if success, 0 if failure. */ + int expected; + + /* Host name to match. */ + const char *host_name; + + /* Common name (CN). */ + const char *common_name; + + /* Comma separated list of certificate names to match against. Any occurrence + of '#' will be replaced with a null character before processing. */ + const char *dns_names; + +} cert_name_test_entry; + +/* Largely inspired from: + chromium/src/net/cert/x509_certificate_unittest.cc. + TODO(jboeuf) uncomment test cases as we fix tsi_ssl_peer_matches_name. */ +const cert_name_test_entry cert_name_test_entries[] = { + {1, "foo.com", "foo.com", NULL}, + {1, "f", "f", NULL}, + {0, "h", "i", NULL}, + {1, "bar.foo.com", "*.foo.com", NULL}, + {1, "www.test.fr", "common.name", + "*.test.com,*.test.co.uk,*.test.de,*.test.fr"}, + /* + {1, "wwW.tESt.fr", "common.name", ",*.*,*.test.de,*.test.FR,www"}, + */ + {0, "f.uk", ".uk", NULL}, + {0, "w.bar.foo.com", "?.bar.foo.com", NULL}, + {0, "www.foo.com", "(www|ftp).foo.com", NULL}, + {0, "www.foo.com", "www.foo.com#", NULL}, /* # = null char. */ + {0, "www.foo.com", "", "www.foo.com#*.foo.com,#,#"}, + {0, "www.house.example", "ww.house.example", NULL}, + {0, "test.org", "", "www.test.org,*.test.org,*.org"}, + {0, "w.bar.foo.com", "w*.bar.foo.com", NULL}, + {0, "www.bar.foo.com", "ww*ww.bar.foo.com", NULL}, + {0, "wwww.bar.foo.com", "ww*ww.bar.foo.com", NULL}, + {0, "wwww.bar.foo.com", "w*w.bar.foo.com", NULL}, + {0, "wwww.bar.foo.com", "w*w.bar.foo.c0m", NULL}, + {0, "WALLY.bar.foo.com", "wa*.bar.foo.com", NULL}, + {0, "wally.bar.foo.com", "*Ly.bar.foo.com", NULL}, + /* + {1, "ww%57.foo.com", "", "www.foo.com"}, + {1, "www&.foo.com", "www%26.foo.com", NULL}, + */ + + /* Common name must not be used if subject alternative name was provided. */ + {0, "www.test.co.jp", "www.test.co.jp", + "*.test.de,*.jp,www.test.co.uk,www.*.co.jp"}, + {0, "www.bar.foo.com", "www.bar.foo.com", + "*.foo.com,*.*.foo.com,*.*.bar.foo.com,*..bar.foo.com,"}, + + /* IDN tests */ + {1, "xn--poema-9qae5a.com.br", "xn--poema-9qae5a.com.br", NULL}, + {1, "www.xn--poema-9qae5a.com.br", "*.xn--poema-9qae5a.com.br", NULL}, + {0, "xn--poema-9qae5a.com.br", "", + "*.xn--poema-9qae5a.com.br," + "xn--poema-*.com.br," + "xn--*-9qae5a.com.br," + "*--poema-9qae5a.com.br"}, + + /* The following are adapted from the examples quoted from + http://tools.ietf.org/html/rfc6125#section-6.4.3 + (e.g., *.example.com would match foo.example.com but + not bar.foo.example.com or example.com). */ + {1, "foo.example.com", "*.example.com", NULL}, + {0, "bar.foo.example.com", "*.example.com", NULL}, + {0, "example.com", "*.example.com", NULL}, + + /* Partial wildcards are disallowed, though RFC 2818 rules allow them. + That is, forms such as baz*.example.net, *baz.example.net, and + b*z.example.net should NOT match domains. Instead, the wildcard must + always be the left-most label, and only a single label. */ + {0, "baz1.example.net", "baz*.example.net", NULL}, + {0, "foobaz.example.net", "*baz.example.net", NULL}, + {0, "buzz.example.net", "b*z.example.net", NULL}, + {0, "www.test.example.net", "www.*.example.net", NULL}, + + /* Wildcards should not be valid for public registry controlled domains, + and unknown/unrecognized domains, at least three domain components must + be present. */ + {1, "www.test.example", "*.test.example", NULL}, + {1, "test.example.co.uk", "*.example.co.uk", NULL}, + {0, "test.example", "*.example", NULL}, + /* + {0, "example.co.uk", "*.co.uk", NULL}, + */ + {0, "foo.com", "*.com", NULL}, + {0, "foo.us", "*.us", NULL}, + {0, "foo", "*", NULL}, + + /* IDN variants of wildcards and registry controlled domains. */ + {1, "www.xn--poema-9qae5a.com.br", "*.xn--poema-9qae5a.com.br", NULL}, + {1, "test.example.xn--mgbaam7a8h", "*.example.xn--mgbaam7a8h", NULL}, + /* + {0, "xn--poema-9qae5a.com.br", "*.com.br", NULL}, + */ + {0, "example.xn--mgbaam7a8h", "*.xn--mgbaam7a8h", NULL}, + + /* Wildcards should be permissible for 'private' registry controlled + domains. */ + {1, "www.appspot.com", "*.appspot.com", NULL}, + {1, "foo.s3.amazonaws.com", "*.s3.amazonaws.com", NULL}, + + /* Multiple wildcards are not valid. */ + {0, "foo.example.com", "*.*.com", NULL}, + {0, "foo.bar.example.com", "*.bar.*.com", NULL}, + + /* Absolute vs relative DNS name tests. Although not explicitly specified + in RFC 6125, absolute reference names (those ending in a .) should + match either absolute or relative presented names. */ + {1, "foo.com", "foo.com.", NULL}, + {1, "foo.com.", "foo.com", NULL}, + {1, "foo.com.", "foo.com.", NULL}, + {1, "f", "f.", NULL}, + {1, "f.", "f", NULL}, + {1, "f.", "f.", NULL}, + {1, "www-3.bar.foo.com", "*.bar.foo.com.", NULL}, + {1, "www-3.bar.foo.com.", "*.bar.foo.com", NULL}, + {1, "www-3.bar.foo.com.", "*.bar.foo.com.", NULL}, + {0, ".", ".", NULL}, + {0, "example.com", "*.com.", NULL}, + {0, "example.com.", "*.com", NULL}, + {0, "example.com.", "*.com.", NULL}, + {0, "foo.", "*.", NULL}, + {0, "foo", "*.", NULL}, + /* + {0, "foo.co.uk", "*.co.uk.", NULL}, + {0, "foo.co.uk.", "*.co.uk.", NULL}, + */ + + /* An empty CN is OK. */ + {1, "test.foo.com", "", "test.foo.com"}, + + /* An IP should not be used for the CN. */ + {0, "173.194.195.139", "173.194.195.139", NULL}, +}; + +typedef struct name_list { + const char *name; + struct name_list *next; +} name_list; + +typedef struct { + size_t name_count; + char *buffer; + name_list *names; +} parsed_dns_names; + +name_list *name_list_add(const char *n) { + name_list *result = gpr_malloc(sizeof(name_list)); + result->name = n; + result->next = NULL; + return result; +} + +static parsed_dns_names parse_dns_names(const char *dns_names_str) { + parsed_dns_names result; + name_list *current_nl; + size_t i; + memset(&result, 0, sizeof(parsed_dns_names)); + if (dns_names_str == 0) return result; + result.name_count = 1; + result.buffer = gpr_strdup(dns_names_str); + result.names = name_list_add(result.buffer); + current_nl = result.names; + for (i = 0; i < strlen(dns_names_str); i++) { + if (dns_names_str[i] == ',') { + result.buffer[i] = '\0'; + result.name_count++; + i++; + current_nl->next = name_list_add(result.buffer + i); + current_nl = current_nl->next; + } + } + return result; +} + +static void destruct_parsed_dns_names(parsed_dns_names *pdn) { + name_list *nl = pdn->names; + if (pdn->buffer != NULL) gpr_free(pdn->buffer); + while (nl != NULL) { + name_list *to_be_free = nl; + nl = nl->next; + gpr_free(to_be_free); + } +} + +static char *processed_dns_name(const char *dns_name) { + char *result = gpr_strdup(dns_name); + size_t i; + for (i = 0; i < strlen(result); i++) { + if (result[i] == '#') { + result[i] = '\0'; + } + } + return result; +} + +static tsi_peer peer_from_cert_name_test_entry( + const cert_name_test_entry *entry) { + size_t i; + tsi_peer peer; + name_list *nl; + parsed_dns_names dns_entries = parse_dns_names(entry->dns_names); + nl = dns_entries.names; + GPR_ASSERT(tsi_construct_peer(2, &peer) == TSI_OK); + GPR_ASSERT(tsi_construct_string_peer_property_from_cstring( + TSI_X509_SUBJECT_COMMON_NAME_PEER_PROPERTY, entry->common_name, + &peer.properties[0]) == TSI_OK); + GPR_ASSERT(tsi_construct_list_peer_property( + TSI_X509_SUBJECT_ALTERNATIVE_NAMES_PEER_PROPERTY, + dns_entries.name_count, &peer.properties[1]) == TSI_OK); + i = 0; + while (nl != NULL) { + char *processed = processed_dns_name(nl->name); + GPR_ASSERT(tsi_construct_string_peer_property( + NULL, processed, strlen(nl->name), + &peer.properties[1].value.list.children[i++]) == TSI_OK); + nl = nl->next; + gpr_free(processed); + } + destruct_parsed_dns_names(&dns_entries); + return peer; +} + +char *cert_name_test_entry_to_string(const cert_name_test_entry *entry) { + char *s; + gpr_asprintf( + &s, "{ success = %s, host_name = %s, common_name = %s, dns_names = %s}", + entry->expected ? "true" : "false", entry->host_name, entry->common_name, + entry->dns_names != NULL ? entry->dns_names : ""); + return s; +} + +static void test_peer_matches_name(void) { + size_t i = 0; + for (i = 0; i < GPR_ARRAY_SIZE(cert_name_test_entries); i++) { + const cert_name_test_entry *entry = &cert_name_test_entries[i]; + tsi_peer peer = peer_from_cert_name_test_entry(entry); + int result = tsi_ssl_peer_matches_name(&peer, entry->host_name); + if (result != entry->expected) { + char *entry_str = cert_name_test_entry_to_string(entry); + gpr_log(GPR_ERROR, "%s", entry_str); + gpr_free(entry_str); + GPR_ASSERT(0); /* Unexpected result. */ + } + tsi_peer_destruct(&peer); + } +} + +int main(int argc, char **argv) { + grpc_test_init(argc, argv); + test_peer_matches_name(); + return 0; +} diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json index 84f830c456e..4fb3e2d6b9e 100644 --- a/tools/run_tests/tests.json +++ b/tools/run_tests/tests.json @@ -265,6 +265,10 @@ "language": "c", "name": "transport_metadata_test" }, + { + "language": "c", + "name": "transport_security_test" + }, { "language": "c++", "name": "async_end2end_test" diff --git a/vsprojects/vs2013/Grpc.mak b/vsprojects/vs2013/Grpc.mak index 9272d07cb93..203c7872878 100644 --- a/vsprojects/vs2013/Grpc.mak +++ b/vsprojects/vs2013/Grpc.mak @@ -53,10 +53,10 @@ grpc_test_util: $(OUT_DIR): mkdir $(OUT_DIR) -buildtests: alarm_heap_test.exe alarm_list_test.exe alarm_test.exe alpn_test.exe bin_encoder_test.exe census_hash_table_test.exe census_statistics_multiple_writers_circular_buffer_test.exe census_statistics_multiple_writers_test.exe census_statistics_performance_test.exe census_statistics_quick_test.exe census_statistics_small_log_test.exe census_stats_store_test.exe census_stub_test.exe census_trace_store_test.exe census_window_stats_test.exe chttp2_status_conversion_test.exe chttp2_stream_encoder_test.exe chttp2_stream_map_test.exe chttp2_transport_end2end_test.exe dualstack_socket_test.exe echo_test.exe fd_posix_test.exe fling_stream_test.exe fling_test.exe gpr_cancellable_test.exe gpr_cmdline_test.exe gpr_env_test.exe gpr_file_test.exe gpr_histogram_test.exe gpr_host_port_test.exe gpr_log_test.exe gpr_slice_buffer_test.exe gpr_slice_test.exe gpr_string_test.exe gpr_sync_test.exe gpr_thd_test.exe gpr_time_test.exe gpr_useful_test.exe grpc_base64_test.exe grpc_byte_buffer_reader_test.exe grpc_channel_stack_test.exe grpc_completion_queue_test.exe grpc_credentials_test.exe grpc_json_token_test.exe grpc_stream_op_test.exe hpack_parser_test.exe hpack_table_test.exe httpcli_format_request_test.exe httpcli_parser_test.exe httpcli_test.exe json_rewrite_test.exe json_test.exe lame_client_test.exe message_compress_test.exe metadata_buffer_test.exe multi_init_test.exe murmur_hash_test.exe no_server_test.exe poll_kick_posix_test.exe resolve_address_test.exe secure_endpoint_test.exe sockaddr_utils_test.exe tcp_client_posix_test.exe tcp_posix_test.exe tcp_server_posix_test.exe time_averaged_stats_test.exe time_test.exe timeout_encoding_test.exe transport_metadata_test.exe +buildtests: alarm_heap_test.exe alarm_list_test.exe alarm_test.exe alpn_test.exe bin_encoder_test.exe census_hash_table_test.exe census_statistics_multiple_writers_circular_buffer_test.exe census_statistics_multiple_writers_test.exe census_statistics_performance_test.exe census_statistics_quick_test.exe census_statistics_small_log_test.exe census_stats_store_test.exe census_stub_test.exe census_trace_store_test.exe census_window_stats_test.exe chttp2_status_conversion_test.exe chttp2_stream_encoder_test.exe chttp2_stream_map_test.exe chttp2_transport_end2end_test.exe dualstack_socket_test.exe echo_test.exe fd_posix_test.exe fling_stream_test.exe fling_test.exe gpr_cancellable_test.exe gpr_cmdline_test.exe gpr_env_test.exe gpr_file_test.exe gpr_histogram_test.exe gpr_host_port_test.exe gpr_log_test.exe gpr_slice_buffer_test.exe gpr_slice_test.exe gpr_string_test.exe gpr_sync_test.exe gpr_thd_test.exe gpr_time_test.exe gpr_useful_test.exe grpc_base64_test.exe grpc_byte_buffer_reader_test.exe grpc_channel_stack_test.exe grpc_completion_queue_test.exe grpc_credentials_test.exe grpc_json_token_test.exe grpc_stream_op_test.exe hpack_parser_test.exe hpack_table_test.exe httpcli_format_request_test.exe httpcli_parser_test.exe httpcli_test.exe json_rewrite_test.exe json_test.exe lame_client_test.exe message_compress_test.exe metadata_buffer_test.exe multi_init_test.exe murmur_hash_test.exe no_server_test.exe poll_kick_posix_test.exe resolve_address_test.exe secure_endpoint_test.exe sockaddr_utils_test.exe tcp_client_posix_test.exe tcp_posix_test.exe tcp_server_posix_test.exe time_averaged_stats_test.exe time_test.exe timeout_encoding_test.exe transport_metadata_test.exe transport_security_test.exe echo All tests built. -test: alarm_heap_test alarm_list_test alarm_test alpn_test bin_encoder_test census_hash_table_test census_statistics_multiple_writers_circular_buffer_test census_statistics_multiple_writers_test census_statistics_performance_test census_statistics_quick_test census_statistics_small_log_test census_stats_store_test census_stub_test census_trace_store_test census_window_stats_test chttp2_status_conversion_test chttp2_stream_encoder_test chttp2_stream_map_test chttp2_transport_end2end_test dualstack_socket_test echo_test fd_posix_test fling_stream_test fling_test gpr_cancellable_test gpr_cmdline_test gpr_env_test gpr_file_test gpr_histogram_test gpr_host_port_test gpr_log_test gpr_slice_buffer_test gpr_slice_test gpr_string_test gpr_sync_test gpr_thd_test gpr_time_test gpr_useful_test grpc_base64_test grpc_byte_buffer_reader_test grpc_channel_stack_test grpc_completion_queue_test grpc_credentials_test grpc_json_token_test grpc_stream_op_test hpack_parser_test hpack_table_test httpcli_format_request_test httpcli_parser_test httpcli_test json_rewrite_test json_test lame_client_test message_compress_test metadata_buffer_test multi_init_test murmur_hash_test no_server_test poll_kick_posix_test resolve_address_test secure_endpoint_test sockaddr_utils_test tcp_client_posix_test tcp_posix_test tcp_server_posix_test time_averaged_stats_test time_test timeout_encoding_test transport_metadata_test +test: alarm_heap_test alarm_list_test alarm_test alpn_test bin_encoder_test census_hash_table_test census_statistics_multiple_writers_circular_buffer_test census_statistics_multiple_writers_test census_statistics_performance_test census_statistics_quick_test census_statistics_small_log_test census_stats_store_test census_stub_test census_trace_store_test census_window_stats_test chttp2_status_conversion_test chttp2_stream_encoder_test chttp2_stream_map_test chttp2_transport_end2end_test dualstack_socket_test echo_test fd_posix_test fling_stream_test fling_test gpr_cancellable_test gpr_cmdline_test gpr_env_test gpr_file_test gpr_histogram_test gpr_host_port_test gpr_log_test gpr_slice_buffer_test gpr_slice_test gpr_string_test gpr_sync_test gpr_thd_test gpr_time_test gpr_useful_test grpc_base64_test grpc_byte_buffer_reader_test grpc_channel_stack_test grpc_completion_queue_test grpc_credentials_test grpc_json_token_test grpc_stream_op_test hpack_parser_test hpack_table_test httpcli_format_request_test httpcli_parser_test httpcli_test json_rewrite_test json_test lame_client_test message_compress_test metadata_buffer_test multi_init_test murmur_hash_test no_server_test poll_kick_posix_test resolve_address_test secure_endpoint_test sockaddr_utils_test tcp_client_posix_test tcp_posix_test tcp_server_posix_test time_averaged_stats_test time_test timeout_encoding_test transport_metadata_test transport_security_test echo All tests ran. test_gpr: gpr_cancellable_test gpr_cmdline_test gpr_env_test gpr_file_test gpr_histogram_test gpr_host_port_test gpr_log_test gpr_slice_buffer_test gpr_slice_test gpr_string_test gpr_sync_test gpr_thd_test gpr_time_test gpr_useful_test @@ -702,3 +702,11 @@ transport_metadata_test: transport_metadata_test.exe echo Running transport_metadata_test $(OUT_DIR)\transport_metadata_test.exe +transport_security_test.exe: grpc_test_util + echo Building transport_security_test + $(CC) $(CFLAGS) /Fo:$(OUT_DIR)\ ..\..\test\core\tsi\transport_security_test.c + $(LINK) $(LFLAGS) /OUT:"$(OUT_DIR)\transport_security_test.exe" Debug\grpc_test_util.lib Debug\grpc.lib Debug\gpr_test_util.lib Debug\gpr.lib $(LIBS) $(OUT_DIR)\transport_security_test.obj +transport_security_test: transport_security_test.exe + echo Running transport_security_test + $(OUT_DIR)\transport_security_test.exe + From 042e63ca360e73524aa6c37e0c87c4a6ca77c6db Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Tue, 24 Feb 2015 17:02:09 -0800 Subject: [PATCH 10/75] Fixed import of google-auth-library --- src/node/examples/pubsub/pubsub_demo.js | 2 +- src/node/index.js | 2 +- src/node/interop/interop_client.js | 2 +- src/node/package.json | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/node/examples/pubsub/pubsub_demo.js b/src/node/examples/pubsub/pubsub_demo.js index 4f7a9a92eef..26301515f02 100644 --- a/src/node/examples/pubsub/pubsub_demo.js +++ b/src/node/examples/pubsub/pubsub_demo.js @@ -35,7 +35,7 @@ var async = require('async'); var fs = require('fs'); -var GoogleAuth = require('googleauth'); +var GoogleAuth = require('google-auth-library'); var parseArgs = require('minimist'); var strftime = require('strftime'); var _ = require('underscore'); diff --git a/src/node/index.js b/src/node/index.js index 4b5302e4382..ad3dd96af77 100644 --- a/src/node/index.js +++ b/src/node/index.js @@ -78,7 +78,7 @@ function load(filename) { /** * Get a function that a client can use to update metadata with authentication * information from a Google Auth credential object, which comes from the - * googleauth library. + * google-auth-library. * @param {Object} credential The credential object to use * @return {function(Object, callback)} Metadata updater function */ diff --git a/src/node/interop/interop_client.js b/src/node/interop/interop_client.js index eaf254bcfef..8060baf8271 100644 --- a/src/node/interop/interop_client.js +++ b/src/node/interop/interop_client.js @@ -37,7 +37,7 @@ var fs = require('fs'); var path = require('path'); var grpc = require('..'); var testProto = grpc.load(__dirname + '/test.proto').grpc.testing; -var GoogleAuth = require('googleauth'); +var GoogleAuth = require('google-auth-library'); var assert = require('assert'); diff --git a/src/node/package.json b/src/node/package.json index e6ac5505545..1c44b106fb4 100644 --- a/src/node/package.json +++ b/src/node/package.json @@ -16,7 +16,7 @@ }, "devDependencies": { "async": "^0.9.0", - "googleauth": "google/google-auth-library-nodejs", + "google-auth-library": "^0.9.2", "minimist": "^1.1.0", "mocha": "~1.21.0", "strftime": "^0.8.2" From 2c04a534505a0a2d7621e8098e44dbc1a767db9d Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 24 Feb 2015 17:12:47 -0800 Subject: [PATCH 11/75] Spam cleanup --- src/core/iomgr/resolve_address_posix.c | 17 ----------------- src/core/statistics/census_init.c | 2 -- src/core/statistics/census_rpc_stats.c | 2 -- src/core/statistics/census_tracing.c | 2 -- 4 files changed, 23 deletions(-) diff --git a/src/core/iomgr/resolve_address_posix.c b/src/core/iomgr/resolve_address_posix.c index edf40b5ad14..989b968ae27 100644 --- a/src/core/iomgr/resolve_address_posix.c +++ b/src/core/iomgr/resolve_address_posix.c @@ -66,7 +66,6 @@ grpc_resolved_addresses *grpc_blocking_resolve_address( int s; size_t i; grpc_resolved_addresses *addrs = NULL; - const gpr_timespec start_time = gpr_now(); struct sockaddr_un *un; if (name[0] == 'u' && name[1] == 'n' && name[2] == 'i' && name[3] == 'x' && @@ -121,22 +120,6 @@ grpc_resolved_addresses *grpc_blocking_resolve_address( i++; } - /* Temporary logging, to help identify flakiness in dualstack_socket_test. */ - { - const gpr_timespec delay = gpr_time_sub(gpr_now(), start_time); - const int delay_ms = - delay.tv_sec * GPR_MS_PER_SEC + delay.tv_nsec / GPR_NS_PER_MS; - gpr_log(GPR_INFO, "logspam: getaddrinfo(%s, %s) resolved %d addrs in %dms:", - host, port, addrs->naddrs, delay_ms); - for (i = 0; i < addrs->naddrs; i++) { - char *buf; - grpc_sockaddr_to_string(&buf, (struct sockaddr *)&addrs->addrs[i].addr, - 0); - gpr_log(GPR_INFO, "logspam: [%d] %s", i, buf); - gpr_free(buf); - } - } - done: gpr_free(host); gpr_free(port); diff --git a/src/core/statistics/census_init.c b/src/core/statistics/census_init.c index 820d75f795e..e6306f5e6fa 100644 --- a/src/core/statistics/census_init.c +++ b/src/core/statistics/census_init.c @@ -38,13 +38,11 @@ #include "src/core/statistics/census_tracing.h" void census_init(void) { - gpr_log(GPR_INFO, "Initialize census library."); census_tracing_init(); census_stats_store_init(); } void census_shutdown(void) { - gpr_log(GPR_INFO, "Shutdown census library."); census_stats_store_shutdown(); census_tracing_shutdown(); } diff --git a/src/core/statistics/census_rpc_stats.c b/src/core/statistics/census_rpc_stats.c index 388ce4fe2c8..0491c919479 100644 --- a/src/core/statistics/census_rpc_stats.c +++ b/src/core/statistics/census_rpc_stats.c @@ -222,7 +222,6 @@ void census_get_server_stats(census_aggregated_rpc_stats* data) { } void census_stats_store_init(void) { - gpr_log(GPR_INFO, "Initialize census stats store."); init_mutex_once(); gpr_mu_lock(&g_mu); if (g_client_stats_store == NULL && g_server_stats_store == NULL) { @@ -235,7 +234,6 @@ void census_stats_store_init(void) { } void census_stats_store_shutdown(void) { - gpr_log(GPR_INFO, "Shutdown census stats store."); init_mutex_once(); gpr_mu_lock(&g_mu); if (g_client_stats_store != NULL) { diff --git a/src/core/statistics/census_tracing.c b/src/core/statistics/census_tracing.c index adfcbecb4c8..05e72b99c0b 100644 --- a/src/core/statistics/census_tracing.c +++ b/src/core/statistics/census_tracing.c @@ -154,7 +154,6 @@ void census_tracing_end_op(census_op_id op_id) { } void census_tracing_init(void) { - gpr_log(GPR_INFO, "Initialize census trace store."); init_mutex_once(); gpr_mu_lock(&g_mu); if (g_trace_store == NULL) { @@ -167,7 +166,6 @@ void census_tracing_init(void) { } void census_tracing_shutdown(void) { - gpr_log(GPR_INFO, "Shutdown census trace store."); gpr_mu_lock(&g_mu); if (g_trace_store != NULL) { census_ht_destroy(g_trace_store); From 5c6f21eda4ca7bb2cd110c7002a1e7b66db17ba0 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 24 Feb 2015 17:16:14 -0800 Subject: [PATCH 12/75] Also get rid of CHTTP2 settings spam --- src/core/transport/chttp2/frame_settings.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/core/transport/chttp2/frame_settings.c b/src/core/transport/chttp2/frame_settings.c index 06429e220b7..e6c4b7e38f1 100644 --- a/src/core/transport/chttp2/frame_settings.c +++ b/src/core/transport/chttp2/frame_settings.c @@ -35,6 +35,7 @@ #include +#include "src/core/debug/trace.h" #include "src/core/transport/chttp2/frame.h" #include #include @@ -53,7 +54,8 @@ const grpc_chttp2_setting_parameters {"MAX_FRAME_SIZE", 16384, 16384, 16777215, GRPC_CHTTP2_DISCONNECT_ON_INVALID_VALUE}, {"MAX_HEADER_LIST_SIZE", 0xffffffffu, 0, 0xffffffffu, - GRPC_CHTTP2_CLAMP_INVALID_VALUE}, }; + GRPC_CHTTP2_CLAMP_INVALID_VALUE}, +}; static gpr_uint8 *fill_header(gpr_uint8 *out, gpr_uint32 length, gpr_uint8 flags) { @@ -155,7 +157,7 @@ grpc_chttp2_parse_error grpc_chttp2_settings_parser_parse( } return GRPC_CHTTP2_PARSE_OK; } - parser->id = ((gpr_uint16) * cur) << 8; + parser->id = ((gpr_uint16)*cur) << 8; cur++; /* fallthrough */ case GRPC_CHTTP2_SPS_ID1: @@ -171,7 +173,7 @@ grpc_chttp2_parse_error grpc_chttp2_settings_parser_parse( parser->state = GRPC_CHTTP2_SPS_VAL0; return GRPC_CHTTP2_PARSE_OK; } - parser->value = ((gpr_uint32) * cur) << 24; + parser->value = ((gpr_uint32)*cur) << 24; cur++; /* fallthrough */ case GRPC_CHTTP2_SPS_VAL1: @@ -179,7 +181,7 @@ grpc_chttp2_parse_error grpc_chttp2_settings_parser_parse( parser->state = GRPC_CHTTP2_SPS_VAL1; return GRPC_CHTTP2_PARSE_OK; } - parser->value |= ((gpr_uint32) * cur) << 16; + parser->value |= ((gpr_uint32)*cur) << 16; cur++; /* fallthrough */ case GRPC_CHTTP2_SPS_VAL2: @@ -187,7 +189,7 @@ grpc_chttp2_parse_error grpc_chttp2_settings_parser_parse( parser->state = GRPC_CHTTP2_SPS_VAL2; return GRPC_CHTTP2_PARSE_OK; } - parser->value |= ((gpr_uint32) * cur) << 8; + parser->value |= ((gpr_uint32)*cur) << 8; cur++; /* fallthrough */ case GRPC_CHTTP2_SPS_VAL3: @@ -216,8 +218,10 @@ grpc_chttp2_parse_error grpc_chttp2_settings_parser_parse( } } parser->incoming_settings[parser->id] = parser->value; - gpr_log(GPR_DEBUG, "CHTTP2: got setting %d = %d", parser->id, - parser->value); + if (grpc_trace_bits & GRPC_TRACE_HTTP) { + gpr_log(GPR_DEBUG, "CHTTP2: got setting %d = %d", parser->id, + parser->value); + } } else { gpr_log(GPR_ERROR, "CHTTP2: Ignoring unknown setting %d (value %d)", parser->id, parser->value); From c6bccc24d39cf651219e96e91ccc7767943272b8 Mon Sep 17 00:00:00 2001 From: David Klempner Date: Tue, 24 Feb 2015 17:33:05 -0800 Subject: [PATCH 13/75] Move close() to when the fd refcount goes to zero Instead, we do a shutdown() at the point we are currently closing, to kick off socket teardown while ensuring an fd ref is sufficient to make concurrent syscalls like epoll_ctl safe. --- src/core/iomgr/fd_posix.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/iomgr/fd_posix.c b/src/core/iomgr/fd_posix.c index 41fd24e05a8..abdd49bbda3 100644 --- a/src/core/iomgr/fd_posix.c +++ b/src/core/iomgr/fd_posix.c @@ -38,6 +38,7 @@ #include "src/core/iomgr/fd_posix.h" #include +#include #include #include "src/core/iomgr/iomgr_internal.h" @@ -113,6 +114,7 @@ static void ref_by(grpc_fd *fd, int n) { static void unref_by(grpc_fd *fd, int n) { gpr_atm old = gpr_atm_full_fetch_add(&fd->refst, -n); if (old == n) { + close(fd->fd); grpc_iomgr_add_callback(fd->on_done, fd->on_done_user_data); freelist_fd(fd); grpc_iomgr_unref(); @@ -158,9 +160,9 @@ static void wake_watchers(grpc_fd *fd) { void grpc_fd_orphan(grpc_fd *fd, grpc_iomgr_cb_func on_done, void *user_data) { fd->on_done = on_done ? on_done : do_nothing; fd->on_done_user_data = user_data; + shutdown(fd->fd, SHUT_RDWR); ref_by(fd, 1); /* remove active status, but keep referenced */ wake_watchers(fd); - close(fd->fd); unref_by(fd, 2); /* drop the reference */ } From 0170a6c662337a1d9c741fa466d3a26723f2d5cf Mon Sep 17 00:00:00 2001 From: Julien Boeuf Date: Tue, 24 Feb 2015 18:08:01 -0800 Subject: [PATCH 14/75] Addressing another round of comments. --- src/core/tsi/ssl_transport_security.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/core/tsi/ssl_transport_security.c b/src/core/tsi/ssl_transport_security.c index bda28e90016..567b990610b 100644 --- a/src/core/tsi/ssl_transport_security.c +++ b/src/core/tsi/ssl_transport_security.c @@ -180,7 +180,9 @@ static void ssl_info_callback(const SSL* ssl, int where, int ret) { ssl_log_where_info(ssl, where, SSL_CB_HANDSHAKE_DONE, "HANDSHAKE DONE"); } -/* Returns 1 if name looks like an IP address, 0 otherwise. */ +/* Returns 1 if name looks like an IP address, 0 otherwise. + This is a very rough heuristic as it does not handle IPV6 or things like: + 0300.0250.00.01, 0xC0.0Xa8.0x0.0x1, 000030052000001, 0xc0.052000001 */ static int looks_like_ip_address(const char *name) { size_t i; size_t dot_count = 0; @@ -1078,10 +1080,10 @@ static int does_entry_match_name(const char* entry, size_t entry_length, } if (entry[entry_length - 1] == '.') { entry_length--; + if (entry_length == 0) return 0; } - if ((entry_length > 0) && (name_length == entry_length) && - !strncmp(name, entry, entry_length)) { + if ((name_length == entry_length) && !strncmp(name, entry, entry_length)) { return 1; /* Perfect match. */ } if (entry[0] != '*') return 0; @@ -1092,11 +1094,12 @@ static int does_entry_match_name(const char* entry, size_t entry_length, return 0; } name_subdomain = strchr(name, '.'); - if (name_subdomain == NULL || strlen(name_subdomain) < 2) return 0; + name_subdomain_length = strlen(name_subdomain); + if (name_subdomain == NULL || name_subdomain_length < 2) return 0; name_subdomain++; /* Starts after the dot. */ + name_subdomain_length--; entry += 2; /* Remove *. */ entry_length -= 2; - name_subdomain_length = strlen(name_subdomain); dot = strchr(name_subdomain, '.'); if ((dot == NULL) || (dot == &name_subdomain[name_subdomain_length - 1])) { gpr_log(GPR_ERROR, "Invalid toplevel subdomain: %s", name_subdomain); From f5c6625847219d27c154deeff8b4a86ae26098a9 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Tue, 24 Feb 2015 18:11:47 -0800 Subject: [PATCH 15/75] Fixed environment variable passing in node cloud-prod command --- tools/gce_setup/grpc_docker.sh | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/tools/gce_setup/grpc_docker.sh b/tools/gce_setup/grpc_docker.sh index bbc138c6beb..361a350bba4 100755 --- a/tools/gce_setup/grpc_docker.sh +++ b/tools/gce_setup/grpc_docker.sh @@ -945,7 +945,7 @@ grpc_cloud_prod_auth_service_account_creds_gen_go_cmd() { local test_script="cd src/google.golang.org/grpc/interop/client" local test_script+=" && go run client.go --use_tls=true" local gfe_flags=" --tls_ca_file=\"\" --tls_server_name=\"\" --server_port=443 --server_host=grpc-test.sandbox.google.com" - local added_gfe_flags=$(_grpc_svc_acc_test_flags) + local added_gfe_flags=$(_grpc_svc_acc_test_flags) local the_cmd="$cmd_prefix '$test_script $gfe_flags $added_gfe_flags $@'" echo $the_cmd } @@ -960,7 +960,7 @@ grpc_cloud_prod_auth_compute_engine_creds_gen_go_cmd() { local test_script="cd src/google.golang.org/grpc/interop/client" local test_script+=" && go run client.go --use_tls=true" local gfe_flags=" --tls_ca_file=\"\" --tls_server_name=\"\" --server_port=443 --server_host=grpc-test.sandbox.google.com" - local added_gfe_flags=$(_grpc_gce_test_flags) + local added_gfe_flags=$(_grpc_gce_test_flags) local the_cmd="$cmd_prefix '$test_script $gfe_flags $added_gfe_flags $@'" echo $the_cmd } @@ -1085,7 +1085,8 @@ grpc_interop_gen_node_cmd() { # flags= .... # generic flags to include the command # cmd=$($grpc_gen_test_cmd $flags) grpc_cloud_prod_gen_node_cmd() { - local cmd_prefix="sudo docker run grpc/node"; + local env_flag="-e SSL_CERT_FILE=/cacerts/roots.pem " + local cmd_prefix="sudo docker run $env_flag grpc/node"; local test_script="/usr/bin/nodejs /var/local/git/grpc/src/node/interop/interop_client.js --use_tls=true"; local gfe_flags=$(_grpc_prod_gfe_flags); local the_cmd="$cmd_prefix $test_script $gfe_flags $@"; @@ -1098,12 +1099,12 @@ grpc_cloud_prod_gen_node_cmd() { # flags= .... # generic flags to include the command # cmd=$($grpc_gen_test_cmd $flags) grpc_cloud_prod_auth_service_account_creds_gen_node_cmd() { - local cmd_prefix="sudo docker run grpc/node"; + local env_flag="-e SSL_CERT_FILE=/cacerts/roots.pem " + env_flag+="-e GOOGLE_APPLICATION_CREDENTIALS=/service_account/stubbyCloudTestingTest-7dd63462c60c.json " + local cmd_prefix="sudo docker run $env_flag grpc/node"; local test_script="/usr/bin/nodejs /var/local/git/grpc/src/node/interop/interop_client.js --use_tls=true"; local gfe_flags=$(_grpc_prod_gfe_flags); - local env_prefix="SSL_CERT_FILE=/cacerts/roots.pem" - env_prefix+=" GOOGLE_APPLICATION_CREDENTIALS=/service_account/stubbyCloudTestingTest-7dd63462c60c.json" - local the_cmd="$env_prefix $cmd_prefix $test_script $gfe_flags $@"; + local the_cmd="$cmd_prefix $test_script $gfe_flags $@"; echo $the_cmd } From 09e4583751dd8e7bc31b648af484b3a13c534917 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Tue, 24 Feb 2015 18:22:34 -0800 Subject: [PATCH 16/75] Fixed node cloud-prod commands --- tools/gce_setup/grpc_docker.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/gce_setup/grpc_docker.sh b/tools/gce_setup/grpc_docker.sh index 361a350bba4..6fff057c832 100755 --- a/tools/gce_setup/grpc_docker.sh +++ b/tools/gce_setup/grpc_docker.sh @@ -503,7 +503,7 @@ grpc_cloud_prod_auth_test_args() { [[ -n $1 ]] && { # client_type case $1 in - cxx|go|java|nodejs|php|python|ruby) + cxx|go|java|node|php|python|ruby) grpc_gen_test_cmd+="_gen_$1_cmd" declare -F $grpc_gen_test_cmd >> /dev/null || { echo "-f: test_func for $1 => $grpc_gen_test_cmd is not defined" 1>&2 From 59d9ff4d9fd596f7cf77cf4285c3519363df4af8 Mon Sep 17 00:00:00 2001 From: Masood Malekghassemi Date: Mon, 23 Feb 2015 15:28:07 -0800 Subject: [PATCH 17/75] Updated Python protoc plugin testing. --- src/compiler/python_generator.cc | 367 +++++++++++++++----------- src/compiler/python_generator.h | 3 +- src/compiler/python_plugin.cc | 16 +- test/compiler/python_plugin_test.py | 395 +++++++++++++++------------- test/compiler/test.proto | 3 +- tools/run_tests/run_python.sh | 3 +- 6 files changed, 443 insertions(+), 344 deletions(-) diff --git a/src/compiler/python_generator.cc b/src/compiler/python_generator.cc index cdd3d8a98a5..34d5332d03f 100644 --- a/src/compiler/python_generator.cc +++ b/src/compiler/python_generator.cc @@ -33,9 +33,11 @@ #include #include +#include #include #include #include +#include #include "src/compiler/python_generator.h" #include @@ -43,14 +45,19 @@ #include #include +using google::protobuf::Descriptor; using google::protobuf::FileDescriptor; using google::protobuf::ServiceDescriptor; using google::protobuf::MethodDescriptor; using google::protobuf::io::Printer; using google::protobuf::io::StringOutputStream; using std::initializer_list; +using std::make_pair; using std::map; +using std::pair; using std::string; +using std::strlen; +using std::vector; namespace grpc_python_generator { namespace { @@ -99,62 +106,81 @@ class IndentScope { // END FORMATTING BOILERPLATE // //////////////////////////////// -void PrintService(const ServiceDescriptor* service, - Printer* out) { +bool PrintServicer(const ServiceDescriptor* service, + Printer* out) { string doc = ""; map dict = ListToDict({ "Service", service->name(), "Documentation", doc, }); - out->Print(dict, "class $Service$Service(object):\n"); + out->Print(dict, "class EarlyAdopter$Service$Servicer(object):\n"); { IndentScope raii_class_indent(out); out->Print(dict, "\"\"\"$Documentation$\"\"\"\n"); - out->Print("def __init__(self):\n"); - { - IndentScope raii_method_indent(out); - out->Print("pass\n"); + out->Print("__metaclass__ = abc.ABCMeta\n"); + for (int i = 0; i < service->method_count(); ++i) { + auto meth = service->method(i); + string arg_name = meth->client_streaming() ? + "request_iterator" : "request"; + out->Print("@abc.abstractmethod\n"); + out->Print("def $Method$(self, $ArgName$):\n", + "Method", meth->name(), "ArgName", arg_name); + { + IndentScope raii_method_indent(out); + out->Print("raise NotImplementedError()\n"); + } } } + return true; } -void PrintServicer(const ServiceDescriptor* service, - Printer* out) { +bool PrintServer(const ServiceDescriptor* service, Printer* out) { string doc = ""; map dict = ListToDict({ "Service", service->name(), "Documentation", doc, }); - out->Print(dict, "class $Service$Servicer(object):\n"); + out->Print(dict, "class EarlyAdopter$Service$Server(object):\n"); { IndentScope raii_class_indent(out); out->Print(dict, "\"\"\"$Documentation$\"\"\"\n"); - for (int i = 0; i < service->method_count(); ++i) { - auto meth = service->method(i); - out->Print("def $Method$(self, arg):\n", "Method", meth->name()); - { - IndentScope raii_method_indent(out); - out->Print("raise NotImplementedError()\n"); - } + out->Print("__metaclass__ = abc.ABCMeta\n"); + out->Print("@abc.abstractmethod\n"); + out->Print("def start(self):\n"); + { + IndentScope raii_method_indent(out); + out->Print("raise NotImplementedError()\n"); + } + + out->Print("@abc.abstractmethod\n"); + out->Print("def stop(self):\n"); + { + IndentScope raii_method_indent(out); + out->Print("raise NotImplementedError()\n"); } } + return true; } -void PrintStub(const ServiceDescriptor* service, +bool PrintStub(const ServiceDescriptor* service, Printer* out) { string doc = ""; map dict = ListToDict({ "Service", service->name(), "Documentation", doc, }); - out->Print(dict, "class $Service$Stub(object):\n"); + out->Print(dict, "class EarlyAdopter$Service$Stub(object):\n"); { IndentScope raii_class_indent(out); out->Print(dict, "\"\"\"$Documentation$\"\"\"\n"); + out->Print("__metaclass__ = abc.ABCMeta\n"); for (int i = 0; i < service->method_count(); ++i) { const MethodDescriptor* meth = service->method(i); - auto methdict = ListToDict({"Method", meth->name()}); - out->Print(methdict, "def $Method$(self, arg):\n"); + string arg_name = meth->client_streaming() ? + "request_iterator" : "request"; + auto methdict = ListToDict({"Method", meth->name(), "ArgName", arg_name}); + out->Print("@abc.abstractmethod\n"); + out->Print(methdict, "def $Method$(self, $ArgName$):\n"); { IndentScope raii_method_indent(out); out->Print("raise NotImplementedError()\n"); @@ -162,169 +188,190 @@ void PrintStub(const ServiceDescriptor* service, out->Print(methdict, "$Method$.async = None\n"); } } + return true; } -void PrintStubImpl(const ServiceDescriptor* service, - Printer* out) { - map dict = ListToDict({ - "Service", service->name(), - }); - out->Print(dict, "class _$Service$Stub($Service$Stub):\n"); - { - IndentScope raii_class_indent(out); - out->Print("def __init__(self, face_stub, default_timeout):\n"); - { - IndentScope raii_method_indent(out); - out->Print("self._face_stub = face_stub\n" - "self._default_timeout = default_timeout\n" - "stub_self = self\n"); +bool GetModuleAndMessagePath(const Descriptor* type, + pair* out) { + const Descriptor* path_elem_type = type; + vector message_path; + do { + message_path.push_back(path_elem_type); + path_elem_type = path_elem_type->containing_type(); + } while (path_elem_type != nullptr); + string file_name = type->file()->name(); + string module_name; + static const int proto_suffix_length = strlen(".proto"); + if (!(file_name.size() > static_cast(proto_suffix_length) && + file_name.find_last_of(".proto") == file_name.size() - 1)) { + return false; + } + module_name = file_name.substr( + 0, file_name.size() - proto_suffix_length) + "_pb2"; + string package = type->file()->package(); + string module = (package.empty() ? "" : package + ".") + + module_name; + string message_type; + for (auto path_iter = message_path.rbegin(); + path_iter != message_path.rend(); ++path_iter) { + message_type += (*path_iter)->name() + "."; + } + message_type.pop_back(); + *out = make_pair(module, message_type); + return true; +} - for (int i = 0; i < service->method_count(); ++i) { - const MethodDescriptor* meth = service->method(i); - bool server_streaming = meth->server_streaming(); - bool client_streaming = meth->client_streaming(); - std::string blocking_call, future_call; - if (server_streaming) { - if (client_streaming) { - blocking_call = "stub_self._face_stub.inline_stream_in_stream_out"; - future_call = blocking_call; - } else { - blocking_call = "stub_self._face_stub.inline_value_in_stream_out"; - future_call = blocking_call; - } - } else { - if (client_streaming) { - blocking_call = "stub_self._face_stub.blocking_stream_in_value_out"; - future_call = "stub_self._face_stub.future_stream_in_value_out"; - } else { - blocking_call = "stub_self._face_stub.blocking_value_in_value_out"; - future_call = "stub_self._face_stub.future_value_in_value_out"; - } - } - // TODO(atash): use the solution described at - // http://stackoverflow.com/a/2982 to bind 'async' attribute - // functions to def'd functions instead of using callable attributes. - auto methdict = ListToDict({ - "Method", meth->name(), - "BlockingCall", blocking_call, - "FutureCall", future_call - }); - out->Print(methdict, "class $Method$(object):\n"); - { - IndentScope raii_callable_indent(out); - out->Print("def __call__(self, arg):\n"); - { - IndentScope raii_callable_call_indent(out); - out->Print(methdict, - "return $BlockingCall$(\"$Method$\", arg, " - "stub_self._default_timeout)\n"); - } - out->Print("def async(self, arg):\n"); - { - IndentScope raii_callable_async_indent(out); - out->Print(methdict, - "return $FutureCall$(\"$Method$\", arg, " - "stub_self._default_timeout)\n"); - } - } - out->Print(methdict, "self.$Method$ = $Method$()\n"); +bool PrintServerFactory(const ServiceDescriptor* service, Printer* out) { + out->Print("def early_adopter_create_$Service$_server(servicer, port, " + "root_certificates, key_chain_pairs):\n", + "Service", service->name()); + { + IndentScope raii_create_server_indent(out); + map> method_to_module_and_message; + out->Print("method_implementations = {\n"); + for (int i = 0; i < service->method_count(); ++i) { + IndentScope raii_implementations_indent(out); + const MethodDescriptor* meth = service->method(i); + string meth_type = + string(meth->client_streaming() ? "stream" : "unary") + + string(meth->server_streaming() ? "_stream" : "_unary") + "_inline"; + out->Print("\"$Method$\": utilities.$Type$(servicer.$Method$),\n", + "Method", meth->name(), + "Type", meth_type); + // Maintain information on the input type of the service method for later + // use in constructing the service assembly's activated fore link. + const Descriptor* input_type = meth->input_type(); + pair module_and_message; + if (!GetModuleAndMessagePath(input_type, &module_and_message)) { + return false; } + method_to_module_and_message.emplace( + meth->name(), module_and_message); + } + out->Print("}\n"); + // Ensure that we've imported all of the relevant messages. + for (auto& meth_vals : method_to_module_and_message) { + out->Print("import $Module$\n", + "Module", meth_vals.second.first); } + out->Print("request_deserializers = {\n"); + for (auto& meth_vals : method_to_module_and_message) { + IndentScope raii_serializers_indent(out); + string full_input_type_path = meth_vals.second.first + "." + + meth_vals.second.second; + out->Print("\"$Method$\": $Type$.FromString,\n", + "Method", meth_vals.first, + "Type", full_input_type_path); + } + out->Print("}\n"); + out->Print("response_serializers = {\n"); + for (auto& meth_vals : method_to_module_and_message) { + IndentScope raii_serializers_indent(out); + out->Print("\"$Method$\": lambda x: x.SerializeToString(),\n", + "Method", meth_vals.first); + } + out->Print("}\n"); + out->Print("link = fore.activated_fore_link(port, request_deserializers, " + "response_serializers, root_certificates, key_chain_pairs)\n"); + out->Print("return implementations.assemble_service(" + "method_implementations, link)\n"); } + return true; } -void PrintStubGenerators(const ServiceDescriptor* service, Printer* out) { +bool PrintStubFactory(const ServiceDescriptor* service, Printer* out) { map dict = ListToDict({ "Service", service->name(), }); - // Write out a generator of linked pairs of Server/Stub - out->Print(dict, "def mock_$Service$(servicer, default_timeout):\n"); + out->Print(dict, "def early_adopter_create_$Service$_stub(host, port):\n"); { - IndentScope raii_mock_indent(out); - out->Print("value_in_value_out = {}\n" - "value_in_stream_out = {}\n" - "stream_in_value_out = {}\n" - "stream_in_stream_out = {}\n"); + IndentScope raii_create_server_indent(out); + map> method_to_module_and_message; + out->Print("method_implementations = {\n"); for (int i = 0; i < service->method_count(); ++i) { + IndentScope raii_implementations_indent(out); const MethodDescriptor* meth = service->method(i); - std::string super_interface, meth_dict; - bool server_streaming = meth->server_streaming(); - bool client_streaming = meth->client_streaming(); - if (server_streaming) { - if (client_streaming) { - super_interface = "InlineStreamInStreamOutMethod"; - meth_dict = "stream_in_stream_out"; - } else { - super_interface = "InlineValueInStreamOutMethod"; - meth_dict = "value_in_stream_out"; - } - } else { - if (client_streaming) { - super_interface = "InlineStreamInValueOutMethod"; - meth_dict = "stream_in_value_out"; - } else { - super_interface = "InlineValueInValueOutMethod"; - meth_dict = "value_in_value_out"; - } - } - map methdict = ListToDict({ - "Method", meth->name(), - "SuperInterface", super_interface, - "MethodDict", meth_dict - }); - out->Print( - methdict, "class $Method$(_face_interfaces.$SuperInterface$):\n"); - { - IndentScope raii_inline_class_indent(out); - out->Print("def service(self, request, context):\n"); - { - IndentScope raii_inline_class_fn_indent(out); - out->Print(methdict, "return servicer.$Method$(request)\n"); - } + string meth_type = + string(meth->client_streaming() ? "stream" : "unary") + + string(meth->server_streaming() ? "_stream" : "_unary") + "_inline"; + // TODO(atash): once the expected input to assemble_dynamic_inline_stub is + // cleaned up, change this to the expected argument's dictionary values. + out->Print("\"$Method$\": utilities.$Type$(None),\n", + "Method", meth->name(), + "Type", meth_type); + // Maintain information on the input type of the service method for later + // use in constructing the service assembly's activated fore link. + const Descriptor* output_type = meth->output_type(); + pair module_and_message; + if (!GetModuleAndMessagePath(output_type, &module_and_message)) { + return false; } - out->Print(methdict, "$MethodDict$['$Method$'] = $Method$()\n"); + method_to_module_and_message.emplace( + meth->name(), module_and_message); } - out->Print( - "face_linked_pair = _face_testing.server_and_stub(default_timeout," - "inline_value_in_value_out_methods=value_in_value_out," - "inline_value_in_stream_out_methods=value_in_stream_out," - "inline_stream_in_value_out_methods=stream_in_value_out," - "inline_stream_in_stream_out_methods=stream_in_stream_out)\n"); - out->Print("class LinkedPair(object):\n"); - { - IndentScope raii_linked_pair(out); - out->Print("def __init__(self, server, stub):\n"); - { - IndentScope raii_linked_pair_init(out); - out->Print("self.server = server\n" - "self.stub = stub\n"); - } + out->Print("}\n"); + // Ensure that we've imported all of the relevant messages. + for (auto& meth_vals : method_to_module_and_message) { + out->Print("import $Module$\n", + "Module", meth_vals.second.first); } - out->Print( - dict, - "stub = _$Service$Stub(face_linked_pair.stub, default_timeout)\n"); - out->Print("return LinkedPair(None, stub)\n"); + out->Print("response_deserializers = {\n"); + for (auto& meth_vals : method_to_module_and_message) { + IndentScope raii_serializers_indent(out); + string full_output_type_path = meth_vals.second.first + "." + + meth_vals.second.second; + out->Print("\"$Method$\": $Type$.FromString,\n", + "Method", meth_vals.first, + "Type", full_output_type_path); + } + out->Print("}\n"); + out->Print("request_serializers = {\n"); + for (auto& meth_vals : method_to_module_and_message) { + IndentScope raii_serializers_indent(out); + out->Print("\"$Method$\": lambda x: x.SerializeToString(),\n", + "Method", meth_vals.first); + } + out->Print("}\n"); + out->Print("link = rear.activated_rear_link(" + "host, port, request_serializers, response_deserializers)\n"); + out->Print("return implementations.assemble_dynamic_inline_stub(" + "method_implementations, link)\n"); } + return true; +} + +bool PrintPreamble(const FileDescriptor* file, Printer* out) { + out->Print("import abc\n"); + out->Print("from grpc._adapter import fore\n"); + out->Print("from grpc._adapter import rear\n"); + out->Print("from grpc.framework.assembly import implementations\n"); + out->Print("from grpc.framework.assembly import utilities\n"); + return true; } } // namespace -string GetServices(const FileDescriptor* file) { +pair GetServices(const FileDescriptor* file) { string output; - StringOutputStream output_stream(&output); - Printer out(&output_stream, '$'); - out.Print("from grpc.framework.face import demonstration as _face_testing\n"); - out.Print("from grpc.framework.face import interfaces as _face_interfaces\n"); - - for (int i = 0; i < file->service_count(); ++i) { - auto service = file->service(i); - PrintService(service, &out); - PrintServicer(service, &out); - PrintStub(service, &out); - PrintStubImpl(service, &out); - PrintStubGenerators(service, &out); + { + // Scope the output stream so it closes and finalizes output to the string. + StringOutputStream output_stream(&output); + Printer out(&output_stream, '$'); + if (!PrintPreamble(file, &out)) { + return make_pair(false, ""); + } + for (int i = 0; i < file->service_count(); ++i) { + auto service = file->service(i); + if (!(PrintServicer(service, &out) && + PrintServer(service, &out) && + PrintStub(service, &out) && + PrintServerFactory(service, &out) && + PrintStubFactory(service, &out))) { + return make_pair(false, ""); + } + } } - return output; + return make_pair(true, std::move(output)); } } // namespace grpc_python_generator diff --git a/src/compiler/python_generator.h b/src/compiler/python_generator.h index 673ef7b23b3..773dfa3513d 100644 --- a/src/compiler/python_generator.h +++ b/src/compiler/python_generator.h @@ -35,6 +35,7 @@ #define __GRPC_COMPILER_PYTHON_GENERATOR_H__ #include +#include namespace google { namespace protobuf { @@ -44,7 +45,7 @@ class FileDescriptor; namespace grpc_python_generator { -std::string GetServices(const google::protobuf::FileDescriptor* file); +std::pair GetServices(const google::protobuf::FileDescriptor* file); } // namespace grpc_python_generator diff --git a/src/compiler/python_plugin.cc b/src/compiler/python_plugin.cc index 05c6b095d8e..ed1e0494fbe 100644 --- a/src/compiler/python_plugin.cc +++ b/src/compiler/python_plugin.cc @@ -33,6 +33,7 @@ // Generates a Python gRPC service interface out of Protobuf IDL. +#include #include #include @@ -50,6 +51,7 @@ using google::protobuf::compiler::PluginMain; using google::protobuf::io::CodedOutputStream; using google::protobuf::io::ZeroCopyOutputStream; using std::string; +using std::strlen; class PythonGrpcGenerator : public CodeGenerator { public: @@ -62,7 +64,7 @@ class PythonGrpcGenerator : public CodeGenerator { string* error) const override { // Get output file name. string file_name; - static const int proto_suffix_length = 6; // length of ".proto" + static const int proto_suffix_length = strlen(".proto"); if (file->name().size() > static_cast(proto_suffix_length) && file->name().find_last_of(".proto") == file->name().size() - 1) { file_name = file->name().substr( @@ -75,9 +77,15 @@ class PythonGrpcGenerator : public CodeGenerator { std::unique_ptr output( context->OpenForInsert(file_name, "module_scope")); CodedOutputStream coded_out(output.get()); - string code = grpc_python_generator::GetServices(file); - coded_out.WriteRaw(code.data(), code.size()); - return true; + bool success = false; + string code = ""; + tie(success, code) = grpc_python_generator::GetServices(file); + if (success) { + coded_out.WriteRaw(code.data(), code.size()); + return true; + } else { + return false; + } } }; diff --git a/test/compiler/python_plugin_test.py b/test/compiler/python_plugin_test.py index b0c9ec62d07..3919de14509 100644 --- a/test/compiler/python_plugin_test.py +++ b/test/compiler/python_plugin_test.py @@ -40,8 +40,24 @@ import unittest from grpc.framework.face import exceptions from grpc.framework.foundation import future +# Identifiers of entities we expect to find in the generated module. +SERVICER_IDENTIFIER = 'EarlyAdopterTestServiceServicer' +SERVER_IDENTIFIER = 'EarlyAdopterTestServiceServer' +STUB_IDENTIFIER = 'EarlyAdopterTestServiceStub' +SERVER_FACTORY_IDENTIFIER = 'early_adopter_create_TestService_server' +STUB_FACTORY_IDENTIFIER = 'early_adopter_create_TestService_stub' + +# Timeouts and delays. +SHORT_TIMEOUT = 0.1 +NORMAL_TIMEOUT = 1 +LONG_TIMEOUT = 2 +DOES_NOT_MATTER_DELAY = 0 +NO_DELAY = 0 +LONG_DELAY = 1 + # Assigned in __main__. _build_mode = None +_port = None class _ServicerMethods(object): @@ -71,14 +87,14 @@ class _ServicerMethods(object): while self._paused: time.sleep(0) - def UnaryCall(self, request): + def UnaryCall(self, request, context): response = self.test_pb2.SimpleResponse() response.payload.payload_type = self.test_pb2.COMPRESSABLE response.payload.payload_compressable = 'a' * request.response_size self._control() return response - def StreamingOutputCall(self, request): + def StreamingOutputCall(self, request, context): for parameter in request.response_parameters: response = self.test_pb2.StreamingOutputCallResponse() response.payload.payload_type = self.test_pb2.COMPRESSABLE @@ -86,7 +102,7 @@ class _ServicerMethods(object): self._control() yield response - def StreamingInputCall(self, request_iter): + def StreamingInputCall(self, request_iter, context): response = self.test_pb2.StreamingInputCallResponse() aggregated_payload_size = 0 for request in request_iter: @@ -95,7 +111,7 @@ class _ServicerMethods(object): self._control() return response - def FullDuplexCall(self, request_iter): + def FullDuplexCall(self, request_iter, context): for request in request_iter: for parameter in request.response_parameters: response = self.test_pb2.StreamingOutputCallResponse() @@ -104,7 +120,7 @@ class _ServicerMethods(object): self._control() yield response - def HalfDuplexCall(self, request_iter): + def HalfDuplexCall(self, request_iter, context): responses = [] for request in request_iter: for parameter in request.response_parameters: @@ -117,7 +133,7 @@ class _ServicerMethods(object): yield response -def CreateService(test_pb2, delay=0, timeout=1): +def _CreateService(test_pb2, delay): """Provides a servicer backend and a stub. The servicer is just the implementation @@ -136,28 +152,30 @@ def CreateService(test_pb2, delay=0, timeout=1): A two-tuple (servicer, stub), where the servicer is the back-end of the service bound to the stub. """ - class Servicer(test_pb2.TestServiceServicer): + servicer_methods = _ServicerMethods(test_pb2, delay) - def UnaryCall(self, request): - return servicer_methods.UnaryCall(request) + class Servicer(getattr(test_pb2, SERVICER_IDENTIFIER)): - def StreamingOutputCall(self, request): - return servicer_methods.StreamingOutputCall(request) + def UnaryCall(self, request, context): + return servicer_methods.UnaryCall(request, context) - def StreamingInputCall(self, request_iter): - return servicer_methods.StreamingInputCall(request_iter) + def StreamingOutputCall(self, request, context): + return servicer_methods.StreamingOutputCall(request, context) - def FullDuplexCall(self, request_iter): - return servicer_methods.FullDuplexCall(request_iter) + def StreamingInputCall(self, request_iter, context): + return servicer_methods.StreamingInputCall(request_iter, context) - def HalfDuplexCall(self, request_iter): - return servicer_methods.HalfDuplexCall(request_iter) + def FullDuplexCall(self, request_iter, context): + return servicer_methods.FullDuplexCall(request_iter, context) + + def HalfDuplexCall(self, request_iter, context): + return servicer_methods.HalfDuplexCall(request_iter, context) - servicer_methods = _ServicerMethods(test_pb2, delay) servicer = Servicer() - linked_pair = test_pb2.mock_TestService(servicer, timeout) - stub = linked_pair.stub - return servicer_methods, stub + server = getattr(test_pb2, SERVER_FACTORY_IDENTIFIER)(servicer, _port, + None, None) + stub = getattr(test_pb2, STUB_FACTORY_IDENTIFIER)('localhost', _port) + return servicer_methods, stub, server def StreamingInputRequest(test_pb2): @@ -198,19 +216,20 @@ class PythonPluginTest(unittest.TestCase): def setUp(self): protoc_command = '../../bins/%s/protobuf/protoc' % _build_mode protoc_plugin_filename = '../../bins/%s/grpc_python_plugin' % _build_mode - test_proto_filename = '../cpp/interop/test.proto' + test_proto_filename = './test.proto' if not os.path.isfile(protoc_command): # Assume that if we haven't built protoc that it's on the system. protoc_command = 'protoc' - # ensure that the output directory exists - outdir = '../../gens/test/compiler/python/' + # Ensure that the output directory exists. + outdir = '../../gens/test/compiler/python' try: os.makedirs(outdir) except OSError as exception: if exception.errno != errno.EEXIST: raise + # Invoke protoc with the plugin. cmd = [ protoc_command, '--plugin=protoc-gen-python-grpc=%s' % protoc_plugin_filename, @@ -222,215 +241,231 @@ class PythonPluginTest(unittest.TestCase): subprocess.call(' '.join(cmd), shell=True) sys.path.append(outdir) - self.delay = 1 # seconds - self.timeout = 2 # seconds + # TODO(atash): Figure out which of theses tests is hanging flakily with small + # probability. def testImportAttributes(self): - # check that we can access the members + # check that we can access the generated module and its members. import test_pb2 # pylint: disable=g-import-not-at-top - self.assertIsNotNone(getattr(test_pb2, 'TestServiceServicer', None)) - self.assertIsNotNone(getattr(test_pb2, 'TestServiceService', None)) - self.assertIsNotNone(getattr(test_pb2, 'TestServiceStub', None)) + self.assertIsNotNone(getattr(test_pb2, SERVICER_IDENTIFIER, None)) + self.assertIsNotNone(getattr(test_pb2, SERVER_IDENTIFIER, None)) + self.assertIsNotNone(getattr(test_pb2, STUB_IDENTIFIER, None)) + self.assertIsNotNone(getattr(test_pb2, SERVER_FACTORY_IDENTIFIER, None)) + self.assertIsNotNone(getattr(test_pb2, STUB_FACTORY_IDENTIFIER, None)) + + def testUpDown(self): + import test_pb2 + servicer, stub, server = _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) + request = test_pb2.SimpleRequest(response_size=13) + with server, stub: + pass def testUnaryCall(self): import test_pb2 # pylint: disable=g-import-not-at-top - servicer, stub = CreateService(test_pb2) + servicer, stub, server = _CreateService(test_pb2, NO_DELAY) request = test_pb2.SimpleRequest(response_size=13) - response = stub.UnaryCall(request) - expected_response = servicer.UnaryCall(request) + with server, stub: + response = stub.UnaryCall(request, NORMAL_TIMEOUT) + expected_response = servicer.UnaryCall(request, None) self.assertEqual(expected_response, response) def testUnaryCallAsync(self): import test_pb2 # pylint: disable=g-import-not-at-top - servicer, stub = CreateService( - test_pb2, delay=self.delay, timeout=self.timeout) + servicer, stub, server = _CreateService(test_pb2, LONG_DELAY) request = test_pb2.SimpleRequest(response_size=13) - # TODO(atash): consider using the 'profile' module? Does it even work here? - start_time = time.clock() - response_future = stub.UnaryCall.async(request) - self.assertGreater(self.delay, time.clock() - start_time) - response = response_future.result() - expected_response = servicer.UnaryCall(request) + with server, stub: + start_time = time.clock() + response_future = stub.UnaryCall.async(request, LONG_TIMEOUT) + # Check that we didn't block on the asynchronous call. + self.assertGreater(LONG_DELAY, time.clock() - start_time) + response = response_future.result() + expected_response = servicer.UnaryCall(request, None) self.assertEqual(expected_response, response) def testUnaryCallAsyncExpired(self): import test_pb2 # pylint: disable=g-import-not-at-top # set the timeout super low... - servicer, stub = CreateService(test_pb2, delay=1, timeout=0.1) + servicer, stub, server = _CreateService(test_pb2, + delay=DOES_NOT_MATTER_DELAY) request = test_pb2.SimpleRequest(response_size=13) - with servicer.pause(): - response_future = stub.UnaryCall.async(request) - with self.assertRaises(exceptions.ExpirationError): - response_future.result() + with server, stub: + with servicer.pause(): + response_future = stub.UnaryCall.async(request, SHORT_TIMEOUT) + with self.assertRaises(exceptions.ExpirationError): + response_future.result() def testUnaryCallAsyncCancelled(self): import test_pb2 # pylint: disable=g-import-not-at-top - servicer, stub = CreateService(test_pb2) + servicer, stub, server = _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) request = test_pb2.SimpleRequest(response_size=13) - with servicer.pause(): - response_future = stub.UnaryCall.async(request) - response_future.cancel() - self.assertTrue(response_future.cancelled()) + with server, stub: + with servicer.pause(): + response_future = stub.UnaryCall.async(request, 1) + response_future.cancel() + self.assertTrue(response_future.cancelled()) def testUnaryCallAsyncFailed(self): import test_pb2 # pylint: disable=g-import-not-at-top - servicer, stub = CreateService(test_pb2) + servicer, stub, server = _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) request = test_pb2.SimpleRequest(response_size=13) - with servicer.fail(): - response_future = stub.UnaryCall.async(request) - self.assertIsNotNone(response_future.exception()) + with server, stub: + with servicer.fail(): + response_future = stub.UnaryCall.async(request, NORMAL_TIMEOUT) + self.assertIsNotNone(response_future.exception()) def testStreamingOutputCall(self): import test_pb2 # pylint: disable=g-import-not-at-top - servicer, stub = CreateService(test_pb2) + servicer, stub, server = _CreateService(test_pb2, NO_DELAY) request = StreamingOutputRequest(test_pb2) - responses = stub.StreamingOutputCall(request) - expected_responses = servicer.StreamingOutputCall(request) - for check in itertools.izip_longest(expected_responses, responses): - expected_response, response = check - self.assertEqual(expected_response, response) - - def testStreamingOutputCallAsync(self): - import test_pb2 # pylint: disable=g-import-not-at-top - servicer, stub = CreateService(test_pb2, timeout=self.timeout) - request = StreamingOutputRequest(test_pb2) - responses = stub.StreamingOutputCall.async(request) - expected_responses = servicer.StreamingOutputCall(request) - for check in itertools.izip_longest(expected_responses, responses): - expected_response, response = check - self.assertEqual(expected_response, response) - - def testStreamingOutputCallAsyncExpired(self): + with server, stub: + responses = stub.StreamingOutputCall(request, NORMAL_TIMEOUT) + expected_responses = servicer.StreamingOutputCall(request, None) + for check in itertools.izip_longest(expected_responses, responses): + expected_response, response = check + self.assertEqual(expected_response, response) + + def testStreamingOutputCallExpired(self): import test_pb2 # pylint: disable=g-import-not-at-top - servicer, stub = CreateService(test_pb2, timeout=0.1) + servicer, stub, server = _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) request = StreamingOutputRequest(test_pb2) - with servicer.pause(): - responses = stub.StreamingOutputCall.async(request) - with self.assertRaises(exceptions.ExpirationError): - list(responses) + with server, stub: + with servicer.pause(): + responses = stub.StreamingOutputCall(request, SHORT_TIMEOUT) + with self.assertRaises(exceptions.ExpirationError): + list(responses) - def testStreamingOutputCallAsyncCancelled(self): + def testStreamingOutputCallCancelled(self): import test_pb2 # pylint: disable=g-import-not-at-top - _, stub = CreateService(test_pb2, timeout=0.1) + unused_servicer, stub, server = _CreateService(test_pb2, + DOES_NOT_MATTER_DELAY) request = StreamingOutputRequest(test_pb2) - responses = stub.StreamingOutputCall.async(request) - next(responses) - responses.cancel() - with self.assertRaises(future.CancelledError): + with server, stub: + responses = stub.StreamingOutputCall(request, SHORT_TIMEOUT) next(responses) + responses.cancel() + with self.assertRaises(future.CancelledError): + next(responses) - def testStreamingOutputCallAsyncFailed(self): + @unittest.skip('TODO(atash,nathaniel): figure out why this times out ' + 'instead of raising the proper error.') + def testStreamingOutputCallFailed(self): import test_pb2 # pylint: disable=g-import-not-at-top - servicer, stub = CreateService(test_pb2, timeout=0.1) + servicer, stub, server = _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) request = StreamingOutputRequest(test_pb2) - with servicer.fail(): - responses = stub.StreamingOutputCall.async(request) - self.assertIsNotNone(responses) - with self.assertRaises(exceptions.ServicerError): - next(responses) + with server, stub: + with servicer.fail(): + responses = stub.StreamingOutputCall(request, 1) + self.assertIsNotNone(responses) + with self.assertRaises(exceptions.ServicerError): + next(responses) def testStreamingInputCall(self): import test_pb2 # pylint: disable=g-import-not-at-top - servicer, stub = CreateService(test_pb2) - response = stub.StreamingInputCall(StreamingInputRequest(test_pb2)) + servicer, stub, server = _CreateService(test_pb2, NO_DELAY) + with server, stub: + response = stub.StreamingInputCall(StreamingInputRequest(test_pb2), + NORMAL_TIMEOUT) expected_response = servicer.StreamingInputCall( - StreamingInputRequest(test_pb2)) + StreamingInputRequest(test_pb2), None) self.assertEqual(expected_response, response) def testStreamingInputCallAsync(self): import test_pb2 # pylint: disable=g-import-not-at-top - servicer, stub = CreateService( - test_pb2, delay=self.delay, timeout=self.timeout) - start_time = time.clock() - response_future = stub.StreamingInputCall.async( - StreamingInputRequest(test_pb2)) - self.assertGreater(self.delay, time.clock() - start_time) - response = response_future.result() + servicer, stub, server = _CreateService( + test_pb2, LONG_DELAY) + with server, stub: + start_time = time.clock() + response_future = stub.StreamingInputCall.async( + StreamingInputRequest(test_pb2), LONG_TIMEOUT) + self.assertGreater(LONG_DELAY, time.clock() - start_time) + response = response_future.result() expected_response = servicer.StreamingInputCall( - StreamingInputRequest(test_pb2)) + StreamingInputRequest(test_pb2), None) self.assertEqual(expected_response, response) def testStreamingInputCallAsyncExpired(self): import test_pb2 # pylint: disable=g-import-not-at-top # set the timeout super low... - servicer, stub = CreateService(test_pb2, delay=1, timeout=0.1) - with servicer.pause(): - response_future = stub.StreamingInputCall.async( - StreamingInputRequest(test_pb2)) - with self.assertRaises(exceptions.ExpirationError): - response_future.result() - self.assertIsInstance( - response_future.exception(), exceptions.ExpirationError) + servicer, stub, server = _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) + with server, stub: + with servicer.pause(): + response_future = stub.StreamingInputCall.async( + StreamingInputRequest(test_pb2), SHORT_TIMEOUT) + with self.assertRaises(exceptions.ExpirationError): + response_future.result() + self.assertIsInstance( + response_future.exception(), exceptions.ExpirationError) def testStreamingInputCallAsyncCancelled(self): import test_pb2 # pylint: disable=g-import-not-at-top - servicer, stub = CreateService(test_pb2) - with servicer.pause(): - response_future = stub.StreamingInputCall.async( - StreamingInputRequest(test_pb2)) - response_future.cancel() - self.assertTrue(response_future.cancelled()) - with self.assertRaises(future.CancelledError): - response_future.result() + servicer, stub, server = _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) + with server, stub: + with servicer.pause(): + response_future = stub.StreamingInputCall.async( + StreamingInputRequest(test_pb2), NORMAL_TIMEOUT) + response_future.cancel() + self.assertTrue(response_future.cancelled()) + with self.assertRaises(future.CancelledError): + response_future.result() def testStreamingInputCallAsyncFailed(self): import test_pb2 # pylint: disable=g-import-not-at-top - servicer, stub = CreateService(test_pb2) - with servicer.fail(): - response_future = stub.StreamingInputCall.async( - StreamingInputRequest(test_pb2)) - self.assertIsNotNone(response_future.exception()) + servicer, stub, server = _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) + with server, stub: + with servicer.fail(): + response_future = stub.StreamingInputCall.async( + StreamingInputRequest(test_pb2), SHORT_TIMEOUT) + self.assertIsNotNone(response_future.exception()) def testFullDuplexCall(self): import test_pb2 # pylint: disable=g-import-not-at-top - servicer, stub = CreateService(test_pb2) - responses = stub.FullDuplexCall(FullDuplexRequest(test_pb2)) - expected_responses = servicer.FullDuplexCall(FullDuplexRequest(test_pb2)) - for check in itertools.izip_longest(expected_responses, responses): - expected_response, response = check - self.assertEqual(expected_response, response) - - def testFullDuplexCallAsync(self): + servicer, stub, server = _CreateService(test_pb2, NO_DELAY) + with server, stub: + responses = stub.FullDuplexCall(FullDuplexRequest(test_pb2), + NORMAL_TIMEOUT) + expected_responses = servicer.FullDuplexCall(FullDuplexRequest(test_pb2), + None) + for check in itertools.izip_longest(expected_responses, responses): + expected_response, response = check + self.assertEqual(expected_response, response) + + def testFullDuplexCallExpired(self): import test_pb2 # pylint: disable=g-import-not-at-top - servicer, stub = CreateService(test_pb2, timeout=self.timeout) - responses = stub.FullDuplexCall.async(FullDuplexRequest(test_pb2)) - expected_responses = servicer.FullDuplexCall(FullDuplexRequest(test_pb2)) - for check in itertools.izip_longest(expected_responses, responses): - expected_response, response = check - self.assertEqual(expected_response, response) - - def testFullDuplexCallAsyncExpired(self): - import test_pb2 # pylint: disable=g-import-not-at-top - servicer, stub = CreateService(test_pb2, timeout=0.1) + servicer, stub, server = _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) request = FullDuplexRequest(test_pb2) - with servicer.pause(): - responses = stub.FullDuplexCall.async(request) - with self.assertRaises(exceptions.ExpirationError): - list(responses) + with server, stub: + with servicer.pause(): + responses = stub.FullDuplexCall(request, SHORT_TIMEOUT) + with self.assertRaises(exceptions.ExpirationError): + list(responses) - def testFullDuplexCallAsyncCancelled(self): + def testFullDuplexCallCancelled(self): import test_pb2 # pylint: disable=g-import-not-at-top - _, stub = CreateService(test_pb2, timeout=0.1) - request = FullDuplexRequest(test_pb2) - responses = stub.FullDuplexCall.async(request) - next(responses) - responses.cancel() - with self.assertRaises(future.CancelledError): + unused_servicer, stub, server = _CreateService(test_pb2, NO_DELAY) + with server, stub: + request = FullDuplexRequest(test_pb2) + responses = stub.FullDuplexCall(request, NORMAL_TIMEOUT) next(responses) + responses.cancel() + with self.assertRaises(future.CancelledError): + next(responses) - def testFullDuplexCallAsyncFailed(self): + @unittest.skip('TODO(atash,nathaniel): figure out why this hangs forever ' + 'and fix.') + def testFullDuplexCallFailed(self): import test_pb2 # pylint: disable=g-import-not-at-top - servicer, stub = CreateService(test_pb2, timeout=0.1) + servicer, stub, server = _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) request = FullDuplexRequest(test_pb2) - with servicer.fail(): - responses = stub.FullDuplexCall.async(request) - self.assertIsNotNone(responses) - with self.assertRaises(exceptions.ServicerError): - next(responses) + with server, stub: + with servicer.fail(): + responses = stub.FullDuplexCall(request, NORMAL_TIMEOUT) + self.assertIsNotNone(responses) + with self.assertRaises(exceptions.ServicerError): + next(responses) def testHalfDuplexCall(self): import test_pb2 # pylint: disable=g-import-not-at-top - servicer, stub = CreateService(test_pb2) + servicer, stub, server = _CreateService(test_pb2, NO_DELAY) def HalfDuplexRequest(): request = test_pb2.StreamingOutputCallRequest() request.response_parameters.add(size=1, interval_us=0) @@ -439,15 +474,16 @@ class PythonPluginTest(unittest.TestCase): request.response_parameters.add(size=2, interval_us=0) request.response_parameters.add(size=3, interval_us=0) yield request - responses = stub.HalfDuplexCall(HalfDuplexRequest()) - expected_responses = servicer.HalfDuplexCall(HalfDuplexRequest()) - for check in itertools.izip_longest(expected_responses, responses): - expected_response, response = check - self.assertEqual(expected_response, response) - - def testHalfDuplexCallAsyncWedged(self): + with server, stub: + responses = stub.HalfDuplexCall(HalfDuplexRequest(), NORMAL_TIMEOUT) + expected_responses = servicer.HalfDuplexCall(HalfDuplexRequest(), None) + for check in itertools.izip_longest(expected_responses, responses): + expected_response, response = check + self.assertEqual(expected_response, response) + + def testHalfDuplexCallWedged(self): import test_pb2 # pylint: disable=g-import-not-at-top - _, stub = CreateService(test_pb2, timeout=1) + _, stub, server = _CreateService(test_pb2, NO_DELAY) wait_flag = [False] @contextlib.contextmanager def wait(): # pylint: disable=invalid-name @@ -461,20 +497,25 @@ class PythonPluginTest(unittest.TestCase): yield request while wait_flag[0]: time.sleep(0.1) - with wait(): - responses = stub.HalfDuplexCall.async(HalfDuplexRequest()) - # half-duplex waits for the client to send all info - with self.assertRaises(exceptions.ExpirationError): - next(responses) + with server, stub: + with wait(): + responses = stub.HalfDuplexCall(HalfDuplexRequest(), NORMAL_TIMEOUT) + # half-duplex waits for the client to send all info + with self.assertRaises(exceptions.ExpirationError): + next(responses) if __name__ == '__main__': os.chdir(os.path.dirname(sys.argv[0])) - parser = argparse.ArgumentParser(description='Run Python compiler plugin test.') - parser.add_argument('--build_mode', dest='build_mode', type=str, default='dbg', - help='The build mode of the targets to test, e.g. ' - '"dbg", "opt", "asan", etc.') + parser = argparse.ArgumentParser( + description='Run Python compiler plugin test.') + parser.add_argument( + '--build_mode', dest='build_mode', type=str, default='dbg', + help='The build mode of the targets to test, e.g. "dbg", "opt", "asan", ' + 'etc.') + parser.add_argument('--port', dest='port', type=int, default=0) args, remainder = parser.parse_known_args() _build_mode = args.build_mode + _port = args.port sys.argv[1:] = remainder unittest.main() diff --git a/test/compiler/test.proto b/test/compiler/test.proto index ed7c6a7b797..1714de7c11b 100644 --- a/test/compiler/test.proto +++ b/test/compiler/test.proto @@ -32,7 +32,8 @@ // This file is duplicated around the code base. See GitHub issue #526. syntax = "proto2"; -package grpc.testing; +// TODO(atash): Investigate this statement's utility. +// package grpc.testing; enum PayloadType { // Compressable text format. diff --git a/tools/run_tests/run_python.sh b/tools/run_tests/run_python.sh index fe40b511860..2475c37b0bc 100755 --- a/tools/run_tests/run_python.sh +++ b/tools/run_tests/run_python.sh @@ -37,7 +37,8 @@ root=`pwd` export LD_LIBRARY_PATH=$root/libs/opt source python2.7_virtual_environment/bin/activate # TODO(issue 215): Properly itemize these in run_tests.py so that they can be parallelized. -python2.7 -B test/compiler/python_plugin_test.py +# TODO(atash): Enable dynamic unused port discovery for this test. +python2.7 -B test/compiler/python_plugin_test.py --build_mode=opt --port=40987 python2.7 -B -m grpc._adapter._blocking_invocation_inline_service_test python2.7 -B -m grpc._adapter._c_test python2.7 -B -m grpc._adapter._event_invocation_synchronous_event_service_test From 5d9f62a49a59fa4103e5eadd1729c722d5ad7784 Mon Sep 17 00:00:00 2001 From: Donna Dionne Date: Tue, 24 Feb 2015 19:15:51 -0800 Subject: [PATCH 18/75] Adding auth test into suite to be run automatically Temporarly taking out time out as it is not working properly on gcloud command Restore a flag incorrectly removed earlier --- tools/gce_setup/cloud_prod_runner.sh | 13 +++++++++++++ tools/gce_setup/grpc_docker.sh | 26 ++++---------------------- 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/tools/gce_setup/cloud_prod_runner.sh b/tools/gce_setup/cloud_prod_runner.sh index 52e9b5e2a32..4732f952c26 100755 --- a/tools/gce_setup/cloud_prod_runner.sh +++ b/tools/gce_setup/cloud_prod_runner.sh @@ -32,6 +32,7 @@ main() { source grpc_docker.sh test_cases=(large_unary empty_unary ping_pong client_streaming server_streaming service_account_creds compute_engine_creds) + auth_test_cases=(service_account_creds compute_engine_creds) clients=(cxx java go ruby node) for test_case in "${test_cases[@]}" do @@ -45,6 +46,18 @@ main() { fi done done + for test_case in "${auth_test_cases[@]}" + do + for client in "${clients[@]}" + do + if grpc_cloud_prod_auth_test $test_case grpc-docker-testclients $client + then + echo "$test_case $client $server passed" >> /tmp/cloud_prod_result.txt + else + echo "$test_case $client $server failed" >> /tmp/cloud_prod_result.txt + fi + done + done gsutil cp /tmp/cloud_prod_result.txt gs://stoked-keyword-656-output/cloud_prod_result.txt rm /tmp/cloud_prod_result.txt } diff --git a/tools/gce_setup/grpc_docker.sh b/tools/gce_setup/grpc_docker.sh index 6fff057c832..231625efb3a 100755 --- a/tools/gce_setup/grpc_docker.sh +++ b/tools/gce_setup/grpc_docker.sh @@ -350,7 +350,7 @@ grpc_interop_test_flags() { echo "$FUNCNAME: missing arg: test_case" 1>&2 return 1 } - echo "--server_host=$server_ip --server_port=$port --test_case=$test_case" + echo "--server_host_override=foo.test.google.fr --server_host=$server_ip --server_port=$port --test_case=$test_case" } # checks the positional args and assigns them to variables visible in the caller @@ -673,7 +673,7 @@ _grpc_launch_servers_args() { [[ -n $1 ]] && { servers="$@" } || { - servers="cxx java go node ruby" + servers="cxx java go node ruby python" echo "$FUNCNAME: no servers specified, will launch defaults '$servers'" } } @@ -795,16 +795,7 @@ grpc_interop_test() { echo " $ssh_cmd" echo "on $host" [[ $dry_run == 1 ]] && return 0 # don't run the command on a dry run - gcloud compute $project_opt ssh $zone_opt $host --command "$cmd" & - PID=$! - sleep 10 - echo "pid is $PID" - if ps -p $PID - then - kill $PID - return 1 - fi - + gcloud compute $project_opt ssh $zone_opt $host --command "$cmd" } # Runs a test command on a docker instance. @@ -850,16 +841,7 @@ grpc_cloud_prod_test() { echo " $ssh_cmd" echo "on $host" [[ $dry_run == 1 ]] && return 0 # don't run the command on a dry run - gcloud compute $project_opt ssh $zone_opt $host --command "$cmd" & - PID=$! - sleep 10 - echo "pid is $PID" - if ps -p $PID - then - kill $PID - return 1 - fi - + gcloud compute $project_opt ssh $zone_opt $host --command "$cmd" } # Runs a test command on a docker instance. From 7fa3f41226df76895e5eb6a512d7017a502bd9dc Mon Sep 17 00:00:00 2001 From: Julien Boeuf Date: Tue, 24 Feb 2015 19:30:41 -0800 Subject: [PATCH 19/75] Removing port from checked ssl target name. - Should fix #746. --- src/core/security/security_context.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/core/security/security_context.c b/src/core/security/security_context.c index 9dce5af7400..3629f0499da 100644 --- a/src/core/security/security_context.c +++ b/src/core/security/security_context.c @@ -44,7 +44,9 @@ #include "src/core/support/string.h" #include "src/core/surface/lame_client.h" #include "src/core/transport/chttp2/alpn.h" + #include +#include #include #include #include "src/core/tsi/fake_transport_security.h" @@ -443,6 +445,7 @@ grpc_security_status grpc_ssl_channel_security_context_create( size_t i; const unsigned char *pem_root_certs; size_t pem_root_certs_size; + char *port; for (i = 0; i < num_alpn_protocols; i++) { alpn_protocol_strings[i] = @@ -468,9 +471,8 @@ grpc_security_status grpc_ssl_channel_security_context_create( c->base.base.url_scheme = GRPC_SSL_URL_SCHEME; c->base.request_metadata_creds = grpc_credentials_ref(request_metadata_creds); c->base.check_call_host = ssl_channel_check_call_host; - if (target_name != NULL) { - c->target_name = gpr_strdup(target_name); - } + gpr_split_host_port(target_name, &c->target_name, &port); + gpr_free(port); if (overridden_target_name != NULL) { c->overridden_target_name = gpr_strdup(overridden_target_name); } From 8d6ec91241743d121d5540cb9e389de048690415 Mon Sep 17 00:00:00 2001 From: Julien Boeuf Date: Tue, 24 Feb 2015 20:07:59 -0800 Subject: [PATCH 20/75] Using HTTP2 compliant cipher suites by default. - Added a way to override the cipher suites with an environment variable so that we can still do interop testing with java7. - Takes care of #681. --- src/core/security/security_context.c | 33 +++++++++++++++++++--------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/src/core/security/security_context.c b/src/core/security/security_context.c index 9dce5af7400..eb1dd1cc4a4 100644 --- a/src/core/security/security_context.c +++ b/src/core/security/security_context.c @@ -52,20 +52,33 @@ /* -- Constants. -- */ -/* Defines the cipher suites that we accept. All these cipher suites are - compliant with TLS 1.2 and use an RSA public key. We prefer GCM over CBC - and ECDHE-RSA over just RSA. */ -#define GRPC_SSL_CIPHER_SUITES \ - "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:AES128-GCM-SHA256:" \ - "AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384:AES128-" \ - "SHA256:AES256-SHA256" - #ifndef INSTALL_PREFIX static const char *installed_roots_path = "/usr/share/grpc/roots.pem"; #else static const char *installed_roots_path = INSTALL_PREFIX "/share/grpc/roots.pem"; #endif +/* -- Cipher suites. -- */ + +/* Defines the cipher suites that we accept by default. All these cipher suites + are compliant with HTTP2. */ +#define GRPC_SSL_CIPHER_SUITES \ + "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:AES128-GCM-SHA256:" \ + "AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384" + +static gpr_once cipher_suites_once = GPR_ONCE_INIT; +static const char *cipher_suites = NULL; + +static void init_cipher_suites(void) { + char *overridden = gpr_getenv("GRPC_SSL_CIPHER_SUITES"); + cipher_suites = overridden != NULL ? overridden : GRPC_SSL_CIPHER_SUITES; +} + +static const char *ssl_cipher_suites(void) { + gpr_once_init(&cipher_suites_once, init_cipher_suites); + return cipher_suites; +} + /* -- Common methods. -- */ grpc_security_status grpc_security_context_create_handshaker( @@ -487,7 +500,7 @@ grpc_security_status grpc_ssl_channel_security_context_create( result = tsi_create_ssl_client_handshaker_factory( config->pem_private_key, config->pem_private_key_size, config->pem_cert_chain, config->pem_cert_chain_size, pem_root_certs, - pem_root_certs_size, GRPC_SSL_CIPHER_SUITES, alpn_protocol_strings, + pem_root_certs_size, ssl_cipher_suites(), alpn_protocol_strings, alpn_protocol_string_lengths, num_alpn_protocols, &c->handshaker_factory); if (result != TSI_OK) { gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", @@ -541,7 +554,7 @@ grpc_security_status grpc_ssl_server_security_context_create( (const unsigned char **)config->pem_cert_chains, config->pem_cert_chains_sizes, config->num_key_cert_pairs, config->pem_root_certs, config->pem_root_certs_size, - GRPC_SSL_CIPHER_SUITES, alpn_protocol_strings, + ssl_cipher_suites(), alpn_protocol_strings, alpn_protocol_string_lengths, num_alpn_protocols, &c->handshaker_factory); if (result != TSI_OK) { gpr_log(GPR_ERROR, "Handshaker factory creation failed with %s.", From fc975090b5c8d6577eec9769665265fb4b33adf1 Mon Sep 17 00:00:00 2001 From: Donna Dionne Date: Tue, 24 Feb 2015 20:39:31 -0800 Subject: [PATCH 21/75] Fixing go commands Fixing test names --- tools/gce_setup/cloud_prod_runner.sh | 2 +- tools/gce_setup/grpc_docker.sh | 9 ++++++--- tools/gce_setup/interop_test_runner.sh | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/tools/gce_setup/cloud_prod_runner.sh b/tools/gce_setup/cloud_prod_runner.sh index 4732f952c26..e11185c226b 100755 --- a/tools/gce_setup/cloud_prod_runner.sh +++ b/tools/gce_setup/cloud_prod_runner.sh @@ -31,7 +31,7 @@ main() { source grpc_docker.sh - test_cases=(large_unary empty_unary ping_pong client_streaming server_streaming service_account_creds compute_engine_creds) + test_cases=(large_unary empty_unary ping_pong client_streaming server_streaming cancel_after_begin cancel_after_first_response) auth_test_cases=(service_account_creds compute_engine_creds) clients=(cxx java go ruby node) for test_case in "${test_cases[@]}" diff --git a/tools/gce_setup/grpc_docker.sh b/tools/gce_setup/grpc_docker.sh index 231625efb3a..5bb42b19994 100755 --- a/tools/gce_setup/grpc_docker.sh +++ b/tools/gce_setup/grpc_docker.sh @@ -926,7 +926,8 @@ grpc_cloud_prod_auth_service_account_creds_gen_go_cmd() { local cmd_prefix="sudo docker run grpc/go /bin/bash -c" local test_script="cd src/google.golang.org/grpc/interop/client" local test_script+=" && go run client.go --use_tls=true" - local gfe_flags=" --tls_ca_file=\"\" --tls_server_name=\"\" --server_port=443 --server_host=grpc-test.sandbox.google.com" + local gfe_flags=$(_grpc_prod_gfe_flags) + local gfe_flags+=" --tls_ca_file=\"\"" local added_gfe_flags=$(_grpc_svc_acc_test_flags) local the_cmd="$cmd_prefix '$test_script $gfe_flags $added_gfe_flags $@'" echo $the_cmd @@ -941,7 +942,8 @@ grpc_cloud_prod_auth_compute_engine_creds_gen_go_cmd() { local cmd_prefix="sudo docker run grpc/go /bin/bash -c" local test_script="cd src/google.golang.org/grpc/interop/client" local test_script+=" && go run client.go --use_tls=true" - local gfe_flags=" --tls_ca_file=\"\" --tls_server_name=\"\" --server_port=443 --server_host=grpc-test.sandbox.google.com" + local gfe_flags=$(_grpc_prod_gfe_flags) + local gfe_flags+=" --tls_ca_file=\"\"" local added_gfe_flags=$(_grpc_gce_test_flags) local the_cmd="$cmd_prefix '$test_script $gfe_flags $added_gfe_flags $@'" echo $the_cmd @@ -1001,7 +1003,8 @@ grpc_cloud_prod_gen_go_cmd() { local cmd_prefix="sudo docker run grpc/go /bin/bash -c" local test_script="cd src/google.golang.org/grpc/interop/client" local test_script+=" && go run client.go --use_tls=true" - local gfe_flags=" --tls_ca_file=\"\" --tls_server_name=\"\" --server_port=443 --server_host=grpc-test.sandbox.google.com" + local gfe_flags=$(_grpc_prod_gfe_flags) + local gfe_flags+=" --tls_ca_file=\"\"" local the_cmd="$cmd_prefix '$test_script $gfe_flags $@'" echo $the_cmd } diff --git a/tools/gce_setup/interop_test_runner.sh b/tools/gce_setup/interop_test_runner.sh index 465c2ab6a78..5f8c0e70645 100755 --- a/tools/gce_setup/interop_test_runner.sh +++ b/tools/gce_setup/interop_test_runner.sh @@ -35,7 +35,7 @@ echo $result_file_name main() { source grpc_docker.sh - test_cases=(large_unary empty_unary ping_pong client_streaming server_streaming cancel_after_being cancel_after_first_response) + test_cases=(large_unary empty_unary ping_pong client_streaming server_streaming cancel_after_begin cancel_after_first_response) clients=(cxx java go ruby node) servers=(cxx java go ruby node python) for test_case in "${test_cases[@]}" From d43f0c371387d2f667cf14f78caadad5701d25c5 Mon Sep 17 00:00:00 2001 From: Julien Boeuf Date: Tue, 24 Feb 2015 20:54:12 -0800 Subject: [PATCH 22/75] Addressing comments. --- src/core/security/security_context.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/security/security_context.c b/src/core/security/security_context.c index eb1dd1cc4a4..c4fdc2b9400 100644 --- a/src/core/security/security_context.c +++ b/src/core/security/security_context.c @@ -62,9 +62,9 @@ static const char *installed_roots_path = INSTALL_PREFIX "/share/grpc/roots.pem" /* Defines the cipher suites that we accept by default. All these cipher suites are compliant with HTTP2. */ -#define GRPC_SSL_CIPHER_SUITES \ - "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:AES128-GCM-SHA256:" \ - "AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384" +#define GRPC_SSL_CIPHER_SUITES \ + "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-" \ + "SHA384:ECDHE-RSA-AES256-GCM-SHA384" static gpr_once cipher_suites_once = GPR_ONCE_INIT; static const char *cipher_suites = NULL; From b5a79f62dec25afb34b16ff40e40c6f92d20ec65 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 24 Feb 2015 21:02:51 -0800 Subject: [PATCH 23/75] Fix mac build --- src/core/support/cpu_posix.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/support/cpu_posix.c b/src/core/support/cpu_posix.c index 33c7b90b0b2..5f45fb0bc36 100644 --- a/src/core/support/cpu_posix.c +++ b/src/core/support/cpu_posix.c @@ -40,6 +40,7 @@ #include #include +#include static __thread char magic_thread_local; @@ -55,7 +56,7 @@ static void init_ncpus() { unsigned gpr_cpu_num_cores(void) { static gpr_once once = GPR_ONCE_INIT; - gpr_once_init(&once, init_num_cpus); + gpr_once_init(&once, init_ncpus); return ncpus; } From d1345ded70c390f4287072b2ec82a890bb980312 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 24 Feb 2015 21:55:20 -0800 Subject: [PATCH 24/75] Fix shutdown race in CHTTP2 After we have called closed() ensure that no other callbacks are ever made. --- src/core/transport/chttp2_transport.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/core/transport/chttp2_transport.c b/src/core/transport/chttp2_transport.c index ccd8d0c3764..f8b1db8d25d 100644 --- a/src/core/transport/chttp2_transport.c +++ b/src/core/transport/chttp2_transport.c @@ -301,7 +301,7 @@ static void push_setting(transport *t, grpc_chttp2_setting_id id, gpr_uint32 value); static int prepare_callbacks(transport *t); -static void run_callbacks(transport *t); +static void run_callbacks(transport *t, const grpc_transport_callbacks *cb); static int prepare_write(transport *t); static void perform_write(transport *t, grpc_endpoint *ep); @@ -706,6 +706,7 @@ static void unlock(transport *t) { pending_goaway *goaways = NULL; grpc_endpoint *ep = t->ep; grpc_stream_op_buffer nuke_now; + const grpc_transport_callbacks *cb = t->cb; grpc_sopb_init(&nuke_now); if (t->nuke_later_sopb.nops) { @@ -725,7 +726,7 @@ static void unlock(transport *t) { } /* gather any callbacks that need to be made */ - if (!t->calling_back && t->cb) { + if (!t->calling_back && cb) { perform_callbacks = prepare_callbacks(t); if (perform_callbacks) { t->calling_back = 1; @@ -733,6 +734,7 @@ static void unlock(transport *t) { if (t->error_state == ERROR_STATE_SEEN) { call_closed = 1; t->calling_back = 1; + t->cb = NULL; /* no more callbacks */ t->error_state = ERROR_STATE_NOTIFIED; } if (t->num_pending_goaways) { @@ -754,16 +756,16 @@ static void unlock(transport *t) { /* perform some callbacks if necessary */ for (i = 0; i < num_goaways; i++) { - t->cb->goaway(t->cb_user_data, &t->base, goaways[i].status, - goaways[i].debug); + cb->goaway(t->cb_user_data, &t->base, goaways[i].status, + goaways[i].debug); } if (perform_callbacks) { - run_callbacks(t); + run_callbacks(t, cb); } if (call_closed) { - t->cb->closed(t->cb_user_data, &t->base); + cb->closed(t->cb_user_data, &t->base); } /* write some bytes if necessary */ @@ -1741,13 +1743,13 @@ static int prepare_callbacks(transport *t) { return n; } -static void run_callbacks(transport *t) { +static void run_callbacks(transport *t, const grpc_transport_callbacks *cb) { stream *s; while ((s = stream_list_remove_head(t, EXECUTING_CALLBACKS))) { size_t nops = s->callback_sopb.nops; s->callback_sopb.nops = 0; - t->cb->recv_batch(t->cb_user_data, &t->base, (grpc_stream *)s, - s->callback_sopb.ops, nops, s->callback_state); + cb->recv_batch(t->cb_user_data, &t->base, (grpc_stream *)s, + s->callback_sopb.ops, nops, s->callback_state); } } From cc1150f49f7374a76f2e29b9ab4fa4bc15fe02f1 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Tue, 24 Feb 2015 21:26:21 -0800 Subject: [PATCH 25/75] Adds a reference to GoogleAuth --- src/ruby/grpc.gemspec | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ruby/grpc.gemspec b/src/ruby/grpc.gemspec index bc59c234e5a..25a3ff5ce27 100755 --- a/src/ruby/grpc.gemspec +++ b/src/ruby/grpc.gemspec @@ -22,6 +22,7 @@ Gem::Specification.new do |s| s.add_dependency 'faraday', '~> 0.9' s.add_dependency 'google-protobuf', '~> 3.0.0alpha.1.1' + s.add_dependency 'googleauth', '~> 0.1' s.add_dependency 'logging', '~> 1.8' s.add_dependency 'jwt', '~> 1.2.1' s.add_dependency 'minitest', '~> 5.4' # reqd for interop tests From b44da465d6cc2488e7919358d0a7c3d08b964736 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Tue, 24 Feb 2015 21:29:11 -0800 Subject: [PATCH 26/75] Updates the interop client to use the new auth library --- src/ruby/bin/interop/interop_client.rb | 31 +++++++------------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/src/ruby/bin/interop/interop_client.rb b/src/ruby/bin/interop/interop_client.rb index 76402b7c894..4e60ca0b71d 100755 --- a/src/ruby/bin/interop/interop_client.rb +++ b/src/ruby/bin/interop/interop_client.rb @@ -48,6 +48,7 @@ require 'minitest' require 'minitest/assertions' require 'grpc' +require 'googleauth' require 'google/protobuf' require 'test/cpp/interop/test_services' @@ -56,7 +57,7 @@ require 'test/cpp/interop/empty' require 'signet/ssl_config' -include GRPC::Auth +AUTH_ENV = Google::Auth::ServiceAccountCredentials::ENV_VAR # loads the certificates used to access the test server securely. def load_test_certs @@ -101,22 +102,14 @@ def create_stub(opts) } # Add service account creds if specified - if %w(all service_account_creds).include?(opts.test_case) + wants_creds = %w(all compute_engine_creds service_account_creds) + if wants_creds.include?(opts.test_case) unless opts.oauth_scope.nil? - fd = StringIO.new(File.read(opts.oauth_key_file)) - logger.info("loading oauth certs from #{opts.oauth_key_file}") - auth_creds = ServiceAccountCredentials.new(opts.oauth_scope, fd) + auth_creds = Google::Auth.get_application_default(opts.oauth_scope) stub_opts[:update_metadata] = auth_creds.updater_proc end end - # Add compute engine creds if specified - if %w(all compute_engine_creds).include?(opts.test_case) - unless opts.oauth_scope.nil? - stub_opts[:update_metadata] = GCECredentials.new.update_proc - end - end - logger.info("... connecting securely to #{address}") Grpc::Testing::TestService::Stub.new(address, **stub_opts) else @@ -193,11 +186,11 @@ class NamedTests def service_account_creds # ignore this test if the oauth options are not set - if @args.oauth_scope.nil? || @args.oauth_key_file.nil? + if @args.oauth_scope.nil? p 'NOT RUN: service_account_creds; no service_account settings' return end - json_key = File.read(@args.oauth_key_file) + json_key = File.read(ENV[AUTH_ENV]) wanted_email = MultiJson.load(json_key)['client_email'] resp = perform_large_unary(fill_username: true, fill_oauth_scope: true) @@ -285,7 +278,7 @@ end # Args is used to hold the command line info. Args = Struct.new(:default_service_account, :host, :host_override, - :oauth_scope, :oauth_key_file, :port, :secure, :test_case, + :oauth_scope, :port, :secure, :test_case, :use_test_ca) # validates the the command line options, returning them as a Hash. @@ -302,10 +295,6 @@ def parse_args 'email address of the default service account') do |v| args['default_service_account'] = v end - opts.on('--service_account_key_file PATH', - 'Path to the service account json key file') do |v| - args['oauth_key_file'] = v - end opts.on('--server_host_override HOST_OVERRIDE', 'override host via a HTTP header') do |v| args['host_override'] = v @@ -333,10 +322,6 @@ def _check_args(args) fail(OptionParser::MissingArgument, "please specify --#{arg}") end end - if args['oauth_key_file'].nil? ^ args['oauth_scope'].nil? - fail(OptionParser::MissingArgument, - 'please specify both of --service_account_key_file and --oauth_scope') - end args end From 2731d3f40db0bbbfeb2b9fb0f5abb4c8de077790 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Tue, 24 Feb 2015 21:56:22 -0800 Subject: [PATCH 27/75] Updates the pubsub demo to use the new auth library --- src/ruby/bin/apis/pubsub_demo.rb | 35 +++++++++++--------------------- 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/src/ruby/bin/apis/pubsub_demo.rb b/src/ruby/bin/apis/pubsub_demo.rb index 6656a561309..9bb324ff646 100755 --- a/src/ruby/bin/apis/pubsub_demo.rb +++ b/src/ruby/bin/apis/pubsub_demo.rb @@ -31,10 +31,9 @@ # pubsub_demo demos accesses the Google PubSub API via its gRPC interface # -# TODO: update the Usage once the usable auth gem is available -# $ SSL_CERT_FILE= \ +# $ GOOGLE_APPLICATION_CREDENTIALS= \ +# SSL_CERT_FILE= \ # path/to/pubsub_demo.rb \ -# --service_account_key_file= \ # [--action= ] # # There are options related to the chosen action, see #parse_args below. @@ -49,6 +48,7 @@ $LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir) require 'optparse' require 'grpc' +require 'googleauth' require 'google/protobuf' require 'google/protobuf/empty' @@ -59,7 +59,9 @@ require 'tech/pubsub/proto/pubsub_services' def load_prod_cert fail 'could not find a production cert' if ENV['SSL_CERT_FILE'].nil? p "loading prod certs from #{ENV['SSL_CERT_FILE']}" - File.open(ENV['SSL_CERT_FILE']).read + File.open(ENV['SSL_CERT_FILE']) do |f| + return f.read + end end # creates a SSL Credentials from the production certificates. @@ -68,14 +70,9 @@ def ssl_creds end # Builds the metadata authentication update proc. -# -# TODO: replace this once the ruby usable auth repo is available. def auth_proc(opts) - if GRPC::Auth::GCECredentials.on_gce? - return GRPC::Auth::GCECredentials.new.updater_proc - end - fd = StringIO.new(File.read(opts.oauth_key_file)) - GRPC::Auth::ServiceAccountCredentials.new(opts.oauth_scope, fd).updater_proc + auth_creds = Google::Auth.get_application_default(opts.oauth_scope) + return auth_creds.updater_proc end # Creates a stub for accessing the publisher service. @@ -216,14 +213,14 @@ class NamedActions end # Args is used to hold the command line info. -Args = Struct.new(:host, :oauth_scope, :oauth_key_file, :port, :action, - :project_id, :topic_name, :sub_name) +Args = Struct.new(:host, :oauth_scope, :port, :action, :project_id, :topic_name, + :sub_name) # validates the the command line options, returning them as an Arg. def parse_args args = Args.new('pubsub-staging.googleapis.com', 'https://www.googleapis.com/auth/pubsub', - nil, 443, 'list_some_topics', 'stoked-keyword-656') + 443, 'list_some_topics', 'stoked-keyword-656') OptionParser.new do |opts| opts.on('--oauth_scope scope', 'Scope for OAuth tokens') { |v| args['oauth_scope'] = v } @@ -233,10 +230,6 @@ def parse_args opts.on('--server_port SERVER_PORT', 'server port') do |v| args.port = v end - opts.on('--service_account_key_file PATH', - 'Path to the service account json key file') do |v| - args.oauth_key_file = v - end # instance_methods(false) gives only the methods defined in that class. scenes = NamedActions.instance_methods(false).map { |t| t.to_s } @@ -257,15 +250,11 @@ def parse_args end def _check_args(args) - %w(host port action).each do |a| + %w(host port action oauth_scope).each do |a| if args[a].nil? raise OptionParser::MissingArgument.new("please specify --#{a}") end end - if args['oauth_key_file'].nil? || args['oauth_scope'].nil? - fail(OptionParser::MissingArgument, - 'please specify both of --service_account_key_file and --oauth_scope') - end args end From 494f2f9706cc7491e111a819f8d3ea6ecd37170d Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Tue, 24 Feb 2015 22:00:42 -0800 Subject: [PATCH 28/75] Remove the ruby gRPC auth implementation --- src/ruby/lib/grpc.rb | 2 - src/ruby/lib/grpc/auth/compute_engine.rb | 67 --------- src/ruby/lib/grpc/auth/service_account.rb | 66 --------- src/ruby/lib/grpc/auth/signet.rb | 67 --------- src/ruby/spec/auth/apply_auth_examples.rb | 163 --------------------- src/ruby/spec/auth/compute_engine_spec.rb | 108 -------------- src/ruby/spec/auth/service_account_spec.rb | 75 ---------- src/ruby/spec/auth/signet_spec.rb | 70 --------- 8 files changed, 618 deletions(-) delete mode 100644 src/ruby/lib/grpc/auth/compute_engine.rb delete mode 100644 src/ruby/lib/grpc/auth/service_account.rb delete mode 100644 src/ruby/lib/grpc/auth/signet.rb delete mode 100644 src/ruby/spec/auth/apply_auth_examples.rb delete mode 100644 src/ruby/spec/auth/compute_engine_spec.rb delete mode 100644 src/ruby/spec/auth/service_account_spec.rb delete mode 100644 src/ruby/spec/auth/signet_spec.rb diff --git a/src/ruby/lib/grpc.rb b/src/ruby/lib/grpc.rb index a2a609f59ee..dd02ef7666a 100644 --- a/src/ruby/lib/grpc.rb +++ b/src/ruby/lib/grpc.rb @@ -27,8 +27,6 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -require 'grpc/auth/compute_engine.rb' -require 'grpc/auth/service_account.rb' require 'grpc/errors' require 'grpc/grpc' require 'grpc/logconfig' diff --git a/src/ruby/lib/grpc/auth/compute_engine.rb b/src/ruby/lib/grpc/auth/compute_engine.rb deleted file mode 100644 index 5cb1e1a4dcf..00000000000 --- a/src/ruby/lib/grpc/auth/compute_engine.rb +++ /dev/null @@ -1,67 +0,0 @@ -# Copyright 2015, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -require 'faraday' -require 'grpc/auth/signet' - -module GRPC - # Module Auth provides classes that provide Google-specific authentication - # used to access Google gRPC services. - module Auth - # Extends Signet::OAuth2::Client so that the auth token is obtained from - # the GCE metadata server. - class GCECredentials < Signet::OAuth2::Client - COMPUTE_AUTH_TOKEN_URI = 'http://metadata/computeMetadata/v1/'\ - 'instance/service-accounts/default/token' - COMPUTE_CHECK_URI = 'http://metadata.google.internal' - - # Detect if this appear to be a GCE instance, by checking if metadata - # is available - def self.on_gce?(options = {}) - c = options[:connection] || Faraday.default_connection - resp = c.get(COMPUTE_CHECK_URI) - return false unless resp.status == 200 - return false unless resp.headers.key?('Metadata-Flavor') - return resp.headers['Metadata-Flavor'] == 'Google' - rescue Faraday::ConnectionFailed - return false - end - - # Overrides the super class method to change how access tokens are - # fetched. - def fetch_access_token(options = {}) - c = options[:connection] || Faraday.default_connection - c.headers = { 'Metadata-Flavor' => 'Google' } - resp = c.get(COMPUTE_AUTH_TOKEN_URI) - Signet::OAuth2.parse_credentials(resp.body, - resp.headers['content-type']) - end - end - end -end diff --git a/src/ruby/lib/grpc/auth/service_account.rb b/src/ruby/lib/grpc/auth/service_account.rb deleted file mode 100644 index 14b81a9e034..00000000000 --- a/src/ruby/lib/grpc/auth/service_account.rb +++ /dev/null @@ -1,66 +0,0 @@ -# Copyright 2015, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -require 'grpc/auth/signet' -require 'multi_json' -require 'openssl' - -# Reads the private key and client email fields from service account JSON key. -def read_json_key(json_key_io) - json_key = MultiJson.load(json_key_io.read) - fail 'missing client_email' unless json_key.key?('client_email') - fail 'missing private_key' unless json_key.key?('private_key') - [json_key['private_key'], json_key['client_email']] -end - -module GRPC - # Module Auth provides classes that provide Google-specific authentication - # used to access Google gRPC services. - module Auth - # Authenticates requests using Google's Service Account credentials. - # (cf https://developers.google.com/accounts/docs/OAuth2ServiceAccount) - class ServiceAccountCredentials < Signet::OAuth2::Client - TOKEN_CRED_URI = 'https://www.googleapis.com/oauth2/v3/token' - AUDIENCE = TOKEN_CRED_URI - - # Initializes a ServiceAccountCredentials. - # - # @param scope [string|array] the scope(s) to access - # @param json_key_io [IO] an IO from which the JSON key can be read - def initialize(scope, json_key_io) - private_key, client_email = read_json_key(json_key_io) - super(token_credential_uri: TOKEN_CRED_URI, - audience: AUDIENCE, - scope: scope, - issuer: client_email, - signing_key: OpenSSL::PKey::RSA.new(private_key)) - end - end - end -end diff --git a/src/ruby/lib/grpc/auth/signet.rb b/src/ruby/lib/grpc/auth/signet.rb deleted file mode 100644 index a8bce1255c2..00000000000 --- a/src/ruby/lib/grpc/auth/signet.rb +++ /dev/null @@ -1,67 +0,0 @@ -# Copyright 2015, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -require 'signet/oauth_2/client' - -module Signet - # Signet::OAuth2 supports OAuth2 authentication. - module OAuth2 - AUTH_METADATA_KEY = :Authorization - # Signet::OAuth2::Client creates an OAuth2 client - # - # Here client is re-opened to add the #apply and #apply! methods which - # update a hash map with the fetched authentication token - # - # Eventually, this change may be merged into signet itself, or some other - # package that provides Google-specific auth via signet, and this extension - # will be unnecessary. - class Client - # Updates a_hash updated with the authentication token - def apply!(a_hash, opts = {}) - # fetch the access token there is currently not one, or if the client - # has expired - fetch_access_token!(opts) if access_token.nil? || expired? - a_hash[AUTH_METADATA_KEY] = "Bearer #{access_token}" - end - - # Returns a clone of a_hash updated with the authentication token - def apply(a_hash, opts = {}) - a_copy = a_hash.clone - apply!(a_copy, opts) - a_copy - end - - # Returns a reference to the #apply method, suitable for passing as - # a closure - def updater_proc - lambda(&method(:apply)) - end - end - end -end diff --git a/src/ruby/spec/auth/apply_auth_examples.rb b/src/ruby/spec/auth/apply_auth_examples.rb deleted file mode 100644 index 09b393026f0..00000000000 --- a/src/ruby/spec/auth/apply_auth_examples.rb +++ /dev/null @@ -1,163 +0,0 @@ -# Copyright 2015, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -spec_dir = File.expand_path(File.join(File.dirname(__FILE__))) -$LOAD_PATH.unshift(spec_dir) -$LOAD_PATH.uniq! - -require 'faraday' -require 'spec_helper' - -def build_json_response(payload) - [200, - { 'Content-Type' => 'application/json; charset=utf-8' }, - MultiJson.dump(payload)] -end - -WANTED_AUTH_KEY = :Authorization - -shared_examples 'apply/apply! are OK' do - # tests that use these examples need to define - # - # @client which should be an auth client - # - # @make_auth_stubs, which should stub out the expected http behaviour of the - # auth client - describe '#fetch_access_token' do - it 'should set access_token to the fetched value' do - token = '1/abcdef1234567890' - stubs = make_auth_stubs with_access_token: token - c = Faraday.new do |b| - b.adapter(:test, stubs) - end - - @client.fetch_access_token!(connection: c) - expect(@client.access_token).to eq(token) - stubs.verify_stubbed_calls - end - end - - describe '#apply!' do - it 'should update the target hash with fetched access token' do - token = '1/abcdef1234567890' - stubs = make_auth_stubs with_access_token: token - c = Faraday.new do |b| - b.adapter(:test, stubs) - end - - md = { foo: 'bar' } - @client.apply!(md, connection: c) - want = { :foo => 'bar', WANTED_AUTH_KEY => "Bearer #{token}" } - expect(md).to eq(want) - stubs.verify_stubbed_calls - end - end - - describe 'updater_proc' do - it 'should provide a proc that updates a hash with the access token' do - token = '1/abcdef1234567890' - stubs = make_auth_stubs with_access_token: token - c = Faraday.new do |b| - b.adapter(:test, stubs) - end - - md = { foo: 'bar' } - the_proc = @client.updater_proc - got = the_proc.call(md, connection: c) - want = { :foo => 'bar', WANTED_AUTH_KEY => "Bearer #{token}" } - expect(got).to eq(want) - stubs.verify_stubbed_calls - end - end - - describe '#apply' do - it 'should not update the original hash with the access token' do - token = '1/abcdef1234567890' - stubs = make_auth_stubs with_access_token: token - c = Faraday.new do |b| - b.adapter(:test, stubs) - end - - md = { foo: 'bar' } - @client.apply(md, connection: c) - want = { foo: 'bar' } - expect(md).to eq(want) - stubs.verify_stubbed_calls - end - - it 'should add the token to the returned hash' do - token = '1/abcdef1234567890' - stubs = make_auth_stubs with_access_token: token - c = Faraday.new do |b| - b.adapter(:test, stubs) - end - - md = { foo: 'bar' } - got = @client.apply(md, connection: c) - want = { :foo => 'bar', WANTED_AUTH_KEY => "Bearer #{token}" } - expect(got).to eq(want) - stubs.verify_stubbed_calls - end - - it 'should not fetch a new token if the current is not expired' do - token = '1/abcdef1234567890' - stubs = make_auth_stubs with_access_token: token - c = Faraday.new do |b| - b.adapter(:test, stubs) - end - - n = 5 # arbitrary - n.times do |_t| - md = { foo: 'bar' } - got = @client.apply(md, connection: c) - want = { :foo => 'bar', WANTED_AUTH_KEY => "Bearer #{token}" } - expect(got).to eq(want) - end - stubs.verify_stubbed_calls - end - - it 'should fetch a new token if the current one is expired' do - token_1 = '1/abcdef1234567890' - token_2 = '2/abcdef1234567890' - - [token_1, token_2].each do |t| - stubs = make_auth_stubs with_access_token: t - c = Faraday.new do |b| - b.adapter(:test, stubs) - end - md = { foo: 'bar' } - got = @client.apply(md, connection: c) - want = { :foo => 'bar', WANTED_AUTH_KEY => "Bearer #{t}" } - expect(got).to eq(want) - stubs.verify_stubbed_calls - @client.expires_at -= 3601 # default is to expire in 1hr - end - end - end -end diff --git a/src/ruby/spec/auth/compute_engine_spec.rb b/src/ruby/spec/auth/compute_engine_spec.rb deleted file mode 100644 index c43214d0861..00000000000 --- a/src/ruby/spec/auth/compute_engine_spec.rb +++ /dev/null @@ -1,108 +0,0 @@ -# Copyright 2015, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -spec_dir = File.expand_path(File.join(File.dirname(__FILE__))) -$LOAD_PATH.unshift(spec_dir) -$LOAD_PATH.uniq! - -require 'apply_auth_examples' -require 'faraday' -require 'grpc/auth/compute_engine' -require 'spec_helper' - -describe GRPC::Auth::GCECredentials do - MD_URI = '/computeMetadata/v1/instance/service-accounts/default/token' - GCECredentials = GRPC::Auth::GCECredentials - - before(:example) do - @client = GCECredentials.new - end - - def make_auth_stubs(with_access_token: '') - Faraday::Adapter::Test::Stubs.new do |stub| - stub.get(MD_URI) do |env| - headers = env[:request_headers] - expect(headers['Metadata-Flavor']).to eq('Google') - build_json_response( - 'access_token' => with_access_token, - 'token_type' => 'Bearer', - 'expires_in' => 3600) - end - end - end - - it_behaves_like 'apply/apply! are OK' - - describe '#on_gce?' do - it 'should be true when Metadata-Flavor is Google' do - stubs = Faraday::Adapter::Test::Stubs.new do |stub| - stub.get('/') do |_env| - [200, - { 'Metadata-Flavor' => 'Google' }, - ''] - end - end - c = Faraday.new do |b| - b.adapter(:test, stubs) - end - expect(GCECredentials.on_gce?(connection: c)).to eq(true) - stubs.verify_stubbed_calls - end - - it 'should be false when Metadata-Flavor is not Google' do - stubs = Faraday::Adapter::Test::Stubs.new do |stub| - stub.get('/') do |_env| - [200, - { 'Metadata-Flavor' => 'NotGoogle' }, - ''] - end - end - c = Faraday.new do |b| - b.adapter(:test, stubs) - end - expect(GCECredentials.on_gce?(connection: c)).to eq(false) - stubs.verify_stubbed_calls - end - - it 'should be false if the response is not 200' do - stubs = Faraday::Adapter::Test::Stubs.new do |stub| - stub.get('/') do |_env| - [404, - { 'Metadata-Flavor' => 'Google' }, - ''] - end - end - c = Faraday.new do |b| - b.adapter(:test, stubs) - end - expect(GCECredentials.on_gce?(connection: c)).to eq(false) - stubs.verify_stubbed_calls - end - end -end diff --git a/src/ruby/spec/auth/service_account_spec.rb b/src/ruby/spec/auth/service_account_spec.rb deleted file mode 100644 index 2f14a1ae053..00000000000 --- a/src/ruby/spec/auth/service_account_spec.rb +++ /dev/null @@ -1,75 +0,0 @@ -# Copyright 2015, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -spec_dir = File.expand_path(File.join(File.dirname(__FILE__))) -$LOAD_PATH.unshift(spec_dir) -$LOAD_PATH.uniq! - -require 'apply_auth_examples' -require 'grpc/auth/service_account' -require 'jwt' -require 'multi_json' -require 'openssl' -require 'spec_helper' - -describe GRPC::Auth::ServiceAccountCredentials do - before(:example) do - @key = OpenSSL::PKey::RSA.new(2048) - cred_json = { - private_key_id: 'a_private_key_id', - private_key: @key.to_pem, - client_email: 'app@developer.gserviceaccount.com', - client_id: 'app.apps.googleusercontent.com', - type: 'service_account' - } - cred_json_text = MultiJson.dump(cred_json) - @client = GRPC::Auth::ServiceAccountCredentials.new( - 'https://www.googleapis.com/auth/userinfo.profile', - StringIO.new(cred_json_text)) - end - - def make_auth_stubs(with_access_token: '') - Faraday::Adapter::Test::Stubs.new do |stub| - stub.post('/oauth2/v3/token') do |env| - params = Addressable::URI.form_unencode(env[:body]) - _claim, _header = JWT.decode(params.assoc('assertion').last, - @key.public_key) - want = ['grant_type', 'urn:ietf:params:oauth:grant-type:jwt-bearer'] - expect(params.assoc('grant_type')).to eq(want) - build_json_response( - 'access_token' => with_access_token, - 'token_type' => 'Bearer', - 'expires_in' => 3600 - ) - end - end - end - - it_behaves_like 'apply/apply! are OK' -end diff --git a/src/ruby/spec/auth/signet_spec.rb b/src/ruby/spec/auth/signet_spec.rb deleted file mode 100644 index 1712edf2961..00000000000 --- a/src/ruby/spec/auth/signet_spec.rb +++ /dev/null @@ -1,70 +0,0 @@ -# Copyright 2015, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -spec_dir = File.expand_path(File.join(File.dirname(__FILE__))) -$LOAD_PATH.unshift(spec_dir) -$LOAD_PATH.uniq! - -require 'apply_auth_examples' -require 'grpc/auth/signet' -require 'jwt' -require 'openssl' -require 'spec_helper' - -describe Signet::OAuth2::Client do - before(:example) do - @key = OpenSSL::PKey::RSA.new(2048) - @client = Signet::OAuth2::Client.new( - token_credential_uri: 'https://accounts.google.com/o/oauth2/token', - scope: 'https://www.googleapis.com/auth/userinfo.profile', - issuer: 'app@example.com', - audience: 'https://accounts.google.com/o/oauth2/token', - signing_key: @key - ) - end - - def make_auth_stubs(with_access_token: '') - Faraday::Adapter::Test::Stubs.new do |stub| - stub.post('/o/oauth2/token') do |env| - params = Addressable::URI.form_unencode(env[:body]) - _claim, _header = JWT.decode(params.assoc('assertion').last, - @key.public_key) - want = ['grant_type', 'urn:ietf:params:oauth:grant-type:jwt-bearer'] - expect(params.assoc('grant_type')).to eq(want) - build_json_response( - 'access_token' => with_access_token, - 'token_type' => 'Bearer', - 'expires_in' => 3600 - ) - end - end - end - - it_behaves_like 'apply/apply! are OK' -end From fa4a4b52d80304e21dfbab85e867fda922e69f67 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Wed, 25 Feb 2015 06:06:27 -0800 Subject: [PATCH 29/75] Updates the docker test commands --- tools/gce_setup/grpc_docker.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tools/gce_setup/grpc_docker.sh b/tools/gce_setup/grpc_docker.sh index bbc138c6beb..54cec2f1440 100755 --- a/tools/gce_setup/grpc_docker.sh +++ b/tools/gce_setup/grpc_docker.sh @@ -975,9 +975,10 @@ grpc_cloud_prod_auth_service_account_creds_gen_ruby_cmd() { local test_script="/var/local/git/grpc/src/ruby/bin/interop/interop_client.rb" local test_script+=" --use_tls" local gfe_flags=$(_grpc_prod_gfe_flags) - local added_gfe_flags=$(_grpc_svc_acc_test_flags) + local added_gfe_flags=$(_grpc_default_creds_test_flags) local env_prefix="SSL_CERT_FILE=/cacerts/roots.pem" - local the_cmd="$cmd_prefix '$env_prefix ruby $test_script $gfe_flags $added_gfe_flag $@'" + env_prefix+=" GOOGLE_APPLICATION_CREDENTIALS=/service_account/stubbyCloudTestingTest-7dd63462c60c.json" + local the_cmd="$cmd_prefix '$env_prefix ruby $test_script $gfe_flags $added_gfe_flags $@'" echo $the_cmd } @@ -1170,6 +1171,11 @@ _grpc_svc_acc_test_flags() { echo " --service_account_key_file=/service_account/stubbyCloudTestingTest-7dd63462c60c.json --oauth_scope=https://www.googleapis.com/auth/xapi.zoo" } +# default credentials test flag +_grpc_default_creds_test_flags() { + echo " --oauth_scope=https://www.googleapis.com/auth/xapi.zoo" +} + # outputs the flags passed to the gcloud auth tests _grpc_gce_test_flags() { echo " --default_service_account=155450119199-r5aaqa2vqoa9g5mv2m6s3m1l293rlmel@developer.gserviceaccount.com --oauth_scope=https://www.googleapis.com/auth/xapi.zoo" From 635dbbe2fcb58be1bcd9086917488c5de5a90a5a Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Wed, 25 Feb 2015 06:17:00 -0800 Subject: [PATCH 30/75] Fixes the GCE creds test flags --- tools/gce_setup/grpc_docker.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/gce_setup/grpc_docker.sh b/tools/gce_setup/grpc_docker.sh index 54cec2f1440..117edd55ba0 100755 --- a/tools/gce_setup/grpc_docker.sh +++ b/tools/gce_setup/grpc_docker.sh @@ -994,7 +994,7 @@ grpc_cloud_prod_auth_compute_engine_creds_gen_ruby_cmd() { local gfe_flags=$(_grpc_prod_gfe_flags) local added_gfe_flags=$(_grpc_gce_test_flags) local env_prefix="SSL_CERT_FILE=/cacerts/roots.pem" - local the_cmd="$cmd_prefix '$env_prefix ruby $test_script $gfe_flags $added_gfe_flag $@'" + local the_cmd="$cmd_prefix '$env_prefix ruby $test_script $gfe_flags $added_gfe_flags $@'" echo $the_cmd } From f73fdfbbb337ab68434f666724b9f62c031df97f Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Tue, 24 Feb 2015 21:26:21 -0800 Subject: [PATCH 31/75] Adds a reference to GoogleAuth --- src/ruby/grpc.gemspec | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ruby/grpc.gemspec b/src/ruby/grpc.gemspec index bc59c234e5a..25a3ff5ce27 100755 --- a/src/ruby/grpc.gemspec +++ b/src/ruby/grpc.gemspec @@ -22,6 +22,7 @@ Gem::Specification.new do |s| s.add_dependency 'faraday', '~> 0.9' s.add_dependency 'google-protobuf', '~> 3.0.0alpha.1.1' + s.add_dependency 'googleauth', '~> 0.1' s.add_dependency 'logging', '~> 1.8' s.add_dependency 'jwt', '~> 1.2.1' s.add_dependency 'minitest', '~> 5.4' # reqd for interop tests From d6e652716a01abb38ea91f8cd29facc070c01c44 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Tue, 24 Feb 2015 21:29:11 -0800 Subject: [PATCH 32/75] Updates the interop client to use the new auth library --- src/ruby/bin/interop/interop_client.rb | 31 +++++++------------------- 1 file changed, 8 insertions(+), 23 deletions(-) diff --git a/src/ruby/bin/interop/interop_client.rb b/src/ruby/bin/interop/interop_client.rb index 380ceb11df0..b0b24b949f2 100755 --- a/src/ruby/bin/interop/interop_client.rb +++ b/src/ruby/bin/interop/interop_client.rb @@ -48,6 +48,7 @@ require 'minitest' require 'minitest/assertions' require 'grpc' +require 'googleauth' require 'google/protobuf' require 'test/cpp/interop/test_services' @@ -56,7 +57,7 @@ require 'test/cpp/interop/empty' require 'signet/ssl_config' -include GRPC::Auth +AUTH_ENV = Google::Auth::ServiceAccountCredentials::ENV_VAR # loads the certificates used to access the test server securely. def load_test_certs @@ -101,22 +102,14 @@ def create_stub(opts) } # Add service account creds if specified - if %w(all service_account_creds).include?(opts.test_case) + wants_creds = %w(all compute_engine_creds service_account_creds) + if wants_creds.include?(opts.test_case) unless opts.oauth_scope.nil? - fd = StringIO.new(File.read(opts.oauth_key_file)) - logger.info("loading oauth certs from #{opts.oauth_key_file}") - auth_creds = ServiceAccountCredentials.new(opts.oauth_scope, fd) + auth_creds = Google::Auth.get_application_default(opts.oauth_scope) stub_opts[:update_metadata] = auth_creds.updater_proc end end - # Add compute engine creds if specified - if %w(all compute_engine_creds).include?(opts.test_case) - unless opts.oauth_scope.nil? - stub_opts[:update_metadata] = GCECredentials.new.update_proc - end - end - logger.info("... connecting securely to #{address}") Grpc::Testing::TestService::Stub.new(address, **stub_opts) else @@ -193,11 +186,11 @@ class NamedTests def service_account_creds # ignore this test if the oauth options are not set - if @args.oauth_scope.nil? || @args.oauth_key_file.nil? + if @args.oauth_scope.nil? p 'NOT RUN: service_account_creds; no service_account settings' return end - json_key = File.read(@args.oauth_key_file) + json_key = File.read(ENV[AUTH_ENV]) wanted_email = MultiJson.load(json_key)['client_email'] resp = perform_large_unary(fill_username: true, fill_oauth_scope: true) @@ -285,7 +278,7 @@ end # Args is used to hold the command line info. Args = Struct.new(:default_service_account, :host, :host_override, - :oauth_scope, :oauth_key_file, :port, :secure, :test_case, + :oauth_scope, :port, :secure, :test_case, :use_test_ca) # validates the the command line options, returning them as a Hash. @@ -302,10 +295,6 @@ def parse_args 'email address of the default service account') do |v| args['default_service_account'] = v end - opts.on('--service_account_key_file PATH', - 'Path to the service account json key file') do |v| - args['oauth_key_file'] = v - end opts.on('--server_host_override HOST_OVERRIDE', 'override host via a HTTP header') do |v| args['host_override'] = v @@ -333,10 +322,6 @@ def _check_args(args) fail(OptionParser::MissingArgument, "please specify --#{arg}") end end - if args['oauth_key_file'].nil? ^ args['oauth_scope'].nil? - fail(OptionParser::MissingArgument, - 'please specify both of --service_account_key_file and --oauth_scope') - end args end From 71034819fd1ca2dfb45fde318fbdb983b3482595 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Tue, 24 Feb 2015 21:56:22 -0800 Subject: [PATCH 33/75] Updates the pubsub demo to use the new auth library --- src/ruby/bin/apis/pubsub_demo.rb | 35 +++++++++++--------------------- 1 file changed, 12 insertions(+), 23 deletions(-) diff --git a/src/ruby/bin/apis/pubsub_demo.rb b/src/ruby/bin/apis/pubsub_demo.rb index 6656a561309..9bb324ff646 100755 --- a/src/ruby/bin/apis/pubsub_demo.rb +++ b/src/ruby/bin/apis/pubsub_demo.rb @@ -31,10 +31,9 @@ # pubsub_demo demos accesses the Google PubSub API via its gRPC interface # -# TODO: update the Usage once the usable auth gem is available -# $ SSL_CERT_FILE= \ +# $ GOOGLE_APPLICATION_CREDENTIALS= \ +# SSL_CERT_FILE= \ # path/to/pubsub_demo.rb \ -# --service_account_key_file= \ # [--action= ] # # There are options related to the chosen action, see #parse_args below. @@ -49,6 +48,7 @@ $LOAD_PATH.unshift(this_dir) unless $LOAD_PATH.include?(this_dir) require 'optparse' require 'grpc' +require 'googleauth' require 'google/protobuf' require 'google/protobuf/empty' @@ -59,7 +59,9 @@ require 'tech/pubsub/proto/pubsub_services' def load_prod_cert fail 'could not find a production cert' if ENV['SSL_CERT_FILE'].nil? p "loading prod certs from #{ENV['SSL_CERT_FILE']}" - File.open(ENV['SSL_CERT_FILE']).read + File.open(ENV['SSL_CERT_FILE']) do |f| + return f.read + end end # creates a SSL Credentials from the production certificates. @@ -68,14 +70,9 @@ def ssl_creds end # Builds the metadata authentication update proc. -# -# TODO: replace this once the ruby usable auth repo is available. def auth_proc(opts) - if GRPC::Auth::GCECredentials.on_gce? - return GRPC::Auth::GCECredentials.new.updater_proc - end - fd = StringIO.new(File.read(opts.oauth_key_file)) - GRPC::Auth::ServiceAccountCredentials.new(opts.oauth_scope, fd).updater_proc + auth_creds = Google::Auth.get_application_default(opts.oauth_scope) + return auth_creds.updater_proc end # Creates a stub for accessing the publisher service. @@ -216,14 +213,14 @@ class NamedActions end # Args is used to hold the command line info. -Args = Struct.new(:host, :oauth_scope, :oauth_key_file, :port, :action, - :project_id, :topic_name, :sub_name) +Args = Struct.new(:host, :oauth_scope, :port, :action, :project_id, :topic_name, + :sub_name) # validates the the command line options, returning them as an Arg. def parse_args args = Args.new('pubsub-staging.googleapis.com', 'https://www.googleapis.com/auth/pubsub', - nil, 443, 'list_some_topics', 'stoked-keyword-656') + 443, 'list_some_topics', 'stoked-keyword-656') OptionParser.new do |opts| opts.on('--oauth_scope scope', 'Scope for OAuth tokens') { |v| args['oauth_scope'] = v } @@ -233,10 +230,6 @@ def parse_args opts.on('--server_port SERVER_PORT', 'server port') do |v| args.port = v end - opts.on('--service_account_key_file PATH', - 'Path to the service account json key file') do |v| - args.oauth_key_file = v - end # instance_methods(false) gives only the methods defined in that class. scenes = NamedActions.instance_methods(false).map { |t| t.to_s } @@ -257,15 +250,11 @@ def parse_args end def _check_args(args) - %w(host port action).each do |a| + %w(host port action oauth_scope).each do |a| if args[a].nil? raise OptionParser::MissingArgument.new("please specify --#{a}") end end - if args['oauth_key_file'].nil? || args['oauth_scope'].nil? - fail(OptionParser::MissingArgument, - 'please specify both of --service_account_key_file and --oauth_scope') - end args end From fca1eb454cef13bb02ec365f61e06867ad3a48c9 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Tue, 24 Feb 2015 22:00:42 -0800 Subject: [PATCH 34/75] Remove the ruby gRPC auth implementation --- src/ruby/lib/grpc.rb | 2 - src/ruby/lib/grpc/auth/compute_engine.rb | 67 --------- src/ruby/lib/grpc/auth/service_account.rb | 66 --------- src/ruby/lib/grpc/auth/signet.rb | 67 --------- src/ruby/spec/auth/apply_auth_examples.rb | 163 --------------------- src/ruby/spec/auth/compute_engine_spec.rb | 108 -------------- src/ruby/spec/auth/service_account_spec.rb | 75 ---------- src/ruby/spec/auth/signet_spec.rb | 70 --------- 8 files changed, 618 deletions(-) delete mode 100644 src/ruby/lib/grpc/auth/compute_engine.rb delete mode 100644 src/ruby/lib/grpc/auth/service_account.rb delete mode 100644 src/ruby/lib/grpc/auth/signet.rb delete mode 100644 src/ruby/spec/auth/apply_auth_examples.rb delete mode 100644 src/ruby/spec/auth/compute_engine_spec.rb delete mode 100644 src/ruby/spec/auth/service_account_spec.rb delete mode 100644 src/ruby/spec/auth/signet_spec.rb diff --git a/src/ruby/lib/grpc.rb b/src/ruby/lib/grpc.rb index a2a609f59ee..dd02ef7666a 100644 --- a/src/ruby/lib/grpc.rb +++ b/src/ruby/lib/grpc.rb @@ -27,8 +27,6 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -require 'grpc/auth/compute_engine.rb' -require 'grpc/auth/service_account.rb' require 'grpc/errors' require 'grpc/grpc' require 'grpc/logconfig' diff --git a/src/ruby/lib/grpc/auth/compute_engine.rb b/src/ruby/lib/grpc/auth/compute_engine.rb deleted file mode 100644 index 5cb1e1a4dcf..00000000000 --- a/src/ruby/lib/grpc/auth/compute_engine.rb +++ /dev/null @@ -1,67 +0,0 @@ -# Copyright 2015, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -require 'faraday' -require 'grpc/auth/signet' - -module GRPC - # Module Auth provides classes that provide Google-specific authentication - # used to access Google gRPC services. - module Auth - # Extends Signet::OAuth2::Client so that the auth token is obtained from - # the GCE metadata server. - class GCECredentials < Signet::OAuth2::Client - COMPUTE_AUTH_TOKEN_URI = 'http://metadata/computeMetadata/v1/'\ - 'instance/service-accounts/default/token' - COMPUTE_CHECK_URI = 'http://metadata.google.internal' - - # Detect if this appear to be a GCE instance, by checking if metadata - # is available - def self.on_gce?(options = {}) - c = options[:connection] || Faraday.default_connection - resp = c.get(COMPUTE_CHECK_URI) - return false unless resp.status == 200 - return false unless resp.headers.key?('Metadata-Flavor') - return resp.headers['Metadata-Flavor'] == 'Google' - rescue Faraday::ConnectionFailed - return false - end - - # Overrides the super class method to change how access tokens are - # fetched. - def fetch_access_token(options = {}) - c = options[:connection] || Faraday.default_connection - c.headers = { 'Metadata-Flavor' => 'Google' } - resp = c.get(COMPUTE_AUTH_TOKEN_URI) - Signet::OAuth2.parse_credentials(resp.body, - resp.headers['content-type']) - end - end - end -end diff --git a/src/ruby/lib/grpc/auth/service_account.rb b/src/ruby/lib/grpc/auth/service_account.rb deleted file mode 100644 index 14b81a9e034..00000000000 --- a/src/ruby/lib/grpc/auth/service_account.rb +++ /dev/null @@ -1,66 +0,0 @@ -# Copyright 2015, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -require 'grpc/auth/signet' -require 'multi_json' -require 'openssl' - -# Reads the private key and client email fields from service account JSON key. -def read_json_key(json_key_io) - json_key = MultiJson.load(json_key_io.read) - fail 'missing client_email' unless json_key.key?('client_email') - fail 'missing private_key' unless json_key.key?('private_key') - [json_key['private_key'], json_key['client_email']] -end - -module GRPC - # Module Auth provides classes that provide Google-specific authentication - # used to access Google gRPC services. - module Auth - # Authenticates requests using Google's Service Account credentials. - # (cf https://developers.google.com/accounts/docs/OAuth2ServiceAccount) - class ServiceAccountCredentials < Signet::OAuth2::Client - TOKEN_CRED_URI = 'https://www.googleapis.com/oauth2/v3/token' - AUDIENCE = TOKEN_CRED_URI - - # Initializes a ServiceAccountCredentials. - # - # @param scope [string|array] the scope(s) to access - # @param json_key_io [IO] an IO from which the JSON key can be read - def initialize(scope, json_key_io) - private_key, client_email = read_json_key(json_key_io) - super(token_credential_uri: TOKEN_CRED_URI, - audience: AUDIENCE, - scope: scope, - issuer: client_email, - signing_key: OpenSSL::PKey::RSA.new(private_key)) - end - end - end -end diff --git a/src/ruby/lib/grpc/auth/signet.rb b/src/ruby/lib/grpc/auth/signet.rb deleted file mode 100644 index a8bce1255c2..00000000000 --- a/src/ruby/lib/grpc/auth/signet.rb +++ /dev/null @@ -1,67 +0,0 @@ -# Copyright 2015, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -require 'signet/oauth_2/client' - -module Signet - # Signet::OAuth2 supports OAuth2 authentication. - module OAuth2 - AUTH_METADATA_KEY = :Authorization - # Signet::OAuth2::Client creates an OAuth2 client - # - # Here client is re-opened to add the #apply and #apply! methods which - # update a hash map with the fetched authentication token - # - # Eventually, this change may be merged into signet itself, or some other - # package that provides Google-specific auth via signet, and this extension - # will be unnecessary. - class Client - # Updates a_hash updated with the authentication token - def apply!(a_hash, opts = {}) - # fetch the access token there is currently not one, or if the client - # has expired - fetch_access_token!(opts) if access_token.nil? || expired? - a_hash[AUTH_METADATA_KEY] = "Bearer #{access_token}" - end - - # Returns a clone of a_hash updated with the authentication token - def apply(a_hash, opts = {}) - a_copy = a_hash.clone - apply!(a_copy, opts) - a_copy - end - - # Returns a reference to the #apply method, suitable for passing as - # a closure - def updater_proc - lambda(&method(:apply)) - end - end - end -end diff --git a/src/ruby/spec/auth/apply_auth_examples.rb b/src/ruby/spec/auth/apply_auth_examples.rb deleted file mode 100644 index 09b393026f0..00000000000 --- a/src/ruby/spec/auth/apply_auth_examples.rb +++ /dev/null @@ -1,163 +0,0 @@ -# Copyright 2015, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -spec_dir = File.expand_path(File.join(File.dirname(__FILE__))) -$LOAD_PATH.unshift(spec_dir) -$LOAD_PATH.uniq! - -require 'faraday' -require 'spec_helper' - -def build_json_response(payload) - [200, - { 'Content-Type' => 'application/json; charset=utf-8' }, - MultiJson.dump(payload)] -end - -WANTED_AUTH_KEY = :Authorization - -shared_examples 'apply/apply! are OK' do - # tests that use these examples need to define - # - # @client which should be an auth client - # - # @make_auth_stubs, which should stub out the expected http behaviour of the - # auth client - describe '#fetch_access_token' do - it 'should set access_token to the fetched value' do - token = '1/abcdef1234567890' - stubs = make_auth_stubs with_access_token: token - c = Faraday.new do |b| - b.adapter(:test, stubs) - end - - @client.fetch_access_token!(connection: c) - expect(@client.access_token).to eq(token) - stubs.verify_stubbed_calls - end - end - - describe '#apply!' do - it 'should update the target hash with fetched access token' do - token = '1/abcdef1234567890' - stubs = make_auth_stubs with_access_token: token - c = Faraday.new do |b| - b.adapter(:test, stubs) - end - - md = { foo: 'bar' } - @client.apply!(md, connection: c) - want = { :foo => 'bar', WANTED_AUTH_KEY => "Bearer #{token}" } - expect(md).to eq(want) - stubs.verify_stubbed_calls - end - end - - describe 'updater_proc' do - it 'should provide a proc that updates a hash with the access token' do - token = '1/abcdef1234567890' - stubs = make_auth_stubs with_access_token: token - c = Faraday.new do |b| - b.adapter(:test, stubs) - end - - md = { foo: 'bar' } - the_proc = @client.updater_proc - got = the_proc.call(md, connection: c) - want = { :foo => 'bar', WANTED_AUTH_KEY => "Bearer #{token}" } - expect(got).to eq(want) - stubs.verify_stubbed_calls - end - end - - describe '#apply' do - it 'should not update the original hash with the access token' do - token = '1/abcdef1234567890' - stubs = make_auth_stubs with_access_token: token - c = Faraday.new do |b| - b.adapter(:test, stubs) - end - - md = { foo: 'bar' } - @client.apply(md, connection: c) - want = { foo: 'bar' } - expect(md).to eq(want) - stubs.verify_stubbed_calls - end - - it 'should add the token to the returned hash' do - token = '1/abcdef1234567890' - stubs = make_auth_stubs with_access_token: token - c = Faraday.new do |b| - b.adapter(:test, stubs) - end - - md = { foo: 'bar' } - got = @client.apply(md, connection: c) - want = { :foo => 'bar', WANTED_AUTH_KEY => "Bearer #{token}" } - expect(got).to eq(want) - stubs.verify_stubbed_calls - end - - it 'should not fetch a new token if the current is not expired' do - token = '1/abcdef1234567890' - stubs = make_auth_stubs with_access_token: token - c = Faraday.new do |b| - b.adapter(:test, stubs) - end - - n = 5 # arbitrary - n.times do |_t| - md = { foo: 'bar' } - got = @client.apply(md, connection: c) - want = { :foo => 'bar', WANTED_AUTH_KEY => "Bearer #{token}" } - expect(got).to eq(want) - end - stubs.verify_stubbed_calls - end - - it 'should fetch a new token if the current one is expired' do - token_1 = '1/abcdef1234567890' - token_2 = '2/abcdef1234567890' - - [token_1, token_2].each do |t| - stubs = make_auth_stubs with_access_token: t - c = Faraday.new do |b| - b.adapter(:test, stubs) - end - md = { foo: 'bar' } - got = @client.apply(md, connection: c) - want = { :foo => 'bar', WANTED_AUTH_KEY => "Bearer #{t}" } - expect(got).to eq(want) - stubs.verify_stubbed_calls - @client.expires_at -= 3601 # default is to expire in 1hr - end - end - end -end diff --git a/src/ruby/spec/auth/compute_engine_spec.rb b/src/ruby/spec/auth/compute_engine_spec.rb deleted file mode 100644 index c43214d0861..00000000000 --- a/src/ruby/spec/auth/compute_engine_spec.rb +++ /dev/null @@ -1,108 +0,0 @@ -# Copyright 2015, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -spec_dir = File.expand_path(File.join(File.dirname(__FILE__))) -$LOAD_PATH.unshift(spec_dir) -$LOAD_PATH.uniq! - -require 'apply_auth_examples' -require 'faraday' -require 'grpc/auth/compute_engine' -require 'spec_helper' - -describe GRPC::Auth::GCECredentials do - MD_URI = '/computeMetadata/v1/instance/service-accounts/default/token' - GCECredentials = GRPC::Auth::GCECredentials - - before(:example) do - @client = GCECredentials.new - end - - def make_auth_stubs(with_access_token: '') - Faraday::Adapter::Test::Stubs.new do |stub| - stub.get(MD_URI) do |env| - headers = env[:request_headers] - expect(headers['Metadata-Flavor']).to eq('Google') - build_json_response( - 'access_token' => with_access_token, - 'token_type' => 'Bearer', - 'expires_in' => 3600) - end - end - end - - it_behaves_like 'apply/apply! are OK' - - describe '#on_gce?' do - it 'should be true when Metadata-Flavor is Google' do - stubs = Faraday::Adapter::Test::Stubs.new do |stub| - stub.get('/') do |_env| - [200, - { 'Metadata-Flavor' => 'Google' }, - ''] - end - end - c = Faraday.new do |b| - b.adapter(:test, stubs) - end - expect(GCECredentials.on_gce?(connection: c)).to eq(true) - stubs.verify_stubbed_calls - end - - it 'should be false when Metadata-Flavor is not Google' do - stubs = Faraday::Adapter::Test::Stubs.new do |stub| - stub.get('/') do |_env| - [200, - { 'Metadata-Flavor' => 'NotGoogle' }, - ''] - end - end - c = Faraday.new do |b| - b.adapter(:test, stubs) - end - expect(GCECredentials.on_gce?(connection: c)).to eq(false) - stubs.verify_stubbed_calls - end - - it 'should be false if the response is not 200' do - stubs = Faraday::Adapter::Test::Stubs.new do |stub| - stub.get('/') do |_env| - [404, - { 'Metadata-Flavor' => 'Google' }, - ''] - end - end - c = Faraday.new do |b| - b.adapter(:test, stubs) - end - expect(GCECredentials.on_gce?(connection: c)).to eq(false) - stubs.verify_stubbed_calls - end - end -end diff --git a/src/ruby/spec/auth/service_account_spec.rb b/src/ruby/spec/auth/service_account_spec.rb deleted file mode 100644 index 2f14a1ae053..00000000000 --- a/src/ruby/spec/auth/service_account_spec.rb +++ /dev/null @@ -1,75 +0,0 @@ -# Copyright 2015, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -spec_dir = File.expand_path(File.join(File.dirname(__FILE__))) -$LOAD_PATH.unshift(spec_dir) -$LOAD_PATH.uniq! - -require 'apply_auth_examples' -require 'grpc/auth/service_account' -require 'jwt' -require 'multi_json' -require 'openssl' -require 'spec_helper' - -describe GRPC::Auth::ServiceAccountCredentials do - before(:example) do - @key = OpenSSL::PKey::RSA.new(2048) - cred_json = { - private_key_id: 'a_private_key_id', - private_key: @key.to_pem, - client_email: 'app@developer.gserviceaccount.com', - client_id: 'app.apps.googleusercontent.com', - type: 'service_account' - } - cred_json_text = MultiJson.dump(cred_json) - @client = GRPC::Auth::ServiceAccountCredentials.new( - 'https://www.googleapis.com/auth/userinfo.profile', - StringIO.new(cred_json_text)) - end - - def make_auth_stubs(with_access_token: '') - Faraday::Adapter::Test::Stubs.new do |stub| - stub.post('/oauth2/v3/token') do |env| - params = Addressable::URI.form_unencode(env[:body]) - _claim, _header = JWT.decode(params.assoc('assertion').last, - @key.public_key) - want = ['grant_type', 'urn:ietf:params:oauth:grant-type:jwt-bearer'] - expect(params.assoc('grant_type')).to eq(want) - build_json_response( - 'access_token' => with_access_token, - 'token_type' => 'Bearer', - 'expires_in' => 3600 - ) - end - end - end - - it_behaves_like 'apply/apply! are OK' -end diff --git a/src/ruby/spec/auth/signet_spec.rb b/src/ruby/spec/auth/signet_spec.rb deleted file mode 100644 index 1712edf2961..00000000000 --- a/src/ruby/spec/auth/signet_spec.rb +++ /dev/null @@ -1,70 +0,0 @@ -# Copyright 2015, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -spec_dir = File.expand_path(File.join(File.dirname(__FILE__))) -$LOAD_PATH.unshift(spec_dir) -$LOAD_PATH.uniq! - -require 'apply_auth_examples' -require 'grpc/auth/signet' -require 'jwt' -require 'openssl' -require 'spec_helper' - -describe Signet::OAuth2::Client do - before(:example) do - @key = OpenSSL::PKey::RSA.new(2048) - @client = Signet::OAuth2::Client.new( - token_credential_uri: 'https://accounts.google.com/o/oauth2/token', - scope: 'https://www.googleapis.com/auth/userinfo.profile', - issuer: 'app@example.com', - audience: 'https://accounts.google.com/o/oauth2/token', - signing_key: @key - ) - end - - def make_auth_stubs(with_access_token: '') - Faraday::Adapter::Test::Stubs.new do |stub| - stub.post('/o/oauth2/token') do |env| - params = Addressable::URI.form_unencode(env[:body]) - _claim, _header = JWT.decode(params.assoc('assertion').last, - @key.public_key) - want = ['grant_type', 'urn:ietf:params:oauth:grant-type:jwt-bearer'] - expect(params.assoc('grant_type')).to eq(want) - build_json_response( - 'access_token' => with_access_token, - 'token_type' => 'Bearer', - 'expires_in' => 3600 - ) - end - end - end - - it_behaves_like 'apply/apply! are OK' -end From d2bff8e8ca3225cb09a925a9b829c8c79ed4aa22 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Wed, 25 Feb 2015 06:06:27 -0800 Subject: [PATCH 35/75] Updates the docker test commands --- tools/gce_setup/grpc_docker.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/tools/gce_setup/grpc_docker.sh b/tools/gce_setup/grpc_docker.sh index 231625efb3a..6da3174c06f 100755 --- a/tools/gce_setup/grpc_docker.sh +++ b/tools/gce_setup/grpc_docker.sh @@ -957,9 +957,10 @@ grpc_cloud_prod_auth_service_account_creds_gen_ruby_cmd() { local test_script="/var/local/git/grpc/src/ruby/bin/interop/interop_client.rb" local test_script+=" --use_tls" local gfe_flags=$(_grpc_prod_gfe_flags) - local added_gfe_flags=$(_grpc_svc_acc_test_flags) + local added_gfe_flags=$(_grpc_default_creds_test_flags) local env_prefix="SSL_CERT_FILE=/cacerts/roots.pem" - local the_cmd="$cmd_prefix '$env_prefix ruby $test_script $gfe_flags $added_gfe_flag $@'" + env_prefix+=" GOOGLE_APPLICATION_CREDENTIALS=/service_account/stubbyCloudTestingTest-7dd63462c60c.json" + local the_cmd="$cmd_prefix '$env_prefix ruby $test_script $gfe_flags $added_gfe_flags $@'" echo $the_cmd } @@ -1153,6 +1154,11 @@ _grpc_svc_acc_test_flags() { echo " --service_account_key_file=/service_account/stubbyCloudTestingTest-7dd63462c60c.json --oauth_scope=https://www.googleapis.com/auth/xapi.zoo" } +# default credentials test flag +_grpc_default_creds_test_flags() { + echo " --oauth_scope=https://www.googleapis.com/auth/xapi.zoo" +} + # outputs the flags passed to the gcloud auth tests _grpc_gce_test_flags() { echo " --default_service_account=155450119199-r5aaqa2vqoa9g5mv2m6s3m1l293rlmel@developer.gserviceaccount.com --oauth_scope=https://www.googleapis.com/auth/xapi.zoo" From b7a64640bbf5ccd7713716c6db37797cd2992313 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Wed, 25 Feb 2015 06:17:00 -0800 Subject: [PATCH 36/75] Fixes the GCE creds test flags --- tools/gce_setup/grpc_docker.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/gce_setup/grpc_docker.sh b/tools/gce_setup/grpc_docker.sh index 6da3174c06f..f6b8d8c2f5c 100755 --- a/tools/gce_setup/grpc_docker.sh +++ b/tools/gce_setup/grpc_docker.sh @@ -976,7 +976,7 @@ grpc_cloud_prod_auth_compute_engine_creds_gen_ruby_cmd() { local gfe_flags=$(_grpc_prod_gfe_flags) local added_gfe_flags=$(_grpc_gce_test_flags) local env_prefix="SSL_CERT_FILE=/cacerts/roots.pem" - local the_cmd="$cmd_prefix '$env_prefix ruby $test_script $gfe_flags $added_gfe_flag $@'" + local the_cmd="$cmd_prefix '$env_prefix ruby $test_script $gfe_flags $added_gfe_flags $@'" echo $the_cmd } From 8ad8a41a84bf7e17c6e9a5fd8d975370a222c0fe Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 25 Feb 2015 08:36:40 -0800 Subject: [PATCH 37/75] Introduce slowdown factor for unit test deadlines Dramatically lowers (eliminates maybe?) false negatives from ?SAN runs. --- Makefile | 10 +- templates/Makefile.template | 10 +- test/core/channel/channel_stack_test.c | 8 +- test/core/channel/metadata_buffer_test.c | 14 +- test/core/echo/client.c | 5 +- test/core/echo/server.c | 3 +- test/core/end2end/cq_verifier.c | 9 +- test/core/end2end/cq_verifier.h | 1 + test/core/end2end/dualstack_socket_test.c | 2 +- .../end2end/fixtures/chttp2_fake_security.c | 3 +- test/core/end2end/fixtures/chttp2_fullstack.c | 3 +- .../fixtures/chttp2_simple_ssl_fullstack.c | 6 +- .../chttp2_simple_ssl_with_oauth2_fullstack.c | 3 +- .../end2end/fixtures/chttp2_socket_pair.c | 3 +- .../chttp2_socket_pair_one_byte_at_a_time.c | 3 +- test/core/end2end/no_server_test.c | 3 +- test/core/end2end/tests/cancel_after_accept.c | 10 +- .../cancel_after_accept_and_writes_closed.c | 6 +- ...el_after_accept_and_writes_closed_legacy.c | 2 +- .../tests/cancel_after_accept_legacy.c | 2 +- test/core/end2end/tests/cancel_after_invoke.c | 2 +- .../tests/cancel_after_invoke_legacy.c | 2 +- .../core/end2end/tests/cancel_before_invoke.c | 5 +- .../tests/cancel_before_invoke_legacy.c | 2 +- test/core/end2end/tests/cancel_in_a_vacuum.c | 2 +- .../end2end/tests/cancel_in_a_vacuum_legacy.c | 2 +- .../end2end/tests/census_simple_request.c | 2 +- .../tests/census_simple_request_legacy.c | 2 +- test/core/end2end/tests/disappearing_server.c | 6 +- .../tests/disappearing_server_legacy.c | 2 +- ..._server_shutdown_finishes_inflight_calls.c | 6 +- ..._shutdown_finishes_inflight_calls_legacy.c | 2 +- .../early_server_shutdown_finishes_tags.c | 2 +- ...rly_server_shutdown_finishes_tags_legacy.c | 2 +- test/core/end2end/tests/empty_batch.c | 2 +- .../end2end/tests/graceful_server_shutdown.c | 6 +- .../tests/graceful_server_shutdown_legacy.c | 2 +- .../core/end2end/tests/invoke_large_request.c | 6 +- .../tests/invoke_large_request_legacy.c | 2 +- .../end2end/tests/max_concurrent_streams.c | 6 +- .../tests/max_concurrent_streams_legacy.c | 2 +- test/core/end2end/tests/no_op.c | 2 +- test/core/end2end/tests/no_op_legacy.c | 2 +- test/core/end2end/tests/ping_pong_streaming.c | 6 +- .../tests/ping_pong_streaming_legacy.c | 2 +- ...esponse_with_binary_metadata_and_payload.c | 5 +- ..._with_binary_metadata_and_payload_legacy.c | 9 +- ...quest_response_with_metadata_and_payload.c | 5 +- ...esponse_with_metadata_and_payload_legacy.c | 2 +- .../tests/request_response_with_payload.c | 5 +- .../request_response_with_payload_legacy.c | 2 +- ...ponse_with_trailing_metadata_and_payload.c | 5 +- ...ith_trailing_metadata_and_payload_legacy.c | 2 +- .../tests/request_with_large_metadata.c | 7 +- .../request_with_large_metadata_legacy.c | 4 +- .../core/end2end/tests/request_with_payload.c | 5 +- .../tests/request_with_payload_legacy.c | 2 +- .../end2end/tests/simple_delayed_request.c | 5 +- .../tests/simple_delayed_request_legacy.c | 2 +- test/core/end2end/tests/simple_request.c | 5 +- .../end2end/tests/simple_request_legacy.c | 2 +- test/core/end2end/tests/thread_stress.c | 7 +- .../core/end2end/tests/thread_stress_legacy.c | 7 +- .../writes_done_hangs_with_pending_read.c | 6 +- ...ites_done_hangs_with_pending_read_legacy.c | 6 +- test/core/httpcli/httpcli_test.c | 2 +- test/core/iomgr/alarm_list_test.c | 14 +- test/core/iomgr/alarm_test.c | 17 +- test/core/iomgr/endpoint_tests.c | 10 +- test/core/iomgr/resolve_address_test.c | 16 +- test/core/iomgr/tcp_client_posix_test.c | 11 +- test/core/iomgr/tcp_posix_test.c | 15 +- test/core/iomgr/tcp_server_posix_test.c | 2 +- test/core/json/json_rewrite.c | 31 ++-- test/core/json/json_rewrite_test.c | 63 +++----- test/core/json/json_test.c | 153 +++++++++--------- test/core/security/credentials_test.c | 26 +-- test/core/security/json_token_test.c | 12 +- .../print_google_default_creds_token.c | 3 +- test/core/security/secure_endpoint_test.c | 3 +- test/core/statistics/census_log_tests.c | 7 +- test/core/statistics/hash_table_test.c | 4 +- test/core/statistics/trace_test.c | 2 +- test/core/support/file_test.c | 1 - test/core/support/sync_test.c | 6 +- .../core/surface/completion_queue_benchmark.c | 14 +- test/core/surface/completion_queue_test.c | 22 +-- test/core/surface/lame_client_test.c | 5 +- .../core/transport/chttp2/hpack_parser_test.c | 4 +- test/core/transport/chttp2/stream_map_test.c | 6 +- .../transport/chttp2_transport_end2end_test.c | 3 +- test/core/transport/transport_end2end_tests.c | 24 ++- test/core/tsi/transport_security_test.c | 6 +- test/core/util/port_posix.c | 7 +- test/core/util/test_config.h | 14 ++ 95 files changed, 383 insertions(+), 396 deletions(-) diff --git a/Makefile b/Makefile index 277e8caebc2..e87f641afd7 100644 --- a/Makefile +++ b/Makefile @@ -77,7 +77,7 @@ LDXX_valgrind = g++ CPPFLAGS_valgrind = -O0 OPENSSL_CFLAGS_valgrind = -DPURIFY LDFLAGS_valgrind = -DEFINES_valgrind = _DEBUG DEBUG +DEFINES_valgrind = _DEBUG DEBUG GRPC_TEST_SLOWDOWN_FACTOR=20 VALID_CONFIG_tsan = 1 REQUIRE_CUSTOM_LIBRARIES_tsan = 1 @@ -87,7 +87,7 @@ LD_tsan = clang LDXX_tsan = clang++ CPPFLAGS_tsan = -O1 -fsanitize=thread -fno-omit-frame-pointer LDFLAGS_tsan = -fsanitize=thread -DEFINES_tsan = NDEBUG +DEFINES_tsan = NDEBUG GRPC_TEST_SLOWDOWN_FACTOR=10 VALID_CONFIG_asan = 1 REQUIRE_CUSTOM_LIBRARIES_asan = 1 @@ -97,7 +97,7 @@ LD_asan = clang LDXX_asan = clang++ CPPFLAGS_asan = -O1 -fsanitize=address -fno-omit-frame-pointer LDFLAGS_asan = -fsanitize=address -DEFINES_asan = NDEBUG +DEFINES_asan = NDEBUG GRPC_TEST_SLOWDOWN_FACTOR=5 VALID_CONFIG_msan = 1 REQUIRE_CUSTOM_LIBRARIES_msan = 1 @@ -108,7 +108,7 @@ LDXX_msan = clang++-libc++ CPPFLAGS_msan = -O1 -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_USE_OWN_TR1_TUPLE=1 OPENSSL_CFLAGS_msan = -DPURIFY LDFLAGS_msan = -fsanitize=memory -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_USE_OWN_TR1_TUPLE=1 -DEFINES_msan = NDEBUG +DEFINES_msan = NDEBUG GRPC_TEST_SLOWDOWN_FACTOR=20 VALID_CONFIG_ubsan = 1 REQUIRE_CUSTOM_LIBRARIES_ubsan = 1 @@ -119,7 +119,7 @@ LDXX_ubsan = clang++ CPPFLAGS_ubsan = -O1 -fsanitize=undefined -fno-omit-frame-pointer OPENSSL_CFLAGS_ubsan = -DPURIFY LDFLAGS_ubsan = -fsanitize=undefined -DEFINES_ubsan = NDEBUG +DEFINES_ubsan = NDEBUG GRPC_TEST_SLOWDOWN_FACTOR=10 VALID_CONFIG_gcov = 1 CC_gcov = gcc diff --git a/templates/Makefile.template b/templates/Makefile.template index 8240996cfc6..0984a6d008e 100644 --- a/templates/Makefile.template +++ b/templates/Makefile.template @@ -94,7 +94,7 @@ LDXX_valgrind = g++ CPPFLAGS_valgrind = -O0 OPENSSL_CFLAGS_valgrind = -DPURIFY LDFLAGS_valgrind = -DEFINES_valgrind = _DEBUG DEBUG +DEFINES_valgrind = _DEBUG DEBUG GRPC_TEST_SLOWDOWN_FACTOR=20 VALID_CONFIG_tsan = 1 REQUIRE_CUSTOM_LIBRARIES_tsan = 1 @@ -104,7 +104,7 @@ LD_tsan = clang LDXX_tsan = clang++ CPPFLAGS_tsan = -O1 -fsanitize=thread -fno-omit-frame-pointer LDFLAGS_tsan = -fsanitize=thread -DEFINES_tsan = NDEBUG +DEFINES_tsan = NDEBUG GRPC_TEST_SLOWDOWN_FACTOR=10 VALID_CONFIG_asan = 1 REQUIRE_CUSTOM_LIBRARIES_asan = 1 @@ -114,7 +114,7 @@ LD_asan = clang LDXX_asan = clang++ CPPFLAGS_asan = -O1 -fsanitize=address -fno-omit-frame-pointer LDFLAGS_asan = -fsanitize=address -DEFINES_asan = NDEBUG +DEFINES_asan = NDEBUG GRPC_TEST_SLOWDOWN_FACTOR=5 VALID_CONFIG_msan = 1 REQUIRE_CUSTOM_LIBRARIES_msan = 1 @@ -125,7 +125,7 @@ LDXX_msan = clang++-libc++ CPPFLAGS_msan = -O1 -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_USE_OWN_TR1_TUPLE=1 OPENSSL_CFLAGS_msan = -DPURIFY LDFLAGS_msan = -fsanitize=memory -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_USE_OWN_TR1_TUPLE=1 -DEFINES_msan = NDEBUG +DEFINES_msan = NDEBUG GRPC_TEST_SLOWDOWN_FACTOR=20 VALID_CONFIG_ubsan = 1 REQUIRE_CUSTOM_LIBRARIES_ubsan = 1 @@ -136,7 +136,7 @@ LDXX_ubsan = clang++ CPPFLAGS_ubsan = -O1 -fsanitize=undefined -fno-omit-frame-pointer OPENSSL_CFLAGS_ubsan = -DPURIFY LDFLAGS_ubsan = -fsanitize=undefined -DEFINES_ubsan = NDEBUG +DEFINES_ubsan = NDEBUG GRPC_TEST_SLOWDOWN_FACTOR=10 VALID_CONFIG_gcov = 1 CC_gcov = gcc diff --git a/test/core/channel/channel_stack_test.c b/test/core/channel/channel_stack_test.c index 59a4564220b..e92db592493 100644 --- a/test/core/channel/channel_stack_test.c +++ b/test/core/channel/channel_stack_test.c @@ -77,10 +77,10 @@ static void channel_func(grpc_channel_element *elem, } static void test_create_channel_stack(void) { - const grpc_channel_filter - filter = {call_func, channel_func, sizeof(int), - call_init_func, call_destroy_func, sizeof(int), - channel_init_func, channel_destroy_func, "some_test_filter" }; + const grpc_channel_filter filter = { + call_func, channel_func, sizeof(int), + call_init_func, call_destroy_func, sizeof(int), + channel_init_func, channel_destroy_func, "some_test_filter"}; const grpc_channel_filter *filters = &filter; grpc_channel_stack *channel_stack; grpc_call_stack *call_stack; diff --git a/test/core/channel/metadata_buffer_test.c b/test/core/channel/metadata_buffer_test.c index ba8100b7d2f..4fc434f9a5d 100644 --- a/test/core/channel/metadata_buffer_test.c +++ b/test/core/channel/metadata_buffer_test.c @@ -110,14 +110,14 @@ static void init_channel_elem(grpc_channel_element *elem, static void destroy_channel_elem(grpc_channel_element *elem) {} static const grpc_channel_filter top_filter = { - fail_call_op, fail_channel_op, sizeof(size_t), - init_call_elem, destroy_call_elem, sizeof(channel_data), - init_channel_elem, destroy_channel_elem, "top_filter" }; + fail_call_op, fail_channel_op, sizeof(size_t), + init_call_elem, destroy_call_elem, sizeof(channel_data), + init_channel_elem, destroy_channel_elem, "top_filter"}; static const grpc_channel_filter bottom_filter = { - expect_call_op, fail_channel_op, sizeof(size_t), - init_call_elem, destroy_call_elem, sizeof(channel_data), - init_channel_elem, destroy_channel_elem, "bottom_filter" }; + expect_call_op, fail_channel_op, sizeof(size_t), + init_call_elem, destroy_call_elem, sizeof(channel_data), + init_channel_elem, destroy_channel_elem, "bottom_filter"}; static const grpc_channel_filter *filters[2] = {&top_filter, &bottom_filter}; @@ -149,7 +149,7 @@ static void test_case(size_t key_prefix_len, size_t value_prefix_len, op.flags = i; op.data.metadata = grpc_mdelem_from_slices(mdctx, key, value); op.done_cb = do_nothing; - op.user_data = (void *)(gpr_uintptr)i; + op.user_data = (void *)(gpr_uintptr) i; grpc_metadata_buffer_queue(&buffer, &op); } diff --git a/test/core/echo/client.c b/test/core/echo/client.c index fb1e366b15b..f2b69ec3203 100644 --- a/test/core/echo/client.c +++ b/test/core/echo/client.c @@ -78,9 +78,8 @@ int main(int argc, char **argv) { GPR_ASSERT(argc == 2); channel = grpc_channel_create(argv[1], NULL); - call = grpc_channel_create_call_old( - channel, "/foo", "localhost", - gpr_time_add(gpr_time_from_seconds(5), gpr_now())); + call = grpc_channel_create_call_old(channel, "/foo", "localhost", + GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5)); GPR_ASSERT(grpc_call_invoke_old(call, cq, (void *)1, (void *)1, 0) == GRPC_CALL_OK); diff --git a/test/core/echo/server.c b/test/core/echo/server.c index 83da8b644d6..3eb6f4345a0 100644 --- a/test/core/echo/server.c +++ b/test/core/echo/server.c @@ -165,8 +165,7 @@ int main(int argc, char **argv) { grpc_completion_queue_shutdown(cq); shutdown_started = 1; } - ev = grpc_completion_queue_next( - cq, gpr_time_add(gpr_now(), gpr_time_from_micros(1000000))); + ev = grpc_completion_queue_next(cq, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1)); if (!ev) continue; s = ev->tag; switch (ev->type) { diff --git a/test/core/end2end/cq_verifier.c b/test/core/end2end/cq_verifier.c index 9ed98a43457..621ddf1dcd6 100644 --- a/test/core/end2end/cq_verifier.c +++ b/test/core/end2end/cq_verifier.c @@ -116,7 +116,8 @@ static int has_metadata(const grpc_metadata *md, size_t count, const char *key, return 0; } -int contains_metadata(grpc_metadata_array *array, const char *key, const char *value) { +int contains_metadata(grpc_metadata_array *array, const char *key, + const char *value) { return has_metadata(array->metadata, array->count, key, value); } @@ -327,8 +328,7 @@ static void fail_no_event_received(cq_verifier *v) { } void cq_verify(cq_verifier *v) { - gpr_timespec deadline = - gpr_time_add(gpr_now(), gpr_time_from_micros(10 * GPR_US_PER_SEC)); + gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10); grpc_event *ev; expectation *e; char *s; @@ -371,8 +371,7 @@ void cq_verify(cq_verifier *v) { } void cq_verify_empty(cq_verifier *v) { - gpr_timespec deadline = - gpr_time_add(gpr_now(), gpr_time_from_micros(3000000)); + gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(3); grpc_event *ev; GPR_ASSERT(v->expect.next == &v->expect && "expectation queue must be empty"); diff --git a/test/core/end2end/cq_verifier.h b/test/core/end2end/cq_verifier.h index ad6481102e7..8f1471060f8 100644 --- a/test/core/end2end/cq_verifier.h +++ b/test/core/end2end/cq_verifier.h @@ -35,6 +35,7 @@ #define __GRPC_TEST_END2END_CQ_VERIFIER_H__ #include +#include "test/core/util/test_config.h" /* A cq_verifier can verify that expected events arrive in a timely fashion on a single completion queue */ diff --git a/test/core/end2end/dualstack_socket_test.c b/test/core/end2end/dualstack_socket_test.c index 62676d01e09..e7183cc7c67 100644 --- a/test/core/end2end/dualstack_socket_test.c +++ b/test/core/end2end/dualstack_socket_test.c @@ -45,7 +45,7 @@ static void *tag(gpr_intptr i) { return (void *)i; } static gpr_timespec ms_from_now(int ms) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_MS * ms)); + return GRPC_TIMEOUT_MILLIS_TO_DEADLINE(ms); } static void drain_cq(grpc_completion_queue *cq) { diff --git a/test/core/end2end/fixtures/chttp2_fake_security.c b/test/core/end2end/fixtures/chttp2_fake_security.c index 039909f76cb..247d1fd3223 100644 --- a/test/core/end2end/fixtures/chttp2_fake_security.c +++ b/test/core/end2end/fixtures/chttp2_fake_security.c @@ -117,7 +117,8 @@ static grpc_end2end_test_config configs[] = { chttp2_create_fixture_secure_fullstack, chttp2_init_client_fake_secure_fullstack, chttp2_init_server_fake_secure_fullstack, - chttp2_tear_down_secure_fullstack}, }; + chttp2_tear_down_secure_fullstack}, +}; int main(int argc, char **argv) { size_t i; diff --git a/test/core/end2end/fixtures/chttp2_fullstack.c b/test/core/end2end/fixtures/chttp2_fullstack.c index ea367f4446b..ab7c7f4caa9 100644 --- a/test/core/end2end/fixtures/chttp2_fullstack.c +++ b/test/core/end2end/fixtures/chttp2_fullstack.c @@ -99,7 +99,8 @@ void chttp2_tear_down_fullstack(grpc_end2end_test_fixture *f) { static grpc_end2end_test_config configs[] = { {"chttp2/fullstack", FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION, chttp2_create_fixture_fullstack, chttp2_init_client_fullstack, - chttp2_init_server_fullstack, chttp2_tear_down_fullstack}, }; + chttp2_init_server_fullstack, chttp2_tear_down_fullstack}, +}; int main(int argc, char **argv) { size_t i; diff --git a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c index 9343eb5a427..16946d5f97e 100644 --- a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c +++ b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c @@ -101,8 +101,7 @@ void chttp2_tear_down_secure_fullstack(grpc_end2end_test_fixture *f) { static void chttp2_init_client_simple_ssl_secure_fullstack( grpc_end2end_test_fixture *f, grpc_channel_args *client_args) { - grpc_credentials *ssl_creds = - grpc_ssl_credentials_create(NULL, NULL); + grpc_credentials *ssl_creds = grpc_ssl_credentials_create(NULL, NULL); grpc_arg ssl_name_override = {GRPC_ARG_STRING, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG, {"foo.test.google.fr"}}; @@ -128,7 +127,8 @@ static grpc_end2end_test_config configs[] = { chttp2_create_fixture_secure_fullstack, chttp2_init_client_simple_ssl_secure_fullstack, chttp2_init_server_simple_ssl_secure_fullstack, - chttp2_tear_down_secure_fullstack}, }; + chttp2_tear_down_secure_fullstack}, +}; int main(int argc, char **argv) { size_t i; diff --git a/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c b/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c index 9fb95c95d9d..c451e01024a 100644 --- a/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c +++ b/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c @@ -133,7 +133,8 @@ static grpc_end2end_test_config configs[] = { chttp2_create_fixture_secure_fullstack, chttp2_init_client_simple_ssl_with_oauth2_secure_fullstack, chttp2_init_server_simple_ssl_secure_fullstack, - chttp2_tear_down_secure_fullstack}, }; + chttp2_tear_down_secure_fullstack}, +}; int main(int argc, char **argv) { size_t i; diff --git a/test/core/end2end/fixtures/chttp2_socket_pair.c b/test/core/end2end/fixtures/chttp2_socket_pair.c index 759c6b4b9d7..1225f7db0c2 100644 --- a/test/core/end2end/fixtures/chttp2_socket_pair.c +++ b/test/core/end2end/fixtures/chttp2_socket_pair.c @@ -133,7 +133,8 @@ static void chttp2_tear_down_socketpair(grpc_end2end_test_fixture *f) { static grpc_end2end_test_config configs[] = { {"chttp2/socketpair", 0, chttp2_create_fixture_socketpair, chttp2_init_client_socketpair, chttp2_init_server_socketpair, - chttp2_tear_down_socketpair}, }; + chttp2_tear_down_socketpair}, +}; int main(int argc, char **argv) { size_t i; diff --git a/test/core/end2end/fixtures/chttp2_socket_pair_one_byte_at_a_time.c b/test/core/end2end/fixtures/chttp2_socket_pair_one_byte_at_a_time.c index c814527a8f0..9f6ad980063 100644 --- a/test/core/end2end/fixtures/chttp2_socket_pair_one_byte_at_a_time.c +++ b/test/core/end2end/fixtures/chttp2_socket_pair_one_byte_at_a_time.c @@ -133,7 +133,8 @@ static void chttp2_tear_down_socketpair(grpc_end2end_test_fixture *f) { static grpc_end2end_test_config configs[] = { {"chttp2/socketpair_one_byte_at_a_time", 0, chttp2_create_fixture_socketpair, chttp2_init_client_socketpair, - chttp2_init_server_socketpair, chttp2_tear_down_socketpair}, }; + chttp2_init_server_socketpair, chttp2_tear_down_socketpair}, +}; int main(int argc, char **argv) { size_t i; diff --git a/test/core/end2end/no_server_test.c b/test/core/end2end/no_server_test.c index 92e8e5ad6bf..d953552c0a2 100644 --- a/test/core/end2end/no_server_test.c +++ b/test/core/end2end/no_server_test.c @@ -41,8 +41,7 @@ static void *tag(gpr_intptr i) { return (void *)i; } int main(int argc, char **argv) { grpc_channel *chan; grpc_call *call; - gpr_timespec timeout = gpr_time_from_seconds(4); - gpr_timespec deadline = gpr_time_add(gpr_now(), timeout); + gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5); grpc_completion_queue *cq; cq_verifier *cqv; grpc_event *ev; diff --git a/test/core/end2end/tests/cancel_after_accept.c b/test/core/end2end/tests/cancel_after_accept.c index 1aeb723553a..9a19abf676f 100644 --- a/test/core/end2end/tests/cancel_after_accept.c +++ b/test/core/end2end/tests/cancel_after_accept.c @@ -62,7 +62,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } @@ -163,11 +163,9 @@ static void test_cancel_after_accept(grpc_end2end_test_config config, op++; GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(c, ops, op - ops, tag(1))); - GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, &s, - &call_details, - &request_metadata_recv, - f.server_cq, - tag(2))); + GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call( + f.server, &s, &call_details, + &request_metadata_recv, f.server_cq, tag(2))); cq_expect_completion(v_server, tag(2), GRPC_OP_OK); cq_verify(v_server); diff --git a/test/core/end2end/tests/cancel_after_accept_and_writes_closed.c b/test/core/end2end/tests/cancel_after_accept_and_writes_closed.c index a69f86a3271..f360fa31a48 100644 --- a/test/core/end2end/tests/cancel_after_accept_and_writes_closed.c +++ b/test/core/end2end/tests/cancel_after_accept_and_writes_closed.c @@ -62,7 +62,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } @@ -121,8 +121,8 @@ static void test_cancel_after_accept_and_writes_closed( grpc_call_invoke_old(c, f.client_cq, tag(2), tag(3), 0)); GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); - cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", - "foo.test.google.fr", deadline, NULL); + cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr", + deadline, NULL); cq_verify(v_server); GPR_ASSERT(GRPC_CALL_OK == diff --git a/test/core/end2end/tests/cancel_after_accept_and_writes_closed_legacy.c b/test/core/end2end/tests/cancel_after_accept_and_writes_closed_legacy.c index 6a3a6528b90..f360fa31a48 100644 --- a/test/core/end2end/tests/cancel_after_accept_and_writes_closed_legacy.c +++ b/test/core/end2end/tests/cancel_after_accept_and_writes_closed_legacy.c @@ -62,7 +62,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } diff --git a/test/core/end2end/tests/cancel_after_accept_legacy.c b/test/core/end2end/tests/cancel_after_accept_legacy.c index 15338b5c7ad..904a06f8a18 100644 --- a/test/core/end2end/tests/cancel_after_accept_legacy.c +++ b/test/core/end2end/tests/cancel_after_accept_legacy.c @@ -62,7 +62,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } diff --git a/test/core/end2end/tests/cancel_after_invoke.c b/test/core/end2end/tests/cancel_after_invoke.c index 71d241ffee9..e15fa7fcd91 100644 --- a/test/core/end2end/tests/cancel_after_invoke.c +++ b/test/core/end2end/tests/cancel_after_invoke.c @@ -62,7 +62,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } diff --git a/test/core/end2end/tests/cancel_after_invoke_legacy.c b/test/core/end2end/tests/cancel_after_invoke_legacy.c index 092b35d0a9a..6ad471d6613 100644 --- a/test/core/end2end/tests/cancel_after_invoke_legacy.c +++ b/test/core/end2end/tests/cancel_after_invoke_legacy.c @@ -62,7 +62,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } diff --git a/test/core/end2end/tests/cancel_before_invoke.c b/test/core/end2end/tests/cancel_before_invoke.c index 0ab9ac6c2f2..6e100db1853 100644 --- a/test/core/end2end/tests/cancel_before_invoke.c +++ b/test/core/end2end/tests/cancel_before_invoke.c @@ -61,7 +61,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } @@ -103,7 +103,8 @@ static void end_test(grpc_end2end_test_fixture *f) { } /* Cancel before invoke */ -static void test_cancel_before_invoke(grpc_end2end_test_config config, int test_ops) { +static void test_cancel_before_invoke(grpc_end2end_test_config config, + int test_ops) { grpc_op ops[6]; grpc_op *op; grpc_call *c; diff --git a/test/core/end2end/tests/cancel_before_invoke_legacy.c b/test/core/end2end/tests/cancel_before_invoke_legacy.c index 0c308acde03..c8db3d256cf 100644 --- a/test/core/end2end/tests/cancel_before_invoke_legacy.c +++ b/test/core/end2end/tests/cancel_before_invoke_legacy.c @@ -61,7 +61,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } diff --git a/test/core/end2end/tests/cancel_in_a_vacuum.c b/test/core/end2end/tests/cancel_in_a_vacuum.c index 6cb87525d00..a88ca0b5b7a 100644 --- a/test/core/end2end/tests/cancel_in_a_vacuum.c +++ b/test/core/end2end/tests/cancel_in_a_vacuum.c @@ -60,7 +60,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } diff --git a/test/core/end2end/tests/cancel_in_a_vacuum_legacy.c b/test/core/end2end/tests/cancel_in_a_vacuum_legacy.c index cc6297b1337..a827eed72c6 100644 --- a/test/core/end2end/tests/cancel_in_a_vacuum_legacy.c +++ b/test/core/end2end/tests/cancel_in_a_vacuum_legacy.c @@ -60,7 +60,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } diff --git a/test/core/end2end/tests/census_simple_request.c b/test/core/end2end/tests/census_simple_request.c index 98244db5412..dabdc56ed3b 100644 --- a/test/core/end2end/tests/census_simple_request.c +++ b/test/core/end2end/tests/census_simple_request.c @@ -46,7 +46,7 @@ #include "test/core/end2end/cq_verifier.h" static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, diff --git a/test/core/end2end/tests/census_simple_request_legacy.c b/test/core/end2end/tests/census_simple_request_legacy.c index 98244db5412..dabdc56ed3b 100644 --- a/test/core/end2end/tests/census_simple_request_legacy.c +++ b/test/core/end2end/tests/census_simple_request_legacy.c @@ -46,7 +46,7 @@ #include "test/core/end2end/cq_verifier.h" static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, diff --git a/test/core/end2end/tests/disappearing_server.c b/test/core/end2end/tests/disappearing_server.c index d5d1550f903..a65a9f37f56 100644 --- a/test/core/end2end/tests/disappearing_server.c +++ b/test/core/end2end/tests/disappearing_server.c @@ -49,7 +49,7 @@ enum { TIMEOUT = 200000 }; static void *tag(gpr_intptr t) { return (void *)t; } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } @@ -109,8 +109,8 @@ static void do_request_and_shutdown_server(grpc_end2end_test_fixture *f, cq_verify(v_client); GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f->server, tag(100))); - cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", - "foo.test.google.fr", deadline, NULL); + cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr", + deadline, NULL); cq_verify(v_server); GPR_ASSERT(GRPC_CALL_OK == diff --git a/test/core/end2end/tests/disappearing_server_legacy.c b/test/core/end2end/tests/disappearing_server_legacy.c index 7dd6804b380..a65a9f37f56 100644 --- a/test/core/end2end/tests/disappearing_server_legacy.c +++ b/test/core/end2end/tests/disappearing_server_legacy.c @@ -49,7 +49,7 @@ enum { TIMEOUT = 200000 }; static void *tag(gpr_intptr t) { return (void *)t; } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } diff --git a/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls.c b/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls.c index d65617c4735..16ed627f378 100644 --- a/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls.c +++ b/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls.c @@ -61,7 +61,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } @@ -123,8 +123,8 @@ static void test_early_server_shutdown_finishes_inflight_calls( cq_verify(v_client); GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); - cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", - "foo.test.google.fr", deadline, NULL); + cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr", + deadline, NULL); cq_verify(v_server); GPR_ASSERT(GRPC_CALL_OK == diff --git a/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls_legacy.c b/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls_legacy.c index 09ddfc1671a..16ed627f378 100644 --- a/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls_legacy.c +++ b/test/core/end2end/tests/early_server_shutdown_finishes_inflight_calls_legacy.c @@ -61,7 +61,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } diff --git a/test/core/end2end/tests/early_server_shutdown_finishes_tags.c b/test/core/end2end/tests/early_server_shutdown_finishes_tags.c index 49dddc79759..061a2d335c2 100644 --- a/test/core/end2end/tests/early_server_shutdown_finishes_tags.c +++ b/test/core/end2end/tests/early_server_shutdown_finishes_tags.c @@ -61,7 +61,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } diff --git a/test/core/end2end/tests/early_server_shutdown_finishes_tags_legacy.c b/test/core/end2end/tests/early_server_shutdown_finishes_tags_legacy.c index ed8f839a973..bb0ef92542a 100644 --- a/test/core/end2end/tests/early_server_shutdown_finishes_tags_legacy.c +++ b/test/core/end2end/tests/early_server_shutdown_finishes_tags_legacy.c @@ -61,7 +61,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } diff --git a/test/core/end2end/tests/empty_batch.c b/test/core/end2end/tests/empty_batch.c index de22518301b..6237e29b12a 100644 --- a/test/core/end2end/tests/empty_batch.c +++ b/test/core/end2end/tests/empty_batch.c @@ -63,7 +63,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } diff --git a/test/core/end2end/tests/graceful_server_shutdown.c b/test/core/end2end/tests/graceful_server_shutdown.c index 9227d3bd463..39830b0b4b4 100644 --- a/test/core/end2end/tests/graceful_server_shutdown.c +++ b/test/core/end2end/tests/graceful_server_shutdown.c @@ -61,7 +61,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } @@ -122,8 +122,8 @@ static void test_early_server_shutdown_finishes_inflight_calls( cq_verify(v_client); GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); - cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", - "foo.test.google.fr", deadline, NULL); + cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr", + deadline, NULL); cq_verify(v_server); GPR_ASSERT(GRPC_CALL_OK == diff --git a/test/core/end2end/tests/graceful_server_shutdown_legacy.c b/test/core/end2end/tests/graceful_server_shutdown_legacy.c index 19c895eaa28..39830b0b4b4 100644 --- a/test/core/end2end/tests/graceful_server_shutdown_legacy.c +++ b/test/core/end2end/tests/graceful_server_shutdown_legacy.c @@ -61,7 +61,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } diff --git a/test/core/end2end/tests/invoke_large_request.c b/test/core/end2end/tests/invoke_large_request.c index 86a0fbdb70d..55606ca6a72 100644 --- a/test/core/end2end/tests/invoke_large_request.c +++ b/test/core/end2end/tests/invoke_large_request.c @@ -61,7 +61,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static void drain_cq(grpc_completion_queue *cq) { @@ -138,8 +138,8 @@ static void test_invoke_large_request(grpc_end2end_test_config config) { request (as this request is very large) */ cq_verify_empty(v_client); - cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", - "foo.test.google.fr", deadline, NULL); + cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr", + deadline, NULL); cq_verify(v_server); GPR_ASSERT(GRPC_CALL_OK == diff --git a/test/core/end2end/tests/invoke_large_request_legacy.c b/test/core/end2end/tests/invoke_large_request_legacy.c index d0a1cebfcb4..55606ca6a72 100644 --- a/test/core/end2end/tests/invoke_large_request_legacy.c +++ b/test/core/end2end/tests/invoke_large_request_legacy.c @@ -61,7 +61,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static void drain_cq(grpc_completion_queue *cq) { diff --git a/test/core/end2end/tests/max_concurrent_streams.c b/test/core/end2end/tests/max_concurrent_streams.c index 743048881d7..d85c9351adb 100644 --- a/test/core/end2end/tests/max_concurrent_streams.c +++ b/test/core/end2end/tests/max_concurrent_streams.c @@ -61,7 +61,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } @@ -121,8 +121,8 @@ static void simple_request_body(grpc_end2end_test_fixture f) { cq_verify(v_client); GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); - cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", - "foo.test.google.fr", deadline, NULL); + cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr", + deadline, NULL); cq_verify(v_server); GPR_ASSERT(GRPC_CALL_OK == diff --git a/test/core/end2end/tests/max_concurrent_streams_legacy.c b/test/core/end2end/tests/max_concurrent_streams_legacy.c index 8bf11543878..d85c9351adb 100644 --- a/test/core/end2end/tests/max_concurrent_streams_legacy.c +++ b/test/core/end2end/tests/max_concurrent_streams_legacy.c @@ -61,7 +61,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } diff --git a/test/core/end2end/tests/no_op.c b/test/core/end2end/tests/no_op.c index 00d940ddb54..497bdccdbd0 100644 --- a/test/core/end2end/tests/no_op.c +++ b/test/core/end2end/tests/no_op.c @@ -59,7 +59,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } diff --git a/test/core/end2end/tests/no_op_legacy.c b/test/core/end2end/tests/no_op_legacy.c index 00d940ddb54..497bdccdbd0 100644 --- a/test/core/end2end/tests/no_op_legacy.c +++ b/test/core/end2end/tests/no_op_legacy.c @@ -59,7 +59,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } diff --git a/test/core/end2end/tests/ping_pong_streaming.c b/test/core/end2end/tests/ping_pong_streaming.c index 06a029eb650..23721e91338 100644 --- a/test/core/end2end/tests/ping_pong_streaming.c +++ b/test/core/end2end/tests/ping_pong_streaming.c @@ -61,7 +61,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } @@ -127,8 +127,8 @@ static void test_pingpong_streaming(grpc_end2end_test_config config, GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); - cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", - "foo.test.google.fr", deadline, NULL); + cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr", + deadline, NULL); cq_verify(v_server); GPR_ASSERT(GRPC_CALL_OK == grpc_call_server_accept_old(s, f.server_cq, tag(102))); diff --git a/test/core/end2end/tests/ping_pong_streaming_legacy.c b/test/core/end2end/tests/ping_pong_streaming_legacy.c index b4175b4d095..23721e91338 100644 --- a/test/core/end2end/tests/ping_pong_streaming_legacy.c +++ b/test/core/end2end/tests/ping_pong_streaming_legacy.c @@ -61,7 +61,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } diff --git a/test/core/end2end/tests/request_response_with_binary_metadata_and_payload.c b/test/core/end2end/tests/request_response_with_binary_metadata_and_payload.c index 45b2ea3e823..a120f275968 100644 --- a/test/core/end2end/tests/request_response_with_binary_metadata_and_payload.c +++ b/test/core/end2end/tests/request_response_with_binary_metadata_and_payload.c @@ -61,7 +61,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } @@ -175,8 +175,7 @@ static void test_request_response_with_metadata_and_payload( GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, - f.server_cq, - tag(101))); + f.server_cq, tag(101))); cq_expect_completion(v_server, tag(101), GRPC_OP_OK); cq_verify(v_server); diff --git a/test/core/end2end/tests/request_response_with_binary_metadata_and_payload_legacy.c b/test/core/end2end/tests/request_response_with_binary_metadata_and_payload_legacy.c index be74e8bdce9..75fddeacb1f 100644 --- a/test/core/end2end/tests/request_response_with_binary_metadata_and_payload_legacy.c +++ b/test/core/end2end/tests/request_response_with_binary_metadata_and_payload_legacy.c @@ -61,7 +61,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } @@ -157,9 +157,10 @@ static void test_request_response_with_metadata_and_payload( cq_verify(v_client); cq_expect_server_rpc_new( - v_server, &s, tag(100), "/foo", "foo.test.google.fr", deadline, "key1-bin", - "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc", "key2-bin", - "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d", NULL); + v_server, &s, tag(100), "/foo", "foo.test.google.fr", deadline, + "key1-bin", "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc", + "key2-bin", "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d", + NULL); cq_verify(v_server); grpc_call_server_accept_old(s, f.server_cq, tag(102)); diff --git a/test/core/end2end/tests/request_response_with_metadata_and_payload.c b/test/core/end2end/tests/request_response_with_metadata_and_payload.c index 1675a9e5377..d5f58d33b87 100644 --- a/test/core/end2end/tests/request_response_with_metadata_and_payload.c +++ b/test/core/end2end/tests/request_response_with_metadata_and_payload.c @@ -61,7 +61,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } @@ -168,8 +168,7 @@ static void test_request_response_with_metadata_and_payload( GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, - f.server_cq, - tag(101))); + f.server_cq, tag(101))); cq_expect_completion(v_server, tag(101), GRPC_OP_OK); cq_verify(v_server); diff --git a/test/core/end2end/tests/request_response_with_metadata_and_payload_legacy.c b/test/core/end2end/tests/request_response_with_metadata_and_payload_legacy.c index 5c0b9d5b12f..91a0442d268 100644 --- a/test/core/end2end/tests/request_response_with_metadata_and_payload_legacy.c +++ b/test/core/end2end/tests/request_response_with_metadata_and_payload_legacy.c @@ -61,7 +61,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } diff --git a/test/core/end2end/tests/request_response_with_payload.c b/test/core/end2end/tests/request_response_with_payload.c index 16f07c7107b..92036590a77 100644 --- a/test/core/end2end/tests/request_response_with_payload.c +++ b/test/core/end2end/tests/request_response_with_payload.c @@ -61,7 +61,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } @@ -162,8 +162,7 @@ static void request_response_with_payload(grpc_end2end_test_fixture f) { GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, - f.server_cq, - tag(101))); + f.server_cq, tag(101))); cq_expect_completion(v_server, tag(101), GRPC_OP_OK); cq_verify(v_server); diff --git a/test/core/end2end/tests/request_response_with_payload_legacy.c b/test/core/end2end/tests/request_response_with_payload_legacy.c index 37ce89b29a5..bc9e0aec3e0 100644 --- a/test/core/end2end/tests/request_response_with_payload_legacy.c +++ b/test/core/end2end/tests/request_response_with_payload_legacy.c @@ -61,7 +61,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } diff --git a/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload.c b/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload.c index fa0d313f490..b7834a1e6ca 100644 --- a/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload.c +++ b/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload.c @@ -61,7 +61,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } @@ -169,8 +169,7 @@ static void test_request_response_with_metadata_and_payload( GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, - f.server_cq, - tag(101))); + f.server_cq, tag(101))); cq_expect_completion(v_server, tag(101), GRPC_OP_OK); cq_verify(v_server); diff --git a/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload_legacy.c b/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload_legacy.c index 5bce89a3fa6..6431ec5ad5c 100644 --- a/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload_legacy.c +++ b/test/core/end2end/tests/request_response_with_trailing_metadata_and_payload_legacy.c @@ -61,7 +61,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } diff --git a/test/core/end2end/tests/request_with_large_metadata.c b/test/core/end2end/tests/request_with_large_metadata.c index 7908493565d..c5b4e0c57ee 100644 --- a/test/core/end2end/tests/request_with_large_metadata.c +++ b/test/core/end2end/tests/request_with_large_metadata.c @@ -61,7 +61,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } @@ -134,7 +134,7 @@ static void test_request_with_large_metadata(grpc_end2end_test_config config) { meta.key = "key"; meta.value = gpr_malloc(large_size + 1); memset((char *)meta.value, 'a', large_size); - ((char*)meta.value)[large_size] = 0; + ((char *)meta.value)[large_size] = 0; meta.value_length = large_size; grpc_metadata_array_init(&initial_metadata_recv); @@ -166,8 +166,7 @@ static void test_request_with_large_metadata(grpc_end2end_test_config config) { GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, - f.server_cq, - tag(101))); + f.server_cq, tag(101))); cq_expect_completion(v_server, tag(101), GRPC_OP_OK); cq_verify(v_server); diff --git a/test/core/end2end/tests/request_with_large_metadata_legacy.c b/test/core/end2end/tests/request_with_large_metadata_legacy.c index 85926aac149..082b5ad05cb 100644 --- a/test/core/end2end/tests/request_with_large_metadata_legacy.c +++ b/test/core/end2end/tests/request_with_large_metadata_legacy.c @@ -61,7 +61,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } @@ -118,7 +118,7 @@ static void test_request_with_large_metadata(grpc_end2end_test_config config) { meta.key = "key"; meta.value = gpr_malloc(large_size + 1); memset((char *)meta.value, 'a', large_size); - ((char*)meta.value)[large_size] = 0; + ((char *)meta.value)[large_size] = 0; meta.value_length = large_size; c = grpc_channel_create_call_old(f.client, "/foo", "foo.test.google.fr", diff --git a/test/core/end2end/tests/request_with_payload.c b/test/core/end2end/tests/request_with_payload.c index 72614a0bf80..63b7c5ee40b 100644 --- a/test/core/end2end/tests/request_with_payload.c +++ b/test/core/end2end/tests/request_with_payload.c @@ -61,7 +61,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } @@ -157,8 +157,7 @@ static void test_invoke_request_with_payload(grpc_end2end_test_config config) { GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, - f.server_cq, - tag(101))); + f.server_cq, tag(101))); cq_expect_completion(v_server, tag(101), GRPC_OP_OK); cq_verify(v_server); diff --git a/test/core/end2end/tests/request_with_payload_legacy.c b/test/core/end2end/tests/request_with_payload_legacy.c index b71e682b9d9..266f9bd560a 100644 --- a/test/core/end2end/tests/request_with_payload_legacy.c +++ b/test/core/end2end/tests/request_with_payload_legacy.c @@ -61,7 +61,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } diff --git a/test/core/end2end/tests/simple_delayed_request.c b/test/core/end2end/tests/simple_delayed_request.c index 83b065b59eb..0dbb35d4546 100644 --- a/test/core/end2end/tests/simple_delayed_request.c +++ b/test/core/end2end/tests/simple_delayed_request.c @@ -49,7 +49,7 @@ enum { TIMEOUT = 200000 }; static void *tag(gpr_intptr t) { return (void *)t; } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } @@ -144,8 +144,7 @@ static void simple_delayed_request_body(grpc_end2end_test_config config, GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f->server, &s, &call_details, &request_metadata_recv, - f->server_cq, - tag(101))); + f->server_cq, tag(101))); cq_expect_completion(v_server, tag(101), GRPC_OP_OK); cq_verify(v_server); diff --git a/test/core/end2end/tests/simple_delayed_request_legacy.c b/test/core/end2end/tests/simple_delayed_request_legacy.c index 325261449af..7ab97eec3b2 100644 --- a/test/core/end2end/tests/simple_delayed_request_legacy.c +++ b/test/core/end2end/tests/simple_delayed_request_legacy.c @@ -49,7 +49,7 @@ enum { TIMEOUT = 200000 }; static void *tag(gpr_intptr t) { return (void *)t; } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } diff --git a/test/core/end2end/tests/simple_request.c b/test/core/end2end/tests/simple_request.c index dac82535be7..1263155f985 100644 --- a/test/core/end2end/tests/simple_request.c +++ b/test/core/end2end/tests/simple_request.c @@ -63,7 +63,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } @@ -150,8 +150,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) { GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(f.server, &s, &call_details, &request_metadata_recv, - f.server_cq, - tag(101))); + f.server_cq, tag(101))); cq_expect_completion(v_server, tag(101), GRPC_OP_OK); cq_verify(v_server); diff --git a/test/core/end2end/tests/simple_request_legacy.c b/test/core/end2end/tests/simple_request_legacy.c index 52dd6b08451..3e1b3f6c7c5 100644 --- a/test/core/end2end/tests/simple_request_legacy.c +++ b/test/core/end2end/tests/simple_request_legacy.c @@ -62,7 +62,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } diff --git a/test/core/end2end/tests/thread_stress.c b/test/core/end2end/tests/thread_stress.c index 996229c2282..a42956f7bc0 100644 --- a/test/core/end2end/tests/thread_stress.c +++ b/test/core/end2end/tests/thread_stress.c @@ -41,6 +41,7 @@ #include #include #include +#include "test/core/util/test_config.h" #define SERVER_THREADS 16 #define CLIENT_THREADS 16 @@ -53,7 +54,7 @@ static gpr_mu g_mu; static int g_active_requests; static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } @@ -280,11 +281,11 @@ static void run_test(grpc_end2end_test_config config, int requests_in_flight) { /* kick off threads */ for (i = 0; i < CLIENT_THREADS; i++) { gpr_event_init(&g_client_done[i]); - gpr_thd_new(&thd_id, client_thread, (void *)(gpr_intptr)i, NULL); + gpr_thd_new(&thd_id, client_thread, (void *)(gpr_intptr) i, NULL); } for (i = 0; i < SERVER_THREADS; i++) { gpr_event_init(&g_server_done[i]); - gpr_thd_new(&thd_id, server_thread, (void *)(gpr_intptr)i, NULL); + gpr_thd_new(&thd_id, server_thread, (void *)(gpr_intptr) i, NULL); } /* start requests */ diff --git a/test/core/end2end/tests/thread_stress_legacy.c b/test/core/end2end/tests/thread_stress_legacy.c index 996229c2282..a42956f7bc0 100644 --- a/test/core/end2end/tests/thread_stress_legacy.c +++ b/test/core/end2end/tests/thread_stress_legacy.c @@ -41,6 +41,7 @@ #include #include #include +#include "test/core/util/test_config.h" #define SERVER_THREADS 16 #define CLIENT_THREADS 16 @@ -53,7 +54,7 @@ static gpr_mu g_mu; static int g_active_requests; static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } @@ -280,11 +281,11 @@ static void run_test(grpc_end2end_test_config config, int requests_in_flight) { /* kick off threads */ for (i = 0; i < CLIENT_THREADS; i++) { gpr_event_init(&g_client_done[i]); - gpr_thd_new(&thd_id, client_thread, (void *)(gpr_intptr)i, NULL); + gpr_thd_new(&thd_id, client_thread, (void *)(gpr_intptr) i, NULL); } for (i = 0; i < SERVER_THREADS; i++) { gpr_event_init(&g_server_done[i]); - gpr_thd_new(&thd_id, server_thread, (void *)(gpr_intptr)i, NULL); + gpr_thd_new(&thd_id, server_thread, (void *)(gpr_intptr) i, NULL); } /* start requests */ diff --git a/test/core/end2end/tests/writes_done_hangs_with_pending_read.c b/test/core/end2end/tests/writes_done_hangs_with_pending_read.c index 0189762b5eb..75b4bfba908 100644 --- a/test/core/end2end/tests/writes_done_hangs_with_pending_read.c +++ b/test/core/end2end/tests/writes_done_hangs_with_pending_read.c @@ -61,7 +61,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } @@ -140,8 +140,8 @@ static void test_writes_done_hangs_with_pending_read( cq_verify(v_client); GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); - cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", - "foo.test.google.fr", deadline, NULL); + cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr", + deadline, NULL); cq_verify(v_server); GPR_ASSERT(GRPC_CALL_OK == diff --git a/test/core/end2end/tests/writes_done_hangs_with_pending_read_legacy.c b/test/core/end2end/tests/writes_done_hangs_with_pending_read_legacy.c index 0189762b5eb..75b4bfba908 100644 --- a/test/core/end2end/tests/writes_done_hangs_with_pending_read_legacy.c +++ b/test/core/end2end/tests/writes_done_hangs_with_pending_read_legacy.c @@ -61,7 +61,7 @@ static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, } static gpr_timespec n_seconds_time(int n) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(GPR_US_PER_SEC * n)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n); } static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); } @@ -140,8 +140,8 @@ static void test_writes_done_hangs_with_pending_read( cq_verify(v_client); GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(100))); - cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", - "foo.test.google.fr", deadline, NULL); + cq_expect_server_rpc_new(v_server, &s, tag(100), "/foo", "foo.test.google.fr", + deadline, NULL); cq_verify(v_server); GPR_ASSERT(GRPC_CALL_OK == diff --git a/test/core/httpcli/httpcli_test.c b/test/core/httpcli/httpcli_test.c index 599b3ad4eaa..17a2996baab 100644 --- a/test/core/httpcli/httpcli_test.c +++ b/test/core/httpcli/httpcli_test.c @@ -43,7 +43,7 @@ static gpr_event g_done; static gpr_timespec n_seconds_time(int seconds) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(seconds * 1000000)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(seconds); } static void on_finish(void *arg, const grpc_httpcli_response *response) { diff --git a/test/core/iomgr/alarm_list_test.c b/test/core/iomgr/alarm_list_test.c index f2ccd1fb357..684e3f579a4 100644 --- a/test/core/iomgr/alarm_list_test.c +++ b/test/core/iomgr/alarm_list_test.c @@ -61,13 +61,13 @@ static void add_test(void) { /* 10 ms alarms. will expire in the current epoch */ for (i = 0; i < 10; i++) { grpc_alarm_init(&alarms[i], gpr_time_add(start, gpr_time_from_millis(10)), - cb, (void *)(gpr_intptr)i, start); + cb, (void *)(gpr_intptr) i, start); } /* 1010 ms alarms. will expire in the next epoch */ for (i = 10; i < 20; i++) { grpc_alarm_init(&alarms[i], gpr_time_add(start, gpr_time_from_millis(1010)), - cb, (void *)(gpr_intptr)i, start); + cb, (void *)(gpr_intptr) i, start); } /* collect alarms. Only the first batch should be ready. */ @@ -115,15 +115,15 @@ void destruction_test(void) { memset(cb_called, 0, sizeof(cb_called)); grpc_alarm_init(&alarms[0], gpr_time_from_millis(100), cb, - (void *)(gpr_intptr)0, gpr_time_0); + (void *)(gpr_intptr) 0, gpr_time_0); grpc_alarm_init(&alarms[1], gpr_time_from_millis(3), cb, - (void *)(gpr_intptr)1, gpr_time_0); + (void *)(gpr_intptr) 1, gpr_time_0); grpc_alarm_init(&alarms[2], gpr_time_from_millis(100), cb, - (void *)(gpr_intptr)2, gpr_time_0); + (void *)(gpr_intptr) 2, gpr_time_0); grpc_alarm_init(&alarms[3], gpr_time_from_millis(3), cb, - (void *)(gpr_intptr)3, gpr_time_0); + (void *)(gpr_intptr) 3, gpr_time_0); grpc_alarm_init(&alarms[4], gpr_time_from_millis(1), cb, - (void *)(gpr_intptr)4, gpr_time_0); + (void *)(gpr_intptr) 4, gpr_time_0); GPR_ASSERT(1 == grpc_alarm_check(NULL, gpr_time_from_millis(2), NULL)); GPR_ASSERT(1 == cb_called[4][1]); grpc_alarm_cancel(&alarms[0]); diff --git a/test/core/iomgr/alarm_test.c b/test/core/iomgr/alarm_test.c index 18f57725a26..8d49332fa65 100644 --- a/test/core/iomgr/alarm_test.c +++ b/test/core/iomgr/alarm_test.c @@ -113,10 +113,10 @@ static void test_grpc_alarm(void) { gpr_cv_init(&arg.cv); gpr_event_init(&arg.fcb_arg); - grpc_alarm_init(&alarm, gpr_time_add(gpr_time_from_millis(100), gpr_now()), - alarm_cb, &arg, gpr_now()); + grpc_alarm_init(&alarm, GRPC_TIMEOUT_MILLIS_TO_DEADLINE(100), alarm_cb, &arg, + gpr_now()); - alarm_deadline = gpr_time_add(gpr_now(), gpr_time_from_seconds(1)); + alarm_deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1); gpr_mu_lock(&arg.mu); while (arg.done == 0) { if (gpr_cv_wait(&arg.cv, &arg.mu, alarm_deadline)) { @@ -126,7 +126,7 @@ static void test_grpc_alarm(void) { } gpr_mu_unlock(&arg.mu); - followup_deadline = gpr_time_add(gpr_now(), gpr_time_from_seconds(5)); + followup_deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5); fdone = gpr_event_wait(&arg.fcb_arg, followup_deadline); if (arg.counter != 1) { @@ -162,12 +162,11 @@ static void test_grpc_alarm(void) { gpr_cv_init(&arg2.cv); gpr_event_init(&arg2.fcb_arg); - grpc_alarm_init(&alarm_to_cancel, - gpr_time_add(gpr_time_from_millis(100), gpr_now()), alarm_cb, - &arg2, gpr_now()); + grpc_alarm_init(&alarm_to_cancel, GRPC_TIMEOUT_MILLIS_TO_DEADLINE(100), + alarm_cb, &arg2, gpr_now()); grpc_alarm_cancel(&alarm_to_cancel); - alarm_deadline = gpr_time_add(gpr_now(), gpr_time_from_seconds(1)); + alarm_deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1); gpr_mu_lock(&arg2.mu); while (arg2.done == 0) { gpr_cv_wait(&arg2.cv, &arg2.mu, alarm_deadline); @@ -176,7 +175,7 @@ static void test_grpc_alarm(void) { gpr_log(GPR_INFO, "alarm done = %d", arg2.done); - followup_deadline = gpr_time_add(gpr_now(), gpr_time_from_seconds(5)); + followup_deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5); fdone = gpr_event_wait(&arg2.fcb_arg, followup_deadline); if (arg2.counter != arg2.done_success_ctr) { diff --git a/test/core/iomgr/endpoint_tests.c b/test/core/iomgr/endpoint_tests.c index c08ee7d48f2..e63048e26c8 100644 --- a/test/core/iomgr/endpoint_tests.c +++ b/test/core/iomgr/endpoint_tests.c @@ -39,6 +39,7 @@ #include #include #include +#include "test/core/util/test_config.h" /* General test notes: @@ -211,7 +212,7 @@ static void read_and_write_test(grpc_endpoint_test_config config, size_t num_bytes, size_t write_size, size_t slice_size, int shutdown) { struct read_and_write_test_state state; - gpr_timespec deadline = gpr_time_add(gpr_now(), gpr_time_from_seconds(20)); + gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(20); grpc_endpoint_test_fixture f = begin_test(config, __FUNCTION__, slice_size); if (shutdown) { @@ -290,7 +291,7 @@ static void shutdown_during_write_test_read_handler( if (error != GRPC_ENDPOINT_CB_OK) { grpc_endpoint_destroy(st->ep); - gpr_event_set(&st->ev, (void *)(gpr_intptr)error); + gpr_event_set(&st->ev, (void *)(gpr_intptr) error); } else { grpc_endpoint_notify_on_read( st->ep, shutdown_during_write_test_read_handler, user_data); @@ -309,7 +310,7 @@ static void shutdown_during_write_test_write_handler( gpr_log(GPR_ERROR, "shutdown_during_write_test_write_handler completed unexpectedly"); } - gpr_event_set(&st->ev, (void *)(gpr_intptr)1); + gpr_event_set(&st->ev, (void *)(gpr_intptr) 1); } static void shutdown_during_write_test(grpc_endpoint_test_config config, @@ -345,8 +346,7 @@ static void shutdown_during_write_test(grpc_endpoint_test_config config, abort(); case GRPC_ENDPOINT_WRITE_PENDING: grpc_endpoint_shutdown(write_st.ep); - deadline = - gpr_time_add(gpr_now(), gpr_time_from_micros(10 * GPR_US_PER_SEC)); + deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10); GPR_ASSERT(gpr_event_wait(&write_st.ev, deadline)); grpc_endpoint_destroy(write_st.ep); GPR_ASSERT(gpr_event_wait(&read_st.ev, deadline)); diff --git a/test/core/iomgr/resolve_address_test.c b/test/core/iomgr/resolve_address_test.c index 0961a3659f6..668c5399f90 100644 --- a/test/core/iomgr/resolve_address_test.c +++ b/test/core/iomgr/resolve_address_test.c @@ -39,7 +39,7 @@ #include "test/core/util/test_config.h" static gpr_timespec test_deadline(void) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(100000000)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(100); } static void must_succeed(void* evp, grpc_resolved_addresses* p) { @@ -83,8 +83,9 @@ static void test_ipv6_with_port(void) { } static void test_ipv6_without_port(void) { - const char* const kCases[] = {"2001:db8::1", "2001:db8::1.2.3.4", - "[2001:db8::1]", }; + const char* const kCases[] = { + "2001:db8::1", "2001:db8::1.2.3.4", "[2001:db8::1]", + }; unsigned i; for (i = 0; i < sizeof(kCases) / sizeof(*kCases); i++) { gpr_event ev; @@ -95,7 +96,9 @@ static void test_ipv6_without_port(void) { } static void test_invalid_ip_addresses(void) { - const char* const kCases[] = {"293.283.1238.3:1", "[2001:db8::11111]:1", }; + const char* const kCases[] = { + "293.283.1238.3:1", "[2001:db8::11111]:1", + }; unsigned i; for (i = 0; i < sizeof(kCases) / sizeof(*kCases); i++) { gpr_event ev; @@ -106,8 +109,9 @@ static void test_invalid_ip_addresses(void) { } static void test_unparseable_hostports(void) { - const char* const kCases[] = {"[", "[::1", "[::1]bad", - "[1.2.3.4]", "[localhost]", "[localhost]:1", }; + const char* const kCases[] = { + "[", "[::1", "[::1]bad", "[1.2.3.4]", "[localhost]", "[localhost]:1", + }; unsigned i; for (i = 0; i < sizeof(kCases) / sizeof(*kCases); i++) { gpr_event ev; diff --git a/test/core/iomgr/tcp_client_posix_test.c b/test/core/iomgr/tcp_client_posix_test.c index ad5a3170448..3c4d8fed4f7 100644 --- a/test/core/iomgr/tcp_client_posix_test.c +++ b/test/core/iomgr/tcp_client_posix_test.c @@ -43,9 +43,10 @@ #include "src/core/iomgr/socket_utils_posix.h" #include #include +#include "test/core/util/test_config.h" static gpr_timespec test_deadline(void) { - return gpr_time_add(gpr_now(), gpr_time_from_seconds(10)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(10); } static void must_succeed(void *arg, grpc_endpoint *tcp) { @@ -150,13 +151,12 @@ void test_times_out(void) { /* connect to dummy server address */ - connect_deadline = gpr_time_add(gpr_now(), gpr_time_from_micros(1000000)); + connect_deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1); grpc_tcp_client_connect(must_fail, &ev, (struct sockaddr *)&addr, addr_len, connect_deadline); /* Make sure the event doesn't trigger early */ - GPR_ASSERT(!gpr_event_wait( - &ev, gpr_time_add(gpr_now(), gpr_time_from_micros(500000)))); + GPR_ASSERT(!gpr_event_wait(&ev, GRPC_TIMEOUT_MILLIS_TO_DEADLINE(500))); /* Now wait until it should have triggered */ sleep(1); @@ -168,7 +168,8 @@ void test_times_out(void) { } } -int main(void) { +int main(int argc, char **argv) { + grpc_test_init(argc, argv); grpc_iomgr_init(); test_succeeds(); gpr_log(GPR_ERROR, "End of first test"); diff --git a/test/core/iomgr/tcp_posix_test.c b/test/core/iomgr/tcp_posix_test.c index 0f81ba77344..59e525a8e1b 100644 --- a/test/core/iomgr/tcp_posix_test.c +++ b/test/core/iomgr/tcp_posix_test.c @@ -163,8 +163,7 @@ static void read_test(ssize_t num_bytes, ssize_t slice_size) { grpc_endpoint *ep; struct read_socket_state state; ssize_t written_bytes; - gpr_timespec rel_deadline = {20, 0}; - gpr_timespec deadline = gpr_time_add(gpr_now(), rel_deadline); + gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(20); gpr_log(GPR_INFO, "Read test of size %d, slice size %d", num_bytes, slice_size); @@ -206,8 +205,7 @@ static void large_read_test(ssize_t slice_size) { grpc_endpoint *ep; struct read_socket_state state; ssize_t written_bytes; - gpr_timespec rel_deadline = {20, 0}; - gpr_timespec deadline = gpr_time_add(gpr_now(), rel_deadline); + gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(20); gpr_log(GPR_INFO, "Start large read test, slice size %d", slice_size); @@ -343,8 +341,7 @@ static void write_test(ssize_t num_bytes, ssize_t slice_size) { size_t num_blocks; gpr_slice *slices; int current_data = 0; - gpr_timespec rel_deadline = {20, 0}; - gpr_timespec deadline = gpr_time_add(gpr_now(), rel_deadline); + gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(20); gpr_log(GPR_INFO, "Start write test with %d bytes, slice size %d", num_bytes, slice_size); @@ -400,8 +397,7 @@ static void write_error_test(ssize_t num_bytes, ssize_t slice_size) { size_t num_blocks; gpr_slice *slices; int current_data = 0; - gpr_timespec rel_deadline = {20, 0}; - gpr_timespec deadline = gpr_time_add(gpr_now(), rel_deadline); + gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(20); gpr_log(GPR_INFO, "Start write error test with %d bytes, slice size %d", num_bytes, slice_size); @@ -482,7 +478,8 @@ static grpc_endpoint_test_fixture create_fixture_tcp_socketpair( } static grpc_endpoint_test_config configs[] = { - {"tcp/tcp_socketpair", create_fixture_tcp_socketpair, clean_up}, }; + {"tcp/tcp_socketpair", create_fixture_tcp_socketpair, clean_up}, +}; int main(int argc, char **argv) { grpc_test_init(argc, argv); diff --git a/test/core/iomgr/tcp_server_posix_test.c b/test/core/iomgr/tcp_server_posix_test.c index b26115bcd00..2689c3f38e5 100644 --- a/test/core/iomgr/tcp_server_posix_test.c +++ b/test/core/iomgr/tcp_server_posix_test.c @@ -123,7 +123,7 @@ static void test_connect(int n) { grpc_tcp_server_start(s, NULL, 0, on_connect, NULL); for (i = 0; i < n; i++) { - deadline = gpr_time_add(gpr_now(), gpr_time_from_micros(10000000)); + deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1); nconnects_before = nconnects; clifd = socket(addr.ss_family, SOCK_STREAM, 0); diff --git a/test/core/json/json_rewrite.c b/test/core/json/json_rewrite.c index 203e75c7d57..02f60a3163c 100644 --- a/test/core/json/json_rewrite.c +++ b/test/core/json/json_rewrite.c @@ -40,9 +40,7 @@ #include "src/core/json/json_reader.h" #include "src/core/json/json_writer.h" -typedef struct json_writer_userdata { - FILE* out; -} json_writer_userdata; +typedef struct json_writer_userdata { FILE* out; } json_writer_userdata; typedef struct stacked_container { grpc_json_type type; @@ -76,11 +74,9 @@ static void json_writer_output_string_with_len(void* userdata, const char* str, fwrite(str, len, 1, state->out); } -grpc_json_writer_vtable writer_vtable = { - json_writer_output_char, - json_writer_output_string, - json_writer_output_string_with_len -}; +grpc_json_writer_vtable writer_vtable = {json_writer_output_char, + json_writer_output_string, + json_writer_output_string_with_len}; static void check_string(json_reader_userdata* state, size_t needed) { if (state->free_space >= needed) return; @@ -202,19 +198,12 @@ static void json_reader_set_null(void* userdata) { } static grpc_json_reader_vtable reader_vtable = { - json_reader_string_clear, - json_reader_string_add_char, - json_reader_string_add_utf32, - json_reader_read_char, - json_reader_container_begins, - json_reader_container_ends, - json_reader_set_key, - json_reader_set_string, - json_reader_set_number, - json_reader_set_true, - json_reader_set_false, - json_reader_set_null -}; + json_reader_string_clear, json_reader_string_add_char, + json_reader_string_add_utf32, json_reader_read_char, + json_reader_container_begins, json_reader_container_ends, + json_reader_set_key, json_reader_set_string, + json_reader_set_number, json_reader_set_true, + json_reader_set_false, json_reader_set_null}; int rewrite(FILE* in, FILE* out, int indent) { grpc_json_writer writer; diff --git a/test/core/json/json_rewrite_test.c b/test/core/json/json_rewrite_test.c index 78dff92a777..ec6deebe76c 100644 --- a/test/core/json/json_rewrite_test.c +++ b/test/core/json/json_rewrite_test.c @@ -42,9 +42,7 @@ #include "src/core/json/json_reader.h" #include "src/core/json/json_writer.h" -typedef struct json_writer_userdata { - FILE* cmp; -} json_writer_userdata; +typedef struct json_writer_userdata { FILE* cmp; } json_writer_userdata; typedef struct stacked_container { grpc_json_type type; @@ -83,11 +81,9 @@ static void json_writer_output_string_with_len(void* userdata, const char* str, } } -grpc_json_writer_vtable writer_vtable = { - json_writer_output_char, - json_writer_output_string, - json_writer_output_string_with_len -}; +grpc_json_writer_vtable writer_vtable = {json_writer_output_char, + json_writer_output_string, + json_writer_output_string_with_len}; static void check_string(json_reader_userdata* state, size_t needed) { if (state->free_space >= needed) return; @@ -216,19 +212,12 @@ static void json_reader_set_null(void* userdata) { } static grpc_json_reader_vtable reader_vtable = { - json_reader_string_clear, - json_reader_string_add_char, - json_reader_string_add_utf32, - json_reader_read_char, - json_reader_container_begins, - json_reader_container_ends, - json_reader_set_key, - json_reader_set_string, - json_reader_set_number, - json_reader_set_true, - json_reader_set_false, - json_reader_set_null -}; + json_reader_string_clear, json_reader_string_add_char, + json_reader_string_add_utf32, json_reader_read_char, + json_reader_container_begins, json_reader_container_ends, + json_reader_set_key, json_reader_set_string, + json_reader_set_number, json_reader_set_true, + json_reader_set_false, json_reader_set_null}; int rewrite_and_compare(FILE* in, FILE* cmp, int indent) { grpc_json_writer writer; @@ -275,26 +264,14 @@ typedef struct test_file { } test_file; static test_file test_files[] = { - { - "test/core/json/rewrite_test_input.json", - "test/core/json/rewrite_test_output_condensed.json", - 0 - }, - { - "test/core/json/rewrite_test_input.json", - "test/core/json/rewrite_test_output_indented.json", - 2 - }, - { - "test/core/json/rewrite_test_output_indented.json", - "test/core/json/rewrite_test_output_condensed.json", - 0 - }, - { - "test/core/json/rewrite_test_output_condensed.json", - "test/core/json/rewrite_test_output_indented.json", - 2 - }, + {"test/core/json/rewrite_test_input.json", + "test/core/json/rewrite_test_output_condensed.json", 0}, + {"test/core/json/rewrite_test_input.json", + "test/core/json/rewrite_test_output_indented.json", 2}, + {"test/core/json/rewrite_test_output_indented.json", + "test/core/json/rewrite_test_output_condensed.json", 0}, + {"test/core/json/rewrite_test_output_condensed.json", + "test/core/json/rewrite_test_output_indented.json", 2}, }; void test_rewrites() { @@ -305,8 +282,8 @@ void test_rewrites() { FILE* input = fopen(test->input, "rb"); FILE* cmp = fopen(test->cmp, "rb"); int status; - gpr_log(GPR_INFO, "Testing file %s against %s using indent=%i", - test->input, test->cmp, test->indent); + gpr_log(GPR_INFO, "Testing file %s against %s using indent=%i", test->input, + test->cmp, test->indent); status = rewrite_and_compare(input, cmp, test->indent); GPR_ASSERT(status); fclose(input); diff --git a/test/core/json/json_test.c b/test/core/json/json_test.c index bc3c7a3da84..9a50a6929ee 100644 --- a/test/core/json/json_test.c +++ b/test/core/json/json_test.c @@ -47,80 +47,83 @@ typedef struct testing_pair { } testing_pair; static testing_pair testing_pairs[] = { - /* Testing valid parsing. */ - - /* Testing trivial parses, with de-indentation. */ - { " 0 ", "0" }, - { " 1 ", "1" }, - { " \"a\" ", "\"a\"" }, - { " true ", "true" }, - /* Testing the parser's ability to decode trivial UTF-16. */ - { "\"\\u0020\\\\\\u0010\\u000a\\u000D\"", "\" \\\\\\u0010\\n\\r\"" }, - /* Testing various UTF-8 sequences. */ - { "\"ßâñć௵⇒\"", "\"\\u00df\\u00e2\\u00f1\\u0107\\u0bf5\\u21d2\"" }, - { "\"\\u00df\\u00e2\\u00f1\\u0107\\u0bf5\\u21d2\"", "\"\\u00df\\u00e2\\u00f1\\u0107\\u0bf5\\u21d2\"" }, - /* Testing UTF-8 character "𝄞", U+11D1E. */ - { "\"\xf0\x9d\x84\x9e\"", "\"\\ud834\\udd1e\"" }, - { "\"\\ud834\\udd1e\"", "\"\\ud834\\udd1e\"" }, - /* Testing nested empty containers. */ - { " [ [ ] , { } , [ ] ] ", "[[],{},[]]", }, - /* Testing escapes and control chars in key strings. */ - { " { \"\x7f\\n\\\\a , b\": 1, \"\": 0 } ", "{\"\\u007f\\n\\\\a , b\":1,\"\":0}" }, - /* Testing the writer's ability to cut off invalid UTF-8 sequences. */ - { "\"abc\xf0\x9d\x24\"", "\"abc\"" }, - { "\"\xff\"", "\"\"" }, - /* Testing valid number parsing. */ - { "[0, 42 , 0.0123, 123.456]", "[0,42,0.0123,123.456]"}, - { "[1e4,-53.235e-31, 0.3e+3]", "[1e4,-53.235e-31,0.3e+3]" }, - /* Testing keywords parsing. */ - { "[true, false, null]", "[true,false,null]" }, - - - /* Testing invalid parsing. */ - - /* Testing plain invalid things, exercising the state machine. */ - { "\\", NULL }, - { "nu ll", NULL }, - { "fals", NULL }, - /* Testing unterminated string. */ - { "\"\\x", NULL }, - /* Testing invalid UTF-16 number. */ - { "\"\\u123x", NULL }, - /* Testing imbalanced surrogate pairs. */ - { "\"\\ud834f", NULL }, - { "\"\\ud834\\n", NULL }, - { "\"\\udd1ef", NULL }, - { "\"\\ud834\\ud834\"", NULL }, - { "\"\\ud834\\u1234\"", NULL }, - /* Testing embedded invalid whitechars. */ - { "\"\n\"", NULL }, - { "\"\t\"", NULL }, - /* Testing empty json data. */ - { "", NULL }, - /* Testing extra characters after end of parsing. */ - { "{},", NULL }, - /* Testing imbalanced containers. */ - { "{}}", NULL }, - { "[]]", NULL }, - { "{{}", NULL }, - { "[[]", NULL }, - { "[}", NULL }, - { "{]", NULL }, - /*Testing trailing comma. */ - { "{,}", NULL }, - { "[1,2,3,4,]", NULL }, - /* Testing having a key syntax in an array. */ - { "[\"x\":0]", NULL }, - /* Testing invalid numbers. */ - { "1.", NULL }, - { "1e", NULL }, - { ".12", NULL }, - { "1.x", NULL }, - { "1.12x", NULL }, - { "1ex", NULL }, - { "1e12x", NULL }, - { ".12x", NULL }, - { "000", NULL }, + /* Testing valid parsing. */ + + /* Testing trivial parses, with de-indentation. */ + {" 0 ", "0"}, + {" 1 ", "1"}, + {" \"a\" ", "\"a\""}, + {" true ", "true"}, + /* Testing the parser's ability to decode trivial UTF-16. */ + {"\"\\u0020\\\\\\u0010\\u000a\\u000D\"", "\" \\\\\\u0010\\n\\r\""}, + /* Testing various UTF-8 sequences. */ + {"\"ßâñć௵⇒\"", "\"\\u00df\\u00e2\\u00f1\\u0107\\u0bf5\\u21d2\""}, + {"\"\\u00df\\u00e2\\u00f1\\u0107\\u0bf5\\u21d2\"", + "\"\\u00df\\u00e2\\u00f1\\u0107\\u0bf5\\u21d2\""}, + /* Testing UTF-8 character "𝄞", U+11D1E. */ + {"\"\xf0\x9d\x84\x9e\"", "\"\\ud834\\udd1e\""}, + {"\"\\ud834\\udd1e\"", "\"\\ud834\\udd1e\""}, + /* Testing nested empty containers. */ + { + " [ [ ] , { } , [ ] ] ", "[[],{},[]]", + }, + /* Testing escapes and control chars in key strings. */ + {" { \"\x7f\\n\\\\a , b\": 1, \"\": 0 } ", + "{\"\\u007f\\n\\\\a , b\":1,\"\":0}"}, + /* Testing the writer's ability to cut off invalid UTF-8 sequences. */ + {"\"abc\xf0\x9d\x24\"", "\"abc\""}, + {"\"\xff\"", "\"\""}, + /* Testing valid number parsing. */ + {"[0, 42 , 0.0123, 123.456]", "[0,42,0.0123,123.456]"}, + {"[1e4,-53.235e-31, 0.3e+3]", "[1e4,-53.235e-31,0.3e+3]"}, + /* Testing keywords parsing. */ + {"[true, false, null]", "[true,false,null]"}, + + /* Testing invalid parsing. */ + + /* Testing plain invalid things, exercising the state machine. */ + {"\\", NULL}, + {"nu ll", NULL}, + {"fals", NULL}, + /* Testing unterminated string. */ + {"\"\\x", NULL}, + /* Testing invalid UTF-16 number. */ + {"\"\\u123x", NULL}, + /* Testing imbalanced surrogate pairs. */ + {"\"\\ud834f", NULL}, + {"\"\\ud834\\n", NULL}, + {"\"\\udd1ef", NULL}, + {"\"\\ud834\\ud834\"", NULL}, + {"\"\\ud834\\u1234\"", NULL}, + /* Testing embedded invalid whitechars. */ + {"\"\n\"", NULL}, + {"\"\t\"", NULL}, + /* Testing empty json data. */ + {"", NULL}, + /* Testing extra characters after end of parsing. */ + {"{},", NULL}, + /* Testing imbalanced containers. */ + {"{}}", NULL}, + {"[]]", NULL}, + {"{{}", NULL}, + {"[[]", NULL}, + {"[}", NULL}, + {"{]", NULL}, + /*Testing trailing comma. */ + {"{,}", NULL}, + {"[1,2,3,4,]", NULL}, + /* Testing having a key syntax in an array. */ + {"[\"x\":0]", NULL}, + /* Testing invalid numbers. */ + {"1.", NULL}, + {"1e", NULL}, + {".12", NULL}, + {"1.x", NULL}, + {"1.12x", NULL}, + {"1ex", NULL}, + {"1e12x", NULL}, + {".12x", NULL}, + {"000", NULL}, }; static void test_pairs() { @@ -169,7 +172,7 @@ static void test_atypical() { gpr_free(scratchpad); } -int main(int argc, char **argv) { +int main(int argc, char** argv) { grpc_test_init(argc, argv); test_pairs(); test_atypical(); diff --git a/test/core/security/credentials_test.c b/test/core/security/credentials_test.c index 91229c95c25..50ef2d7657e 100644 --- a/test/core/security/credentials_test.c +++ b/test/core/security/credentials_test.c @@ -55,7 +55,8 @@ static const char test_root_cert[] = "I am the root!"; Maximum size for a string literal is 509 chars in C89, yay! */ static const char test_json_key_str_part1[] = "{ \"private_key\": \"-----BEGIN PRIVATE KEY-----" - "\\nMIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAOEvJsnoHnyHkXcp\\n7mJEqg" + "\\nMIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAOEvJsnoHnyHkXcp\\n7mJE" + "qg" "WGjiw71NfXByguekSKho65FxaGbsnSM9SMQAqVk7Q2rG+I0OpsT0LrWQtZ\\nyjSeg/" "rWBQvS4hle4LfijkP3J5BG+" "IXDMP8RfziNRQsenAXDNPkY4kJCvKux2xdD\\nOnVF6N7dL3nTYZg+" @@ -66,11 +67,14 @@ static const char test_json_key_str_part1[] = static const char test_json_key_str_part2[] = "53XxNVnxBHsYb+AYEfklR96yVi8HywjVHP34+OQZ\\nCslxoHQM8s+" "dBnjfScLu22JqkPv04xyxmt0QAKm9+vTdAkEA4ib7YvEAn2jXzcCI\\nEkoy2L/" - "XydR1GCHoacdfdAwiL2npOdnbvi4ZmdYRPY1LSTO058tQHKVXV7NLeCa3\\nAARh2QJBAMKeDAG" - "W303SQv2cZTdbeaLKJbB5drz3eo3j7dDKjrTD9JupixFbzcGw\\n8FZi5c8idxiwC36kbAL6HzA" + "XydR1GCHoacdfdAwiL2npOdnbvi4ZmdYRPY1LSTO058tQHKVXV7NLeCa3\\nAARh2QJBAMKeDA" + "G" + "W303SQv2cZTdbeaLKJbB5drz3eo3j7dDKjrTD9JupixFbzcGw\\n8FZi5c8idxiwC36kbAL6Hz" + "A" "ZoX+ofI0CQE6KCzPJTtYNqyShgKAZdJ8hwOcvCZtf\\n6z8RJm0+" "6YBd38lfh5j8mZd7aHFf6I17j5AQY7oPEc47TjJj/" - "5nZ68ECQQDvYuI3\\nLyK5fS8g0SYbmPOL9TlcHDOqwG0mrX9qpg5DC2fniXNSrrZ64GTDKdzZY" + "5nZ68ECQQDvYuI3\\nLyK5fS8g0SYbmPOL9TlcHDOqwG0mrX9qpg5DC2fniXNSrrZ64GTDKdzZ" + "Y" "Ap6LI9W\\nIqv4vr6y38N79TTC\\n-----END PRIVATE KEY-----\\n\", "; static const char test_json_key_str_part3[] = "\"private_key_id\": \"e6b5137873db8d2ef81e06a47289e6434ec8a165\", " @@ -614,9 +618,10 @@ static void test_service_account_creds_signing_failure(void) { grpc_jwt_encode_and_sign_set_override(NULL); } -static void on_jwt_creds_get_metadata_success( - void *user_data, grpc_mdelem **md_elems, size_t num_md, - grpc_credentials_status status) { +static void on_jwt_creds_get_metadata_success(void *user_data, + grpc_mdelem **md_elems, + size_t num_md, + grpc_credentials_status status) { char *expected_md_value; gpr_asprintf(&expected_md_value, "Bearer %s", test_signed_jwt); GPR_ASSERT(status == GRPC_CREDENTIALS_OK); @@ -630,9 +635,10 @@ static void on_jwt_creds_get_metadata_success( gpr_free(expected_md_value); } -static void on_jwt_creds_get_metadata_failure( - void *user_data, grpc_mdelem **md_elems, size_t num_md, - grpc_credentials_status status) { +static void on_jwt_creds_get_metadata_failure(void *user_data, + grpc_mdelem **md_elems, + size_t num_md, + grpc_credentials_status status) { GPR_ASSERT(status == GRPC_CREDENTIALS_ERROR); GPR_ASSERT(num_md == 0); GPR_ASSERT(user_data != NULL); diff --git a/test/core/security/json_token_test.c b/test/core/security/json_token_test.c index eed0fdf3321..fae911721ad 100644 --- a/test/core/security/json_token_test.c +++ b/test/core/security/json_token_test.c @@ -49,7 +49,8 @@ Maximum size for a string literal is 509 chars in C89, yay! */ static const char test_json_key_str_part1[] = "{ \"private_key\": \"-----BEGIN PRIVATE KEY-----" - "\\nMIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAOEvJsnoHnyHkXcp\\n7mJEqg" + "\\nMIICeAIBADANBgkqhkiG9w0BAQEFAASCAmIwggJeAgEAAoGBAOEvJsnoHnyHkXcp\\n7mJE" + "qg" "WGjiw71NfXByguekSKho65FxaGbsnSM9SMQAqVk7Q2rG+I0OpsT0LrWQtZ\\nyjSeg/" "rWBQvS4hle4LfijkP3J5BG+" "IXDMP8RfziNRQsenAXDNPkY4kJCvKux2xdD\\nOnVF6N7dL3nTYZg+" @@ -60,11 +61,14 @@ static const char test_json_key_str_part1[] = static const char test_json_key_str_part2[] = "53XxNVnxBHsYb+AYEfklR96yVi8HywjVHP34+OQZ\\nCslxoHQM8s+" "dBnjfScLu22JqkPv04xyxmt0QAKm9+vTdAkEA4ib7YvEAn2jXzcCI\\nEkoy2L/" - "XydR1GCHoacdfdAwiL2npOdnbvi4ZmdYRPY1LSTO058tQHKVXV7NLeCa3\\nAARh2QJBAMKeDAG" - "W303SQv2cZTdbeaLKJbB5drz3eo3j7dDKjrTD9JupixFbzcGw\\n8FZi5c8idxiwC36kbAL6HzA" + "XydR1GCHoacdfdAwiL2npOdnbvi4ZmdYRPY1LSTO058tQHKVXV7NLeCa3\\nAARh2QJBAMKeDA" + "G" + "W303SQv2cZTdbeaLKJbB5drz3eo3j7dDKjrTD9JupixFbzcGw\\n8FZi5c8idxiwC36kbAL6Hz" + "A" "ZoX+ofI0CQE6KCzPJTtYNqyShgKAZdJ8hwOcvCZtf\\n6z8RJm0+" "6YBd38lfh5j8mZd7aHFf6I17j5AQY7oPEc47TjJj/" - "5nZ68ECQQDvYuI3\\nLyK5fS8g0SYbmPOL9TlcHDOqwG0mrX9qpg5DC2fniXNSrrZ64GTDKdzZY" + "5nZ68ECQQDvYuI3\\nLyK5fS8g0SYbmPOL9TlcHDOqwG0mrX9qpg5DC2fniXNSrrZ64GTDKdzZ" + "Y" "Ap6LI9W\\nIqv4vr6y38N79TTC\\n-----END PRIVATE KEY-----\\n\", "; static const char test_json_key_str_part3[] = "\"private_key_id\": \"e6b5137873db8d2ef81e06a47289e6434ec8a165\", " diff --git a/test/core/security/print_google_default_creds_token.c b/test/core/security/print_google_default_creds_token.c index cfd62cf6ccb..76e69ef7163 100644 --- a/test/core/security/print_google_default_creds_token.c +++ b/test/core/security/print_google_default_creds_token.c @@ -73,8 +73,7 @@ int main(int argc, char **argv) { char *service_url = "https://test.foo.google.com/Foo"; gpr_cmdline *cl = gpr_cmdline_create("print_google_default_creds_token"); gpr_cmdline_add_string(cl, "service_url", - "Service URL for the token request.", - &service_url); + "Service URL for the token request.", &service_url); gpr_cmdline_parse(cl, argc, argv); grpc_init(); diff --git a/test/core/security/secure_endpoint_test.c b/test/core/security/secure_endpoint_test.c index 03a4d3a1e69..f7bd3cb4ae0 100644 --- a/test/core/security/secure_endpoint_test.c +++ b/test/core/security/secure_endpoint_test.c @@ -130,7 +130,8 @@ static grpc_endpoint_test_config configs[] = { {"secure_ep/tcp_socketpair", secure_endpoint_create_fixture_tcp_socketpair_noleftover, clean_up}, {"secure_ep/tcp_socketpair_leftover", - secure_endpoint_create_fixture_tcp_socketpair_leftover, clean_up}, }; + secure_endpoint_create_fixture_tcp_socketpair_leftover, clean_up}, +}; static void verify_leftover(void *user_data, gpr_slice *slices, size_t nslices, grpc_endpoint_cb_status error) { diff --git a/test/core/statistics/census_log_tests.c b/test/core/statistics/census_log_tests.c index fbc96bbde61..241ec1ce4f4 100644 --- a/test/core/statistics/census_log_tests.c +++ b/test/core/statistics/census_log_tests.c @@ -42,6 +42,7 @@ #include #include #include +#include "test/core/util/test_config.h" /* Fills in 'record' of size 'size'. Each byte in record is filled in with the same value. The value is extracted from 'record' pointer. */ @@ -123,8 +124,8 @@ static void assert_log_empty(void) { /* Given log size and record size, computes the minimum usable space. */ static gpr_int32 min_usable_space(size_t log_size, size_t record_size) { gpr_int32 usable_space; - gpr_int32 num_blocks = GPR_MAX(log_size / CENSUS_LOG_MAX_RECORD_SIZE, - gpr_cpu_num_cores()); + gpr_int32 num_blocks = + GPR_MAX(log_size / CENSUS_LOG_MAX_RECORD_SIZE, gpr_cpu_num_cores()); gpr_int32 waste_per_block = CENSUS_LOG_MAX_RECORD_SIZE % record_size; /* In the worst case, all except one core-local block is full. */ gpr_int32 num_full_blocks = num_blocks - 1; @@ -198,7 +199,7 @@ static void writer_thread(void* arg) { This should never happen for circular logs. */ printf(" Writer stalled due to out-of-space: %d out of %d written\n", records_written, args->num_records); - gpr_sleep_until(gpr_time_add(gpr_now(), gpr_time_from_micros(10000))); + gpr_sleep_until(GRPC_TIMEOUT_MILLIS_TO_DEADLINE(10)); } } /* Done. Decrement count and signal. */ diff --git a/test/core/statistics/hash_table_test.c b/test/core/statistics/hash_table_test.c index 2752d6d89d5..1e9e1c8d236 100644 --- a/test/core/statistics/hash_table_test.c +++ b/test/core/statistics/hash_table_test.c @@ -97,7 +97,7 @@ static void test_table_with_int_key(void) { for (i = 0; i < 20; ++i) { census_ht_key key; key.val = i; - census_ht_insert(ht, key, (void*)(gpr_intptr)i); + census_ht_insert(ht, key, (void*)(gpr_intptr) i); GPR_ASSERT(census_ht_get_size(ht) == i + 1); } for (i = 0; i < 20; i++) { @@ -105,7 +105,7 @@ static void test_table_with_int_key(void) { census_ht_key key; key.val = i; val = census_ht_find(ht, key); - GPR_ASSERT(val == (void*)(gpr_intptr)i); + GPR_ASSERT(val == (void*)(gpr_intptr) i); } elements = census_ht_get_all_elements(ht, &num_elements); GPR_ASSERT(elements != NULL); diff --git a/test/core/statistics/trace_test.c b/test/core/statistics/trace_test.c index 65b70e1006a..b13fd03f70b 100644 --- a/test/core/statistics/trace_test.c +++ b/test/core/statistics/trace_test.c @@ -111,7 +111,7 @@ static void mimic_trace_op_sequences(void* arg) { id = census_tracing_start_op(); census_add_method_tag(id, method_name); /* pretend doing 1us work. */ - gpr_sleep_until(gpr_time_add(gpr_now(), gpr_time_from_micros(1))); + gpr_sleep_until(GRPC_TIMEOUT_MICROS_TO_DEADLINE(1)); census_tracing_end_op(id); } gpr_log(GPR_INFO, "End trace op sequence thread."); diff --git a/test/core/support/file_test.c b/test/core/support/file_test.c index c0c14ffa0e5..dd8caf7a80d 100644 --- a/test/core/support/file_test.c +++ b/test/core/support/file_test.c @@ -148,7 +148,6 @@ static void test_load_big_file(void) { gpr_slice_unref(slice); } - int main(int argc, char **argv) { grpc_test_init(argc, argv); test_load_empty_file(); diff --git a/test/core/support/sync_test.c b/test/core/support/sync_test.c index 43d05c6302b..44bc6ba4711 100644 --- a/test/core/support/sync_test.c +++ b/test/core/support/sync_test.c @@ -56,9 +56,9 @@ typedef struct queue { (That is, except during initialization or destruction, the fields below should be accessed only by a thread that holds mu.) */ - int head; /* Index of head of queue 0..N-1. */ - int length; /* Number of valid elements in queue 0..N. */ - int elem[N]; /* elem[head .. head+length-1] are queue elements. */ + int head; /* Index of head of queue 0..N-1. */ + int length; /* Number of valid elements in queue 0..N. */ + int elem[N]; /* elem[head .. head+length-1] are queue elements. */ } queue; /* Initialize *q. */ diff --git a/test/core/surface/completion_queue_benchmark.c b/test/core/surface/completion_queue_benchmark.c index 9116fd0fe4c..81ebe15415f 100644 --- a/test/core/surface/completion_queue_benchmark.c +++ b/test/core/surface/completion_queue_benchmark.c @@ -53,23 +53,23 @@ static void producer_thread(void *arg) { test_thread_options *opt = arg; int i; - gpr_event_set(&opt->on_started, (void *)(gpr_intptr)1); + gpr_event_set(&opt->on_started, (void *)(gpr_intptr) 1); GPR_ASSERT(gpr_event_wait(opt->start, gpr_inf_future)); for (i = 0; i < opt->iterations; i++) { grpc_cq_begin_op(opt->cc, NULL, GRPC_WRITE_ACCEPTED); - grpc_cq_end_write_accepted(opt->cc, (void *)(gpr_intptr)1, NULL, NULL, NULL, - GRPC_OP_OK); + grpc_cq_end_write_accepted(opt->cc, (void *)(gpr_intptr) 1, NULL, NULL, + NULL, GRPC_OP_OK); } - gpr_event_set(&opt->on_finished, (void *)(gpr_intptr)1); + gpr_event_set(&opt->on_finished, (void *)(gpr_intptr) 1); } static void consumer_thread(void *arg) { test_thread_options *opt = arg; grpc_event *ev; - gpr_event_set(&opt->on_started, (void *)(gpr_intptr)1); + gpr_event_set(&opt->on_started, (void *)(gpr_intptr) 1); GPR_ASSERT(gpr_event_wait(opt->start, gpr_inf_future)); for (;;) { @@ -78,7 +78,7 @@ static void consumer_thread(void *arg) { case GRPC_WRITE_ACCEPTED: break; case GRPC_QUEUE_SHUTDOWN: - gpr_event_set(&opt->on_finished, (void *)(gpr_intptr)1); + gpr_event_set(&opt->on_finished, (void *)(gpr_intptr) 1); return; default: gpr_log(GPR_ERROR, "Invalid event received: %d", ev->type); @@ -112,7 +112,7 @@ double ops_per_second(int consumers, int producers, int iterations) { /* start the benchmark */ t_start = gpr_now(); - gpr_event_set(&start, (void *)(gpr_intptr)1); + gpr_event_set(&start, (void *)(gpr_intptr) 1); /* wait for producers to finish */ for (i = 0; i < producers; i++) { diff --git a/test/core/surface/completion_queue_test.c b/test/core/surface/completion_queue_test.c index 35f150c7815..414ca2eac9c 100644 --- a/test/core/surface/completion_queue_test.c +++ b/test/core/surface/completion_queue_test.c @@ -248,7 +248,7 @@ typedef struct test_thread_options { } test_thread_options; gpr_timespec ten_seconds_time(void) { - return gpr_time_add(gpr_now(), gpr_time_from_micros(10 * 1000000)); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1); } static void producer_thread(void *arg) { @@ -256,7 +256,7 @@ static void producer_thread(void *arg) { int i; gpr_log(GPR_INFO, "producer %d started", opt->id); - gpr_event_set(&opt->on_started, (void *)(gpr_intptr)1); + gpr_event_set(&opt->on_started, (void *)(gpr_intptr) 1); GPR_ASSERT(gpr_event_wait(opt->phase1, ten_seconds_time())); gpr_log(GPR_INFO, "producer %d phase 1", opt->id); @@ -265,18 +265,18 @@ static void producer_thread(void *arg) { } gpr_log(GPR_INFO, "producer %d phase 1 done", opt->id); - gpr_event_set(&opt->on_phase1_done, (void *)(gpr_intptr)1); + gpr_event_set(&opt->on_phase1_done, (void *)(gpr_intptr) 1); GPR_ASSERT(gpr_event_wait(opt->phase2, ten_seconds_time())); gpr_log(GPR_INFO, "producer %d phase 2", opt->id); for (i = 0; i < TEST_THREAD_EVENTS; i++) { - grpc_cq_end_write_accepted(opt->cc, (void *)(gpr_intptr)1, NULL, NULL, NULL, - GRPC_OP_OK); + grpc_cq_end_write_accepted(opt->cc, (void *)(gpr_intptr) 1, NULL, NULL, + NULL, GRPC_OP_OK); opt->events_triggered++; } gpr_log(GPR_INFO, "producer %d phase 2 done", opt->id); - gpr_event_set(&opt->on_finished, (void *)(gpr_intptr)1); + gpr_event_set(&opt->on_finished, (void *)(gpr_intptr) 1); } static void consumer_thread(void *arg) { @@ -284,13 +284,13 @@ static void consumer_thread(void *arg) { grpc_event *ev; gpr_log(GPR_INFO, "consumer %d started", opt->id); - gpr_event_set(&opt->on_started, (void *)(gpr_intptr)1); + gpr_event_set(&opt->on_started, (void *)(gpr_intptr) 1); GPR_ASSERT(gpr_event_wait(opt->phase1, ten_seconds_time())); gpr_log(GPR_INFO, "consumer %d phase 1", opt->id); gpr_log(GPR_INFO, "consumer %d phase 1 done", opt->id); - gpr_event_set(&opt->on_phase1_done, (void *)(gpr_intptr)1); + gpr_event_set(&opt->on_phase1_done, (void *)(gpr_intptr) 1); GPR_ASSERT(gpr_event_wait(opt->phase2, ten_seconds_time())); gpr_log(GPR_INFO, "consumer %d phase 2", opt->id); @@ -305,7 +305,7 @@ static void consumer_thread(void *arg) { break; case GRPC_QUEUE_SHUTDOWN: gpr_log(GPR_INFO, "consumer %d phase 2 done", opt->id); - gpr_event_set(&opt->on_finished, (void *)(gpr_intptr)1); + gpr_event_set(&opt->on_finished, (void *)(gpr_intptr) 1); grpc_event_finish(ev); return; default: @@ -350,7 +350,7 @@ static void test_threading(int producers, int consumers) { /* start phase1: producers will pre-declare all operations they will complete */ gpr_log(GPR_INFO, "start phase 1"); - gpr_event_set(&phase1, (void *)(gpr_intptr)1); + gpr_event_set(&phase1, (void *)(gpr_intptr) 1); gpr_log(GPR_INFO, "wait phase 1"); for (i = 0; i < producers + consumers; i++) { @@ -360,7 +360,7 @@ static void test_threading(int producers, int consumers) { /* start phase2: operations will complete, and consumers will consume them */ gpr_log(GPR_INFO, "start phase 2"); - gpr_event_set(&phase2, (void *)(gpr_intptr)1); + gpr_event_set(&phase2, (void *)(gpr_intptr) 1); /* in parallel, we shutdown the completion channel - all events should still be consumed */ diff --git a/test/core/surface/lame_client_test.c b/test/core/surface/lame_client_test.c index 0142768261d..3653c5a1b0d 100644 --- a/test/core/surface/lame_client_test.c +++ b/test/core/surface/lame_client_test.c @@ -51,9 +51,8 @@ int main(int argc, char **argv) { chan = grpc_lame_client_channel_create(); GPR_ASSERT(chan); - call = grpc_channel_create_call_old( - chan, "/Foo", "anywhere", - gpr_time_add(gpr_now(), gpr_time_from_seconds(100))); + call = grpc_channel_create_call_old(chan, "/Foo", "anywhere", + GRPC_TIMEOUT_SECONDS_TO_DEADLINE(100)); GPR_ASSERT(call); cq = grpc_completion_queue_create(); cqv = cq_verifier_create(cq); diff --git a/test/core/transport/chttp2/hpack_parser_test.c b/test/core/transport/chttp2/hpack_parser_test.c index 86c6bb1f56a..1d6ad2a758e 100644 --- a/test/core/transport/chttp2/hpack_parser_test.c +++ b/test/core/transport/chttp2/hpack_parser_test.c @@ -42,9 +42,7 @@ #include "test/core/util/slice_splitter.h" #include "test/core/util/test_config.h" -typedef struct { - va_list args; -} test_checker; +typedef struct { va_list args; } test_checker; static void onhdr(void *ud, grpc_mdelem *md) { const char *ekey, *evalue; diff --git a/test/core/transport/chttp2/stream_map_test.c b/test/core/transport/chttp2/stream_map_test.c index 49d58114f87..6b91bdf14fd 100644 --- a/test/core/transport/chttp2/stream_map_test.c +++ b/test/core/transport/chttp2/stream_map_test.c @@ -93,7 +93,7 @@ static void test_basic_add_find(size_t n) { grpc_chttp2_stream_map_init(&map, 8); GPR_ASSERT(0 == grpc_chttp2_stream_map_size(&map)); for (i = 1; i <= n; i++) { - grpc_chttp2_stream_map_add(&map, i, (void *)(gpr_uintptr)i); + grpc_chttp2_stream_map_add(&map, i, (void *)(gpr_uintptr) i); } GPR_ASSERT(n == grpc_chttp2_stream_map_size(&map)); GPR_ASSERT(NULL == grpc_chttp2_stream_map_find(&map, 0)); @@ -148,7 +148,7 @@ static void test_delete_evens_sweep(size_t n) { grpc_chttp2_stream_map_init(&map, 8); for (i = 1; i <= n; i++) { - grpc_chttp2_stream_map_add(&map, i, (void *)(gpr_uintptr)i); + grpc_chttp2_stream_map_add(&map, i, (void *)(gpr_uintptr) i); } for (i = 1; i <= n; i++) { if ((i & 1) == 0) { @@ -170,7 +170,7 @@ static void test_delete_evens_incremental(size_t n) { grpc_chttp2_stream_map_init(&map, 8); for (i = 1; i <= n; i++) { - grpc_chttp2_stream_map_add(&map, i, (void *)(gpr_uintptr)i); + grpc_chttp2_stream_map_add(&map, i, (void *)(gpr_uintptr) i); if ((i & 1) == 0) { grpc_chttp2_stream_map_delete(&map, i); } diff --git a/test/core/transport/chttp2_transport_end2end_test.c b/test/core/transport/chttp2_transport_end2end_test.c index a3c9f97ce4c..b90fe229999 100644 --- a/test/core/transport/chttp2_transport_end2end_test.c +++ b/test/core/transport/chttp2_transport_end2end_test.c @@ -100,7 +100,8 @@ grpc_transport_test_config fixture_configs[] = { {"chttp2_on_socketpair/medium", create_http2_transport_for_test_medium_slices}, {"chttp2_on_socketpair/large", - create_http2_transport_for_test_large_slices}, }; + create_http2_transport_for_test_large_slices}, +}; /* Driver function: run the test suite for each test configuration */ int main(int argc, char **argv) { diff --git a/test/core/transport/transport_end2end_tests.c b/test/core/transport/transport_end2end_tests.c index 6d13bf1f8c9..437a1c3ef55 100644 --- a/test/core/transport/transport_end2end_tests.c +++ b/test/core/transport/transport_end2end_tests.c @@ -43,8 +43,7 @@ #include #include #include - -enum { REQUEST_DEADLINE = 200000 }; /* valgrind need a large value */ +#include "test/core/util/test_config.h" static grpc_mdctx *g_metadata_context; @@ -63,9 +62,7 @@ static int g_pending_ops; typedef struct test_fixture test_fixture; /* User data passed to the transport and handed to each callback */ -typedef struct test_user_data { - test_fixture *fixture; -} test_user_data; +typedef struct test_user_data { test_fixture *fixture; } test_user_data; /* A message we expect to receive (forms a singly linked list with next) */ typedef struct expected_message { @@ -131,8 +128,7 @@ static void expect_metadata(test_stream *s, int from_client, const char *key, /* Convert some number of seconds into a gpr_timespec that many seconds in the future */ static gpr_timespec deadline_from_seconds(double deadline_seconds) { - return gpr_time_add(gpr_now(), - gpr_time_from_micros((long)(deadline_seconds * 1e6))); + return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(deadline_seconds); } /* Init a test_user_data instance */ @@ -576,7 +572,7 @@ static grpc_transport_setup_result setup_client_transport( name - the name of this test */ static void begin_test(test_fixture *f, grpc_transport_test_config *config, const char *name) { - gpr_timespec timeout = gpr_time_add(gpr_now(), gpr_time_from_seconds(100)); + gpr_timespec timeout = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(100); gpr_log(GPR_INFO, "BEGIN: %s/%s", name, config->name); @@ -591,9 +587,10 @@ static void begin_test(test_fixture *f, grpc_transport_test_config *config, f->client_transport = NULL; f->server_transport = NULL; - GPR_ASSERT(0 == config->create_transport(setup_client_transport, f, - setup_server_transport, f, - g_metadata_context)); + GPR_ASSERT(0 == + config->create_transport(setup_client_transport, f, + setup_server_transport, f, + g_metadata_context)); gpr_mu_lock(&f->mu); while (!f->client_transport || !f->server_transport) { @@ -909,8 +906,9 @@ static void test_ping(grpc_transport_test_config *config) { * Test driver */ -static const size_t interesting_message_lengths[] = {1, 100, 10000, - 100000, 1000000, }; +static const size_t interesting_message_lengths[] = { + 1, 100, 10000, 100000, 1000000, +}; void grpc_transport_end2end_tests(grpc_transport_test_config *config) { unsigned i; diff --git a/test/core/tsi/transport_security_test.c b/test/core/tsi/transport_security_test.c index 597b390c9b9..c5882af966c 100644 --- a/test/core/tsi/transport_security_test.c +++ b/test/core/tsi/transport_security_test.c @@ -189,9 +189,9 @@ typedef struct name_list { } name_list; typedef struct { - size_t name_count; - char *buffer; - name_list *names; + size_t name_count; + char *buffer; + name_list *names; } parsed_dns_names; name_list *name_list_add(const char *n) { diff --git a/test/core/util/port_posix.c b/test/core/util/port_posix.c index f0fe1a0e7c3..0b6e7918acc 100644 --- a/test/core/util/port_posix.c +++ b/test/core/util/port_posix.c @@ -113,11 +113,12 @@ int grpc_pick_unused_port(void) { /* Type of port to first pick in next iteration */ int is_tcp = 1; - int try = 0; + int try + = 0; for (;;) { - int port = - try < NUM_RANDOM_PORTS_TO_PICK ? rand() % (65536 - 30000) + 30000 : 0; + int port = try + < NUM_RANDOM_PORTS_TO_PICK ? rand() % (65536 - 30000) + 30000 : 0; if (!is_port_available(&port, is_tcp)) { continue; } diff --git a/test/core/util/test_config.h b/test/core/util/test_config.h index b97fbfa6138..74c2a3cf1b1 100644 --- a/test/core/util/test_config.h +++ b/test/core/util/test_config.h @@ -34,10 +34,24 @@ #ifndef __GRPC_TEST_UTIL_TEST_CONFIG_H__ #define __GRPC_TEST_UTIL_TEST_CONFIG_H__ +#include + #ifdef __cplusplus extern "C" { #endif /* __cplusplus */ +#ifndef GRPC_TEST_SLOWDOWN_FACTOR +#define GRPC_TEST_SLOWDOWN_FACTOR 1.0 +#endif + +#define GRPC_TIMEOUT_SECONDS_TO_DEADLINE(x) \ + gpr_time_add(gpr_now(), \ + gpr_time_from_micros(GRPC_TEST_SLOWDOWN_FACTOR * 1e6 * (x))) + +#define GRPC_TIMEOUT_MILLIS_TO_DEADLINE(x) \ + gpr_time_add(gpr_now(), \ + gpr_time_from_micros(GRPC_TEST_SLOWDOWN_FACTOR * 1e3 * (x))) + void grpc_test_init(int argc, char **argv); #ifdef __cplusplus From 4b5c4dbbb8c63a959c2c806b01973fa608031f1e Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 25 Feb 2015 08:51:18 -0800 Subject: [PATCH 38/75] Drastic speed up --- test/core/end2end/cq_verifier.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/core/end2end/cq_verifier.c b/test/core/end2end/cq_verifier.c index 621ddf1dcd6..9369dfd7ec6 100644 --- a/test/core/end2end/cq_verifier.c +++ b/test/core/end2end/cq_verifier.c @@ -371,7 +371,7 @@ void cq_verify(cq_verifier *v) { } void cq_verify_empty(cq_verifier *v) { - gpr_timespec deadline = GRPC_TIMEOUT_SECONDS_TO_DEADLINE(3); + gpr_timespec deadline = gpr_time_add(gpr_now(), gpr_time_from_seconds(1)); grpc_event *ev; GPR_ASSERT(v->expect.next == &v->expect && "expectation queue must be empty"); From c1f1162787a84abdbc6cbe1717909692fad41261 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 25 Feb 2015 09:09:59 -0800 Subject: [PATCH 39/75] Drastic speed up --- test/core/echo/server.c | 3 ++- tools/run_tests/run_tests.py | 3 +-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/core/echo/server.c b/test/core/echo/server.c index 3eb6f4345a0..bc84645a040 100644 --- a/test/core/echo/server.c +++ b/test/core/echo/server.c @@ -165,7 +165,8 @@ int main(int argc, char **argv) { grpc_completion_queue_shutdown(cq); shutdown_started = 1; } - ev = grpc_completion_queue_next(cq, GRPC_TIMEOUT_SECONDS_TO_DEADLINE(1)); + ev = grpc_completion_queue_next( + cq, gpr_time_add(gpr_now(), gpr_time_from_seconds(1))); if (!ev) continue; s = ev->tag; switch (ev->type) { diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index 7732466d6ea..7c6a050a675 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -232,6 +232,7 @@ class TestCache(object): def finished(self, cmdline, bin_hash): self._last_successful_run[cmdline] = bin_hash + self.save() def dump(self): return [{'cmdline': k, 'hash': v} @@ -286,7 +287,6 @@ if forever: 'All tests are now passing properly', do_newline=True) jobset.message('IDLE', 'No change detected') - test_cache.save() while not have_files_changed(): time.sleep(1) else: @@ -297,5 +297,4 @@ else: jobset.message('SUCCESS', 'All tests passed', do_newline=True) else: jobset.message('FAILED', 'Some tests failed', do_newline=True) - test_cache.save() sys.exit(result) From 9280790a5d5817855463d8a940d386954dc62ce1 Mon Sep 17 00:00:00 2001 From: Nathaniel Manista Date: Wed, 25 Feb 2015 17:14:11 +0000 Subject: [PATCH 40/75] Final changes to the early_adopter API. This makes grpc.early_adopter much more independent of RPC Framework and cleaner at the cost of reexporting most of the interfaces and writing several delegation classes. --- src/python/interop/interop/methods.py | 34 +-- .../grpc/early_adopter/_assembly_utilities.py | 168 +++++++++++ .../src/grpc/early_adopter/_face_utilities.py | 178 ------------ .../src/grpc/early_adopter/_reexport.py | 207 +++++++++++++ .../src/grpc/early_adopter/exceptions.py | 48 ++++ .../src/grpc/early_adopter/implementations.py | 145 +++++++--- .../early_adopter/implementations_test.py | 176 ++++++++++++ .../src/grpc/early_adopter/interfaces.py | 271 +++++++++++++++--- .../src/grpc/early_adopter/utilities.py | 132 ++++----- tools/run_tests/run_python.sh | 1 + 10 files changed, 1013 insertions(+), 347 deletions(-) create mode 100644 src/python/src/grpc/early_adopter/_assembly_utilities.py delete mode 100644 src/python/src/grpc/early_adopter/_face_utilities.py create mode 100644 src/python/src/grpc/early_adopter/_reexport.py create mode 100644 src/python/src/grpc/early_adopter/exceptions.py create mode 100644 src/python/src/grpc/early_adopter/implementations_test.py diff --git a/src/python/interop/interop/methods.py b/src/python/interop/interop/methods.py index 26c1869f93e..6d5990087ee 100644 --- a/src/python/interop/interop/methods.py +++ b/src/python/interop/interop/methods.py @@ -34,47 +34,47 @@ from grpc.early_adopter import utilities from interop import empty_pb2 from interop import messages_pb2 -def _empty_call(request): +def _empty_call(request, unused_context): return empty_pb2.Empty() -_CLIENT_EMPTY_CALL = utilities.unary_unary_client_rpc_method( +_CLIENT_EMPTY_CALL = utilities.unary_unary_invocation_description( empty_pb2.Empty.SerializeToString, empty_pb2.Empty.FromString) -_SERVER_EMPTY_CALL = utilities.unary_unary_server_rpc_method( +_SERVER_EMPTY_CALL = utilities.unary_unary_service_description( _empty_call, empty_pb2.Empty.FromString, empty_pb2.Empty.SerializeToString) -def _unary_call(request): +def _unary_call(request, unused_context): return messages_pb2.SimpleResponse( payload=messages_pb2.Payload( type=messages_pb2.COMPRESSABLE, body=b'\x00' * request.response_size)) -_CLIENT_UNARY_CALL = utilities.unary_unary_client_rpc_method( +_CLIENT_UNARY_CALL = utilities.unary_unary_invocation_description( messages_pb2.SimpleRequest.SerializeToString, messages_pb2.SimpleResponse.FromString) -_SERVER_UNARY_CALL = utilities.unary_unary_server_rpc_method( +_SERVER_UNARY_CALL = utilities.unary_unary_service_description( _unary_call, messages_pb2.SimpleRequest.FromString, messages_pb2.SimpleResponse.SerializeToString) -def _streaming_output_call(request): +def _streaming_output_call(request, unused_context): for response_parameters in request.response_parameters: yield messages_pb2.StreamingOutputCallResponse( payload=messages_pb2.Payload( type=request.response_type, body=b'\x00' * response_parameters.size)) -_CLIENT_STREAMING_OUTPUT_CALL = utilities.unary_stream_client_rpc_method( +_CLIENT_STREAMING_OUTPUT_CALL = utilities.unary_stream_invocation_description( messages_pb2.StreamingOutputCallRequest.SerializeToString, messages_pb2.StreamingOutputCallResponse.FromString) -_SERVER_STREAMING_OUTPUT_CALL = utilities.unary_stream_server_rpc_method( +_SERVER_STREAMING_OUTPUT_CALL = utilities.unary_stream_service_description( _streaming_output_call, messages_pb2.StreamingOutputCallRequest.FromString, messages_pb2.StreamingOutputCallResponse.SerializeToString) -def _streaming_input_call(request_iterator): +def _streaming_input_call(request_iterator, unused_context): aggregate_size = 0 for request in request_iterator: if request.payload and request.payload.body: @@ -82,35 +82,35 @@ def _streaming_input_call(request_iterator): return messages_pb2.StreamingInputCallResponse( aggregated_payload_size=aggregate_size) -_CLIENT_STREAMING_INPUT_CALL = utilities.stream_unary_client_rpc_method( +_CLIENT_STREAMING_INPUT_CALL = utilities.stream_unary_invocation_description( messages_pb2.StreamingInputCallRequest.SerializeToString, messages_pb2.StreamingInputCallResponse.FromString) -_SERVER_STREAMING_INPUT_CALL = utilities.stream_unary_server_rpc_method( +_SERVER_STREAMING_INPUT_CALL = utilities.stream_unary_service_description( _streaming_input_call, messages_pb2.StreamingInputCallRequest.FromString, messages_pb2.StreamingInputCallResponse.SerializeToString) -def _full_duplex_call(request_iterator): +def _full_duplex_call(request_iterator, unused_context): for request in request_iterator: yield messages_pb2.StreamingOutputCallResponse( payload=messages_pb2.Payload( type=request.payload.type, body=b'\x00' * request.response_parameters[0].size)) -_CLIENT_FULL_DUPLEX_CALL = utilities.stream_stream_client_rpc_method( +_CLIENT_FULL_DUPLEX_CALL = utilities.stream_stream_invocation_description( messages_pb2.StreamingOutputCallRequest.SerializeToString, messages_pb2.StreamingOutputCallResponse.FromString) -_SERVER_FULL_DUPLEX_CALL = utilities.stream_stream_server_rpc_method( +_SERVER_FULL_DUPLEX_CALL = utilities.stream_stream_service_description( _full_duplex_call, messages_pb2.StreamingOutputCallRequest.FromString, messages_pb2.StreamingOutputCallResponse.SerializeToString) # NOTE(nathaniel): Apparently this is the same as the full-duplex call? -_CLIENT_HALF_DUPLEX_CALL = utilities.stream_stream_client_rpc_method( +_CLIENT_HALF_DUPLEX_CALL = utilities.stream_stream_invocation_description( messages_pb2.StreamingOutputCallRequest.SerializeToString, messages_pb2.StreamingOutputCallResponse.FromString) -_SERVER_HALF_DUPLEX_CALL = utilities.stream_stream_server_rpc_method( +_SERVER_HALF_DUPLEX_CALL = utilities.stream_stream_service_description( _full_duplex_call, messages_pb2.StreamingOutputCallRequest.FromString, messages_pb2.StreamingOutputCallResponse.SerializeToString) diff --git a/src/python/src/grpc/early_adopter/_assembly_utilities.py b/src/python/src/grpc/early_adopter/_assembly_utilities.py new file mode 100644 index 00000000000..facfc2bf0e6 --- /dev/null +++ b/src/python/src/grpc/early_adopter/_assembly_utilities.py @@ -0,0 +1,168 @@ +# Copyright 2015, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import abc +import collections + +# assembly_interfaces is referenced from specification in this module. +from grpc.framework.assembly import interfaces as assembly_interfaces # pylint: disable=unused-import +from grpc.framework.assembly import utilities as assembly_utilities +from grpc.early_adopter import _reexport +from grpc.early_adopter import interfaces + + +# TODO(issue 726): Kill the "implementations" attribute of this in favor +# of the same-information-less-bogusly-represented "cardinalities". +class InvocationBreakdown(object): + """An intermediate representation of invocation-side views of RPC methods. + + Attributes: + cardinalities: A dictionary from RPC method name to interfaces.Cardinality + value. + implementations: A dictionary from RPC method name to + assembly_interfaces.MethodImplementation describing the method. + request_serializers: A dictionary from RPC method name to callable + behavior to be used serializing request values for the RPC. + response_deserializers: A dictionary from RPC method name to callable + behavior to be used deserializing response values for the RPC. + """ + __metaclass__ = abc.ABCMeta + + +class _EasyInvocationBreakdown( + InvocationBreakdown, + collections.namedtuple( + '_EasyInvocationBreakdown', + ('cardinalities', 'implementations', 'request_serializers', + 'response_deserializers'))): + pass + + +class ServiceBreakdown(object): + """An intermediate representation of service-side views of RPC methods. + + Attributes: + implementations: A dictionary from RPC method name + assembly_interfaces.MethodImplementation implementing the RPC method. + request_deserializers: A dictionary from RPC method name to callable + behavior to be used deserializing request values for the RPC. + response_serializers: A dictionary from RPC method name to callable + behavior to be used serializing response values for the RPC. + """ + __metaclass__ = abc.ABCMeta + + +class _EasyServiceBreakdown( + ServiceBreakdown, + collections.namedtuple( + '_EasyServiceBreakdown', + ('implementations', 'request_deserializers', 'response_serializers'))): + pass + + +def break_down_invocation(method_descriptions): + """Derives an InvocationBreakdown from several RPC method descriptions. + + Args: + method_descriptions: A dictionary from RPC method name to + interfaces.RpcMethodInvocationDescription describing the RPCs. + + Returns: + An InvocationBreakdown corresponding to the given method descriptions. + """ + cardinalities = {} + implementations = {} + request_serializers = {} + response_deserializers = {} + for name, method_description in method_descriptions.iteritems(): + cardinality = method_description.cardinality() + cardinalities[name] = cardinality + if cardinality is interfaces.Cardinality.UNARY_UNARY: + implementations[name] = assembly_utilities.unary_unary_inline(None) + elif cardinality is interfaces.Cardinality.UNARY_STREAM: + implementations[name] = assembly_utilities.unary_stream_inline(None) + elif cardinality is interfaces.Cardinality.STREAM_UNARY: + implementations[name] = assembly_utilities.stream_unary_inline(None) + elif cardinality is interfaces.Cardinality.STREAM_STREAM: + implementations[name] = assembly_utilities.stream_stream_inline(None) + request_serializers[name] = method_description.serialize_request + response_deserializers[name] = method_description.deserialize_response + return _EasyInvocationBreakdown( + cardinalities, implementations, request_serializers, + response_deserializers) + + +def break_down_service(method_descriptions): + """Derives a ServiceBreakdown from several RPC method descriptions. + + Args: + method_descriptions: A dictionary from RPC method name to + interfaces.RpcMethodServiceDescription describing the RPCs. + + Returns: + A ServiceBreakdown corresponding to the given method descriptions. + """ + implementations = {} + request_deserializers = {} + response_serializers = {} + for name, method_description in method_descriptions.iteritems(): + cardinality = method_description.cardinality() + if cardinality is interfaces.Cardinality.UNARY_UNARY: + def service( + request, face_rpc_context, + service_behavior=method_description.service_unary_unary): + return service_behavior( + request, _reexport.rpc_context(face_rpc_context)) + implementations[name] = assembly_utilities.unary_unary_inline(service) + elif cardinality is interfaces.Cardinality.UNARY_STREAM: + def service( + request, face_rpc_context, + service_behavior=method_description.service_unary_stream): + return service_behavior( + request, _reexport.rpc_context(face_rpc_context)) + implementations[name] = assembly_utilities.unary_stream_inline(service) + elif cardinality is interfaces.Cardinality.STREAM_UNARY: + def service( + request_iterator, face_rpc_context, + service_behavior=method_description.service_stream_unary): + return service_behavior( + request_iterator, _reexport.rpc_context(face_rpc_context)) + implementations[name] = assembly_utilities.stream_unary_inline(service) + elif cardinality is interfaces.Cardinality.STREAM_STREAM: + def service( + request_iterator, face_rpc_context, + service_behavior=method_description.service_stream_stream): + return service_behavior( + request_iterator, _reexport.rpc_context(face_rpc_context)) + implementations[name] = assembly_utilities.stream_stream_inline(service) + request_deserializers[name] = method_description.deserialize_request + response_serializers[name] = method_description.serialize_response + + return _EasyServiceBreakdown( + implementations, request_deserializers, response_serializers) diff --git a/src/python/src/grpc/early_adopter/_face_utilities.py b/src/python/src/grpc/early_adopter/_face_utilities.py deleted file mode 100644 index 3e37b08752b..00000000000 --- a/src/python/src/grpc/early_adopter/_face_utilities.py +++ /dev/null @@ -1,178 +0,0 @@ -# Copyright 2015, Google Inc. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following disclaimer -# in the documentation and/or other materials provided with the -# distribution. -# * Neither the name of Google Inc. nor the names of its -# contributors may be used to endorse or promote products derived from -# this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -import abc -import collections - -from grpc.framework.face import interfaces as face_interfaces - -from grpc.early_adopter import interfaces - - -class _InlineUnaryUnaryMethod(face_interfaces.InlineValueInValueOutMethod): - - def __init__(self, unary_unary_server_rpc_method): - self._method = unary_unary_server_rpc_method - - def service(self, request, context): - """See face_interfaces.InlineValueInValueOutMethod.service for spec.""" - return self._method.service_unary_unary(request) - - -class _InlineUnaryStreamMethod(face_interfaces.InlineValueInStreamOutMethod): - - def __init__(self, unary_stream_server_rpc_method): - self._method = unary_stream_server_rpc_method - - def service(self, request, context): - """See face_interfaces.InlineValueInStreamOutMethod.service for spec.""" - return self._method.service_unary_stream(request) - - -class _InlineStreamUnaryMethod(face_interfaces.InlineStreamInValueOutMethod): - - def __init__(self, stream_unary_server_rpc_method): - self._method = stream_unary_server_rpc_method - - def service(self, request_iterator, context): - """See face_interfaces.InlineStreamInValueOutMethod.service for spec.""" - return self._method.service_stream_unary(request_iterator) - - -class _InlineStreamStreamMethod(face_interfaces.InlineStreamInStreamOutMethod): - - def __init__(self, stream_stream_server_rpc_method): - self._method = stream_stream_server_rpc_method - - def service(self, request_iterator, context): - """See face_interfaces.InlineStreamInStreamOutMethod.service for spec.""" - return self._method.service_stream_stream(request_iterator) - - -class ClientBreakdown(object): - """An intermediate representation of invocation-side views of RPC methods. - - Attributes: - request_serializers: A dictionary from RPC method name to callable - behavior to be used serializing request values for the RPC. - response_deserializers: A dictionary from RPC method name to callable - behavior to be used deserializing response values for the RPC. - """ - __metaclass__ = abc.ABCMeta - - -class _EasyClientBreakdown( - ClientBreakdown, - collections.namedtuple( - '_EasyClientBreakdown', - ('request_serializers', 'response_deserializers'))): - pass - - -class ServerBreakdown(object): - """An intermediate representation of implementations of RPC methods. - - Attributes: - unary_unary_methods: A dictionary from RPC method name to callable - behavior implementing the RPC method for unary-unary RPC methods. - unary_stream_methods: A dictionary from RPC method name to callable - behavior implementing the RPC method for unary-stream RPC methods. - stream_unary_methods: A dictionary from RPC method name to callable - behavior implementing the RPC method for stream-unary RPC methods. - stream_stream_methods: A dictionary from RPC method name to callable - behavior implementing the RPC method for stream-stream RPC methods. - request_deserializers: A dictionary from RPC method name to callable - behavior to be used deserializing request values for the RPC. - response_serializers: A dictionary from RPC method name to callable - behavior to be used serializing response values for the RPC. - """ - __metaclass__ = abc.ABCMeta - - - -class _EasyServerBreakdown( - ServerBreakdown, - collections.namedtuple( - '_EasyServerBreakdown', - ('unary_unary_methods', 'unary_stream_methods', 'stream_unary_methods', - 'stream_stream_methods', 'request_deserializers', - 'response_serializers'))): - pass - - -def client_break_down(methods): - """Derives a ClientBreakdown from several interfaces.ClientRpcMethods. - - Args: - methods: A dictionary from RPC mthod name to - interfaces.ClientRpcMethod object describing the RPCs. - - Returns: - A ClientBreakdown corresponding to the given methods. - """ - request_serializers = {} - response_deserializers = {} - for name, method in methods.iteritems(): - request_serializers[name] = method.serialize_request - response_deserializers[name] = method.deserialize_response - return _EasyClientBreakdown(request_serializers, response_deserializers) - - -def server_break_down(methods): - """Derives a ServerBreakdown from several interfaces.ServerRpcMethods. - - Args: - methods: A dictionary from RPC mthod name to - interfaces.ServerRpcMethod object describing the RPCs. - - Returns: - A ServerBreakdown corresponding to the given methods. - """ - unary_unary = {} - unary_stream = {} - stream_unary = {} - stream_stream = {} - request_deserializers = {} - response_serializers = {} - for name, method in methods.iteritems(): - cardinality = method.cardinality() - if cardinality is interfaces.Cardinality.UNARY_UNARY: - unary_unary[name] = _InlineUnaryUnaryMethod(method) - elif cardinality is interfaces.Cardinality.UNARY_STREAM: - unary_stream[name] = _InlineUnaryStreamMethod(method) - elif cardinality is interfaces.Cardinality.STREAM_UNARY: - stream_unary[name] = _InlineStreamUnaryMethod(method) - elif cardinality is interfaces.Cardinality.STREAM_STREAM: - stream_stream[name] = _InlineStreamStreamMethod(method) - request_deserializers[name] = method.deserialize_request - response_serializers[name] = method.serialize_response - - return _EasyServerBreakdown( - unary_unary, unary_stream, stream_unary, stream_stream, - request_deserializers, response_serializers) diff --git a/src/python/src/grpc/early_adopter/_reexport.py b/src/python/src/grpc/early_adopter/_reexport.py new file mode 100644 index 00000000000..35855bc9c80 --- /dev/null +++ b/src/python/src/grpc/early_adopter/_reexport.py @@ -0,0 +1,207 @@ +# Copyright 2015, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +import abc +import collections + +from grpc.framework.face import exceptions as face_exceptions +from grpc.framework.face import interfaces as face_interfaces +from grpc.framework.foundation import future +from grpc.early_adopter import exceptions +from grpc.early_adopter import interfaces + +_ABORTION_REEXPORT = { + face_interfaces.Abortion.CANCELLED: interfaces.Abortion.CANCELLED, + face_interfaces.Abortion.EXPIRED: interfaces.Abortion.EXPIRED, + face_interfaces.Abortion.NETWORK_FAILURE: + interfaces.Abortion.NETWORK_FAILURE, + face_interfaces.Abortion.SERVICED_FAILURE: + interfaces.Abortion.SERVICED_FAILURE, + face_interfaces.Abortion.SERVICER_FAILURE: + interfaces.Abortion.SERVICER_FAILURE, +} + + +class _RpcError(exceptions.RpcError): + pass + + +def _reexport_error(face_rpc_error): + if isinstance(face_rpc_error, face_exceptions.CancellationError): + return exceptions.CancellationError() + elif isinstance(face_rpc_error, face_exceptions.ExpirationError): + return exceptions.ExpirationError() + else: + return _RpcError() + + +def _as_face_abortion_callback(abortion_callback): + def face_abortion_callback(face_abortion): + abortion_callback(_ABORTION_REEXPORT[face_abortion]) + return face_abortion_callback + + +class _ReexportedFuture(future.Future): + + def __init__(self, face_future): + self._face_future = face_future + + def cancel(self): + return self._face_future.cancel() + + def cancelled(self): + return self._face_future.cancelled() + + def running(self): + return self._face_future.running() + + def done(self): + return self._face_future.done() + + def result(self, timeout=None): + try: + return self._face_future.result(timeout=timeout) + except face_exceptions.RpcError as e: + raise _reexport_error(e) + + def exception(self, timeout=None): + face_error = self._face_future.exception(timeout=timeout) + return None if face_error is None else _reexport_error(face_error) + + def traceback(self, timeout=None): + return self._face_future.traceback(timeout=timeout) + + def add_done_callback(self, fn): + self._face_future.add_done_callback(lambda unused_face_future: fn(self)) + + +def _call_reexporting_errors(behavior, *args, **kwargs): + try: + return behavior(*args, **kwargs) + except face_exceptions.RpcError as e: + raise _reexport_error(e) + + +def _reexported_future(face_future): + return _ReexportedFuture(face_future) + + +class _CancellableIterator(interfaces.CancellableIterator): + + def __init__(self, face_cancellable_iterator): + self._face_cancellable_iterator = face_cancellable_iterator + + def __iter__(self): + return self + + def next(self): + return _call_reexporting_errors(self._face_cancellable_iterator.next) + + def cancel(self): + self._face_cancellable_iterator.cancel() + + +class _RpcContext(interfaces.RpcContext): + + def __init__(self, face_rpc_context): + self._face_rpc_context = face_rpc_context + + def is_active(self): + return self._face_rpc_context.is_active() + + def time_remaining(self): + return self._face_rpc_context.time_remaining() + + def add_abortion_callback(self, abortion_callback): + self._face_rpc_context.add_abortion_callback( + _as_face_abortion_callback(abortion_callback)) + + +class _UnaryUnarySyncAsync(interfaces.UnaryUnarySyncAsync): + + def __init__(self, face_unary_unary_sync_async): + self._underlying = face_unary_unary_sync_async + + def __call__(self, request, timeout): + return _call_reexporting_errors( + self._underlying, request, timeout) + + def async(self, request, timeout): + return _ReexportedFuture(self._underlying.async(request, timeout)) + + +class _StreamUnarySyncAsync(interfaces.StreamUnarySyncAsync): + + def __init__(self, face_stream_unary_sync_async): + self._underlying = face_stream_unary_sync_async + + def __call__(self, request_iterator, timeout): + return _call_reexporting_errors( + self._underlying, request_iterator, timeout) + + def async(self, request_iterator, timeout): + return _ReexportedFuture(self._underlying.async(request_iterator, timeout)) + + +class _Stub(interfaces.Stub): + + def __init__(self, assembly_stub, cardinalities): + self._assembly_stub = assembly_stub + self._cardinalities = cardinalities + + def __enter__(self): + self._assembly_stub.__enter__() + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self._assembly_stub.__exit__(exc_type, exc_val, exc_tb) + return False + + def __getattr__(self, attr): + underlying_attr = self._assembly_stub.__getattr__(attr) + cardinality = self._cardinalities.get(attr) + if cardinality is interfaces.Cardinality.UNARY_UNARY: + return _UnaryUnarySyncAsync(underlying_attr) + elif cardinality is interfaces.Cardinality.UNARY_STREAM: + return lambda request, timeout: _CancellableIterator( + underlying_attr(request, timeout)) + elif cardinality is interfaces.Cardinality.STREAM_UNARY: + return _StreamUnarySyncAsync(underlying_attr) + elif cardinality is interfaces.Cardinality.STREAM_STREAM: + return lambda request_iterator, timeout: _CancellableIterator( + underlying_attr(request_iterator, timeout)) + else: + raise AttributeError(attr) + +def rpc_context(face_rpc_context): + return _RpcContext(face_rpc_context) + + +def stub(assembly_stub, cardinalities): + return _Stub(assembly_stub, cardinalities) diff --git a/src/python/src/grpc/early_adopter/exceptions.py b/src/python/src/grpc/early_adopter/exceptions.py new file mode 100644 index 00000000000..5234d3b91ce --- /dev/null +++ b/src/python/src/grpc/early_adopter/exceptions.py @@ -0,0 +1,48 @@ +# Copyright 2015, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Exceptions raised by GRPC. + +Only GRPC should instantiate and raise these exceptions. +""" + +import abc + + +class RpcError(Exception): + """Common super type for all exceptions raised by GRPC.""" + __metaclass__ = abc.ABCMeta + + +class CancellationError(RpcError): + """Indicates that an RPC has been cancelled.""" + + +class ExpirationError(RpcError): + """Indicates that an RPC has expired ("timed out").""" diff --git a/src/python/src/grpc/early_adopter/implementations.py b/src/python/src/grpc/early_adopter/implementations.py index 1d76d0f9e0d..241ed7dcdbb 100644 --- a/src/python/src/grpc/early_adopter/implementations.py +++ b/src/python/src/grpc/early_adopter/implementations.py @@ -31,15 +31,12 @@ import threading -from grpc._adapter import fore -from grpc.framework.base.packets import implementations as _tickets_implementations -from grpc.framework.face import implementations as _face_implementations -from grpc.framework.foundation import logging_pool -from grpc.early_adopter import _face_utilities +from grpc._adapter import fore as _fore +from grpc._adapter import rear as _rear +from grpc.early_adopter import _assembly_utilities +from grpc.early_adopter import _reexport from grpc.early_adopter import interfaces - -_MEGA_TIMEOUT = 60 * 60 * 24 -_THREAD_POOL_SIZE = 80 +from grpc.framework.assembly import implementations as _assembly_implementations class _Server(interfaces.Server): @@ -48,63 +45,120 @@ class _Server(interfaces.Server): self._lock = threading.Lock() self._breakdown = breakdown self._port = port - self._private_key = private_key - self._certificate_chain = certificate_chain + if private_key is None or certificate_chain is None: + self._key_chain_pairs = () + else: + self._key_chain_pairs = ((private_key, certificate_chain),) - self._pool = None self._fore_link = None - self._back = None + self._server = None - def start(self): - """See interfaces.Server.start for specification.""" + def _start(self): with self._lock: - if self._pool is None: - self._pool = logging_pool.pool(_THREAD_POOL_SIZE) - servicer = _face_implementations.servicer( - self._pool, - inline_value_in_value_out_methods=self._breakdown.unary_unary_methods, - inline_value_in_stream_out_methods=self._breakdown.unary_stream_methods, - inline_stream_in_value_out_methods=self._breakdown.stream_unary_methods, - inline_stream_in_stream_out_methods=self._breakdown.stream_stream_methods) - self._fore_link = fore.ForeLink( - self._pool, self._breakdown.request_deserializers, - self._breakdown.response_serializers, None, - ((self._private_key, self._certificate_chain),), port=self._port) - self._fore_link.start() - port = self._fore_link.port() - self._back = _tickets_implementations.back( - servicer, self._pool, self._pool, self._pool, _MEGA_TIMEOUT, - _MEGA_TIMEOUT) - self._fore_link.join_rear_link(self._back) - self._back.join_fore_link(self._fore_link) - return port + if self._server is None: + self._fore_link = _fore.activated_fore_link( + self._port, self._breakdown.request_deserializers, + self._breakdown.response_serializers, None, self._key_chain_pairs) + + self._server = _assembly_implementations.assemble_service( + self._breakdown.implementations, self._fore_link) + self._server.start() else: raise ValueError('Server currently running!') - def stop(self): - """See interfaces.Server.stop for specification.""" + def _stop(self): with self._lock: - if self._pool is None: + if self._server is None: raise ValueError('Server not running!') else: - self._fore_link.stop() - self._pool.shutdown(wait=True) - self._pool = None + self._server.stop() + self._server = None + self._fore_link = None + + def __enter__(self): + self._start() + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self._stop() + return False + + def start(self): + self._start() + + def stop(self): + self._stop() + + def port(self): + with self._lock: + return self._fore_link.port() + +def _build_stub( + methods, host, port, root_certificates, private_key, certificate_chain): + breakdown = _assembly_utilities.break_down_invocation(methods) + # TODO(nathaniel): pass security values. + activated_rear_link = _rear.activated_rear_link( + host, port, breakdown.request_serializers, + breakdown.response_deserializers) + assembly_stub = _assembly_implementations.assemble_dynamic_inline_stub( + breakdown.implementations, activated_rear_link) + return _reexport.stub(assembly_stub, breakdown.cardinalities) def _build_server(methods, port, private_key, certificate_chain): - breakdown = _face_utilities.server_break_down(methods) + breakdown = _assembly_utilities.break_down_service(methods) return _Server(breakdown, port, private_key, certificate_chain) +def insecure_stub(methods, host, port): + """Constructs an insecure interfaces.Stub. + + Args: + methods: A dictionary from RPC method name to + interfaces.RpcMethodInvocationDescription describing the RPCs to be + supported by the created stub. + host: The host to which to connect for RPC service. + port: The port to which to connect for RPC service. + + Returns: + An interfaces.Stub affording RPC invocation. + """ + return _build_stub(methods, host, port, None, None, None) + + +def secure_stub( + methods, host, port, root_certificates, private_key, certificate_chain): + """Constructs an insecure interfaces.Stub. + + Args: + methods: A dictionary from RPC method name to + interfaces.RpcMethodInvocationDescription describing the RPCs to be + supported by the created stub. + host: The host to which to connect for RPC service. + port: The port to which to connect for RPC service. + root_certificates: The PEM-encoded root certificates or None to ask for + them to be retrieved from a default location. + private_key: The PEM-encoded private key to use or None if no private key + should be used. + certificate_chain: The PEM-encoded certificate chain to use or None if no + certificate chain should be used. + + Returns: + An interfaces.Stub affording RPC invocation. + """ + return _build_stub( + methods, host, port, root_certificates, private_key, certificate_chain) + + def insecure_server(methods, port): """Constructs an insecure interfaces.Server. Args: methods: A dictionary from RPC method name to - interfaces.ServerRpcMethod object describing the RPCs to + interfaces.RpcMethodServiceDescription describing the RPCs to be serviced by the created server. - port: The port on which to serve. + port: The desired port on which to serve or zero to ask for a port to + be automatically selected. Returns: An interfaces.Server that will run with no security and @@ -118,9 +172,10 @@ def secure_server(methods, port, private_key, certificate_chain): Args: methods: A dictionary from RPC method name to - interfaces.ServerRpcMethod object describing the RPCs to + interfaces.RpcMethodServiceDescription describing the RPCs to be serviced by the created server. - port: The port on which to serve. + port: The port on which to serve or zero to ask for a port to be + automatically selected. private_key: A pem-encoded private key. certificate_chain: A pem-encoded certificate chain. diff --git a/src/python/src/grpc/early_adopter/implementations_test.py b/src/python/src/grpc/early_adopter/implementations_test.py new file mode 100644 index 00000000000..9ef06c32cbc --- /dev/null +++ b/src/python/src/grpc/early_adopter/implementations_test.py @@ -0,0 +1,176 @@ +# Copyright 2015, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +# TODO(nathaniel): Expand this test coverage. + +"""Test of the GRPC-backed ForeLink and RearLink.""" + +import unittest + +from grpc.early_adopter import implementations +from grpc.early_adopter import utilities +from grpc._junkdrawer import math_pb2 + +DIV = 'Div' +DIV_MANY = 'DivMany' +FIB = 'Fib' +SUM = 'Sum' + +def _fibbonacci(limit): + left, right = 0, 1 + for _ in xrange(limit): + yield left + left, right = right, left + right + + +def _div(request, unused_context): + return math_pb2.DivReply( + quotient=request.dividend / request.divisor, + remainder=request.dividend % request.divisor) + + +def _div_many(request_iterator, unused_context): + for request in request_iterator: + yield math_pb2.DivReply( + quotient=request.dividend / request.divisor, + remainder=request.dividend % request.divisor) + + +def _fib(request, unused_context): + for number in _fibbonacci(request.limit): + yield math_pb2.Num(num=number) + + +def _sum(request_iterator, unused_context): + accumulation = 0 + for request in request_iterator: + accumulation += request.num + return math_pb2.Num(num=accumulation) + + +_INVOCATION_DESCRIPTIONS = { + DIV: utilities.unary_unary_invocation_description( + math_pb2.DivArgs.SerializeToString, math_pb2.DivReply.FromString), + DIV_MANY: utilities.stream_stream_invocation_description( + math_pb2.DivArgs.SerializeToString, math_pb2.DivReply.FromString), + FIB: utilities.unary_stream_invocation_description( + math_pb2.FibArgs.SerializeToString, math_pb2.Num.FromString), + SUM: utilities.stream_unary_invocation_description( + math_pb2.Num.SerializeToString, math_pb2.Num.FromString), +} + +_SERVICE_DESCRIPTIONS = { + DIV: utilities.unary_unary_service_description( + _div, math_pb2.DivArgs.FromString, + math_pb2.DivReply.SerializeToString), + DIV_MANY: utilities.stream_stream_service_description( + _div_many, math_pb2.DivArgs.FromString, + math_pb2.DivReply.SerializeToString), + FIB: utilities.unary_stream_service_description( + _fib, math_pb2.FibArgs.FromString, math_pb2.Num.SerializeToString), + SUM: utilities.stream_unary_service_description( + _sum, math_pb2.Num.FromString, math_pb2.Num.SerializeToString), +} + +_TIMEOUT = 3 + + +class EarlyAdopterImplementationsTest(unittest.TestCase): + + def setUp(self): + self.server = implementations.insecure_server(_SERVICE_DESCRIPTIONS, 0) + self.server.start() + port = self.server.port() + self.stub = implementations.insecure_stub(_INVOCATION_DESCRIPTIONS, 'localhost', port) + + def tearDown(self): + self.server.stop() + + def testUpAndDown(self): + with self.stub: + pass + + def testUnaryUnary(self): + divisor = 59 + dividend = 973 + expected_quotient = dividend / divisor + expected_remainder = dividend % divisor + + with self.stub: + response = self.stub.Div( + math_pb2.DivArgs(divisor=divisor, dividend=dividend), _TIMEOUT) + self.assertEqual(expected_quotient, response.quotient) + self.assertEqual(expected_remainder, response.remainder) + + def testUnaryStream(self): + stream_length = 43 + + with self.stub: + response_iterator = self.stub.Fib( + math_pb2.FibArgs(limit=stream_length), _TIMEOUT) + numbers = tuple(response.num for response in response_iterator) + for early, middle, later in zip(numbers, numbers[:1], numbers[:2]): + self.assertEqual(early + middle, later) + self.assertEqual(stream_length, len(numbers)) + + def testStreamUnary(self): + stream_length = 127 + + with self.stub: + response_future = self.stub.Sum.async( + (math_pb2.Num(num=index) for index in range(stream_length)), + _TIMEOUT) + self.assertEqual( + (stream_length * (stream_length - 1)) / 2, + response_future.result().num) + + def testStreamStream(self): + stream_length = 179 + divisor_offset = 71 + dividend_offset = 1763 + + with self.stub: + response_iterator = self.stub.DivMany( + (math_pb2.DivArgs( + divisor=divisor_offset + index, + dividend=dividend_offset + index) + for index in range(stream_length)), + _TIMEOUT) + for index, response in enumerate(response_iterator): + self.assertEqual( + (dividend_offset + index) / (divisor_offset + index), + response.quotient) + self.assertEqual( + (dividend_offset + index) % (divisor_offset + index), + response.remainder) + self.assertEqual(stream_length, index + 1) + + +if __name__ == '__main__': + unittest.main() diff --git a/src/python/src/grpc/early_adopter/interfaces.py b/src/python/src/grpc/early_adopter/interfaces.py index 0ec371f8e88..b733873c1c9 100644 --- a/src/python/src/grpc/early_adopter/interfaces.py +++ b/src/python/src/grpc/early_adopter/interfaces.py @@ -32,6 +32,11 @@ import abc import enum +# exceptions is referenced from specification in this module. +from grpc.early_adopter import exceptions # pylint: disable=unused-import +from grpc.framework.foundation import activated +from grpc.framework.foundation import future + @enum.unique class Cardinality(enum.Enum): @@ -43,24 +48,166 @@ class Cardinality(enum.Enum): STREAM_STREAM = 'request-streaming/response-streaming' -class RpcMethod(object): - """A type for the common aspects of RPC method specifications.""" +@enum.unique +class Abortion(enum.Enum): + """Categories of RPC abortion.""" + + CANCELLED = 'cancelled' + EXPIRED = 'expired' + NETWORK_FAILURE = 'network failure' + SERVICED_FAILURE = 'serviced failure' + SERVICER_FAILURE = 'servicer failure' + + +class CancellableIterator(object): + """Implements the Iterator protocol and affords a cancel method.""" + __metaclass__ = abc.ABCMeta + + @abc.abstractmethod + def __iter__(self): + """Returns the self object in accordance with the Iterator protocol.""" + raise NotImplementedError() + + @abc.abstractmethod + def next(self): + """Returns a value or raises StopIteration per the Iterator protocol.""" + raise NotImplementedError() + + @abc.abstractmethod + def cancel(self): + """Requests cancellation of whatever computation underlies this iterator.""" + raise NotImplementedError() + + +class RpcContext(object): + """Provides RPC-related information and action.""" + __metaclass__ = abc.ABCMeta + + @abc.abstractmethod + def is_active(self): + """Describes whether the RPC is active or has terminated.""" + raise NotImplementedError() + + @abc.abstractmethod + def time_remaining(self): + """Describes the length of allowed time remaining for the RPC. + Returns: + A nonnegative float indicating the length of allowed time in seconds + remaining for the RPC to complete before it is considered to have timed + out. + """ + raise NotImplementedError() + + @abc.abstractmethod + def add_abortion_callback(self, abortion_callback): + """Registers a callback to be called if the RPC is aborted. + Args: + abortion_callback: A callable to be called and passed an Abortion value + in the event of RPC abortion. + """ + raise NotImplementedError() + + +class UnaryUnarySyncAsync(object): + """Affords invoking a unary-unary RPC synchronously or asynchronously. + Values implementing this interface are directly callable and present an + "async" method. Both calls take a request value and a numeric timeout. + Direct invocation of a value of this type invokes its associated RPC and + blocks until the RPC's response is available. Calling the "async" method + of a value of this type invokes its associated RPC and immediately returns a + future.Future bound to the asynchronous execution of the RPC. + """ + __metaclass__ = abc.ABCMeta + + @abc.abstractmethod + def __call__(self, request, timeout): + """Synchronously invokes the underlying RPC. + Args: + request: The request value for the RPC. + timeout: A duration of time in seconds to allow for the RPC. + Returns: + The response value for the RPC. + Raises: + exceptions.RpcError: Indicating that the RPC was aborted. + """ + raise NotImplementedError() + + @abc.abstractmethod + def async(self, request, timeout): + """Asynchronously invokes the underlying RPC. + Args: + request: The request value for the RPC. + timeout: A duration of time in seconds to allow for the RPC. + Returns: + A future.Future representing the RPC. In the event of RPC completion, the + returned Future's result value will be the response value of the RPC. + In the event of RPC abortion, the returned Future's exception value + will be an exceptions.RpcError. + """ + raise NotImplementedError() + + +class StreamUnarySyncAsync(object): + """Affords invoking a stream-unary RPC synchronously or asynchronously. + Values implementing this interface are directly callable and present an + "async" method. Both calls take an iterator of request values and a numeric + timeout. Direct invocation of a value of this type invokes its associated RPC + and blocks until the RPC's response is available. Calling the "async" method + of a value of this type invokes its associated RPC and immediately returns a + future.Future bound to the asynchronous execution of the RPC. + """ + __metaclass__ = abc.ABCMeta + + @abc.abstractmethod + def __call__(self, request_iterator, timeout): + """Synchronously invokes the underlying RPC. + + Args: + request_iterator: An iterator that yields request values for the RPC. + timeout: A duration of time in seconds to allow for the RPC. + + Returns: + The response value for the RPC. + + Raises: + exceptions.RpcError: Indicating that the RPC was aborted. + """ + raise NotImplementedError() + + @abc.abstractmethod + def async(self, request_iterator, timeout): + """Asynchronously invokes the underlying RPC. + + Args: + request_iterator: An iterator that yields request values for the RPC. + timeout: A duration of time in seconds to allow for the RPC. + + Returns: + A future.Future representing the RPC. In the event of RPC completion, the + returned Future's result value will be the response value of the RPC. + In the event of RPC abortion, the returned Future's exception value + will be an exceptions.RpcError. + """ + raise NotImplementedError() + + +class RpcMethodDescription(object): + """A type for the common aspects of RPC method descriptions.""" __metaclass__ = abc.ABCMeta @abc.abstractmethod def cardinality(self): - """Identifies the cardinality of this RpcMethod. + """Identifies the cardinality of this RpcMethodDescription. Returns: A Cardinality value identifying whether or not this - RpcMethod is request-unary or request-streaming and - whether or not it is response-unary or - response-streaming. + RpcMethodDescription is request-unary or request-streaming and + whether or not it is response-unary or response-streaming. """ raise NotImplementedError() -class ClientRpcMethod(RpcMethod): +class RpcMethodInvocationDescription(RpcMethodDescription): """Invocation-side description of an RPC method.""" __metaclass__ = abc.ABCMeta @@ -69,7 +216,8 @@ class ClientRpcMethod(RpcMethod): """Serializes a request value. Args: - request: A request value appropriate for this RpcMethod. + request: A request value appropriate for the RPC method described by this + RpcMethodInvocationDescription. Returns: The serialization of the given request value as a @@ -82,9 +230,9 @@ class ClientRpcMethod(RpcMethod): """Deserializes a response value. Args: - serialized_response: A bytestring that is the - serialization of a response value appropriate for this - RpcMethod. + serialized_response: A bytestring that is the serialization of a response + value appropriate for the RPC method described by this + RpcMethodInvocationDescription. Returns: A response value corresponding to the given bytestring. @@ -92,7 +240,7 @@ class ClientRpcMethod(RpcMethod): raise NotImplementedError() -class ServerRpcMethod(RpcMethod): +class RpcMethodServiceDescription(RpcMethodDescription): """Service-side description of an RPC method.""" __metaclass__ = abc.ABCMeta @@ -101,9 +249,9 @@ class ServerRpcMethod(RpcMethod): """Deserializes a request value. Args: - serialized_request: A bytestring that is the - serialization of a request value appropriate for this - RpcMethod. + serialized_request: A bytestring that is the serialization of a request + value appropriate for the RPC method described by this + RpcMethodServiceDescription. Returns: A request value corresponding to the given bytestring. @@ -115,7 +263,8 @@ class ServerRpcMethod(RpcMethod): """Serializes a response value. Args: - response: A response value appropriate for this RpcMethod. + response: A response value appropriate for the RPC method described by + this RpcMethodServiceDescription. Returns: The serialization of the given response value as a @@ -124,80 +273,116 @@ class ServerRpcMethod(RpcMethod): raise NotImplementedError() @abc.abstractmethod - def service_unary_unary(self, request): + def service_unary_unary(self, request, context): """Carries out this RPC. This method may only be called if the cardinality of this - RpcMethod is Cardinality.UNARY_UNARY. + RpcMethodServiceDescription is Cardinality.UNARY_UNARY. Args: - request: A request value appropriate for this RpcMethod. + request: A request value appropriate for the RPC method described by this + RpcMethodServiceDescription. + context: An RpcContext object for the RPC. Returns: - A response value appropriate for this RpcMethod. + A response value appropriate for the RPC method described by this + RpcMethodServiceDescription. """ raise NotImplementedError() @abc.abstractmethod - def service_unary_stream(self, request): + def service_unary_stream(self, request, context): """Carries out this RPC. This method may only be called if the cardinality of this - RpcMethod is Cardinality.UNARY_STREAM. + RpcMethodServiceDescription is Cardinality.UNARY_STREAM. Args: - request: A request value appropriate for this RpcMethod. + request: A request value appropriate for the RPC method described by this + RpcMethodServiceDescription. + context: An RpcContext object for the RPC. Yields: - Zero or more response values appropriate for this - RpcMethod. + Zero or more response values appropriate for the RPC method described by + this RpcMethodServiceDescription. """ raise NotImplementedError() @abc.abstractmethod - def service_stream_unary(self, request_iterator): + def service_stream_unary(self, request_iterator, context): """Carries out this RPC. This method may only be called if the cardinality of this - RpcMethod is Cardinality.STREAM_UNARY. + RpcMethodServiceDescription is Cardinality.STREAM_UNARY. Args: - request_iterator: An iterator of request values - appropriate for this RpcMethod. + request_iterator: An iterator of request values appropriate for the RPC + method described by this RpcMethodServiceDescription. + context: An RpcContext object for the RPC. Returns: - A response value appropriate for this RpcMethod. + A response value appropriate for the RPC method described by this + RpcMethodServiceDescription. """ raise NotImplementedError() @abc.abstractmethod - def service_stream_stream(self, request_iterator): + def service_stream_stream(self, request_iterator, context): """Carries out this RPC. This method may only be called if the cardinality of this - RpcMethod is Cardinality.STREAM_STREAM. + RpcMethodServiceDescription is Cardinality.STREAM_STREAM. Args: - request_iterator: An iterator of request values - appropriate for this RpcMethod. + request_iterator: An iterator of request values appropriate for the RPC + method described by this RpcMethodServiceDescription. + context: An RpcContext object for the RPC. Yields: - Zero or more response values appropraite for this - RpcMethod. + Zero or more response values appropriate for the RPC method described by + this RpcMethodServiceDescription. """ raise NotImplementedError() -class Server(object): +class Stub(object): + """A stub with callable RPC method names for attributes. + + Instances of this type are context managers and only afford RPC invocation + when used in context. + + Instances of this type, when used in context, respond to attribute access + as follows: if the requested attribute is the name of a unary-unary RPC + method, the value of the attribute will be a UnaryUnarySyncAsync with which + to invoke the RPC method. If the requested attribute is the name of a + unary-stream RPC method, the value of the attribute will be a callable taking + a request object and a timeout parameter and returning a CancellableIterator + that yields the response values of the RPC. If the requested attribute is the + name of a stream-unary RPC method, the value of the attribute will be a + StreamUnarySyncAsync with which to invoke the RPC method. If the requested + attribute is the name of a stream-stream RPC method, the value of the + attribute will be a callable taking an iterator of request objects and a + timeout and returning a CancellableIterator that yields the response values + of the RPC. + + In all cases indication of abortion is indicated by raising of + exceptions.RpcError, exceptions.CancellationError, + and exceptions.ExpirationError. + """ + __metaclass__ = abc.ABCMeta + + +class Server(activated.Activated): """A GRPC Server.""" __metaclass__ = abc.ABCMeta @abc.abstractmethod - def start(self): - """Instructs this server to commence service of RPCs.""" - raise NotImplementedError() + def port(self): + """Reports the port on which the server is serving. - @abc.abstractmethod - def stop(self): - """Instructs this server to halt service of RPCs.""" + This method may only be called while the server is activated. + + Returns: + The port on which the server is serving. + """ raise NotImplementedError() diff --git a/src/python/src/grpc/early_adopter/utilities.py b/src/python/src/grpc/early_adopter/utilities.py index 9277d3f6ad4..da8ef825aa5 100644 --- a/src/python/src/grpc/early_adopter/utilities.py +++ b/src/python/src/grpc/early_adopter/utilities.py @@ -32,7 +32,9 @@ from grpc.early_adopter import interfaces -class _RpcMethod(interfaces.ClientRpcMethod, interfaces.ServerRpcMethod): +class _RpcMethodDescription( + interfaces.RpcMethodInvocationDescription, + interfaces.RpcMethodServiceDescription): def __init__( self, cardinality, unary_unary, unary_stream, stream_unary, @@ -49,44 +51,45 @@ class _RpcMethod(interfaces.ClientRpcMethod, interfaces.ServerRpcMethod): self._response_deserializer = response_deserializer def cardinality(self): - """See interfaces.RpcMethod.cardinality for specification.""" + """See interfaces.RpcMethodDescription.cardinality for specification.""" return self._cardinality def serialize_request(self, request): - """See interfaces.RpcMethod.serialize_request for specification.""" + """See interfaces.RpcMethodInvocationDescription.serialize_request.""" return self._request_serializer(request) def deserialize_request(self, serialized_request): - """See interfaces.RpcMethod.deserialize_request for specification.""" + """See interfaces.RpcMethodServiceDescription.deserialize_request.""" return self._request_deserializer(serialized_request) def serialize_response(self, response): - """See interfaces.RpcMethod.serialize_response for specification.""" + """See interfaces.RpcMethodServiceDescription.serialize_response.""" return self._response_serializer(response) def deserialize_response(self, serialized_response): - """See interfaces.RpcMethod.deserialize_response for specification.""" + """See interfaces.RpcMethodInvocationDescription.deserialize_response.""" return self._response_deserializer(serialized_response) - def service_unary_unary(self, request): - """See interfaces.RpcMethod.service_unary_unary for specification.""" - return self._unary_unary(request) + def service_unary_unary(self, request, context): + """See interfaces.RpcMethodServiceDescription.service_unary_unary.""" + return self._unary_unary(request, context) - def service_unary_stream(self, request): - """See interfaces.RpcMethod.service_unary_stream for specification.""" - return self._unary_stream(request) + def service_unary_stream(self, request, context): + """See interfaces.RpcMethodServiceDescription.service_unary_stream.""" + return self._unary_stream(request, context) - def service_stream_unary(self, request_iterator): - """See interfaces.RpcMethod.service_stream_unary for specification.""" - return self._stream_unary(request_iterator) + def service_stream_unary(self, request_iterator, context): + """See interfaces.RpcMethodServiceDescription.service_stream_unary.""" + return self._stream_unary(request_iterator, context) - def service_stream_stream(self, request_iterator): - """See interfaces.RpcMethod.service_stream_stream for specification.""" - return self._stream_stream(request_iterator) + def service_stream_stream(self, request_iterator, context): + """See interfaces.RpcMethodServiceDescription.service_stream_stream.""" + return self._stream_stream(request_iterator, context) -def unary_unary_client_rpc_method(request_serializer, response_deserializer): - """Constructs an interfaces.ClientRpcMethod for a unary-unary RPC method. +def unary_unary_invocation_description( + request_serializer, response_deserializer): + """Creates an interfaces.RpcMethodInvocationDescription for an RPC method. Args: request_serializer: A callable that when called on a request @@ -96,17 +99,17 @@ def unary_unary_client_rpc_method(request_serializer, response_deserializer): that bytestring. Returns: - An interfaces.ClientRpcMethod constructed from the given - arguments representing a unary-request/unary-response RPC - method. + An interfaces.RpcMethodInvocationDescription constructed from the given + arguments representing a unary-request/unary-response RPC method. """ - return _RpcMethod( + return _RpcMethodDescription( interfaces.Cardinality.UNARY_UNARY, None, None, None, None, request_serializer, None, None, response_deserializer) -def unary_stream_client_rpc_method(request_serializer, response_deserializer): - """Constructs an interfaces.ClientRpcMethod for a unary-stream RPC method. +def unary_stream_invocation_description( + request_serializer, response_deserializer): + """Creates an interfaces.RpcMethodInvocationDescription for an RPC method. Args: request_serializer: A callable that when called on a request @@ -116,17 +119,17 @@ def unary_stream_client_rpc_method(request_serializer, response_deserializer): that bytestring. Returns: - An interfaces.ClientRpcMethod constructed from the given - arguments representing a unary-request/streaming-response - RPC method. + An interfaces.RpcMethodInvocationDescription constructed from the given + arguments representing a unary-request/streaming-response RPC method. """ - return _RpcMethod( + return _RpcMethodDescription( interfaces.Cardinality.UNARY_STREAM, None, None, None, None, request_serializer, None, None, response_deserializer) -def stream_unary_client_rpc_method(request_serializer, response_deserializer): - """Constructs an interfaces.ClientRpcMethod for a stream-unary RPC method. +def stream_unary_invocation_description( + request_serializer, response_deserializer): + """Creates an interfaces.RpcMethodInvocationDescription for an RPC method. Args: request_serializer: A callable that when called on a request @@ -136,17 +139,17 @@ def stream_unary_client_rpc_method(request_serializer, response_deserializer): that bytestring. Returns: - An interfaces.ClientRpcMethod constructed from the given - arguments representing a streaming-request/unary-response - RPC method. + An interfaces.RpcMethodInvocationDescription constructed from the given + arguments representing a streaming-request/unary-response RPC method. """ - return _RpcMethod( + return _RpcMethodDescription( interfaces.Cardinality.STREAM_UNARY, None, None, None, None, request_serializer, None, None, response_deserializer) -def stream_stream_client_rpc_method(request_serializer, response_deserializer): - """Constructs an interfaces.ClientRpcMethod for a stream-stream RPC method. +def stream_stream_invocation_description( + request_serializer, response_deserializer): + """Creates an interfaces.RpcMethodInvocationDescription for an RPC method. Args: request_serializer: A callable that when called on a request @@ -156,23 +159,23 @@ def stream_stream_client_rpc_method(request_serializer, response_deserializer): that bytestring. Returns: - An interfaces.ClientRpcMethod constructed from the given - arguments representing a - streaming-request/streaming-response RPC method. + An interfaces.RpcMethodInvocationDescription constructed from the given + arguments representing a streaming-request/streaming-response RPC + method. """ - return _RpcMethod( + return _RpcMethodDescription( interfaces.Cardinality.STREAM_STREAM, None, None, None, None, request_serializer, None, None, response_deserializer) -def unary_unary_server_rpc_method( +def unary_unary_service_description( behavior, request_deserializer, response_serializer): - """Constructs an interfaces.ServerRpcMethod for the given behavior. + """Creates an interfaces.RpcMethodServiceDescription for the given behavior. Args: behavior: A callable that implements a unary-unary RPC - method that accepts a single request and returns a single - response. + method that accepts a single request and an interfaces.RpcContext and + returns a single response. request_deserializer: A callable that when called on a bytestring returns the request value corresponding to that bytestring. @@ -181,23 +184,23 @@ def unary_unary_server_rpc_method( that value. Returns: - An interfaces.ServerRpcMethod constructed from the given + An interfaces.RpcMethodServiceDescription constructed from the given arguments representing a unary-request/unary-response RPC method. """ - return _RpcMethod( + return _RpcMethodDescription( interfaces.Cardinality.UNARY_UNARY, behavior, None, None, None, None, request_deserializer, response_serializer, None) -def unary_stream_server_rpc_method( +def unary_stream_service_description( behavior, request_deserializer, response_serializer): - """Constructs an interfaces.ServerRpcMethod for the given behavior. + """Creates an interfaces.RpcMethodServiceDescription for the given behavior. Args: behavior: A callable that implements a unary-stream RPC - method that accepts a single request and returns an - iterator of zero or more responses. + method that accepts a single request and an interfaces.RpcContext + and returns an iterator of zero or more responses. request_deserializer: A callable that when called on a bytestring returns the request value corresponding to that bytestring. @@ -206,23 +209,23 @@ def unary_stream_server_rpc_method( that value. Returns: - An interfaces.ServerRpcMethod constructed from the given + An interfaces.RpcMethodServiceDescription constructed from the given arguments representing a unary-request/streaming-response RPC method. """ - return _RpcMethod( + return _RpcMethodDescription( interfaces.Cardinality.UNARY_STREAM, None, behavior, None, None, None, request_deserializer, response_serializer, None) -def stream_unary_server_rpc_method( +def stream_unary_service_description( behavior, request_deserializer, response_serializer): - """Constructs an interfaces.ServerRpcMethod for the given behavior. + """Creates an interfaces.RpcMethodServiceDescription for the given behavior. Args: behavior: A callable that implements a stream-unary RPC method that accepts an iterator of zero or more requests - and returns a single response. + and an interfaces.RpcContext and returns a single response. request_deserializer: A callable that when called on a bytestring returns the request value corresponding to that bytestring. @@ -231,23 +234,24 @@ def stream_unary_server_rpc_method( that value. Returns: - An interfaces.ServerRpcMethod constructed from the given + An interfaces.RpcMethodServiceDescription constructed from the given arguments representing a streaming-request/unary-response RPC method. """ - return _RpcMethod( + return _RpcMethodDescription( interfaces.Cardinality.STREAM_UNARY, None, None, behavior, None, None, request_deserializer, response_serializer, None) -def stream_stream_server_rpc_method( +def stream_stream_service_description( behavior, request_deserializer, response_serializer): - """Constructs an interfaces.ServerRpcMethod for the given behavior. + """Creates an interfaces.RpcMethodServiceDescription for the given behavior. Args: behavior: A callable that implements a stream-stream RPC method that accepts an iterator of zero or more requests - and returns an iterator of zero or more responses. + and an interfaces.RpcContext and returns an iterator of + zero or more responses. request_deserializer: A callable that when called on a bytestring returns the request value corresponding to that bytestring. @@ -256,10 +260,10 @@ def stream_stream_server_rpc_method( that value. Returns: - An interfaces.ServerRpcMethod constructed from the given + An interfaces.RpcMethodServiceDescription constructed from the given arguments representing a streaming-request/streaming-response RPC method. """ - return _RpcMethod( + return _RpcMethodDescription( interfaces.Cardinality.STREAM_STREAM, None, None, None, behavior, None, request_deserializer, response_serializer, None) diff --git a/tools/run_tests/run_python.sh b/tools/run_tests/run_python.sh index fe40b511860..2ef5b9eb232 100755 --- a/tools/run_tests/run_python.sh +++ b/tools/run_tests/run_python.sh @@ -45,6 +45,7 @@ python2.7 -B -m grpc._adapter._future_invocation_asynchronous_event_service_test python2.7 -B -m grpc._adapter._links_test python2.7 -B -m grpc._adapter._lonely_rear_link_test python2.7 -B -m grpc._adapter._low_test +python2.7 -B -m grpc.early_adopter.implementations_test python2.7 -B -m grpc.framework.assembly.implementations_test python2.7 -B -m grpc.framework.base.packets.implementations_test python2.7 -B -m grpc.framework.face.blocking_invocation_inline_service_test From 5339814591c41c845996cba7ed9d83c506922de4 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 24 Feb 2015 08:21:57 -0800 Subject: [PATCH 41/75] Added ability for c# to redirect C core logs to arbitrary sink --- src/csharp/Grpc.Core/Grpc.Core.csproj | 7 +- src/csharp/Grpc.Core/GrpcEnvironment.cs | 1 + src/csharp/Grpc.Core/Internal/GrpcLog.cs | 94 ++++++++++++++++++++++++ src/csharp/ext/grpc_csharp_ext.c | 24 +++++- 4 files changed, 120 insertions(+), 6 deletions(-) create mode 100644 src/csharp/Grpc.Core/Internal/GrpcLog.cs diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj index 135ce26cbd2..6156b2f38bb 100644 --- a/src/csharp/Grpc.Core/Grpc.Core.csproj +++ b/src/csharp/Grpc.Core/Grpc.Core.csproj @@ -1,4 +1,4 @@ - + Debug @@ -33,6 +33,7 @@ + @@ -66,8 +67,4 @@ - - - - \ No newline at end of file diff --git a/src/csharp/Grpc.Core/GrpcEnvironment.cs b/src/csharp/Grpc.Core/GrpcEnvironment.cs index 0e3a0a581cd..d3a8da4729e 100644 --- a/src/csharp/Grpc.Core/GrpcEnvironment.cs +++ b/src/csharp/Grpc.Core/GrpcEnvironment.cs @@ -107,6 +107,7 @@ namespace Grpc.Core /// private GrpcEnvironment() { + GrpcLog.RedirectNativeLogs(Console.Error); grpcsharp_init(); threadPool = new GrpcThreadPool(THREAD_POOL_SIZE); threadPool.Start(); diff --git a/src/csharp/Grpc.Core/Internal/GrpcLog.cs b/src/csharp/Grpc.Core/Internal/GrpcLog.cs new file mode 100644 index 00000000000..98768d05c6d --- /dev/null +++ b/src/csharp/Grpc.Core/Internal/GrpcLog.cs @@ -0,0 +1,94 @@ +#region Copyright notice and license + +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; +using System.Collections.Concurrent; +using System.Diagnostics; +using System.IO; +using System.Runtime.InteropServices; +using System.Threading; + +namespace Grpc.Core.Internal +{ + internal delegate void GprLogDelegate(IntPtr fileStringPtr, Int32 line, UInt64 threadId, IntPtr severityStringPtr, IntPtr msgPtr); + + /// + /// Logs from gRPC C core library can get lost if your application is not a console app. + /// This class allows redirection of logs to arbitrary destination. + /// + internal static class GrpcLog + { + static object staticLock = new object(); + static GprLogDelegate writeCallback; + static TextWriter dest; + + [DllImport("grpc_csharp_ext.dll")] + static extern void grpcsharp_redirect_log(GprLogDelegate callback); + + /// + /// Sets text writer as destination for logs from native gRPC C core library. + /// Only first invocation has effect. + /// + /// + public static void RedirectNativeLogs(TextWriter textWriter) + { + lock (staticLock) + { + if (writeCallback == null) + { + writeCallback = new GprLogDelegate(HandleWrite); + dest = textWriter; + grpcsharp_redirect_log(writeCallback); + } + } + } + + private static void HandleWrite(IntPtr fileStringPtr, Int32 line, UInt64 threadId, IntPtr severityStringPtr, IntPtr msgPtr) + { + try + { + // TODO: DateTime format used here is different than in C core. + dest.WriteLine(string.Format("{0}{1} {2} {3}:{4}: {5}", + Marshal.PtrToStringAnsi(severityStringPtr), DateTime.Now, + threadId, + Marshal.PtrToStringAnsi(fileStringPtr), + line, + Marshal.PtrToStringAnsi(msgPtr))); + } + catch (Exception e) + { + Console.WriteLine("Caught exception in native callback " + e); + } + } + } +} diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c index 18e0431e3b2..3cdeaef715f 100644 --- a/src/csharp/ext/grpc_csharp_ext.c +++ b/src/csharp/ext/grpc_csharp_ext.c @@ -35,9 +35,10 @@ #include #include -#include #include #include +#include +#include #include @@ -579,6 +580,27 @@ grpcsharp_server_request_call(grpc_server *server, grpc_completion_queue *cq, &(ctx->server_rpc_new.request_metadata), cq, ctx); } +/* Logging */ + +typedef void(GPR_CALLTYPE *grpcsharp_log_func)(const char *file, + gpr_int32 line, + gpr_uint64 thd_id, + const char *severity_string, + const char *msg); +static grpcsharp_log_func log_func = NULL; + +/* Redirects gpr_log to log_func callback */ +static void grpcsharp_log_handler(gpr_log_func_args *args) { + log_func(args->file, args->line, gpr_thd_currentid(), + gpr_log_severity_string(args->severity), args->message); +} + +GPR_EXPORT void GPR_CALLTYPE +grpcsharp_redirect_log(grpcsharp_log_func func) { + GPR_ASSERT(func); + log_func = func; + gpr_set_log_function(grpcsharp_log_handler); +} /* For testing */ GPR_EXPORT void GPR_CALLTYPE From abf22022465f628fce764e1f5a775310c0317973 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 24 Feb 2015 08:43:02 -0800 Subject: [PATCH 42/75] grpc_csharp_ext.dll added to the project to force automatic copying to the output dir --- src/csharp/Grpc.Core/Grpc.Core.csproj | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj index 6156b2f38bb..f88c9b373fe 100644 --- a/src/csharp/Grpc.Core/Grpc.Core.csproj +++ b/src/csharp/Grpc.Core/Grpc.Core.csproj @@ -66,5 +66,10 @@ + + + PreserveNewest + + \ No newline at end of file From 5ffb4c33dcffa83677370ee4e46ccee665ecedea Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 24 Feb 2015 09:07:42 -0800 Subject: [PATCH 43/75] Include grpc_csharp_ext.dll only under Windows --- src/csharp/Grpc.Core/Grpc.Core.csproj | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj index f88c9b373fe..b5c15ee374f 100644 --- a/src/csharp/Grpc.Core/Grpc.Core.csproj +++ b/src/csharp/Grpc.Core/Grpc.Core.csproj @@ -66,10 +66,17 @@ - - - PreserveNewest - - + + + + + + PreserveNewest + + + + + \ No newline at end of file From b17b00b5410fdcc253f2e1c14c37ed093ff4cf95 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 24 Feb 2015 09:13:48 -0800 Subject: [PATCH 44/75] Fix to make the conditional include under Windows --- src/csharp/Grpc.Core/Grpc.Core.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj index b5c15ee374f..183c4423583 100644 --- a/src/csharp/Grpc.Core/Grpc.Core.csproj +++ b/src/csharp/Grpc.Core/Grpc.Core.csproj @@ -69,7 +69,7 @@ - + PreserveNewest From 035a9042660d003f52b38029a25f430b0ce8b277 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 25 Feb 2015 09:47:00 -0800 Subject: [PATCH 45/75] Make PHP compile --- src/php/ext/grpc/credentials.c | 2 +- src/php/ext/grpc/event.c | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/php/ext/grpc/credentials.c b/src/php/ext/grpc/credentials.c index f25e042dd7f..6d8f59fa33d 100644 --- a/src/php/ext/grpc/credentials.c +++ b/src/php/ext/grpc/credentials.c @@ -94,7 +94,7 @@ zval *grpc_php_wrap_credentials(grpc_credentials *wrapped) { * @return Credentials The new default credentials object */ PHP_METHOD(Credentials, createDefault) { - grpc_credentials *creds = grpc_default_credentials_create(); + grpc_credentials *creds = grpc_google_default_credentials_create(); zval *creds_object = grpc_php_wrap_credentials(creds); RETURN_DESTROY_ZVAL(creds_object); } diff --git a/src/php/ext/grpc/event.c b/src/php/ext/grpc/event.c index 8d398450a4d..452c4b8bcba 100644 --- a/src/php/ext/grpc/event.c +++ b/src/php/ext/grpc/event.c @@ -90,10 +90,6 @@ zval *grpc_php_convert_event(grpc_event *event) { add_property_stringl(event_object, "data", read_string, read_len, true); } break; - case GRPC_INVOKE_ACCEPTED: - add_property_long(event_object, "data", - (long)event->data.invoke_accepted); - break; case GRPC_WRITE_ACCEPTED: add_property_long(event_object, "data", (long)event->data.write_accepted); break; From 363eb8e27befc10dcff85aaadcbbf5d651c2394e Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 25 Feb 2015 09:50:46 -0800 Subject: [PATCH 46/75] Fix read through null pointer --- src/core/tsi/ssl_transport_security.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/tsi/ssl_transport_security.c b/src/core/tsi/ssl_transport_security.c index 9ca8e6ddc98..8446cc4fdc2 100644 --- a/src/core/tsi/ssl_transport_security.c +++ b/src/core/tsi/ssl_transport_security.c @@ -1094,8 +1094,9 @@ static int does_entry_match_name(const char* entry, size_t entry_length, return 0; } name_subdomain = strchr(name, '.'); + if (name_subdomain == NULL) return 0; name_subdomain_length = strlen(name_subdomain); - if (name_subdomain == NULL || name_subdomain_length < 2) return 0; + if (name_subdomain_length < 2) return 0; name_subdomain++; /* Starts after the dot. */ name_subdomain_length--; entry += 2; /* Remove *. */ From 44553b5810939042665d966efb0d83f98bb7398c Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 25 Feb 2015 09:52:18 -0800 Subject: [PATCH 47/75] clang-format --- src/csharp/ext/grpc_csharp_ext.c | 42 ++++++++++++++++---------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/src/csharp/ext/grpc_csharp_ext.c b/src/csharp/ext/grpc_csharp_ext.c index 3cdeaef715f..8f5a4141872 100644 --- a/src/csharp/ext/grpc_csharp_ext.c +++ b/src/csharp/ext/grpc_csharp_ext.c @@ -346,14 +346,19 @@ grpcsharp_call_start_unary(grpc_call *call, callback_funcptr callback, /* Synchronous unary call */ GPR_EXPORT void GPR_CALLTYPE -grpcsharp_call_blocking_unary(grpc_call *call, grpc_completion_queue *dedicated_cq, callback_funcptr callback, - const char *send_buffer, size_t send_buffer_len) { - GPR_ASSERT(grpcsharp_call_start_unary(call, callback, send_buffer, send_buffer_len) == GRPC_CALL_OK); +grpcsharp_call_blocking_unary(grpc_call *call, + grpc_completion_queue *dedicated_cq, + callback_funcptr callback, + const char *send_buffer, size_t send_buffer_len) { + GPR_ASSERT(grpcsharp_call_start_unary(call, callback, send_buffer, + send_buffer_len) == GRPC_CALL_OK); /* TODO: we would like to use pluck, but we don't know the tag */ - GPR_ASSERT(grpcsharp_completion_queue_next_with_callback(dedicated_cq) == GRPC_OP_COMPLETE); + GPR_ASSERT(grpcsharp_completion_queue_next_with_callback(dedicated_cq) == + GRPC_OP_COMPLETE); grpc_completion_queue_shutdown(dedicated_cq); - GPR_ASSERT(grpcsharp_completion_queue_next_with_callback(dedicated_cq) == GRPC_QUEUE_SHUTDOWN); + GPR_ASSERT(grpcsharp_completion_queue_next_with_callback(dedicated_cq) == + GRPC_QUEUE_SHUTDOWN); } GPR_EXPORT grpc_call_error GPR_CALLTYPE @@ -582,24 +587,22 @@ grpcsharp_server_request_call(grpc_server *server, grpc_completion_queue *cq, /* Logging */ -typedef void(GPR_CALLTYPE *grpcsharp_log_func)(const char *file, - gpr_int32 line, - gpr_uint64 thd_id, - const char *severity_string, - const char *msg); +typedef void(GPR_CALLTYPE *grpcsharp_log_func)(const char *file, gpr_int32 line, + gpr_uint64 thd_id, + const char *severity_string, + const char *msg); static grpcsharp_log_func log_func = NULL; /* Redirects gpr_log to log_func callback */ static void grpcsharp_log_handler(gpr_log_func_args *args) { - log_func(args->file, args->line, gpr_thd_currentid(), - gpr_log_severity_string(args->severity), args->message); + log_func(args->file, args->line, gpr_thd_currentid(), + gpr_log_severity_string(args->severity), args->message); } -GPR_EXPORT void GPR_CALLTYPE -grpcsharp_redirect_log(grpcsharp_log_func func) { - GPR_ASSERT(func); - log_func = func; - gpr_set_log_function(grpcsharp_log_handler); +GPR_EXPORT void GPR_CALLTYPE grpcsharp_redirect_log(grpcsharp_log_func func) { + GPR_ASSERT(func); + log_func = func; + gpr_set_log_function(grpcsharp_log_handler); } /* For testing */ @@ -609,7 +612,4 @@ grpcsharp_test_callback(callback_funcptr callback) { } /* For testing */ -GPR_EXPORT void *GPR_CALLTYPE -grpcsharp_test_nop(void *ptr) { - return ptr; -} +GPR_EXPORT void *GPR_CALLTYPE grpcsharp_test_nop(void *ptr) { return ptr; } From 208313895d768d6ca9cba940ce0c5d5c1943c4de Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 24 Feb 2015 14:16:04 -0800 Subject: [PATCH 48/75] Added interop server, interop unit tests and fixes to pingpong --- src/csharp/Grpc.Examples/MathServiceImpl.cs | 11 +- src/csharp/Grpc.IntegrationTesting/Client.cs | 20 +-- .../Grpc.IntegrationTesting.csproj | 2 + .../InteropClientServerTest.cs | 119 +++++++++++++++ .../TestServiceImpl.cs | 140 ++++++++++++++++++ 5 files changed, 274 insertions(+), 18 deletions(-) create mode 100644 src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs create mode 100644 src/csharp/Grpc.IntegrationTesting/TestServiceImpl.cs diff --git a/src/csharp/Grpc.Examples/MathServiceImpl.cs b/src/csharp/Grpc.Examples/MathServiceImpl.cs index 462fab4454f..76a08ce5186 100644 --- a/src/csharp/Grpc.Examples/MathServiceImpl.cs +++ b/src/csharp/Grpc.Examples/MathServiceImpl.cs @@ -127,8 +127,7 @@ namespace math public void OnCompleted() { - Task.Factory.StartNew(() => - responseObserver.OnCompleted()); + responseObserver.OnCompleted(); } public void OnError(Exception error) @@ -138,13 +137,7 @@ namespace math public void OnNext(DivArgs value) { - // TODO: currently we need this indirection because - // responseObserver waits for write to finish, this - // callback is called from grpc threadpool which - // currently only has one thread. - // Same story for OnCompleted(). - Task.Factory.StartNew(() => - responseObserver.OnNext(DivInternal(value))); + responseObserver.OnNext(DivInternal(value)); } } } diff --git a/src/csharp/Grpc.IntegrationTesting/Client.cs b/src/csharp/Grpc.IntegrationTesting/Client.cs index 0c70744cea5..fa1c7cd051b 100644 --- a/src/csharp/Grpc.IntegrationTesting/Client.cs +++ b/src/csharp/Grpc.IntegrationTesting/Client.cs @@ -138,7 +138,7 @@ namespace Grpc.IntegrationTesting } } - private void RunEmptyUnary(TestServiceGrpc.ITestServiceClient client) + public static void RunEmptyUnary(TestServiceGrpc.ITestServiceClient client) { Console.WriteLine("running empty_unary"); var response = client.EmptyCall(Empty.DefaultInstance); @@ -146,7 +146,7 @@ namespace Grpc.IntegrationTesting Console.WriteLine("Passed!"); } - private void RunLargeUnary(TestServiceGrpc.ITestServiceClient client) + public static void RunLargeUnary(TestServiceGrpc.ITestServiceClient client) { Console.WriteLine("running large_unary"); var request = SimpleRequest.CreateBuilder() @@ -162,7 +162,7 @@ namespace Grpc.IntegrationTesting Console.WriteLine("Passed!"); } - private void RunClientStreaming(TestServiceGrpc.ITestServiceClient client) + public static void RunClientStreaming(TestServiceGrpc.ITestServiceClient client) { Console.WriteLine("running client_streaming"); @@ -181,7 +181,7 @@ namespace Grpc.IntegrationTesting Console.WriteLine("Passed!"); } - private void RunServerStreaming(TestServiceGrpc.ITestServiceClient client) + public static void RunServerStreaming(TestServiceGrpc.ITestServiceClient client) { Console.WriteLine("running server_streaming"); @@ -206,7 +206,7 @@ namespace Grpc.IntegrationTesting Console.WriteLine("Passed!"); } - private void RunPingPong(TestServiceGrpc.ITestServiceClient client) + public static void RunPingPong(TestServiceGrpc.ITestServiceClient client) { Console.WriteLine("running ping_pong"); @@ -235,7 +235,7 @@ namespace Grpc.IntegrationTesting inputs.OnNext(StreamingOutputCallRequest.CreateBuilder() .SetResponseType(PayloadType.COMPRESSABLE) - .AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(2635)) + .AddResponseParameters(ResponseParameters.CreateBuilder().SetSize(2653)) .SetPayload(CreateZerosPayload(1828)).Build()); response = recorder.Queue.Take(); @@ -252,13 +252,15 @@ namespace Grpc.IntegrationTesting Assert.AreEqual(PayloadType.COMPRESSABLE, response.Payload.Type); Assert.AreEqual(58979, response.Payload.Body.Length); + inputs.OnCompleted(); + recorder.Finished.Wait(); Assert.AreEqual(0, recorder.Queue.Count); Console.WriteLine("Passed!"); } - private void RunEmptyStream(TestServiceGrpc.ITestServiceClient client) + public static void RunEmptyStream(TestServiceGrpc.ITestServiceClient client) { Console.WriteLine("running empty_stream"); @@ -273,13 +275,13 @@ namespace Grpc.IntegrationTesting } // This is not an official interop test, but it's useful. - private void RunBenchmarkEmptyUnary(TestServiceGrpc.ITestServiceClient client) + public static void RunBenchmarkEmptyUnary(TestServiceGrpc.ITestServiceClient client) { BenchmarkUtil.RunBenchmark(10000, 10000, () => { client.EmptyCall(Empty.DefaultInstance);}); } - private Payload CreateZerosPayload(int size) { + private static Payload CreateZerosPayload(int size) { return Payload.CreateBuilder().SetBody(ByteString.CopyFrom(new byte[size])).Build(); } diff --git a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj index 9b46a644bc1..e66f708a945 100644 --- a/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj +++ b/src/csharp/Grpc.IntegrationTesting/Grpc.IntegrationTesting.csproj @@ -47,6 +47,8 @@ + + diff --git a/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs b/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs new file mode 100644 index 00000000000..87d25b0a98c --- /dev/null +++ b/src/csharp/Grpc.IntegrationTesting/InteropClientServerTest.cs @@ -0,0 +1,119 @@ +#region Copyright notice and license + +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Grpc.Core; +using Grpc.Core.Utils; +using NUnit.Framework; +using grpc.testing; + +namespace Grpc.IntegrationTesting +{ + /// + /// Runs interop tests in-process. + /// + public class InteropClientServerTest + { + string host = "localhost"; + Server server; + Channel channel; + TestServiceGrpc.ITestServiceClient client; + + [TestFixtureSetUp] + public void Init() + { + GrpcEnvironment.Initialize(); + + server = new Server(); + server.AddServiceDefinition(TestServiceGrpc.BindService(new TestServiceImpl())); + int port = server.AddPort(host + ":0"); + server.Start(); + channel = new Channel(host + ":" + port); + client = TestServiceGrpc.NewStub(channel); + } + + [TestFixtureTearDown] + public void Cleanup() + { + channel.Dispose(); + + server.ShutdownAsync().Wait(); + GrpcEnvironment.Shutdown(); + } + + [Test] + public void EmptyUnary() + { + Client.RunEmptyUnary(client); + } + + [Test] + public void LargeUnary() + { + Client.RunEmptyUnary(client); + } + + [Test] + public void ClientStreaming() + { + Client.RunClientStreaming(client); + } + + [Test] + public void ServerStreaming() + { + Client.RunServerStreaming(client); + } + + [Test] + public void PingPong() + { + Client.RunPingPong(client); + } + + [Test] + public void EmptyStream() + { + Client.RunEmptyStream(client); + } + + // TODO: add cancel_after_begin + + // TODO: add cancel_after_first_response + + } +} + diff --git a/src/csharp/Grpc.IntegrationTesting/TestServiceImpl.cs b/src/csharp/Grpc.IntegrationTesting/TestServiceImpl.cs new file mode 100644 index 00000000000..176843b1305 --- /dev/null +++ b/src/csharp/Grpc.IntegrationTesting/TestServiceImpl.cs @@ -0,0 +1,140 @@ +#region Copyright notice and license + +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; +using System.Collections.Generic; +using System.Threading; +using System.Threading.Tasks; +using Google.ProtocolBuffers; +using Grpc.Core.Utils; + +namespace grpc.testing +{ + /// + /// Implementation of TestService server + /// + public class TestServiceImpl : TestServiceGrpc.ITestService + { + public void EmptyCall(Empty request, IObserver responseObserver) + { + responseObserver.OnNext(Empty.DefaultInstance); + responseObserver.OnCompleted(); + } + + public void UnaryCall(SimpleRequest request, IObserver responseObserver) + { + var response = SimpleResponse.CreateBuilder() + .SetPayload(CreateZerosPayload(request.ResponseSize)).Build(); + //TODO: check we support ReponseType + responseObserver.OnNext(response); + responseObserver.OnCompleted(); + } + + public void StreamingOutputCall(StreamingOutputCallRequest request, IObserver responseObserver) + { + foreach(var responseParam in request.ResponseParametersList) + { + var response = StreamingOutputCallResponse.CreateBuilder() + .SetPayload(CreateZerosPayload(responseParam.Size)).Build(); + responseObserver.OnNext(response); + } + responseObserver.OnCompleted(); + } + + public IObserver StreamingInputCall(IObserver responseObserver) + { + var recorder = new RecordingObserver(); + Task.Run(() => { + int sum = 0; + foreach(var req in recorder.ToList().Result) + { + sum += req.Payload.Body.Length; + } + var response = StreamingInputCallResponse.CreateBuilder() + .SetAggregatedPayloadSize(sum).Build(); + responseObserver.OnNext(response); + responseObserver.OnCompleted(); + }); + return recorder; + } + + public IObserver FullDuplexCall(IObserver responseObserver) + { + return new FullDuplexObserver(responseObserver); + } + + public IObserver HalfDuplexCall(IObserver responseObserver) + { + throw new NotImplementedException(); + } + + private class FullDuplexObserver : IObserver { + + readonly IObserver responseObserver; + + public FullDuplexObserver(IObserver responseObserver) + { + this.responseObserver = responseObserver; + } + + public void OnCompleted() + { + responseObserver.OnCompleted(); + } + + public void OnError(Exception error) + { + throw new NotImplementedException(); + } + + public void OnNext(StreamingOutputCallRequest value) + { + // TODO: this is not in order!!! + //Task.Factory.StartNew(() => { + + foreach(var responseParam in value.ResponseParametersList) + { + var response = StreamingOutputCallResponse.CreateBuilder() + .SetPayload(CreateZerosPayload(responseParam.Size)).Build(); + responseObserver.OnNext(response); + } + //}); + } + } + + private static Payload CreateZerosPayload(int size) { + return Payload.CreateBuilder().SetBody(ByteString.CopyFrom(new byte[size])).Build(); + } + } +} + From 0e1f527914a3b08ddb2dcb4a22b622f5a30d5215 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 24 Feb 2015 14:27:11 -0800 Subject: [PATCH 49/75] fix to make empty_stream pass against C++ server --- src/csharp/Grpc.Core/Internal/AsyncCall.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs index dadc9ab76cf..44f0b37b0ff 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs @@ -544,6 +544,8 @@ namespace Grpc.Core.Internal } observer = readObserver; status = finishedStatus; + + ReleaseResourcesIfPossible(); } // TODO: wrap deserialization... From 4788e78d10919a74437d228790c0837ad96fcf6b Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Tue, 24 Feb 2015 16:14:28 -0800 Subject: [PATCH 50/75] fixed server streaming --- src/csharp/Grpc.Core/Internal/AsyncCall.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs index 44f0b37b0ff..6f37b059f75 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs @@ -181,6 +181,7 @@ namespace Grpc.Core.Internal { started = true; halfcloseRequested = true; + halfclosed = true; // halfclose not confirmed yet, but it will be once finishedHandler is called. this.readObserver = readObserver; From e0172a86a0a0ab5a8b9d1a8122cf4e5017d6e004 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 25 Feb 2015 10:23:29 -0800 Subject: [PATCH 51/75] fix readme --- src/python/README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/python/README.md b/src/python/README.md index be2f2bedf9c..5a4194b7cdf 100755 --- a/src/python/README.md +++ b/src/python/README.md @@ -1,7 +1,7 @@ -GRPC Python +gRPC Python ========= -The Python facility of GRPC. +The Python facility of gRPC. Prerequisites @@ -13,8 +13,8 @@ Python 2.7, virtualenv, pip, libprotobuf-dev, and libprotoc-dev. Building from source ---------------------- -- Build the GRPC core -E.g, from the root of the grpc [git repo](https://github.com/google/grpc) +- Build the gRPC core from the root of the + [gRPC git repo](https://github.com/grpc/grpc) ``` $ make shared_c static_c ``` @@ -28,7 +28,7 @@ $ tools/run_tests/build_python.sh Testing ----------------------- -- Use run_python.sh to run GRPC as it was installed into the virtual environment +- Use run_python.sh to run gRPC as it was installed into the virtual environment ``` $ tools/run_tests/run_python.sh ``` From 3061606fdec09ab74d56a865ea8b3bb847f94b77 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Wed, 25 Feb 2015 10:38:34 -0800 Subject: [PATCH 52/75] Fixed TLS host resolution problems --- src/node/ext/channel.cc | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/node/ext/channel.cc b/src/node/ext/channel.cc index 6c7a89e596d..bc9461d7dfd 100644 --- a/src/node/ext/channel.cc +++ b/src/node/ext/channel.cc @@ -103,11 +103,15 @@ NAN_METHOD(Channel::New) { grpc_channel *wrapped_channel; // Owned by the Channel object NanUtf8String *host = new NanUtf8String(args[0]); + NanUtf8String *host_override = NULL; if (args[1]->IsUndefined()) { wrapped_channel = grpc_channel_create(**host, NULL); } else if (args[1]->IsObject()) { grpc_credentials *creds = NULL; Handle args_hash(args[1]->ToObject()->Clone()); + if (args_hash->HasOwnProperty(NanNew(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG))) { + host_override = new NanUtf8String(args_hash->Get(NanNew(GRPC_SSL_TARGET_NAME_OVERRIDE_ARG))); + } if (args_hash->HasOwnProperty(NanNew("credentials"))) { Handle creds_value = args_hash->Get(NanNew("credentials")); if (!Credentials::HasInstance(creds_value)) { @@ -155,7 +159,12 @@ NAN_METHOD(Channel::New) { } else { return NanThrowTypeError("Channel expects a string and an object"); } - Channel *channel = new Channel(wrapped_channel, host); + Channel *channel; + if (host_override == NULL) { + channel = new Channel(wrapped_channel, host); + } else { + channel = new Channel(wrapped_channel, host_override); + } channel->Wrap(args.This()); NanReturnValue(args.This()); } else { From 1d5f2d26df535f886a64b33b22f3a8088402fc61 Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Wed, 25 Feb 2015 10:55:27 -0800 Subject: [PATCH 53/75] Removes a redundant canary test --- src/ruby/spec/credentials_spec.rb | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/ruby/spec/credentials_spec.rb b/src/ruby/spec/credentials_spec.rb index 001fecd12b6..fc97d11a878 100644 --- a/src/ruby/spec/credentials_spec.rb +++ b/src/ruby/spec/credentials_spec.rb @@ -68,10 +68,4 @@ describe Credentials do expect { cred1.compose(cred2) }.to_not raise_error end end - - describe 'Credentials#default' do - it 'is not implemented yet' do - expect { Credentials.default }.to raise_error RuntimeError - end - end end From 9e81817ee587478035536634c95d011372397d6f Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Wed, 25 Feb 2015 11:04:44 -0800 Subject: [PATCH 54/75] Update CONTRIBUTING.md Massage wording and fix the instructions for run_tests to remove reference to non-existsant -l all option. --- CONTRIBUTING.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 57d176f6637..b58c3568fcd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -24,27 +24,27 @@ properly run all the tests. If you are planning to work on any of the languages other than C and C++, you will also need their appropriate development environments. -If you want to work under Windows, we recommend you to use Visual Studio 2013. +If you want to work under Windows, we recommend the use of Visual Studio 2013. The [Community or Express editions](http://www.visualstudio.com/en-us/downloads/download-visual-studio-vs.aspx) are free and suitable for developing with grpc. Note however that our test environment and tools are available for Unix environments only at the moment. ## Testing your changes -We provide a tool to help you run our suite of tests in various environments. +We provide a tool to help run the suite of tests in various environments. In order to run most of the available tests, one would need to run: `./tools/run_tests/run_tests.py` -If you want to run all the possible tests for all possible languages, do this: +If you want to run all the possible tests for any of the languages {c, c++, node, php, python}, do this: -`./tools/run_tests/run_tests.py -lall -call` +`./tools/run_tests/run_tests.py -l -c all` ## Adding or removing source code Each language uses its own build system to work. Currently, the root's Makefile -and the Visual Studio project files are building the C and C++ source code only -at the moment. In order to ease the maintenance of these files, we have a +and the Visual Studio project files are building only the C and C++ source code. +In order to ease the maintenance of these files, we have a template system. Please do not contribute manual changes to any of the generated files. Instead, modify the template files, or the build.json file, and re-generate the project files using the following command: From c855d576663973392eac56ddb12c6fad996e1f38 Mon Sep 17 00:00:00 2001 From: Nathaniel Manista Date: Wed, 25 Feb 2015 19:09:08 +0000 Subject: [PATCH 55/75] Python ClientCredentials object. --- src/python/src/grpc/_adapter/_c.c | 4 + src/python/src/grpc/_adapter/_c_test.py | 23 ++++ .../src/grpc/_adapter/_client_credentials.c | 120 ++++++++++++++++++ .../src/grpc/_adapter/_client_credentials.h | 48 +++++++ src/python/src/grpc/_adapter/_low.py | 1 + src/python/src/setup.py | 1 + 6 files changed, 197 insertions(+) create mode 100644 src/python/src/grpc/_adapter/_client_credentials.c create mode 100644 src/python/src/grpc/_adapter/_client_credentials.h diff --git a/src/python/src/grpc/_adapter/_c.c b/src/python/src/grpc/_adapter/_c.c index 55b9d0512c9..f096a55b618 100644 --- a/src/python/src/grpc/_adapter/_c.c +++ b/src/python/src/grpc/_adapter/_c.c @@ -38,6 +38,7 @@ #include "grpc/_adapter/_channel.h" #include "grpc/_adapter/_call.h" #include "grpc/_adapter/_server.h" +#include "grpc/_adapter/_client_credentials.h" #include "grpc/_adapter/_server_credentials.h" static PyObject *init(PyObject *self) { @@ -76,6 +77,9 @@ PyMODINIT_FUNC init_c(void) { if (pygrpc_add_server(module) == -1) { return; } + if (pygrpc_add_client_credentials(module) == -1) { + return; + } if (pygrpc_add_server_credentials(module) == -1) { return; } diff --git a/src/python/src/grpc/_adapter/_c_test.py b/src/python/src/grpc/_adapter/_c_test.py index d421692ec9c..44aff44ffa0 100644 --- a/src/python/src/grpc/_adapter/_c_test.py +++ b/src/python/src/grpc/_adapter/_c_test.py @@ -136,6 +136,29 @@ class _CTest(unittest.TestCase): _c.shut_down() + def test_client_credentials(self): + root_certificates = b'Trust starts here. Really.' + private_key = b'This is a really bad private key, yo.' + certificate_chain = b'Trust me! Do I not look trustworty?' + + _c.init() + + client_credentials = _c.ClientCredentials( + None, None, None) + self.assertIsNotNone(client_credentials) + client_credentials = _c.ClientCredentials( + root_certificates, None, None) + self.assertIsNotNone(client_credentials) + client_credentials = _c.ClientCredentials( + None, private_key, certificate_chain) + self.assertIsNotNone(client_credentials) + client_credentials = _c.ClientCredentials( + root_certificates, private_key, certificate_chain) + self.assertIsNotNone(client_credentials) + del client_credentials + + _c.shut_down() + def test_server_credentials(self): root_certificates = b'Trust starts here. Really.' first_private_key = b'This is a really bad private key, yo.' diff --git a/src/python/src/grpc/_adapter/_client_credentials.c b/src/python/src/grpc/_adapter/_client_credentials.c new file mode 100644 index 00000000000..b970c866ef7 --- /dev/null +++ b/src/python/src/grpc/_adapter/_client_credentials.c @@ -0,0 +1,120 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include "grpc/_adapter/_client_credentials.h" + +#include +#include +#include + +static int pygrpc_client_credentials_init(ClientCredentials *self, + PyObject *args, PyObject *kwds) { + char *root_certificates; + grpc_ssl_pem_key_cert_pair key_certificate_pair; + static char *kwlist[] = {"root_certificates", "private_key", + "certificate_chain", NULL}; + + if (!PyArg_ParseTupleAndKeywords(args, kwds, "zzz:ClientCredentials", kwlist, + &root_certificates, + &key_certificate_pair.private_key, + &key_certificate_pair.cert_chain)) { + return -1; + } + + if (key_certificate_pair.private_key != NULL && key_certificate_pair.cert_chain != NULL) { + self->c_client_credentials = + grpc_ssl_credentials_create(root_certificates, &key_certificate_pair); + } else { + self->c_client_credentials = + grpc_ssl_credentials_create(root_certificates, NULL); + } +} + +static void pygrpc_client_credentials_dealloc(ClientCredentials *self) { + if (self->c_client_credentials != NULL) { + grpc_credentials_release(self->c_client_credentials); + } + self->ob_type->tp_free((PyObject *)self); +} + +PyTypeObject pygrpc_ClientCredentialsType = { + PyVarObject_HEAD_INIT(NULL, 0) + "_grpc.ClientCredencials", /*tp_name*/ + sizeof(ClientCredentials), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)pygrpc_client_credentials_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + 0, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT, /*tp_flags*/ + "Wrapping of grpc_credentials.", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + 0, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)pygrpc_client_credentials_init, /* tp_init */ + 0, /* tp_alloc */ + PyType_GenericNew, /* tp_new */ +}; + +int pygrpc_add_client_credentials(PyObject *module) { + if (PyType_Ready(&pygrpc_ClientCredentialsType) < 0) { + return -1; + } + if (PyModule_AddObject(module, "ClientCredentials", + (PyObject *)&pygrpc_ClientCredentialsType) == -1) { + return -1; + } + return 0; +} diff --git a/src/python/src/grpc/_adapter/_client_credentials.h b/src/python/src/grpc/_adapter/_client_credentials.h new file mode 100644 index 00000000000..664dc80d751 --- /dev/null +++ b/src/python/src/grpc/_adapter/_client_credentials.h @@ -0,0 +1,48 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef _ADAPTER__CLIENT_CREDENTIALS_H_ +#define _ADAPTER__CLIENT_CREDENTIALS_H_ + +#include +#include + +typedef struct { + PyObject_HEAD grpc_credentials *c_client_credentials; +} ClientCredentials; + +PyTypeObject pygrpc_ClientCredentialsType; + +int pygrpc_add_client_credentials(PyObject *module); + +#endif /* _ADAPTER__CLIENT_CREDENTIALS_H_ */ diff --git a/src/python/src/grpc/_adapter/_low.py b/src/python/src/grpc/_adapter/_low.py index 2ef2eb879c1..a24baaeb3e7 100644 --- a/src/python/src/grpc/_adapter/_low.py +++ b/src/python/src/grpc/_adapter/_low.py @@ -52,5 +52,6 @@ Call = _c.Call Channel = _c.Channel CompletionQueue = _c.CompletionQueue Server = _c.Server +ClientCredentials = _c.ClientCredentials ServerCredentials = _c.ServerCredentials # pylint: enable=invalid-name diff --git a/src/python/src/setup.py b/src/python/src/setup.py index e3f13fa5c8f..23f128636e4 100644 --- a/src/python/src/setup.py +++ b/src/python/src/setup.py @@ -38,6 +38,7 @@ _EXTENSION_SOURCES = ( 'grpc/_adapter/_completion_queue.c', 'grpc/_adapter/_error.c', 'grpc/_adapter/_server.c', + 'grpc/_adapter/_client_credentials.c', 'grpc/_adapter/_server_credentials.c', ) From d32eab2a44cda82e54c6fa01b36312c9defd9946 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Wed, 25 Feb 2015 20:19:16 +0100 Subject: [PATCH 56/75] We have decided our release version number shall be 0.5.0. --- Makefile | 2 +- build.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 277e8caebc2..ee79df40f42 100644 --- a/Makefile +++ b/Makefile @@ -195,7 +195,7 @@ E = @echo Q = @ endif -VERSION = 0.8.0.0 +VERSION = 0.5.0.0 CPPFLAGS_NO_ARCH += $(addprefix -I, $(INCLUDES)) $(addprefix -D, $(DEFINES)) CPPFLAGS += $(CPPFLAGS_NO_ARCH) $(ARCH_FLAGS) diff --git a/build.json b/build.json index 7a030ea888a..96437d0a66f 100644 --- a/build.json +++ b/build.json @@ -3,7 +3,7 @@ "#": "The public version number of the library.", "version": { "major": 0, - "minor": 8, + "minor": 5, "micro": 0, "build": 0 } From 85f9963e14d4362eb06dc858f8ddafcc227bb250 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar Date: Wed, 25 Feb 2015 11:45:05 -0800 Subject: [PATCH 57/75] Update README --- examples/pubsub/README | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/examples/pubsub/README b/examples/pubsub/README index b55083afc56..faeb622153f 100644 --- a/examples/pubsub/README +++ b/examples/pubsub/README @@ -1,3 +1,6 @@ +Experimental example code, likely to change. +Users should not attempt to run this code till this warning is removed. + C++ Client implementation for Cloud Pub/Sub service (https://developers.google.com/apis-explorer/#p/pubsub/v1beta1/). @@ -12,19 +15,7 @@ be created with scope "https://www.googleapis.com/auth/cloud-platform" as below: gcloud compute instances create instance-name --image debian-7 --scopes https://www.googleapis.com/auth/cloud-platform -Google TLS cert is required to run the client, which can be downloaded from -Chrome browser. - -To run the client from GCE: -make pubsub_client -GRPC_DEFAULT_SSL_ROOTS_FILE_PATH="Google TLS cert" bins/opt/pubsub_client - --project_id="your project id" - -A service account credential is required to run the client from other -environments, which can be generated as a JSON key file from -https://console.developers.google.com/project/. To run the client with a service -account credential: -GRPC_DEFAULT_SSL_ROOTS_FILE_PATH="Google TLS cert" bins/opt/pubsub_client - --project_id="your project id" - --service_account_key_file="absolute path to the JSON key file" +To run the client: +make pubsub_client +bins/opt/pubsub_client --project_id="your project id" From 7708998b5a8018cbef7bd696563edc1e4aac210c Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Wed, 25 Feb 2015 11:49:34 -0800 Subject: [PATCH 58/75] Tmp fix: splits the hostname from the host before creating a call --- src/ruby/lib/grpc/generic/client_stub.rb | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/ruby/lib/grpc/generic/client_stub.rb b/src/ruby/lib/grpc/generic/client_stub.rb index 7fc0d83501a..f234984eec3 100644 --- a/src/ruby/lib/grpc/generic/client_stub.rb +++ b/src/ruby/lib/grpc/generic/client_stub.rb @@ -400,7 +400,12 @@ module GRPC # @param deadline [TimeConst] def new_active_call(ch, marshal, unmarshal, deadline = nil) absolute_deadline = Core::TimeConsts.from_relative_time(deadline) - call = @ch.create_call(ch, @host, absolute_deadline) + # It should be OK to to pass the hostname:port to create_call, but at + # the moment this fails a security check. This will be corrected. + # + # TODO: # remove this after create_call is updated + host = @host.split(':')[0] + call = @ch.create_call(ch, host, absolute_deadline) ActiveCall.new(call, @queue, marshal, unmarshal, absolute_deadline, started: false) end From deb49dd1aa4a12003cc445f08b55f3f95859fe67 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 25 Feb 2015 11:58:49 -0800 Subject: [PATCH 59/75] Strip port in peer name check This string comes from an authority field, which is allowed to contain a ':' port (see https://tools.ietf.org/html/rfc3986#section-3.2). We need to strip it before performing host name verification. --- src/core/security/security_context.c | 23 +++++++++++++++++++++-- test/core/end2end/tests/simple_request.c | 4 ++-- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/core/security/security_context.c b/src/core/security/security_context.c index 60064dc83dd..0dc37fa73c0 100644 --- a/src/core/security/security_context.c +++ b/src/core/security/security_context.c @@ -338,6 +338,24 @@ static grpc_security_status ssl_server_create_handshaker( return ssl_create_handshaker(c->handshaker_factory, 0, NULL, handshaker); } +static int ssl_host_matches_name(const tsi_peer *peer, + const char *peer_name) { + char *allocated_name = NULL; + int r; + + if (strchr(peer_name, ':') != NULL) { + char *ignored_port; + gpr_split_host_port(peer_name, &allocated_name, &ignored_port); + gpr_free(ignored_port); + peer_name = allocated_name; + if (!peer_name) return 0; + } + + r = tsi_ssl_peer_matches_name(peer, peer_name); + gpr_free(allocated_name); + return r; +} + static grpc_security_status ssl_check_peer(const char *peer_name, const tsi_peer *peer) { /* Check the ALPN. */ @@ -359,10 +377,11 @@ static grpc_security_status ssl_check_peer(const char *peer_name, /* Check the peer name if specified. */ if (peer_name != NULL && - !tsi_ssl_peer_matches_name(peer, peer_name)) { + !ssl_host_matches_name(peer, peer_name)) { gpr_log(GPR_ERROR, "Peer name %s is not in peer certificate", peer_name); return GRPC_SECURITY_ERROR; } + return GRPC_SECURITY_OK; } @@ -398,7 +417,7 @@ static grpc_security_status ssl_channel_check_call_host( grpc_ssl_channel_security_context *c = (grpc_ssl_channel_security_context *)ctx; - if (tsi_ssl_peer_matches_name(&c->peer, host)) return GRPC_SECURITY_OK; + if (ssl_host_matches_name(&c->peer, host)) return GRPC_SECURITY_OK; /* If the target name was overridden, then the original target_name was 'checked' transitively during the previous peer check at the end of the diff --git a/test/core/end2end/tests/simple_request.c b/test/core/end2end/tests/simple_request.c index dac82535be7..5b36a19f3db 100644 --- a/test/core/end2end/tests/simple_request.c +++ b/test/core/end2end/tests/simple_request.c @@ -122,7 +122,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) { int was_cancelled = 2; c = grpc_channel_create_call(f.client, f.client_cq, "/foo", - "foo.test.google.fr", deadline); + "foo.test.google.fr:1234", deadline); GPR_ASSERT(c); grpc_metadata_array_init(&initial_metadata_recv); @@ -178,7 +178,7 @@ static void simple_request_body(grpc_end2end_test_fixture f) { GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); GPR_ASSERT(0 == strcmp(details, "xyz")); GPR_ASSERT(0 == strcmp(call_details.method, "/foo")); - GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr")); + GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr:1234")); GPR_ASSERT(was_cancelled == 0); gpr_free(details); From 60fcca5dec4973faf3d1f0f7d83dfb419f882614 Mon Sep 17 00:00:00 2001 From: Dan Ciruli Date: Wed, 25 Feb 2015 12:24:39 -0800 Subject: [PATCH 60/75] Update binding.gyp --- src/node/binding.gyp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/node/binding.gyp b/src/node/binding.gyp index fb4c779f8eb..5c34be24ff5 100644 --- a/src/node/binding.gyp +++ b/src/node/binding.gyp @@ -7,7 +7,7 @@ "targets" : [ { 'include_dirs': [ - " Date: Wed, 25 Feb 2015 12:30:26 -0800 Subject: [PATCH 61/75] Changing to use node instead of nodejs --- src/node/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/node/package.json b/src/node/package.json index 1c44b106fb4..24b4a6ead45 100644 --- a/src/node/package.json +++ b/src/node/package.json @@ -3,8 +3,8 @@ "version": "0.2.0", "description": "gRPC Library for Node", "scripts": { - "lint": "nodejs ./node_modules/jshint/bin/jshint src test examples interop index.js", - "test": "nodejs ./node_modules/mocha/bin/mocha && npm run-script lint" + "lint": "node ./node_modules/jshint/bin/jshint src test examples interop index.js", + "test": "node ./node_modules/mocha/bin/mocha && npm run-script lint" }, "dependencies": { "bindings": "^1.2.1", From de3c654bc991d3e0d58e9dc81b4ac6aad2965e6d Mon Sep 17 00:00:00 2001 From: Dan Ciruli Date: Wed, 25 Feb 2015 12:50:09 -0800 Subject: [PATCH 62/75] Clarify INSTALL Added better instructions (including the git instructions). --- INSTALL | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/INSTALL b/INSTALL index 2f5f29c788f..c12bea089fc 100644 --- a/INSTALL +++ b/INSTALL @@ -9,15 +9,16 @@ wiki pages: * If you are in a hurry * ************************* -A typical unix installation won't require any more steps than running: + $ git clone https://github.com/grpc/grpc.git + $ git submodule update --init - $ make - # make install + $ make + $ sudo make install You don't need anything else than GNU Make, gcc and autotools. Under a Debian or Ubuntu system, this should boil down to the following packages: - # apt-get install build-essential autoconf libtool + $ apt-get install build-essential autoconf libtool Building the python wrapper requires the following: From e6d72c2b4efc6eeb23e5a5141b4ac465d8629b8e Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Wed, 25 Feb 2015 22:16:45 +0100 Subject: [PATCH 63/75] Removing emplace from python plugin. --- src/compiler/python_generator.cc | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/compiler/python_generator.cc b/src/compiler/python_generator.cc index 34d5332d03f..a93b08c5ceb 100644 --- a/src/compiler/python_generator.cc +++ b/src/compiler/python_generator.cc @@ -245,8 +245,8 @@ bool PrintServerFactory(const ServiceDescriptor* service, Printer* out) { if (!GetModuleAndMessagePath(input_type, &module_and_message)) { return false; } - method_to_module_and_message.emplace( - meth->name(), module_and_message); + method_to_module_and_message.insert( + make_pair(meth->name(), module_and_message)); } out->Print("}\n"); // Ensure that we've imported all of the relevant messages. @@ -306,8 +306,8 @@ bool PrintStubFactory(const ServiceDescriptor* service, Printer* out) { if (!GetModuleAndMessagePath(output_type, &module_and_message)) { return false; } - method_to_module_and_message.emplace( - meth->name(), module_and_message); + method_to_module_and_message.insert( + make_pair(meth->name(), module_and_message)); } out->Print("}\n"); // Ensure that we've imported all of the relevant messages. From b189cbe7c0d8ef6077d262653fc462740d14f826 Mon Sep 17 00:00:00 2001 From: Michael Lumish Date: Wed, 25 Feb 2015 13:24:30 -0800 Subject: [PATCH 64/75] Add Debian nodejs-legacy instructions --- src/node/README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/node/README.md b/src/node/README.md index 8880213e9a9..5b3de6b4f6e 100644 --- a/src/node/README.md +++ b/src/node/README.md @@ -4,6 +4,10 @@ Alpha : Ready for early adopters +## Prerequisites + +This requires `node` to be installed. If you instead have the `nodejs` executable on Debian, you should install the [`nodejs-legacy`](https://packages.debian.org/sid/nodejs-legacy) package. + ## Installation First, clone this repository (NPM package coming soon). Then follow the instructions in the `INSTALL` file in the root of the repository to install the C core library that this package depends on. From 9e47368d8fcd2615f5e301364386f3427883ab88 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Wed, 25 Feb 2015 13:28:22 -0800 Subject: [PATCH 65/75] Bumped node version to 0.5.0 --- src/node/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/node/package.json b/src/node/package.json index 1c44b106fb4..57434a618ae 100644 --- a/src/node/package.json +++ b/src/node/package.json @@ -1,6 +1,6 @@ { "name": "grpc", - "version": "0.2.0", + "version": "0.5.0", "description": "gRPC Library for Node", "scripts": { "lint": "nodejs ./node_modules/jshint/bin/jshint src test examples interop index.js", From c6e42c8a868ca3b471cd1f4a7697bc7195efea06 Mon Sep 17 00:00:00 2001 From: Nathaniel Manista Date: Wed, 25 Feb 2015 21:30:24 +0000 Subject: [PATCH 66/75] Set Python version number to 0.4.0. --- src/python/src/setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python/src/setup.py b/src/python/src/setup.py index 23f128636e4..26121dcfab6 100644 --- a/src/python/src/setup.py +++ b/src/python/src/setup.py @@ -81,6 +81,6 @@ _PACKAGE_DIRECTORIES = { } _core.setup( - name='grpc-2015', version='0.0.1', + name='grpc-2015', version='0.4.0', ext_modules=[_EXTENSION_MODULE], packages=_PACKAGES, package_dir=_PACKAGE_DIRECTORIES) From 57c0061d782cb9ff45583c942eceb8b96896df80 Mon Sep 17 00:00:00 2001 From: David Klempner Date: Wed, 25 Feb 2015 13:37:12 -0800 Subject: [PATCH 67/75] Deflake dualstack socket test The test currently allocates a single port and reuses it through the test. Given the timeouts in this test this leaves substantial race windows where other processes on the same machine could steal the port between subcases. Instead, as a simple hack, allocate a new port before each test. --- test/core/end2end/dualstack_socket_test.c | 51 +++++++++++------------ 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/test/core/end2end/dualstack_socket_test.c b/test/core/end2end/dualstack_socket_test.c index 62676d01e09..5e2c80af5ad 100644 --- a/test/core/end2end/dualstack_socket_test.c +++ b/test/core/end2end/dualstack_socket_test.c @@ -75,6 +75,10 @@ void test_connect(const char *server_host, const char *client_host, int port, gpr_timespec deadline; int got_port; + if (port == 0) { + port = grpc_pick_unused_port_or_die(); + } + gpr_join_host_port(&server_hostport, server_host, port); /* Create server. */ @@ -179,7 +183,6 @@ void test_connect(const char *server_host, const char *client_host, int port, int main(int argc, char **argv) { int do_ipv6 = 1; - int fixed_port; grpc_test_init(argc, argv); grpc_init(); @@ -189,32 +192,28 @@ int main(int argc, char **argv) { do_ipv6 = 0; } - for (fixed_port = 0; fixed_port <= 1; fixed_port++) { - int port = fixed_port ? grpc_pick_unused_port_or_die() : 0; - /* For coverage, test with and without dualstack sockets. */ - for (grpc_forbid_dualstack_sockets_for_testing = 0; - grpc_forbid_dualstack_sockets_for_testing <= 1; - grpc_forbid_dualstack_sockets_for_testing++) { - /* :: and 0.0.0.0 are handled identically. */ - test_connect("::", "127.0.0.1", port, 1); - test_connect("::", "::ffff:127.0.0.1", port, 1); - test_connect("::", "localhost", port, 1); - test_connect("0.0.0.0", "127.0.0.1", port, 1); - test_connect("0.0.0.0", "::ffff:127.0.0.1", port, 1); - test_connect("0.0.0.0", "localhost", port, 1); - if (do_ipv6) { - test_connect("::", "::1", port, 1); - test_connect("0.0.0.0", "::1", port, 1); - } - - /* These only work when the families agree. */ - test_connect("127.0.0.1", "127.0.0.1", port, 1); - if (do_ipv6) { - test_connect("::1", "::1", port, 1); - test_connect("::1", "127.0.0.1", port, 0); - test_connect("127.0.0.1", "::1", port, 0); - } + for (grpc_forbid_dualstack_sockets_for_testing = 0; + grpc_forbid_dualstack_sockets_for_testing <= 1; + grpc_forbid_dualstack_sockets_for_testing++) { + /* :: and 0.0.0.0 are handled identically. */ + test_connect("::", "127.0.0.1", 0, 1); + test_connect("::", "::ffff:127.0.0.1", 0, 1); + test_connect("::", "localhost", 0, 1); + test_connect("0.0.0.0", "127.0.0.1", 0, 1); + test_connect("0.0.0.0", "::ffff:127.0.0.1", 0, 1); + test_connect("0.0.0.0", "localhost", 0, 1); + if (do_ipv6) { + test_connect("::", "::1", 0, 1); + test_connect("0.0.0.0", "::1", 0, 1); + } + + /* These only work when the families agree. */ + test_connect("127.0.0.1", "127.0.0.1", 0, 1); + if (do_ipv6) { + test_connect("::1", "::1", 0, 1); + test_connect("::1", "127.0.0.1", 0, 0); + test_connect("127.0.0.1", "::1", 0, 0); } } From ed3671e1800fd31fe95c152f04d357e8ef91d45a Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Wed, 25 Feb 2015 13:38:53 -0800 Subject: [PATCH 68/75] Synchronize initial package versions --- src/ruby/lib/grpc/version.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ruby/lib/grpc/version.rb b/src/ruby/lib/grpc/version.rb index d4eb0ed24f6..513a53724f3 100644 --- a/src/ruby/lib/grpc/version.rb +++ b/src/ruby/lib/grpc/version.rb @@ -29,5 +29,5 @@ # GRPC contains the General RPC module. module GRPC - VERSION = '0.0.1' + VERSION = '0.5.0' end From 1ffe4feb6fc30312da18d5bcf70097a8e0b62634 Mon Sep 17 00:00:00 2001 From: Nathaniel Manista Date: Wed, 25 Feb 2015 21:39:05 +0000 Subject: [PATCH 69/75] Sanitize a reference number. --- src/python/src/grpc/_adapter/_call.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python/src/grpc/_adapter/_call.c b/src/python/src/grpc/_adapter/_call.c index 325d3d5bbd6..dca2e49373b 100644 --- a/src/python/src/grpc/_adapter/_call.c +++ b/src/python/src/grpc/_adapter/_call.c @@ -161,7 +161,7 @@ static const PyObject *pygrpc_call_accept(Call *self, PyObject *args) { } static const PyObject *pygrpc_call_premetadata(Call *self) { - /* TODO(b/18702680): Actually support metadata. */ + /* TODO(nathaniel): Metadata support. */ return pygrpc_translate_call_error( grpc_call_server_end_initial_metadata_old(self->c_call, 0)); } From fcfbb41f1d927b792a0c75103456fd27cc9aa404 Mon Sep 17 00:00:00 2001 From: Jayant Kolhe Date: Wed, 25 Feb 2015 14:36:21 -0800 Subject: [PATCH 70/75] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fc35934f2df..eacb8c0f42f 100644 --- a/README.md +++ b/README.md @@ -13,9 +13,9 @@ This repository contains source code for gRPC libraries for multiple lanugages w of shared C core library [src/core] (src/core). * C++ source code: [src/cpp] (src/cpp) - * Python source code: [src/python] (src/python) * Ruby source code: [src/ruby] (src/ruby) * NodeJS source code: [src/node] (src/node) + * Python source code: [src/python] (src/python) * PHP source code: [src/php] (src/php) * C# source code: [src/csharp] (src/csharp) * Objective-C source code: [src/objective-c] (src/objective-c) @@ -33,9 +33,9 @@ Libraries in different languages are in different state of development. We are s * shared C core library [src/core] (src/core) : Early adopter ready - Alpha. * C++ Library: [src/cpp] (src/cpp) : Early adopter ready - Alpha. - * Python Library: [src/python] (src/python) : Early adopter ready - Alpha. * Ruby Library: [src/ruby] (src/ruby) : Early adopter ready - Alpha. * NodeJS Library: [src/node] (src/node) : Early adopter ready - Alpha. + * Python Library: [src/python] (src/python) : Usable with limitations - Pre-Alpha. * PHP Library: [src/php] (src/php) : Pre-Alpha. * C# Library: [src/csharp] (src/csharp) : Pre-Alpha. * Objective-C Library: [src/objective-c] (src/objective-c): Pre-Alpha. From 806dde1bcb3193040599976f884c2d051322cacc Mon Sep 17 00:00:00 2001 From: Jayant Kolhe Date: Wed, 25 Feb 2015 14:39:14 -0800 Subject: [PATCH 71/75] Update README.md --- src/python/README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/python/README.md b/src/python/README.md index be2f2bedf9c..ff045caa94f 100755 --- a/src/python/README.md +++ b/src/python/README.md @@ -4,6 +4,11 @@ GRPC Python The Python facility of GRPC. +Status +------- + +Usable with limitations, Pre-Alpha + Prerequisites ----------------------- From e2d795a27bfcd01e627d0fc5523ad138ddb4eda6 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Wed, 25 Feb 2015 15:00:21 -0800 Subject: [PATCH 72/75] Fix max_concurrent_streams test --- test/core/end2end/tests/max_concurrent_streams.c | 4 ++-- test/core/end2end/tests/max_concurrent_streams_legacy.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/core/end2end/tests/max_concurrent_streams.c b/test/core/end2end/tests/max_concurrent_streams.c index 743048881d7..3a2f2b36552 100644 --- a/test/core/end2end/tests/max_concurrent_streams.c +++ b/test/core/end2end/tests/max_concurrent_streams.c @@ -196,7 +196,7 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) { GPR_ASSERT(GRPC_CALL_OK == grpc_call_invoke_old(c2, f.client_cq, tag(401), tag(402), 0)); GPR_ASSERT(GRPC_CALL_OK == grpc_call_writes_done_old(c1, tag(303))); - GPR_ASSERT(GRPC_CALL_OK == grpc_call_writes_done_old(c2, tag(303))); + GPR_ASSERT(GRPC_CALL_OK == grpc_call_writes_done_old(c2, tag(403))); ev = grpc_completion_queue_next( f.client_cq, gpr_time_add(gpr_now(), gpr_time_from_seconds(10))); @@ -230,8 +230,8 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) { /* first request is finished, we should be able to start the second */ cq_expect_finished_with_status(v_client, tag(live_call + 2), GRPC_STATUS_UNIMPLEMENTED, "xyz", NULL); - cq_expect_finish_accepted(v_client, tag(live_call + 3), GRPC_OP_OK); live_call = (live_call == 300) ? 400 : 300; + cq_expect_finish_accepted(v_client, tag(live_call + 3), GRPC_OP_OK); cq_verify(v_client); GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(200))); diff --git a/test/core/end2end/tests/max_concurrent_streams_legacy.c b/test/core/end2end/tests/max_concurrent_streams_legacy.c index 8bf11543878..0d55286de9b 100644 --- a/test/core/end2end/tests/max_concurrent_streams_legacy.c +++ b/test/core/end2end/tests/max_concurrent_streams_legacy.c @@ -196,7 +196,7 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) { GPR_ASSERT(GRPC_CALL_OK == grpc_call_invoke_old(c2, f.client_cq, tag(401), tag(402), 0)); GPR_ASSERT(GRPC_CALL_OK == grpc_call_writes_done_old(c1, tag(303))); - GPR_ASSERT(GRPC_CALL_OK == grpc_call_writes_done_old(c2, tag(303))); + GPR_ASSERT(GRPC_CALL_OK == grpc_call_writes_done_old(c2, tag(403))); ev = grpc_completion_queue_next( f.client_cq, gpr_time_add(gpr_now(), gpr_time_from_seconds(10))); @@ -230,8 +230,8 @@ static void test_max_concurrent_streams(grpc_end2end_test_config config) { /* first request is finished, we should be able to start the second */ cq_expect_finished_with_status(v_client, tag(live_call + 2), GRPC_STATUS_UNIMPLEMENTED, "xyz", NULL); - cq_expect_finish_accepted(v_client, tag(live_call + 3), GRPC_OP_OK); live_call = (live_call == 300) ? 400 : 300; + cq_expect_finish_accepted(v_client, tag(live_call + 3), GRPC_OP_OK); cq_verify(v_client); GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call_old(f.server, tag(200))); From 4175d84d00d2af7cb43f829ceddd75616419de29 Mon Sep 17 00:00:00 2001 From: Dan Ciruli Date: Wed, 25 Feb 2015 16:24:22 -0800 Subject: [PATCH 73/75] Update INSTALL for C Missed a step --- INSTALL | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/INSTALL b/INSTALL index c12bea089fc..50040d7d21c 100644 --- a/INSTALL +++ b/INSTALL @@ -10,10 +10,10 @@ wiki pages: ************************* $ git clone https://github.com/grpc/grpc.git + $ cd grpc $ git submodule update --init - - $ make - $ sudo make install + $ make + $ sudo make install You don't need anything else than GNU Make, gcc and autotools. Under a Debian or Ubuntu system, this should boil down to the following packages: From c2b402001b4718032a5d4089399444953a49661f Mon Sep 17 00:00:00 2001 From: Nathaniel Manista Date: Thu, 26 Feb 2015 16:23:38 +0000 Subject: [PATCH 74/75] The Python interop client. The server_host_override flag's implementation remaining outstanding means that this only works over insecure connections for now. --- src/python/interop/interop/client.py | 86 +++++++++++ src/python/interop/interop/credentials/ca.pem | 15 ++ src/python/interop/interop/methods.py | 136 ++++++++++++++++++ src/python/interop/interop/resources.py | 56 ++++++++ src/python/interop/interop/server.py | 11 +- src/python/interop/setup.py | 4 +- 6 files changed, 299 insertions(+), 9 deletions(-) create mode 100644 src/python/interop/interop/client.py create mode 100755 src/python/interop/interop/credentials/ca.pem create mode 100644 src/python/interop/interop/resources.py diff --git a/src/python/interop/interop/client.py b/src/python/interop/interop/client.py new file mode 100644 index 00000000000..f4a449ef9e7 --- /dev/null +++ b/src/python/interop/interop/client.py @@ -0,0 +1,86 @@ +# Copyright 2015, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""The Python implementation of the GRPC interoperability test client.""" + +import argparse + +from grpc.early_adopter import implementations + +from interop import methods +from interop import resources + +_ONE_DAY_IN_SECONDS = 60 * 60 * 24 + + +def _args(): + parser = argparse.ArgumentParser() + parser.add_argument( + '--server_host', help='the host to which to connect', type=str) + parser.add_argument( + '--server_host_override', + help='the server host to which to claim to connect', type=str) + parser.add_argument( + '--server_port', help='the port to which to connect', type=int) + parser.add_argument( + '--test_case', help='the test case to execute', type=str) + parser.add_argument( + '--use_tls', help='require a secure connection', dest='use_tls', + action='store_true') + parser.add_argument( + '--use_test_ca', help='replace platform root CAs with ca.pem', + action='store_true') + return parser.parse_args() + + +def _stub(args): + if args.use_tls: + if args.use_test_ca: + root_certificates = resources.test_root_certificates() + else: + root_certificates = resources.prod_root_certificates() + # TODO(nathaniel): server host override. + + stub = implementations.secure_stub( + methods.CLIENT_METHODS, args.server_host, args.server_port, + root_certificates, None, None) + else: + stub = implementations.insecure_stub( + methods.CLIENT_METHODS, args.server_host, args.server_port) + return stub + + +def _test_interoperability(): + args = _args() + stub = _stub(args) + methods.test_interoperability(args.test_case, stub) + + +if __name__ == '__main__': + _test_interoperability() diff --git a/src/python/interop/interop/credentials/ca.pem b/src/python/interop/interop/credentials/ca.pem new file mode 100755 index 00000000000..6c8511a73c6 --- /dev/null +++ b/src/python/interop/interop/credentials/ca.pem @@ -0,0 +1,15 @@ +-----BEGIN CERTIFICATE----- +MIICSjCCAbOgAwIBAgIJAJHGGR4dGioHMA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNV +BAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX +aWRnaXRzIFB0eSBMdGQxDzANBgNVBAMTBnRlc3RjYTAeFw0xNDExMTEyMjMxMjla +Fw0yNDExMDgyMjMxMjlaMFYxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0 +YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQxDzANBgNVBAMT +BnRlc3RjYTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAwEDfBV5MYdlHVHJ7 ++L4nxrZy7mBfAVXpOc5vMYztssUI7mL2/iYujiIXM+weZYNTEpLdjyJdu7R5gGUu +g1jSVK/EPHfc74O7AyZU34PNIP4Sh33N+/A5YexrNgJlPY+E3GdVYi4ldWJjgkAd +Qah2PH5ACLrIIC6tRka9hcaBlIECAwEAAaMgMB4wDAYDVR0TBAUwAwEB/zAOBgNV +HQ8BAf8EBAMCAgQwDQYJKoZIhvcNAQELBQADgYEAHzC7jdYlzAVmddi/gdAeKPau +sPBG/C2HCWqHzpCUHcKuvMzDVkY/MP2o6JIW2DBbY64bO/FceExhjcykgaYtCH/m +oIU63+CFOTtR7otyQAWHqXa7q4SbCDlG7DyRFxqG0txPtGvy12lgldA2+RgcigQG +Dfcog5wrJytaQ6UA0wE= +-----END CERTIFICATE----- diff --git a/src/python/interop/interop/methods.py b/src/python/interop/interop/methods.py index 6d5990087ee..4da28ee7759 100644 --- a/src/python/interop/interop/methods.py +++ b/src/python/interop/interop/methods.py @@ -29,11 +29,16 @@ """Implementations of interoperability test methods.""" +import threading + from grpc.early_adopter import utilities from interop import empty_pb2 from interop import messages_pb2 +_TIMEOUT = 7 + + def _empty_call(request, unused_context): return empty_pb2.Empty() @@ -142,3 +147,134 @@ SERVER_METHODS = { FULL_DUPLEX_CALL_METHOD_NAME: _SERVER_FULL_DUPLEX_CALL, HALF_DUPLEX_CALL_METHOD_NAME: _SERVER_HALF_DUPLEX_CALL, } + + +def _empty_unary(stub): + with stub: + response = stub.EmptyCall(empty_pb2.Empty(), _TIMEOUT) + if not isinstance(response, empty_pb2.Empty): + raise TypeError( + 'response is of type "%s", not empty_pb2.Empty!', type(response)) + + +def _large_unary(stub): + with stub: + request = messages_pb2.SimpleRequest( + response_type=messages_pb2.COMPRESSABLE, response_size=314159, + payload=messages_pb2.Payload(body=b'\x00' * 271828)) + response_future = stub.UnaryCall.async(request, _TIMEOUT) + response = response_future.result() + if response.payload.type is not messages_pb2.COMPRESSABLE: + raise ValueError( + 'response payload type is "%s"!' % type(response.payload.type)) + if len(response.payload.body) != 314159: + raise ValueError( + 'response body of incorrect size %d!' % len(response.payload.body)) + + +def _client_streaming(stub): + with stub: + payload_body_sizes = (27182, 8, 1828, 45904) + payloads = ( + messages_pb2.Payload(body=b'\x00' * size) + for size in payload_body_sizes) + requests = ( + messages_pb2.StreamingInputCallRequest(payload=payload) + for payload in payloads) + response = stub.StreamingInputCall(requests, _TIMEOUT) + if response.aggregated_payload_size != 74922: + raise ValueError( + 'incorrect size %d!' % response.aggregated_payload_size) + + +def _server_streaming(stub): + sizes = (31415, 9, 2653, 58979) + + with stub: + request = messages_pb2.StreamingOutputCallRequest( + response_type=messages_pb2.COMPRESSABLE, + response_parameters=( + messages_pb2.ResponseParameters(size=sizes[0]), + messages_pb2.ResponseParameters(size=sizes[1]), + messages_pb2.ResponseParameters(size=sizes[2]), + messages_pb2.ResponseParameters(size=sizes[3]), + )) + response_iterator = stub.StreamingOutputCall(request, _TIMEOUT) + for index, response in enumerate(response_iterator): + if response.payload.type != messages_pb2.COMPRESSABLE: + raise ValueError( + 'response body of invalid type %s!' % response.payload.type) + if len(response.payload.body) != sizes[index]: + raise ValueError( + 'response body of invalid size %d!' % len(response.payload.body)) + + +class _Pipe(object): + + def __init__(self): + self._condition = threading.Condition() + self._values = [] + self._open = True + + def __iter__(self): + return self + + def next(self): + with self._condition: + while not self._values and self._open: + self._condition.wait() + if self._values: + return self._values.pop(0) + else: + raise StopIteration() + + def add(self, value): + with self._condition: + self._values.append(value) + self._condition.notify() + + def close(self): + with self._condition: + self._open = False + self._condition.notify() + + +def _ping_pong(stub): + request_response_sizes = (31415, 9, 2653, 58979) + request_payload_sizes = (27182, 8, 1828, 45904) + + with stub: + pipe = _Pipe() + response_iterator = stub.FullDuplexCall(pipe, _TIMEOUT) + print 'Starting ping-pong with response iterator %s' % response_iterator + for response_size, payload_size in zip( + request_response_sizes, request_payload_sizes): + request = messages_pb2.StreamingOutputCallRequest( + response_type=messages_pb2.COMPRESSABLE, + response_parameters=(messages_pb2.ResponseParameters( + size=response_size),), + payload=messages_pb2.Payload(body=b'\x00' * payload_size)) + pipe.add(request) + response = next(response_iterator) + if response.payload.type != messages_pb2.COMPRESSABLE: + raise ValueError( + 'response body of invalid type %s!' % response.payload.type) + if len(response.payload.body) != response_size: + raise ValueError( + 'response body of invalid size %d!' % len(response.payload.body)) + pipe.close() + + +def test_interoperability(test_case, stub): + if test_case == 'empty_unary': + _empty_unary(stub) + elif test_case == 'large_unary': + _large_unary(stub) + elif test_case == 'server_streaming': + _server_streaming(stub) + elif test_case == 'client_streaming': + _client_streaming(stub) + elif test_case == 'ping_pong': + _ping_pong(stub) + else: + raise NotImplementedError('Test case "%s" not implemented!') diff --git a/src/python/interop/interop/resources.py b/src/python/interop/interop/resources.py new file mode 100644 index 00000000000..2c3045313d4 --- /dev/null +++ b/src/python/interop/interop/resources.py @@ -0,0 +1,56 @@ +# Copyright 2015, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +"""Constants and functions for data used in interoperability testing.""" + +import os + +import pkg_resources + +_ROOT_CERTIFICATES_RESOURCE_PATH = 'credentials/ca.pem' +_PRIVATE_KEY_RESOURCE_PATH = 'credentials/server1.key' +_CERTIFICATE_CHAIN_RESOURCE_PATH = 'credentials/server1.pem' + + +def test_root_certificates(): + return pkg_resources.resource_string( + __name__, _ROOT_CERTIFICATES_RESOURCE_PATH) + + +def prod_root_certificates(): + return open(os.environ['SSL_CERT_FILE'], mode='rb').read() + + +def private_key(): + return pkg_resources.resource_string(__name__, _PRIVATE_KEY_RESOURCE_PATH) + + +def certificate_chain(): + return pkg_resources.resource_string( + __name__, _CERTIFICATE_CHAIN_RESOURCE_PATH) diff --git a/src/python/interop/interop/server.py b/src/python/interop/interop/server.py index 785d482fe59..4e4b127a9a7 100644 --- a/src/python/interop/interop/server.py +++ b/src/python/interop/interop/server.py @@ -31,18 +31,15 @@ import argparse import logging -import pkg_resources import time from grpc.early_adopter import implementations from interop import methods +from interop import resources _ONE_DAY_IN_SECONDS = 60 * 60 * 24 -_PRIVATE_KEY_RESOURCE_PATH = 'credentials/server1.key' -_CERTIFICATE_CHAIN_RESOURCE_PATH = 'credentials/server1.pem' - def serve(): parser = argparse.ArgumentParser() @@ -54,10 +51,8 @@ def serve(): args = parser.parse_args() if args.use_tls: - private_key = pkg_resources.resource_string( - __name__, _PRIVATE_KEY_RESOURCE_PATH) - certificate_chain = pkg_resources.resource_string( - __name__, _CERTIFICATE_CHAIN_RESOURCE_PATH) + private_key = resources.private_key() + certificate_chain = resources.certificate_chain() server = implementations.secure_server( methods.SERVER_METHODS, args.port, private_key, certificate_chain) else: diff --git a/src/python/interop/setup.py b/src/python/interop/setup.py index 4b7709f2348..6db54350903 100644 --- a/src/python/interop/setup.py +++ b/src/python/interop/setup.py @@ -40,7 +40,9 @@ _PACKAGE_DIRECTORIES = { } _PACKAGE_DATA = { - 'interop': ['credentials/server1.key', 'credentials/server1.pem',] + 'interop': [ + 'credentials/ca.pem', 'credentials/server1.key', + 'credentials/server1.pem',] } _INSTALL_REQUIRES = ['grpc-2015>=0.0.1'] From 1c37fe62fd99ca9a899002e15342fd3584b83ca0 Mon Sep 17 00:00:00 2001 From: Nathaniel Manista Date: Thu, 26 Feb 2015 16:09:06 +0000 Subject: [PATCH 75/75] Work towards invocation-side security. --- src/python/src/grpc/_adapter/_c_test.py | 4 +- src/python/src/grpc/_adapter/_channel.c | 22 ++++-- .../src/grpc/_adapter/_client_credentials.c | 1 + .../src/grpc/_adapter/_face_test_case.py | 3 +- src/python/src/grpc/_adapter/_links_test.py | 6 +- .../grpc/_adapter/_lonely_rear_link_test.py | 5 +- src/python/src/grpc/_adapter/_low_test.py | 6 +- src/python/src/grpc/_adapter/rear.py | 71 +++++++++++++++++-- .../src/grpc/early_adopter/_reexport.py | 11 ++- .../src/grpc/early_adopter/implementations.py | 22 +++--- .../framework/assembly/implementations.py | 16 +++-- 11 files changed, 128 insertions(+), 39 deletions(-) diff --git a/src/python/src/grpc/_adapter/_c_test.py b/src/python/src/grpc/_adapter/_c_test.py index 44aff44ffa0..d81c63e3469 100644 --- a/src/python/src/grpc/_adapter/_c_test.py +++ b/src/python/src/grpc/_adapter/_c_test.py @@ -70,7 +70,7 @@ class _CTest(unittest.TestCase): def testChannel(self): _c.init() - channel = _c.Channel('test host:12345') + channel = _c.Channel('test host:12345', None) del channel _c.shut_down() @@ -81,7 +81,7 @@ class _CTest(unittest.TestCase): _c.init() - channel = _c.Channel('%s:%d' % (host, 12345)) + channel = _c.Channel('%s:%d' % (host, 12345), None) call = _c.Call(channel, method, host, time.time() + _TIMEOUT) del call del channel diff --git a/src/python/src/grpc/_adapter/_channel.c b/src/python/src/grpc/_adapter/_channel.c index 3ba943e4b2d..9cf580bcfb5 100644 --- a/src/python/src/grpc/_adapter/_channel.c +++ b/src/python/src/grpc/_adapter/_channel.c @@ -35,18 +35,28 @@ #include #include +#include + +#include "grpc/_adapter/_client_credentials.h" static int pygrpc_channel_init(Channel *self, PyObject *args, PyObject *kwds) { const char *hostport; - static char *kwlist[] = {"hostport", NULL}; + PyObject *client_credentials; + static char *kwlist[] = {"hostport", "client_credentials", NULL}; - if (!(PyArg_ParseTupleAndKeywords(args, kwds, "s:Channel", kwlist, - &hostport))) { + if (!(PyArg_ParseTupleAndKeywords(args, kwds, "sO:Channel", kwlist, + &hostport, &client_credentials))) { return -1; } - - self->c_channel = grpc_channel_create(hostport, NULL); - return 0; + if (client_credentials == Py_None) { + self->c_channel = grpc_channel_create(hostport, NULL); + return 0; + } else { + self->c_channel = grpc_secure_channel_create( + ((ClientCredentials *)client_credentials)->c_client_credentials, + hostport, NULL); + return 0; + } } static void pygrpc_channel_dealloc(Channel *self) { diff --git a/src/python/src/grpc/_adapter/_client_credentials.c b/src/python/src/grpc/_adapter/_client_credentials.c index b970c866ef7..e8ccff8d17d 100644 --- a/src/python/src/grpc/_adapter/_client_credentials.c +++ b/src/python/src/grpc/_adapter/_client_credentials.c @@ -58,6 +58,7 @@ static int pygrpc_client_credentials_init(ClientCredentials *self, self->c_client_credentials = grpc_ssl_credentials_create(root_certificates, NULL); } + return 0; } static void pygrpc_client_credentials_dealloc(ClientCredentials *self) { diff --git a/src/python/src/grpc/_adapter/_face_test_case.py b/src/python/src/grpc/_adapter/_face_test_case.py index 8cce322d300..475d780c950 100644 --- a/src/python/src/grpc/_adapter/_face_test_case.py +++ b/src/python/src/grpc/_adapter/_face_test_case.py @@ -85,7 +85,8 @@ class FaceTestCase(test_case.FaceTestCase, coverage.BlockingCoverage): port = fore_link.port() rear_link = rear.RearLink( 'localhost', port, pool, - serialization.request_serializers, serialization.response_deserializers) + serialization.request_serializers, + serialization.response_deserializers, False, None, None, None) rear_link.start() front = tickets_implementations.front(pool, pool, pool) back = tickets_implementations.back( diff --git a/src/python/src/grpc/_adapter/_links_test.py b/src/python/src/grpc/_adapter/_links_test.py index 6b3bcee9fa8..5d7e6772434 100644 --- a/src/python/src/grpc/_adapter/_links_test.py +++ b/src/python/src/grpc/_adapter/_links_test.py @@ -75,7 +75,7 @@ class RoundTripTest(unittest.TestCase): rear_link = rear.RearLink( 'localhost', port, self.rear_link_pool, {test_method: None}, - {test_method: None}) + {test_method: None}, False, None, None, None) rear_link.join_fore_link(test_fore_link) test_fore_link.join_rear_link(rear_link) rear_link.start() @@ -129,7 +129,7 @@ class RoundTripTest(unittest.TestCase): rear_link = rear.RearLink( 'localhost', port, self.rear_link_pool, {test_method: _IDENTITY}, - {test_method: _IDENTITY}) + {test_method: _IDENTITY}, False, None, None, None) rear_link.join_fore_link(test_fore_link) test_fore_link.join_rear_link(rear_link) rear_link.start() @@ -193,7 +193,7 @@ class RoundTripTest(unittest.TestCase): rear_link = rear.RearLink( 'localhost', port, self.rear_link_pool, {test_method: scenario.serialize_request}, - {test_method: scenario.deserialize_response}) + {test_method: scenario.deserialize_response}, False, None, None, None) rear_link.join_fore_link(test_fore_link) test_fore_link.join_rear_link(rear_link) rear_link.start() diff --git a/src/python/src/grpc/_adapter/_lonely_rear_link_test.py b/src/python/src/grpc/_adapter/_lonely_rear_link_test.py index 9a13309a182..77821ba71a4 100644 --- a/src/python/src/grpc/_adapter/_lonely_rear_link_test.py +++ b/src/python/src/grpc/_adapter/_lonely_rear_link_test.py @@ -50,7 +50,8 @@ class LonelyRearLinkTest(unittest.TestCase): self.pool.shutdown(wait=True) def testUpAndDown(self): - rear_link = rear.RearLink('nonexistent', 54321, self.pool, {}, {}) + rear_link = rear.RearLink( + 'nonexistent', 54321, self.pool, {}, {}, False, None, None, None) rear_link.start() rear_link.stop() @@ -63,7 +64,7 @@ class LonelyRearLinkTest(unittest.TestCase): rear_link = rear.RearLink( 'nonexistent', 54321, self.pool, {test_method: None}, - {test_method: None}) + {test_method: None}, False, None, None, None) rear_link.join_fore_link(fore_link) rear_link.start() diff --git a/src/python/src/grpc/_adapter/_low_test.py b/src/python/src/grpc/_adapter/_low_test.py index 898c62c0026..03e3f473a3e 100644 --- a/src/python/src/grpc/_adapter/_low_test.py +++ b/src/python/src/grpc/_adapter/_low_test.py @@ -56,7 +56,7 @@ class LonelyClientTest(unittest.TestCase): finish_tag = object() completion_queue = _low.CompletionQueue() - channel = _low.Channel('%s:%d' % (host, port)) + channel = _low.Channel('%s:%d' % (host, port), None) client_call = _low.Call(channel, method, host, deadline) client_call.invoke(completion_queue, metadata_tag, finish_tag) @@ -87,7 +87,7 @@ class EchoTest(unittest.TestCase): self.server.start() self.client_completion_queue = _low.CompletionQueue() - self.channel = _low.Channel('%s:%d' % (self.host, port)) + self.channel = _low.Channel('%s:%d' % (self.host, port), None) def tearDown(self): self.server.stop() @@ -265,7 +265,7 @@ class CancellationTest(unittest.TestCase): self.server.start() self.client_completion_queue = _low.CompletionQueue() - self.channel = _low.Channel('%s:%d' % (self.host, port)) + self.channel = _low.Channel('%s:%d' % (self.host, port), None) def tearDown(self): self.server.stop() diff --git a/src/python/src/grpc/_adapter/rear.py b/src/python/src/grpc/_adapter/rear.py index 94ff66ffdad..bfde5f5c577 100644 --- a/src/python/src/grpc/_adapter/rear.py +++ b/src/python/src/grpc/_adapter/rear.py @@ -92,7 +92,8 @@ class RearLink(ticket_interfaces.RearLink, activated.Activated): """An invocation-side bridge between RPC Framework and the C-ish _low code.""" def __init__( - self, host, port, pool, request_serializers, response_deserializers): + self, host, port, pool, request_serializers, response_deserializers, + secure, root_certificates, private_key, certificate_chain): """Constructor. Args: @@ -103,6 +104,13 @@ class RearLink(ticket_interfaces.RearLink, activated.Activated): serializer behaviors. response_deserializers: A dict from RPC method names to response object deserializer behaviors. + secure: A boolean indicating whether or not to use a secure connection. + root_certificates: The PEM-encoded root certificates or None to ask for + them to be retrieved from a default location. + private_key: The PEM-encoded private key to use or None if no private + key should be used. + certificate_chain: The PEM-encoded certificate chain to use or None if + no certificate chain should be used. """ self._condition = threading.Condition() self._host = host @@ -116,6 +124,14 @@ class RearLink(ticket_interfaces.RearLink, activated.Activated): self._channel = None self._rpc_states = {} self._spinning = False + if secure: + self._client_credentials = _low.ClientCredentials( + root_certificates, private_key, certificate_chain) + else: + self._client_credentials = None + self._root_certificates = root_certificates + self._private_key = private_key + self._certificate_chain = certificate_chain def _on_write_event(self, operation_id, event, rpc_state): if event.write_accepted: @@ -310,7 +326,8 @@ class RearLink(ticket_interfaces.RearLink, activated.Activated): """ with self._condition: self._completion_queue = _low.CompletionQueue() - self._channel = _low.Channel('%s:%d' % (self._host, self._port)) + self._channel = _low.Channel( + '%s:%d' % (self._host, self._port), self._client_credentials) return self def _stop(self): @@ -369,11 +386,17 @@ class RearLink(ticket_interfaces.RearLink, activated.Activated): class _ActivatedRearLink(ticket_interfaces.RearLink, activated.Activated): - def __init__(self, host, port, request_serializers, response_deserializers): + def __init__( + self, host, port, request_serializers, response_deserializers, secure, + root_certificates, private_key, certificate_chain): self._host = host self._port = port self._request_serializers = request_serializers self._response_deserializers = response_deserializers + self._secure = secure + self._root_certificates = root_certificates + self._private_key = private_key + self._certificate_chain = certificate_chain self._lock = threading.Lock() self._pool = None @@ -391,7 +414,8 @@ class _ActivatedRearLink(ticket_interfaces.RearLink, activated.Activated): self._pool = logging_pool.pool(_THREAD_POOL_SIZE) self._rear_link = RearLink( self._host, self._port, self._pool, self._request_serializers, - self._response_deserializers) + self._response_deserializers, self._secure, self._root_certificates, + self._private_key, self._certificate_chain) self._rear_link.join_fore_link(self._fore_link) self._rear_link.start() return self @@ -422,6 +446,7 @@ class _ActivatedRearLink(ticket_interfaces.RearLink, activated.Activated): self._rear_link.accept_front_to_back_ticket(ticket) +# TODO(issue 726): reconcile these two creation functions. def activated_rear_link( host, port, request_serializers, response_deserializers): """Creates a RearLink that is also an activated.Activated. @@ -436,6 +461,42 @@ def activated_rear_link( serializer behavior. response_deserializers: A dictionary from RPC method name to response object deserializer behavior. + secure: A boolean indicating whether or not to use a secure connection. + root_certificates: The PEM-encoded root certificates or None to ask for + them to be retrieved from a default location. + private_key: The PEM-encoded private key to use or None if no private key + should be used. + certificate_chain: The PEM-encoded certificate chain to use or None if no + certificate chain should be used. + """ + return _ActivatedRearLink( + host, port, request_serializers, response_deserializers, False, None, + None, None) + + + +def secure_activated_rear_link( + host, port, request_serializers, response_deserializers, root_certificates, + private_key, certificate_chain): + """Creates a RearLink that is also an activated.Activated. + + The returned object is only valid for use between calls to its start and stop + methods (or in context when used as a context manager). + + Args: + host: The host to which to connect for RPC service. + port: The port to which to connect for RPC service. + request_serializers: A dictionary from RPC method name to request object + serializer behavior. + response_deserializers: A dictionary from RPC method name to response + object deserializer behavior. + root_certificates: The PEM-encoded root certificates or None to ask for + them to be retrieved from a default location. + private_key: The PEM-encoded private key to use or None if no private key + should be used. + certificate_chain: The PEM-encoded certificate chain to use or None if no + certificate chain should be used. """ return _ActivatedRearLink( - host, port, request_serializers, response_deserializers) + host, port, request_serializers, response_deserializers, True, + root_certificates, private_key, certificate_chain) diff --git a/src/python/src/grpc/early_adopter/_reexport.py b/src/python/src/grpc/early_adopter/_reexport.py index 35855bc9c80..35f4e85a728 100644 --- a/src/python/src/grpc/early_adopter/_reexport.py +++ b/src/python/src/grpc/early_adopter/_reexport.py @@ -27,9 +27,6 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -import abc -import collections - from grpc.framework.face import exceptions as face_exceptions from grpc.framework.face import interfaces as face_interfaces from grpc.framework.foundation import future @@ -186,6 +183,14 @@ class _Stub(interfaces.Stub): def __getattr__(self, attr): underlying_attr = self._assembly_stub.__getattr__(attr) cardinality = self._cardinalities.get(attr) + # TODO(nathaniel): unify this trick with its other occurrence in the code. + if cardinality is None: + for name, cardinality in self._cardinalities.iteritems(): + last_slash_index = name.rfind('/') + if 0 <= last_slash_index and name[last_slash_index + 1:] == attr: + break + else: + raise AttributeError(attr) if cardinality is interfaces.Cardinality.UNARY_UNARY: return _UnaryUnarySyncAsync(underlying_attr) elif cardinality is interfaces.Cardinality.UNARY_STREAM: diff --git a/src/python/src/grpc/early_adopter/implementations.py b/src/python/src/grpc/early_adopter/implementations.py index 241ed7dcdbb..61959586240 100644 --- a/src/python/src/grpc/early_adopter/implementations.py +++ b/src/python/src/grpc/early_adopter/implementations.py @@ -93,13 +93,7 @@ class _Server(interfaces.Server): with self._lock: return self._fore_link.port() -def _build_stub( - methods, host, port, root_certificates, private_key, certificate_chain): - breakdown = _assembly_utilities.break_down_invocation(methods) - # TODO(nathaniel): pass security values. - activated_rear_link = _rear.activated_rear_link( - host, port, breakdown.request_serializers, - breakdown.response_deserializers) +def _build_stub(breakdown, activated_rear_link): assembly_stub = _assembly_implementations.assemble_dynamic_inline_stub( breakdown.implementations, activated_rear_link) return _reexport.stub(assembly_stub, breakdown.cardinalities) @@ -123,7 +117,11 @@ def insecure_stub(methods, host, port): Returns: An interfaces.Stub affording RPC invocation. """ - return _build_stub(methods, host, port, None, None, None) + breakdown = _assembly_utilities.break_down_invocation(methods) + activated_rear_link = _rear.activated_rear_link( + host, port, breakdown.request_serializers, + breakdown.response_deserializers) + return _build_stub(breakdown, activated_rear_link) def secure_stub( @@ -146,8 +144,12 @@ def secure_stub( Returns: An interfaces.Stub affording RPC invocation. """ - return _build_stub( - methods, host, port, root_certificates, private_key, certificate_chain) + breakdown = _assembly_utilities.break_down_invocation(methods) + activated_rear_link = _rear.secure_activated_rear_link( + host, port, breakdown.request_serializers, + breakdown.response_deserializers, root_certificates, private_key, + certificate_chain) + return _build_stub(breakdown, activated_rear_link) def insecure_server(methods, port): diff --git a/src/python/src/grpc/framework/assembly/implementations.py b/src/python/src/grpc/framework/assembly/implementations.py index b9d314844c8..f7166ed99d1 100644 --- a/src/python/src/grpc/framework/assembly/implementations.py +++ b/src/python/src/grpc/framework/assembly/implementations.py @@ -31,16 +31,18 @@ import threading +# tickets_interfaces, face_interfaces, and activated are referenced from +# specification in this module. from grpc.framework.assembly import interfaces from grpc.framework.base import util as base_utilities from grpc.framework.base.packets import implementations as tickets_implementations -from grpc.framework.base.packets import interfaces as tickets_interfaces +from grpc.framework.base.packets import interfaces as tickets_interfaces # pylint: disable=unused-import from grpc.framework.common import cardinality from grpc.framework.common import style from grpc.framework.face import implementations as face_implementations -from grpc.framework.face import interfaces as face_interfaces +from grpc.framework.face import interfaces as face_interfaces # pylint: disable=unused-import from grpc.framework.face import utilities as face_utilities -from grpc.framework.foundation import activated +from grpc.framework.foundation import activated # pylint: disable=unused-import from grpc.framework.foundation import logging_pool _ONE_DAY_IN_SECONDS = 60 * 60 * 24 @@ -138,7 +140,13 @@ class _DynamicInlineStub(object): with self._lock: behavior = self._behaviors.get(attr) if behavior is None: - raise AttributeError(attr) + for name, behavior in self._behaviors.iteritems(): + last_slash_index = name.rfind('/') + if 0 <= last_slash_index and name[last_slash_index + 1:] == attr: + return behavior + else: + raise AttributeError( + '_DynamicInlineStub instance has no attribute "%s"!' % attr) else: return behavior