diff --git a/BUILD b/BUILD index ad6903d6847..1ca357896a7 100644 --- a/BUILD +++ b/BUILD @@ -892,6 +892,8 @@ cc_library( "include/grpc++/impl/rpc_service_method.h", "include/grpc++/impl/serialization_traits.h", "include/grpc++/impl/server_builder_option.h", + "include/grpc++/impl/server_builder_plugin.h", + "include/grpc++/impl/server_initializer.h", "include/grpc++/impl/service_type.h", "include/grpc++/impl/sync.h", "include/grpc++/impl/sync_cxx11.h", @@ -1038,6 +1040,8 @@ cc_library( "include/grpc++/impl/rpc_service_method.h", "include/grpc++/impl/serialization_traits.h", "include/grpc++/impl/server_builder_option.h", + "include/grpc++/impl/server_builder_plugin.h", + "include/grpc++/impl/server_initializer.h", "include/grpc++/impl/service_type.h", "include/grpc++/impl/sync.h", "include/grpc++/impl/sync_cxx11.h", diff --git a/Makefile b/Makefile index 1ff2cb67c55..f0a0ebd3eb6 100644 --- a/Makefile +++ b/Makefile @@ -1042,6 +1042,7 @@ reconnect_interop_client: $(BINDIR)/$(CONFIG)/reconnect_interop_client reconnect_interop_server: $(BINDIR)/$(CONFIG)/reconnect_interop_server secure_auth_context_test: $(BINDIR)/$(CONFIG)/secure_auth_context_test secure_sync_unary_ping_pong_test: $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test +server_builder_plugin_test: $(BINDIR)/$(CONFIG)/server_builder_plugin_test server_crash_test: $(BINDIR)/$(CONFIG)/server_crash_test server_crash_test_client: $(BINDIR)/$(CONFIG)/server_crash_test_client shutdown_test: $(BINDIR)/$(CONFIG)/shutdown_test @@ -1410,6 +1411,7 @@ buildtests_cxx: buildtests_zookeeper privatelibs_cxx \ $(BINDIR)/$(CONFIG)/reconnect_interop_server \ $(BINDIR)/$(CONFIG)/secure_auth_context_test \ $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test \ + $(BINDIR)/$(CONFIG)/server_builder_plugin_test \ $(BINDIR)/$(CONFIG)/server_crash_test \ $(BINDIR)/$(CONFIG)/server_crash_test_client \ $(BINDIR)/$(CONFIG)/shutdown_test \ @@ -1743,6 +1745,8 @@ test_cxx: test_zookeeper buildtests_cxx $(Q) $(BINDIR)/$(CONFIG)/secure_auth_context_test || ( echo test secure_auth_context_test failed ; exit 1 ) $(E) "[RUN] Testing secure_sync_unary_ping_pong_test" $(Q) $(BINDIR)/$(CONFIG)/secure_sync_unary_ping_pong_test || ( echo test secure_sync_unary_ping_pong_test failed ; exit 1 ) + $(E) "[RUN] Testing server_builder_plugin_test" + $(Q) $(BINDIR)/$(CONFIG)/server_builder_plugin_test || ( echo test server_builder_plugin_test failed ; exit 1 ) $(E) "[RUN] Testing server_crash_test" $(Q) $(BINDIR)/$(CONFIG)/server_crash_test || ( echo test server_crash_test failed ; exit 1 ) $(E) "[RUN] Testing shutdown_test" @@ -3213,6 +3217,8 @@ PUBLIC_HEADERS_CXX += \ include/grpc++/impl/rpc_service_method.h \ include/grpc++/impl/serialization_traits.h \ include/grpc++/impl/server_builder_option.h \ + include/grpc++/impl/server_builder_plugin.h \ + include/grpc++/impl/server_initializer.h \ include/grpc++/impl/service_type.h \ include/grpc++/impl/sync.h \ include/grpc++/impl/sync_cxx11.h \ @@ -3517,6 +3523,8 @@ PUBLIC_HEADERS_CXX += \ include/grpc++/impl/rpc_service_method.h \ include/grpc++/impl/serialization_traits.h \ include/grpc++/impl/server_builder_option.h \ + include/grpc++/impl/server_builder_plugin.h \ + include/grpc++/impl/server_initializer.h \ include/grpc++/impl/service_type.h \ include/grpc++/impl/sync.h \ include/grpc++/impl/sync_cxx11.h \ @@ -11494,6 +11502,49 @@ endif endif +SERVER_BUILDER_PLUGIN_TEST_SRC = \ + test/cpp/end2end/server_builder_plugin_test.cc \ + +SERVER_BUILDER_PLUGIN_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(SERVER_BUILDER_PLUGIN_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/server_builder_plugin_test: openssl_dep_error + +else + + + + +ifeq ($(NO_PROTOBUF),true) + +# You can't build the protoc plugins or protobuf-enabled targets if you don't have protobuf 3.0.0+. + +$(BINDIR)/$(CONFIG)/server_builder_plugin_test: protobuf_dep_error + +else + +$(BINDIR)/$(CONFIG)/server_builder_plugin_test: $(PROTOBUF_DEP) $(SERVER_BUILDER_PLUGIN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) $(SERVER_BUILDER_PLUGIN_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBSXX) $(LDLIBS_PROTOBUF) $(LDLIBS) $(LDLIBS_SECURE) $(GTEST_LIB) -o $(BINDIR)/$(CONFIG)/server_builder_plugin_test + +endif + +endif + +$(OBJDIR)/$(CONFIG)/test/cpp/end2end/server_builder_plugin_test.o: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_server_builder_plugin_test: $(SERVER_BUILDER_PLUGIN_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(SERVER_BUILDER_PLUGIN_TEST_OBJS:.o=.dep) +endif +endif + + SERVER_CRASH_TEST_SRC = \ test/cpp/end2end/server_crash_test.cc \ diff --git a/build.yaml b/build.yaml index b2cbd4d890f..187eb9ca8c6 100644 --- a/build.yaml +++ b/build.yaml @@ -591,6 +591,8 @@ filegroups: - include/grpc++/impl/rpc_service_method.h - include/grpc++/impl/serialization_traits.h - include/grpc++/impl/server_builder_option.h + - include/grpc++/impl/server_builder_plugin.h + - include/grpc++/impl/server_initializer.h - include/grpc++/impl/service_type.h - include/grpc++/impl/sync.h - include/grpc++/impl/sync_cxx11.h @@ -2915,6 +2917,19 @@ targets: - mac - linux - posix +- name: server_builder_plugin_test + gtest: true + build: test + language: c++ + src: + - test/cpp/end2end/server_builder_plugin_test.cc + deps: + - grpc++_test_util + - grpc_test_util + - grpc++ + - grpc + - gpr_test_util + - gpr - name: server_crash_test gtest: true cpu_cost: 0.1 diff --git a/include/grpc++/impl/codegen/method_handler_impl.h b/include/grpc++/impl/codegen/method_handler_impl.h index ad74efabc4b..21ac6c4fb55 100644 --- a/include/grpc++/impl/codegen/method_handler_impl.h +++ b/include/grpc++/impl/codegen/method_handler_impl.h @@ -44,10 +44,10 @@ namespace grpc { template class RpcMethodHandler : public MethodHandler { public: - RpcMethodHandler( - std::function func, - ServiceType* service) + RpcMethodHandler(std::function + func, + ServiceType* service) : func_(func), service_(service) {} void RunHandler(const HandlerParameter& param) GRPC_FINAL { @@ -88,7 +88,8 @@ class ClientStreamingHandler : public MethodHandler { public: ClientStreamingHandler( std::function*, ResponseType*)> func, + ServerReader*, ResponseType*)> + func, ServiceType* service) : func_(func), service_(service) {} @@ -124,7 +125,8 @@ class ServerStreamingHandler : public MethodHandler { public: ServerStreamingHandler( std::function*)> func, + ServerWriter*)> + func, ServiceType* service) : func_(func), service_(service) {} diff --git a/include/grpc++/impl/server_builder_option.h b/include/grpc++/impl/server_builder_option.h index bcb19824fdf..2b7e89f5e5d 100644 --- a/include/grpc++/impl/server_builder_option.h +++ b/include/grpc++/impl/server_builder_option.h @@ -34,6 +34,10 @@ #ifndef GRPCXX_IMPL_SERVER_BUILDER_OPTION_H #define GRPCXX_IMPL_SERVER_BUILDER_OPTION_H +#include +#include + +#include #include namespace grpc { @@ -44,6 +48,10 @@ class ServerBuilderOption { virtual ~ServerBuilderOption() {} /// Alter the \a ChannelArguments used to create the gRPC server. virtual void UpdateArguments(ChannelArguments* args) = 0; + /// Alter the ServerBuilderPlugin map that will be added into ServerBuilder. + virtual void UpdatePlugins( + std::map >* + plugins) = 0; }; } // namespace grpc diff --git a/include/grpc++/impl/server_builder_plugin.h b/include/grpc++/impl/server_builder_plugin.h new file mode 100644 index 00000000000..1e157efa111 --- /dev/null +++ b/include/grpc++/impl/server_builder_plugin.h @@ -0,0 +1,67 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPCXX_IMPL_SERVER_BUILDER_PLUGIN_H +#define GRPCXX_IMPL_SERVER_BUILDER_PLUGIN_H + +#include + +#include + +namespace grpc { + +class ServerInitializer; + +class ServerBuilderPlugin { + public: + virtual ~ServerBuilderPlugin() {} + virtual grpc::string name() = 0; + + // InitServer will be called in ServerBuilder::BuildAndStart(), after the + // Server instance is created. + virtual void InitServer(ServerInitializer* si) = 0; + + // Finish will be called at the end of ServerBuilder::BuildAndStart(). + virtual void Finish(ServerInitializer* si) = 0; + + // ChangeArguments is an interface that can be used in + // ServerBuilderOption::UpdatePlugins + virtual void ChangeArguments(const grpc::string& name, void* value) = 0; + + virtual bool has_sync_methods() const { return false; } + virtual bool has_async_methods() const { return false; } +}; + +} // namespace grpc + +#endif // GRPCXX_IMPL_SERVER_BUILDER_PLUGIN_H diff --git a/include/grpc++/impl/server_initializer.h b/include/grpc++/impl/server_initializer.h new file mode 100644 index 00000000000..dbcecc7026c --- /dev/null +++ b/include/grpc++/impl/server_initializer.h @@ -0,0 +1,70 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef GRPCXX_IMPL_SERVER_INITIALIZER_H +#define GRPCXX_IMPL_SERVER_INITIALIZER_H + +#include +#include + +#include + +namespace grpc { + +class Server; +class Service; + +class ServerInitializer { + public: + ServerInitializer(Server* server) : server_(server) {} + + bool RegisterService(std::shared_ptr service) { + if (!server_->RegisterService(nullptr, service.get())) { + return false; + } + default_services_.push_back(service); + return true; + } + + const std::vector* GetServiceList() { + return &server_->services_; + } + + private: + Server* server_; + std::vector > default_services_; +}; + +} // namespace grpc + +#endif // GRPCXX_IMPL_SERVER_INITIALIZER_H diff --git a/include/grpc++/server.h b/include/grpc++/server.h index 729a5143bf8..a0ee0e98e47 100644 --- a/include/grpc++/server.h +++ b/include/grpc++/server.h @@ -36,6 +36,7 @@ #include #include +#include #include #include @@ -57,6 +58,7 @@ class GenericServerContext; class AsyncGenericService; class ServerAsyncStreamingInterface; class ServerContext; +class ServerInitializer; class ThreadPoolInterface; /// Models a gRPC server. @@ -94,6 +96,7 @@ class Server GRPC_FINAL : public ServerInterface, private GrpcLibraryCodegen { private: friend class AsyncGenericService; friend class ServerBuilder; + friend class ServerInitializer; class SyncRequest; class AsyncRequest; @@ -159,6 +162,8 @@ class Server GRPC_FINAL : public ServerInterface, private GrpcLibraryCodegen { grpc_server* server() GRPC_OVERRIDE { return server_; }; + ServerInitializer* initializer(); + const int max_message_size_; // Completion queue. @@ -175,6 +180,7 @@ class Server GRPC_FINAL : public ServerInterface, private GrpcLibraryCodegen { std::shared_ptr global_callbacks_; std::list* sync_methods_; + std::vector services_; std::unique_ptr unknown_method_; bool has_generic_service_; @@ -184,6 +190,8 @@ class Server GRPC_FINAL : public ServerInterface, private GrpcLibraryCodegen { ThreadPoolInterface* thread_pool_; // Whether the thread pool is created and owned by the server. bool thread_pool_owned_; + + std::unique_ptr server_initializer_; }; } // namespace grpc diff --git a/include/grpc++/server_builder.h b/include/grpc++/server_builder.h index 86c7fecef59..ad629521cbe 100644 --- a/include/grpc++/server_builder.h +++ b/include/grpc++/server_builder.h @@ -34,10 +34,12 @@ #ifndef GRPCXX_SERVER_BUILDER_H #define GRPCXX_SERVER_BUILDER_H +#include #include #include #include +#include #include #include @@ -51,6 +53,10 @@ class ServerCompletionQueue; class ServerCredentials; class Service; +namespace testing { +class ServerBuilderPluginTest; +} // namespace testing + /// A builder class for the creation and startup of \a grpc::Server instances. class ServerBuilder { public: @@ -107,7 +113,13 @@ class ServerBuilder { /// Return a running server which is ready for processing calls. std::unique_ptr BuildAndStart(); + /// For internal use only: Register a ServerBuilderPlugin factory function. + static void InternalAddPluginFactory( + std::unique_ptr (*CreatePlugin)()); + private: + friend class ::grpc::testing::ServerBuilderPluginTest; + struct Port { grpc::string addr; std::shared_ptr creds; @@ -130,6 +142,7 @@ class ServerBuilder { std::vector ports_; std::vector cqs_; std::shared_ptr creds_; + std::map> plugins_; AsyncGenericService* generic_service_; }; diff --git a/package.json b/package.json index 54a44ca5513..5bdaa761e28 100644 --- a/package.json +++ b/package.json @@ -67,6 +67,8 @@ "src/node/ext", "include/grpc", "src/core", + "src/boringssl", + "src/zlib", "third_party/nanopb", "third_party/zlib", "third_party/boringssl", diff --git a/src/cpp/server/server.cc b/src/cpp/server/server.cc index fafe31e84c1..f955a314944 100644 --- a/src/cpp/server/server.cc +++ b/src/cpp/server/server.cc @@ -33,6 +33,7 @@ #include +#include #include #include @@ -41,6 +42,7 @@ #include #include #include +#include #include #include #include @@ -284,7 +286,8 @@ Server::Server(ThreadPoolInterface* thread_pool, bool thread_pool_owned, has_generic_service_(false), server_(nullptr), thread_pool_(thread_pool), - thread_pool_owned_(thread_pool_owned) { + thread_pool_owned_(thread_pool_owned), + server_initializer_(new ServerInitializer(this)) { g_gli_initializer.summon(); gpr_once_init(&g_once_init_callbacks, InitGlobalCallbacks); global_callbacks_ = g_callbacks; @@ -341,6 +344,7 @@ bool Server::RegisterService(const grpc::string* host, Service* service) { "Can only register an asynchronous service against one server."); service->server_ = this; } + const char* method_name = nullptr; for (auto it = service->methods_.begin(); it != service->methods_.end(); ++it) { if (it->get() == nullptr) { // Handled by generic service if any. @@ -360,6 +364,17 @@ bool Server::RegisterService(const grpc::string* host, Service* service) { } else { sync_methods_->emplace_back(method, tag); } + method_name = method->name(); + } + + // Parse service name. + if (method_name != nullptr) { + std::stringstream ss(method_name); + grpc::string service_name; + if (std::getline(ss, service_name, '/') && + std::getline(ss, service_name, '/')) { + services_.push_back(service_name); + } } return true; } @@ -598,4 +613,6 @@ void Server::RunRpc() { } } +ServerInitializer* Server::initializer() { return server_initializer_.get(); } + } // namespace grpc diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc index 68cc38258cf..9658a567455 100644 --- a/src/cpp/server/server_builder.cc +++ b/src/cpp/server/server_builder.cc @@ -41,9 +41,23 @@ namespace grpc { +static std::vector (*)()>* + g_plugin_factory_list; +static gpr_once once_init_plugin_list = GPR_ONCE_INIT; + +static void do_plugin_list_init(void) { + g_plugin_factory_list = + new std::vector (*)()>(); +} + ServerBuilder::ServerBuilder() : max_message_size_(-1), generic_service_(nullptr) { grpc_compression_options_init(&compression_options_); + gpr_once_init(&once_init_plugin_list, do_plugin_list_init); + for (auto factory : (*g_plugin_factory_list)) { + std::unique_ptr plugin = factory(); + plugins_[plugin->name()] = std::move(plugin); + } } std::unique_ptr ServerBuilder::AddCompletionQueue() { @@ -96,6 +110,15 @@ std::unique_ptr ServerBuilder::BuildAndStart() { ChannelArguments args; for (auto option = options_.begin(); option != options_.end(); ++option) { (*option)->UpdateArguments(&args); + (*option)->UpdatePlugins(&plugins_); + } + if (thread_pool == nullptr) { + for (auto plugin = plugins_.begin(); plugin != plugins_.end(); plugin++) { + if ((*plugin).second->has_sync_methods()) { + thread_pool.reset(CreateDefaultThreadPool()); + break; + } + } } if (max_message_size_ > 0) { args.SetInt(GRPC_ARG_MAX_MESSAGE_LENGTH, max_message_size_); @@ -104,6 +127,7 @@ std::unique_ptr ServerBuilder::BuildAndStart() { compression_options_.enabled_algorithms_bitset); std::unique_ptr server( new Server(thread_pool.release(), true, max_message_size_, &args)); + ServerInitializer* initializer = server->initializer(); for (auto cq = cqs_.begin(); cq != cqs_.end(); ++cq) { grpc_server_register_completion_queue(server->server_, (*cq)->cq(), nullptr); @@ -114,6 +138,9 @@ std::unique_ptr ServerBuilder::BuildAndStart() { return nullptr; } } + for (auto plugin = plugins_.begin(); plugin != plugins_.end(); plugin++) { + (*plugin).second->InitServer(initializer); + } if (generic_service_) { server->RegisterAsyncGenericService(generic_service_); } else { @@ -137,7 +164,16 @@ std::unique_ptr ServerBuilder::BuildAndStart() { if (!server->Start(cqs_data, cqs_.size())) { return nullptr; } + for (auto plugin = plugins_.begin(); plugin != plugins_.end(); plugin++) { + (*plugin).second->Finish(initializer); + } return server; } +void ServerBuilder::InternalAddPluginFactory( + std::unique_ptr (*CreatePlugin)()) { + gpr_once_init(&once_init_plugin_list, do_plugin_list_init); + (*g_plugin_factory_list).push_back(CreatePlugin); +} + } // namespace grpc diff --git a/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs b/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs index 875202b9509..ee11105efe7 100644 --- a/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs +++ b/src/csharp/Grpc.Examples.Tests/MathClientServerTests.cs @@ -92,7 +92,7 @@ namespace Math.Tests public void DivByZero() { var ex = Assert.Throws(() => client.Div(new DivArgs { Dividend = 0, Divisor = 0 })); - Assert.AreEqual(StatusCode.Unknown, ex.Status.StatusCode); + Assert.AreEqual(StatusCode.InvalidArgument, ex.Status.StatusCode); } [Test] diff --git a/src/csharp/Grpc.Examples/MathExamples.cs b/src/csharp/Grpc.Examples/MathExamples.cs index 60754209748..d260830b94d 100644 --- a/src/csharp/Grpc.Examples/MathExamples.cs +++ b/src/csharp/Grpc.Examples/MathExamples.cs @@ -32,6 +32,7 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; +using Grpc.Core; using Grpc.Core.Utils; namespace Math @@ -109,5 +110,42 @@ namespace Math DivReply result = await client.DivAsync(new DivArgs { Dividend = sum.Num_, Divisor = numbers.Count }); Console.WriteLine("Avg Result: " + result); } + + /// + /// Shows how to handle a call ending with non-OK status. + /// + public static async Task HandleErrorExample(Math.MathClient client) + { + try + { + DivReply result = await client.DivAsync(new DivArgs { Dividend = 5, Divisor = 0 }); + } + catch (RpcException ex) + { + Console.WriteLine(string.Format("RPC ended with status {0}", ex.Status)); + } + } + + /// + /// Shows how to send request headers and how to access response headers + /// and response trailers. + /// + public static async Task MetadataExample(Math.MathClient client) + { + var requestHeaders = new Metadata + { + { "custom-header", "custom-value" } + }; + + var call = client.DivAsync(new DivArgs { Dividend = 5, Divisor = 0 }, requestHeaders); + + // Get response headers + Metadata responseHeaders = await call.ResponseHeadersAsync; + + var result = await call; + + // Get response trailers after the call has finished. + Metadata responseTrailers = call.GetTrailers(); + } } } diff --git a/src/csharp/Grpc.Examples/MathServiceImpl.cs b/src/csharp/Grpc.Examples/MathServiceImpl.cs index 79c56e57a85..a28020f62f3 100644 --- a/src/csharp/Grpc.Examples/MathServiceImpl.cs +++ b/src/csharp/Grpc.Examples/MathServiceImpl.cs @@ -52,23 +52,15 @@ namespace Math public override async Task Fib(FibArgs request, IServerStreamWriter responseStream, ServerCallContext context) { - if (request.Limit <= 0) - { - // keep streaming the sequence until cancelled. - IEnumerator fibEnumerator = FibInternal(long.MaxValue).GetEnumerator(); - while (!context.CancellationToken.IsCancellationRequested && fibEnumerator.MoveNext()) - { - await responseStream.WriteAsync(fibEnumerator.Current); - await Task.Delay(100); - } - } + var limit = request.Limit > 0 ? request.Limit : long.MaxValue; + var fibEnumerator = FibInternal(limit).GetEnumerator(); - if (request.Limit > 0) + // Keep streaming the sequence until the call is cancelled. + // Use CancellationToken from ServerCallContext to detect the cancellation. + while (!context.CancellationToken.IsCancellationRequested && fibEnumerator.MoveNext()) { - foreach (var num in FibInternal(request.Limit)) - { - await responseStream.WriteAsync(num); - } + await responseStream.WriteAsync(fibEnumerator.Current); + await Task.Delay(100); } } @@ -89,6 +81,13 @@ namespace Math static DivReply DivInternal(DivArgs args) { + if (args.Divisor == 0) + { + // One can finish the RPC with non-ok status by throwing RpcException instance. + // Alternatively, resulting status can be set using ServerCallContext.Status + throw new RpcException(new Status(StatusCode.InvalidArgument, "Division by zero")); + } + long quotient = args.Dividend / args.Divisor; long remainder = args.Dividend % args.Divisor; return new DivReply { Quotient = quotient, Remainder = remainder }; diff --git a/src/csharp/Grpc.IntegrationTesting/StressTestClient.cs b/src/csharp/Grpc.IntegrationTesting/StressTestClient.cs index 8db691cb048..4d6ca7ece57 100644 --- a/src/csharp/Grpc.IntegrationTesting/StressTestClient.cs +++ b/src/csharp/Grpc.IntegrationTesting/StressTestClient.cs @@ -311,7 +311,7 @@ namespace Grpc.IntegrationTesting var snapshot = histogram.GetSnapshot(true); var elapsedSnapshot = wallClockStopwatch.GetElapsedSnapshot(true); - return (long) (snapshot.Count / elapsedSnapshot.Seconds); + return (long) (snapshot.Count / elapsedSnapshot.TotalSeconds); } } } diff --git a/src/node/tools/bin/protoc.js b/src/node/tools/bin/protoc.js index 4d50c94b0f8..53fc5dc4280 100755 --- a/src/node/tools/bin/protoc.js +++ b/src/node/tools/bin/protoc.js @@ -47,10 +47,11 @@ var exe_ext = process.platform === 'win32' ? '.exe' : ''; var protoc = path.resolve(__dirname, 'protoc' + exe_ext); -execFile(protoc, process.argv.slice(2), function(error, stdout, stderr) { +var child_process = execFile(protoc, process.argv.slice(2), function(error, stdout, stderr) { if (error) { throw error; } - console.log(stdout); - console.log(stderr); }); + +child_process.stdout.pipe(process.stdout); +child_process.stderr.pipe(process.stderr); diff --git a/src/node/tools/bin/protoc_plugin.js b/src/node/tools/bin/protoc_plugin.js index 281ec0d85e5..857882e1c34 100755 --- a/src/node/tools/bin/protoc_plugin.js +++ b/src/node/tools/bin/protoc_plugin.js @@ -47,10 +47,12 @@ var exe_ext = process.platform === 'win32' ? '.exe' : ''; var plugin = path.resolve(__dirname, 'grpc_node_plugin' + exe_ext); -execFile(plugin, process.argv.slice(2), function(error, stdout, stderr) { +var child_process = execFile(plugin, process.argv.slice(2), {encoding: 'buffer'}, function(error, stdout, stderr) { if (error) { throw error; } - console.log(stdout); - console.log(stderr); }); + +process.stdin.pipe(child_process.stdin); +child_process.stdout.pipe(process.stdout); +child_process.stderr.pipe(process.stderr); diff --git a/src/proto/grpc/testing/echo_messages.proto b/src/proto/grpc/testing/echo_messages.proto index 1be1966f101..b405acf0431 100644 --- a/src/proto/grpc/testing/echo_messages.proto +++ b/src/proto/grpc/testing/echo_messages.proto @@ -32,6 +32,12 @@ syntax = "proto3"; package grpc.testing; +// Message to be echoed back serialized in trailer. +message DebugInfo { + repeated string stack_entries = 1; + string detail = 2; +} + message RequestParams { bool echo_deadline = 1; int32 client_cancel_after_us = 2; @@ -43,6 +49,7 @@ message RequestParams { string expected_client_identity = 8; // will force check_auth_context. bool skip_cancelled_check = 9; string expected_transport_security_type = 10; + DebugInfo debug_info = 11; } message EchoRequest { diff --git a/src/python/grpcio/tests/qps/benchmark_client.py b/src/python/grpcio/tests/qps/benchmark_client.py index eed0b0c6dac..b372ea01ade 100644 --- a/src/python/grpcio/tests/qps/benchmark_client.py +++ b/src/python/grpcio/tests/qps/benchmark_client.py @@ -39,6 +39,7 @@ except ImportError: from concurrent import futures from grpc.beta import implementations +from grpc.framework.interfaces.face import face from src.proto.grpc.testing import messages_pb2 from src.proto.grpc.testing import services_pb2 from tests.unit import resources @@ -141,10 +142,10 @@ class UnaryAsyncBenchmarkClient(BenchmarkClient): self._stub = None -class StreamingAsyncBenchmarkClient(BenchmarkClient): +class StreamingSyncBenchmarkClient(BenchmarkClient): def __init__(self, server, config, hist): - super(StreamingAsyncBenchmarkClient, self).__init__(server, config, hist) + super(StreamingSyncBenchmarkClient, self).__init__(server, config, hist) self._is_streaming = False self._pool = futures.ThreadPoolExecutor(max_workers=1) # Use a thread-safe queue to put requests on the stream @@ -167,12 +168,12 @@ class StreamingAsyncBenchmarkClient(BenchmarkClient): def _request_stream(self): self._is_streaming = True if self._generic: - response_stream = self._stub.inline_stream_stream( - 'grpc.testing.BenchmarkService', 'StreamingCall', - self._request_generator(), _TIMEOUT) + stream_callable = self._stub.stream_stream( + 'grpc.testing.BenchmarkService', 'StreamingCall') else: - response_stream = self._stub.StreamingCall(self._request_generator(), - _TIMEOUT) + stream_callable = self._stub.StreamingCall + + response_stream = stream_callable(self._request_generator(), _TIMEOUT) for _ in response_stream: end_time = time.time() self._handle_response(end_time - self._send_time_queue.get_nowait()) @@ -184,3 +185,48 @@ class StreamingAsyncBenchmarkClient(BenchmarkClient): yield request except queue.Empty: pass + + +class AsyncReceiver(face.ResponseReceiver): + """Receiver for async stream responses.""" + + def __init__(self, send_time_queue, response_handler): + self._send_time_queue = send_time_queue + self._response_handler = response_handler + + def initial_metadata(self, initial_mdetadata): + pass + + def response(self, response): + end_time = time.time() + self._response_handler(end_time - self._send_time_queue.get_nowait()) + + def complete(self, terminal_metadata, code, details): + pass + + +class StreamingAsyncBenchmarkClient(BenchmarkClient): + + def __init__(self, server, config, hist): + super(StreamingAsyncBenchmarkClient, self).__init__(server, config, hist) + self._send_time_queue = queue.Queue() + self._receiver = AsyncReceiver(self._send_time_queue, self._handle_response) + self._rendezvous = None + + def send_request(self): + if self._rendezvous is not None: + self._send_time_queue.put(time.time()) + self._rendezvous.consume(self._request) + + def start(self): + if self._generic: + stream_callable = self._stub.stream_stream( + 'grpc.testing.BenchmarkService', 'StreamingCall') + else: + stream_callable = self._stub.StreamingCall + self._rendezvous = stream_callable.event( + self._receiver, lambda *args: None, _TIMEOUT) + + def stop(self): + self._rendezvous.terminate() + self._rendezvous = None diff --git a/src/python/grpcio/tests/qps/client_runner.py b/src/python/grpcio/tests/qps/client_runner.py index a36c30ccc0a..1ede7d2af1b 100644 --- a/src/python/grpcio/tests/qps/client_runner.py +++ b/src/python/grpcio/tests/qps/client_runner.py @@ -89,9 +89,9 @@ class ClosedLoopClientRunner(ClientRunner): def start(self): self._is_running = True + self._client.start() for _ in xrange(self._request_count): self._client.send_request() - self._client.start() def stop(self): self._is_running = False diff --git a/src/python/grpcio/tests/qps/worker_server.py b/src/python/grpcio/tests/qps/worker_server.py index 0b3acc14e7d..1f9af5482cc 100644 --- a/src/python/grpcio/tests/qps/worker_server.py +++ b/src/python/grpcio/tests/qps/worker_server.py @@ -146,8 +146,9 @@ class WorkerServer(services_pb2.BetaWorkerServiceServicer): if config.rpc_type == control_pb2.UNARY: client = benchmark_client.UnarySyncBenchmarkClient( server, config, qps_data) - else: - raise Exception('STREAMING SYNC client not supported') + elif config.rpc_type == control_pb2.STREAMING: + client = benchmark_client.StreamingSyncBenchmarkClient( + server, config, qps_data) elif config.client_type == control_pb2.ASYNC_CLIENT: if config.rpc_type == control_pb2.UNARY: client = benchmark_client.UnaryAsyncBenchmarkClient( diff --git a/src/ruby/lib/grpc/generic/client_stub.rb b/src/ruby/lib/grpc/generic/client_stub.rb index 68e167a69fc..12946fe819b 100644 --- a/src/ruby/lib/grpc/generic/client_stub.rb +++ b/src/ruby/lib/grpc/generic/client_stub.rb @@ -49,7 +49,12 @@ module GRPC fail(TypeError, '!Channel') unless alt_chan.is_a?(Core::Channel) return alt_chan end - kw['grpc.primary_user_agent'] = "grpc-ruby/#{VERSION}" + if kw['grpc.primary_user_agent'].nil? + kw['grpc.primary_user_agent'] = '' + else + kw['grpc.primary_user_agent'] += ' ' + end + kw['grpc.primary_user_agent'] += "grpc-ruby/#{VERSION}" unless creds.is_a?(Core::ChannelCredentials) || creds.is_a?(Symbol) fail(TypeError, '!ChannelCredentials or Symbol') end diff --git a/src/ruby/tools/grpc-tools.gemspec b/src/ruby/tools/grpc-tools.gemspec index af904de4a91..9fa4b66392d 100644 --- a/src/ruby/tools/grpc-tools.gemspec +++ b/src/ruby/tools/grpc-tools.gemspec @@ -18,5 +18,5 @@ Gem::Specification.new do |s| s.platform = Gem::Platform::RUBY - s.executables = %w( protoc.rb protoc_grpc_ruby_plugin.rb ) + s.executables = %w( grpc_tools_ruby_protoc.rb grpc_tools_ruby_protoc_plugin.rb ) end diff --git a/templates/package.json.template b/templates/package.json.template index 11718b1ccbd..9d19ca06293 100644 --- a/templates/package.json.template +++ b/templates/package.json.template @@ -69,6 +69,8 @@ "src/node/ext", "include/grpc", "src/core", + "src/boringssl", + "src/zlib", "third_party/nanopb", "third_party/zlib", "third_party/boringssl", diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc index 0232a9fa317..e0649bd6948 100644 --- a/test/cpp/end2end/async_end2end_test.cc +++ b/test/cpp/end2end/async_end2end_test.cc @@ -199,6 +199,28 @@ class Verifier { bool spin_; }; +// This class disables the server builder plugins that may add sync services to +// the server. If there are sync services, UnimplementedRpc test will triger +// the sync unkown rpc routine on the server side, rather than the async one +// that needs to be tested here. +class ServerBuilderSyncPluginDisabler : public ::grpc::ServerBuilderOption { + public: + void UpdateArguments(ChannelArguments* arg) GRPC_OVERRIDE {} + + void UpdatePlugins( + std::map>* plugins) + GRPC_OVERRIDE { + auto plugin = plugins->begin(); + while (plugin != plugins->end()) { + if ((*plugin).second->has_sync_methods()) { + plugins->erase(plugin++); + } else { + plugin++; + } + } + } +}; + class TestScenario { public: TestScenario(bool non_block, const grpc::string& creds_type, @@ -232,6 +254,12 @@ class AsyncEnd2endTest : public ::testing::TestWithParam { builder.AddListeningPort(server_address_.str(), server_creds); builder.RegisterService(&service_); cq_ = builder.AddCompletionQueue(); + + // TODO(zyc): make a test option to choose wheather sync plugins should be + // deleted + std::unique_ptr sync_plugin_disabler( + new ServerBuilderSyncPluginDisabler()); + builder.SetOption(move(sync_plugin_disabler)); server_ = builder.BuildAndStart(); gpr_tls_set(&g_is_async_end2end_test, 1); diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index 0c9313f88f0..e3408bff75e 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -975,6 +975,34 @@ TEST_P(End2endTest, NonExistingService) { EXPECT_EQ("", s.error_message()); } +// Ask the server to send back a serialized proto in trailer. +// This is an example of setting error details. +TEST_P(End2endTest, BinaryTrailerTest) { + ResetStub(); + EchoRequest request; + EchoResponse response; + ClientContext context; + + request.mutable_param()->set_echo_metadata(true); + DebugInfo* info = request.mutable_param()->mutable_debug_info(); + info->add_stack_entries("stack_entry_1"); + info->add_stack_entries("stack_entry_2"); + info->add_stack_entries("stack_entry_3"); + info->set_detail("detailed debug info"); + grpc::string expected_string = info->SerializeAsString(); + request.set_message("Hello"); + + Status s = stub_->Echo(&context, request, &response); + EXPECT_FALSE(s.ok()); + auto trailers = context.GetServerTrailingMetadata(); + EXPECT_EQ(1u, trailers.count(kDebugInfoTrailerKey)); + auto iter = trailers.find(kDebugInfoTrailerKey); + EXPECT_EQ(expected_string, iter->second); + // Parse the returned trailer into a DebugInfo proto. + DebugInfo returned_info; + EXPECT_TRUE(returned_info.ParseFromString(ToString(iter->second))); +} + ////////////////////////////////////////////////////////////////////////// // Test with and without a proxy. class ProxyEnd2endTest : public End2endTest { diff --git a/test/cpp/end2end/server_builder_plugin_test.cc b/test/cpp/end2end/server_builder_plugin_test.cc new file mode 100644 index 00000000000..87e3709d7d2 --- /dev/null +++ b/test/cpp/end2end/server_builder_plugin_test.cc @@ -0,0 +1,256 @@ +/* + * + * Copyright 2016, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" +#include "test/cpp/end2end/test_service_impl.h" + +#define PLUGIN_NAME "TestServerBuilderPlugin" + +namespace grpc { +namespace testing { + +class TestServerBuilderPlugin : public ServerBuilderPlugin { + public: + TestServerBuilderPlugin() : service_(new TestServiceImpl()) { + init_server_is_called_ = false; + finish_is_called_ = false; + change_arguments_is_called_ = false; + } + + grpc::string name() GRPC_OVERRIDE { return PLUGIN_NAME; } + + void InitServer(ServerInitializer* si) GRPC_OVERRIDE { + init_server_is_called_ = true; + if (register_service_) { + si->RegisterService(service_); + } + } + + void Finish(ServerInitializer* si) GRPC_OVERRIDE { finish_is_called_ = true; } + + void ChangeArguments(const grpc::string& name, void* value) GRPC_OVERRIDE { + change_arguments_is_called_ = true; + } + + bool has_async_methods() const GRPC_OVERRIDE { + if (register_service_) { + return service_->has_async_methods(); + } + return false; + } + + bool has_sync_methods() const GRPC_OVERRIDE { + if (register_service_) { + return service_->has_synchronous_methods(); + } + return false; + } + + void SetRegisterService() { register_service_ = true; } + + bool init_server_is_called() { return init_server_is_called_; } + bool finish_is_called() { return finish_is_called_; } + bool change_arguments_is_called() { return change_arguments_is_called_; } + + private: + bool init_server_is_called_; + bool finish_is_called_; + bool change_arguments_is_called_; + bool register_service_; + std::shared_ptr service_; +}; + +class InsertPluginServerBuilderOption : public ServerBuilderOption { + public: + InsertPluginServerBuilderOption() { register_service_ = false; } + + void UpdateArguments(ChannelArguments* arg) GRPC_OVERRIDE {} + + void UpdatePlugins( + std::map>* plugins) + GRPC_OVERRIDE { + plugins->clear(); + + std::unique_ptr plugin( + new TestServerBuilderPlugin()); + if (register_service_) plugin->SetRegisterService(); + (*plugins)[plugin->name()] = std::move(plugin); + } + + void SetRegisterService() { register_service_ = true; } + + private: + bool register_service_; +}; + +std::unique_ptr CreateTestServerBuilderPlugin() { + return std::unique_ptr(new TestServerBuilderPlugin()); +} + +void AddTestServerBuilderPlugin() { + static bool already_here = false; + if (already_here) return; + already_here = true; + ::grpc::ServerBuilder::InternalAddPluginFactory( + &CreateTestServerBuilderPlugin); +} + +// Force AddServerBuilderPlugin() to be called at static initialization time. +struct StaticTestPluginInitializer { + StaticTestPluginInitializer() { AddTestServerBuilderPlugin(); } +} static_plugin_initializer_test_; + +// When the param boolean is true, the ServerBuilder plugin will be added at the +// time of static initialization. When it's false, the ServerBuilder plugin will +// be added using ServerBuilder::SetOption(). +class ServerBuilderPluginTest : public ::testing::TestWithParam { + public: + ServerBuilderPluginTest() {} + + void SetUp() GRPC_OVERRIDE { + port_ = grpc_pick_unused_port_or_die(); + builder_.reset(new ServerBuilder()); + } + + void InsertPlugin() { + if (GetParam()) { + // Add ServerBuilder plugin in static initialization + EXPECT_TRUE(builder_->plugins_[PLUGIN_NAME] != nullptr); + } else { + // Add ServerBuilder plugin using ServerBuilder::SetOption() + builder_->SetOption(std::unique_ptr( + new InsertPluginServerBuilderOption())); + } + } + + void InsertPluginWithTestService() { + if (GetParam()) { + // Add ServerBuilder plugin in static initialization + EXPECT_TRUE(builder_->plugins_[PLUGIN_NAME] != nullptr); + auto plugin = static_cast( + builder_->plugins_[PLUGIN_NAME].get()); + EXPECT_TRUE(plugin != nullptr); + plugin->SetRegisterService(); + } else { + // Add ServerBuilder plugin using ServerBuilder::SetOption() + std::unique_ptr option( + new InsertPluginServerBuilderOption()); + option->SetRegisterService(); + builder_->SetOption(std::move(option)); + } + } + + void StartServer() { + grpc::string server_address = "localhost:" + to_string(port_); + builder_->AddListeningPort(server_address, InsecureServerCredentials()); + server_ = builder_->BuildAndStart(); + EXPECT_TRUE(builder_->plugins_[PLUGIN_NAME] != nullptr); + } + + void ResetStub() { + string target = "dns:localhost:" + to_string(port_); + channel_ = CreateChannel(target, InsecureChannelCredentials()); + stub_ = grpc::testing::EchoTestService::NewStub(channel_); + } + + void TearDown() GRPC_OVERRIDE { + EXPECT_TRUE(builder_->plugins_[PLUGIN_NAME] != nullptr); + auto plugin = static_cast( + builder_->plugins_[PLUGIN_NAME].get()); + EXPECT_TRUE(plugin != nullptr); + EXPECT_TRUE(plugin->init_server_is_called()); + EXPECT_TRUE(plugin->finish_is_called()); + } + + string to_string(const int number) { + std::stringstream strs; + strs << number; + return strs.str(); + } + + protected: + std::shared_ptr channel_; + std::unique_ptr builder_; + std::unique_ptr stub_; + std::unique_ptr server_; + TestServiceImpl service_; + int port_; +}; + +TEST_P(ServerBuilderPluginTest, PluginWithoutServiceTest) { + InsertPlugin(); + StartServer(); +} + +TEST_P(ServerBuilderPluginTest, PluginWithServiceTest) { + InsertPluginWithTestService(); + StartServer(); + ResetStub(); + + EchoRequest request; + EchoResponse response; + request.set_message("Hello hello hello hello"); + ClientContext context; + context.set_compression_algorithm(GRPC_COMPRESS_GZIP); + Status s = stub_->Echo(&context, request, &response); + EXPECT_EQ(response.message(), request.message()); + EXPECT_TRUE(s.ok()); +} + +INSTANTIATE_TEST_CASE_P(ServerBuilderPluginTest, ServerBuilderPluginTest, + ::testing::Values(false, true)); + +} // namespace testing +} // namespace grpc + +int main(int argc, char** argv) { + grpc_test_init(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/cpp/end2end/test_service_impl.cc b/test/cpp/end2end/test_service_impl.cc index 2f5dd6d49e8..cbaee922289 100644 --- a/test/cpp/end2end/test_service_impl.cc +++ b/test/cpp/end2end/test_service_impl.cc @@ -135,6 +135,14 @@ Status TestServiceImpl::Echo(ServerContext* context, const EchoRequest* request, context->AddTrailingMetadata(ToString(iter->first), ToString(iter->second)); } + // Terminate rpc with error and debug info in trailer. + if (request->param().debug_info().stack_entries_size() || + !request->param().debug_info().detail().empty()) { + grpc::string serialized_debug_info = + request->param().debug_info().SerializeAsString(); + context->AddTrailingMetadata(kDebugInfoTrailerKey, serialized_debug_info); + return Status::CANCELLED; + } } if (request->has_param() && (request->param().expected_client_identity().length() > 0 || diff --git a/test/cpp/end2end/test_service_impl.h b/test/cpp/end2end/test_service_impl.h index 1ab6ced9e00..c89f88c900e 100644 --- a/test/cpp/end2end/test_service_impl.h +++ b/test/cpp/end2end/test_service_impl.h @@ -47,6 +47,7 @@ namespace testing { const int kNumResponseStreamsMsgs = 3; const char* const kServerCancelAfterReads = "cancel_after_reads"; const char* const kServerTryCancelRequest = "server_try_cancel"; +const char* const kDebugInfoTrailerKey = "debug-info-bin"; typedef enum { DO_NOT_CANCEL = 0, diff --git a/test/cpp/qps/client_async.cc b/test/cpp/qps/client_async.cc index e72cef28114..c32160a7d45 100644 --- a/test/cpp/qps/client_async.cc +++ b/test/cpp/qps/client_async.cc @@ -84,7 +84,8 @@ class ClientRpcContextUnaryImpl : public ClientRpcContext { std::function< std::unique_ptr>( BenchmarkService::Stub*, grpc::ClientContext*, const RequestType&, - CompletionQueue*)> start_req, + CompletionQueue*)> + start_req, std::function on_done) : context_(), stub_(stub), @@ -165,7 +166,8 @@ class AsyncClient : public ClientImpl { AsyncClient(const ClientConfig& config, std::function next_issue, - const RequestType&)> setup_ctx, + const RequestType&)> + setup_ctx, std::function(std::shared_ptr)> create_stub) : ClientImpl(config, create_stub), @@ -278,7 +280,8 @@ class ClientRpcContextStreamingImpl : public ClientRpcContext { std::function>( BenchmarkService::Stub*, grpc::ClientContext*, CompletionQueue*, - void*)> start_req, + void*)> + start_req, std::function on_done) : context_(), stub_(stub), @@ -405,7 +408,8 @@ class ClientRpcContextGenericStreamingImpl : public ClientRpcContext { std::function next_issue, std::function( grpc::GenericStub*, grpc::ClientContext*, - const grpc::string& method_name, CompletionQueue*, void*)> start_req, + const grpc::string& method_name, CompletionQueue*, void*)> + start_req, std::function on_done) : context_(), stub_(stub), diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc index a68f1ae7b67..1234542687d 100644 --- a/test/cpp/qps/server_async.cc +++ b/test/cpp/qps/server_async.cc @@ -73,7 +73,8 @@ class AsyncQpsServerTest : public Server { CompletionQueue *, ServerCompletionQueue *, void *)> request_streaming_function, std::function process_rpc) + ResponseType *)> + process_rpc) : Server(config) { char *server_address = NULL; @@ -190,7 +191,8 @@ class AsyncQpsServerTest : public Server { ServerRpcContextUnaryImpl( std::function *, - void *)> request_method, + void *)> + request_method, std::function invoke_method) : srv_ctx_(new ServerContextType), diff --git a/third_party/protobuf b/third_party/protobuf index d5fb408ddc2..a1938b2aa9c 160000 --- a/third_party/protobuf +++ b/third_party/protobuf @@ -1 +1 @@ -Subproject commit d5fb408ddc281ffcadeb08699e65bb694656d0bd +Subproject commit a1938b2aa9ca86ce7ce50c27ff9737c1008d2a03 diff --git a/tools/distrib/python/grpcio_tools/protoc_lib_deps.py b/tools/distrib/python/grpcio_tools/protoc_lib_deps.py index 9f31172170d..135ac5cbb3b 100644 --- a/tools/distrib/python/grpcio_tools/protoc_lib_deps.py +++ b/tools/distrib/python/grpcio_tools/protoc_lib_deps.py @@ -29,4 +29,4 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # AUTO-GENERATED BY make_grpcio_tools.py! -CC_FILES=['google/protobuf/compiler/zip_writer.cc', 'google/protobuf/compiler/subprocess.cc', 'google/protobuf/compiler/ruby/ruby_generator.cc', 'google/protobuf/compiler/python/python_generator.cc', 'google/protobuf/compiler/plugin.pb.cc', 'google/protobuf/compiler/plugin.cc', 'google/protobuf/compiler/objectivec/objectivec_primitive_field.cc', 'google/protobuf/compiler/objectivec/objectivec_oneof.cc', 'google/protobuf/compiler/objectivec/objectivec_message_field.cc', 'google/protobuf/compiler/objectivec/objectivec_message.cc', 'google/protobuf/compiler/objectivec/objectivec_map_field.cc', 'google/protobuf/compiler/objectivec/objectivec_helpers.cc', 'google/protobuf/compiler/objectivec/objectivec_generator.cc', 'google/protobuf/compiler/objectivec/objectivec_file.cc', 'google/protobuf/compiler/objectivec/objectivec_field.cc', 'google/protobuf/compiler/objectivec/objectivec_extension.cc', 'google/protobuf/compiler/objectivec/objectivec_enum_field.cc', 'google/protobuf/compiler/objectivec/objectivec_enum.cc', 'google/protobuf/compiler/js/js_generator.cc', 'google/protobuf/compiler/javanano/javanano_primitive_field.cc', 'google/protobuf/compiler/javanano/javanano_message_field.cc', 'google/protobuf/compiler/javanano/javanano_message.cc', 'google/protobuf/compiler/javanano/javanano_map_field.cc', 'google/protobuf/compiler/javanano/javanano_helpers.cc', 'google/protobuf/compiler/javanano/javanano_generator.cc', 'google/protobuf/compiler/javanano/javanano_file.cc', 'google/protobuf/compiler/javanano/javanano_field.cc', 'google/protobuf/compiler/javanano/javanano_extension.cc', 'google/protobuf/compiler/javanano/javanano_enum_field.cc', 'google/protobuf/compiler/javanano/javanano_enum.cc', 'google/protobuf/compiler/java/java_string_field_lite.cc', 'google/protobuf/compiler/java/java_string_field.cc', 'google/protobuf/compiler/java/java_shared_code_generator.cc', 'google/protobuf/compiler/java/java_service.cc', 'google/protobuf/compiler/java/java_primitive_field_lite.cc', 'google/protobuf/compiler/java/java_primitive_field.cc', 'google/protobuf/compiler/java/java_name_resolver.cc', 'google/protobuf/compiler/java/java_message_lite.cc', 'google/protobuf/compiler/java/java_message_field_lite.cc', 'google/protobuf/compiler/java/java_message_field.cc', 'google/protobuf/compiler/java/java_message_builder_lite.cc', 'google/protobuf/compiler/java/java_message_builder.cc', 'google/protobuf/compiler/java/java_message.cc', 'google/protobuf/compiler/java/java_map_field_lite.cc', 'google/protobuf/compiler/java/java_map_field.cc', 'google/protobuf/compiler/java/java_lazy_message_field_lite.cc', 'google/protobuf/compiler/java/java_lazy_message_field.cc', 'google/protobuf/compiler/java/java_helpers.cc', 'google/protobuf/compiler/java/java_generator_factory.cc', 'google/protobuf/compiler/java/java_generator.cc', 'google/protobuf/compiler/java/java_file.cc', 'google/protobuf/compiler/java/java_field.cc', 'google/protobuf/compiler/java/java_extension.cc', 'google/protobuf/compiler/java/java_enum_lite.cc', 'google/protobuf/compiler/java/java_enum_field_lite.cc', 'google/protobuf/compiler/java/java_enum_field.cc', 'google/protobuf/compiler/java/java_enum.cc', 'google/protobuf/compiler/java/java_doc_comment.cc', 'google/protobuf/compiler/java/java_context.cc', 'google/protobuf/compiler/csharp/csharp_wrapper_field.cc', 'google/protobuf/compiler/csharp/csharp_source_generator_base.cc', 'google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc', 'google/protobuf/compiler/csharp/csharp_repeated_message_field.cc', 'google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc', 'google/protobuf/compiler/csharp/csharp_reflection_class.cc', 'google/protobuf/compiler/csharp/csharp_primitive_field.cc', 'google/protobuf/compiler/csharp/csharp_message_field.cc', 'google/protobuf/compiler/csharp/csharp_message.cc', 'google/protobuf/compiler/csharp/csharp_map_field.cc', 'google/protobuf/compiler/csharp/csharp_helpers.cc', 'google/protobuf/compiler/csharp/csharp_generator.cc', 'google/protobuf/compiler/csharp/csharp_field_base.cc', 'google/protobuf/compiler/csharp/csharp_enum_field.cc', 'google/protobuf/compiler/csharp/csharp_enum.cc', 'google/protobuf/compiler/csharp/csharp_doc_comment.cc', 'google/protobuf/compiler/cpp/cpp_string_field.cc', 'google/protobuf/compiler/cpp/cpp_service.cc', 'google/protobuf/compiler/cpp/cpp_primitive_field.cc', 'google/protobuf/compiler/cpp/cpp_message_field.cc', 'google/protobuf/compiler/cpp/cpp_message.cc', 'google/protobuf/compiler/cpp/cpp_map_field.cc', 'google/protobuf/compiler/cpp/cpp_helpers.cc', 'google/protobuf/compiler/cpp/cpp_generator.cc', 'google/protobuf/compiler/cpp/cpp_file.cc', 'google/protobuf/compiler/cpp/cpp_field.cc', 'google/protobuf/compiler/cpp/cpp_extension.cc', 'google/protobuf/compiler/cpp/cpp_enum_field.cc', 'google/protobuf/compiler/cpp/cpp_enum.cc', 'google/protobuf/compiler/command_line_interface.cc', 'google/protobuf/compiler/code_generator.cc', 'google/protobuf/wrappers.pb.cc', 'google/protobuf/wire_format.cc', 'google/protobuf/util/type_resolver_util.cc', 'google/protobuf/util/time_util.cc', 'google/protobuf/util/message_differencer.cc', 'google/protobuf/util/json_util.cc', 'google/protobuf/util/internal/utility.cc', 'google/protobuf/util/internal/type_info_test_helper.cc', 'google/protobuf/util/internal/type_info.cc', 'google/protobuf/util/internal/protostream_objectwriter.cc', 'google/protobuf/util/internal/protostream_objectsource.cc', 'google/protobuf/util/internal/proto_writer.cc', 'google/protobuf/util/internal/object_writer.cc', 'google/protobuf/util/internal/json_stream_parser.cc', 'google/protobuf/util/internal/json_objectwriter.cc', 'google/protobuf/util/internal/json_escaping.cc', 'google/protobuf/util/internal/field_mask_utility.cc', 'google/protobuf/util/internal/error_listener.cc', 'google/protobuf/util/internal/default_value_objectwriter.cc', 'google/protobuf/util/internal/datapiece.cc', 'google/protobuf/util/field_mask_util.cc', 'google/protobuf/util/field_comparator.cc', 'google/protobuf/unknown_field_set.cc', 'google/protobuf/type.pb.cc', 'google/protobuf/timestamp.pb.cc', 'google/protobuf/text_format.cc', 'google/protobuf/stubs/substitute.cc', 'google/protobuf/stubs/mathlimits.cc', 'google/protobuf/struct.pb.cc', 'google/protobuf/source_context.pb.cc', 'google/protobuf/service.cc', 'google/protobuf/reflection_ops.cc', 'google/protobuf/message.cc', 'google/protobuf/map_field.cc', 'google/protobuf/io/zero_copy_stream_impl.cc', 'google/protobuf/io/tokenizer.cc', 'google/protobuf/io/strtod.cc', 'google/protobuf/io/printer.cc', 'google/protobuf/io/gzip_stream.cc', 'google/protobuf/generated_message_reflection.cc', 'google/protobuf/field_mask.pb.cc', 'google/protobuf/extension_set_heavy.cc', 'google/protobuf/empty.pb.cc', 'google/protobuf/dynamic_message.cc', 'google/protobuf/duration.pb.cc', 'google/protobuf/descriptor_database.cc', 'google/protobuf/descriptor.pb.cc', 'google/protobuf/descriptor.cc', 'google/protobuf/compiler/parser.cc', 'google/protobuf/compiler/importer.cc', 'google/protobuf/api.pb.cc', 'google/protobuf/any.pb.cc', 'google/protobuf/any.cc', 'google/protobuf/wire_format_lite.cc', 'google/protobuf/stubs/time.cc', 'google/protobuf/stubs/strutil.cc', 'google/protobuf/stubs/structurally_valid.cc', 'google/protobuf/stubs/stringprintf.cc', 'google/protobuf/stubs/stringpiece.cc', 'google/protobuf/stubs/statusor.cc', 'google/protobuf/stubs/status.cc', 'google/protobuf/stubs/once.cc', 'google/protobuf/stubs/int128.cc', 'google/protobuf/stubs/common.cc', 'google/protobuf/stubs/bytestream.cc', 'google/protobuf/stubs/atomicops_internals_x86_msvc.cc', 'google/protobuf/stubs/atomicops_internals_x86_gcc.cc', 'google/protobuf/repeated_field.cc', 'google/protobuf/message_lite.cc', 'google/protobuf/io/zero_copy_stream_impl_lite.cc', 'google/protobuf/io/zero_copy_stream.cc', 'google/protobuf/io/coded_stream.cc', 'google/protobuf/generated_message_util.cc', 'google/protobuf/extension_set.cc', 'google/protobuf/arenastring.cc', 'google/protobuf/arena.cc'] +CC_FILES=['google/protobuf/compiler/zip_writer.cc', 'google/protobuf/compiler/subprocess.cc', 'google/protobuf/compiler/ruby/ruby_generator.cc', 'google/protobuf/compiler/python/python_generator.cc', 'google/protobuf/compiler/plugin.pb.cc', 'google/protobuf/compiler/plugin.cc', 'google/protobuf/compiler/objectivec/objectivec_primitive_field.cc', 'google/protobuf/compiler/objectivec/objectivec_oneof.cc', 'google/protobuf/compiler/objectivec/objectivec_message_field.cc', 'google/protobuf/compiler/objectivec/objectivec_message.cc', 'google/protobuf/compiler/objectivec/objectivec_map_field.cc', 'google/protobuf/compiler/objectivec/objectivec_helpers.cc', 'google/protobuf/compiler/objectivec/objectivec_generator.cc', 'google/protobuf/compiler/objectivec/objectivec_file.cc', 'google/protobuf/compiler/objectivec/objectivec_field.cc', 'google/protobuf/compiler/objectivec/objectivec_extension.cc', 'google/protobuf/compiler/objectivec/objectivec_enum_field.cc', 'google/protobuf/compiler/objectivec/objectivec_enum.cc', 'google/protobuf/compiler/js/js_generator.cc', 'google/protobuf/compiler/javanano/javanano_primitive_field.cc', 'google/protobuf/compiler/javanano/javanano_message_field.cc', 'google/protobuf/compiler/javanano/javanano_message.cc', 'google/protobuf/compiler/javanano/javanano_map_field.cc', 'google/protobuf/compiler/javanano/javanano_helpers.cc', 'google/protobuf/compiler/javanano/javanano_generator.cc', 'google/protobuf/compiler/javanano/javanano_file.cc', 'google/protobuf/compiler/javanano/javanano_field.cc', 'google/protobuf/compiler/javanano/javanano_extension.cc', 'google/protobuf/compiler/javanano/javanano_enum_field.cc', 'google/protobuf/compiler/javanano/javanano_enum.cc', 'google/protobuf/compiler/java/java_string_field_lite.cc', 'google/protobuf/compiler/java/java_string_field.cc', 'google/protobuf/compiler/java/java_shared_code_generator.cc', 'google/protobuf/compiler/java/java_service.cc', 'google/protobuf/compiler/java/java_primitive_field_lite.cc', 'google/protobuf/compiler/java/java_primitive_field.cc', 'google/protobuf/compiler/java/java_name_resolver.cc', 'google/protobuf/compiler/java/java_message_lite.cc', 'google/protobuf/compiler/java/java_message_field_lite.cc', 'google/protobuf/compiler/java/java_message_field.cc', 'google/protobuf/compiler/java/java_message_builder_lite.cc', 'google/protobuf/compiler/java/java_message_builder.cc', 'google/protobuf/compiler/java/java_message.cc', 'google/protobuf/compiler/java/java_map_field_lite.cc', 'google/protobuf/compiler/java/java_map_field.cc', 'google/protobuf/compiler/java/java_lazy_message_field_lite.cc', 'google/protobuf/compiler/java/java_lazy_message_field.cc', 'google/protobuf/compiler/java/java_helpers.cc', 'google/protobuf/compiler/java/java_generator_factory.cc', 'google/protobuf/compiler/java/java_generator.cc', 'google/protobuf/compiler/java/java_file.cc', 'google/protobuf/compiler/java/java_field.cc', 'google/protobuf/compiler/java/java_extension_lite.cc', 'google/protobuf/compiler/java/java_extension.cc', 'google/protobuf/compiler/java/java_enum_lite.cc', 'google/protobuf/compiler/java/java_enum_field_lite.cc', 'google/protobuf/compiler/java/java_enum_field.cc', 'google/protobuf/compiler/java/java_enum.cc', 'google/protobuf/compiler/java/java_doc_comment.cc', 'google/protobuf/compiler/java/java_context.cc', 'google/protobuf/compiler/csharp/csharp_wrapper_field.cc', 'google/protobuf/compiler/csharp/csharp_source_generator_base.cc', 'google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc', 'google/protobuf/compiler/csharp/csharp_repeated_message_field.cc', 'google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc', 'google/protobuf/compiler/csharp/csharp_reflection_class.cc', 'google/protobuf/compiler/csharp/csharp_primitive_field.cc', 'google/protobuf/compiler/csharp/csharp_message_field.cc', 'google/protobuf/compiler/csharp/csharp_message.cc', 'google/protobuf/compiler/csharp/csharp_map_field.cc', 'google/protobuf/compiler/csharp/csharp_helpers.cc', 'google/protobuf/compiler/csharp/csharp_generator.cc', 'google/protobuf/compiler/csharp/csharp_field_base.cc', 'google/protobuf/compiler/csharp/csharp_enum_field.cc', 'google/protobuf/compiler/csharp/csharp_enum.cc', 'google/protobuf/compiler/csharp/csharp_doc_comment.cc', 'google/protobuf/compiler/cpp/cpp_string_field.cc', 'google/protobuf/compiler/cpp/cpp_service.cc', 'google/protobuf/compiler/cpp/cpp_primitive_field.cc', 'google/protobuf/compiler/cpp/cpp_message_field.cc', 'google/protobuf/compiler/cpp/cpp_message.cc', 'google/protobuf/compiler/cpp/cpp_map_field.cc', 'google/protobuf/compiler/cpp/cpp_helpers.cc', 'google/protobuf/compiler/cpp/cpp_generator.cc', 'google/protobuf/compiler/cpp/cpp_file.cc', 'google/protobuf/compiler/cpp/cpp_field.cc', 'google/protobuf/compiler/cpp/cpp_extension.cc', 'google/protobuf/compiler/cpp/cpp_enum_field.cc', 'google/protobuf/compiler/cpp/cpp_enum.cc', 'google/protobuf/compiler/command_line_interface.cc', 'google/protobuf/compiler/code_generator.cc', 'google/protobuf/wrappers.pb.cc', 'google/protobuf/wire_format.cc', 'google/protobuf/util/type_resolver_util.cc', 'google/protobuf/util/time_util.cc', 'google/protobuf/util/message_differencer.cc', 'google/protobuf/util/json_util.cc', 'google/protobuf/util/internal/utility.cc', 'google/protobuf/util/internal/type_info_test_helper.cc', 'google/protobuf/util/internal/type_info.cc', 'google/protobuf/util/internal/protostream_objectwriter.cc', 'google/protobuf/util/internal/protostream_objectsource.cc', 'google/protobuf/util/internal/proto_writer.cc', 'google/protobuf/util/internal/object_writer.cc', 'google/protobuf/util/internal/json_stream_parser.cc', 'google/protobuf/util/internal/json_objectwriter.cc', 'google/protobuf/util/internal/json_escaping.cc', 'google/protobuf/util/internal/field_mask_utility.cc', 'google/protobuf/util/internal/error_listener.cc', 'google/protobuf/util/internal/default_value_objectwriter.cc', 'google/protobuf/util/internal/datapiece.cc', 'google/protobuf/util/field_mask_util.cc', 'google/protobuf/util/field_comparator.cc', 'google/protobuf/unknown_field_set.cc', 'google/protobuf/type.pb.cc', 'google/protobuf/timestamp.pb.cc', 'google/protobuf/text_format.cc', 'google/protobuf/stubs/substitute.cc', 'google/protobuf/stubs/mathlimits.cc', 'google/protobuf/struct.pb.cc', 'google/protobuf/source_context.pb.cc', 'google/protobuf/service.cc', 'google/protobuf/reflection_ops.cc', 'google/protobuf/message.cc', 'google/protobuf/map_field.cc', 'google/protobuf/io/zero_copy_stream_impl.cc', 'google/protobuf/io/tokenizer.cc', 'google/protobuf/io/strtod.cc', 'google/protobuf/io/printer.cc', 'google/protobuf/io/gzip_stream.cc', 'google/protobuf/generated_message_reflection.cc', 'google/protobuf/field_mask.pb.cc', 'google/protobuf/extension_set_heavy.cc', 'google/protobuf/empty.pb.cc', 'google/protobuf/dynamic_message.cc', 'google/protobuf/duration.pb.cc', 'google/protobuf/descriptor_database.cc', 'google/protobuf/descriptor.pb.cc', 'google/protobuf/descriptor.cc', 'google/protobuf/compiler/parser.cc', 'google/protobuf/compiler/importer.cc', 'google/protobuf/api.pb.cc', 'google/protobuf/any.pb.cc', 'google/protobuf/any.cc', 'google/protobuf/wire_format_lite.cc', 'google/protobuf/stubs/time.cc', 'google/protobuf/stubs/strutil.cc', 'google/protobuf/stubs/structurally_valid.cc', 'google/protobuf/stubs/stringprintf.cc', 'google/protobuf/stubs/stringpiece.cc', 'google/protobuf/stubs/statusor.cc', 'google/protobuf/stubs/status.cc', 'google/protobuf/stubs/once.cc', 'google/protobuf/stubs/int128.cc', 'google/protobuf/stubs/common.cc', 'google/protobuf/stubs/bytestream.cc', 'google/protobuf/stubs/atomicops_internals_x86_msvc.cc', 'google/protobuf/stubs/atomicops_internals_x86_gcc.cc', 'google/protobuf/repeated_field.cc', 'google/protobuf/message_lite.cc', 'google/protobuf/io/zero_copy_stream_impl_lite.cc', 'google/protobuf/io/zero_copy_stream.cc', 'google/protobuf/io/coded_stream.cc', 'google/protobuf/generated_message_util.cc', 'google/protobuf/extension_set.cc', 'google/protobuf/arenastring.cc', 'google/protobuf/arena.cc'] diff --git a/tools/doxygen/Doxyfile.c++ b/tools/doxygen/Doxyfile.c++ index 2a319db9796..798d68b0181 100644 --- a/tools/doxygen/Doxyfile.c++ +++ b/tools/doxygen/Doxyfile.c++ @@ -777,6 +777,8 @@ include/grpc++/impl/rpc_method.h \ include/grpc++/impl/rpc_service_method.h \ include/grpc++/impl/serialization_traits.h \ include/grpc++/impl/server_builder_option.h \ +include/grpc++/impl/server_builder_plugin.h \ +include/grpc++/impl/server_initializer.h \ include/grpc++/impl/service_type.h \ include/grpc++/impl/sync.h \ include/grpc++/impl/sync_cxx11.h \ diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index 5fdfafbf3ed..ce1d6ac3c1b 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -777,6 +777,8 @@ include/grpc++/impl/rpc_method.h \ include/grpc++/impl/rpc_service_method.h \ include/grpc++/impl/serialization_traits.h \ include/grpc++/impl/server_builder_option.h \ +include/grpc++/impl/server_builder_plugin.h \ +include/grpc++/impl/server_initializer.h \ include/grpc++/impl/service_type.h \ include/grpc++/impl/sync.h \ include/grpc++/impl/sync_cxx11.h \ diff --git a/tools/gource/create_auth_context.h b/tools/gource/create_auth_context.h new file mode 100644 index 00000000000..387407bfec5 --- /dev/null +++ b/tools/gource/create_auth_context.h @@ -0,0 +1,42 @@ +/* + * + * 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 + +#include +#include + +namespace grpc { + +std::shared_ptr CreateAuthContext(grpc_call* call); + +} // namespace grpc diff --git a/tools/gource/gen-all-logs.sh b/tools/gource/gen-all-logs.sh new file mode 100755 index 00000000000..85352c514e9 --- /dev/null +++ b/tools/gource/gen-all-logs.sh @@ -0,0 +1,47 @@ +#!/bin/bash +# Copyright 2016, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +set -ex + +outdir=`pwd` + +tmpdir=`mktemp -d` +mkdir -p $tmpdir/logs +repos="grpc grpc-common grpc-go grpc-java grpc.github.io grpc-tools homebrew-grpc grpc-docker-library" +for repo in $repos +do + cd $tmpdir + git clone https://github.com/grpc/$repo.git + cd $repo + gource --output-custom-log $tmpdir/logs/$repo + sed -i .backup "s,\|/,\|/$repo/,g" $tmpdir/logs/$repo +done +rm $tmpdir/logs/*.backup +cat $tmpdir/logs/* | sort -n > $outdir/all-logs.txt diff --git a/tools/gource/gource.sh b/tools/gource/gource.sh index 0199609e9b2..b3dad5d7c7a 100755 --- a/tools/gource/gource.sh +++ b/tools/gource/gource.sh @@ -28,5 +28,13 @@ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -gource --multi-sampling -c 4 -s 0.1 --max-file-lag 0.05 --max-files 0 -e 0.05 --hide filenames,dirnames $* - +gource \ + --multi-sampling \ + -s 0.1 \ + --max-file-lag 0.05 \ + --max-files 0 \ + -e 0.01 \ + --hide filenames,dirnames \ + --disable-auto-rotate \ + --file-filter '/grpc/doc/ref' \ + $* diff --git a/tools/gource/make-video.sh b/tools/gource/make-video.sh new file mode 100755 index 00000000000..02d79df81bf --- /dev/null +++ b/tools/gource/make-video.sh @@ -0,0 +1,47 @@ +#!/bin/bash +# Copyright 2016, Google Inc. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are +# met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above +# copyright notice, this list of conditions and the following disclaimer +# in the documentation and/or other materials provided with the +# distribution. +# * Neither the name of Google Inc. nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +set -ex + +dst=$1 +shift +$(dirname $0)/gource.sh \ + --disable-progress \ + --stop-at-end \ + --output-ppm-stream - \ + $@ | \ +ffmpeg \ + -y \ + -r 60 \ + -f image2pipe \ + -vcodec ppm \ + -i - \ + -vcodec libx264 \ + $dst diff --git a/tools/jenkins/run_performance.sh b/tools/jenkins/run_performance.sh index 13a332751b2..99b920f6a09 100755 --- a/tools/jenkins/run_performance.sh +++ b/tools/jenkins/run_performance.sh @@ -34,4 +34,4 @@ set -ex # Enter the gRPC repo root cd $(dirname $0)/../.. -tools/run_tests/run_performance_tests.py -l c++ node ruby csharp python +tools/run_tests/run_performance_tests.py -l c++ node ruby csharp python --netperf --category smoketest diff --git a/tools/run_tests/build_package_node.sh b/tools/run_tests/build_package_node.sh index 6bc9466b633..4646072a545 100755 --- a/tools/run_tests/build_package_node.sh +++ b/tools/run_tests/build_package_node.sh @@ -55,7 +55,7 @@ npm pack cp grpc-tools-*.tgz $artifacts/ tools_version=$(npm list | grep -oP '(?<=grpc-tools@)\S+') -output_dir=$artifacts/grpc-precompiled-binaries/node/grpc-tools/$tools_version +output_dir=$artifacts/grpc-precompiled-binaries/node/grpc-tools/v$tools_version mkdir -p $output_dir for arch in {x86,x64}; do diff --git a/tools/run_tests/performance/build_performance.sh b/tools/run_tests/performance/build_performance.sh index 8cfe1c48e99..352c6797579 100755 --- a/tools/run_tests/performance/build_performance.sh +++ b/tools/run_tests/performance/build_performance.sh @@ -33,8 +33,6 @@ set -ex cd $(dirname $0)/../../.. -#TODO(jtattermusch): add support for more languages - CONFIG=${CONFIG:-opt} # build C++ qps worker & driver always - we need at least the driver to @@ -53,6 +51,9 @@ do (cd ../grpc-java/ && ./gradlew -PskipCodegen=true :grpc-benchmarks:installDist) ;; + "go") + tools/run_tests/performance/build_performance_go.sh + ;; *) tools/run_tests/run_tests.py -l $language -c $CONFIG --build_only -j 8 ;; diff --git a/tools/run_tests/performance/build_performance_go.sh b/tools/run_tests/performance/build_performance_go.sh new file mode 100755 index 00000000000..3719cc5986d --- /dev/null +++ b/tools/run_tests/performance/build_performance_go.sh @@ -0,0 +1,44 @@ +#!/bin/bash +# 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. + +set -ex + +cd $(dirname $0)/../../.. + +export GOPATH=$(pwd)/../gopath + +# Get grpc-go and the dependencies but get rid of the upstream/master version +go get google.golang.org/grpc +rm -rf "${GOPATH}/src/google.golang.org/grpc" + +# Get the revision of grpc-go we want to test +git clone --recursive ../grpc-go ${GOPATH}/src/google.golang.org/grpc + +(cd ${GOPATH}/src/google.golang.org/grpc/benchmark/worker && go install) diff --git a/tools/run_tests/performance/kill_workers.sh b/tools/run_tests/performance/kill_workers.sh index 7a8763424dc..f306f0c9912 100755 --- a/tools/run_tests/performance/kill_workers.sh +++ b/tools/run_tests/performance/kill_workers.sh @@ -52,3 +52,6 @@ ps -C python -o pid=,cmd= | grep 'qps_worker.py' | awk '{print $1}' | xargs kill # Java jps | grep LoadWorker | awk '{print $1}' | xargs kill -9 + +# Go +killall -9 worker || true diff --git a/tools/run_tests/performance/remote_host_prepare.sh b/tools/run_tests/performance/remote_host_prepare.sh index d7f539a74e8..f81102bbdc4 100755 --- a/tools/run_tests/performance/remote_host_prepare.sh +++ b/tools/run_tests/performance/remote_host_prepare.sh @@ -39,7 +39,7 @@ ssh "${USER_AT_HOST}" "rm -rf ~/performance_workspace && mkdir -p ~/performance_ # mess with the results, be rough and reboot the slave here # and wait for it to come back online. # could also kill jenkins. -ssh "${USER_AT_HOST}" "killall -9 qps_worker mono node ruby || true" +ssh "${USER_AT_HOST}" "killall -9 qps_worker mono node ruby worker || true" # push the current sources to the slave and unpack it. scp ../grpc.tar "${USER_AT_HOST}:~/performance_workspace" diff --git a/tools/run_tests/performance/run_worker_go.sh b/tools/run_tests/performance/run_worker_go.sh new file mode 100755 index 00000000000..6b1242a4197 --- /dev/null +++ b/tools/run_tests/performance/run_worker_go.sh @@ -0,0 +1,37 @@ +#!/bin/bash +# 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. + +set -ex + +cd $(dirname $0)/../../.. + +export GOPATH=$(pwd)/../gopath + +${GOPATH}/bin/worker $@ diff --git a/tools/run_tests/performance/scenario_config.py b/tools/run_tests/performance/scenario_config.py index 8f76d0a02ea..4fe66dff41d 100644 --- a/tools/run_tests/performance/scenario_config.py +++ b/tools/run_tests/performance/scenario_config.py @@ -349,39 +349,39 @@ class PythonLanguage: return 500 def scenarios(self): - # TODO(jtattermusch): this scenario reports QPS 0.0 - yield _ping_pong_scenario( - 'python_generic_async_streaming_ping_pong', rpc_type='STREAMING', - client_type='ASYNC_CLIENT', server_type='ASYNC_GENERIC_SERVER', - use_generic_payload=True, - categories=[SMOKETEST]) - - # TODO(jtattermusch): make this scenario work + # TODO(issue #6522): Empty streaming requests does not work for python #yield _ping_pong_scenario( - # 'python_protobuf_async_streaming_ping_pong', rpc_type='STREAMING', - # client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER') + # 'python_generic_async_streaming_ping_pong', rpc_type='STREAMING', + # client_type='ASYNC_CLIENT', server_type='ASYNC_GENERIC_SERVER', + # use_generic_payload=True, + # categories=[SMOKETEST]) - # TODO(jtattermusch): make this scenario work - #yield _ping_pong_scenario( - # 'python_protobuf_async_unary_ping_pong', rpc_type='UNARY', - # client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER') + yield _ping_pong_scenario( + 'python_protobuf_async_streaming_ping_pong', rpc_type='STREAMING', + client_type='ASYNC_CLIENT', server_type='SYNC_SERVER') + + yield _ping_pong_scenario( + 'python_protobuf_async_unary_ping_pong', rpc_type='UNARY', + client_type='ASYNC_CLIENT', server_type='SYNC_SERVER') yield _ping_pong_scenario( 'python_protobuf_sync_unary_ping_pong', rpc_type='UNARY', client_type='SYNC_CLIENT', server_type='SYNC_SERVER', categories=[SMOKETEST]) - # TODO(jtattermusch): make this scenario work + # TODO(jtattermusch): + # The qps_worker server gets thread starved with ~6400 threads, the GIL + # enforces that a single thread runs at a time, with no way to set thread + # priority. Re-evaluate after changing DEEP and WIDE. #yield _ping_pong_scenario( # 'python_protobuf_sync_unary_qps_unconstrained', rpc_type='UNARY', # client_type='SYNC_CLIENT', server_type='SYNC_SERVER', # use_unconstrained_client=True) - # TODO(jtattermusch): make this scenario work - #yield _ping_pong_scenario( - # 'python_protobuf_async_streaming_qps_unconstrained', rpc_type='STREAMING', - # client_type='ASYNC_CLIENT', server_type='ASYNC_SERVER', - # use_unconstrained_client=True) + yield _ping_pong_scenario( + 'python_protobuf_async_streaming_qps_unconstrained', rpc_type='STREAMING', + client_type='ASYNC_CLIENT', server_type='SYNC_SERVER', + use_unconstrained_client=True) yield _ping_pong_scenario( 'python_to_cpp_protobuf_sync_unary_ping_pong', rpc_type='UNARY', @@ -389,11 +389,10 @@ class PythonLanguage: server_language='c++', server_core_limit=1, async_server_threads=1, categories=[SMOKETEST]) - # TODO(jtattermusch): make this scenario work - #yield _ping_pong_scenario( - # 'python_to_cpp_protobuf_sync_streaming_ping_pong', rpc_type='STREAMING', - # client_type='SYNC_CLIENT', server_type='SYNC_SERVER', - # server_language='c++', server_core_limit=1, async_server_threads=1) + yield _ping_pong_scenario( + 'python_to_cpp_protobuf_sync_streaming_ping_pong', rpc_type='STREAMING', + client_type='SYNC_CLIENT', server_type='SYNC_SERVER', + server_language='c++', server_core_limit=1, async_server_threads=1) def __str__(self): return 'python' @@ -522,6 +521,72 @@ class JavaLanguage: return 'java' +class GoLanguage: + + def __init__(self): + pass + self.safename = str(self) + + def worker_cmdline(self): + return ['tools/run_tests/performance/run_worker_go.sh'] + + def worker_port_offset(self): + return 600 + + def scenarios(self): + for secure in [True, False]: + secstr = 'secure' if secure else 'insecure' + smoketest_categories = [SMOKETEST] if secure else None + + # ASYNC_GENERIC_SERVER for Go actually uses a sync streaming server, + # but that's mostly because of lack of better name of the enum value. + yield _ping_pong_scenario( + 'go_generic_sync_streaming_ping_pong_%s' % secstr, rpc_type='STREAMING', + client_type='SYNC_CLIENT', server_type='ASYNC_GENERIC_SERVER', + use_generic_payload=True, async_server_threads=1, + secure=secure, + categories=smoketest_categories) + + yield _ping_pong_scenario( + 'go_protobuf_sync_streaming_ping_pong_%s' % secstr, rpc_type='STREAMING', + client_type='SYNC_CLIENT', server_type='SYNC_SERVER', + async_server_threads=1, + secure=secure) + + yield _ping_pong_scenario( + 'go_protobuf_sync_unary_ping_pong_%s' % secstr, rpc_type='UNARY', + client_type='SYNC_CLIENT', server_type='SYNC_SERVER', + async_server_threads=1, + secure=secure, + categories=smoketest_categories) + + yield _ping_pong_scenario( + 'go_protobuf_sync_unary_qps_unconstrained_%s' % secstr, rpc_type='UNARY', + client_type='SYNC_CLIENT', server_type='SYNC_SERVER', + use_unconstrained_client=True, + secure=secure, + categories=smoketest_categories) + + yield _ping_pong_scenario( + 'go_protobuf_sync_streaming_qps_unconstrained_%s' % secstr, rpc_type='STREAMING', + client_type='SYNC_CLIENT', server_type='SYNC_SERVER', + use_unconstrained_client=True, + secure=secure) + + # ASYNC_GENERIC_SERVER for Go actually uses a sync streaming server, + # but that's mostly because of lack of better name of the enum value. + yield _ping_pong_scenario( + 'go_generic_sync_streaming_qps_unconstrained_%s' % secstr, rpc_type='STREAMING', + client_type='SYNC_CLIENT', server_type='ASYNC_GENERIC_SERVER', + use_unconstrained_client=True, use_generic_payload=True, + secure=secure) + + # TODO(jtattermusch): add scenarios go vs C++ + + def __str__(self): + return 'go' + + LANGUAGES = { 'c++' : CXXLanguage(), 'csharp' : CSharpLanguage(), @@ -529,4 +594,5 @@ LANGUAGES = { 'ruby' : RubyLanguage(), 'java' : JavaLanguage(), 'python' : PythonLanguage(), + 'go' : GoLanguage(), } diff --git a/tools/run_tests/run_performance_tests.py b/tools/run_tests/run_performance_tests.py index 674d8645396..a7728e7f7d5 100755 --- a/tools/run_tests/run_performance_tests.py +++ b/tools/run_tests/run_performance_tests.py @@ -137,6 +137,17 @@ def create_netperf_jobspec(server_host='localhost', client_host=None, cmd = 'NETPERF_SERVER_HOST="%s" ' % server_host if bq_result_table: cmd += 'BQ_RESULT_TABLE="%s" ' % bq_result_table + if client_host: + # If netperf is running remotely, the env variables populated by Jenkins + # won't be available on the client, but we need them for uploading results + # to BigQuery. + jenkins_job_name = os.getenv('JOB_NAME') + if jenkins_job_name: + cmd += 'JOB_NAME="%s" ' % jenkins_job_name + jenkins_build_number = os.getenv('BUILD_NUMBER') + if jenkins_build_number: + cmd += 'BUILD_NUMBER="%s" ' % jenkins_build_number + cmd += 'tools/run_tests/performance/run_netperf.sh' if client_host: user_at_host = '%s@%s' % (_REMOTE_HOST_USERNAME, client_host) diff --git a/tools/run_tests/sanity/check_submodules.sh b/tools/run_tests/sanity/check_submodules.sh index 3349d28cf9e..3b8d81b18fe 100755 --- a/tools/run_tests/sanity/check_submodules.sh +++ b/tools/run_tests/sanity/check_submodules.sh @@ -45,7 +45,7 @@ cat << EOF | awk '{ print $1 }' | sort > $want_submodules 05b155ff59114735ec8cd089f669c4c3d8f59029 third_party/gflags (v2.1.0-45-g05b155f) c99458533a9b4c743ed51537e25989ea55944908 third_party/googletest (release-1.7.0) f8ac463766281625ad710900479130c7fcb4d63b third_party/nanopb (nanopb-0.3.4-29-gf8ac463) - d5fb408ddc281ffcadeb08699e65bb694656d0bd third_party/protobuf (v3.0.0-beta-2) + a1938b2aa9ca86ce7ce50c27ff9737c1008d2a03 third_party/protobuf (v3.0.0-beta-3-pre1) 50893291621658f355bc5b4d450a8d06a563053d third_party/zlib (v1.2.8) EOF diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index 8b1aa574e85..b36f0a8ca8e 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -2588,6 +2588,24 @@ "third_party": false, "type": "target" }, + { + "deps": [ + "gpr", + "gpr_test_util", + "grpc", + "grpc++", + "grpc++_test_util", + "grpc_test_util" + ], + "headers": [], + "language": "c++", + "name": "server_builder_plugin_test", + "src": [ + "test/cpp/end2end/server_builder_plugin_test.cc" + ], + "third_party": false, + "type": "target" + }, { "deps": [ "gpr", @@ -6345,6 +6363,8 @@ "include/grpc++/impl/rpc_service_method.h", "include/grpc++/impl/serialization_traits.h", "include/grpc++/impl/server_builder_option.h", + "include/grpc++/impl/server_builder_plugin.h", + "include/grpc++/impl/server_initializer.h", "include/grpc++/impl/service_type.h", "include/grpc++/impl/sync.h", "include/grpc++/impl/sync_cxx11.h", @@ -6395,6 +6415,8 @@ "include/grpc++/impl/rpc_service_method.h", "include/grpc++/impl/serialization_traits.h", "include/grpc++/impl/server_builder_option.h", + "include/grpc++/impl/server_builder_plugin.h", + "include/grpc++/impl/server_initializer.h", "include/grpc++/impl/service_type.h", "include/grpc++/impl/sync.h", "include/grpc++/impl/sync_cxx11.h", diff --git a/tools/run_tests/tests.json b/tools/run_tests/tests.json index f1d302f2ef2..581b8fd0e71 100644 --- a/tools/run_tests/tests.json +++ b/tools/run_tests/tests.json @@ -2448,6 +2448,27 @@ "posix" ] }, + { + "args": [], + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "cpu_cost": 1.0, + "exclude_configs": [], + "flaky": false, + "gtest": true, + "language": "c++", + "name": "server_builder_plugin_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ] + }, { "args": [], "ci_platforms": [ diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj b/vsprojects/vcxproj/grpc++/grpc++.vcxproj index 0ec53acf655..65de5e97175 100644 --- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj +++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj @@ -275,6 +275,8 @@ + + diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters index 491aeaeb678..ce50bd9de8d 100644 --- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters +++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters @@ -147,6 +147,12 @@ include\grpc++\impl + + include\grpc++\impl + + + include\grpc++\impl + include\grpc++\impl diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj index 96bee4101c8..895e2233518 100644 --- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj +++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj @@ -275,6 +275,8 @@ + + diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters index fe9eed781c7..ab305fa9297 100644 --- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters +++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters @@ -132,6 +132,12 @@ include\grpc++\impl + + include\grpc++\impl + + + include\grpc++\impl + include\grpc++\impl diff --git a/vsprojects/vcxproj/test/server_builder_plugin_test/server_builder_plugin_test.vcxproj b/vsprojects/vcxproj/test/server_builder_plugin_test/server_builder_plugin_test.vcxproj new file mode 100644 index 00000000000..0ebdd988172 --- /dev/null +++ b/vsprojects/vcxproj/test/server_builder_plugin_test/server_builder_plugin_test.vcxproj @@ -0,0 +1,207 @@ + + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {86751DC8-C8D9-57B6-2C8A-BB33021C773C} + true + $(SolutionDir)IntDir\$(MSBuildProjectName)\ + + + + v100 + + + v110 + + + v120 + + + v140 + + + Application + true + Unicode + + + Application + false + true + Unicode + + + + + + + + + + + + + + + + server_builder_plugin_test + static + Debug + static + Debug + + + server_builder_plugin_test + static + Release + static + Release + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + None + false + + + Console + true + false + + + + + + NotUsing + Level3 + Disabled + WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions) + true + MultiThreadedDebug + true + None + false + + + Console + true + false + + + + + + NotUsing + Level3 + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + true + MultiThreaded + true + None + false + + + Console + true + false + true + true + + + + + + NotUsing + Level3 + MaxSpeed + WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions) + true + true + true + MultiThreaded + true + None + false + + + Console + true + false + true + true + + + + + + + + + + {0BE77741-552A-929B-A497-4EF7ECE17A64} + + + {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} + + + {C187A093-A0FE-489D-A40A-6E33DE0F9FEB} + + + {29D16885-7228-4C31-81ED-5F9187C7F2A9} + + + {EAB0A629-17A9-44DB-B5FF-E91A721FE037} + + + {B23D3D1A-9438-4EDA-BEB6-9A0A03D17792} + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Enable NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + + + + + diff --git a/vsprojects/vcxproj/test/server_builder_plugin_test/server_builder_plugin_test.vcxproj.filters b/vsprojects/vcxproj/test/server_builder_plugin_test/server_builder_plugin_test.vcxproj.filters new file mode 100644 index 00000000000..629b913fc6e --- /dev/null +++ b/vsprojects/vcxproj/test/server_builder_plugin_test/server_builder_plugin_test.vcxproj.filters @@ -0,0 +1,21 @@ + + + + + test\cpp\end2end + + + + + + {37b2ebc1-b2f2-ecb9-37b7-f6d757bb99e3} + + + {39400fed-f7b7-0f44-0ef3-ba3693d42011} + + + {dab9dd19-3e5b-005e-4b5a-456de6111d71} + + + +