diff --git a/BUILD b/BUILD index ad6903d68479e9494209556256702de9f1b61247..1ca357896a7da2154462c653e233be089c7c60df 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 1ff2cb67c5525dc21cc0bff0676a75c5eff4bcab..f0a0ebd3eb6ca31471dbef1f4e614d735cc60df9 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 b2cbd4d890f7d8dcd8afd56a6573cffca7823572..187eb9ca8c6cd0d4e35cf118433f3b6928d92a4f 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 ad74efabc4ba1f595ec2d9c2ca44ab10188afcbe..21ac6c4fb5545c7c3b73b2291ca9272d182a37b2 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 ServiceType, class RequestType, class ResponseType> class RpcMethodHandler : public MethodHandler { public: - RpcMethodHandler( - std::function<Status(ServiceType*, ServerContext*, const RequestType*, - ResponseType*)> func, - ServiceType* service) + RpcMethodHandler(std::function<Status(ServiceType*, ServerContext*, + const RequestType*, ResponseType*)> + 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<Status(ServiceType*, ServerContext*, - ServerReader<RequestType>*, ResponseType*)> func, + ServerReader<RequestType>*, ResponseType*)> + func, ServiceType* service) : func_(func), service_(service) {} @@ -124,7 +125,8 @@ class ServerStreamingHandler : public MethodHandler { public: ServerStreamingHandler( std::function<Status(ServiceType*, ServerContext*, const RequestType*, - ServerWriter<ResponseType>*)> func, + ServerWriter<ResponseType>*)> + 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 bcb19824fdf462acd9716ae8fe8b4886f4652589..2b7e89f5e5def483c611f8766f35540719fc833e 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 <map> +#include <memory> + +#include <grpc++/impl/server_builder_plugin.h> #include <grpc++/support/channel_arguments.h> 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<grpc::string, std::unique_ptr<ServerBuilderPlugin> >* + 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 0000000000000000000000000000000000000000..1e157efa1119791e0b148fa321d644dad5e8cc05 --- /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 <memory> + +#include <grpc++/support/config.h> + +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 0000000000000000000000000000000000000000..dbcecc7026c1a64fd2c6f155919cae4d98526fbf --- /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 <memory> +#include <vector> + +#include <grpc++/server.h> + +namespace grpc { + +class Server; +class Service; + +class ServerInitializer { + public: + ServerInitializer(Server* server) : server_(server) {} + + bool RegisterService(std::shared_ptr<Service> service) { + if (!server_->RegisterService(nullptr, service.get())) { + return false; + } + default_services_.push_back(service); + return true; + } + + const std::vector<grpc::string>* GetServiceList() { + return &server_->services_; + } + + private: + Server* server_; + std::vector<std::shared_ptr<Service> > default_services_; +}; + +} // namespace grpc + +#endif // GRPCXX_IMPL_SERVER_INITIALIZER_H diff --git a/include/grpc++/server.h b/include/grpc++/server.h index 729a5143bf8b3fd83bcdf481c192860583844cd2..a0ee0e98e47dcd4fe7c291726b2d88a860296f64 100644 --- a/include/grpc++/server.h +++ b/include/grpc++/server.h @@ -36,6 +36,7 @@ #include <list> #include <memory> +#include <vector> #include <grpc++/completion_queue.h> #include <grpc++/impl/call.h> @@ -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<GlobalCallbacks> global_callbacks_; std::list<SyncRequest>* sync_methods_; + std::vector<grpc::string> services_; std::unique_ptr<RpcServiceMethod> 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<ServerInitializer> server_initializer_; }; } // namespace grpc diff --git a/include/grpc++/server_builder.h b/include/grpc++/server_builder.h index 86c7fecef59f53e3bd2e3fcdc449ee25401adf15..ad629521cbe415e5a8e7b0f0f24d8f6aa72f2158 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 <map> #include <memory> #include <vector> #include <grpc++/impl/server_builder_option.h> +#include <grpc++/impl/server_builder_plugin.h> #include <grpc++/support/config.h> #include <grpc/compression.h> @@ -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<Server> BuildAndStart(); + /// For internal use only: Register a ServerBuilderPlugin factory function. + static void InternalAddPluginFactory( + std::unique_ptr<ServerBuilderPlugin> (*CreatePlugin)()); + private: + friend class ::grpc::testing::ServerBuilderPluginTest; + struct Port { grpc::string addr; std::shared_ptr<ServerCredentials> creds; @@ -130,6 +142,7 @@ class ServerBuilder { std::vector<Port> ports_; std::vector<ServerCompletionQueue*> cqs_; std::shared_ptr<ServerCredentials> creds_; + std::map<grpc::string, std::unique_ptr<ServerBuilderPlugin>> plugins_; AsyncGenericService* generic_service_; }; diff --git a/package.json b/package.json index 54a44ca5513bf0e2571d3771bbf9aa86109a14ff..5bdaa761e28adac5ca5f0d45b414faf2ef29ee61 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 fafe31e84c111c250408baed612504cd5836b4ed..f955a314944c6a761d3b893b4e07d8e1fb937883 100644 --- a/src/cpp/server/server.cc +++ b/src/cpp/server/server.cc @@ -33,6 +33,7 @@ #include <grpc++/server.h> +#include <sstream> #include <utility> #include <grpc++/completion_queue.h> @@ -41,6 +42,7 @@ #include <grpc++/impl/grpc_library.h> #include <grpc++/impl/method_handler_impl.h> #include <grpc++/impl/rpc_service_method.h> +#include <grpc++/impl/server_initializer.h> #include <grpc++/impl/service_type.h> #include <grpc++/security/server_credentials.h> #include <grpc++/server_context.h> @@ -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 68cc38258cf91a376020eb8b95685ab07464e6d3..9658a567455ae4384223518b97a2b9f1ba114a89 100644 --- a/src/cpp/server/server_builder.cc +++ b/src/cpp/server/server_builder.cc @@ -41,9 +41,23 @@ namespace grpc { +static std::vector<std::unique_ptr<ServerBuilderPlugin> (*)()>* + 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<std::unique_ptr<ServerBuilderPlugin> (*)()>(); +} + 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<ServerBuilderPlugin> plugin = factory(); + plugins_[plugin->name()] = std::move(plugin); + } } std::unique_ptr<ServerCompletionQueue> ServerBuilder::AddCompletionQueue() { @@ -96,6 +110,15 @@ std::unique_ptr<Server> 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<Server> ServerBuilder::BuildAndStart() { compression_options_.enabled_algorithms_bitset); std::unique_ptr<Server> 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<Server> 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<Server> 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<ServerBuilderPlugin> (*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 875202b9509192833096c524d3aee42cf37340db..ee11105efe7f8018f4003a21e63a92b3cf9888f2 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<RpcException>(() => 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 6075420974889cd4cf26e08cb8c088a8e6ff5d12..d260830b94d1229710e467c36c697023b1760539 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); } + + /// <summary> + /// Shows how to handle a call ending with non-OK status. + /// </summary> + 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)); + } + } + + /// <summary> + /// Shows how to send request headers and how to access response headers + /// and response trailers. + /// </summary> + 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 79c56e57a85a220cb6d833f552134f361e2ab6d9..a28020f62f31b172f6130eb599361a03ed3bfec5 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<Num> responseStream, ServerCallContext context) { - if (request.Limit <= 0) - { - // keep streaming the sequence until cancelled. - IEnumerator<Num> 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 8db691cb048b1767542d18318c0705af4e414c25..4d6ca7ece57834a32ce62638b4e943402681eb83 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 4d50c94b0f85081a6729e01e7cb749cf8082e393..53fc5dc428025e4e5136d87730b6142c873d5907 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 281ec0d85e56f9bff88ce6bb314e341ed9583a5a..857882e1c346396b18b5f788b501fb2672fd969f 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 1be1966f101486b5f57b3cddac87a31cea9a63d4..b405acf043123999a5381a999ba5304268860010 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 eed0b0c6dac616137c1617965d657b8fee054751..b372ea01ade53c26706a366c8cf12bf10d0ad6f5 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 a36c30ccc0a8a5862b42e5ef3238407955c8cdde..1ede7d2af1b67428facb05dce41010d03beade3c 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 0b3acc14e7de785b7ee7ca70752f56e57a672a64..1f9af5482ccc451fbc456656f02f4502d9293586 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 68e167a69fcc08368a429661b5b6e96f91d00391..12946fe819b662aa63f1b30c865c4a74ec2610bb 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 af904de4a91006ef68832eea54e5df324c6683fd..9fa4b66392d9d78c3f4113c3b4295e6208680b2c 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 11718b1ccbd407e2b86229b1496fa189c248a276..9d19ca062934f07f4866ce06bcc51b7b19b8a41b 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 0232a9fa3171cf073d6c19122dad7a35c500461c..e0649bd694864c1d850bd3f5ebd55a4f7968534e 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<grpc::string, std::unique_ptr<ServerBuilderPlugin>>* 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<TestScenario> { 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<ServerBuilderOption> 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 0c9313f88f0d7e8ef09ade3ee458de00058d85e4..e3408bff75eda5d32b5ceaf8d69cee69ea6d859c 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 0000000000000000000000000000000000000000..87e3709d7d272bbf562af639adebf4a960f4207a --- /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 <grpc++/channel.h> +#include <grpc++/client_context.h> +#include <grpc++/create_channel.h> +#include <grpc++/impl/server_builder_option.h> +#include <grpc++/impl/server_builder_plugin.h> +#include <grpc++/impl/server_initializer.h> +#include <grpc++/security/credentials.h> +#include <grpc++/security/server_credentials.h> +#include <grpc++/server.h> +#include <grpc++/server_builder.h> +#include <grpc++/server_context.h> +#include <grpc/grpc.h> +#include <gtest/gtest.h> + +#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<TestServiceImpl> service_; +}; + +class InsertPluginServerBuilderOption : public ServerBuilderOption { + public: + InsertPluginServerBuilderOption() { register_service_ = false; } + + void UpdateArguments(ChannelArguments* arg) GRPC_OVERRIDE {} + + void UpdatePlugins( + std::map<grpc::string, std::unique_ptr<ServerBuilderPlugin>>* plugins) + GRPC_OVERRIDE { + plugins->clear(); + + std::unique_ptr<TestServerBuilderPlugin> 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<ServerBuilderPlugin> CreateTestServerBuilderPlugin() { + return std::unique_ptr<ServerBuilderPlugin>(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<bool> { + 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<ServerBuilderOption>( + new InsertPluginServerBuilderOption())); + } + } + + void InsertPluginWithTestService() { + if (GetParam()) { + // Add ServerBuilder plugin in static initialization + EXPECT_TRUE(builder_->plugins_[PLUGIN_NAME] != nullptr); + auto plugin = static_cast<TestServerBuilderPlugin*>( + builder_->plugins_[PLUGIN_NAME].get()); + EXPECT_TRUE(plugin != nullptr); + plugin->SetRegisterService(); + } else { + // Add ServerBuilder plugin using ServerBuilder::SetOption() + std::unique_ptr<InsertPluginServerBuilderOption> 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<TestServerBuilderPlugin*>( + 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> channel_; + std::unique_ptr<ServerBuilder> builder_; + std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_; + std::unique_ptr<Server> 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 2f5dd6d49e8602eed8fb6c8f3d0559dc900eb9a4..cbaee922289f91faab0ab29d36502ccc3306ece9 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 1ab6ced9e00c23de2feb966a6f714b28bc809bc6..c89f88c900edadf8679856fd33ab447a198b071f 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 e72cef28114d5b2dd1799612b22313a6a50d5f59..c32160a7d4552fd907bfb4f21986234abf1bf613 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<grpc::ClientAsyncResponseReader<ResponseType>>( BenchmarkService::Stub*, grpc::ClientContext*, const RequestType&, - CompletionQueue*)> start_req, + CompletionQueue*)> + start_req, std::function<void(grpc::Status, ResponseType*)> on_done) : context_(), stub_(stub), @@ -165,7 +166,8 @@ class AsyncClient : public ClientImpl<StubType, RequestType> { AsyncClient(const ClientConfig& config, std::function<ClientRpcContext*( StubType*, std::function<gpr_timespec()> next_issue, - const RequestType&)> setup_ctx, + const RequestType&)> + setup_ctx, std::function<std::unique_ptr<StubType>(std::shared_ptr<Channel>)> create_stub) : ClientImpl<StubType, RequestType>(config, create_stub), @@ -278,7 +280,8 @@ class ClientRpcContextStreamingImpl : public ClientRpcContext { std::function<std::unique_ptr< grpc::ClientAsyncReaderWriter<RequestType, ResponseType>>( BenchmarkService::Stub*, grpc::ClientContext*, CompletionQueue*, - void*)> start_req, + void*)> + start_req, std::function<void(grpc::Status, ResponseType*)> on_done) : context_(), stub_(stub), @@ -405,7 +408,8 @@ class ClientRpcContextGenericStreamingImpl : public ClientRpcContext { std::function<gpr_timespec()> next_issue, std::function<std::unique_ptr<grpc::GenericClientAsyncReaderWriter>( grpc::GenericStub*, grpc::ClientContext*, - const grpc::string& method_name, CompletionQueue*, void*)> start_req, + const grpc::string& method_name, CompletionQueue*, void*)> + start_req, std::function<void(grpc::Status, ByteBuffer*)> on_done) : context_(), stub_(stub), diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc index a68f1ae7b672086d366d9af5182b210bb9335128..1234542687dd00ac8f650a87e47ec73752ee51c7 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<grpc::Status(const PayloadConfig &, const RequestType *, - ResponseType *)> process_rpc) + ResponseType *)> + process_rpc) : Server(config) { char *server_address = NULL; @@ -190,7 +191,8 @@ class AsyncQpsServerTest : public Server { ServerRpcContextUnaryImpl( std::function<void(ServerContextType *, RequestType *, grpc::ServerAsyncResponseWriter<ResponseType> *, - void *)> request_method, + void *)> + request_method, std::function<grpc::Status(const RequestType *, ResponseType *)> invoke_method) : srv_ctx_(new ServerContextType), diff --git a/third_party/protobuf b/third_party/protobuf index d5fb408ddc281ffcadeb08699e65bb694656d0bd..a1938b2aa9ca86ce7ce50c27ff9737c1008d2a03 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 9f31172170d1fe83b8684f2781dd565ae511f59e..135ac5cbb3bfce3855c54a6ac831d1d0c721270f 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 2a319db979639acaf9222fa326768ec865cfdc38..798d68b0181e8488e903ec3e208e059219d5c131 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 5fdfafbf3ed89faece768037702956b49bf44521..ce1d6ac3c1b61922386279d1dff5242f56815272 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 0000000000000000000000000000000000000000..387407bfec5d8e4d106940e5642e46d976df2258 --- /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 <memory> + +#include <grpc++/security/auth_context.h> +#include <grpc/grpc.h> + +namespace grpc { + +std::shared_ptr<const AuthContext> 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 0000000000000000000000000000000000000000..85352c514e92c8c6f6caef5bdc07c112fafb84c9 --- /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 0199609e9b2ce88ae4cef357d8cc54af3c078524..b3dad5d7c7a42e01b0bd45065e22a96c56d74351 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 0000000000000000000000000000000000000000..02d79df81bf66e777b9fb0456e7190224ce6b013 --- /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 13a332751b22bd5b0f532282ee5213d9dbb50d44..99b920f6a095ba772a20eb2ac430170d25a26131 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 6bc9466b6337c604727c131950ff47fc49cfb329..4646072a545aa59529078a47f9deb0e97176bc83 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 8cfe1c48e99e0ee9f3edbbaf5c09192444c7f096..352c6797579c543faafef77dc784c4cb7a4a2893 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 0000000000000000000000000000000000000000..3719cc5986dc9cb24b6b718232e5a79f67e496ec --- /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 7a8763424dcf3dede31d277e8f8210bdc6af19c1..f306f0c991225e181c78dd3fb2aa008c1dff1bea 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 d7f539a74e8e50d2483139f25e81e3607b48312c..f81102bbdc4facf2962cc62f161bd874cf589256 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 0000000000000000000000000000000000000000..6b1242a41977bb419698df45d9371e4eb21884c0 --- /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 8f76d0a02ea1bc67291691f129854298b4f131a0..4fe66dff41d391be0aad2ee94c03e04c641c39f4 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 674d8645396b0b76adcca5b0f6611b2d979847f6..a7728e7f7d53aac8a424929cc678a57f0f4c89a9 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 3349d28cf9e71cf2b63f001062439d983c2e3b8f..3b8d81b18fe552247178ba5509f847162a85d478 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 8b1aa574e853dc4a10cc203bb63152fb3838231f..b36f0a8ca8ef2c8a62ed1ea6d3fe3bcd4d247d05 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 f1d302f2ef22061612494407faf6077aed03e28b..581b8fd0e7122689dafd646b4ba5cd33b47af346 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 0ec53acf6553571a33024e0987ae3d144ba035eb..65de5e97175a0ab7438bcdcd9fc0c1be57277460 100644 --- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj +++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj @@ -275,6 +275,8 @@ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\rpc_service_method.h" /> <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\serialization_traits.h" /> <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\server_builder_option.h" /> + <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\server_builder_plugin.h" /> + <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\server_initializer.h" /> <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\service_type.h" /> <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\sync.h" /> <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\sync_cxx11.h" /> diff --git a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters index 491aeaeb6786bc328d6b5690610177f79de5c436..ce50bd9de8d865b98195552446859142e4a1d072 100644 --- a/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters +++ b/vsprojects/vcxproj/grpc++/grpc++.vcxproj.filters @@ -147,6 +147,12 @@ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\server_builder_option.h"> <Filter>include\grpc++\impl</Filter> </ClInclude> + <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\server_builder_plugin.h"> + <Filter>include\grpc++\impl</Filter> + </ClInclude> + <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\server_initializer.h"> + <Filter>include\grpc++\impl</Filter> + </ClInclude> <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\service_type.h"> <Filter>include\grpc++\impl</Filter> </ClInclude> diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj index 96bee4101c8cededd99a59264734456567b06d06..895e2233518faa18e5811004f0f4a1c4f9277e7d 100644 --- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj +++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj @@ -275,6 +275,8 @@ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\rpc_service_method.h" /> <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\serialization_traits.h" /> <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\server_builder_option.h" /> + <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\server_builder_plugin.h" /> + <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\server_initializer.h" /> <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\service_type.h" /> <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\sync.h" /> <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\sync_cxx11.h" /> diff --git a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters index fe9eed781c7cfdeb48b2ef04b135844fa7ad888d..ab305fa92972d5fc2df02c4dc4734db575fae846 100644 --- a/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters +++ b/vsprojects/vcxproj/grpc++_unsecure/grpc++_unsecure.vcxproj.filters @@ -132,6 +132,12 @@ <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\server_builder_option.h"> <Filter>include\grpc++\impl</Filter> </ClInclude> + <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\server_builder_plugin.h"> + <Filter>include\grpc++\impl</Filter> + </ClInclude> + <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\server_initializer.h"> + <Filter>include\grpc++\impl</Filter> + </ClInclude> <ClInclude Include="$(SolutionDir)\..\include\grpc++\impl\service_type.h"> <Filter>include\grpc++\impl</Filter> </ClInclude> 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 0000000000000000000000000000000000000000..0ebdd988172735901437fffe326efcedf140d07a --- /dev/null +++ b/vsprojects/vcxproj/test/server_builder_plugin_test/server_builder_plugin_test.vcxproj @@ -0,0 +1,207 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\1.0.204.1.props')" /> + <ItemGroup Label="ProjectConfigurations"> + <ProjectConfiguration Include="Debug|Win32"> + <Configuration>Debug</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Debug|x64"> + <Configuration>Debug</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|Win32"> + <Configuration>Release</Configuration> + <Platform>Win32</Platform> + </ProjectConfiguration> + <ProjectConfiguration Include="Release|x64"> + <Configuration>Release</Configuration> + <Platform>x64</Platform> + </ProjectConfiguration> + </ItemGroup> + <PropertyGroup Label="Globals"> + <ProjectGuid>{86751DC8-C8D9-57B6-2C8A-BB33021C773C}</ProjectGuid> + <IgnoreWarnIntDirInTempDetected>true</IgnoreWarnIntDirInTempDetected> + <IntDir>$(SolutionDir)IntDir\$(MSBuildProjectName)\</IntDir> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> + <PropertyGroup Condition="'$(VisualStudioVersion)' == '10.0'" Label="Configuration"> + <PlatformToolset>v100</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(VisualStudioVersion)' == '11.0'" Label="Configuration"> + <PlatformToolset>v110</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(VisualStudioVersion)' == '12.0'" Label="Configuration"> + <PlatformToolset>v120</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(VisualStudioVersion)' == '14.0'" Label="Configuration"> + <PlatformToolset>v140</PlatformToolset> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>true</UseDebugLibraries> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration"> + <ConfigurationType>Application</ConfigurationType> + <UseDebugLibraries>false</UseDebugLibraries> + <WholeProgramOptimization>true</WholeProgramOptimization> + <CharacterSet>Unicode</CharacterSet> + </PropertyGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> + <ImportGroup Label="ExtensionSettings"> + </ImportGroup> + <ImportGroup Label="PropertySheets"> + <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> + <Import Project="$(SolutionDir)\..\vsprojects\cpptest.props" /> + <Import Project="$(SolutionDir)\..\vsprojects\global.props" /> + <Import Project="$(SolutionDir)\..\vsprojects\openssl.props" /> + <Import Project="$(SolutionDir)\..\vsprojects\protobuf.props" /> + <Import Project="$(SolutionDir)\..\vsprojects\winsock.props" /> + <Import Project="$(SolutionDir)\..\vsprojects\zlib.props" /> + </ImportGroup> + <PropertyGroup Label="UserMacros" /> + <PropertyGroup Condition="'$(Configuration)'=='Debug'"> + <TargetName>server_builder_plugin_test</TargetName> + <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib> + <Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib> + <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl> + <Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl> + </PropertyGroup> + <PropertyGroup Condition="'$(Configuration)'=='Release'"> + <TargetName>server_builder_plugin_test</TargetName> + <Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib> + <Configuration-grpc_dependencies_zlib>Release</Configuration-grpc_dependencies_zlib> + <Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl> + <Configuration-grpc_dependencies_openssl>Release</Configuration-grpc_dependencies_openssl> + </PropertyGroup> + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <TreatWarningAsError>true</TreatWarningAsError> + <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat> + <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation> + <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>Disabled</Optimization> + <PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <SDLCheck>true</SDLCheck> + <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary> + <TreatWarningAsError>true</TreatWarningAsError> + <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat> + <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation> + <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation> + </Link> + </ItemDefinitionGroup> + + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <TreatWarningAsError>true</TreatWarningAsError> + <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat> + <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation> + <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + + <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> + <ClCompile> + <PrecompiledHeader>NotUsing</PrecompiledHeader> + <WarningLevel>Level3</WarningLevel> + <Optimization>MaxSpeed</Optimization> + <PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <FunctionLevelLinking>true</FunctionLevelLinking> + <IntrinsicFunctions>true</IntrinsicFunctions> + <SDLCheck>true</SDLCheck> + <RuntimeLibrary>MultiThreaded</RuntimeLibrary> + <TreatWarningAsError>true</TreatWarningAsError> + <DebugInformationFormat Condition="$(Jenkins)">None</DebugInformationFormat> + <MinimalRebuild Condition="$(Jenkins)">false</MinimalRebuild> + </ClCompile> + <Link> + <SubSystem>Console</SubSystem> + <GenerateDebugInformation Condition="!$(Jenkins)">true</GenerateDebugInformation> + <GenerateDebugInformation Condition="$(Jenkins)">false</GenerateDebugInformation> + <EnableCOMDATFolding>true</EnableCOMDATFolding> + <OptimizeReferences>true</OptimizeReferences> + </Link> + </ItemDefinitionGroup> + + <ItemGroup> + <ClCompile Include="$(SolutionDir)\..\test\cpp\end2end\server_builder_plugin_test.cc"> + </ClCompile> + </ItemGroup> + <ItemGroup> + <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++_test_util\grpc++_test_util.vcxproj"> + <Project>{0BE77741-552A-929B-A497-4EF7ECE17A64}</Project> + </ProjectReference> + <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc_test_util\grpc_test_util.vcxproj"> + <Project>{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}</Project> + </ProjectReference> + <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc++\grpc++.vcxproj"> + <Project>{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}</Project> + </ProjectReference> + <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\grpc\grpc.vcxproj"> + <Project>{29D16885-7228-4C31-81ED-5F9187C7F2A9}</Project> + </ProjectReference> + <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr_test_util\gpr_test_util.vcxproj"> + <Project>{EAB0A629-17A9-44DB-B5FF-E91A721FE037}</Project> + </ProjectReference> + <ProjectReference Include="$(SolutionDir)\..\vsprojects\vcxproj\.\gpr\gpr.vcxproj"> + <Project>{B23D3D1A-9438-4EDA-BEB6-9A0A03D17792}</Project> + </ProjectReference> + </ItemGroup> + <ItemGroup> + <None Include="packages.config" /> + </ItemGroup> + <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> + <ImportGroup Label="ExtensionTargets"> + <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" /> + <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies\grpc.dependencies.zlib.targets')" /> + <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" /> + <Import Project="$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets" Condition="Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies\grpc.dependencies.openssl.targets')" /> + </ImportGroup> + <Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild"> + <PropertyGroup> + <ErrorText>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}.</ErrorText> + </PropertyGroup> + <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.redist.1.2.8.10\build\native\grpc.dependencies.zlib.redist.targets')" /> + <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.zlib.1.2.8.10\build\native\grpc.dependencies.zlib.targets')" /> + <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.redist.1.0.204.1\build\native\grpc.dependencies.openssl.redist.targets')" /> + <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.props')" /> + <Error Condition="!Exists('$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\..\vsprojects\packages\grpc.dependencies.openssl.1.0.204.1\build\native\grpc.dependencies.openssl.targets')" /> + </Target> +</Project> + 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 0000000000000000000000000000000000000000..629b913fc6e48d4cba6f88da362a94454b1fb686 --- /dev/null +++ b/vsprojects/vcxproj/test/server_builder_plugin_test/server_builder_plugin_test.vcxproj.filters @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <ItemGroup> + <ClCompile Include="$(SolutionDir)\..\test\cpp\end2end\server_builder_plugin_test.cc"> + <Filter>test\cpp\end2end</Filter> + </ClCompile> + </ItemGroup> + + <ItemGroup> + <Filter Include="test"> + <UniqueIdentifier>{37b2ebc1-b2f2-ecb9-37b7-f6d757bb99e3}</UniqueIdentifier> + </Filter> + <Filter Include="test\cpp"> + <UniqueIdentifier>{39400fed-f7b7-0f44-0ef3-ba3693d42011}</UniqueIdentifier> + </Filter> + <Filter Include="test\cpp\end2end"> + <UniqueIdentifier>{dab9dd19-3e5b-005e-4b5a-456de6111d71}</UniqueIdentifier> + </Filter> + </ItemGroup> +</Project> +