From 47c83fdaf71ca5072d0ab37322b37586d23f5ceb Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Sat, 21 Feb 2015 22:45:35 -0800 Subject: [PATCH 001/120] Credentials prototyping - Remove CredentialsFactory as it's unnecessary - Effectively make Credentials a channel factory, allowing different credential types to create different channel types - this gives us a hook so that InsecureCredentials can at runtime instantiate a different kind of channel as required - giving us a way of generating an openssl free version of grpc++. - Server credentials not touched yet, but they'll need to be updated. --- Makefile | 154 ++++++++++++++++++++++++- build.json | 121 +++++++++++-------- include/grpc++/channel_arguments.h | 6 +- include/grpc++/create_channel.h | 3 - include/grpc++/credentials.h | 95 +++++++-------- src/cpp/client/channel.cc | 40 ++----- src/cpp/client/channel.h | 7 +- src/cpp/client/create_channel.cc | 7 +- src/cpp/client/credentials.cc | 77 +------------ src/cpp/client/insecure_credentials.cc | 60 ++++++++++ src/cpp/client/secure_credentials.cc | 128 ++++++++++++++++++++ test/cpp/client/credentials_test.cc | 3 +- test/cpp/end2end/async_end2end_test.cc | 67 +++++------ test/cpp/end2end/end2end_test.cc | 14 +-- test/cpp/interop/client.cc | 17 +-- test/cpp/interop/server.cc | 7 +- test/cpp/util/create_test_channel.cc | 11 +- 17 files changed, 524 insertions(+), 293 deletions(-) create mode 100644 src/cpp/client/insecure_credentials.cc create mode 100644 src/cpp/client/secure_credentials.cc diff --git a/Makefile b/Makefile index b018febea10..8bb6b7f1ac3 100644 --- a/Makefile +++ b/Makefile @@ -908,13 +908,13 @@ static: static_c static_cxx static_c: $(LIBDIR)/$(CONFIG)/libgpr.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.a -static_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++.a +static_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a shared: shared_c shared_cxx shared_c: $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT) -shared_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT) +shared_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT) shared_csharp: shared_c $(LIBDIR)/$(CONFIG)/libgrpc_csharp_ext.$(SHARED_EXT) grpc_csharp_ext: shared_csharp @@ -1794,6 +1794,8 @@ strip-static_cxx: static_cxx ifeq ($(CONFIG),opt) $(E) "[STRIP] Stripping libgrpc++.a" $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++.a + $(E) "[STRIP] Stripping libgrpc++_unsecure.a" + $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a endif strip-shared_c: shared_c @@ -1810,6 +1812,8 @@ strip-shared_cxx: shared_cxx ifeq ($(CONFIG),opt) $(E) "[STRIP] Stripping libgrpc++.so" $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++.$(SHARED_EXT) + $(E) "[STRIP] Stripping libgrpc++_unsecure.so" + $(Q) $(STRIP) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT) endif strip-shared_csharp: shared_csharp @@ -1969,6 +1973,9 @@ install-static_cxx: static_cxx strip-static_cxx $(E) "[INSTALL] Installing libgrpc++.a" $(Q) $(INSTALL) -d $(prefix)/lib $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++.a $(prefix)/lib/libgrpc++.a + $(E) "[INSTALL] Installing libgrpc++_unsecure.a" + $(Q) $(INSTALL) -d $(prefix)/lib + $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(prefix)/lib/libgrpc++_unsecure.a @@ -2033,6 +2040,19 @@ ifneq ($(SYSTEM),Darwin) $(Q) ln -sf libgrpc++.$(SHARED_EXT) $(prefix)/lib/libgrpc++.so endif endif +ifeq ($(SYSTEM),MINGW32) + $(E) "[INSTALL] Installing grpc++_unsecure.$(SHARED_EXT)" + $(Q) $(INSTALL) -d $(prefix)/lib + $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/grpc++_unsecure.$(SHARED_EXT) $(prefix)/lib/grpc++_unsecure.$(SHARED_EXT) + $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure-imp.a $(prefix)/lib/libgrpc++_unsecure-imp.a +else + $(E) "[INSTALL] Installing libgrpc++_unsecure.$(SHARED_EXT)" + $(Q) $(INSTALL) -d $(prefix)/lib + $(Q) $(INSTALL) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT) $(prefix)/lib/libgrpc++_unsecure.$(SHARED_EXT) +ifneq ($(SYSTEM),Darwin) + $(Q) ln -sf libgrpc++_unsecure.$(SHARED_EXT) $(prefix)/lib/libgrpc++_unsecure.so +endif +endif ifneq ($(SYSTEM),MINGW32) ifneq ($(SYSTEM),Darwin) $(Q) ldconfig || true @@ -3004,12 +3024,14 @@ $(OBJDIR)/$(CONFIG)/src/core/transport/transport.o: LIBGRPC++_SRC = \ + src/cpp/client/secure_credentials.cc \ src/cpp/client/channel.cc \ src/cpp/client/channel_arguments.cc \ src/cpp/client/client_context.cc \ src/cpp/client/client_unary_call.cc \ src/cpp/client/create_channel.cc \ src/cpp/client/credentials.cc \ + src/cpp/client/insecure_credentials.cc \ src/cpp/client/internal_stub.cc \ src/cpp/common/call.cc \ src/cpp/common/completion_queue.cc \ @@ -3081,12 +3103,14 @@ ifneq ($(OPENSSL_DEP),) # This is to ensure the embedded OpenSSL is built beforehand, properly # installing headers to their final destination on the drive. We need this # otherwise parallel compilation will fail if a source is compiled first. +src/cpp/client/secure_credentials.cc: $(OPENSSL_DEP) src/cpp/client/channel.cc: $(OPENSSL_DEP) src/cpp/client/channel_arguments.cc: $(OPENSSL_DEP) src/cpp/client/client_context.cc: $(OPENSSL_DEP) src/cpp/client/client_unary_call.cc: $(OPENSSL_DEP) src/cpp/client/create_channel.cc: $(OPENSSL_DEP) src/cpp/client/credentials.cc: $(OPENSSL_DEP) +src/cpp/client/insecure_credentials.cc: $(OPENSSL_DEP) src/cpp/client/internal_stub.cc: $(OPENSSL_DEP) src/cpp/common/call.cc: $(OPENSSL_DEP) src/cpp/common/completion_queue.cc: $(OPENSSL_DEP) @@ -3106,6 +3130,13 @@ $(LIBDIR)/$(CONFIG)/libgrpc++.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DEP) $(LI $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++.a $(Q) $(AR) rcs $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBGRPC++_OBJS) + $(Q) rm -rf tmp-merge + $(Q) mkdir tmp-merge + $(Q) ( cd tmp-merge ; $(AR) x ../$(LIBDIR)/$(CONFIG)/libgrpc++.a ) + $(Q) for l in $(OPENSSL_MERGE_LIBS) ; do ( cd tmp-merge ; ar x ../$${l} ) ; done + $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++.a tmp-merge/__.SYMDEF* + $(Q) ar rcs $(LIBDIR)/$(CONFIG)/libgrpc++.a tmp-merge/* + $(Q) rm -rf tmp-merge ifeq ($(SYSTEM),Darwin) $(Q) ranlib $(LIBDIR)/$(CONFIG)/libgrpc++.a endif @@ -3140,12 +3171,14 @@ ifneq ($(NO_DEPS),true) endif endif +$(OBJDIR)/$(CONFIG)/src/cpp/client/secure_credentials.o: $(OBJDIR)/$(CONFIG)/src/cpp/client/channel.o: $(OBJDIR)/$(CONFIG)/src/cpp/client/channel_arguments.o: $(OBJDIR)/$(CONFIG)/src/cpp/client/client_context.o: $(OBJDIR)/$(CONFIG)/src/cpp/client/client_unary_call.o: $(OBJDIR)/$(CONFIG)/src/cpp/client/create_channel.o: $(OBJDIR)/$(CONFIG)/src/cpp/client/credentials.o: +$(OBJDIR)/$(CONFIG)/src/cpp/client/insecure_credentials.o: $(OBJDIR)/$(CONFIG)/src/cpp/client/internal_stub.o: $(OBJDIR)/$(CONFIG)/src/cpp/common/call.o: $(OBJDIR)/$(CONFIG)/src/cpp/common/completion_queue.o: @@ -3225,6 +3258,123 @@ endif $(OBJDIR)/$(CONFIG)/test/cpp/util/create_test_channel.o: $(GENDIR)/test/cpp/util/messages.pb.cc $(GENDIR)/test/cpp/util/echo.pb.cc $(GENDIR)/test/cpp/util/echo_duplicate.pb.cc +LIBGRPC++_UNSECURE_SRC = \ + src/cpp/client/channel.cc \ + src/cpp/client/channel_arguments.cc \ + src/cpp/client/client_context.cc \ + src/cpp/client/client_unary_call.cc \ + src/cpp/client/create_channel.cc \ + src/cpp/client/credentials.cc \ + src/cpp/client/insecure_credentials.cc \ + src/cpp/client/internal_stub.cc \ + src/cpp/common/call.cc \ + src/cpp/common/completion_queue.cc \ + src/cpp/common/rpc_method.cc \ + src/cpp/proto/proto_utils.cc \ + src/cpp/server/server.cc \ + src/cpp/server/server_builder.cc \ + src/cpp/server/server_context.cc \ + src/cpp/server/server_credentials.cc \ + src/cpp/server/thread_pool.cc \ + src/cpp/util/status.cc \ + src/cpp/util/time.cc \ + +PUBLIC_HEADERS_CXX += \ + include/grpc++/async_unary_call.h \ + include/grpc++/channel_arguments.h \ + include/grpc++/channel_interface.h \ + include/grpc++/client_context.h \ + include/grpc++/completion_queue.h \ + include/grpc++/config.h \ + include/grpc++/create_channel.h \ + include/grpc++/credentials.h \ + include/grpc++/impl/call.h \ + include/grpc++/impl/client_unary_call.h \ + include/grpc++/impl/internal_stub.h \ + include/grpc++/impl/rpc_method.h \ + include/grpc++/impl/rpc_service_method.h \ + include/grpc++/impl/service_type.h \ + include/grpc++/server.h \ + include/grpc++/server_builder.h \ + include/grpc++/server_context.h \ + include/grpc++/server_credentials.h \ + include/grpc++/status.h \ + include/grpc++/status_code_enum.h \ + include/grpc++/stream.h \ + include/grpc++/thread_pool_interface.h \ + +LIBGRPC++_UNSECURE_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBGRPC++_UNSECURE_SRC)))) + +ifeq ($(NO_PROTOBUF),true) + +# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. + +$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a: protobuf_dep_error + +ifeq ($(SYSTEM),MINGW32) +$(LIBDIR)/$(CONFIG)/grpc++_unsecure.$(SHARED_EXT): protobuf_dep_error +else +$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT): protobuf_dep_error +endif + +else + +$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a: $(ZLIB_DEP) $(PROTOBUF_DEP) $(LIBGRPC++_UNSECURE_OBJS) + $(E) "[AR] Creating $@" + $(Q) mkdir -p `dirname $@` + $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a + $(Q) $(AR) rcs $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a $(LIBGRPC++_UNSECURE_OBJS) +ifeq ($(SYSTEM),Darwin) + $(Q) ranlib $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.a +endif + + + +ifeq ($(SYSTEM),MINGW32) +$(LIBDIR)/$(CONFIG)/grpc++_unsecure.$(SHARED_EXT): $(LIBGRPC++_UNSECURE_OBJS) $(ZLIB_DEP)$(LIBDIR)/$(CONFIG)/gpr.$(SHARED_EXT)$(LIBDIR)/$(CONFIG)/grpc_unsecure.$(SHARED_EXT) + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,--output-def=$(LIBDIR)/$(CONFIG)/grpc++_unsecure.def -Wl,--out-implib=$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure-imp.a -o $(LIBDIR)/$(CONFIG)/grpc++_unsecure.$(SHARED_EXT) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr-imp -lgrpc_unsecure-imp +else +$(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT): $(LIBGRPC++_UNSECURE_OBJS) $(ZLIB_DEP) $(LIBDIR)/$(CONFIG)/libgpr.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc_unsecure.$(SHARED_EXT) + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` +ifeq ($(SYSTEM),Darwin) + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -dynamiclib -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure +else + $(Q) $(LDXX) $(LDFLAGS) -L$(LIBDIR)/$(CONFIG) -shared -Wl,-soname,libgrpc++_unsecure.so.0 -o $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.$(SHARED_EXT) $(LIBGRPC++_UNSECURE_OBJS) $(LDLIBS) $(LDLIBSXX) $(LDLIBS_PROTOBUF) -lgpr -lgrpc_unsecure + $(Q) ln -sf libgrpc++_unsecure.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.so.0 + $(Q) ln -sf libgrpc++_unsecure.$(SHARED_EXT) $(LIBDIR)/$(CONFIG)/libgrpc++_unsecure.so +endif +endif + +endif + +ifneq ($(NO_DEPS),true) +-include $(LIBGRPC++_UNSECURE_OBJS:.o=.dep) +endif + +$(OBJDIR)/$(CONFIG)/src/cpp/client/channel.o: +$(OBJDIR)/$(CONFIG)/src/cpp/client/channel_arguments.o: +$(OBJDIR)/$(CONFIG)/src/cpp/client/client_context.o: +$(OBJDIR)/$(CONFIG)/src/cpp/client/client_unary_call.o: +$(OBJDIR)/$(CONFIG)/src/cpp/client/create_channel.o: +$(OBJDIR)/$(CONFIG)/src/cpp/client/credentials.o: +$(OBJDIR)/$(CONFIG)/src/cpp/client/insecure_credentials.o: +$(OBJDIR)/$(CONFIG)/src/cpp/client/internal_stub.o: +$(OBJDIR)/$(CONFIG)/src/cpp/common/call.o: +$(OBJDIR)/$(CONFIG)/src/cpp/common/completion_queue.o: +$(OBJDIR)/$(CONFIG)/src/cpp/common/rpc_method.o: +$(OBJDIR)/$(CONFIG)/src/cpp/proto/proto_utils.o: +$(OBJDIR)/$(CONFIG)/src/cpp/server/server.o: +$(OBJDIR)/$(CONFIG)/src/cpp/server/server_builder.o: +$(OBJDIR)/$(CONFIG)/src/cpp/server/server_context.o: +$(OBJDIR)/$(CONFIG)/src/cpp/server/server_credentials.o: +$(OBJDIR)/$(CONFIG)/src/cpp/server/thread_pool.o: +$(OBJDIR)/$(CONFIG)/src/cpp/util/status.o: +$(OBJDIR)/$(CONFIG)/src/cpp/util/time.o: + + LIBPUBSUB_CLIENT_LIB_SRC = \ $(GENDIR)/examples/pubsub/label.pb.cc \ $(GENDIR)/examples/pubsub/empty.pb.cc \ diff --git a/build.json b/build.json index f6ef33b25fc..9ab59f93795 100644 --- a/build.json +++ b/build.json @@ -9,6 +9,60 @@ } }, "filegroups": [ + { + "name": "grpc++_base", + "public_headers": [ + "include/grpc++/async_unary_call.h", + "include/grpc++/channel_arguments.h", + "include/grpc++/channel_interface.h", + "include/grpc++/client_context.h", + "include/grpc++/completion_queue.h", + "include/grpc++/config.h", + "include/grpc++/create_channel.h", + "include/grpc++/credentials.h", + "include/grpc++/impl/call.h", + "include/grpc++/impl/client_unary_call.h", + "include/grpc++/impl/internal_stub.h", + "include/grpc++/impl/rpc_method.h", + "include/grpc++/impl/rpc_service_method.h", + "include/grpc++/impl/service_type.h", + "include/grpc++/server.h", + "include/grpc++/server_builder.h", + "include/grpc++/server_context.h", + "include/grpc++/server_credentials.h", + "include/grpc++/status.h", + "include/grpc++/status_code_enum.h", + "include/grpc++/stream.h", + "include/grpc++/thread_pool_interface.h" + ], + "headers": [ + "src/cpp/client/channel.h", + "src/cpp/proto/proto_utils.h", + "src/cpp/server/thread_pool.h", + "src/cpp/util/time.h" + ], + "src": [ + "src/cpp/client/channel.cc", + "src/cpp/client/channel_arguments.cc", + "src/cpp/client/client_context.cc", + "src/cpp/client/client_unary_call.cc", + "src/cpp/client/create_channel.cc", + "src/cpp/client/credentials.cc", + "src/cpp/client/insecure_credentials.cc", + "src/cpp/client/internal_stub.cc", + "src/cpp/common/call.cc", + "src/cpp/common/completion_queue.cc", + "src/cpp/common/rpc_method.cc", + "src/cpp/proto/proto_utils.cc", + "src/cpp/server/server.cc", + "src/cpp/server/server_builder.cc", + "src/cpp/server/server_context.cc", + "src/cpp/server/server_credentials.cc", + "src/cpp/server/thread_pool.cc", + "src/cpp/util/status.cc", + "src/cpp/util/time.cc" + ] + }, { "name": "grpc_base", "public_headers": [ @@ -383,60 +437,17 @@ "name": "grpc++", "build": "all", "language": "c++", - "public_headers": [ - "include/grpc++/async_unary_call.h", - "include/grpc++/channel_arguments.h", - "include/grpc++/channel_interface.h", - "include/grpc++/client_context.h", - "include/grpc++/completion_queue.h", - "include/grpc++/config.h", - "include/grpc++/create_channel.h", - "include/grpc++/credentials.h", - "include/grpc++/impl/call.h", - "include/grpc++/impl/client_unary_call.h", - "include/grpc++/impl/internal_stub.h", - "include/grpc++/impl/rpc_method.h", - "include/grpc++/impl/rpc_service_method.h", - "include/grpc++/impl/service_type.h", - "include/grpc++/server.h", - "include/grpc++/server_builder.h", - "include/grpc++/server_context.h", - "include/grpc++/server_credentials.h", - "include/grpc++/status.h", - "include/grpc++/status_code_enum.h", - "include/grpc++/stream.h", - "include/grpc++/thread_pool_interface.h" - ], - "headers": [ - "src/cpp/client/channel.h", - "src/cpp/proto/proto_utils.h", - "src/cpp/server/thread_pool.h", - "src/cpp/util/time.h" - ], "src": [ - "src/cpp/client/channel.cc", - "src/cpp/client/channel_arguments.cc", - "src/cpp/client/client_context.cc", - "src/cpp/client/client_unary_call.cc", - "src/cpp/client/create_channel.cc", - "src/cpp/client/credentials.cc", - "src/cpp/client/internal_stub.cc", - "src/cpp/common/call.cc", - "src/cpp/common/completion_queue.cc", - "src/cpp/common/rpc_method.cc", - "src/cpp/proto/proto_utils.cc", - "src/cpp/server/server.cc", - "src/cpp/server/server_builder.cc", - "src/cpp/server/server_context.cc", - "src/cpp/server/server_credentials.cc", - "src/cpp/server/thread_pool.cc", - "src/cpp/util/status.cc", - "src/cpp/util/time.cc" + "src/cpp/client/secure_credentials.cc" ], "deps": [ "gpr", "grpc" ], + "baselib": true, + "filegroups": [ + "grpc++_base" + ], "secure": true, "vs_project_guid": "{C187A093-A0FE-489D-A40A-6E33DE0F9FEB}" }, @@ -451,6 +462,20 @@ "test/cpp/util/create_test_channel.cc" ] }, + { + "name": "grpc++_unsecure", + "build": "all", + "language": "c++", + "deps": [ + "gpr", + "grpc_unsecure" + ], + "baselib": true, + "filegroups": [ + "grpc++_base" + ], + "secure": false + }, { "name": "pubsub_client_lib", "build": "private", diff --git a/include/grpc++/channel_arguments.h b/include/grpc++/channel_arguments.h index 75c3cf45b49..91f89f313e4 100644 --- a/include/grpc++/channel_arguments.h +++ b/include/grpc++/channel_arguments.h @@ -62,6 +62,9 @@ class ChannelArguments { void SetInt(const grpc::string& key, int value); void SetString(const grpc::string& key, const grpc::string& value); + // Populates given channel_args with args_, does not take ownership. + void SetChannelArgs(grpc_channel_args* channel_args) const; + private: friend class Channel; friend class testing::ChannelArgumentsTest; @@ -73,9 +76,6 @@ class ChannelArguments { // Returns empty string when it is not set. grpc::string GetSslTargetNameOverride() const; - // Populates given channel_args with args_, does not take ownership. - void SetChannelArgs(grpc_channel_args* channel_args) const; - std::vector args_; std::list strings_; }; diff --git a/include/grpc++/create_channel.h b/include/grpc++/create_channel.h index eadabda3596..2c40047e9a1 100644 --- a/include/grpc++/create_channel.h +++ b/include/grpc++/create_channel.h @@ -43,9 +43,6 @@ namespace grpc { class ChannelArguments; class ChannelInterface; -std::shared_ptr CreateChannel(const grpc::string& target, - const ChannelArguments& args); - // If creds does not hold an object or is invalid, a lame channel is returned. std::shared_ptr CreateChannel( const grpc::string& target, const std::unique_ptr& creds, diff --git a/include/grpc++/credentials.h b/include/grpc++/credentials.h index ac6f394847d..b462b450daf 100644 --- a/include/grpc++/credentials.h +++ b/include/grpc++/credentials.h @@ -39,29 +39,21 @@ #include -struct grpc_credentials; - namespace grpc { +class ChannelArguments; +class ChannelInterface; -// grpc_credentials wrapper class. Typical use in C++ applications is limited -// to creating an instance using CredentialsFactory, and passing it down -// during channel construction. - -class Credentials final { +class Credentials { public: - ~Credentials(); - - // TODO(abhikumar): Specify a plugin API here to be implemented by - // credentials that do not have a corresponding implementation in C. + virtual ~Credentials(); private: - explicit Credentials(grpc_credentials*); - grpc_credentials* GetRawCreds(); - - friend class Channel; - friend class CredentialsFactory; + friend std::shared_ptr CreateChannel( + const grpc::string& target, const std::unique_ptr& creds, + const ChannelArguments& args); - grpc_credentials* creds_; + virtual std::shared_ptr CreateChannel( + const grpc::string& target, const ChannelArguments& args) = 0; }; // Options used to build SslCredentials @@ -79,43 +71,44 @@ struct SslCredentialsOptions { grpc::string pem_cert_chain; }; -// Factory for building different types of Credentials -// The methods may return empty unique_ptr when credentials cannot be created. +// Factories for building different types of Credentials +// The functions may return empty unique_ptr when credentials cannot be created. // If a Credentials pointer is returned, it can still be invalid when used to // create a channel. A lame channel will be created then and all rpcs will // fail on it. -class CredentialsFactory { - public: - // Builds credentials with reasonable defaults. - static std::unique_ptr DefaultCredentials(); - - // Builds SSL Credentials given SSL specific options - static std::unique_ptr SslCredentials( - const SslCredentialsOptions& options); - - // Builds credentials for use when running in GCE - static std::unique_ptr ComputeEngineCredentials(); - - // Builds service account credentials. - // json_key is the JSON key string containing the client's private key. - // scope is a space-delimited list of the requested permissions. - // token_lifetime is the lifetime of each token acquired through this service - // account credentials. It should be positive and should not exceed - // grpc_max_auth_token_lifetime or will be cropped to this value. - static std::unique_ptr ServiceAccountCredentials( - const grpc::string& json_key, const grpc::string& scope, - std::chrono::seconds token_lifetime); - - // Builds IAM credentials. - static std::unique_ptr IAMCredentials( - const grpc::string& authorization_token, - const grpc::string& authority_selector); - - // Combines two credentials objects into a composite credentials - static std::unique_ptr ComposeCredentials( - const std::unique_ptr& creds1, - const std::unique_ptr& creds2); -}; + +// Builds credentials with reasonable defaults. +std::unique_ptr DefaultCredentials(); + +// Builds SSL Credentials given SSL specific options +std::unique_ptr SslCredentials( + const SslCredentialsOptions& options); + +// Builds credentials for use when running in GCE +std::unique_ptr ComputeEngineCredentials(); + +// Builds service account credentials. +// json_key is the JSON key string containing the client's private key. +// scope is a space-delimited list of the requested permissions. +// token_lifetime is the lifetime of each token acquired through this service +// account credentials. It should be positive and should not exceed +// grpc_max_auth_token_lifetime or will be cropped to this value. +std::unique_ptr ServiceAccountCredentials( + const grpc::string& json_key, const grpc::string& scope, + std::chrono::seconds token_lifetime); + +// Builds IAM credentials. +std::unique_ptr IAMCredentials( + const grpc::string& authorization_token, + const grpc::string& authority_selector); + +// Combines two credentials objects into a composite credentials +std::unique_ptr ComposeCredentials( + const std::unique_ptr& creds1, + const std::unique_ptr& creds2); + +// Credentials for an unencrypted, unauthenticated channel +std::unique_ptr InsecureCredentials(); } // namespace grpc diff --git a/src/cpp/client/channel.cc b/src/cpp/client/channel.cc index ca69d66cbbf..65bd135d5cb 100644 --- a/src/cpp/client/channel.cc +++ b/src/cpp/client/channel.cc @@ -54,43 +54,23 @@ namespace grpc { -Channel::Channel(const grpc::string &target, const ChannelArguments &args) - : target_(target) { - grpc_channel_args channel_args; - args.SetChannelArgs(&channel_args); - c_channel_ = grpc_channel_create( - target_.c_str(), channel_args.num_args > 0 ? &channel_args : nullptr); -} - -Channel::Channel(const grpc::string &target, - const std::unique_ptr &creds, - const ChannelArguments &args) - : target_(args.GetSslTargetNameOverride().empty() - ? target - : args.GetSslTargetNameOverride()) { - grpc_channel_args channel_args; - args.SetChannelArgs(&channel_args); - grpc_credentials *c_creds = creds ? creds->GetRawCreds() : nullptr; - c_channel_ = grpc_secure_channel_create( - c_creds, target.c_str(), - channel_args.num_args > 0 ? &channel_args : nullptr); -} +Channel::Channel(const grpc::string& target, grpc_channel* channel) + : target_(target), c_channel_(channel) {} Channel::~Channel() { grpc_channel_destroy(c_channel_); } -Call Channel::CreateCall(const RpcMethod &method, ClientContext *context, - CompletionQueue *cq) { - auto c_call = - grpc_channel_create_call( - c_channel_, cq->cq(), method.name(), - context->authority().empty() ? target_.c_str() - : context->authority().c_str(), - context->RawDeadline()); +Call Channel::CreateCall(const RpcMethod& method, ClientContext* context, + CompletionQueue* cq) { + auto c_call = grpc_channel_create_call(c_channel_, cq->cq(), method.name(), + context->authority().empty() + ? target_.c_str() + : context->authority().c_str(), + context->RawDeadline()); context->set_call(c_call); return Call(c_call, this, cq); } -void Channel::PerformOpsOnCall(CallOpBuffer *buf, Call *call) { +void Channel::PerformOpsOnCall(CallOpBuffer* buf, Call* call) { static const size_t MAX_OPS = 8; size_t nops = MAX_OPS; grpc_op ops[MAX_OPS]; diff --git a/src/cpp/client/channel.h b/src/cpp/client/channel.h index 06f5a8ffdfe..f5c9e0f6160 100644 --- a/src/cpp/client/channel.h +++ b/src/cpp/client/channel.h @@ -51,10 +51,7 @@ class StreamContextInterface; class Channel final : public ChannelInterface { public: - Channel(const grpc::string &target, const ChannelArguments &args); - Channel(const grpc::string &target, const std::unique_ptr &creds, - const ChannelArguments &args); - + Channel(const grpc::string &target, grpc_channel *c_channel); ~Channel() override; virtual Call CreateCall(const RpcMethod &method, ClientContext *context, @@ -63,7 +60,7 @@ class Channel final : public ChannelInterface { private: const grpc::string target_; - grpc_channel *c_channel_; // owned + grpc_channel *const c_channel_; // owned }; } // namespace grpc diff --git a/src/cpp/client/create_channel.cc b/src/cpp/client/create_channel.cc index acf51cb90b1..ef2deb35563 100644 --- a/src/cpp/client/create_channel.cc +++ b/src/cpp/client/create_channel.cc @@ -40,14 +40,9 @@ namespace grpc { class ChannelArguments; -std::shared_ptr CreateChannel(const grpc::string &target, - const ChannelArguments &args) { - return std::shared_ptr(new Channel(target, args)); -} - std::shared_ptr CreateChannel( const grpc::string &target, const std::unique_ptr &creds, const ChannelArguments &args) { - return std::shared_ptr(new Channel(target, creds, args)); + return creds->CreateChannel(target, args); } } // namespace grpc diff --git a/src/cpp/client/credentials.cc b/src/cpp/client/credentials.cc index 66571cad73d..e8062849887 100644 --- a/src/cpp/client/credentials.cc +++ b/src/cpp/client/credentials.cc @@ -31,85 +31,10 @@ * */ -#include - -#include -#include - #include namespace grpc { -Credentials::Credentials(grpc_credentials *c_creds) : creds_(c_creds) {} - -Credentials::~Credentials() { grpc_credentials_release(creds_); } -grpc_credentials *Credentials::GetRawCreds() { return creds_; } - -std::unique_ptr CredentialsFactory::DefaultCredentials() { - grpc_credentials *c_creds = grpc_default_credentials_create(); - std::unique_ptr cpp_creds(new Credentials(c_creds)); - return cpp_creds; -} - -// Builds SSL Credentials given SSL specific options -std::unique_ptr CredentialsFactory::SslCredentials( - const SslCredentialsOptions &options) { - grpc_ssl_pem_key_cert_pair pem_key_cert_pair = { - options.pem_private_key.c_str(), options.pem_cert_chain.c_str()}; - - grpc_credentials *c_creds = grpc_ssl_credentials_create( - options.pem_root_certs.empty() ? nullptr : options.pem_root_certs.c_str(), - options.pem_private_key.empty() ? nullptr : &pem_key_cert_pair); - std::unique_ptr cpp_creds( - c_creds == nullptr ? nullptr : new Credentials(c_creds)); - return cpp_creds; -} - -// Builds credentials for use when running in GCE -std::unique_ptr CredentialsFactory::ComputeEngineCredentials() { - grpc_credentials *c_creds = grpc_compute_engine_credentials_create(); - std::unique_ptr cpp_creds( - c_creds == nullptr ? nullptr : new Credentials(c_creds)); - return cpp_creds; -} - -// Builds service account credentials. -std::unique_ptr CredentialsFactory::ServiceAccountCredentials( - const grpc::string &json_key, const grpc::string &scope, - std::chrono::seconds token_lifetime) { - gpr_timespec lifetime = gpr_time_from_seconds( - token_lifetime.count() > 0 ? token_lifetime.count() : 0); - grpc_credentials *c_creds = grpc_service_account_credentials_create( - json_key.c_str(), scope.c_str(), lifetime); - std::unique_ptr cpp_creds( - c_creds == nullptr ? nullptr : new Credentials(c_creds)); - return cpp_creds; -} - -// Builds IAM credentials. -std::unique_ptr CredentialsFactory::IAMCredentials( - const grpc::string &authorization_token, - const grpc::string &authority_selector) { - grpc_credentials *c_creds = grpc_iam_credentials_create( - authorization_token.c_str(), authority_selector.c_str()); - std::unique_ptr cpp_creds( - c_creds == nullptr ? nullptr : new Credentials(c_creds)); - return cpp_creds; -} - -// Combines two credentials objects into a composite credentials. -std::unique_ptr CredentialsFactory::ComposeCredentials( - const std::unique_ptr &creds1, - const std::unique_ptr &creds2) { - // Note that we are not saving unique_ptrs to the two credentials - // passed in here. This is OK because the underlying C objects (i.e., - // creds1 and creds2) into grpc_composite_credentials_create will see their - // refcounts incremented. - grpc_credentials *c_creds = grpc_composite_credentials_create( - creds1->GetRawCreds(), creds2->GetRawCreds()); - std::unique_ptr cpp_creds( - c_creds == nullptr ? nullptr : new Credentials(c_creds)); - return cpp_creds; -} +Credentials::~Credentials() {} } // namespace grpc diff --git a/src/cpp/client/insecure_credentials.cc b/src/cpp/client/insecure_credentials.cc new file mode 100644 index 00000000000..4f3bba5c8e5 --- /dev/null +++ b/src/cpp/client/insecure_credentials.cc @@ -0,0 +1,60 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include + +#include +#include + +#include +#include +#include "src/cpp/client/channel.h" + +namespace grpc { + +namespace { +class InsecureCredentialsImpl final : public Credentials { + public: + std::shared_ptr CreateChannel(const string& target, const grpc::ChannelArguments& args) override { + grpc_channel_args channel_args; + args.SetChannelArgs(&channel_args); + return std::shared_ptr(new Channel(target, grpc_channel_create(target.c_str(), &channel_args))); + } +}; +} // namespace + +std::unique_ptr InsecureCredentials() { + return std::unique_ptr(new InsecureCredentialsImpl()); +} + +} // namespace grpc diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc new file mode 100644 index 00000000000..367dfe3447b --- /dev/null +++ b/src/cpp/client/secure_credentials.cc @@ -0,0 +1,128 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include + +#include +#include + +#include +#include +#include "src/cpp/client/channel.h" + +namespace grpc { + +namespace { +class SecureCredentials final : public Credentials { + public: + explicit SecureCredentials(grpc_credentials* c_creds) : c_creds_(c_creds) {} + ~SecureCredentials() override { grpc_credentials_release(c_creds_); } + grpc_credentials* GetRawCreds() { return c_creds_; } + + std::shared_ptr CreateChannel( + const string& target, const grpc::ChannelArguments& args) override { + grpc_channel_args channel_args; + args.SetChannelArgs(&channel_args); + return std::shared_ptr(new Channel( + target, + grpc_secure_channel_create(c_creds_, target.c_str(), &channel_args))); + } + + private: + grpc_credentials* const c_creds_; +}; + +std::unique_ptr WrapCredentials(grpc_credentials* creds) { + return creds == nullptr + ? nullptr + : std::unique_ptr(new SecureCredentials(creds)); +} +} // namespace + +std::unique_ptr DefaultCredentials() { + return WrapCredentials(grpc_default_credentials_create()); +} + +// Builds SSL Credentials given SSL specific options +std::unique_ptr SslCredentials( + const SslCredentialsOptions& options) { + grpc_ssl_pem_key_cert_pair pem_key_cert_pair = { + options.pem_private_key.c_str(), options.pem_cert_chain.c_str()}; + + grpc_credentials* c_creds = grpc_ssl_credentials_create( + options.pem_root_certs.empty() ? nullptr : options.pem_root_certs.c_str(), + options.pem_private_key.empty() ? nullptr : &pem_key_cert_pair); + return WrapCredentials(c_creds); +} + +// Builds credentials for use when running in GCE +std::unique_ptr ComputeEngineCredentials() { + return WrapCredentials(grpc_compute_engine_credentials_create()); +} + +// Builds service account credentials. +std::unique_ptr ServiceAccountCredentials( + const grpc::string& json_key, const grpc::string& scope, + std::chrono::seconds token_lifetime) { + gpr_timespec lifetime = gpr_time_from_seconds( + token_lifetime.count() > 0 ? token_lifetime.count() : 0); + return WrapCredentials(grpc_service_account_credentials_create( + json_key.c_str(), scope.c_str(), lifetime)); +} + +// Builds IAM credentials. +std::unique_ptr IAMCredentials( + const grpc::string& authorization_token, + const grpc::string& authority_selector) { + return WrapCredentials(grpc_iam_credentials_create( + authorization_token.c_str(), authority_selector.c_str())); +} + +// Combines two credentials objects into a composite credentials. +std::unique_ptr ComposeCredentials( + const std::unique_ptr& creds1, + const std::unique_ptr& creds2) { + // Note that we are not saving unique_ptrs to the two credentials + // passed in here. This is OK because the underlying C objects (i.e., + // creds1 and creds2) into grpc_composite_credentials_create will see their + // refcounts incremented. + SecureCredentials* s1 = dynamic_cast(creds1.get()); + SecureCredentials* s2 = dynamic_cast(creds2.get()); + if (s1 && s2) { + return WrapCredentials(grpc_composite_credentials_create( + s1->GetRawCreds(), s2->GetRawCreds())); + } + return nullptr; +} + +} // namespace grpc diff --git a/test/cpp/client/credentials_test.cc b/test/cpp/client/credentials_test.cc index dc8d76d7eff..59ca33cc297 100644 --- a/test/cpp/client/credentials_test.cc +++ b/test/cpp/client/credentials_test.cc @@ -47,8 +47,7 @@ class CredentialsTest : public ::testing::Test { TEST_F(CredentialsTest, InvalidServiceAccountCreds) { std::unique_ptr bad1 = - CredentialsFactory::ServiceAccountCredentials("", "", - std::chrono::seconds(1)); + ServiceAccountCredentials("", "", std::chrono::seconds(1)); EXPECT_EQ(nullptr, bad1.get()); } diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc index 248e054e49a..85b4ff8120c 100644 --- a/test/cpp/end2end/async_end2end_test.cc +++ b/test/cpp/end2end/async_end2end_test.cc @@ -65,9 +65,7 @@ namespace testing { namespace { -void* tag(int i) { - return (void*)(gpr_intptr)i; -} +void* tag(int i) { return (void*)(gpr_intptr) i; } void verify_ok(CompletionQueue* cq, int i, bool expect_ok) { bool ok; @@ -104,23 +102,15 @@ class AsyncEnd2endTest : public ::testing::Test { } void ResetStub() { - std::shared_ptr channel = - CreateChannel(server_address_.str(), ChannelArguments()); + std::shared_ptr channel = CreateChannel( + server_address_.str(), InsecureCredentials(), ChannelArguments()); stub_.reset(grpc::cpp::test::util::TestService::NewStub(channel)); } - void server_ok(int i) { - verify_ok(&srv_cq_, i, true); - } - void client_ok(int i) { - verify_ok(&cli_cq_, i , true); - } - void server_fail(int i) { - verify_ok(&srv_cq_, i, false); - } - void client_fail(int i) { - verify_ok(&cli_cq_, i, false); - } + void server_ok(int i) { verify_ok(&srv_cq_, i, true); } + void client_ok(int i) { verify_ok(&cli_cq_, i, true); } + void server_fail(int i) { verify_ok(&srv_cq_, i, false); } + void client_fail(int i) { verify_ok(&cli_cq_, i, false); } void SendRpc(int num_rpcs) { for (int i = 0; i < num_rpcs; i++) { @@ -135,12 +125,11 @@ class AsyncEnd2endTest : public ::testing::Test { grpc::ServerAsyncResponseWriter response_writer(&srv_ctx); send_request.set_message("Hello"); - std::unique_ptr > - response_reader(stub_->Echo( - &cli_ctx, send_request, &cli_cq_, tag(1))); + std::unique_ptr > response_reader( + stub_->Echo(&cli_ctx, send_request, &cli_cq_, tag(1))); - service_.RequestEcho( - &srv_ctx, &recv_request, &response_writer, &srv_cq_, tag(2)); + service_.RequestEcho(&srv_ctx, &recv_request, &response_writer, &srv_cq_, + tag(2)); server_ok(2); EXPECT_EQ(send_request.message(), recv_request.message()); @@ -193,8 +182,7 @@ TEST_F(AsyncEnd2endTest, SimpleClientStreaming) { std::unique_ptr > cli_stream( stub_->RequestStream(&cli_ctx, &recv_response, &cli_cq_, tag(1))); - service_.RequestRequestStream( - &srv_ctx, &srv_stream, &srv_cq_, tag(2)); + service_.RequestRequestStream(&srv_ctx, &srv_stream, &srv_cq_, tag(2)); server_ok(2); client_ok(1); @@ -247,8 +235,8 @@ TEST_F(AsyncEnd2endTest, SimpleServerStreaming) { std::unique_ptr > cli_stream( stub_->ResponseStream(&cli_ctx, send_request, &cli_cq_, tag(1))); - service_.RequestResponseStream( - &srv_ctx, &recv_request, &srv_stream, &srv_cq_, tag(2)); + service_.RequestResponseStream(&srv_ctx, &recv_request, &srv_stream, &srv_cq_, + tag(2)); server_ok(2); client_ok(1); @@ -298,8 +286,7 @@ TEST_F(AsyncEnd2endTest, SimpleBidiStreaming) { std::unique_ptr > cli_stream(stub_->BidiStream(&cli_ctx, &cli_cq_, tag(1))); - service_.RequestBidiStream( - &srv_ctx, &srv_stream, &srv_cq_, tag(2)); + service_.RequestBidiStream(&srv_ctx, &srv_stream, &srv_cq_, tag(2)); server_ok(2); client_ok(1); @@ -357,8 +344,8 @@ TEST_F(AsyncEnd2endTest, ClientInitialMetadataRpc) { std::unique_ptr > response_reader( stub_->Echo(&cli_ctx, send_request, &cli_cq_, tag(1))); - service_.RequestEcho( - &srv_ctx, &recv_request, &response_writer, &srv_cq_, tag(2)); + service_.RequestEcho(&srv_ctx, &recv_request, &response_writer, &srv_cq_, + tag(2)); server_ok(2); EXPECT_EQ(send_request.message(), recv_request.message()); auto client_initial_metadata = srv_ctx.client_metadata(); @@ -399,8 +386,8 @@ TEST_F(AsyncEnd2endTest, ServerInitialMetadataRpc) { std::unique_ptr > response_reader( stub_->Echo(&cli_ctx, send_request, &cli_cq_, tag(1))); - service_.RequestEcho( - &srv_ctx, &recv_request, &response_writer, &srv_cq_, tag(2)); + service_.RequestEcho(&srv_ctx, &recv_request, &response_writer, &srv_cq_, + tag(2)); server_ok(2); EXPECT_EQ(send_request.message(), recv_request.message()); srv_ctx.AddInitialMetadata(meta1.first, meta1.second); @@ -447,8 +434,8 @@ TEST_F(AsyncEnd2endTest, ServerTrailingMetadataRpc) { std::unique_ptr > response_reader( stub_->Echo(&cli_ctx, send_request, &cli_cq_, tag(1))); - service_.RequestEcho( - &srv_ctx, &recv_request, &response_writer, &srv_cq_, tag(2)); + service_.RequestEcho(&srv_ctx, &recv_request, &response_writer, &srv_cq_, + tag(2)); server_ok(2); EXPECT_EQ(send_request.message(), recv_request.message()); response_writer.SendInitialMetadata(tag(3)); @@ -462,7 +449,6 @@ TEST_F(AsyncEnd2endTest, ServerTrailingMetadataRpc) { server_ok(4); - response_reader->Finish(&recv_response, &recv_status, tag(5)); client_ok(5); EXPECT_EQ(send_response.message(), recv_response.message()); @@ -491,10 +477,12 @@ TEST_F(AsyncEnd2endTest, MetadataRpc) { std::pair meta2( "key2-bin", {"\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc", 13}); std::pair meta3("key3", "val3"); - std::pair meta6("key4-bin", + std::pair meta6( + "key4-bin", {"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d", 14}); std::pair meta5("key5", "val5"); - std::pair meta4("key6-bin", + std::pair meta4( + "key6-bin", {"\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee", 15}); cli_ctx.AddMetadata(meta1.first, meta1.second); @@ -503,8 +491,8 @@ TEST_F(AsyncEnd2endTest, MetadataRpc) { std::unique_ptr > response_reader( stub_->Echo(&cli_ctx, send_request, &cli_cq_, tag(1))); - service_.RequestEcho( - &srv_ctx, &recv_request, &response_writer, &srv_cq_, tag(2)); + service_.RequestEcho(&srv_ctx, &recv_request, &response_writer, &srv_cq_, + tag(2)); server_ok(2); EXPECT_EQ(send_request.message(), recv_request.message()); auto client_initial_metadata = srv_ctx.client_metadata(); @@ -531,7 +519,6 @@ TEST_F(AsyncEnd2endTest, MetadataRpc) { server_ok(5); - response_reader->Finish(&recv_response, &recv_status, tag(6)); client_ok(6); EXPECT_EQ(send_response.message(), recv_response.message()); diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index d4ca3ef49e4..f5ecd1a20c1 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -160,8 +160,8 @@ class End2endTest : public ::testing::Test { void TearDown() override { server_->Shutdown(); } void ResetStub() { - std::shared_ptr channel = - CreateChannel(server_address_.str(), ChannelArguments()); + std::shared_ptr channel = CreateChannel( + server_address_.str(), InsecureCredentials(), ChannelArguments()); stub_.reset(grpc::cpp::test::util::TestService::NewStub(channel)); } @@ -328,8 +328,7 @@ TEST_F(End2endTest, ResponseStream) { ClientContext context; request.set_message("hello"); - ClientReader* stream = - stub_->ResponseStream(&context, request); + ClientReader* stream = stub_->ResponseStream(&context, request); EXPECT_TRUE(stream->Read(&response)); EXPECT_EQ(response.message(), request.message() + "0"); EXPECT_TRUE(stream->Read(&response)); @@ -381,8 +380,8 @@ TEST_F(End2endTest, BidiStream) { // Talk to the two services with the same name but different package names. // The two stubs are created on the same channel. TEST_F(End2endTest, DiffPackageServices) { - std::shared_ptr channel = - CreateChannel(server_address_.str(), ChannelArguments()); + std::shared_ptr channel = CreateChannel( + server_address_.str(), InsecureCredentials(), ChannelArguments()); EchoRequest request; EchoResponse response; @@ -407,8 +406,7 @@ TEST_F(End2endTest, DiffPackageServices) { // rpc and stream should fail on bad credentials. TEST_F(End2endTest, BadCredentials) { std::unique_ptr bad_creds = - CredentialsFactory::ServiceAccountCredentials("", "", - std::chrono::seconds(1)); + ServiceAccountCredentials("", "", std::chrono::seconds(1)); EXPECT_EQ(nullptr, bad_creds.get()); std::shared_ptr channel = CreateChannel(server_address_.str(), bad_creds, ChannelArguments()); diff --git a/test/cpp/interop/client.cc b/test/cpp/interop/client.cc index 78f2063c45b..abe0aaccd5a 100644 --- a/test/cpp/interop/client.cc +++ b/test/cpp/interop/client.cc @@ -80,9 +80,10 @@ DEFINE_string(oauth_scope, "", "Scope for OAuth tokens."); using grpc::ChannelInterface; using grpc::ClientContext; +using grpc::ComputeEngineCredentials; using grpc::CreateTestChannel; using grpc::Credentials; -using grpc::CredentialsFactory; +using grpc::ServiceAccountCredentials; using grpc::testing::ResponseParameters; using grpc::testing::SimpleRequest; using grpc::testing::SimpleResponse; @@ -94,8 +95,8 @@ using grpc::testing::TestService; // In some distros, gflags is in the namespace google, and in some others, // in gflags. This hack is enabling us to find both. -namespace google { } -namespace gflags { } +namespace google {} +namespace gflags {} using namespace google; using namespace gflags; @@ -133,14 +134,14 @@ std::shared_ptr CreateChannelForTestCase( std::unique_ptr creds; GPR_ASSERT(FLAGS_enable_ssl); grpc::string json_key = GetServiceAccountJsonKey(); - creds = CredentialsFactory::ServiceAccountCredentials( - json_key, FLAGS_oauth_scope, std::chrono::hours(1)); + creds = ServiceAccountCredentials(json_key, FLAGS_oauth_scope, + std::chrono::hours(1)); return CreateTestChannel(host_port, FLAGS_server_host_override, FLAGS_enable_ssl, FLAGS_use_prod_roots, creds); } else if (test_case == "compute_engine_creds") { std::unique_ptr creds; GPR_ASSERT(FLAGS_enable_ssl); - creds = CredentialsFactory::ComputeEngineCredentials(); + creds = ComputeEngineCredentials(); return CreateTestChannel(host_port, FLAGS_server_host_override, FLAGS_enable_ssl, FLAGS_use_prod_roots, creds); } else { @@ -200,7 +201,7 @@ void DoComputeEngineCreds() { GPR_ASSERT(!response.username().empty()); GPR_ASSERT(response.username().c_str() == FLAGS_default_service_account); GPR_ASSERT(!response.oauth_scope().empty()); - const char *oauth_scope_str = response.oauth_scope().c_str(); + const char* oauth_scope_str = response.oauth_scope().c_str(); GPR_ASSERT(FLAGS_oauth_scope.find(oauth_scope_str) != grpc::string::npos); gpr_log(GPR_INFO, "Large unary with compute engine creds done."); } @@ -219,7 +220,7 @@ void DoServiceAccountCreds() { GPR_ASSERT(!response.oauth_scope().empty()); grpc::string json_key = GetServiceAccountJsonKey(); GPR_ASSERT(json_key.find(response.username()) != grpc::string::npos); - const char *oauth_scope_str = response.oauth_scope().c_str(); + const char* oauth_scope_str = response.oauth_scope().c_str(); GPR_ASSERT(FLAGS_oauth_scope.find(oauth_scope_str) != grpc::string::npos); gpr_log(GPR_INFO, "Large unary with service account creds done."); } diff --git a/test/cpp/interop/server.cc b/test/cpp/interop/server.cc index 263bd8e3042..7a7287438f2 100644 --- a/test/cpp/interop/server.cc +++ b/test/cpp/interop/server.cc @@ -77,8 +77,8 @@ using grpc::Status; // In some distros, gflags is in the namespace google, and in some others, // in gflags. This hack is enabling us to find both. -namespace google { } -namespace gflags { } +namespace google {} +namespace gflags {} using namespace google; using namespace gflags; @@ -215,8 +215,7 @@ void RunServer() { if (FLAGS_enable_ssl) { SslServerCredentialsOptions ssl_opts = { "", {{test_server1_key, test_server1_cert}}}; - std::shared_ptr creds = - ServerCredentialsFactory::SslCredentials(ssl_opts); + std::shared_ptr creds = ServerSslCredentials(ssl_opts); builder.SetCredentials(creds); } std::unique_ptr server(builder.BuildAndStart()); diff --git a/test/cpp/util/create_test_channel.cc b/test/cpp/util/create_test_channel.cc index b0472d32a99..278172f6ff6 100644 --- a/test/cpp/util/create_test_channel.cc +++ b/test/cpp/util/create_test_channel.cc @@ -61,12 +61,10 @@ std::shared_ptr CreateTestChannel( const std::unique_ptr& creds) { ChannelArguments channel_args; if (enable_ssl) { - const char* roots_certs = - use_prod_roots ? "" : test_root_cert; + const char* roots_certs = use_prod_roots ? "" : test_root_cert; SslCredentialsOptions ssl_opts = {roots_certs, "", ""}; - std::unique_ptr channel_creds = - CredentialsFactory::SslCredentials(ssl_opts); + std::unique_ptr channel_creds = SslCredentials(ssl_opts); if (!server.empty() && !override_hostname.empty()) { channel_args.SetSslTargetNameOverride(override_hostname); @@ -74,12 +72,11 @@ std::shared_ptr CreateTestChannel( const grpc::string& connect_to = server.empty() ? override_hostname : server; if (creds.get()) { - channel_creds = - CredentialsFactory::ComposeCredentials(creds, channel_creds); + channel_creds = ComposeCredentials(creds, channel_creds); } return CreateChannel(connect_to, channel_creds, channel_args); } else { - return CreateChannel(server, channel_args); + return CreateChannel(server, InsecureCredentials(), channel_args); } } From 759026cbf0419dae4edddd9e75fa338e1028a3d8 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Sun, 22 Feb 2015 23:09:45 -0800 Subject: [PATCH 002/120] Server API simplification Remove 'secure_serer_create', and instead attach credentials to ports, meaning different ports can serve different credentials. --- Makefile | 3 - build.json | 1 - include/grpc/grpc_security.h | 9 +-- src/core/security/factories.c | 28 -------- src/core/security/server_secure_chttp2.c | 70 +++++++++++++++---- src/core/surface/secure_server_create.c | 57 --------------- test/core/echo/server.c | 4 +- .../end2end/fixtures/chttp2_fake_security.c | 4 +- .../fixtures/chttp2_simple_ssl_fullstack.c | 4 +- .../chttp2_simple_ssl_with_oauth2_fullstack.c | 4 +- test/core/fling/server.c | 4 +- vsprojects/vs2013/grpc.vcxproj | 2 - vsprojects/vs2013/grpc.vcxproj.filters | 3 - vsprojects/vs2013/grpc_shared.vcxproj | 2 - vsprojects/vs2013/grpc_shared.vcxproj.filters | 3 - 15 files changed, 67 insertions(+), 131 deletions(-) delete mode 100644 src/core/surface/secure_server_create.c diff --git a/Makefile b/Makefile index 8bb6b7f1ac3..df6d01c5932 100644 --- a/Makefile +++ b/Makefile @@ -2315,7 +2315,6 @@ LIBGRPC_SRC = \ src/core/security/security_context.c \ src/core/security/server_secure_chttp2.c \ src/core/surface/secure_channel_create.c \ - src/core/surface/secure_server_create.c \ src/core/tsi/fake_transport_security.c \ src/core/tsi/ssl_transport_security.c \ src/core/tsi/transport_security.c \ @@ -2456,7 +2455,6 @@ src/core/security/secure_transport_setup.c: $(OPENSSL_DEP) src/core/security/security_context.c: $(OPENSSL_DEP) src/core/security/server_secure_chttp2.c: $(OPENSSL_DEP) src/core/surface/secure_channel_create.c: $(OPENSSL_DEP) -src/core/surface/secure_server_create.c: $(OPENSSL_DEP) src/core/tsi/fake_transport_security.c: $(OPENSSL_DEP) src/core/tsi/ssl_transport_security.c: $(OPENSSL_DEP) src/core/tsi/transport_security.c: $(OPENSSL_DEP) @@ -2614,7 +2612,6 @@ $(OBJDIR)/$(CONFIG)/src/core/security/secure_transport_setup.o: $(OBJDIR)/$(CONFIG)/src/core/security/security_context.o: $(OBJDIR)/$(CONFIG)/src/core/security/server_secure_chttp2.o: $(OBJDIR)/$(CONFIG)/src/core/surface/secure_channel_create.o: -$(OBJDIR)/$(CONFIG)/src/core/surface/secure_server_create.o: $(OBJDIR)/$(CONFIG)/src/core/tsi/fake_transport_security.o: $(OBJDIR)/$(CONFIG)/src/core/tsi/ssl_transport_security.o: $(OBJDIR)/$(CONFIG)/src/core/tsi/transport_security.o: diff --git a/build.json b/build.json index 9ab59f93795..1e9b4d72a35 100644 --- a/build.json +++ b/build.json @@ -381,7 +381,6 @@ "src/core/security/security_context.c", "src/core/security/server_secure_chttp2.c", "src/core/surface/secure_channel_create.c", - "src/core/surface/secure_server_create.c", "src/core/tsi/fake_transport_security.c", "src/core/tsi/ssl_transport_security.c", "src/core/tsi/transport_security.c" diff --git a/include/grpc/grpc_security.h b/include/grpc/grpc_security.h index 0eae444a9b7..196bb3c0e64 100644 --- a/include/grpc/grpc_security.h +++ b/include/grpc/grpc_security.h @@ -168,17 +168,12 @@ grpc_server_credentials *grpc_fake_transport_security_server_credentials_create( /* --- Secure server creation. --- */ -/* Creates a secure server using the passed-in server credentials. */ -grpc_server *grpc_secure_server_create(grpc_server_credentials *creds, - grpc_completion_queue *cq, - const grpc_channel_args *args); - /* Add a HTTP2 over an encrypted link over tcp listener. Server must have been created with grpc_secure_server_create. Returns bound port number on success, 0 on failure. REQUIRES: server not started */ -int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr); - +int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr, + grpc_server_credentials *creds); #ifdef __cplusplus } diff --git a/src/core/security/factories.c b/src/core/security/factories.c index c9701b9080d..372ee256f2a 100644 --- a/src/core/security/factories.c +++ b/src/core/security/factories.c @@ -50,31 +50,3 @@ grpc_channel *grpc_secure_channel_create(grpc_credentials *creds, return grpc_secure_channel_create_with_factories( factories, GPR_ARRAY_SIZE(factories), creds, target, args); } - -grpc_server *grpc_secure_server_create(grpc_server_credentials *creds, - grpc_completion_queue *cq, - const grpc_channel_args *args) { - grpc_security_status status = GRPC_SECURITY_ERROR; - grpc_security_context *ctx = NULL; - grpc_server *server = NULL; - if (creds == NULL) return NULL; /* TODO(ctiller): Return lame server. */ - - if (!strcmp(creds->type, GRPC_CREDENTIALS_TYPE_SSL)) { - status = grpc_ssl_server_security_context_create( - grpc_ssl_server_credentials_get_config(creds), &ctx); - } else if (!strcmp(creds->type, - GRPC_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY)) { - ctx = grpc_fake_server_security_context_create(); - status = GRPC_SECURITY_OK; - } - - if (status != GRPC_SECURITY_OK) { - gpr_log(GPR_ERROR, - "Unable to create secure server with credentials of type %s.", - creds->type); - return NULL; /* TODO(ctiller): Return lame server. */ - } - server = grpc_secure_server_create_internal(cq, args, ctx); - grpc_security_context_unref(ctx); - return server; -} diff --git a/src/core/security/server_secure_chttp2.c b/src/core/security/server_secure_chttp2.c index c88f0726bb7..4dcd4b55244 100644 --- a/src/core/security/server_secure_chttp2.c +++ b/src/core/security/server_secure_chttp2.c @@ -33,6 +33,8 @@ #include +#include + #include "src/core/channel/http_filter.h" #include "src/core/channel/http_server_filter.h" #include "src/core/iomgr/resolve_address.h" @@ -66,37 +68,64 @@ static void on_secure_transport_setup_done(void *server, } } -static void on_accept(void *server, grpc_endpoint *tcp) { - const grpc_channel_args *args = grpc_server_get_channel_args(server); - grpc_security_context *ctx = grpc_find_security_context_in_args(args); - GPR_ASSERT(ctx); - grpc_setup_secure_transport(ctx, tcp, on_secure_transport_setup_done, server); -} +typedef struct { + grpc_tcp_server *tcp; + grpc_security_context *ctx; + grpc_server *server; +} secured_port; -/* Note: the following code is the same with server_chttp2.c */ +static void on_accept(void *spp, grpc_endpoint *tcp) { + secured_port *sp = spp; + grpc_setup_secure_transport(sp->ctx, tcp, on_secure_transport_setup_done, sp->server); +} /* Server callback: start listening on our ports */ -static void start(grpc_server *server, void *tcpp, grpc_pollset **pollsets, +static void start(grpc_server *server, void *spp, grpc_pollset **pollsets, size_t pollset_count) { - grpc_tcp_server *tcp = tcpp; - grpc_tcp_server_start(tcp, pollsets, pollset_count, on_accept, server); + secured_port *sp = spp; + grpc_tcp_server_start(sp->tcp, pollsets, pollset_count, on_accept, sp); } /* Server callback: destroy the tcp listener (so we don't generate further callbacks) */ -static void destroy(grpc_server *server, void *tcpp) { - grpc_tcp_server *tcp = tcpp; - grpc_tcp_server_destroy(tcp); +static void destroy(grpc_server *server, void *spp) { + secured_port *sp = spp; + grpc_tcp_server_destroy(sp->tcp); + grpc_security_context_unref(sp->ctx); + gpr_free(sp); } -int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr) { +int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr, grpc_server_credentials *creds) { grpc_resolved_addresses *resolved = NULL; grpc_tcp_server *tcp = NULL; size_t i; unsigned count = 0; int port_num = -1; int port_temp; + grpc_security_status status = GRPC_SECURITY_ERROR; + grpc_security_context *ctx = NULL; + secured_port *sp = NULL; + + /* create security context */ + if (creds == NULL) goto error; + + if (!strcmp(creds->type, GRPC_CREDENTIALS_TYPE_SSL)) { + status = grpc_ssl_server_security_context_create( + grpc_ssl_server_credentials_get_config(creds), &ctx); + } else if (!strcmp(creds->type, + GRPC_CREDENTIALS_TYPE_FAKE_TRANSPORT_SECURITY)) { + ctx = grpc_fake_server_security_context_create(); + status = GRPC_SECURITY_OK; + } + if (status != GRPC_SECURITY_OK) { + gpr_log(GPR_ERROR, + "Unable to create secure server with credentials of type %s.", + creds->type); + goto error; + } + + /* resolve address */ resolved = grpc_blocking_resolve_address(addr, "https"); if (!resolved) { goto error; @@ -132,18 +161,29 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr) { } grpc_resolved_addresses_destroy(resolved); + sp = gpr_malloc(sizeof(secured_port)); + sp->tcp = tcp; + sp->ctx = ctx; + sp->server = server; + /* Register with the server only upon success */ - grpc_server_add_listener(server, tcp, start, destroy); + grpc_server_add_listener(server, sp, start, destroy); return port_num; /* Error path: cleanup and return */ error: + if (ctx) { + grpc_security_context_unref(ctx); + } if (resolved) { grpc_resolved_addresses_destroy(resolved); } if (tcp) { grpc_tcp_server_destroy(tcp); } + if (sp) { + gpr_free(sp); + } return 0; } diff --git a/src/core/surface/secure_server_create.c b/src/core/surface/secure_server_create.c deleted file mode 100644 index 1d5b9279977..00000000000 --- a/src/core/surface/secure_server_create.c +++ /dev/null @@ -1,57 +0,0 @@ -/* - * - * Copyright 2015, Google Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following disclaimer - * in the documentation and/or other materials provided with the - * distribution. - * * Neither the name of Google Inc. nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - */ - -#include - -#include "src/core/channel/channel_args.h" -#include "src/core/security/security_context.h" -#include "src/core/surface/completion_queue.h" -#include "src/core/surface/server.h" -#include - -grpc_server *grpc_secure_server_create_internal( - grpc_completion_queue *cq, const grpc_channel_args *args, - grpc_security_context *context) { - grpc_arg context_arg; - grpc_channel_args *args_copy; - grpc_server *server; - if (grpc_find_security_context_in_args(args) != NULL) { - gpr_log(GPR_ERROR, "Cannot set security context in channel args."); - } - - context_arg = grpc_security_context_to_arg(context); - args_copy = grpc_channel_args_copy_and_add(args, &context_arg); - server = grpc_server_create_from_filters(cq, NULL, 0, args_copy); - grpc_channel_args_destroy(args_copy); - return server; -} diff --git a/test/core/echo/server.c b/test/core/echo/server.c index 83da8b644d6..8c9175e3cf9 100644 --- a/test/core/echo/server.c +++ b/test/core/echo/server.c @@ -143,8 +143,8 @@ int main(int argc, char **argv) { test_server1_cert}; grpc_server_credentials *ssl_creds = grpc_ssl_server_credentials_create(NULL, &pem_key_cert_pair, 1); - server = grpc_secure_server_create(ssl_creds, cq, &args); - GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr)); + server = grpc_server_create(cq, &args); + GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr, ssl_creds)); grpc_server_credentials_release(ssl_creds); } else { server = grpc_server_create(cq, &args); diff --git a/test/core/end2end/fixtures/chttp2_fake_security.c b/test/core/end2end/fixtures/chttp2_fake_security.c index 039909f76cb..6079b550d83 100644 --- a/test/core/end2end/fixtures/chttp2_fake_security.c +++ b/test/core/end2end/fixtures/chttp2_fake_security.c @@ -84,9 +84,9 @@ static void chttp2_init_server_secure_fullstack( grpc_server_destroy(f->server); } f->server = - grpc_secure_server_create(server_creds, f->server_cq, server_args); + grpc_server_create(f->server_cq, server_args); + GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, server_creds)); grpc_server_credentials_release(server_creds); - GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr)); grpc_server_start(f->server); } diff --git a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c index 1db9e727b86..9af2f46410c 100644 --- a/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c +++ b/test/core/end2end/fixtures/chttp2_simple_ssl_fullstack.c @@ -87,9 +87,9 @@ static void chttp2_init_server_secure_fullstack( grpc_server_destroy(f->server); } f->server = - grpc_secure_server_create(server_creds, f->server_cq, server_args); + grpc_server_create(f->server_cq, server_args); + GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, server_creds)); grpc_server_credentials_release(server_creds); - GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr)); grpc_server_start(f->server); } diff --git a/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c b/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c index 35e022c4947..0be0a2302a0 100644 --- a/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c +++ b/test/core/end2end/fixtures/chttp2_simple_ssl_with_oauth2_fullstack.c @@ -85,9 +85,9 @@ static void chttp2_init_server_secure_fullstack( grpc_server_destroy(f->server); } f->server = - grpc_secure_server_create(server_creds, f->server_cq, server_args); + grpc_server_create(f->server_cq, server_args); + GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr, server_creds)); grpc_server_credentials_release(server_creds); - GPR_ASSERT(grpc_server_add_secure_http2_port(f->server, ffd->localaddr)); grpc_server_start(f->server); } diff --git a/test/core/fling/server.c b/test/core/fling/server.c index 59c303015a3..4f29c3b5cfa 100644 --- a/test/core/fling/server.c +++ b/test/core/fling/server.c @@ -205,8 +205,8 @@ int main(int argc, char **argv) { test_server1_cert}; grpc_server_credentials *ssl_creds = grpc_ssl_server_credentials_create(NULL, &pem_key_cert_pair, 1); - server = grpc_secure_server_create(ssl_creds, cq, NULL); - GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr)); + server = grpc_server_create(cq, NULL); + GPR_ASSERT(grpc_server_add_secure_http2_port(server, addr, ssl_creds)); grpc_server_credentials_release(ssl_creds); } else { server = grpc_server_create(cq, NULL); diff --git a/vsprojects/vs2013/grpc.vcxproj b/vsprojects/vs2013/grpc.vcxproj index 89c0de333c9..1b4005e0363 100644 --- a/vsprojects/vs2013/grpc.vcxproj +++ b/vsprojects/vs2013/grpc.vcxproj @@ -215,8 +215,6 @@ - - diff --git a/vsprojects/vs2013/grpc.vcxproj.filters b/vsprojects/vs2013/grpc.vcxproj.filters index a2d9f30eda7..949be751807 100644 --- a/vsprojects/vs2013/grpc.vcxproj.filters +++ b/vsprojects/vs2013/grpc.vcxproj.filters @@ -43,9 +43,6 @@ src\core\surface - - src\core\surface - src\core\tsi diff --git a/vsprojects/vs2013/grpc_shared.vcxproj b/vsprojects/vs2013/grpc_shared.vcxproj index 81a280d912a..6bbe656a809 100644 --- a/vsprojects/vs2013/grpc_shared.vcxproj +++ b/vsprojects/vs2013/grpc_shared.vcxproj @@ -219,8 +219,6 @@ - - diff --git a/vsprojects/vs2013/grpc_shared.vcxproj.filters b/vsprojects/vs2013/grpc_shared.vcxproj.filters index a2d9f30eda7..949be751807 100644 --- a/vsprojects/vs2013/grpc_shared.vcxproj.filters +++ b/vsprojects/vs2013/grpc_shared.vcxproj.filters @@ -43,9 +43,6 @@ src\core\surface - - src\core\surface - src\core\tsi From 42bc87c0979f7a9f3084366fd466d382cf86ec17 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 23 Feb 2015 08:50:19 -0800 Subject: [PATCH 003/120] Update C++ server with new core API And reflects the C++ API in ServerBuilder. --- Makefile | 8 +++ build.json | 5 +- examples/pubsub/main.cc | 4 +- examples/pubsub/publisher_test.cc | 5 +- examples/pubsub/subscriber_test.cc | 5 +- include/grpc++/server.h | 11 ++- include/grpc++/server_builder.h | 16 +++-- include/grpc++/server_credentials.h | 29 ++++---- include/grpc/grpc.h | 3 + src/core/security/factories.c | 2 +- src/core/security/security_context.c | 1 - src/core/surface/lame_client.c | 2 +- src/cpp/client/create_channel.cc | 3 +- .../server/insecure_server_credentials.cc} | 22 ++++-- src/cpp/server/secure_server_credentials.cc | 70 +++++++++++++++++++ src/cpp/server/server.cc | 27 ++----- src/cpp/server/server_builder.cc | 23 +++--- src/cpp/server/server_credentials.cc | 22 +----- test/core/surface/lame_client_test.c | 2 +- test/cpp/end2end/async_end2end_test.cc | 3 +- test/cpp/end2end/end2end_test.cc | 3 +- test/cpp/interop/server.cc | 7 +- test/cpp/qps/server.cc | 3 +- tools/run_tests/run_tests.py | 2 +- vsprojects/vs2013/grpc.vcxproj | 1 - vsprojects/vs2013/grpc.vcxproj.filters | 3 - vsprojects/vs2013/grpc_shared.vcxproj | 1 - vsprojects/vs2013/grpc_shared.vcxproj.filters | 3 - vsprojects/vs2013/grpc_unsecure.vcxproj | 1 - .../vs2013/grpc_unsecure.vcxproj.filters | 3 - 30 files changed, 165 insertions(+), 125 deletions(-) rename src/{core/surface/lame_client.h => cpp/server/insecure_server_credentials.cc} (75%) create mode 100644 src/cpp/server/secure_server_credentials.cc diff --git a/Makefile b/Makefile index df6d01c5932..36a4df4fea7 100644 --- a/Makefile +++ b/Makefile @@ -3022,6 +3022,7 @@ $(OBJDIR)/$(CONFIG)/src/core/transport/transport.o: LIBGRPC++_SRC = \ src/cpp/client/secure_credentials.cc \ + src/cpp/server/secure_server_credentials.cc \ src/cpp/client/channel.cc \ src/cpp/client/channel_arguments.cc \ src/cpp/client/client_context.cc \ @@ -3034,6 +3035,7 @@ LIBGRPC++_SRC = \ src/cpp/common/completion_queue.cc \ src/cpp/common/rpc_method.cc \ src/cpp/proto/proto_utils.cc \ + src/cpp/server/insecure_server_credentials.cc \ src/cpp/server/server.cc \ src/cpp/server/server_builder.cc \ src/cpp/server/server_context.cc \ @@ -3101,6 +3103,7 @@ ifneq ($(OPENSSL_DEP),) # installing headers to their final destination on the drive. We need this # otherwise parallel compilation will fail if a source is compiled first. src/cpp/client/secure_credentials.cc: $(OPENSSL_DEP) +src/cpp/server/secure_server_credentials.cc: $(OPENSSL_DEP) src/cpp/client/channel.cc: $(OPENSSL_DEP) src/cpp/client/channel_arguments.cc: $(OPENSSL_DEP) src/cpp/client/client_context.cc: $(OPENSSL_DEP) @@ -3113,6 +3116,7 @@ src/cpp/common/call.cc: $(OPENSSL_DEP) src/cpp/common/completion_queue.cc: $(OPENSSL_DEP) src/cpp/common/rpc_method.cc: $(OPENSSL_DEP) src/cpp/proto/proto_utils.cc: $(OPENSSL_DEP) +src/cpp/server/insecure_server_credentials.cc: $(OPENSSL_DEP) src/cpp/server/server.cc: $(OPENSSL_DEP) src/cpp/server/server_builder.cc: $(OPENSSL_DEP) src/cpp/server/server_context.cc: $(OPENSSL_DEP) @@ -3169,6 +3173,7 @@ endif endif $(OBJDIR)/$(CONFIG)/src/cpp/client/secure_credentials.o: +$(OBJDIR)/$(CONFIG)/src/cpp/server/secure_server_credentials.o: $(OBJDIR)/$(CONFIG)/src/cpp/client/channel.o: $(OBJDIR)/$(CONFIG)/src/cpp/client/channel_arguments.o: $(OBJDIR)/$(CONFIG)/src/cpp/client/client_context.o: @@ -3181,6 +3186,7 @@ $(OBJDIR)/$(CONFIG)/src/cpp/common/call.o: $(OBJDIR)/$(CONFIG)/src/cpp/common/completion_queue.o: $(OBJDIR)/$(CONFIG)/src/cpp/common/rpc_method.o: $(OBJDIR)/$(CONFIG)/src/cpp/proto/proto_utils.o: +$(OBJDIR)/$(CONFIG)/src/cpp/server/insecure_server_credentials.o: $(OBJDIR)/$(CONFIG)/src/cpp/server/server.o: $(OBJDIR)/$(CONFIG)/src/cpp/server/server_builder.o: $(OBJDIR)/$(CONFIG)/src/cpp/server/server_context.o: @@ -3268,6 +3274,7 @@ LIBGRPC++_UNSECURE_SRC = \ src/cpp/common/completion_queue.cc \ src/cpp/common/rpc_method.cc \ src/cpp/proto/proto_utils.cc \ + src/cpp/server/insecure_server_credentials.cc \ src/cpp/server/server.cc \ src/cpp/server/server_builder.cc \ src/cpp/server/server_context.cc \ @@ -3363,6 +3370,7 @@ $(OBJDIR)/$(CONFIG)/src/cpp/common/call.o: $(OBJDIR)/$(CONFIG)/src/cpp/common/completion_queue.o: $(OBJDIR)/$(CONFIG)/src/cpp/common/rpc_method.o: $(OBJDIR)/$(CONFIG)/src/cpp/proto/proto_utils.o: +$(OBJDIR)/$(CONFIG)/src/cpp/server/insecure_server_credentials.o: $(OBJDIR)/$(CONFIG)/src/cpp/server/server.o: $(OBJDIR)/$(CONFIG)/src/cpp/server/server_builder.o: $(OBJDIR)/$(CONFIG)/src/cpp/server/server_context.o: diff --git a/build.json b/build.json index 1e9b4d72a35..007b4913fb4 100644 --- a/build.json +++ b/build.json @@ -54,6 +54,7 @@ "src/cpp/common/completion_queue.cc", "src/cpp/common/rpc_method.cc", "src/cpp/proto/proto_utils.cc", + "src/cpp/server/insecure_server_credentials.cc", "src/cpp/server/server.cc", "src/cpp/server/server_builder.cc", "src/cpp/server/server_context.cc", @@ -133,7 +134,6 @@ "src/core/surface/client.h", "src/core/surface/completion_queue.h", "src/core/surface/event_string.h", - "src/core/surface/lame_client.h", "src/core/surface/server.h", "src/core/surface/surface_trace.h", "src/core/transport/chttp2/bin_encoder.h", @@ -437,7 +437,8 @@ "build": "all", "language": "c++", "src": [ - "src/cpp/client/secure_credentials.cc" + "src/cpp/client/secure_credentials.cc", + "src/cpp/server/secure_server_credentials.cc" ], "deps": [ "gpr", diff --git a/examples/pubsub/main.cc b/examples/pubsub/main.cc index 39fb8aea15c..066cfa1e017 100644 --- a/examples/pubsub/main.cc +++ b/examples/pubsub/main.cc @@ -96,10 +96,10 @@ int main(int argc, char** argv) { std::unique_ptr creds; if (FLAGS_service_account_key_file != "") { grpc::string json_key = GetServiceAccountJsonKey(); - creds = grpc::CredentialsFactory::ServiceAccountCredentials( + creds = grpc::ServiceAccountCredentials( json_key, FLAGS_oauth_scope, std::chrono::hours(1)); } else { - creds = grpc::CredentialsFactory::ComputeEngineCredentials(); + creds = grpc::ComputeEngineCredentials(); } ss << FLAGS_server_host << ":" << FLAGS_server_port; diff --git a/examples/pubsub/publisher_test.cc b/examples/pubsub/publisher_test.cc index b7bea5b1bd2..0bb4b842176 100644 --- a/examples/pubsub/publisher_test.cc +++ b/examples/pubsub/publisher_test.cc @@ -40,6 +40,7 @@ #include #include #include +#include #include #include @@ -106,11 +107,11 @@ class PublisherTest : public ::testing::Test { int port = grpc_pick_unused_port_or_die(); server_address_ << "localhost:" << port; ServerBuilder builder; - builder.AddPort(server_address_.str()); + builder.AddPort(server_address_.str(), grpc::InsecureServerCredentials()); builder.RegisterService(&service_); server_ = builder.BuildAndStart(); - channel_ = CreateChannel(server_address_.str(), ChannelArguments()); + channel_ = CreateChannel(server_address_.str(), grpc::InsecureCredentials(), ChannelArguments()); publisher_.reset(new grpc::examples::pubsub::Publisher(channel_)); } diff --git a/examples/pubsub/subscriber_test.cc b/examples/pubsub/subscriber_test.cc index 1fdcc8f755f..49738fcda62 100644 --- a/examples/pubsub/subscriber_test.cc +++ b/examples/pubsub/subscriber_test.cc @@ -40,6 +40,7 @@ #include #include #include +#include #include #include @@ -105,11 +106,11 @@ class SubscriberTest : public ::testing::Test { int port = grpc_pick_unused_port_or_die(); server_address_ << "localhost:" << port; ServerBuilder builder; - builder.AddPort(server_address_.str()); + builder.AddPort(server_address_.str(), grpc::InsecureServerCredentials()); builder.RegisterService(&service_); server_ = builder.BuildAndStart(); - channel_ = CreateChannel(server_address_.str(), ChannelArguments()); + channel_ = CreateChannel(server_address_.str(), grpc::InsecureCredentials(), ChannelArguments()); subscriber_.reset(new grpc::examples::pubsub::Subscriber(channel_)); } diff --git a/include/grpc++/server.h b/include/grpc++/server.h index 26d18d1bbe4..eeee6502ab7 100644 --- a/include/grpc++/server.h +++ b/include/grpc++/server.h @@ -76,15 +76,14 @@ class Server final : private CallHook, class AsyncRequest; // ServerBuilder use only - Server(ThreadPoolInterface* thread_pool, bool thread_pool_owned, - ServerCredentials* creds); - Server(); + Server(ThreadPoolInterface* thread_pool, bool thread_pool_owned); + Server() = delete; // Register a service. This call does not take ownership of the service. // The service must exist for the lifetime of the Server instance. bool RegisterService(RpcService* service); bool RegisterAsyncService(AsynchronousService* service); // Add a listening port. Can be called multiple times. - int AddPort(const grpc::string& addr); + int AddPort(const grpc::string& addr, ServerCredentials* creds); // Start the server. bool Start(); @@ -114,13 +113,11 @@ class Server final : private CallHook, std::list sync_methods_; // Pointer to the c grpc server. - grpc_server* server_; + grpc_server* const server_; ThreadPoolInterface* thread_pool_; // Whether the thread pool is created and owned by the server. bool thread_pool_owned_; - // Whether the server is created with credentials. - bool secure_; }; } // namespace grpc diff --git a/include/grpc++/server_builder.h b/include/grpc++/server_builder.h index 4545c413d25..578e102d6de 100644 --- a/include/grpc++/server_builder.h +++ b/include/grpc++/server_builder.h @@ -65,11 +65,9 @@ class ServerBuilder { void RegisterAsyncService(AsynchronousService* service); // Add a listening port. Can be called multiple times. - void AddPort(const grpc::string& addr); - - // Set a ServerCredentials. Can only be called once. - // TODO(yangg) move this to be part of AddPort - void SetCredentials(const std::shared_ptr& creds); + void AddPort(const grpc::string& addr, + std::shared_ptr creds, + int* selected_port = nullptr); // Set the thread pool used for running appliation rpc handlers. // Does not take ownership. @@ -79,9 +77,15 @@ class ServerBuilder { std::unique_ptr BuildAndStart(); private: + struct Port { + grpc::string addr; + std::shared_ptr creds; + int* selected_port; + }; + std::vector services_; std::vector async_services_; - std::vector ports_; + std::vector ports_; std::shared_ptr creds_; ThreadPoolInterface* thread_pool_ = nullptr; }; diff --git a/include/grpc++/server_credentials.h b/include/grpc++/server_credentials.h index 5c6787a0770..fd4d71db9ff 100644 --- a/include/grpc++/server_credentials.h +++ b/include/grpc++/server_credentials.h @@ -39,24 +39,21 @@ #include -struct grpc_server_credentials; +struct grpc_server; namespace grpc { +class Server; // grpc_server_credentials wrapper class. -class ServerCredentials final { +class ServerCredentials { public: - ~ServerCredentials(); + virtual ~ServerCredentials(); private: - explicit ServerCredentials(grpc_server_credentials* c_creds); + friend class ::grpc::Server; - grpc_server_credentials* GetRawCreds(); - - friend class ServerCredentialsFactory; - friend class Server; - - grpc_server_credentials* creds_; + virtual int AddPortToServer(const grpc::string& addr, + grpc_server* server) = 0; }; // Options to create ServerCredentials with SSL @@ -69,13 +66,11 @@ struct SslServerCredentialsOptions { std::vector pem_key_cert_pairs; }; -// Factory for building different types of ServerCredentials -class ServerCredentialsFactory { - public: - // Builds SSL ServerCredentials given SSL specific options - static std::shared_ptr SslCredentials( - const SslServerCredentialsOptions& options); -}; +// Builds SSL ServerCredentials given SSL specific options +std::shared_ptr SslServerCredentials( + const SslServerCredentialsOptions& options); + +std::shared_ptr InsecureServerCredentials(); } // namespace grpc diff --git a/include/grpc/grpc.h b/include/grpc/grpc.h index 4a720d11f85..2df80b1e310 100644 --- a/include/grpc/grpc.h +++ b/include/grpc/grpc.h @@ -436,6 +436,9 @@ grpc_call_error grpc_call_start_batch(grpc_call *call, const grpc_op *ops, grpc_channel *grpc_channel_create(const char *target, const grpc_channel_args *args); +/* Create a lame client: this client fails every operation attempted on it. */ +grpc_channel *grpc_lame_client_channel_create(void); + /* Close and destroy a grpc channel */ void grpc_channel_destroy(grpc_channel *channel); diff --git a/src/core/security/factories.c b/src/core/security/factories.c index 372ee256f2a..02267d55457 100644 --- a/src/core/security/factories.c +++ b/src/core/security/factories.c @@ -33,9 +33,9 @@ #include +#include #include "src/core/security/credentials.h" #include "src/core/security/security_context.h" -#include "src/core/surface/lame_client.h" #include #include #include diff --git a/src/core/security/security_context.c b/src/core/security/security_context.c index fd8baff539d..4888043e6b1 100644 --- a/src/core/security/security_context.c +++ b/src/core/security/security_context.c @@ -42,7 +42,6 @@ #include "src/core/support/env.h" #include "src/core/support/file.h" #include "src/core/support/string.h" -#include "src/core/surface/lame_client.h" #include "src/core/transport/chttp2/alpn.h" #include #include diff --git a/src/core/surface/lame_client.c b/src/core/surface/lame_client.c index 57f6ddf0f7f..b40c48381f4 100644 --- a/src/core/surface/lame_client.c +++ b/src/core/surface/lame_client.c @@ -31,7 +31,7 @@ * */ -#include "src/core/surface/lame_client.h" +#include #include diff --git a/src/cpp/client/create_channel.cc b/src/cpp/client/create_channel.cc index ef2deb35563..57d215d0f33 100644 --- a/src/cpp/client/create_channel.cc +++ b/src/cpp/client/create_channel.cc @@ -43,6 +43,7 @@ class ChannelArguments; std::shared_ptr CreateChannel( const grpc::string &target, const std::unique_ptr &creds, const ChannelArguments &args) { - return creds->CreateChannel(target, args); + return creds ? creds->CreateChannel(target, args) : + std::shared_ptr(new Channel(target, grpc_lame_client_channel_create())); } } // namespace grpc diff --git a/src/core/surface/lame_client.h b/src/cpp/server/insecure_server_credentials.cc similarity index 75% rename from src/core/surface/lame_client.h rename to src/cpp/server/insecure_server_credentials.cc index 2bd97b95eb1..a99e1104cb0 100644 --- a/src/core/surface/lame_client.h +++ b/src/cpp/server/insecure_server_credentials.cc @@ -31,12 +31,22 @@ * */ -#ifndef __GRPC_INTERNAL_SURFACE_LAME_CLIENT_H_ -#define __GRPC_INTERNAL_SURFACE_LAME_CLIENT_H_ +#include -#include +#include -/* Create a lame client: this client fails every operation attempted on it. */ -grpc_channel *grpc_lame_client_channel_create(void); +namespace grpc { +namespace { +class InsecureServerCredentialsImpl final : public ServerCredentials { + public: + int AddPortToServer(const grpc::string& addr, grpc_server* server) { + return grpc_server_add_http2_port(server, addr.c_str()); + } +}; +} // namespace -#endif /* __GRPC_INTERNAL_SURFACE_LAME_CLIENT_H_ */ +std::shared_ptr InsecureServerCredentials() { + return std::shared_ptr(new InsecureServerCredentialsImpl()); +} + +} // namespace grpc diff --git a/src/cpp/server/secure_server_credentials.cc b/src/cpp/server/secure_server_credentials.cc new file mode 100644 index 00000000000..f90838b086d --- /dev/null +++ b/src/cpp/server/secure_server_credentials.cc @@ -0,0 +1,70 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include + +#include + +namespace grpc { + +namespace { +class SecureServerCredentials final : public ServerCredentials { + public: + explicit SecureServerCredentials(grpc_server_credentials* creds) : creds_(creds) {} + ~SecureServerCredentials() override { + grpc_server_credentials_release(creds_); + } + + int AddPortToServer(const grpc::string& addr, grpc_server* server) override { + return grpc_server_add_secure_http2_port(server, addr.c_str(), creds_); + } + + private: + grpc_server_credentials* const creds_; +}; +} // namespace + +std::shared_ptr SslServerCredentials( + const SslServerCredentialsOptions &options) { + std::vector pem_key_cert_pairs; + for (const auto &key_cert_pair : options.pem_key_cert_pairs) { + pem_key_cert_pairs.push_back( + {key_cert_pair.private_key.c_str(), key_cert_pair.cert_chain.c_str()}); + } + grpc_server_credentials *c_creds = grpc_ssl_server_credentials_create( + options.pem_root_certs.empty() ? nullptr : options.pem_root_certs.c_str(), + &pem_key_cert_pairs[0], pem_key_cert_pairs.size()); + return std::shared_ptr(new SecureServerCredentials(c_creds)); +} + +} // namespace grpc diff --git a/src/cpp/server/server.cc b/src/cpp/server/server.cc index f565d3aa5d5..0d81f0b126e 100644 --- a/src/cpp/server/server.cc +++ b/src/cpp/server/server.cc @@ -169,26 +169,13 @@ class Server::SyncRequest final : public CompletionQueueTag { grpc_completion_queue* cq_; }; -Server::Server(ThreadPoolInterface* thread_pool, bool thread_pool_owned, - ServerCredentials* creds) +Server::Server(ThreadPoolInterface* thread_pool, bool thread_pool_owned) : started_(false), shutdown_(false), num_running_cb_(0), + server_(grpc_server_create(cq_.cq(), nullptr)), thread_pool_(thread_pool), - thread_pool_owned_(thread_pool_owned), - secure_(creds != nullptr) { - if (creds) { - server_ = - grpc_secure_server_create(creds->GetRawCreds(), cq_.cq(), nullptr); - } else { - server_ = grpc_server_create(cq_.cq(), nullptr); - } -} - -Server::Server() { - // Should not be called. - GPR_ASSERT(false); -} + thread_pool_owned_(thread_pool_owned) {} Server::~Server() { std::unique_lock lock(mu_); @@ -238,13 +225,9 @@ bool Server::RegisterAsyncService(AsynchronousService* service) { return true; } -int Server::AddPort(const grpc::string& addr) { +int Server::AddPort(const grpc::string& addr, ServerCredentials* creds) { GPR_ASSERT(!started_); - if (secure_) { - return grpc_server_add_secure_http2_port(server_, addr.c_str()); - } else { - return grpc_server_add_http2_port(server_, addr.c_str()); - } + return creds->AddPortToServer(addr, server_); } bool Server::Start() { diff --git a/src/cpp/server/server_builder.cc b/src/cpp/server/server_builder.cc index 3c2093c3638..d8b3f74939f 100644 --- a/src/cpp/server/server_builder.cc +++ b/src/cpp/server/server_builder.cc @@ -51,14 +51,10 @@ void ServerBuilder::RegisterAsyncService(AsynchronousService* service) { async_services_.push_back(service); } -void ServerBuilder::AddPort(const grpc::string& addr) { - ports_.push_back(addr); -} - -void ServerBuilder::SetCredentials( - const std::shared_ptr& creds) { - GPR_ASSERT(!creds_); - creds_ = creds; +void ServerBuilder::AddPort(const grpc::string& addr, + std::shared_ptr creds, + int* selected_port) { + ports_.push_back(Port{addr, creds, selected_port}); } void ServerBuilder::SetThreadPool(ThreadPoolInterface* thread_pool) { @@ -71,14 +67,13 @@ std::unique_ptr ServerBuilder::BuildAndStart() { gpr_log(GPR_ERROR, "Mixing async and sync services is unsupported for now"); return nullptr; } - if (!thread_pool_ && services_.size()) { + if (!thread_pool_ && !services_.empty()) { int cores = gpr_cpu_num_cores(); if (!cores) cores = 4; thread_pool_ = new ThreadPool(cores); thread_pool_owned = true; } - std::unique_ptr server( - new Server(thread_pool_, thread_pool_owned, creds_.get())); + std::unique_ptr server(new Server(thread_pool_, thread_pool_owned)); for (auto* service : services_) { if (!server->RegisterService(service)) { return nullptr; @@ -90,8 +85,10 @@ std::unique_ptr ServerBuilder::BuildAndStart() { } } for (auto& port : ports_) { - if (!server->AddPort(port)) { - return nullptr; + int r = server->AddPort(port.addr, port.creds.get()); + if (!r) return nullptr; + if (port.selected_port != nullptr) { + *port.selected_port = r; } } if (!server->Start()) { diff --git a/src/cpp/server/server_credentials.cc b/src/cpp/server/server_credentials.cc index 69ad000ccc6..6bdb465baaa 100644 --- a/src/cpp/server/server_credentials.cc +++ b/src/cpp/server/server_credentials.cc @@ -37,26 +37,6 @@ namespace grpc { -ServerCredentials::ServerCredentials(grpc_server_credentials *c_creds) - : creds_(c_creds) {} - -ServerCredentials::~ServerCredentials() { - grpc_server_credentials_release(creds_); -} - -grpc_server_credentials *ServerCredentials::GetRawCreds() { return creds_; } - -std::shared_ptr ServerCredentialsFactory::SslCredentials( - const SslServerCredentialsOptions &options) { - std::vector pem_key_cert_pairs; - for (const auto &key_cert_pair : options.pem_key_cert_pairs) { - pem_key_cert_pairs.push_back( - {key_cert_pair.private_key.c_str(), key_cert_pair.cert_chain.c_str()}); - } - grpc_server_credentials *c_creds = grpc_ssl_server_credentials_create( - options.pem_root_certs.empty() ? nullptr : options.pem_root_certs.c_str(), - &pem_key_cert_pairs[0], pem_key_cert_pairs.size()); - return std::shared_ptr(new ServerCredentials(c_creds)); -} +ServerCredentials::~ServerCredentials() {} } // namespace grpc diff --git a/test/core/surface/lame_client_test.c b/test/core/surface/lame_client_test.c index 0142768261d..cae49271ee1 100644 --- a/test/core/surface/lame_client_test.c +++ b/test/core/surface/lame_client_test.c @@ -31,7 +31,7 @@ * */ -#include "src/core/surface/lame_client.h" +#include #include "test/core/end2end/cq_verifier.h" #include "test/core/util/test_config.h" diff --git a/test/cpp/end2end/async_end2end_test.cc b/test/cpp/end2end/async_end2end_test.cc index 85b4ff8120c..01134a3dc33 100644 --- a/test/cpp/end2end/async_end2end_test.cc +++ b/test/cpp/end2end/async_end2end_test.cc @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include "test/core/util/port.h" @@ -84,7 +85,7 @@ class AsyncEnd2endTest : public ::testing::Test { server_address_ << "localhost:" << port; // Setup server ServerBuilder builder; - builder.AddPort(server_address_.str()); + builder.AddPort(server_address_.str(), grpc::InsecureServerCredentials()); builder.RegisterAsyncService(&service_); server_ = builder.BuildAndStart(); } diff --git a/test/cpp/end2end/end2end_test.cc b/test/cpp/end2end/end2end_test.cc index f5ecd1a20c1..e9f0ce90977 100644 --- a/test/cpp/end2end/end2end_test.cc +++ b/test/cpp/end2end/end2end_test.cc @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include "test/core/util/port.h" @@ -150,7 +151,7 @@ class End2endTest : public ::testing::Test { server_address_ << "localhost:" << port; // Setup server ServerBuilder builder; - builder.AddPort(server_address_.str()); + builder.AddPort(server_address_.str(), InsecureServerCredentials()); builder.RegisterService(&service_); builder.RegisterService(&dup_pkg_service_); builder.SetThreadPool(&thread_pool_); diff --git a/test/cpp/interop/server.cc b/test/cpp/interop/server.cc index 7a7287438f2..1ec51004fac 100644 --- a/test/cpp/interop/server.cc +++ b/test/cpp/interop/server.cc @@ -59,7 +59,6 @@ using grpc::Server; using grpc::ServerBuilder; using grpc::ServerContext; using grpc::ServerCredentials; -using grpc::ServerCredentialsFactory; using grpc::ServerReader; using grpc::ServerReaderWriter; using grpc::ServerWriter; @@ -210,14 +209,14 @@ void RunServer() { SimpleResponse response; ServerBuilder builder; - builder.AddPort(server_address.str()); builder.RegisterService(&service); + std::shared_ptr creds = grpc::InsecureServerCredentials(); if (FLAGS_enable_ssl) { SslServerCredentialsOptions ssl_opts = { "", {{test_server1_key, test_server1_cert}}}; - std::shared_ptr creds = ServerSslCredentials(ssl_opts); - builder.SetCredentials(creds); + creds = grpc::SslServerCredentials(ssl_opts); } + builder.AddPort(server_address.str(), creds); std::unique_ptr server(builder.BuildAndStart()); gpr_log(GPR_INFO, "Server listening on %s", server_address.str().c_str()); while (!got_sigint) { diff --git a/test/cpp/qps/server.cc b/test/cpp/qps/server.cc index 8e136349a15..b54f14d7983 100644 --- a/test/cpp/qps/server.cc +++ b/test/cpp/qps/server.cc @@ -43,6 +43,7 @@ #include #include #include +#include #include #include "src/cpp/server/thread_pool.h" #include "test/core/util/grpc_profiler.h" @@ -134,7 +135,7 @@ static void RunServer() { SimpleResponse response; ServerBuilder builder; - builder.AddPort(server_address); + builder.AddPort(server_address, grpc::InsecureServerCredentials()); builder.RegisterService(&service); std::unique_ptr pool(new ThreadPool(FLAGS_server_threads)); diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index 64478b37532..649cf9f35c9 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -271,7 +271,7 @@ test_cache.maybe_load() if forever: success = True while True: - dw = watch_dirs.DirWatcher(['src', 'include', 'test']) + dw = watch_dirs.DirWatcher(['src', 'include', 'test', 'examples']) initial_time = dw.most_recent_change() have_files_changed = lambda: dw.most_recent_change() != initial_time previous_success = success diff --git a/vsprojects/vs2013/grpc.vcxproj b/vsprojects/vs2013/grpc.vcxproj index 1b4005e0363..02c16b59671 100644 --- a/vsprojects/vs2013/grpc.vcxproj +++ b/vsprojects/vs2013/grpc.vcxproj @@ -160,7 +160,6 @@ - diff --git a/vsprojects/vs2013/grpc.vcxproj.filters b/vsprojects/vs2013/grpc.vcxproj.filters index 949be751807..bd757887613 100644 --- a/vsprojects/vs2013/grpc.vcxproj.filters +++ b/vsprojects/vs2013/grpc.vcxproj.filters @@ -578,9 +578,6 @@ src\core\surface - - src\core\surface - src\core\surface diff --git a/vsprojects/vs2013/grpc_shared.vcxproj b/vsprojects/vs2013/grpc_shared.vcxproj index 6bbe656a809..0a0ce887cac 100644 --- a/vsprojects/vs2013/grpc_shared.vcxproj +++ b/vsprojects/vs2013/grpc_shared.vcxproj @@ -164,7 +164,6 @@ - diff --git a/vsprojects/vs2013/grpc_shared.vcxproj.filters b/vsprojects/vs2013/grpc_shared.vcxproj.filters index 949be751807..bd757887613 100644 --- a/vsprojects/vs2013/grpc_shared.vcxproj.filters +++ b/vsprojects/vs2013/grpc_shared.vcxproj.filters @@ -578,9 +578,6 @@ src\core\surface - - src\core\surface - src\core\surface diff --git a/vsprojects/vs2013/grpc_unsecure.vcxproj b/vsprojects/vs2013/grpc_unsecure.vcxproj index 0c81ec4768b..7421524f1ee 100644 --- a/vsprojects/vs2013/grpc_unsecure.vcxproj +++ b/vsprojects/vs2013/grpc_unsecure.vcxproj @@ -145,7 +145,6 @@ - diff --git a/vsprojects/vs2013/grpc_unsecure.vcxproj.filters b/vsprojects/vs2013/grpc_unsecure.vcxproj.filters index 4b5370a5735..90d44175450 100644 --- a/vsprojects/vs2013/grpc_unsecure.vcxproj.filters +++ b/vsprojects/vs2013/grpc_unsecure.vcxproj.filters @@ -482,9 +482,6 @@ src\core\surface - - src\core\surface - src\core\surface From ad9d0c472d158d7b4df3250793d475724ac3516a Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 23 Feb 2015 10:53:01 -0800 Subject: [PATCH 004/120] Remove dynamic_cast --- include/grpc++/credentials.h | 8 ++++++++ src/cpp/client/insecure_credentials.cc | 2 ++ src/cpp/client/secure_credentials.cc | 10 +++++++--- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/include/grpc++/credentials.h b/include/grpc++/credentials.h index b462b450daf..26e9b556fe4 100644 --- a/include/grpc++/credentials.h +++ b/include/grpc++/credentials.h @@ -42,11 +42,19 @@ namespace grpc { class ChannelArguments; class ChannelInterface; +class SecureCredentials; class Credentials { public: virtual ~Credentials(); + protected: + friend std::unique_ptr ComposeCredentials( + const std::unique_ptr& creds1, + const std::unique_ptr& creds2); + + virtual SecureCredentials* AsSecureCredentials() = 0; + private: friend std::shared_ptr CreateChannel( const grpc::string& target, const std::unique_ptr& creds, diff --git a/src/cpp/client/insecure_credentials.cc b/src/cpp/client/insecure_credentials.cc index 4f3bba5c8e5..8180d1e60ed 100644 --- a/src/cpp/client/insecure_credentials.cc +++ b/src/cpp/client/insecure_credentials.cc @@ -50,6 +50,8 @@ class InsecureCredentialsImpl final : public Credentials { args.SetChannelArgs(&channel_args); return std::shared_ptr(new Channel(target, grpc_channel_create(target.c_str(), &channel_args))); } + + SecureCredentials* AsSecureCredentials() { return nullptr; } }; } // namespace diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc index 367dfe3447b..f8643801054 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -42,7 +42,6 @@ namespace grpc { -namespace { class SecureCredentials final : public Credentials { public: explicit SecureCredentials(grpc_credentials* c_creds) : c_creds_(c_creds) {} @@ -58,10 +57,15 @@ class SecureCredentials final : public Credentials { grpc_secure_channel_create(c_creds_, target.c_str(), &channel_args))); } + SecureCredentials* AsSecureCredentials() { + return this; + } + private: grpc_credentials* const c_creds_; }; +namespace { std::unique_ptr WrapCredentials(grpc_credentials* creds) { return creds == nullptr ? nullptr @@ -116,8 +120,8 @@ std::unique_ptr ComposeCredentials( // passed in here. This is OK because the underlying C objects (i.e., // creds1 and creds2) into grpc_composite_credentials_create will see their // refcounts incremented. - SecureCredentials* s1 = dynamic_cast(creds1.get()); - SecureCredentials* s2 = dynamic_cast(creds2.get()); + SecureCredentials* s1 = creds1->AsSecureCredentials(); + SecureCredentials* s2 = creds2->AsSecureCredentials(); if (s1 && s2) { return WrapCredentials(grpc_composite_credentials_create( s1->GetRawCreds(), s2->GetRawCreds())); From 5c004c68deac80995cb3befcca441fc47cf9f302 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 23 Feb 2015 16:31:57 -0800 Subject: [PATCH 005/120] Driver changes WIP - things compile again after a broad set of changes preparing for the driver code. --- test/cpp/qps/client.cc | 177 +++++++++++++++++-------------------- test/cpp/qps/qpstest.proto | 46 +++++++--- test/cpp/qps/server.cc | 82 +++++++++++++---- 3 files changed, 178 insertions(+), 127 deletions(-) diff --git a/test/cpp/qps/client.cc b/test/cpp/qps/client.cc index 11c39eb4f52..213e5d92149 100644 --- a/test/cpp/qps/client.cc +++ b/test/cpp/qps/client.cc @@ -33,48 +33,36 @@ #include #include +#include #include #include #include #include +#include + #include +#include #include #include +#include #include #include #include +#include +#include #include "test/core/util/grpc_profiler.h" #include "test/cpp/util/create_test_channel.h" #include "test/cpp/qps/qpstest.pb.h" -DEFINE_bool(enable_ssl, false, "Whether to use ssl/tls."); -DEFINE_int32(server_port, 0, "Server port."); -DEFINE_string(server_host, "127.0.0.1", "Server host."); -DEFINE_int32(client_threads, 4, "Number of client threads."); - -// We have a configurable number of channels for sending RPCs. -// RPCs are sent round-robin on the available channels by the -// various threads. Interesting cases are 1 global channel or -// 1 per-thread channel, but we can support any number. -// The channels are assigned round-robin on an RPC by RPC basis -// rather than just at initialization time in order to also measure the -// impact of cache thrashing caused by channel changes. This is an issue -// if you are not in one of the above "interesting cases" -DEFINE_int32(client_channels, 4, "Number of client channels."); - -DEFINE_int32(num_rpcs, 1000, "Number of RPCs per thread."); -DEFINE_int32(payload_size, 1, "Payload size in bytes"); - -// Alternatively, specify parameters for test as a workload so that multiple -// tests are initiated back-to-back. This is convenient for keeping a borg -// allocation consistent. This is a space-separated list of -// [threads channels num_rpcs payload_size ]* -DEFINE_string(workload, "", "Workload parameters"); +DEFINE_int32(driver_port, 0, "Client driver port."); using grpc::ChannelInterface; using grpc::CreateTestChannel; -using grpc::testing::ServerStats; +using grpc::ServerBuilder; +using grpc::testing::ClientArgs; +using grpc::testing::ClientResult; +using grpc::testing::QpsClient; using grpc::testing::SimpleRequest; using grpc::testing::SimpleResponse; using grpc::testing::StatsRequest; @@ -92,8 +80,11 @@ static double now() { return 1e9 * tv.tv_sec + tv.tv_nsec; } -void RunTest(const int client_threads, const int client_channels, - const int num_rpcs, const int payload_size) { +static bool got_sigint = false; + +static void sigint_handler(int x) { got_sigint = 1; } + +ClientResult RunTest(const ClientArgs& args) { gpr_log(GPR_INFO, "QPS test with parameters\n" "enable_ssl = %d\n" @@ -101,17 +92,14 @@ void RunTest(const int client_threads, const int client_channels, "client_threads = %d\n" "num_rpcs = %d\n" "payload_size = %d\n" - "server_host:server_port = %s:%d\n\n", - FLAGS_enable_ssl, client_channels, client_threads, num_rpcs, - payload_size, FLAGS_server_host.c_str(), FLAGS_server_port); - - std::ostringstream oss; - oss << FLAGS_server_host << ":" << FLAGS_server_port; + "server_target = %s\n\n", + args.enable_ssl(), args.client_channels(), args.client_threads(), args.num_rpcs(), + args.payload_size(), args.server_target().c_str()); class ClientChannelInfo { public: - explicit ClientChannelInfo(const grpc::string &server) - : channel_(CreateTestChannel(server, FLAGS_enable_ssl)), + explicit ClientChannelInfo(const ClientArgs& args) + : channel_(CreateTestChannel(args.server_target(), args.enable_ssl())), stub_(TestService::NewStub(channel_)) {} ChannelInterface *get_channel() { return channel_.get(); } TestService::Stub *get_stub() { return stub_.get(); } @@ -122,38 +110,33 @@ void RunTest(const int client_threads, const int client_channels, }; std::vector channels; - for (int i = 0; i < client_channels; i++) { - channels.push_back(ClientChannelInfo(oss.str())); + for (int i = 0; i < args.client_channels(); i++) { + channels.push_back(ClientChannelInfo(args)); } std::vector threads; // Will add threads when ready to execute - std::vector< ::gpr_histogram *> thread_stats(client_threads); + std::vector< ::gpr_histogram *> thread_stats(args.client_threads()); - TestService::Stub *stub_stats = channels[0].get_stub(); grpc::ClientContext context_stats_begin; - StatsRequest stats_request; - ServerStats server_stats_begin; - stats_request.set_test_num(0); - grpc::Status status_beg = stub_stats->CollectServerStats( - &context_stats_begin, stats_request, &server_stats_begin); grpc_profiler_start("qps_client.prof"); - for (int i = 0; i < client_threads; i++) { + gpr_timespec start = gpr_now(); + + for (int i = 0; i < args.client_threads(); i++) { gpr_histogram *hist = gpr_histogram_create(0.01, 60e9); GPR_ASSERT(hist != NULL); thread_stats[i] = hist; threads.push_back( - std::thread([hist, client_threads, client_channels, num_rpcs, - payload_size, &channels](int channel_num) { + std::thread([hist, args, &channels](int channel_num) { SimpleRequest request; SimpleResponse response; request.set_response_type( grpc::testing::PayloadType::COMPRESSABLE); - request.set_response_size(payload_size); + request.set_response_size(args.payload_size()); - for (int j = 0; j < num_rpcs; j++) { + for (int j = 0; j < args.num_rpcs(); j++) { TestService::Stub *stub = channels[channel_num].get_stub(); double start = now(); @@ -166,26 +149,29 @@ void RunTest(const int client_threads, const int client_channels, (response.payload().type() == grpc::testing::PayloadType::COMPRESSABLE) && (response.payload().body().length() == - static_cast(payload_size))); + static_cast(args.payload_size()))); // Now do runtime round-robin assignment of the next // channel number - channel_num += client_threads; - channel_num %= client_channels; + channel_num += args.client_threads(); + channel_num %= args.client_channels(); } }, - i % client_channels)); + i % args.client_channels())); } - gpr_histogram *hist = gpr_histogram_create(0.01, 60e9); - GPR_ASSERT(hist != NULL); for (auto &t : threads) { t.join(); } + gpr_timespec stop = gpr_now(); + grpc_profiler_stop(); - for (int i = 0; i < client_threads; i++) { + gpr_histogram *hist = gpr_histogram_create(0.01, 60e9); + GPR_ASSERT(hist != NULL); + + for (int i = 0; i < args.client_threads(); i++) { gpr_histogram *h = thread_stats[i]; gpr_log(GPR_INFO, "latency at thread %d (50/90/95/99/99.9): %f/%f/%f/%f/%f", i, gpr_histogram_percentile(h, 50), gpr_histogram_percentile(h, 90), @@ -195,57 +181,54 @@ void RunTest(const int client_threads, const int client_channels, gpr_histogram_destroy(h); } - gpr_log( - GPR_INFO, - "latency across %d threads with %d channels and %d payload " - "(50/90/95/99/99.9): %f / %f / %f / %f / %f", - client_threads, client_channels, payload_size, - gpr_histogram_percentile(hist, 50), gpr_histogram_percentile(hist, 90), - gpr_histogram_percentile(hist, 95), gpr_histogram_percentile(hist, 99), - gpr_histogram_percentile(hist, 99.9)); + ClientResult result; + auto* latencies = result.mutable_latencies(); + latencies->set_l_50(gpr_histogram_percentile(hist, 50)); + latencies->set_l_90(gpr_histogram_percentile(hist, 90)); + latencies->set_l_99(gpr_histogram_percentile(hist, 99)); + latencies->set_l_999(gpr_histogram_percentile(hist, 99.9)); + gpr_timespec elapsed = gpr_time_sub(stop, start); + result.set_num_rpcs(args.client_threads() * args.num_rpcs()); + result.set_time_elapsed(elapsed.tv_sec + 1e-9 * elapsed.tv_nsec); + gpr_histogram_destroy(hist); - grpc::ClientContext context_stats_end; - ServerStats server_stats_end; - grpc::Status status_end = stub_stats->CollectServerStats( - &context_stats_end, stats_request, &server_stats_end); + return result; +} - double elapsed = server_stats_end.time_now() - server_stats_begin.time_now(); - int total_rpcs = client_threads * num_rpcs; - double utime = server_stats_end.time_user() - server_stats_begin.time_user(); - double stime = - server_stats_end.time_system() - server_stats_begin.time_system(); - gpr_log(GPR_INFO, - "Elapsed time: %.3f\n" - "RPC Count: %d\n" - "QPS: %.3f\n" - "System time: %.3f\n" - "User time: %.3f\n" - "Resource usage: %.1f%%\n", - elapsed, total_rpcs, total_rpcs / elapsed, stime, utime, - (stime + utime) / elapsed * 100.0); +class ClientImpl : public QpsClient::Service { + public: + + private: + std::mutex client_mu_; +}; + +static void RunServer() { + char* server_address = NULL; + gpr_join_host_port(&server_address, "::", FLAGS_driver_port); + + ClientImpl service; + + ServerBuilder builder; + builder.AddPort(server_address); + builder.RegisterService(&service); + + gpr_free(server_address); + + auto server = builder.BuildAndStart(); + + while (!got_sigint) { + std::this_thread::sleep_for(std::chrono::seconds(5)); + } } int main(int argc, char **argv) { grpc_init(); ParseCommandLineFlags(&argc, &argv, true); - GPR_ASSERT(FLAGS_server_port); - - if (FLAGS_workload.length() == 0) { - RunTest(FLAGS_client_threads, FLAGS_client_channels, FLAGS_num_rpcs, - FLAGS_payload_size); - } else { - std::istringstream workload(FLAGS_workload); - int client_threads, client_channels, num_rpcs, payload_size; - workload >> client_threads; - while (!workload.eof()) { - workload >> client_channels >> num_rpcs >> payload_size; - RunTest(client_threads, client_channels, num_rpcs, payload_size); - workload >> client_threads; - } - gpr_log(GPR_INFO, "Done with specified workload."); - } + signal(SIGINT, sigint_handler); + + RunServer(); grpc_shutdown(); return 0; diff --git a/test/cpp/qps/qpstest.proto b/test/cpp/qps/qpstest.proto index 68ec6149f59..fc589600176 100644 --- a/test/cpp/qps/qpstest.proto +++ b/test/cpp/qps/qpstest.proto @@ -78,17 +78,24 @@ message Latencies { required double l_999 = 4; } -message StartArgs { - required string server_host = 1; - required int32 server_port = 2; - optional bool enable_ssl = 3 [default = false]; - optional int32 client_threads = 4 [default = 1]; - optional int32 client_channels = 5 [default = -1]; - optional int32 num_rpcs = 6 [default = 1]; - optional int32 payload_size = 7 [default = 1]; +message ClientArgs { + required string server_target = 1; + required bool enable_ssl = 3; + required int32 client_threads = 4; + // We have a configurable number of channels for sending RPCs. + // RPCs are sent round-robin on the available channels by the + // various threads. Interesting cases are 1 global channel or + // 1 per-thread channel, but we can support any number. + // The channels are assigned round-robin on an RPC by RPC basis + // rather than just at initialization time in order to also measure the + // impact of cache thrashing caused by channel changes. This is an issue + // if you are not in one of the above "interesting cases" + required int32 client_channels = 5; + required int32 num_rpcs = 6; + required int32 payload_size = 7; } -message StartResult { +message ClientResult { required Latencies latencies = 1; required int32 num_rpcs = 2; required double time_elapsed = 3; @@ -96,6 +103,14 @@ message StartResult { required double time_system = 5; } +message ServerArgs { + required int32 threads = 1; +} + +message ServerStatus { + optional ServerStats stats = 1; +} + message SimpleRequest { // Desired payload type in the response from the server. // If response_type is RANDOM, server randomly chooses one from other formats. @@ -153,9 +168,6 @@ message StreamingOutputCallResponse { } service TestService { - // Start test with specified workload - rpc StartTest(StartArgs) returns (Latencies); - // Collect stats from server, ignore request content rpc CollectServerStats(StatsRequest) returns (ServerStats); @@ -186,3 +198,13 @@ service TestService { rpc HalfDuplexCall(stream StreamingOutputCallRequest) returns (stream StreamingOutputCallResponse); } + +service QpsClient { + // Start test with specified workload + rpc RunTest(ClientArgs) returns (ClientResult); +} + +service QpsServer { + // Start test with specified workload + rpc RunServer(stream ServerArgs) returns (stream ServerStatus); +} diff --git a/test/cpp/qps/server.cc b/test/cpp/qps/server.cc index 8e136349a15..a5edb054938 100644 --- a/test/cpp/qps/server.cc +++ b/test/cpp/qps/server.cc @@ -44,6 +44,7 @@ #include #include #include +#include #include "src/cpp/server/thread_pool.h" #include "test/core/util/grpc_profiler.h" #include "test/cpp/qps/qpstest.pb.h" @@ -51,13 +52,13 @@ #include #include -DEFINE_bool(enable_ssl, false, "Whether to use ssl/tls."); DEFINE_int32(port, 0, "Server port."); -DEFINE_int32(server_threads, 4, "Number of server threads."); +DEFINE_int32(driver_port, 0, "Server driver port."); using grpc::Server; using grpc::ServerBuilder; using grpc::ServerContext; +using grpc::ServerReaderWriter; using grpc::ThreadPool; using grpc::testing::Payload; using grpc::testing::PayloadType; @@ -66,6 +67,10 @@ using grpc::testing::SimpleRequest; using grpc::testing::SimpleResponse; using grpc::testing::StatsRequest; using grpc::testing::TestService; +using grpc::testing::QpsServer; +using grpc::testing::ServerArgs; +using grpc::testing::ServerStats; +using grpc::testing::ServerStatus; using grpc::Status; // In some distros, gflags is in the namespace google, and in some others, @@ -124,34 +129,76 @@ class TestServiceImpl final : public TestService::Service { } // namespace +class ServerImpl : public QpsServer::Service { + public: + Status RunServer(ServerContext* ctx, ServerReaderWriter* stream) { + ServerArgs args; + std::unique_ptr last_stats; + if (!stream->Read(&args)) return Status::OK; + + bool done = false; + while (!done) { + std::lock_guard lock(server_mu_); + + char* server_address = NULL; + gpr_join_host_port(&server_address, "::", FLAGS_port); + + TestServiceImpl service; + + ServerBuilder builder; + builder.AddPort(server_address); + builder.RegisterService(&service); + + gpr_free(server_address); + + std::unique_ptr pool(new ThreadPool(args.threads())); + builder.SetThreadPool(pool.get()); + + auto server = builder.BuildAndStart(); + gpr_log(GPR_INFO, "Server listening on %s\n", server_address); + + ServerStatus last_status; + if (last_stats.get()) { + *last_status.mutable_stats() = *last_stats; + } + if (!stream->Write(last_status)) return Status(grpc::UNKNOWN); + + grpc_profiler_start("qps_server.prof"); + + done = stream->Read(&args); + + grpc_profiler_stop(); + } + + ServerStatus last_status; + if (last_stats.get()) { + *last_status.mutable_stats() = *last_stats; + } + stream->Write(last_status); + return Status::OK; + } + + private: + std::mutex server_mu_; +}; + static void RunServer() { char* server_address = NULL; - gpr_join_host_port(&server_address, "::", FLAGS_port); - - TestServiceImpl service; + gpr_join_host_port(&server_address, "::", FLAGS_driver_port); - SimpleRequest request; - SimpleResponse response; + ServerImpl service; ServerBuilder builder; builder.AddPort(server_address); builder.RegisterService(&service); - std::unique_ptr pool(new ThreadPool(FLAGS_server_threads)); - builder.SetThreadPool(pool.get()); - - std::unique_ptr server(builder.BuildAndStart()); - gpr_log(GPR_INFO, "Server listening on %s\n", server_address); + gpr_free(server_address); - grpc_profiler_start("qps_server.prof"); + auto server = builder.BuildAndStart(); while (!got_sigint) { std::this_thread::sleep_for(std::chrono::seconds(5)); } - - grpc_profiler_stop(); - - gpr_free(server_address); } int main(int argc, char** argv) { @@ -161,7 +208,6 @@ int main(int argc, char** argv) { signal(SIGINT, sigint_handler); GPR_ASSERT(FLAGS_port != 0); - GPR_ASSERT(!FLAGS_enable_ssl); RunServer(); grpc_shutdown(); From e48601934d158f998e50bea19d301ffd8ae3d84f Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 23 Feb 2015 17:10:41 -0800 Subject: [PATCH 006/120] Getting the driver pieces in place Driver logic not implemented yet --- Makefile | 111 ++++++++++++++++++++++++--- build.json | 31 +++++++- test/cpp/qps/driver.cc | 38 +++++++++ test/cpp/qps/driver.h | 42 ++++++++++ test/cpp/qps/qps_driver.cc | 63 +++++++++++++++ test/cpp/qps/single_run_localhost.sh | 26 +++++++ 6 files changed, 297 insertions(+), 14 deletions(-) create mode 100644 test/cpp/qps/driver.cc create mode 100644 test/cpp/qps/driver.h create mode 100644 test/cpp/qps/qps_driver.cc create mode 100755 test/cpp/qps/single_run_localhost.sh diff --git a/Makefile b/Makefile index b018febea10..86da127222e 100644 --- a/Makefile +++ b/Makefile @@ -522,6 +522,7 @@ pubsub_client: $(BINDIR)/$(CONFIG)/pubsub_client pubsub_publisher_test: $(BINDIR)/$(CONFIG)/pubsub_publisher_test pubsub_subscriber_test: $(BINDIR)/$(CONFIG)/pubsub_subscriber_test qps_client: $(BINDIR)/$(CONFIG)/qps_client +qps_driver: $(BINDIR)/$(CONFIG)/qps_driver qps_server: $(BINDIR)/$(CONFIG)/qps_server status_test: $(BINDIR)/$(CONFIG)/status_test thread_pool_test: $(BINDIR)/$(CONFIG)/thread_pool_test @@ -925,13 +926,13 @@ privatelibs: privatelibs_c privatelibs_cxx privatelibs_c: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_chttp2_fake_security.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_chttp2_fullstack.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_chttp2_fullstack_uds.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_chttp2_simple_ssl_fullstack.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_chttp2_simple_ssl_with_oauth2_fullstack.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_chttp2_socket_pair.a $(LIBDIR)/$(CONFIG)/libend2end_fixture_chttp2_socket_pair_one_byte_at_a_time.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_after_accept.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_after_accept_and_writes_closed.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_after_invoke.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_before_invoke.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_in_a_vacuum.a $(LIBDIR)/$(CONFIG)/libend2end_test_census_simple_request.a $(LIBDIR)/$(CONFIG)/libend2end_test_disappearing_server.a $(LIBDIR)/$(CONFIG)/libend2end_test_early_server_shutdown_finishes_inflight_calls.a $(LIBDIR)/$(CONFIG)/libend2end_test_early_server_shutdown_finishes_tags.a $(LIBDIR)/$(CONFIG)/libend2end_test_empty_batch.a $(LIBDIR)/$(CONFIG)/libend2end_test_graceful_server_shutdown.a $(LIBDIR)/$(CONFIG)/libend2end_test_invoke_large_request.a $(LIBDIR)/$(CONFIG)/libend2end_test_max_concurrent_streams.a $(LIBDIR)/$(CONFIG)/libend2end_test_no_op.a $(LIBDIR)/$(CONFIG)/libend2end_test_ping_pong_streaming.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_response_with_binary_metadata_and_payload.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_response_with_metadata_and_payload.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_response_with_payload.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_with_large_metadata.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_with_payload.a $(LIBDIR)/$(CONFIG)/libend2end_test_simple_delayed_request.a $(LIBDIR)/$(CONFIG)/libend2end_test_simple_request.a $(LIBDIR)/$(CONFIG)/libend2end_test_thread_stress.a $(LIBDIR)/$(CONFIG)/libend2end_test_writes_done_hangs_with_pending_read.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_after_accept_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_after_accept_and_writes_closed_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_after_invoke_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_before_invoke_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_cancel_in_a_vacuum_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_census_simple_request_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_disappearing_server_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_early_server_shutdown_finishes_inflight_calls_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_early_server_shutdown_finishes_tags_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_graceful_server_shutdown_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_invoke_large_request_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_max_concurrent_streams_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_no_op_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_ping_pong_streaming_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_response_with_binary_metadata_and_payload_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_response_with_metadata_and_payload_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_response_with_payload_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_response_with_trailing_metadata_and_payload_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_with_large_metadata_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_request_with_payload_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_simple_delayed_request_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_simple_request_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_thread_stress_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_test_writes_done_hangs_with_pending_read_legacy.a $(LIBDIR)/$(CONFIG)/libend2end_certs.a -privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libpubsub_client_lib.a +privatelibs_cxx: $(LIBDIR)/$(CONFIG)/libgrpc++_test_util.a $(LIBDIR)/$(CONFIG)/libpubsub_client_lib.a $(LIBDIR)/$(CONFIG)/libqps.a buildtests: buildtests_c buildtests_cxx buildtests_c: privatelibs_c $(BINDIR)/$(CONFIG)/alarm_heap_test $(BINDIR)/$(CONFIG)/alarm_list_test $(BINDIR)/$(CONFIG)/alarm_test $(BINDIR)/$(CONFIG)/alpn_test $(BINDIR)/$(CONFIG)/bin_encoder_test $(BINDIR)/$(CONFIG)/census_hash_table_test $(BINDIR)/$(CONFIG)/census_statistics_multiple_writers_circular_buffer_test $(BINDIR)/$(CONFIG)/census_statistics_multiple_writers_test $(BINDIR)/$(CONFIG)/census_statistics_performance_test $(BINDIR)/$(CONFIG)/census_statistics_quick_test $(BINDIR)/$(CONFIG)/census_statistics_small_log_test $(BINDIR)/$(CONFIG)/census_stub_test $(BINDIR)/$(CONFIG)/census_window_stats_test $(BINDIR)/$(CONFIG)/chttp2_status_conversion_test $(BINDIR)/$(CONFIG)/chttp2_stream_encoder_test $(BINDIR)/$(CONFIG)/chttp2_stream_map_test $(BINDIR)/$(CONFIG)/chttp2_transport_end2end_test $(BINDIR)/$(CONFIG)/dualstack_socket_test $(BINDIR)/$(CONFIG)/echo_client $(BINDIR)/$(CONFIG)/echo_server $(BINDIR)/$(CONFIG)/echo_test $(BINDIR)/$(CONFIG)/fd_posix_test $(BINDIR)/$(CONFIG)/fling_client $(BINDIR)/$(CONFIG)/fling_server $(BINDIR)/$(CONFIG)/fling_stream_test $(BINDIR)/$(CONFIG)/fling_test $(BINDIR)/$(CONFIG)/gpr_cancellable_test $(BINDIR)/$(CONFIG)/gpr_cmdline_test $(BINDIR)/$(CONFIG)/gpr_env_test $(BINDIR)/$(CONFIG)/gpr_file_test $(BINDIR)/$(CONFIG)/gpr_histogram_test $(BINDIR)/$(CONFIG)/gpr_host_port_test $(BINDIR)/$(CONFIG)/gpr_log_test $(BINDIR)/$(CONFIG)/gpr_slice_buffer_test $(BINDIR)/$(CONFIG)/gpr_slice_test $(BINDIR)/$(CONFIG)/gpr_string_test $(BINDIR)/$(CONFIG)/gpr_sync_test $(BINDIR)/$(CONFIG)/gpr_thd_test $(BINDIR)/$(CONFIG)/gpr_time_test $(BINDIR)/$(CONFIG)/gpr_useful_test $(BINDIR)/$(CONFIG)/grpc_base64_test $(BINDIR)/$(CONFIG)/grpc_byte_buffer_reader_test $(BINDIR)/$(CONFIG)/grpc_channel_stack_test $(BINDIR)/$(CONFIG)/grpc_completion_queue_test $(BINDIR)/$(CONFIG)/grpc_credentials_test $(BINDIR)/$(CONFIG)/grpc_json_token_test $(BINDIR)/$(CONFIG)/grpc_stream_op_test $(BINDIR)/$(CONFIG)/hpack_parser_test $(BINDIR)/$(CONFIG)/hpack_table_test $(BINDIR)/$(CONFIG)/httpcli_format_request_test $(BINDIR)/$(CONFIG)/httpcli_parser_test $(BINDIR)/$(CONFIG)/httpcli_test $(BINDIR)/$(CONFIG)/json_rewrite $(BINDIR)/$(CONFIG)/json_rewrite_test $(BINDIR)/$(CONFIG)/json_test $(BINDIR)/$(CONFIG)/lame_client_test $(BINDIR)/$(CONFIG)/message_compress_test $(BINDIR)/$(CONFIG)/metadata_buffer_test $(BINDIR)/$(CONFIG)/multi_init_test $(BINDIR)/$(CONFIG)/murmur_hash_test $(BINDIR)/$(CONFIG)/no_server_test $(BINDIR)/$(CONFIG)/poll_kick_posix_test $(BINDIR)/$(CONFIG)/resolve_address_test $(BINDIR)/$(CONFIG)/secure_endpoint_test $(BINDIR)/$(CONFIG)/sockaddr_utils_test $(BINDIR)/$(CONFIG)/tcp_client_posix_test $(BINDIR)/$(CONFIG)/tcp_posix_test $(BINDIR)/$(CONFIG)/tcp_server_posix_test $(BINDIR)/$(CONFIG)/time_averaged_stats_test $(BINDIR)/$(CONFIG)/time_test $(BINDIR)/$(CONFIG)/timeout_encoding_test $(BINDIR)/$(CONFIG)/transport_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_no_op_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_no_op_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_no_op_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_no_op_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_legacy_test -buildtests_cxx: privatelibs_cxx $(BINDIR)/$(CONFIG)/async_end2end_test $(BINDIR)/$(CONFIG)/channel_arguments_test $(BINDIR)/$(CONFIG)/credentials_test $(BINDIR)/$(CONFIG)/end2end_test $(BINDIR)/$(CONFIG)/interop_client $(BINDIR)/$(CONFIG)/interop_server $(BINDIR)/$(CONFIG)/interop_test $(BINDIR)/$(CONFIG)/pubsub_client $(BINDIR)/$(CONFIG)/pubsub_publisher_test $(BINDIR)/$(CONFIG)/pubsub_subscriber_test $(BINDIR)/$(CONFIG)/qps_client $(BINDIR)/$(CONFIG)/qps_server $(BINDIR)/$(CONFIG)/status_test $(BINDIR)/$(CONFIG)/thread_pool_test +buildtests_cxx: privatelibs_cxx $(BINDIR)/$(CONFIG)/async_end2end_test $(BINDIR)/$(CONFIG)/channel_arguments_test $(BINDIR)/$(CONFIG)/credentials_test $(BINDIR)/$(CONFIG)/end2end_test $(BINDIR)/$(CONFIG)/interop_client $(BINDIR)/$(CONFIG)/interop_server $(BINDIR)/$(CONFIG)/interop_test $(BINDIR)/$(CONFIG)/pubsub_client $(BINDIR)/$(CONFIG)/pubsub_publisher_test $(BINDIR)/$(CONFIG)/pubsub_subscriber_test $(BINDIR)/$(CONFIG)/qps_client $(BINDIR)/$(CONFIG)/qps_driver $(BINDIR)/$(CONFIG)/qps_server $(BINDIR)/$(CONFIG)/status_test $(BINDIR)/$(CONFIG)/thread_pool_test test: test_c test_cxx @@ -3293,6 +3294,65 @@ $(OBJDIR)/$(CONFIG)/examples/pubsub/publisher.o: $(GENDIR)/examples/pubsub/l $(OBJDIR)/$(CONFIG)/examples/pubsub/subscriber.o: $(GENDIR)/examples/pubsub/label.pb.cc $(GENDIR)/examples/pubsub/empty.pb.cc $(GENDIR)/examples/pubsub/pubsub.pb.cc +LIBQPS_SRC = \ + $(GENDIR)/test/cpp/qps/qpstest.pb.cc \ + test/cpp/qps/driver.cc \ + + +LIBQPS_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBQPS_SRC)))) + +ifeq ($(NO_SECURE),true) + +# You can't build secure libraries if you don't have OpenSSL with ALPN. + +$(LIBDIR)/$(CONFIG)/libqps.a: openssl_dep_error + + +else + +ifeq ($(NO_PROTOBUF),true) + +# You can't build a C++ library if you don't have protobuf - a bit overreached, but still okay. + +$(LIBDIR)/$(CONFIG)/libqps.a: protobuf_dep_error + + +else + +ifneq ($(OPENSSL_DEP),) +# This is to ensure the embedded OpenSSL is built beforehand, properly +# installing headers to their final destination on the drive. We need this +# otherwise parallel compilation will fail if a source is compiled first. +test/cpp/qps/qpstest.proto: $(OPENSSL_DEP) +test/cpp/qps/driver.cc: $(OPENSSL_DEP) +endif + +$(LIBDIR)/$(CONFIG)/libqps.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DEP) $(LIBQPS_OBJS) + $(E) "[AR] Creating $@" + $(Q) mkdir -p `dirname $@` + $(Q) rm -f $(LIBDIR)/$(CONFIG)/libqps.a + $(Q) $(AR) rcs $(LIBDIR)/$(CONFIG)/libqps.a $(LIBQPS_OBJS) +ifeq ($(SYSTEM),Darwin) + $(Q) ranlib $(LIBDIR)/$(CONFIG)/libqps.a +endif + + + + +endif + +endif + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(LIBQPS_OBJS:.o=.dep) +endif +endif + + +$(OBJDIR)/$(CONFIG)/test/cpp/qps/driver.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc + + LIBGRPC_CSHARP_EXT_SRC = \ src/csharp/ext/grpc_csharp_ext.c \ @@ -7807,7 +7867,6 @@ endif QPS_CLIENT_SRC = \ - $(GENDIR)/test/cpp/qps/qpstest.pb.cc \ test/cpp/qps/client.cc \ QPS_CLIENT_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(QPS_CLIENT_SRC)))) @@ -7820,15 +7879,14 @@ $(BINDIR)/$(CONFIG)/qps_client: openssl_dep_error else -$(BINDIR)/$(CONFIG)/qps_client: $(QPS_CLIENT_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 +$(BINDIR)/$(CONFIG)/qps_client: $(QPS_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(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) $(QPS_CLIENT_OBJS) $(GTEST_LIB) $(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) -o $(BINDIR)/$(CONFIG)/qps_client + $(Q) $(LDXX) $(LDFLAGS) $(QPS_CLIENT_OBJS) $(GTEST_LIB) $(LIBDIR)/$(CONFIG)/libqps.a $(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) -o $(BINDIR)/$(CONFIG)/qps_client endif -$(OBJDIR)/$(CONFIG)/test/cpp/qps/qpstest.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 -$(OBJDIR)/$(CONFIG)/test/cpp/qps/client.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 +$(OBJDIR)/$(CONFIG)/test/cpp/qps/client.o: $(LIBDIR)/$(CONFIG)/libqps.a $(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_qps_client: $(QPS_CLIENT_OBJS:.o=.dep) @@ -7839,8 +7897,38 @@ endif endif +QPS_DRIVER_SRC = \ + test/cpp/qps/qps_driver.cc \ + +QPS_DRIVER_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(QPS_DRIVER_SRC)))) + +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL with ALPN. + +$(BINDIR)/$(CONFIG)/qps_driver: openssl_dep_error + +else + +$(BINDIR)/$(CONFIG)/qps_driver: $(QPS_DRIVER_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(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) $(QPS_DRIVER_OBJS) $(GTEST_LIB) $(LIBDIR)/$(CONFIG)/libqps.a $(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) -o $(BINDIR)/$(CONFIG)/qps_driver + +endif + +$(OBJDIR)/$(CONFIG)/test/cpp/qps/qps_driver.o: $(LIBDIR)/$(CONFIG)/libqps.a $(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_qps_driver: $(QPS_DRIVER_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(QPS_DRIVER_OBJS:.o=.dep) +endif +endif + + QPS_SERVER_SRC = \ - $(GENDIR)/test/cpp/qps/qpstest.pb.cc \ test/cpp/qps/server.cc \ QPS_SERVER_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(QPS_SERVER_SRC)))) @@ -7853,15 +7941,14 @@ $(BINDIR)/$(CONFIG)/qps_server: openssl_dep_error else -$(BINDIR)/$(CONFIG)/qps_server: $(QPS_SERVER_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 +$(BINDIR)/$(CONFIG)/qps_server: $(QPS_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(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) $(QPS_SERVER_OBJS) $(GTEST_LIB) $(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) -o $(BINDIR)/$(CONFIG)/qps_server + $(Q) $(LDXX) $(LDFLAGS) $(QPS_SERVER_OBJS) $(GTEST_LIB) $(LIBDIR)/$(CONFIG)/libqps.a $(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) -o $(BINDIR)/$(CONFIG)/qps_server endif -$(OBJDIR)/$(CONFIG)/test/cpp/qps/qpstest.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 -$(OBJDIR)/$(CONFIG)/test/cpp/qps/server.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 +$(OBJDIR)/$(CONFIG)/test/cpp/qps/server.o: $(LIBDIR)/$(CONFIG)/libqps.a $(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_qps_server: $(QPS_SERVER_OBJS:.o=.dep) diff --git a/build.json b/build.json index f6ef33b25fc..72afd53a7ea 100644 --- a/build.json +++ b/build.json @@ -468,6 +468,15 @@ "gpr" ] }, + { + "name": "qps", + "build": "private", + "language": "c++", + "src": [ + "test/cpp/qps/qpstest.proto", + "test/cpp/qps/driver.cc" + ] + }, { "name": "grpc_csharp_ext", "build": "all", @@ -1772,10 +1781,28 @@ "run": false, "language": "c++", "src": [ - "test/cpp/qps/qpstest.proto", "test/cpp/qps/client.cc" ], "deps": [ + "qps", + "grpc++_test_util", + "grpc_test_util", + "grpc++", + "grpc", + "gpr_test_util", + "gpr" + ] + }, + { + "name": "qps_driver", + "build": "test", + "run": false, + "language": "c++", + "src": [ + "test/cpp/qps/qps_driver.cc" + ], + "deps": [ + "qps", "grpc++_test_util", "grpc_test_util", "grpc++", @@ -1790,10 +1817,10 @@ "run": false, "language": "c++", "src": [ - "test/cpp/qps/qpstest.proto", "test/cpp/qps/server.cc" ], "deps": [ + "qps", "grpc++_test_util", "grpc_test_util", "grpc++", diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc new file mode 100644 index 00000000000..ed72e306028 --- /dev/null +++ b/test/cpp/qps/driver.cc @@ -0,0 +1,38 @@ +/* + * + * 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 "test/cpp/qps/driver.h" + +void RunScenario(const grpc::testing::ClientArgs& client_args, int num_clients, + const grpc::testing::ServerArgs& server_args, + int num_servers) {} diff --git a/test/cpp/qps/driver.h b/test/cpp/qps/driver.h new file mode 100644 index 00000000000..6d6506d0490 --- /dev/null +++ b/test/cpp/qps/driver.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. + * + */ + +#ifndef TEST_QPS_DRIVER_H +#define TEST_QPS_DRIVER_H + +#include "test/cpp/qps/qpstest.pb.h" + +void RunScenario(const grpc::testing::ClientArgs& client_args, int num_clients, + const grpc::testing::ServerArgs& server_args, int num_servers); + +#endif diff --git a/test/cpp/qps/qps_driver.cc b/test/cpp/qps/qps_driver.cc new file mode 100644 index 00000000000..e7dda8e8eec --- /dev/null +++ b/test/cpp/qps/qps_driver.cc @@ -0,0 +1,63 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include + +#include "test/cpp/qps/driver.h" + +DEFINE_int32(num_clients, 1, "number of client binaries"); +DEFINE_int32(num_servers, 1, "number of server binaries"); + +using grpc::testing::ClientArgs; +using grpc::testing::ServerArgs; + +// In some distros, gflags is in the namespace google, and in some others, +// in gflags. This hack is enabling us to find both. +namespace google { } +namespace gflags { } +using namespace google; +using namespace gflags; + +int main(int argc, char **argv) { + grpc_init(); + ParseCommandLineFlags(&argc, &argv, true); + + ClientArgs client_args; + ServerArgs server_args; + + RunScenario(client_args, FLAGS_num_clients, server_args, FLAGS_num_servers); + + grpc_shutdown(); + return 0; +} + diff --git a/test/cpp/qps/single_run_localhost.sh b/test/cpp/qps/single_run_localhost.sh new file mode 100755 index 00000000000..1c2f1c85ebf --- /dev/null +++ b/test/cpp/qps/single_run_localhost.sh @@ -0,0 +1,26 @@ +#!/bin/sh + +# performs a single qps run with one client and one server + +set -ex + +cd $(dirname $0)/../../.. + +NUMCPUS=`python2.7 -c 'import multiprocessing; print multiprocessing.cpu_count()'` + +make CONFIG=opt qps_client qps_server qps_driver -j$NUMCPUS + +bins/opt/qps_server -driver_port 10000 -port 10002 & +SERVER_PID=$! +bins/opt/qps_client -driver_port 10001 & +CLIENT_PID=$! + +QPS_SERVERS=localhost:10000 +QPS_CLIENTS=localhost:10001 + +bins/opt/qps_driver $* + +kill -2 $CLIENT_PID +kill -2 $SERVER_PID +wait + From 4f7a1ff6ad06b946acb5a11c244af26bbe575d7a Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 23 Feb 2015 17:16:56 -0800 Subject: [PATCH 007/120] 'Fix' a race --- test/cpp/qps/single_run_localhost.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/cpp/qps/single_run_localhost.sh b/test/cpp/qps/single_run_localhost.sh index 1c2f1c85ebf..a0939a7e587 100755 --- a/test/cpp/qps/single_run_localhost.sh +++ b/test/cpp/qps/single_run_localhost.sh @@ -15,6 +15,9 @@ SERVER_PID=$! bins/opt/qps_client -driver_port 10001 & CLIENT_PID=$! +# wait for startup +sleep 2 + QPS_SERVERS=localhost:10000 QPS_CLIENTS=localhost:10001 From 4ef7a29f311165268cb77648805d616598eb3f57 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 23 Feb 2015 17:29:01 -0800 Subject: [PATCH 008/120] Create server/client lists --- test/cpp/qps/driver.cc | 35 ++++++++++++++++++++++++++-- test/cpp/qps/driver.h | 4 ++-- test/cpp/qps/single_run_localhost.sh | 4 ++-- 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc index ed72e306028..e7fc46b9e8c 100644 --- a/test/cpp/qps/driver.cc +++ b/test/cpp/qps/driver.cc @@ -32,7 +32,38 @@ */ #include "test/cpp/qps/driver.h" +#include "src/core/support/env.h" +#include +#include -void RunScenario(const grpc::testing::ClientArgs& client_args, int num_clients, +using std::vector; +using grpc::string; + +static vector get_hosts(const string& name) { + char* env = gpr_getenv(name.c_str()); + if (!env) return vector(); + + vector out; + char* p = env; + for (;;) { + char* comma = strchr(p, ','); + if (comma) { + out.emplace_back(p, comma); + p = comma + 1; + } else { + out.emplace_back(p); + gpr_free(env); + return out; + } + } +} + +void RunScenario(const grpc::testing::ClientArgs& client_args, size_t num_clients, const grpc::testing::ServerArgs& server_args, - int num_servers) {} + size_t num_servers) { + auto clients = get_hosts("QPS_CLIENTS"); + auto servers = get_hosts("QPS_SERVERS"); + + GPR_ASSERT(clients.size() >= num_clients); + GPR_ASSERT(servers.size() >= num_servers); +} diff --git a/test/cpp/qps/driver.h b/test/cpp/qps/driver.h index 6d6506d0490..615e5b1b178 100644 --- a/test/cpp/qps/driver.h +++ b/test/cpp/qps/driver.h @@ -36,7 +36,7 @@ #include "test/cpp/qps/qpstest.pb.h" -void RunScenario(const grpc::testing::ClientArgs& client_args, int num_clients, - const grpc::testing::ServerArgs& server_args, int num_servers); +void RunScenario(const grpc::testing::ClientArgs& client_args, size_t num_clients, + const grpc::testing::ServerArgs& server_args, size_t num_servers); #endif diff --git a/test/cpp/qps/single_run_localhost.sh b/test/cpp/qps/single_run_localhost.sh index a0939a7e587..ef3e343ebde 100755 --- a/test/cpp/qps/single_run_localhost.sh +++ b/test/cpp/qps/single_run_localhost.sh @@ -18,8 +18,8 @@ CLIENT_PID=$! # wait for startup sleep 2 -QPS_SERVERS=localhost:10000 -QPS_CLIENTS=localhost:10001 +export QPS_SERVERS=localhost:10000 +export QPS_CLIENTS=localhost:10001 bins/opt/qps_driver $* From 2d0f36c84b50cce549ad76307cda56c4506f1a49 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 23 Feb 2015 23:16:17 -0800 Subject: [PATCH 009/120] Driver to client/server kind of works --- Makefile | 3 + build.json | 7 +- src/cpp/server/server.cc | 18 ++-- test/core/util/grpc_profiler.c | 2 +- test/cpp/qps/client.cc | 58 ++++++++----- test/cpp/qps/driver.cc | 125 ++++++++++++++++++++++++++- test/cpp/qps/driver.h | 4 +- test/cpp/qps/qps_driver.cc | 34 ++++++-- test/cpp/qps/qpstest.proto | 36 ++++---- test/cpp/qps/server.cc | 77 +++++++---------- test/cpp/qps/single_run_localhost.sh | 12 ++- test/cpp/qps/timer.cc | 65 ++++++++++++++ test/cpp/qps/timer.h | 55 ++++++++++++ 13 files changed, 381 insertions(+), 115 deletions(-) create mode 100644 test/cpp/qps/timer.cc create mode 100644 test/cpp/qps/timer.h diff --git a/Makefile b/Makefile index 609dc507c0a..dc27c2ac2e3 100644 --- a/Makefile +++ b/Makefile @@ -3307,6 +3307,7 @@ $(OBJDIR)/$(CONFIG)/examples/pubsub/subscriber.o: $(GENDIR)/examples/pubsub/ LIBQPS_SRC = \ $(GENDIR)/test/cpp/qps/qpstest.pb.cc \ test/cpp/qps/driver.cc \ + test/cpp/qps/timer.cc \ LIBQPS_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(LIBQPS_SRC)))) @@ -3335,6 +3336,7 @@ ifneq ($(OPENSSL_DEP),) # otherwise parallel compilation will fail if a source is compiled first. test/cpp/qps/qpstest.proto: $(OPENSSL_DEP) test/cpp/qps/driver.cc: $(OPENSSL_DEP) +test/cpp/qps/timer.cc: $(OPENSSL_DEP) endif $(LIBDIR)/$(CONFIG)/libqps.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DEP) $(LIBQPS_OBJS) @@ -3361,6 +3363,7 @@ endif $(OBJDIR)/$(CONFIG)/test/cpp/qps/driver.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc +$(OBJDIR)/$(CONFIG)/test/cpp/qps/timer.o: $(GENDIR)/test/cpp/qps/qpstest.pb.cc LIBGRPC_CSHARP_EXT_SRC = \ diff --git a/build.json b/build.json index 3b6bc6ccdf6..9c357116bb9 100644 --- a/build.json +++ b/build.json @@ -475,9 +475,14 @@ "name": "qps", "build": "private", "language": "c++", + "headers": [ + "test/cpp/qps/driver.h", + "test/cpp/qps/timer.h" + ], "src": [ "test/cpp/qps/qpstest.proto", - "test/cpp/qps/driver.cc" + "test/cpp/qps/driver.cc", + "test/cpp/qps/timer.cc" ] }, { diff --git a/src/cpp/server/server.cc b/src/cpp/server/server.cc index f565d3aa5d5..f9c09fc09ab 100644 --- a/src/cpp/server/server.cc +++ b/src/cpp/server/server.cc @@ -265,17 +265,15 @@ bool Server::Start() { } void Server::Shutdown() { - { - std::unique_lock lock(mu_); - if (started_ && !shutdown_) { - shutdown_ = true; - grpc_server_shutdown(server_); - cq_.Shutdown(); + std::unique_lock lock(mu_); + if (started_ && !shutdown_) { + shutdown_ = true; + grpc_server_shutdown(server_); + cq_.Shutdown(); - // Wait for running callbacks to finish. - while (num_running_cb_ != 0) { - callback_cv_.wait(lock); - } + // Wait for running callbacks to finish. + while (num_running_cb_ != 0) { + callback_cv_.wait(lock); } } } diff --git a/test/core/util/grpc_profiler.c b/test/core/util/grpc_profiler.c index 35b9361c70c..d5b6cfeef10 100644 --- a/test/core/util/grpc_profiler.c +++ b/test/core/util/grpc_profiler.c @@ -44,7 +44,7 @@ void grpc_profiler_stop() { ProfilerStop(); } void grpc_profiler_start(const char *filename) { gpr_log(GPR_DEBUG, - "You do not have google-perftools installed, profiling is disabled"); + "You do not have google-perftools installed, profiling is disabled [for %s]", filename); gpr_log(GPR_DEBUG, "To install on ubuntu: sudo apt-get install google-perftools " "libgoogle-perftools-dev"); diff --git a/test/cpp/qps/client.cc b/test/cpp/qps/client.cc index 213e5d92149..214711e205b 100644 --- a/test/cpp/qps/client.cc +++ b/test/cpp/qps/client.cc @@ -54,13 +54,17 @@ #include "test/core/util/grpc_profiler.h" #include "test/cpp/util/create_test_channel.h" #include "test/cpp/qps/qpstest.pb.h" +#include "test/cpp/qps/timer.h" DEFINE_int32(driver_port, 0, "Client driver port."); using grpc::ChannelInterface; using grpc::CreateTestChannel; using grpc::ServerBuilder; +using grpc::ServerContext; +using grpc::Status; using grpc::testing::ClientArgs; +using grpc::testing::ClientConfig; using grpc::testing::ClientResult; using grpc::testing::QpsClient; using grpc::testing::SimpleRequest; @@ -85,21 +89,22 @@ static bool got_sigint = false; static void sigint_handler(int x) { got_sigint = 1; } ClientResult RunTest(const ClientArgs& args) { + const auto& config = args.config(); + gpr_log(GPR_INFO, "QPS test with parameters\n" "enable_ssl = %d\n" "client_channels = %d\n" "client_threads = %d\n" "num_rpcs = %d\n" - "payload_size = %d\n" - "server_target = %s\n\n", - args.enable_ssl(), args.client_channels(), args.client_threads(), args.num_rpcs(), - args.payload_size(), args.server_target().c_str()); + "payload_size = %d\n", + config.enable_ssl(), config.client_channels(), config.client_threads(), config.num_rpcs(), + config.payload_size()); class ClientChannelInfo { public: - explicit ClientChannelInfo(const ClientArgs& args) - : channel_(CreateTestChannel(args.server_target(), args.enable_ssl())), + explicit ClientChannelInfo(const grpc::string& target, const ClientConfig& config) + : channel_(CreateTestChannel(target, config.enable_ssl())), stub_(TestService::NewStub(channel_)) {} ChannelInterface *get_channel() { return channel_.get(); } TestService::Stub *get_stub() { return stub_.get(); } @@ -110,33 +115,33 @@ ClientResult RunTest(const ClientArgs& args) { }; std::vector channels; - for (int i = 0; i < args.client_channels(); i++) { - channels.push_back(ClientChannelInfo(args)); + for (int i = 0; i < config.client_channels(); i++) { + channels.push_back(ClientChannelInfo(args.server_targets(i % args.server_targets_size()), config)); } std::vector threads; // Will add threads when ready to execute - std::vector< ::gpr_histogram *> thread_stats(args.client_threads()); + std::vector< ::gpr_histogram *> thread_stats(config.client_threads()); grpc::ClientContext context_stats_begin; grpc_profiler_start("qps_client.prof"); - gpr_timespec start = gpr_now(); + Timer timer; - for (int i = 0; i < args.client_threads(); i++) { + for (int i = 0; i < config.client_threads(); i++) { gpr_histogram *hist = gpr_histogram_create(0.01, 60e9); GPR_ASSERT(hist != NULL); thread_stats[i] = hist; threads.push_back( - std::thread([hist, args, &channels](int channel_num) { + std::thread([hist, config, &channels](int channel_num) { SimpleRequest request; SimpleResponse response; request.set_response_type( grpc::testing::PayloadType::COMPRESSABLE); - request.set_response_size(args.payload_size()); + request.set_response_size(config.payload_size()); - for (int j = 0; j < args.num_rpcs(); j++) { + for (int j = 0; j < config.num_rpcs(); j++) { TestService::Stub *stub = channels[channel_num].get_stub(); double start = now(); @@ -149,29 +154,29 @@ ClientResult RunTest(const ClientArgs& args) { (response.payload().type() == grpc::testing::PayloadType::COMPRESSABLE) && (response.payload().body().length() == - static_cast(args.payload_size()))); + static_cast(config.payload_size()))); // Now do runtime round-robin assignment of the next // channel number - channel_num += args.client_threads(); - channel_num %= args.client_channels(); + channel_num += config.client_threads(); + channel_num %= config.client_channels(); } }, - i % args.client_channels())); + i % config.client_channels())); } for (auto &t : threads) { t.join(); } - gpr_timespec stop = gpr_now(); + auto timer_result = timer.Mark(); grpc_profiler_stop(); gpr_histogram *hist = gpr_histogram_create(0.01, 60e9); GPR_ASSERT(hist != NULL); - for (int i = 0; i < args.client_threads(); i++) { + for (int i = 0; i < config.client_threads(); i++) { gpr_histogram *h = thread_stats[i]; gpr_log(GPR_INFO, "latency at thread %d (50/90/95/99/99.9): %f/%f/%f/%f/%f", i, gpr_histogram_percentile(h, 50), gpr_histogram_percentile(h, 90), @@ -187,17 +192,22 @@ ClientResult RunTest(const ClientArgs& args) { latencies->set_l_90(gpr_histogram_percentile(hist, 90)); latencies->set_l_99(gpr_histogram_percentile(hist, 99)); latencies->set_l_999(gpr_histogram_percentile(hist, 99.9)); - gpr_timespec elapsed = gpr_time_sub(stop, start); - result.set_num_rpcs(args.client_threads() * args.num_rpcs()); - result.set_time_elapsed(elapsed.tv_sec + 1e-9 * elapsed.tv_nsec); + result.set_num_rpcs(config.client_threads() * config.num_rpcs()); + result.set_time_elapsed(timer_result.wall); + result.set_time_system(timer_result.system); + result.set_time_user(timer_result.user); gpr_histogram_destroy(hist); return result; } -class ClientImpl : public QpsClient::Service { +class ClientImpl final : public QpsClient::Service { public: + Status RunTest(ServerContext* ctx, const ClientArgs* args, ClientResult* result) override { + *result = ::RunTest(*args); + return Status::OK; + } private: std::mutex client_mu_; diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc index e7fc46b9e8c..098860610ca 100644 --- a/test/cpp/qps/driver.cc +++ b/test/cpp/qps/driver.cc @@ -35,9 +35,33 @@ #include "src/core/support/env.h" #include #include +#include +#include +#include +#include +#include +#include +#include +#include +using std::list; +using std::thread; +using std::unique_ptr; using std::vector; using grpc::string; +using grpc::ChannelArguments; +using grpc::ClientContext; +using grpc::ClientReaderWriter; +using grpc::CreateChannelDeprecated; +using grpc::Status; +using grpc::testing::ClientArgs; +using grpc::testing::ClientConfig; +using grpc::testing::ClientResult; +using grpc::testing::QpsClient; +using grpc::testing::QpsServer; +using grpc::testing::ServerArgs; +using grpc::testing::ServerConfig; +using grpc::testing::ServerStatus; static vector get_hosts(const string& name) { char* env = gpr_getenv(name.c_str()); @@ -58,12 +82,107 @@ static vector get_hosts(const string& name) { } } -void RunScenario(const grpc::testing::ClientArgs& client_args, size_t num_clients, - const grpc::testing::ServerArgs& server_args, - size_t num_servers) { +void RunScenario(const ClientConfig& client_config, size_t num_clients, + const ServerConfig& server_config, size_t num_servers) { + // ClientContext allocator (all are destroyed at scope exit) + list contexts; + auto alloc_context = [&contexts]() { + contexts.emplace_back(); + return &contexts.back(); + }; + + // Get client, server lists auto clients = get_hosts("QPS_CLIENTS"); auto servers = get_hosts("QPS_SERVERS"); GPR_ASSERT(clients.size() >= num_clients); GPR_ASSERT(servers.size() >= num_servers); + + // Trim to just what we need + clients.resize(num_clients); + servers.resize(num_servers); + + // Start servers + vector> server_stubs; + vector>> server_streams; + vector server_targets; + for (const auto& target : servers) { + server_stubs.push_back(QpsServer::NewStub(CreateChannelDeprecated(target, ChannelArguments()))); + auto* stub = server_stubs.back().get(); + ServerArgs args; + *args.mutable_config() = server_config; + server_streams.push_back(stub->RunServer(alloc_context())); + auto* stream = server_streams.back().get(); + if (!stream->Write(args)) { + gpr_log(GPR_ERROR, "Failed starting server"); + return; + } + ServerStatus init_status; + if (!stream->Read(&init_status)) { + gpr_log(GPR_ERROR, "Failed starting server"); + return; + } + char* host; + char* driver_port; + char* cli_target; + gpr_split_host_port(target.c_str(), &host, &driver_port); + gpr_join_host_port(&cli_target, host, init_status.port()); + server_targets.push_back(cli_target); + gpr_free(host); + gpr_free(driver_port); + gpr_free(cli_target); + } + + // Start clients + class Client { + public: + Client(ClientContext* ctx, const string& target, const ClientArgs& args) + : thread_([ctx, target, args, this]() { + auto stub = QpsClient::NewStub(CreateChannelDeprecated(target, ChannelArguments())); + status_ = stub->RunTest(ctx, args, &result_); + }) {} + + ~Client() { join(); } + + void join() { if (!joined_) { thread_.join(); joined_ = true; } } + + const Status& status() const { return status_; } + const ClientResult& result() const { return result_; } + + private: + bool joined_ = false; + Status status_; + ClientResult result_; + thread thread_; + }; + list running_clients; + size_t svr_idx = 0; + for (const auto& target : clients) { + ClientArgs args; + *args.mutable_config() = client_config; + for (size_t i = 0; i < num_servers; i++) { + args.add_server_targets(server_targets[svr_idx]); + svr_idx = (svr_idx + 1) % num_servers; + } + + running_clients.emplace_back(alloc_context(), target, args); + } + + // Finish clients + for (auto& client : running_clients) { + client.join(); + if (!client.status().IsOk()) { + gpr_log(GPR_ERROR, "Client failed"); + return; + } + } + + // Finish servers + for (auto& stream : server_streams) { + ServerStatus final_status; + ServerStatus dummy; + if (!stream->WritesDone() || !stream->Read(&final_status) || stream->Read(&dummy) || !stream->Finish().IsOk()) { + gpr_log(GPR_ERROR, "Server protocol error"); + } + } } diff --git a/test/cpp/qps/driver.h b/test/cpp/qps/driver.h index 615e5b1b178..8ac9d2f0a3f 100644 --- a/test/cpp/qps/driver.h +++ b/test/cpp/qps/driver.h @@ -36,7 +36,7 @@ #include "test/cpp/qps/qpstest.pb.h" -void RunScenario(const grpc::testing::ClientArgs& client_args, size_t num_clients, - const grpc::testing::ServerArgs& server_args, size_t num_servers); +void RunScenario(const grpc::testing::ClientConfig& client_config, size_t num_clients, + const grpc::testing::ServerConfig& server_config, size_t num_servers); #endif diff --git a/test/cpp/qps/qps_driver.cc b/test/cpp/qps/qps_driver.cc index e7dda8e8eec..88b9d373a11 100644 --- a/test/cpp/qps/qps_driver.cc +++ b/test/cpp/qps/qps_driver.cc @@ -35,11 +35,23 @@ #include "test/cpp/qps/driver.h" -DEFINE_int32(num_clients, 1, "number of client binaries"); -DEFINE_int32(num_servers, 1, "number of server binaries"); +DEFINE_int32(num_clients, 1, "Number of client binaries"); +DEFINE_int32(num_servers, 1, "Number of server binaries"); -using grpc::testing::ClientArgs; -using grpc::testing::ServerArgs; +// Common config +DEFINE_bool(enable_ssl, false, "Use SSL"); + +// Server config +DEFINE_int32(server_threads, 1, "Number of server threads"); + +// Client config +DEFINE_int32(client_threads, 1, "Number of client threads"); +DEFINE_int32(client_channels, 1, "Number of client channels"); +DEFINE_int32(num_rpcs, 10000, "Number of rpcs per client thread"); +DEFINE_int32(payload_size, 1, "Payload size"); + +using grpc::testing::ClientConfig; +using grpc::testing::ServerConfig; // In some distros, gflags is in the namespace google, and in some others, // in gflags. This hack is enabling us to find both. @@ -52,10 +64,18 @@ int main(int argc, char **argv) { grpc_init(); ParseCommandLineFlags(&argc, &argv, true); - ClientArgs client_args; - ServerArgs server_args; + ClientConfig client_config; + client_config.set_enable_ssl(FLAGS_enable_ssl); + client_config.set_client_threads(FLAGS_client_threads); + client_config.set_client_channels(FLAGS_client_channels); + client_config.set_num_rpcs(FLAGS_num_rpcs); + client_config.set_payload_size(FLAGS_payload_size); + + ServerConfig server_config; + server_config.set_threads(FLAGS_server_threads); + server_config.set_enable_ssl(FLAGS_enable_ssl); - RunScenario(client_args, FLAGS_num_clients, server_args, FLAGS_num_servers); + RunScenario(client_config, FLAGS_num_clients, server_config, FLAGS_num_servers); grpc_shutdown(); return 0; diff --git a/test/cpp/qps/qpstest.proto b/test/cpp/qps/qpstest.proto index fc589600176..11b7c882a62 100644 --- a/test/cpp/qps/qpstest.proto +++ b/test/cpp/qps/qpstest.proto @@ -51,17 +51,14 @@ message StatsRequest { } message ServerStats { - // wall clock time for timestamp - required double time_now = 1; + // wall clock time + required double time_elapsed = 1; // user time used by the server process and threads required double time_user = 2; // server time used by the server process and all threads required double time_system = 3; - - // RPC count so far - optional int32 num_rpcs = 4; } message Payload { @@ -78,10 +75,9 @@ message Latencies { required double l_999 = 4; } -message ClientArgs { - required string server_target = 1; - required bool enable_ssl = 3; - required int32 client_threads = 4; +message ClientConfig { + required bool enable_ssl = 1; + required int32 client_threads = 2; // We have a configurable number of channels for sending RPCs. // RPCs are sent round-robin on the available channels by the // various threads. Interesting cases are 1 global channel or @@ -90,9 +86,14 @@ message ClientArgs { // rather than just at initialization time in order to also measure the // impact of cache thrashing caused by channel changes. This is an issue // if you are not in one of the above "interesting cases" - required int32 client_channels = 5; - required int32 num_rpcs = 6; - required int32 payload_size = 7; + required int32 client_channels = 3; + required int32 num_rpcs = 4; + required int32 payload_size = 5; +} + +message ClientArgs { + repeated string server_targets = 1; + required ClientConfig config = 2; } message ClientResult { @@ -103,12 +104,18 @@ message ClientResult { required double time_system = 5; } -message ServerArgs { +message ServerConfig { required int32 threads = 1; + required bool enable_ssl = 2; +} + +message ServerArgs { + required ServerConfig config = 1; } message ServerStatus { optional ServerStats stats = 1; + required int32 port = 2; } message SimpleRequest { @@ -168,9 +175,6 @@ message StreamingOutputCallResponse { } service TestService { - // Collect stats from server, ignore request content - rpc CollectServerStats(StatsRequest) returns (ServerStats); - // One request followed by one response. // The server returns the client payload as-is. rpc UnaryCall(SimpleRequest) returns (SimpleResponse); diff --git a/test/cpp/qps/server.cc b/test/cpp/qps/server.cc index a5edb054938..89fdfeb0cb9 100644 --- a/test/cpp/qps/server.cc +++ b/test/cpp/qps/server.cc @@ -31,8 +31,6 @@ * */ -#include -#include #include #include @@ -48,6 +46,7 @@ #include "src/cpp/server/thread_pool.h" #include "test/core/util/grpc_profiler.h" #include "test/cpp/qps/qpstest.pb.h" +#include "test/cpp/qps/timer.h" #include #include @@ -84,10 +83,6 @@ static bool got_sigint = false; static void sigint_handler(int x) { got_sigint = 1; } -static double time_double(struct timeval* tv) { - return tv->tv_sec + 1e-6 * tv->tv_usec; -} - static bool SetPayload(PayloadType type, int size, Payload* payload) { PayloadType response_type = type; // TODO(yangg): Support UNCOMPRESSABLE payload. @@ -104,19 +99,8 @@ namespace { class TestServiceImpl final : public TestService::Service { public: - Status CollectServerStats(ServerContext* context, const StatsRequest*, - ServerStats* response) { - struct rusage usage; - struct timeval tv; - gettimeofday(&tv, NULL); - getrusage(RUSAGE_SELF, &usage); - response->set_time_now(time_double(&tv)); - response->set_time_user(time_double(&usage.ru_utime)); - response->set_time_system(time_double(&usage.ru_stime)); - return Status::OK; - } Status UnaryCall(ServerContext* context, const SimpleRequest* request, - SimpleResponse* response) { + SimpleResponse* response) override { if (request->has_response_size() && request->response_size() > 0) { if (!SetPayload(request->response_type(), request->response_size(), response->mutable_payload())) { @@ -133,48 +117,47 @@ class ServerImpl : public QpsServer::Service { public: Status RunServer(ServerContext* ctx, ServerReaderWriter* stream) { ServerArgs args; - std::unique_ptr last_stats; if (!stream->Read(&args)) return Status::OK; - bool done = false; - while (!done) { - std::lock_guard lock(server_mu_); + std::lock_guard lock(server_mu_); - char* server_address = NULL; - gpr_join_host_port(&server_address, "::", FLAGS_port); + char* server_address = NULL; + gpr_join_host_port(&server_address, "::", FLAGS_port); - TestServiceImpl service; + TestServiceImpl service; - ServerBuilder builder; - builder.AddPort(server_address); - builder.RegisterService(&service); + ServerBuilder builder; + builder.AddPort(server_address); + builder.RegisterService(&service); - gpr_free(server_address); + std::unique_ptr pool(new ThreadPool(args.config().threads())); + builder.SetThreadPool(pool.get()); - std::unique_ptr pool(new ThreadPool(args.threads())); - builder.SetThreadPool(pool.get()); + auto server = builder.BuildAndStart(); + gpr_log(GPR_INFO, "Server listening on %s\n", server_address); - auto server = builder.BuildAndStart(); - gpr_log(GPR_INFO, "Server listening on %s\n", server_address); + gpr_free(server_address); - ServerStatus last_status; - if (last_stats.get()) { - *last_status.mutable_stats() = *last_stats; - } - if (!stream->Write(last_status)) return Status(grpc::UNKNOWN); - - grpc_profiler_start("qps_server.prof"); + ServerStatus status; + status.set_port(FLAGS_port); + if (!stream->Write(status)) return Status(grpc::UNKNOWN); - done = stream->Read(&args); + grpc_profiler_start("qps_server.prof"); + Timer timer; - grpc_profiler_stop(); + if (stream->Read(&args)) { + gpr_log(GPR_ERROR, "Got a server request, but not expecting one"); + return Status(grpc::UNKNOWN); } - ServerStatus last_status; - if (last_stats.get()) { - *last_status.mutable_stats() = *last_stats; - } - stream->Write(last_status); + auto timer_result = timer.Mark(); + grpc_profiler_stop(); + + auto* stats = status.mutable_stats(); + stats->set_time_elapsed(timer_result.wall); + stats->set_time_system(timer_result.system); + stats->set_time_user(timer_result.user); + stream->Write(status); return Status::OK; } diff --git a/test/cpp/qps/single_run_localhost.sh b/test/cpp/qps/single_run_localhost.sh index ef3e343ebde..317202a6abd 100755 --- a/test/cpp/qps/single_run_localhost.sh +++ b/test/cpp/qps/single_run_localhost.sh @@ -6,13 +6,17 @@ set -ex cd $(dirname $0)/../../.. +killall qps_server qps_client || true + +config=opt + NUMCPUS=`python2.7 -c 'import multiprocessing; print multiprocessing.cpu_count()'` -make CONFIG=opt qps_client qps_server qps_driver -j$NUMCPUS +make CONFIG=$config qps_client qps_server qps_driver -j$NUMCPUS -bins/opt/qps_server -driver_port 10000 -port 10002 & +bins/$config/qps_server -driver_port 10000 -port 10002 & SERVER_PID=$! -bins/opt/qps_client -driver_port 10001 & +bins/$config/qps_client -driver_port 10001 & CLIENT_PID=$! # wait for startup @@ -21,7 +25,7 @@ sleep 2 export QPS_SERVERS=localhost:10000 export QPS_CLIENTS=localhost:10001 -bins/opt/qps_driver $* +bins/$config/qps_driver $* kill -2 $CLIENT_PID kill -2 $SERVER_PID diff --git a/test/cpp/qps/timer.cc b/test/cpp/qps/timer.cc new file mode 100644 index 00000000000..ff21f1a3778 --- /dev/null +++ b/test/cpp/qps/timer.cc @@ -0,0 +1,65 @@ +/* + * + * 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 "test/cpp/qps/timer.h" + +#include +#include + +Timer::Timer() : start_(Sample()) {} + +static double time_double(struct timeval* tv) { + return tv->tv_sec + 1e-6 * tv->tv_usec; +} + +Timer::Result Timer::Sample() { + struct rusage usage; + struct timeval tv; + gettimeofday(&tv, NULL); + getrusage(RUSAGE_SELF, &usage); + + Result r; + r.wall = time_double(&tv); + r.user = time_double(&usage.ru_utime); + r.system = time_double(&usage.ru_stime); + return r; +} + +Timer::Result Timer::Mark() { + Result s = Sample(); + Result r; + r.wall = s.wall - start_.wall; + r.user = s.user - start_.user; + r.system = s.system - start_.system; + return r; +} \ No newline at end of file diff --git a/test/cpp/qps/timer.h b/test/cpp/qps/timer.h new file mode 100644 index 00000000000..8a229cbd305 --- /dev/null +++ b/test/cpp/qps/timer.h @@ -0,0 +1,55 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef TEST_QPS_TIMER_H +#define TEST_QPS_TIMER_H + +class Timer { + public: + Timer(); + + struct Result { + double wall; + double user; + double system; + }; + + Result Mark(); + + private: + static Result Sample(); + + const Result start_; +}; + +#endif // TEST_QPS_TIMER_H From 7ab4fee9e7fc0bd01ecfda06f9e70e3974f288a8 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 24 Feb 2015 08:15:53 -0800 Subject: [PATCH 010/120] Allow multiple tmp-merge directories at once make -jN was failing because libgrpc and libgrpc++ wanted to link at the same time. --- Makefile | 28 ++++++++++++++-------------- templates/Makefile.template | 14 +++++++------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/Makefile b/Makefile index d55d2056a77..1d4708b3a22 100644 --- a/Makefile +++ b/Makefile @@ -2566,13 +2566,13 @@ $(LIBDIR)/$(CONFIG)/libgrpc.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(LIBGRPC_OBJS) $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc.a $(Q) $(AR) rcs $(LIBDIR)/$(CONFIG)/libgrpc.a $(LIBGRPC_OBJS) - $(Q) rm -rf tmp-merge - $(Q) mkdir tmp-merge - $(Q) ( cd tmp-merge ; $(AR) x ../$(LIBDIR)/$(CONFIG)/libgrpc.a ) - $(Q) for l in $(OPENSSL_MERGE_LIBS) ; do ( cd tmp-merge ; ar x ../$${l} ) ; done - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc.a tmp-merge/__.SYMDEF* - $(Q) ar rcs $(LIBDIR)/$(CONFIG)/libgrpc.a tmp-merge/* - $(Q) rm -rf tmp-merge + $(Q) rm -rf tmp-merge-grpc + $(Q) mkdir tmp-merge-grpc + $(Q) ( cd tmp-merge-grpc ; $(AR) x ../$(LIBDIR)/$(CONFIG)/libgrpc.a ) + $(Q) for l in $(OPENSSL_MERGE_LIBS) ; do ( cd tmp-merge-grpc ; ar x ../$${l} ) ; done + $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc.a tmp-merge-grpc/__.SYMDEF* + $(Q) ar rcs $(LIBDIR)/$(CONFIG)/libgrpc.a tmp-merge-grpc/* + $(Q) rm -rf tmp-merge-grpc ifeq ($(SYSTEM),Darwin) $(Q) ranlib $(LIBDIR)/$(CONFIG)/libgrpc.a endif @@ -3141,13 +3141,13 @@ $(LIBDIR)/$(CONFIG)/libgrpc++.a: $(ZLIB_DEP) $(OPENSSL_DEP) $(PROTOBUF_DEP) $(LI $(Q) mkdir -p `dirname $@` $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++.a $(Q) $(AR) rcs $(LIBDIR)/$(CONFIG)/libgrpc++.a $(LIBGRPC++_OBJS) - $(Q) rm -rf tmp-merge - $(Q) mkdir tmp-merge - $(Q) ( cd tmp-merge ; $(AR) x ../$(LIBDIR)/$(CONFIG)/libgrpc++.a ) - $(Q) for l in $(OPENSSL_MERGE_LIBS) ; do ( cd tmp-merge ; ar x ../$${l} ) ; done - $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++.a tmp-merge/__.SYMDEF* - $(Q) ar rcs $(LIBDIR)/$(CONFIG)/libgrpc++.a tmp-merge/* - $(Q) rm -rf tmp-merge + $(Q) rm -rf tmp-merge-grpc++ + $(Q) mkdir tmp-merge-grpc++ + $(Q) ( cd tmp-merge-grpc++ ; $(AR) x ../$(LIBDIR)/$(CONFIG)/libgrpc++.a ) + $(Q) for l in $(OPENSSL_MERGE_LIBS) ; do ( cd tmp-merge-grpc++ ; ar x ../$${l} ) ; done + $(Q) rm -f $(LIBDIR)/$(CONFIG)/libgrpc++.a tmp-merge-grpc++/__.SYMDEF* + $(Q) ar rcs $(LIBDIR)/$(CONFIG)/libgrpc++.a tmp-merge-grpc++/* + $(Q) rm -rf tmp-merge-grpc++ ifeq ($(SYSTEM),Darwin) $(Q) ranlib $(LIBDIR)/$(CONFIG)/libgrpc++.a endif diff --git a/templates/Makefile.template b/templates/Makefile.template index cd7eb238454..d8649930e45 100644 --- a/templates/Makefile.template +++ b/templates/Makefile.template @@ -968,13 +968,13 @@ $(LIBDIR)/$(CONFIG)/lib${lib.name}.a: $(ZLIB_DEP)\ $(Q) $(AR) rcs $(LIBDIR)/$(CONFIG)/lib${lib.name}.a $(LIB${lib.name.upper()}_OBJS) % if lib.get('baselib', False): % if lib.get('secure', True): - $(Q) rm -rf tmp-merge - $(Q) mkdir tmp-merge - $(Q) ( cd tmp-merge ; $(AR) x ../$(LIBDIR)/$(CONFIG)/lib${lib.name}.a ) - $(Q) for l in $(OPENSSL_MERGE_LIBS) ; do ( cd tmp-merge ; <%text>ar x ../$${l} ) ; done - $(Q) rm -f $(LIBDIR)/$(CONFIG)/lib${lib.name}.a tmp-merge/__.SYMDEF* - $(Q) ar rcs $(LIBDIR)/$(CONFIG)/lib${lib.name}.a tmp-merge/* - $(Q) rm -rf tmp-merge + $(Q) rm -rf tmp-merge-${lib.name} + $(Q) mkdir tmp-merge-${lib.name} + $(Q) ( cd tmp-merge-${lib.name} ; $(AR) x ../$(LIBDIR)/$(CONFIG)/lib${lib.name}.a ) + $(Q) for l in $(OPENSSL_MERGE_LIBS) ; do ( cd tmp-merge-${lib.name} ; <%text>ar x ../$${l} ) ; done + $(Q) rm -f $(LIBDIR)/$(CONFIG)/lib${lib.name}.a tmp-merge-${lib.name}/__.SYMDEF* + $(Q) ar rcs $(LIBDIR)/$(CONFIG)/lib${lib.name}.a tmp-merge-${lib.name}/* + $(Q) rm -rf tmp-merge-${lib.name} % endif % endif ifeq ($(SYSTEM),Darwin) From 2f3fa9acff3eb7cacbb590446eb9d5546a8a43ca Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 24 Feb 2015 17:04:22 -0800 Subject: [PATCH 011/120] Fix linux compile bug --- test/cpp/qps/timer.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/cpp/qps/timer.cc b/test/cpp/qps/timer.cc index ff21f1a3778..5a5be97071b 100644 --- a/test/cpp/qps/timer.cc +++ b/test/cpp/qps/timer.cc @@ -45,7 +45,7 @@ static double time_double(struct timeval* tv) { Timer::Result Timer::Sample() { struct rusage usage; struct timeval tv; - gettimeofday(&tv, NULL); + gettimeofday(&tv, nullptr); getrusage(RUSAGE_SELF, &usage); Result r; @@ -62,4 +62,4 @@ Timer::Result Timer::Mark() { r.user = s.user - start_.user; r.system = s.system - start_.system; return r; -} \ No newline at end of file +} From 8ecb170151e061f35d3799885ba63b5762f2057e Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 24 Feb 2015 17:08:23 -0800 Subject: [PATCH 012/120] Fix that race better --- test/cpp/qps/client.cc | 4 ++-- test/cpp/qps/server.cc | 4 ++-- test/cpp/qps/single_run_localhost.sh | 3 --- 3 files changed, 4 insertions(+), 7 deletions(-) diff --git a/test/cpp/qps/client.cc b/test/cpp/qps/client.cc index 214711e205b..7c9763a332d 100644 --- a/test/cpp/qps/client.cc +++ b/test/cpp/qps/client.cc @@ -233,11 +233,11 @@ static void RunServer() { } int main(int argc, char **argv) { + signal(SIGINT, sigint_handler); + grpc_init(); ParseCommandLineFlags(&argc, &argv, true); - signal(SIGINT, sigint_handler); - RunServer(); grpc_shutdown(); diff --git a/test/cpp/qps/server.cc b/test/cpp/qps/server.cc index 89fdfeb0cb9..7d9a9d1d28e 100644 --- a/test/cpp/qps/server.cc +++ b/test/cpp/qps/server.cc @@ -185,11 +185,11 @@ static void RunServer() { } int main(int argc, char** argv) { + signal(SIGINT, sigint_handler); + grpc_init(); ParseCommandLineFlags(&argc, &argv, true); - signal(SIGINT, sigint_handler); - GPR_ASSERT(FLAGS_port != 0); RunServer(); diff --git a/test/cpp/qps/single_run_localhost.sh b/test/cpp/qps/single_run_localhost.sh index 317202a6abd..310a0824bb3 100755 --- a/test/cpp/qps/single_run_localhost.sh +++ b/test/cpp/qps/single_run_localhost.sh @@ -19,9 +19,6 @@ SERVER_PID=$! bins/$config/qps_client -driver_port 10001 & CLIENT_PID=$! -# wait for startup -sleep 2 - export QPS_SERVERS=localhost:10000 export QPS_CLIENTS=localhost:10001 From c16b7952f835748d03518dc8c732d1c5fbbf6a1d Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Thu, 26 Feb 2015 03:16:53 +0100 Subject: [PATCH 013/120] Fixing Windows build of the python protoc plugin. --- src/compiler/python_plugin.cc | 1 + 1 file changed, 1 insertion(+) diff --git a/src/compiler/python_plugin.cc b/src/compiler/python_plugin.cc index ed1e0494fbe..6a8c8f5d130 100644 --- a/src/compiler/python_plugin.cc +++ b/src/compiler/python_plugin.cc @@ -36,6 +36,7 @@ #include #include #include +#include #include "src/compiler/python_generator.h" #include From 7795324d19edf896086bca7b26104dbbda7acd9f Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Fri, 27 Feb 2015 14:28:05 -0800 Subject: [PATCH 014/120] Redo #817. Update pubsub example channel creation and credentials --- build.json | 1 - examples/pubsub/main.cc | 42 ++++++++--------------------------------- 2 files changed, 8 insertions(+), 35 deletions(-) diff --git a/build.json b/build.json index 2079b2cce79..e9096a24f0b 100644 --- a/build.json +++ b/build.json @@ -1757,7 +1757,6 @@ ], "deps": [ "pubsub_client_lib", - "grpc++_test_util", "grpc_test_util", "grpc++", "grpc", diff --git a/examples/pubsub/main.cc b/examples/pubsub/main.cc index 39fb8aea15c..75aecac1f98 100644 --- a/examples/pubsub/main.cc +++ b/examples/pubsub/main.cc @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -48,17 +49,11 @@ #include "examples/pubsub/publisher.h" #include "examples/pubsub/subscriber.h" -#include "test/cpp/util/create_test_channel.h" DEFINE_int32(server_port, 443, "Server port."); DEFINE_string(server_host, "pubsub-staging.googleapis.com", "Server host to connect to"); DEFINE_string(project_id, "", "GCE project id such as stoked-keyword-656"); -DEFINE_string(service_account_key_file, "", - "Path to service account json key file."); -DEFINE_string(oauth_scope, - "https://www.googleapis.com/auth/cloud-platform", - "Scope for OAuth tokens."); // In some distros, gflags is in the namespace google, and in some others, // in gflags. This hack is enabling us to find both. @@ -75,17 +70,6 @@ const char kMessageData[] = "Test Data"; } // namespace -grpc::string GetServiceAccountJsonKey() { - grpc::string json_key; - if (json_key.empty()) { - std::ifstream json_key_file(FLAGS_service_account_key_file); - std::stringstream key_stream; - key_stream << json_key_file.rdbuf(); - json_key = key_stream.str(); - } - return json_key; -} - int main(int argc, char** argv) { grpc_init(); ParseCommandLineFlags(&argc, &argv, true); @@ -93,23 +77,12 @@ int main(int argc, char** argv) { std::ostringstream ss; - std::unique_ptr creds; - if (FLAGS_service_account_key_file != "") { - grpc::string json_key = GetServiceAccountJsonKey(); - creds = grpc::CredentialsFactory::ServiceAccountCredentials( - json_key, FLAGS_oauth_scope, std::chrono::hours(1)); - } else { - creds = grpc::CredentialsFactory::ComputeEngineCredentials(); - } - ss << FLAGS_server_host << ":" << FLAGS_server_port; - std::shared_ptr channel( - grpc::CreateTestChannel( - ss.str(), - FLAGS_server_host, - true, // enable SSL - true, // use prod roots - creds)); + + std::unique_ptr creds = + grpc::CredentialsFactory::GoogleDefaultCredentials(); + std::shared_ptr channel = + grpc::CreateChannel(ss.str(), creds, grpc::ChannelArguments()); grpc::examples::pubsub::Publisher publisher(channel); grpc::examples::pubsub::Subscriber subscriber(channel); @@ -127,8 +100,9 @@ int main(int argc, char** argv) { grpc::string subscription_topic; if (subscriber.GetSubscription( subscription_name, &subscription_topic).IsOk()) { - subscriber.DeleteSubscription(subscription_name); + s = subscriber.DeleteSubscription(subscription_name); } + if (publisher.GetTopic(topic).IsOk()) publisher.DeleteTopic(topic); grpc::Status s = publisher.CreateTopic(topic); From 0706ce8a19149fd8d62496de87b2b7002db5d64a Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Fri, 27 Feb 2015 14:31:02 -0800 Subject: [PATCH 015/120] remove debug bits --- examples/pubsub/main.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/pubsub/main.cc b/examples/pubsub/main.cc index 75aecac1f98..ce22cfa1560 100644 --- a/examples/pubsub/main.cc +++ b/examples/pubsub/main.cc @@ -100,7 +100,7 @@ int main(int argc, char** argv) { grpc::string subscription_topic; if (subscriber.GetSubscription( subscription_name, &subscription_topic).IsOk()) { - s = subscriber.DeleteSubscription(subscription_name); + subscriber.DeleteSubscription(subscription_name); } if (publisher.GetTopic(topic).IsOk()) publisher.DeleteTopic(topic); From b9e15638539f37945ce7e461aedc6891dce904da Mon Sep 17 00:00:00 2001 From: mattn Date: Sat, 28 Feb 2015 23:45:58 +0900 Subject: [PATCH 016/120] Support ruby 2.2.0 --- src/ruby/ext/grpc/extconf.rb | 1 - src/ruby/ext/grpc/rb_grpc.c | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/ruby/ext/grpc/extconf.rb b/src/ruby/ext/grpc/extconf.rb index 483a31f60cc..f15f85bf56d 100644 --- a/src/ruby/ext/grpc/extconf.rb +++ b/src/ruby/ext/grpc/extconf.rb @@ -77,7 +77,6 @@ end dir_config('grpc', HEADER_DIRS, LIB_DIRS) -$CFLAGS << ' -std=c89 ' $CFLAGS << ' -Wno-implicit-function-declaration ' $CFLAGS << ' -Wno-pointer-sign ' $CFLAGS << ' -Wno-return-type ' diff --git a/src/ruby/ext/grpc/rb_grpc.c b/src/ruby/ext/grpc/rb_grpc.c index c7671c8a775..400efd0dfad 100644 --- a/src/ruby/ext/grpc/rb_grpc.c +++ b/src/ruby/ext/grpc/rb_grpc.c @@ -119,12 +119,12 @@ gpr_timespec grpc_rb_time_timeval(VALUE time, int interval) { break; case T_FLOAT: - if (interval && RFLOAT(time)->float_value < 0.0) + if (interval && RFLOAT_VALUE(time) < 0.0) rb_raise(rb_eArgError, "%s must be positive", tstr); else { double f, d; - d = modf(RFLOAT(time)->float_value, &f); + d = modf(RFLOAT_VALUE(time), &f); if (d < 0) { d += 1; f -= 1; @@ -132,7 +132,7 @@ gpr_timespec grpc_rb_time_timeval(VALUE time, int interval) { t.tv_sec = (time_t)f; if (f != t.tv_sec) { rb_raise(rb_eRangeError, "%f out of Time range", - RFLOAT(time)->float_value); + RFLOAT_VALUE(time)); } t.tv_nsec = (time_t)(d * 1e9 + 0.5); } From 1a43f87134c1978bc4f1fbf64fa1b60e13552d64 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 2 Mar 2015 09:08:05 -0800 Subject: [PATCH 017/120] De-C++11-ification --- src/cpp/client/insecure_credentials.cc | 9 ++++++--- src/cpp/client/secure_credentials.cc | 11 +++++------ 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/cpp/client/insecure_credentials.cc b/src/cpp/client/insecure_credentials.cc index 8180d1e60ed..2dcfe69591a 100644 --- a/src/cpp/client/insecure_credentials.cc +++ b/src/cpp/client/insecure_credentials.cc @@ -37,18 +37,21 @@ #include #include +#include #include #include "src/cpp/client/channel.h" namespace grpc { namespace { -class InsecureCredentialsImpl final : public Credentials { +class InsecureCredentialsImpl GRPC_FINAL : public Credentials { public: - std::shared_ptr CreateChannel(const string& target, const grpc::ChannelArguments& args) override { + std::shared_ptr CreateChannel( + const string& target, const grpc::ChannelArguments& args) GRPC_OVERRIDE { grpc_channel_args channel_args; args.SetChannelArgs(&channel_args); - return std::shared_ptr(new Channel(target, grpc_channel_create(target.c_str(), &channel_args))); + return std::shared_ptr(new Channel( + target, grpc_channel_create(target.c_str(), &channel_args))); } SecureCredentials* AsSecureCredentials() { return nullptr; } diff --git a/src/cpp/client/secure_credentials.cc b/src/cpp/client/secure_credentials.cc index 175f88f6a94..5eb5c547942 100644 --- a/src/cpp/client/secure_credentials.cc +++ b/src/cpp/client/secure_credentials.cc @@ -37,19 +37,20 @@ #include #include +#include #include #include "src/cpp/client/channel.h" namespace grpc { -class SecureCredentials final : public Credentials { +class SecureCredentials GRPC_FINAL : public Credentials { public: explicit SecureCredentials(grpc_credentials* c_creds) : c_creds_(c_creds) {} - ~SecureCredentials() override { grpc_credentials_release(c_creds_); } + ~SecureCredentials() GRPC_OVERRIDE { grpc_credentials_release(c_creds_); } grpc_credentials* GetRawCreds() { return c_creds_; } std::shared_ptr CreateChannel( - const string& target, const grpc::ChannelArguments& args) override { + const string& target, const grpc::ChannelArguments& args) GRPC_OVERRIDE { grpc_channel_args channel_args; args.SetChannelArgs(&channel_args); return std::shared_ptr(new Channel( @@ -57,9 +58,7 @@ class SecureCredentials final : public Credentials { grpc_secure_channel_create(c_creds_, target.c_str(), &channel_args))); } - SecureCredentials* AsSecureCredentials() { - return this; - } + SecureCredentials* AsSecureCredentials() { return this; } private: grpc_credentials* const c_creds_; From 22176cbbf89aeef3128d4e01bc51014e11e3e28a Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 2 Mar 2015 09:09:38 -0800 Subject: [PATCH 018/120] De-C++11-ification --- src/cpp/server/insecure_server_credentials.cc | 5 +++-- src/cpp/server/secure_server_credentials.cc | 7 ++++--- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/cpp/server/insecure_server_credentials.cc b/src/cpp/server/insecure_server_credentials.cc index 2b0ee775240..f5e4732f730 100644 --- a/src/cpp/server/insecure_server_credentials.cc +++ b/src/cpp/server/insecure_server_credentials.cc @@ -36,9 +36,10 @@ namespace grpc { namespace { -class InsecureServerCredentialsImpl final : public ServerCredentials { +class InsecureServerCredentialsImpl GRPC_FINAL : public ServerCredentials { public: - int AddPortToServer(const grpc::string& addr, grpc_server* server) { + int AddPortToServer(const grpc::string& addr, + grpc_server* server) GRPC_OVERRIDE { return grpc_server_add_http2_port(server, addr.c_str()); } }; diff --git a/src/cpp/server/secure_server_credentials.cc b/src/cpp/server/secure_server_credentials.cc index f90838b086d..ff356385034 100644 --- a/src/cpp/server/secure_server_credentials.cc +++ b/src/cpp/server/secure_server_credentials.cc @@ -38,14 +38,15 @@ namespace grpc { namespace { -class SecureServerCredentials final : public ServerCredentials { +class SecureServerCredentials GRPC_FINAL : public ServerCredentials { public: explicit SecureServerCredentials(grpc_server_credentials* creds) : creds_(creds) {} - ~SecureServerCredentials() override { + ~SecureServerCredentials() GRPC_OVERRIDE { grpc_server_credentials_release(creds_); } - int AddPortToServer(const grpc::string& addr, grpc_server* server) override { + int AddPortToServer(const grpc::string& addr, + grpc_server* server) GRPC_OVERRIDE { return grpc_server_add_secure_http2_port(server, addr.c_str(), creds_); } From b449de0bb45b3acd59d8ddfaaa077c451d56a9f4 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 2 Mar 2015 09:18:05 -0800 Subject: [PATCH 019/120] Cleaned --- build.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/build.json b/build.json index f97ff687e31..590d6f8c8e5 100644 --- a/build.json +++ b/build.json @@ -1834,15 +1834,15 @@ ] }, { - "name": "qps_driver", + "name": "qps_client_async", "build": "test", "run": false, "language": "c++", "src": [ - "test/cpp/qps/qps_driver.cc" + "test/cpp/qps/qpstest.proto", + "test/cpp/qps/client_async.cc" ], "deps": [ - "qps", "grpc++_test_util", "grpc_test_util", "grpc++", @@ -1852,15 +1852,15 @@ ] }, { - "name": "qps_client_async", + "name": "qps_driver", "build": "test", "run": false, "language": "c++", "src": [ - "test/cpp/qps/qpstest.proto", - "test/cpp/qps/client_async.cc" + "test/cpp/qps/qps_driver.cc" ], "deps": [ + "qps", "grpc++_test_util", "grpc_test_util", "grpc++", From 0e61b2d2570f943f063908cbd1e4b53dc76c3bc0 Mon Sep 17 00:00:00 2001 From: David Klempner Date: Mon, 2 Mar 2015 13:41:07 -0800 Subject: [PATCH 020/120] Remove some debugging logs from the unary poll promote path I put these in while debugging correctness, and forgot to remove them. --- src/core/iomgr/pollset_posix.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/core/iomgr/pollset_posix.c b/src/core/iomgr/pollset_posix.c index f0a8453fd77..0151550a818 100644 --- a/src/core/iomgr/pollset_posix.c +++ b/src/core/iomgr/pollset_posix.c @@ -267,7 +267,6 @@ static void unary_poll_do_promote(void *args, int success) { * and we don't have any mechanism to unbecome multipoller. */ pollset->in_flight_cbs--; if (pollset->shutting_down) { - gpr_log(GPR_INFO, "Shutting down"); /* We don't care about this pollset anymore. */ if (pollset->in_flight_cbs == 0) { do_shutdown_cb = 1; @@ -275,7 +274,6 @@ static void unary_poll_do_promote(void *args, int success) { } else if (grpc_fd_is_orphaned(fd)) { /* Don't try to add it to anything, we'll drop our ref on it below */ } else if (pollset->vtable != original_vtable) { - gpr_log(GPR_INFO, "Not original vtable"); pollset->vtable->add_fd(pollset, fd); } else if (fd != pollset->data.ptr) { grpc_fd *fds[2]; From 1542d7dbb048bddcb2f0d56bb9ac52b02c401d57 Mon Sep 17 00:00:00 2001 From: Donna Dionne Date: Mon, 2 Mar 2015 14:42:35 -0800 Subject: [PATCH 021/120] adding a build images script and remove some tests while investigating timeout --- tools/gce_setup/build_images.sh | 46 ++++++++++++++++++++++++++++ tools/gce_setup/cloud_prod_runner.sh | 3 +- 2 files changed, 48 insertions(+), 1 deletion(-) create mode 100755 tools/gce_setup/build_images.sh diff --git a/tools/gce_setup/build_images.sh b/tools/gce_setup/build_images.sh new file mode 100755 index 00000000000..ea58a98608c --- /dev/null +++ b/tools/gce_setup/build_images.sh @@ -0,0 +1,46 @@ +#!/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. + + +main() { + # rebuild images on all languages on existing builder vm. + source grpc_docker.sh + cd ../../ + + # build images for all languages + languages=(cxx java go ruby node python) + for lan in "${languages[@]}" + do + grpc_update_image $lan + done +} + +set -x +main "$@" diff --git a/tools/gce_setup/cloud_prod_runner.sh b/tools/gce_setup/cloud_prod_runner.sh index e11185c226b..3760ae49795 100755 --- a/tools/gce_setup/cloud_prod_runner.sh +++ b/tools/gce_setup/cloud_prod_runner.sh @@ -31,7 +31,8 @@ main() { source grpc_docker.sh - test_cases=(large_unary empty_unary ping_pong client_streaming server_streaming cancel_after_begin cancel_after_first_response) + # temporarily remove ping_pong and cancel_after_first_response while investigating timeout + test_cases=(large_unary empty_unary client_streaming server_streaming cancel_after_begin) auth_test_cases=(service_account_creds compute_engine_creds) clients=(cxx java go ruby node) for test_case in "${test_cases[@]}" From acf6f318fc9605d94fba4873a2848c7266d7eddb Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Mon, 2 Mar 2015 15:13:39 -0800 Subject: [PATCH 022/120] Better use of threads, avoid thread safety issues on destructor with a proper join. Also had been misusing EXPECT_EQ, as well as actually having an invalid expectation on the ok field. Now it should be sane. --- test/cpp/qps/server_async.cc | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/test/cpp/qps/server_async.cc b/test/cpp/qps/server_async.cc index c797d8af963..c006262fc34 100644 --- a/test/cpp/qps/server_async.cc +++ b/test/cpp/qps/server_async.cc @@ -143,21 +143,24 @@ class AsyncQpsServerTest { delete contexts_.front(); contexts_.pop_front(); } + for (auto& thr: threads_) { + thr.join(); + } } void ServeRpcs(int num_threads) { - std::vector threads; for (int i = 0; i < num_threads; i++) { - threads.push_back(std::thread([=]() { + threads_.push_back(std::thread([=]() { // Wait until work is available or we are shutting down bool ok; void *got_tag; while (srv_cq_.Next(&got_tag, &ok)) { - EXPECT_EQ(ok, true); - ServerRpcContext *ctx = detag(got_tag); - // The tag is a pointer to an RPC context to invoke - if (ctx->RunNextState() == false) { - // this RPC context is done, so refresh it - ctx->Reset(); + if (ok) { + ServerRpcContext *ctx = detag(got_tag); + // The tag is a pointer to an RPC context to invoke + if (ctx->RunNextState() == false) { + // this RPC context is done, so refresh it + ctx->Reset(); + } } } return; @@ -260,6 +263,7 @@ class AsyncQpsServerTest { } CompletionQueue srv_cq_; TestService::AsyncService async_service_; + std::vector threads_; std::unique_ptr server_; std::function *, void *)> From 0823cb786b873ce5e6d180dd279865742580e3a3 Mon Sep 17 00:00:00 2001 From: Vijay Pai Date: Mon, 2 Mar 2015 15:48:51 -0800 Subject: [PATCH 023/120] Sanity checks for calls that were causing crashes --- src/cpp/server/server.cc | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/cpp/server/server.cc b/src/cpp/server/server.cc index 97bf0f1a6ea..5c5b8d8286e 100644 --- a/src/cpp/server/server.cc +++ b/src/cpp/server/server.cc @@ -287,12 +287,14 @@ void Server::Wait() { } void Server::PerformOpsOnCall(CallOpBuffer* buf, Call* call) { - static const size_t MAX_OPS = 8; - size_t nops = MAX_OPS; - grpc_op ops[MAX_OPS]; - buf->FillOps(ops, &nops); - GPR_ASSERT(GRPC_CALL_OK == - grpc_call_start_batch(call->call(), ops, nops, buf)); + if (call->call()) { + static const size_t MAX_OPS = 8; + size_t nops = MAX_OPS; + grpc_op ops[MAX_OPS]; + buf->FillOps(ops, &nops); + GPR_ASSERT(GRPC_CALL_OK == + grpc_call_start_batch(call->call(), ops, nops, buf)); + } } class Server::AsyncRequest GRPC_FINAL : public CompletionQueueTag { @@ -343,7 +345,9 @@ class Server::AsyncRequest GRPC_FINAL : public CompletionQueueTag { } ctx_->call_ = call_; Call call(call_, server_, cq_); - ctx_->BeginCompletionOp(&call); + if (call_) { + ctx_->BeginCompletionOp(&call); + } // just the pointers inside call are copied here stream_->BindCall(&call); delete this; From 26598a394a74bb89614b68428f5cdd3cb1279663 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 2 Mar 2015 16:16:00 -0800 Subject: [PATCH 024/120] WIP --- Makefile | 157 +++------------------------- build.json | 64 ++---------- test/cpp/qps/client.h | 53 ++++++++++ test/cpp/qps/driver.cc | 8 +- test/cpp/qps/qpstest.proto | 46 ++++++--- test/cpp/qps/server.h | 53 ++++++++++ test/cpp/qps/worker.cc | 202 +++++++++++++++++++++++++++++++++++++ 7 files changed, 366 insertions(+), 217 deletions(-) create mode 100644 test/cpp/qps/client.h create mode 100644 test/cpp/qps/server.h create mode 100644 test/cpp/qps/worker.cc diff --git a/Makefile b/Makefile index 840fb55e6a0..bb65da78625 100644 --- a/Makefile +++ b/Makefile @@ -544,11 +544,8 @@ interop_test: $(BINDIR)/$(CONFIG)/interop_test pubsub_client: $(BINDIR)/$(CONFIG)/pubsub_client pubsub_publisher_test: $(BINDIR)/$(CONFIG)/pubsub_publisher_test pubsub_subscriber_test: $(BINDIR)/$(CONFIG)/pubsub_subscriber_test -qps_client: $(BINDIR)/$(CONFIG)/qps_client -qps_client_async: $(BINDIR)/$(CONFIG)/qps_client_async qps_driver: $(BINDIR)/$(CONFIG)/qps_driver -qps_server: $(BINDIR)/$(CONFIG)/qps_server -qps_server_async: $(BINDIR)/$(CONFIG)/qps_server_async +qps_worker: $(BINDIR)/$(CONFIG)/qps_worker status_test: $(BINDIR)/$(CONFIG)/status_test thread_pool_test: $(BINDIR)/$(CONFIG)/thread_pool_test chttp2_fake_security_cancel_after_accept_test: $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_test @@ -961,7 +958,7 @@ buildtests: buildtests_c buildtests_cxx buildtests_c: privatelibs_c $(BINDIR)/$(CONFIG)/alarm_heap_test $(BINDIR)/$(CONFIG)/alarm_list_test $(BINDIR)/$(CONFIG)/alarm_test $(BINDIR)/$(CONFIG)/alpn_test $(BINDIR)/$(CONFIG)/bin_encoder_test $(BINDIR)/$(CONFIG)/census_hash_table_test $(BINDIR)/$(CONFIG)/census_statistics_multiple_writers_circular_buffer_test $(BINDIR)/$(CONFIG)/census_statistics_multiple_writers_test $(BINDIR)/$(CONFIG)/census_statistics_performance_test $(BINDIR)/$(CONFIG)/census_statistics_quick_test $(BINDIR)/$(CONFIG)/census_statistics_small_log_test $(BINDIR)/$(CONFIG)/census_stub_test $(BINDIR)/$(CONFIG)/census_window_stats_test $(BINDIR)/$(CONFIG)/chttp2_status_conversion_test $(BINDIR)/$(CONFIG)/chttp2_stream_encoder_test $(BINDIR)/$(CONFIG)/chttp2_stream_map_test $(BINDIR)/$(CONFIG)/chttp2_transport_end2end_test $(BINDIR)/$(CONFIG)/dualstack_socket_test $(BINDIR)/$(CONFIG)/echo_client $(BINDIR)/$(CONFIG)/echo_server $(BINDIR)/$(CONFIG)/echo_test $(BINDIR)/$(CONFIG)/fd_posix_test $(BINDIR)/$(CONFIG)/fling_client $(BINDIR)/$(CONFIG)/fling_server $(BINDIR)/$(CONFIG)/fling_stream_test $(BINDIR)/$(CONFIG)/fling_test $(BINDIR)/$(CONFIG)/gpr_cancellable_test $(BINDIR)/$(CONFIG)/gpr_cmdline_test $(BINDIR)/$(CONFIG)/gpr_env_test $(BINDIR)/$(CONFIG)/gpr_file_test $(BINDIR)/$(CONFIG)/gpr_histogram_test $(BINDIR)/$(CONFIG)/gpr_host_port_test $(BINDIR)/$(CONFIG)/gpr_log_test $(BINDIR)/$(CONFIG)/gpr_slice_buffer_test $(BINDIR)/$(CONFIG)/gpr_slice_test $(BINDIR)/$(CONFIG)/gpr_string_test $(BINDIR)/$(CONFIG)/gpr_sync_test $(BINDIR)/$(CONFIG)/gpr_thd_test $(BINDIR)/$(CONFIG)/gpr_time_test $(BINDIR)/$(CONFIG)/gpr_useful_test $(BINDIR)/$(CONFIG)/grpc_base64_test $(BINDIR)/$(CONFIG)/grpc_byte_buffer_reader_test $(BINDIR)/$(CONFIG)/grpc_channel_stack_test $(BINDIR)/$(CONFIG)/grpc_completion_queue_test $(BINDIR)/$(CONFIG)/grpc_credentials_test $(BINDIR)/$(CONFIG)/grpc_json_token_test $(BINDIR)/$(CONFIG)/grpc_stream_op_test $(BINDIR)/$(CONFIG)/hpack_parser_test $(BINDIR)/$(CONFIG)/hpack_table_test $(BINDIR)/$(CONFIG)/httpcli_format_request_test $(BINDIR)/$(CONFIG)/httpcli_parser_test $(BINDIR)/$(CONFIG)/httpcli_test $(BINDIR)/$(CONFIG)/json_rewrite $(BINDIR)/$(CONFIG)/json_rewrite_test $(BINDIR)/$(CONFIG)/json_test $(BINDIR)/$(CONFIG)/lame_client_test $(BINDIR)/$(CONFIG)/message_compress_test $(BINDIR)/$(CONFIG)/metadata_buffer_test $(BINDIR)/$(CONFIG)/multi_init_test $(BINDIR)/$(CONFIG)/murmur_hash_test $(BINDIR)/$(CONFIG)/no_server_test $(BINDIR)/$(CONFIG)/poll_kick_posix_test $(BINDIR)/$(CONFIG)/resolve_address_test $(BINDIR)/$(CONFIG)/secure_endpoint_test $(BINDIR)/$(CONFIG)/sockaddr_utils_test $(BINDIR)/$(CONFIG)/tcp_client_posix_test $(BINDIR)/$(CONFIG)/tcp_posix_test $(BINDIR)/$(CONFIG)/tcp_server_posix_test $(BINDIR)/$(CONFIG)/time_averaged_stats_test $(BINDIR)/$(CONFIG)/time_test $(BINDIR)/$(CONFIG)/timeout_encoding_test $(BINDIR)/$(CONFIG)/transport_metadata_test $(BINDIR)/$(CONFIG)/transport_security_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fake_security_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_no_op_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_fullstack_uds_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_no_op_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_fullstack_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_no_op_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_simple_ssl_with_oauth2_fullstack_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_no_op_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_writes_done_hangs_with_pending_read_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_census_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_disappearing_server_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_empty_batch_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_graceful_server_shutdown_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_no_op_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_large_metadata_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_payload_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_request_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_thread_stress_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_accept_and_writes_closed_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_after_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_before_invoke_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_cancel_in_a_vacuum_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_census_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_disappearing_server_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_inflight_calls_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_early_server_shutdown_finishes_tags_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_graceful_server_shutdown_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_invoke_large_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_max_concurrent_streams_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_no_op_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_ping_pong_streaming_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_binary_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_response_with_trailing_metadata_and_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_large_metadata_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_request_with_payload_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_delayed_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_simple_request_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_thread_stress_legacy_test $(BINDIR)/$(CONFIG)/chttp2_socket_pair_one_byte_at_a_time_writes_done_hangs_with_pending_read_legacy_test -buildtests_cxx: privatelibs_cxx $(BINDIR)/$(CONFIG)/async_end2end_test $(BINDIR)/$(CONFIG)/channel_arguments_test $(BINDIR)/$(CONFIG)/credentials_test $(BINDIR)/$(CONFIG)/end2end_test $(BINDIR)/$(CONFIG)/interop_client $(BINDIR)/$(CONFIG)/interop_server $(BINDIR)/$(CONFIG)/interop_test $(BINDIR)/$(CONFIG)/pubsub_client $(BINDIR)/$(CONFIG)/pubsub_publisher_test $(BINDIR)/$(CONFIG)/pubsub_subscriber_test $(BINDIR)/$(CONFIG)/qps_client $(BINDIR)/$(CONFIG)/qps_client_async $(BINDIR)/$(CONFIG)/qps_driver $(BINDIR)/$(CONFIG)/qps_server $(BINDIR)/$(CONFIG)/qps_server_async $(BINDIR)/$(CONFIG)/status_test $(BINDIR)/$(CONFIG)/thread_pool_test +buildtests_cxx: privatelibs_cxx $(BINDIR)/$(CONFIG)/async_end2end_test $(BINDIR)/$(CONFIG)/channel_arguments_test $(BINDIR)/$(CONFIG)/credentials_test $(BINDIR)/$(CONFIG)/end2end_test $(BINDIR)/$(CONFIG)/interop_client $(BINDIR)/$(CONFIG)/interop_server $(BINDIR)/$(CONFIG)/interop_test $(BINDIR)/$(CONFIG)/pubsub_client $(BINDIR)/$(CONFIG)/pubsub_publisher_test $(BINDIR)/$(CONFIG)/pubsub_subscriber_test $(BINDIR)/$(CONFIG)/qps_driver $(BINDIR)/$(CONFIG)/qps_worker $(BINDIR)/$(CONFIG)/status_test $(BINDIR)/$(CONFIG)/thread_pool_test test: test_c test_cxx @@ -8081,92 +8078,6 @@ endif endif -QPS_CLIENT_SRC = \ - test/cpp/qps/client.cc \ - -QPS_CLIENT_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(QPS_CLIENT_SRC)))) - -ifeq ($(NO_SECURE),true) - -# You can't build secure targets if you don't have OpenSSL with ALPN. - -$(BINDIR)/$(CONFIG)/qps_client: 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)/qps_client: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/qps_client: $(PROTOBUF_DEP) $(QPS_CLIENT_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(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) $(QPS_CLIENT_OBJS) $(GTEST_LIB) $(LIBDIR)/$(CONFIG)/libqps.a $(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) -o $(BINDIR)/$(CONFIG)/qps_client - -endif - -endif - -$(OBJDIR)/$(CONFIG)/test/cpp/qps/client.o: $(LIBDIR)/$(CONFIG)/libqps.a $(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_qps_client: $(QPS_CLIENT_OBJS:.o=.dep) - -ifneq ($(NO_SECURE),true) -ifneq ($(NO_DEPS),true) --include $(QPS_CLIENT_OBJS:.o=.dep) -endif -endif - - -QPS_CLIENT_ASYNC_SRC = \ - $(GENDIR)/test/cpp/qps/qpstest.pb.cc \ - test/cpp/qps/client_async.cc \ - -QPS_CLIENT_ASYNC_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(QPS_CLIENT_ASYNC_SRC)))) - -ifeq ($(NO_SECURE),true) - -# You can't build secure targets if you don't have OpenSSL with ALPN. - -$(BINDIR)/$(CONFIG)/qps_client_async: 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)/qps_client_async: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/qps_client_async: $(PROTOBUF_DEP) $(QPS_CLIENT_ASYNC_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) $(QPS_CLIENT_ASYNC_OBJS) $(GTEST_LIB) $(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) -o $(BINDIR)/$(CONFIG)/qps_client_async - -endif - -endif - -$(OBJDIR)/$(CONFIG)/test/cpp/qps/qpstest.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 -$(OBJDIR)/$(CONFIG)/test/cpp/qps/client_async.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_qps_client_async: $(QPS_CLIENT_ASYNC_OBJS:.o=.dep) - -ifneq ($(NO_SECURE),true) -ifneq ($(NO_DEPS),true) --include $(QPS_CLIENT_ASYNC_OBJS:.o=.dep) -endif -endif - - QPS_DRIVER_SRC = \ test/cpp/qps/qps_driver.cc \ @@ -8209,16 +8120,18 @@ endif endif -QPS_SERVER_SRC = \ +QPS_WORKER_SRC = \ + test/cpp/qps/client.cc \ test/cpp/qps/server.cc \ + test/cpp/qps/worker.cc \ -QPS_SERVER_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(QPS_SERVER_SRC)))) +QPS_WORKER_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(QPS_WORKER_SRC)))) ifeq ($(NO_SECURE),true) # You can't build secure targets if you don't have OpenSSL with ALPN. -$(BINDIR)/$(CONFIG)/qps_server: openssl_dep_error +$(BINDIR)/$(CONFIG)/qps_worker: openssl_dep_error else @@ -8227,70 +8140,28 @@ 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)/qps_server: protobuf_dep_error +$(BINDIR)/$(CONFIG)/qps_worker: protobuf_dep_error else -$(BINDIR)/$(CONFIG)/qps_server: $(PROTOBUF_DEP) $(QPS_SERVER_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(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 +$(BINDIR)/$(CONFIG)/qps_worker: $(PROTOBUF_DEP) $(QPS_WORKER_OBJS) $(LIBDIR)/$(CONFIG)/libqps.a $(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) $(QPS_SERVER_OBJS) $(GTEST_LIB) $(LIBDIR)/$(CONFIG)/libqps.a $(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) -o $(BINDIR)/$(CONFIG)/qps_server + $(Q) $(LDXX) $(LDFLAGS) $(QPS_WORKER_OBJS) $(GTEST_LIB) $(LIBDIR)/$(CONFIG)/libqps.a $(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) -o $(BINDIR)/$(CONFIG)/qps_worker endif endif +$(OBJDIR)/$(CONFIG)/test/cpp/qps/client.o: $(LIBDIR)/$(CONFIG)/libqps.a $(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 $(OBJDIR)/$(CONFIG)/test/cpp/qps/server.o: $(LIBDIR)/$(CONFIG)/libqps.a $(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 +$(OBJDIR)/$(CONFIG)/test/cpp/qps/worker.o: $(LIBDIR)/$(CONFIG)/libqps.a $(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_qps_server: $(QPS_SERVER_OBJS:.o=.dep) - -ifneq ($(NO_SECURE),true) -ifneq ($(NO_DEPS),true) --include $(QPS_SERVER_OBJS:.o=.dep) -endif -endif - - -QPS_SERVER_ASYNC_SRC = \ - $(GENDIR)/test/cpp/qps/qpstest.pb.cc \ - test/cpp/qps/server_async.cc \ - -QPS_SERVER_ASYNC_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(QPS_SERVER_ASYNC_SRC)))) - -ifeq ($(NO_SECURE),true) - -# You can't build secure targets if you don't have OpenSSL with ALPN. - -$(BINDIR)/$(CONFIG)/qps_server_async: 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)/qps_server_async: protobuf_dep_error - -else - -$(BINDIR)/$(CONFIG)/qps_server_async: $(PROTOBUF_DEP) $(QPS_SERVER_ASYNC_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) $(QPS_SERVER_ASYNC_OBJS) $(GTEST_LIB) $(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) -o $(BINDIR)/$(CONFIG)/qps_server_async - -endif - -endif - -$(OBJDIR)/$(CONFIG)/test/cpp/qps/qpstest.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 -$(OBJDIR)/$(CONFIG)/test/cpp/qps/server_async.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_qps_server_async: $(QPS_SERVER_ASYNC_OBJS:.o=.dep) +deps_qps_worker: $(QPS_WORKER_OBJS:.o=.dep) ifneq ($(NO_SECURE),true) ifneq ($(NO_DEPS),true) --include $(QPS_SERVER_ASYNC_OBJS:.o=.dep) +-include $(QPS_WORKER_OBJS:.o=.dep) endif endif diff --git a/build.json b/build.json index 590d6f8c8e5..a48491ba5a6 100644 --- a/build.json +++ b/build.json @@ -1815,42 +1815,6 @@ "gpr" ] }, - { - "name": "qps_client", - "build": "test", - "run": false, - "language": "c++", - "src": [ - "test/cpp/qps/client.cc" - ], - "deps": [ - "qps", - "grpc++_test_util", - "grpc_test_util", - "grpc++", - "grpc", - "gpr_test_util", - "gpr" - ] - }, - { - "name": "qps_client_async", - "build": "test", - "run": false, - "language": "c++", - "src": [ - "test/cpp/qps/qpstest.proto", - "test/cpp/qps/client_async.cc" - ], - "deps": [ - "grpc++_test_util", - "grpc_test_util", - "grpc++", - "grpc", - "gpr_test_util", - "gpr" - ] - }, { "name": "qps_driver", "build": "test", @@ -1870,33 +1834,21 @@ ] }, { - "name": "qps_server", + "name": "qps_worker", "build": "test", "run": false, "language": "c++", - "src": [ - "test/cpp/qps/server.cc" + "headers": [ + "test/cpp/qps/client.h", + "test/cpp/qps/server.h" ], - "deps": [ - "qps", - "grpc++_test_util", - "grpc_test_util", - "grpc++", - "grpc", - "gpr_test_util", - "gpr" - ] - }, - { - "name": "qps_server_async", - "build": "test", - "run": false, - "language": "c++", "src": [ - "test/cpp/qps/qpstest.proto", - "test/cpp/qps/server_async.cc" + "test/cpp/qps/client.cc", + "test/cpp/qps/server.cc", + "test/cpp/qps/worker.cc" ], "deps": [ + "qps", "grpc++_test_util", "grpc_test_util", "grpc++", diff --git a/test/cpp/qps/client.h b/test/cpp/qps/client.h new file mode 100644 index 00000000000..ab34970ebd3 --- /dev/null +++ b/test/cpp/qps/client.h @@ -0,0 +1,53 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef TEST_QPS_CLIENT_H +#define TEST_QPS_CLIENT_H + +#include "test/cpp/qps/qpstest.pb.h" + +namespace grpc { +namespace testing { + +class Client { + public: + virtual ~Client() {} +}; + +std::unique_ptr CreateSynchronousClient(const ClientConfig& args); +std::unique_ptr CreateAsyncClient(const ClientConfig& args); + +} // namespace testing +} // namespace grpc + +#endif diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc index 098860610ca..a54aad5631f 100644 --- a/test/cpp/qps/driver.cc +++ b/test/cpp/qps/driver.cc @@ -57,12 +57,12 @@ using grpc::Status; using grpc::testing::ClientArgs; using grpc::testing::ClientConfig; using grpc::testing::ClientResult; -using grpc::testing::QpsClient; -using grpc::testing::QpsServer; +using grpc::testing::Worker; using grpc::testing::ServerArgs; using grpc::testing::ServerConfig; using grpc::testing::ServerStatus; +#if 0 static vector get_hosts(const string& name) { char* env = gpr_getenv(name.c_str()); if (!env) return vector(); @@ -92,8 +92,7 @@ void RunScenario(const ClientConfig& client_config, size_t num_clients, }; // Get client, server lists - auto clients = get_hosts("QPS_CLIENTS"); - auto servers = get_hosts("QPS_SERVERS"); + auto workers = get_hosts("QPS_WORKERS"); GPR_ASSERT(clients.size() >= num_clients); GPR_ASSERT(servers.size() >= num_servers); @@ -186,3 +185,4 @@ void RunScenario(const ClientConfig& client_config, size_t num_clients, } } } +#endif \ No newline at end of file diff --git a/test/cpp/qps/qpstest.proto b/test/cpp/qps/qpstest.proto index 11b7c882a62..52d79579446 100644 --- a/test/cpp/qps/qpstest.proto +++ b/test/cpp/qps/qpstest.proto @@ -75,9 +75,21 @@ message Latencies { required double l_999 = 4; } +enum ClientType { + SYNCHRONOUS_CLIENT = 1; + ASYNC_CLIENT = 2; +} + +enum ServerType { + SYNCHRONOUS_SERVER = 1; + ASYNC_SERVER = 2; +} + message ClientConfig { - required bool enable_ssl = 1; - required int32 client_threads = 2; + repeated string server_targets = 1; + required ClientType client_type = 2; + required bool enable_ssl = 3; + required int32 client_threads = 4; // We have a configurable number of channels for sending RPCs. // RPCs are sent round-robin on the available channels by the // various threads. Interesting cases are 1 global channel or @@ -86,14 +98,18 @@ message ClientConfig { // rather than just at initialization time in order to also measure the // impact of cache thrashing caused by channel changes. This is an issue // if you are not in one of the above "interesting cases" - required int32 client_channels = 3; - required int32 num_rpcs = 4; - required int32 payload_size = 5; + required int32 client_channels = 5; + required int32 num_rpcs = 6; + required int32 payload_size = 7; } +message ClientStart {} + message ClientArgs { - repeated string server_targets = 1; - required ClientConfig config = 2; + oneof argtype { + ClientConfig setup = 1; + ClientStart start = 2; + } } message ClientResult { @@ -104,9 +120,14 @@ message ClientResult { required double time_system = 5; } +message ClientStatus { + optional ClientResult result = 1; +} + message ServerConfig { - required int32 threads = 1; - required bool enable_ssl = 2; + required ServerType server_type = 1; + required int32 threads = 2; + required bool enable_ssl = 3; } message ServerArgs { @@ -203,12 +224,9 @@ service TestService { returns (stream StreamingOutputCallResponse); } -service QpsClient { +service Worker { // Start test with specified workload - rpc RunTest(ClientArgs) returns (ClientResult); -} - -service QpsServer { + rpc RunTest(stream ClientArgs) returns (stream ClientStatus); // Start test with specified workload rpc RunServer(stream ServerArgs) returns (stream ServerStatus); } diff --git a/test/cpp/qps/server.h b/test/cpp/qps/server.h new file mode 100644 index 00000000000..25c15e4d0cc --- /dev/null +++ b/test/cpp/qps/server.h @@ -0,0 +1,53 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef TEST_QPS_SERVER_H +#define TEST_QPS_SERVER_H + +#include "test/cpp/qps/qpstest.pb.h" + +namespace grpc { +namespace testing { + +class Server { + public: + virtual ~Server() {} +}; + +std::unique_ptr CreateSynchronousServer(const ServerConfig& config, int port); +std::unique_ptr CreateAsyncServer(const ServerConfig& config, int port); + +} // namespace testing +} // namespace grpc + +#endif diff --git a/test/cpp/qps/worker.cc b/test/cpp/qps/worker.cc new file mode 100644 index 00000000000..749420bd694 --- /dev/null +++ b/test/cpp/qps/worker.cc @@ -0,0 +1,202 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "test/core/util/grpc_profiler.h" +#include "test/cpp/util/create_test_channel.h" +#include "test/cpp/qps/qpstest.pb.h" +#include "test/cpp/qps/client.h" +#include "test/cpp/qps/server.h" + +DEFINE_int32(driver_port, 0, "Driver server port."); +DEFINE_int32(server_port, 0, "Spawned server port."); + +// In some distros, gflags is in the namespace google, and in some others, +// in gflags. This hack is enabling us to find both. +namespace google { } +namespace gflags { } +using namespace google; +using namespace gflags; + +static bool got_sigint = false; + +static void sigint_handler(int x) { got_sigint = 1; } + +namespace grpc { +namespace testing { + +std::unique_ptr CreateClient(const ClientConfig& config) { + switch (config.client_type()) { + case ClientType::SYNCHRONOUS_CLIENT: return CreateSynchronousClient(config); + case ClientType::ASYNC_CLIENT: return CreateAsyncClient(config); + } + abort(); +} + +std::unique_ptr CreateServer(const ServerConfig& config) { + switch (config.server_type()) { + case ServerType::SYNCHRONOUS_SERVER: return CreateSynchronousServer(config, FLAGS_server_port); + case ServerType::ASYNC_SERVER: return CreateAsyncServer(config, FLAGS_server_port); + } + abort(); +} + +class WorkerImpl final : public Worker::Service { + public: + WorkerImpl() : acquired_(false) {} + + Status RunTest(ServerContext* ctx, ServerReaderWriter* stream) GRPC_OVERRIDE { + InstanceGuard g(this); + if (!g.Acquired()) { + return Status(RESOURCE_EXHAUSTED); + } + + ClientArgs args; + if (!stream->Read(&args)) { + return Status(INVALID_ARGUMENT); + } + if (!args.has_setup()) { + return Status(INVALID_ARGUMENT); + } + auto client = CreateClient(args.setup()); + if (!client) { + return Status(INVALID_ARGUMENT); + } + + return Status::OK; + } + + Status RunServer(ServerContext* ctx, ServerReaderWriter* stream) GRPC_OVERRIDE { + InstanceGuard g(this); + if (!g.Acquired()) { + return Status(RESOURCE_EXHAUSTED); + } + + ServerArgs args; + if (!stream->Read(&args)) { + return Status(INVALID_ARGUMENT); + } + if (!args.has_config()) { + return Status(INVALID_ARGUMENT); + } + auto server = CreateServer(args.config()); + if (!server) { + return Status(INVALID_ARGUMENT); + } + + return Status::OK; + } + + private: + class InstanceGuard { + public: + InstanceGuard(WorkerImpl* impl) : impl_(impl), acquired_(impl->TryAcquireInstance()) {} + ~InstanceGuard() { if (acquired_) { impl_->ReleaseInstance(); } } + + bool Acquired() const { return acquired_; } + + private: + WorkerImpl* const impl_; + const bool acquired_; + }; + + bool TryAcquireInstance() { + std::lock_guard g(mu_); + if (acquired_) return false; + acquired_ = true; + return true; + } + + void ReleaseInstance() { + std::lock_guard g(mu_); + GPR_ASSERT(acquired_); + acquired_ = false; + } + + std::mutex mu_; + bool acquired_; +}; + +static void RunServer() { + char* server_address = NULL; + gpr_join_host_port(&server_address, "::", FLAGS_driver_port); + + WorkerImpl service; + + ServerBuilder builder; + builder.AddPort(server_address); + builder.RegisterService(&service); + + gpr_free(server_address); + + auto server = builder.BuildAndStart(); + + while (!got_sigint) { + std::this_thread::sleep_for(std::chrono::seconds(5)); + } +} + +} // namespace testing +} // namespace grpc + +int main(int argc, char **argv) { + signal(SIGINT, sigint_handler); + + grpc_init(); + ParseCommandLineFlags(&argc, &argv, true); + + grpc::testing::RunServer(); + + grpc_shutdown(); + return 0; +} From 4705a5a01ab675c03be473f40923c56e72f0138f Mon Sep 17 00:00:00 2001 From: Qi Zhao Date: Mon, 2 Mar 2015 17:04:30 -0800 Subject: [PATCH 025/120] Revert "dockerfiles/go: go install from GOPATH and remove bash from CMD" --- tools/dockerfile/grpc_go/Dockerfile | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/dockerfile/grpc_go/Dockerfile b/tools/dockerfile/grpc_go/Dockerfile index ada2208097d..06bb3e2d5e7 100644 --- a/tools/dockerfile/grpc_go/Dockerfile +++ b/tools/dockerfile/grpc_go/Dockerfile @@ -37,8 +37,8 @@ RUN go get google.golang.org/grpc ADD service_account service_account # Build the interop client and server -RUN go install google.golang.org/grpc/interop/client -RUN go install google.golang.org/grpc/interop/server +RUN cd src/google.golang.org/grpc/interop/client && go install +RUN cd src/google.golang.org/grpc/interop/server && go install # Specify the default command such that the interop server runs on its known testing port -CMD ["server", "--use_tls=true", "--port=8020"] +CMD ["/bin/bash", "-c", "cd src/google.golang.org/grpc/interop/server && go run server.go --use_tls=true --port=8020"] From da02a67e0551228e5ecd2055c116310edd0aa202 Mon Sep 17 00:00:00 2001 From: murgatroid99 Date: Mon, 2 Mar 2015 17:28:02 -0800 Subject: [PATCH 026/120] Updated Node library to new secure server API --- src/node/ext/server.cc | 32 +++++++++++------------------- src/node/interop/interop_server.js | 10 +++++----- src/node/src/server.js | 19 +++++++++--------- 3 files changed, 27 insertions(+), 34 deletions(-) diff --git a/src/node/ext/server.cc b/src/node/ext/server.cc index ab45da8d199..a87f9194e92 100644 --- a/src/node/ext/server.cc +++ b/src/node/ext/server.cc @@ -164,19 +164,7 @@ NAN_METHOD(Server::New) { if (args[0]->IsUndefined()) { wrapped_server = grpc_server_create(queue, NULL); } else if (args[0]->IsObject()) { - grpc_server_credentials *creds = NULL; - Handle args_hash(args[0]->ToObject()->Clone()); - if (args_hash->HasOwnProperty(NanNew("credentials"))) { - Handle creds_value = args_hash->Get(NanNew("credentials")); - if (!ServerCredentials::HasInstance(creds_value)) { - return NanThrowTypeError( - "credentials arg must be a ServerCredentials object"); - } - ServerCredentials *creds_object = - ObjectWrap::Unwrap(creds_value->ToObject()); - creds = creds_object->GetWrappedServerCredentials(); - args_hash->Delete(NanNew("credentials")); - } + Handle args_hash(args[0]->ToObject()); Handle keys(args_hash->GetOwnPropertyNames()); grpc_channel_args channel_args; channel_args.num_args = keys->Length(); @@ -203,11 +191,7 @@ NAN_METHOD(Server::New) { return NanThrowTypeError("Arg values must be strings"); } } - if (creds == NULL) { - wrapped_server = grpc_server_create(queue, &channel_args); - } else { - wrapped_server = grpc_secure_server_create(creds, queue, &channel_args); - } + wrapped_server = grpc_server_create(queue, &channel_args); free(channel_args.args); } else { return NanThrowTypeError("Server expects an object"); @@ -258,11 +242,19 @@ NAN_METHOD(Server::AddSecureHttp2Port) { "addSecureHttp2Port can only be called on a Server"); } if (!args[0]->IsString()) { - return NanThrowTypeError("addSecureHttp2Port's argument must be a String"); + return NanThrowTypeError( + "addSecureHttp2Port's first argument must be a String"); + } + if (!ServerCredentials::HasInstance(args[1])) { + return NanThrowTypeError( + "addSecureHttp2Port's second argument must be ServerCredentials"); } Server *server = ObjectWrap::Unwrap(args.This()); + ServerCredentials *creds = ObjectWrap::Unwrap( + args[1]->ToObject()); NanReturnValue(NanNew(grpc_server_add_secure_http2_port( - server->wrapped_server, *NanUtf8String(args[0])))); + server->wrapped_server, *NanUtf8String(args[0]), + creds->GetWrappedServerCredentials()))); } NAN_METHOD(Server::Start) { diff --git a/src/node/interop/interop_server.js b/src/node/interop/interop_server.js index 125ede17464..8e5c03666fa 100644 --- a/src/node/interop/interop_server.js +++ b/src/node/interop/interop_server.js @@ -165,16 +165,16 @@ function handleHalfDuplex(call) { function getServer(port, tls) { // TODO(mlumish): enable TLS functionality var options = {}; + var server_creds = null; if (tls) { var key_path = path.join(__dirname, '../test/data/server1.key'); var pem_path = path.join(__dirname, '../test/data/server1.pem'); var key_data = fs.readFileSync(key_path); var pem_data = fs.readFileSync(pem_path); - var server_creds = grpc.ServerCredentials.createSsl(null, - key_data, - pem_data); - options.credentials = server_creds; + server_creds = grpc.ServerCredentials.createSsl(null, + key_data, + pem_data); } var server = new Server({ 'grpc.testing.TestService' : { @@ -186,7 +186,7 @@ function getServer(port, tls) { halfDuplexCall: handleHalfDuplex } }, null, options); - var port_num = server.bind('0.0.0.0:' + port, tls); + var port_num = server.bind('0.0.0.0:' + port, server_creds); return {server: server, port: port_num}; } diff --git a/src/node/src/server.js b/src/node/src/server.js index 91dde022518..b72d110666e 100644 --- a/src/node/src/server.js +++ b/src/node/src/server.js @@ -517,14 +517,15 @@ Server.prototype.register = function(name, handler, serialize, deserialize, }; /** - * Binds the server to the given port, with SSL enabled if secure is specified + * Binds the server to the given port, with SSL enabled if creds is given * @param {string} port The port that the server should bind on, in the format * "address:port" - * @param {boolean=} secure Whether the server should open a secure port + * @param {boolean=} creds Server credential object to be used for SSL. Pass + * nothing for an insecure port */ -Server.prototype.bind = function(port, secure) { - if (secure) { - return this._server.addSecureHttp2Port(port); +Server.prototype.bind = function(port, creds) { + if (creds) { + return this._server.addSecureHttp2Port(port, creds); } else { return this._server.addHttp2Port(port); } @@ -604,14 +605,14 @@ function makeServerConstructor(services) { } /** - * Binds the server to the given port, with SSL enabled if secure is specified + * Binds the server to the given port, with SSL enabled if creds is supplied * @param {string} port The port that the server should bind on, in the format * "address:port" - * @param {boolean=} secure Whether the server should open a secure port + * @param {boolean=} creds Credentials to use for SSL * @return {SurfaceServer} this */ - SurfaceServer.prototype.bind = function(port, secure) { - return this.inner_server.bind(port, secure); + SurfaceServer.prototype.bind = function(port, creds) { + return this.inner_server.bind(port, creds); }; /** From 02fe58d1bdbc995a58b3b8a4fc65a78405cc2693 Mon Sep 17 00:00:00 2001 From: Raul Silvera Date: Mon, 2 Mar 2015 18:42:19 -0800 Subject: [PATCH 027/120] Propagate grpc_google_default_credentials_create errors --- src/cpp/client/credentials.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cpp/client/credentials.cc b/src/cpp/client/credentials.cc index a140f551e0d..eff0892810b 100644 --- a/src/cpp/client/credentials.cc +++ b/src/cpp/client/credentials.cc @@ -47,7 +47,8 @@ grpc_credentials *Credentials::GetRawCreds() { return creds_; } std::unique_ptr CredentialsFactory::GoogleDefaultCredentials() { grpc_credentials *c_creds = grpc_google_default_credentials_create(); - std::unique_ptr cpp_creds(new Credentials(c_creds)); + std::unique_ptr cpp_creds( + c_creds == nullptr ? nullptr : new Credentials(c_creds)); return cpp_creds; } From 36aa8e0193c8ff5d0546ea7a3172f89981c4c55b Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Tue, 3 Mar 2015 04:14:38 +0100 Subject: [PATCH 028/120] Adding a Travis badge. --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 8fa9fa4956e..fa60b83d162 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +[![Build Status](https://travis-ci.org/grpc/grpc.svg?branch=master)](https://travis-ci.org/grpc/grpc) + [gRPC - An RPC library and framework](http://github.com/grpc/grpc) =================================== From 6af9ed0bf78a1fe6cbfe5e91d44d34da5b152f1b Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Mon, 2 Mar 2015 22:42:10 -0800 Subject: [PATCH 029/120] Rework QPS client/server Now setup as a driver and N anonymous workers that may become clients or servers. Will convert async soon. --- test/cpp/qps/client.cc | 272 +++++++++++---------------- test/cpp/qps/client.h | 2 + test/cpp/qps/driver.cc | 218 ++++++++++----------- test/cpp/qps/driver.h | 4 + test/cpp/qps/histogram.h | 63 +++++++ test/cpp/qps/qps_driver.cc | 18 +- test/cpp/qps/qpstest.proto | 26 +-- test/cpp/qps/server.cc | 132 +++---------- test/cpp/qps/server.h | 2 + test/cpp/qps/single_run_localhost.sh | 18 +- test/cpp/qps/timer.cc | 6 + test/cpp/qps/timer.h | 2 + test/cpp/qps/worker.cc | 31 ++- 13 files changed, 387 insertions(+), 407 deletions(-) create mode 100644 test/cpp/qps/histogram.h diff --git a/test/cpp/qps/client.cc b/test/cpp/qps/client.cc index 7c9763a332d..827c1ec09b0 100644 --- a/test/cpp/qps/client.cc +++ b/test/cpp/qps/client.cc @@ -53,53 +53,112 @@ #include #include "test/core/util/grpc_profiler.h" #include "test/cpp/util/create_test_channel.h" +#include "test/cpp/qps/client.h" #include "test/cpp/qps/qpstest.pb.h" +#include "test/cpp/qps/histogram.h" #include "test/cpp/qps/timer.h" -DEFINE_int32(driver_port, 0, "Client driver port."); - -using grpc::ChannelInterface; -using grpc::CreateTestChannel; -using grpc::ServerBuilder; -using grpc::ServerContext; -using grpc::Status; -using grpc::testing::ClientArgs; -using grpc::testing::ClientConfig; -using grpc::testing::ClientResult; -using grpc::testing::QpsClient; -using grpc::testing::SimpleRequest; -using grpc::testing::SimpleResponse; -using grpc::testing::StatsRequest; -using grpc::testing::TestService; - -// In some distros, gflags is in the namespace google, and in some others, -// in gflags. This hack is enabling us to find both. -namespace google { } -namespace gflags { } -using namespace google; -using namespace gflags; - -static double now() { - gpr_timespec tv = gpr_now(); - return 1e9 * tv.tv_sec + tv.tv_nsec; -} +namespace grpc { +namespace testing { -static bool got_sigint = false; +class SynchronousClient GRPC_FINAL : public Client { + public: + SynchronousClient(const ClientConfig& config) : timer_(new Timer) { + for (int i = 0; i < config.client_channels(); i++) { + channels_.push_back(ClientChannelInfo(config.server_targets(i % config.server_targets_size()), config)); + auto* stub = channels_.back().get_stub(); + for (int j = 0; j < config.outstanding_rpcs_per_channel(); j++) { + threads_.emplace_back(new Thread(stub, config)); + } + } + } -static void sigint_handler(int x) { got_sigint = 1; } + ClientStats Mark() { + Histogram latencies; + std::vector to_merge(threads_.size()); + for (size_t i = 0; i < threads_.size(); i++) { + threads_[i]->BeginSwap(&to_merge[i]); + } + std::unique_ptr timer(new Timer); + timer_.swap(timer); + for (size_t i = 0; i < threads_.size(); i++) { + threads_[i]->EndSwap(); + latencies.Merge(&to_merge[i]); + } + + auto timer_result = timer->Mark(); + + ClientStats stats; + auto* l = stats.mutable_latencies(); + l->set_l_50(latencies.Percentile(50)); + l->set_l_90(latencies.Percentile(90)); + l->set_l_99(latencies.Percentile(99)); + l->set_l_999(latencies.Percentile(99.9)); + stats.set_num_rpcs(latencies.Count()); + stats.set_time_elapsed(timer_result.wall); + stats.set_time_system(timer_result.system); + stats.set_time_user(timer_result.user); + return stats; + } -ClientResult RunTest(const ClientArgs& args) { - const auto& config = args.config(); + private: + class Thread { + public: + Thread(TestService::Stub* stub, const ClientConfig& config) : stub_(stub), config_(config), done_(false), new_(nullptr), impl_([this]() { + SimpleRequest request; + SimpleResponse response; + request.set_response_type( + grpc::testing::PayloadType::COMPRESSABLE); + request.set_response_size(config_.payload_size()); + for (;;) { + { + std::lock_guard g(mu_); + if (done_) return; + if (new_) { + new_->Swap(&histogram_); + new_ = nullptr; + cv_.notify_one(); + } + } + double start = Timer::Now(); + grpc::ClientContext context; + grpc::Status s = + stub_->UnaryCall(&context, request, &response); + histogram_.Add((Timer::Now() - start) * 1e9); + } + }) {} + + ~Thread() { + { + std::lock_guard g(mu_); + done_ = true; + } + impl_.join(); + } + + void BeginSwap(Histogram* n) { + std::lock_guard g(mu_); + new_ = n; + } + + void EndSwap() { + std::unique_lock g(mu_); + cv_.wait(g, [this]() { return new_ == nullptr; }); + } - gpr_log(GPR_INFO, - "QPS test with parameters\n" - "enable_ssl = %d\n" - "client_channels = %d\n" - "client_threads = %d\n" - "num_rpcs = %d\n" - "payload_size = %d\n", - config.enable_ssl(), config.client_channels(), config.client_threads(), config.num_rpcs(), - config.payload_size()); + private: + Thread(const Thread&); + Thread& operator=(const Thread&); + + TestService::Stub* stub_; + ClientConfig config_; + std::mutex mu_; + std::condition_variable cv_; + bool done_; + Histogram *new_; + Histogram histogram_; + std::thread impl_; + }; class ClientChannelInfo { public: @@ -113,133 +172,14 @@ ClientResult RunTest(const ClientArgs& args) { std::shared_ptr channel_; std::unique_ptr stub_; }; - - std::vector channels; - for (int i = 0; i < config.client_channels(); i++) { - channels.push_back(ClientChannelInfo(args.server_targets(i % args.server_targets_size()), config)); - } - - std::vector threads; // Will add threads when ready to execute - std::vector< ::gpr_histogram *> thread_stats(config.client_threads()); - - grpc::ClientContext context_stats_begin; - - grpc_profiler_start("qps_client.prof"); - - Timer timer; - - for (int i = 0; i < config.client_threads(); i++) { - gpr_histogram *hist = gpr_histogram_create(0.01, 60e9); - GPR_ASSERT(hist != NULL); - thread_stats[i] = hist; - - threads.push_back( - std::thread([hist, config, &channels](int channel_num) { - SimpleRequest request; - SimpleResponse response; - request.set_response_type( - grpc::testing::PayloadType::COMPRESSABLE); - request.set_response_size(config.payload_size()); - - for (int j = 0; j < config.num_rpcs(); j++) { - TestService::Stub *stub = - channels[channel_num].get_stub(); - double start = now(); - grpc::ClientContext context; - grpc::Status s = - stub->UnaryCall(&context, request, &response); - gpr_histogram_add(hist, now() - start); - - GPR_ASSERT((s.code() == grpc::StatusCode::OK) && - (response.payload().type() == - grpc::testing::PayloadType::COMPRESSABLE) && - (response.payload().body().length() == - static_cast(config.payload_size()))); - - // Now do runtime round-robin assignment of the next - // channel number - channel_num += config.client_threads(); - channel_num %= config.client_channels(); - } - }, - i % config.client_channels())); - } - - for (auto &t : threads) { - t.join(); - } - - auto timer_result = timer.Mark(); - - grpc_profiler_stop(); - - gpr_histogram *hist = gpr_histogram_create(0.01, 60e9); - GPR_ASSERT(hist != NULL); - - for (int i = 0; i < config.client_threads(); i++) { - gpr_histogram *h = thread_stats[i]; - gpr_log(GPR_INFO, "latency at thread %d (50/90/95/99/99.9): %f/%f/%f/%f/%f", - i, gpr_histogram_percentile(h, 50), gpr_histogram_percentile(h, 90), - gpr_histogram_percentile(h, 95), gpr_histogram_percentile(h, 99), - gpr_histogram_percentile(h, 99.9)); - gpr_histogram_merge(hist, h); - gpr_histogram_destroy(h); - } - - ClientResult result; - auto* latencies = result.mutable_latencies(); - latencies->set_l_50(gpr_histogram_percentile(hist, 50)); - latencies->set_l_90(gpr_histogram_percentile(hist, 90)); - latencies->set_l_99(gpr_histogram_percentile(hist, 99)); - latencies->set_l_999(gpr_histogram_percentile(hist, 99.9)); - result.set_num_rpcs(config.client_threads() * config.num_rpcs()); - result.set_time_elapsed(timer_result.wall); - result.set_time_system(timer_result.system); - result.set_time_user(timer_result.user); - - gpr_histogram_destroy(hist); - - return result; -} - -class ClientImpl final : public QpsClient::Service { - public: - Status RunTest(ServerContext* ctx, const ClientArgs* args, ClientResult* result) override { - *result = ::RunTest(*args); - return Status::OK; - } - - private: - std::mutex client_mu_; + std::vector channels_; + std::vector> threads_; + std::unique_ptr timer_; }; -static void RunServer() { - char* server_address = NULL; - gpr_join_host_port(&server_address, "::", FLAGS_driver_port); - - ClientImpl service; - - ServerBuilder builder; - builder.AddPort(server_address); - builder.RegisterService(&service); - - gpr_free(server_address); - - auto server = builder.BuildAndStart(); - - while (!got_sigint) { - std::this_thread::sleep_for(std::chrono::seconds(5)); - } +std::unique_ptr CreateSynchronousClient(const ClientConfig& config) { + return std::unique_ptr(new SynchronousClient(config)); } -int main(int argc, char **argv) { - signal(SIGINT, sigint_handler); - - grpc_init(); - ParseCommandLineFlags(&argc, &argv, true); - - RunServer(); - - grpc_shutdown(); - return 0; -} +} // namespace testing +} // namespace grpc diff --git a/test/cpp/qps/client.h b/test/cpp/qps/client.h index ab34970ebd3..97701d3d18f 100644 --- a/test/cpp/qps/client.h +++ b/test/cpp/qps/client.h @@ -42,6 +42,8 @@ namespace testing { class Client { public: virtual ~Client() {} + + virtual ClientStats Mark() = 0; }; std::unique_ptr CreateSynchronousClient(const ClientConfig& args); diff --git a/test/cpp/qps/driver.cc b/test/cpp/qps/driver.cc index a54aad5631f..c090d0377ca 100644 --- a/test/cpp/qps/driver.cc +++ b/test/cpp/qps/driver.cc @@ -48,21 +48,9 @@ using std::list; using std::thread; using std::unique_ptr; using std::vector; -using grpc::string; -using grpc::ChannelArguments; -using grpc::ClientContext; -using grpc::ClientReaderWriter; -using grpc::CreateChannelDeprecated; -using grpc::Status; -using grpc::testing::ClientArgs; -using grpc::testing::ClientConfig; -using grpc::testing::ClientResult; -using grpc::testing::Worker; -using grpc::testing::ServerArgs; -using grpc::testing::ServerConfig; -using grpc::testing::ServerStatus; - -#if 0 + +namespace grpc { +namespace testing { static vector get_hosts(const string& name) { char* env = gpr_getenv(name.c_str()); if (!env) return vector(); @@ -70,119 +58,139 @@ static vector get_hosts(const string& name) { vector out; char* p = env; for (;;) { - char* comma = strchr(p, ','); - if (comma) { - out.emplace_back(p, comma); - p = comma + 1; - } else { - out.emplace_back(p); - gpr_free(env); - return out; - } + char* comma = strchr(p, ','); + if (comma) { + out.emplace_back(p, comma); + p = comma + 1; + } else { + out.emplace_back(p); + gpr_free(env); + return out; + } } } -void RunScenario(const ClientConfig& client_config, size_t num_clients, +void RunScenario(const ClientConfig& initial_client_config, size_t num_clients, const ServerConfig& server_config, size_t num_servers) { // ClientContext allocator (all are destroyed at scope exit) list contexts; auto alloc_context = [&contexts]() { - contexts.emplace_back(); - return &contexts.back(); + contexts.emplace_back(); + return &contexts.back(); }; // Get client, server lists auto workers = get_hosts("QPS_WORKERS"); + ClientConfig client_config = initial_client_config; - GPR_ASSERT(clients.size() >= num_clients); - GPR_ASSERT(servers.size() >= num_servers); + // TODO(ctiller): support running multiple configurations, and binpack client/server pairs + // to available workers + GPR_ASSERT(workers.size() >= num_clients + num_servers); // Trim to just what we need - clients.resize(num_clients); - servers.resize(num_servers); + workers.resize(num_clients + num_servers); // Start servers - vector> server_stubs; - vector>> server_streams; - vector server_targets; - for (const auto& target : servers) { - server_stubs.push_back(QpsServer::NewStub(CreateChannelDeprecated(target, ChannelArguments()))); - auto* stub = server_stubs.back().get(); - ServerArgs args; - *args.mutable_config() = server_config; - server_streams.push_back(stub->RunServer(alloc_context())); - auto* stream = server_streams.back().get(); - if (!stream->Write(args)) { - gpr_log(GPR_ERROR, "Failed starting server"); - return; - } - ServerStatus init_status; - if (!stream->Read(&init_status)) { - gpr_log(GPR_ERROR, "Failed starting server"); - return; - } - char* host; - char* driver_port; - char* cli_target; - gpr_split_host_port(target.c_str(), &host, &driver_port); - gpr_join_host_port(&cli_target, host, init_status.port()); - server_targets.push_back(cli_target); - gpr_free(host); - gpr_free(driver_port); - gpr_free(cli_target); + struct ServerData { + unique_ptr stub; + unique_ptr> stream; + }; + vector servers; + for (size_t i = 0; i < num_servers; i++) { + ServerData sd; + sd.stub = std::move(Worker::NewStub(CreateChannelDeprecated(workers[i], ChannelArguments()))); + ServerArgs args; + *args.mutable_setup() = server_config; + sd.stream = std::move(sd.stub->RunServer(alloc_context())); + GPR_ASSERT(sd.stream->Write(args)); + ServerStatus init_status; + GPR_ASSERT(sd.stream->Read(&init_status)); + char* host; + char* driver_port; + char* cli_target; + gpr_split_host_port(workers[i].c_str(), &host, &driver_port); + gpr_join_host_port(&cli_target, host, init_status.port()); + client_config.add_server_targets(cli_target); + gpr_free(host); + gpr_free(driver_port); + gpr_free(cli_target); + + servers.push_back(std::move(sd)); } // Start clients - class Client { - public: - Client(ClientContext* ctx, const string& target, const ClientArgs& args) - : thread_([ctx, target, args, this]() { - auto stub = QpsClient::NewStub(CreateChannelDeprecated(target, ChannelArguments())); - status_ = stub->RunTest(ctx, args, &result_); - }) {} - - ~Client() { join(); } - - void join() { if (!joined_) { thread_.join(); joined_ = true; } } - - const Status& status() const { return status_; } - const ClientResult& result() const { return result_; } - - private: - bool joined_ = false; - Status status_; - ClientResult result_; - thread thread_; + struct ClientData { + unique_ptr stub; + unique_ptr> stream; }; - list running_clients; - size_t svr_idx = 0; - for (const auto& target : clients) { - ClientArgs args; - *args.mutable_config() = client_config; - for (size_t i = 0; i < num_servers; i++) { - args.add_server_targets(server_targets[svr_idx]); - svr_idx = (svr_idx + 1) % num_servers; - } - - running_clients.emplace_back(alloc_context(), target, args); + vector clients; + for (size_t i = 0; i < num_clients; i++) { + ClientData cd; + cd.stub = std::move(Worker::NewStub(CreateChannelDeprecated(workers[i + num_servers], ChannelArguments()))); + ClientArgs args; + *args.mutable_setup() = client_config; + cd.stream = std::move(cd.stub->RunTest(alloc_context())); + GPR_ASSERT(cd.stream->Write(args)); + ClientStatus init_status; + GPR_ASSERT(cd.stream->Read(&init_status)); + + clients.push_back(std::move(cd)); } - // Finish clients - for (auto& client : running_clients) { - client.join(); - if (!client.status().IsOk()) { - gpr_log(GPR_ERROR, "Client failed"); - return; - } + // Let everything warmup + gpr_log(GPR_INFO, "Warming up"); + gpr_timespec start = gpr_now(); + gpr_sleep_until(gpr_time_add(start, gpr_time_from_seconds(5))); + + // Start a run + gpr_log(GPR_INFO, "Starting"); + ServerArgs server_mark; + server_mark.mutable_mark(); + ClientArgs client_mark; + client_mark.mutable_mark(); + for (auto& server : servers) { + GPR_ASSERT(server.stream->Write(server_mark)); + } + for (auto& client : clients) { + GPR_ASSERT(client.stream->Write(client_mark)); + } + ServerStatus server_status; + ClientStatus client_status; + for (auto& server : servers) { + GPR_ASSERT(server.stream->Read(&server_status)); } + for (auto& client : clients) { + GPR_ASSERT(client.stream->Read(&client_status)); + } + + // Wait some time + gpr_log(GPR_INFO, "Running"); + gpr_sleep_until(gpr_time_add(start, gpr_time_from_seconds(15))); - // Finish servers - for (auto& stream : server_streams) { - ServerStatus final_status; - ServerStatus dummy; - if (!stream->WritesDone() || !stream->Read(&final_status) || stream->Read(&dummy) || !stream->Finish().IsOk()) { - gpr_log(GPR_ERROR, "Server protocol error"); - } + // Finish a run + gpr_log(GPR_INFO, "Finishing"); + for (auto& server : servers) { + GPR_ASSERT(server.stream->Write(server_mark)); + } + for (auto& client : clients) { + GPR_ASSERT(client.stream->Write(client_mark)); + } + for (auto& server : servers) { + GPR_ASSERT(server.stream->Read(&server_status)); } + for (auto& client : clients) { + GPR_ASSERT(client.stream->Read(&client_status)); + } + + for (auto& client : clients) { + GPR_ASSERT(client.stream->WritesDone()); + GPR_ASSERT(client.stream->Finish().IsOk()); + } + for (auto& server : servers) { + GPR_ASSERT(server.stream->WritesDone()); + GPR_ASSERT(server.stream->Finish().IsOk()); + } +} + +} } -#endif \ No newline at end of file diff --git a/test/cpp/qps/driver.h b/test/cpp/qps/driver.h index 8ac9d2f0a3f..5c548bb8481 100644 --- a/test/cpp/qps/driver.h +++ b/test/cpp/qps/driver.h @@ -36,7 +36,11 @@ #include "test/cpp/qps/qpstest.pb.h" +namespace grpc { +namespace testing { void RunScenario(const grpc::testing::ClientConfig& client_config, size_t num_clients, const grpc::testing::ServerConfig& server_config, size_t num_servers); +} +} #endif diff --git a/test/cpp/qps/histogram.h b/test/cpp/qps/histogram.h new file mode 100644 index 00000000000..b8282a48c23 --- /dev/null +++ b/test/cpp/qps/histogram.h @@ -0,0 +1,63 @@ +/* + * + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#ifndef TEST_QPS_HISTOGRAM_H +#define TEST_QPS_HISTOGRAM_H + +#include + +namespace grpc { +namespace testing { + +class Histogram { + public: + Histogram() : impl_(gpr_histogram_create(0.01, 60e9)) {} + ~Histogram() { gpr_histogram_destroy(impl_); } + + void Merge(Histogram* h) { gpr_histogram_merge(impl_, h->impl_); } + void Add(double value) { gpr_histogram_add(impl_, value); } + double Percentile(double pctile) { return gpr_histogram_percentile(impl_, pctile); } + double Count() { return gpr_histogram_count(impl_); } + void Swap(Histogram* other) { std::swap(impl_, other->impl_); } + + private: + Histogram(const Histogram&); + Histogram& operator=(const Histogram&); + + gpr_histogram* impl_; +}; + +} +} + +#endif /* TEST_QPS_HISTOGRAM_H */ diff --git a/test/cpp/qps/qps_driver.cc b/test/cpp/qps/qps_driver.cc index 88b9d373a11..cbe0b857b04 100644 --- a/test/cpp/qps/qps_driver.cc +++ b/test/cpp/qps/qps_driver.cc @@ -32,6 +32,7 @@ */ #include +#include #include "test/cpp/qps/driver.h" @@ -43,15 +44,18 @@ DEFINE_bool(enable_ssl, false, "Use SSL"); // Server config DEFINE_int32(server_threads, 1, "Number of server threads"); +DEFINE_string(server_type, "SYNCHRONOUS_SERVER", "Server type"); // Client config -DEFINE_int32(client_threads, 1, "Number of client threads"); +DEFINE_int32(outstanding_rpcs_per_channel, 1, "Number of outstanding rpcs per channel"); DEFINE_int32(client_channels, 1, "Number of client channels"); -DEFINE_int32(num_rpcs, 10000, "Number of rpcs per client thread"); DEFINE_int32(payload_size, 1, "Payload size"); +DEFINE_string(client_type, "SYNCHRONOUS_CLIENT", "Client type"); using grpc::testing::ClientConfig; using grpc::testing::ServerConfig; +using grpc::testing::ClientType; +using grpc::testing::ServerType; // In some distros, gflags is in the namespace google, and in some others, // in gflags. This hack is enabling us to find both. @@ -64,14 +68,20 @@ int main(int argc, char **argv) { grpc_init(); ParseCommandLineFlags(&argc, &argv, true); + ClientType client_type; + ServerType server_type; + GPR_ASSERT(ClientType_Parse(FLAGS_client_type, &client_type)); + GPR_ASSERT(ServerType_Parse(FLAGS_server_type, &server_type)); + ClientConfig client_config; + client_config.set_client_type(client_type); client_config.set_enable_ssl(FLAGS_enable_ssl); - client_config.set_client_threads(FLAGS_client_threads); + client_config.set_outstanding_rpcs_per_channel(FLAGS_outstanding_rpcs_per_channel); client_config.set_client_channels(FLAGS_client_channels); - client_config.set_num_rpcs(FLAGS_num_rpcs); client_config.set_payload_size(FLAGS_payload_size); ServerConfig server_config; + server_config.set_server_type(server_type); server_config.set_threads(FLAGS_server_threads); server_config.set_enable_ssl(FLAGS_enable_ssl); diff --git a/test/cpp/qps/qpstest.proto b/test/cpp/qps/qpstest.proto index 52d79579446..39d44cd0ed8 100644 --- a/test/cpp/qps/qpstest.proto +++ b/test/cpp/qps/qpstest.proto @@ -89,30 +89,21 @@ message ClientConfig { repeated string server_targets = 1; required ClientType client_type = 2; required bool enable_ssl = 3; - required int32 client_threads = 4; - // We have a configurable number of channels for sending RPCs. - // RPCs are sent round-robin on the available channels by the - // various threads. Interesting cases are 1 global channel or - // 1 per-thread channel, but we can support any number. - // The channels are assigned round-robin on an RPC by RPC basis - // rather than just at initialization time in order to also measure the - // impact of cache thrashing caused by channel changes. This is an issue - // if you are not in one of the above "interesting cases" + required int32 outstanding_rpcs_per_channel = 4; required int32 client_channels = 5; - required int32 num_rpcs = 6; - required int32 payload_size = 7; + required int32 payload_size = 6; } -message ClientStart {} +message Mark {} message ClientArgs { oneof argtype { ClientConfig setup = 1; - ClientStart start = 2; + Mark mark = 2; } } -message ClientResult { +message ClientStats { required Latencies latencies = 1; required int32 num_rpcs = 2; required double time_elapsed = 3; @@ -121,7 +112,7 @@ message ClientResult { } message ClientStatus { - optional ClientResult result = 1; + optional ClientStats stats = 1; } message ServerConfig { @@ -131,7 +122,10 @@ message ServerConfig { } message ServerArgs { - required ServerConfig config = 1; + oneof argtype { + ServerConfig setup = 1; + Mark mark = 2; + } } message ServerStatus { diff --git a/test/cpp/qps/server.cc b/test/cpp/qps/server.cc index 75425c9eb8e..ebe06c1e4a5 100644 --- a/test/cpp/qps/server.cc +++ b/test/cpp/qps/server.cc @@ -48,42 +48,14 @@ #include "src/cpp/server/thread_pool.h" #include "test/core/util/grpc_profiler.h" #include "test/cpp/qps/qpstest.pb.h" +#include "test/cpp/qps/server.h" #include "test/cpp/qps/timer.h" #include #include -DEFINE_int32(port, 0, "Server port."); -DEFINE_int32(driver_port, 0, "Server driver port."); - -using grpc::Server; -using grpc::ServerBuilder; -using grpc::ServerContext; -using grpc::ServerReaderWriter; -using grpc::ThreadPool; -using grpc::testing::Payload; -using grpc::testing::PayloadType; -using grpc::testing::ServerStats; -using grpc::testing::SimpleRequest; -using grpc::testing::SimpleResponse; -using grpc::testing::StatsRequest; -using grpc::testing::TestService; -using grpc::testing::QpsServer; -using grpc::testing::ServerArgs; -using grpc::testing::ServerStats; -using grpc::testing::ServerStatus; -using grpc::Status; - -// In some distros, gflags is in the namespace google, and in some others, -// in gflags. This hack is enabling us to find both. -namespace google { } -namespace gflags { } -using namespace google; -using namespace gflags; - -static bool got_sigint = false; - -static void sigint_handler(int x) { got_sigint = 1; } +namespace grpc { +namespace testing { static bool SetPayload(PayloadType type, int size, Payload* payload) { PayloadType response_type = type; @@ -97,8 +69,6 @@ static bool SetPayload(PayloadType type, int size, Payload* payload) { return true; } -namespace { - class TestServiceImpl GRPC_FINAL : public TestService::Service { public: Status UnaryCall(ServerContext* context, const SimpleRequest* request, @@ -113,88 +83,46 @@ class TestServiceImpl GRPC_FINAL : public TestService::Service { } }; -} // namespace - -class ServerImpl : public QpsServer::Service { +class SynchronousServer GRPC_FINAL : public grpc::testing::Server { public: - Status RunServer(ServerContext* ctx, ServerReaderWriter* stream) { - ServerArgs args; - if (!stream->Read(&args)) return Status::OK; + SynchronousServer(const ServerConfig& config, int port) : thread_pool_(config.threads()), impl_(MakeImpl(port)), timer_(new Timer) {} - std::lock_guard lock(server_mu_); + ServerStats Mark() GRPC_OVERRIDE { + std::unique_ptr timer(new Timer); + timer.swap(timer_); - char* server_address = NULL; - gpr_join_host_port(&server_address, "::", FLAGS_port); + auto timer_result = timer->Mark(); - TestServiceImpl service; + ServerStats stats; + stats.set_time_elapsed(timer_result.wall); + stats.set_time_system(timer_result.system); + stats.set_time_user(timer_result.user); + return stats; + } + private: + std::unique_ptr MakeImpl(int port) { ServerBuilder builder; - builder.AddPort(server_address); - builder.RegisterService(&service); - - std::unique_ptr pool(new ThreadPool(args.config().threads())); - builder.SetThreadPool(pool.get()); - - auto server = builder.BuildAndStart(); - gpr_log(GPR_INFO, "Server listening on %s\n", server_address); + char* server_address = NULL; + gpr_join_host_port(&server_address, "::", port); + builder.AddPort(server_address); gpr_free(server_address); - ServerStatus status; - status.set_port(FLAGS_port); - if (!stream->Write(status)) return Status(grpc::UNKNOWN); - - grpc_profiler_start("qps_server.prof"); - Timer timer; - - if (stream->Read(&args)) { - gpr_log(GPR_ERROR, "Got a server request, but not expecting one"); - return Status(grpc::UNKNOWN); - } - - auto timer_result = timer.Mark(); - grpc_profiler_stop(); + builder.RegisterService(&service_); - auto* stats = status.mutable_stats(); - stats->set_time_elapsed(timer_result.wall); - stats->set_time_system(timer_result.system); - stats->set_time_user(timer_result.user); - stream->Write(status); - return Status::OK; + return builder.BuildAndStart(); } - private: - std::mutex server_mu_; + TestServiceImpl service_; + ThreadPool thread_pool_; + std::unique_ptr impl_; + std::unique_ptr timer_; }; -static void RunServer() { - char* server_address = NULL; - gpr_join_host_port(&server_address, "::", FLAGS_driver_port); - - ServerImpl service; - - ServerBuilder builder; - builder.AddPort(server_address); - builder.RegisterService(&service); - - gpr_free(server_address); - - auto server = builder.BuildAndStart(); - - while (!got_sigint) { - sleep(5); - } +std::unique_ptr CreateSynchronousServer(const ServerConfig& config, int port) { + return std::unique_ptr(new SynchronousServer(config, port)); } -int main(int argc, char** argv) { - signal(SIGINT, sigint_handler); - - grpc_init(); - ParseCommandLineFlags(&argc, &argv, true); - - GPR_ASSERT(FLAGS_port != 0); - RunServer(); - - grpc_shutdown(); - return 0; -} +} // namespace testing +} // namespace grpc diff --git a/test/cpp/qps/server.h b/test/cpp/qps/server.h index 25c15e4d0cc..35d1aed19f7 100644 --- a/test/cpp/qps/server.h +++ b/test/cpp/qps/server.h @@ -42,6 +42,8 @@ namespace testing { class Server { public: virtual ~Server() {} + + virtual ServerStats Mark() = 0; }; std::unique_ptr CreateSynchronousServer(const ServerConfig& config, int port); diff --git a/test/cpp/qps/single_run_localhost.sh b/test/cpp/qps/single_run_localhost.sh index 310a0824bb3..2f60b4e49de 100755 --- a/test/cpp/qps/single_run_localhost.sh +++ b/test/cpp/qps/single_run_localhost.sh @@ -6,25 +6,23 @@ set -ex cd $(dirname $0)/../../.. -killall qps_server qps_client || true +killall qps_worker || true config=opt NUMCPUS=`python2.7 -c 'import multiprocessing; print multiprocessing.cpu_count()'` -make CONFIG=$config qps_client qps_server qps_driver -j$NUMCPUS +make CONFIG=$config qps_worker qps_driver -j$NUMCPUS -bins/$config/qps_server -driver_port 10000 -port 10002 & -SERVER_PID=$! -bins/$config/qps_client -driver_port 10001 & -CLIENT_PID=$! +bins/$config/qps_worker -driver_port 10000 -server_port 10001 & +PID1=$! +bins/$config/qps_worker -driver_port 10010 -server_port 10011 & +PID2=$! -export QPS_SERVERS=localhost:10000 -export QPS_CLIENTS=localhost:10001 +export QPS_WORKERS="localhost:10000,localhost:10010" bins/$config/qps_driver $* -kill -2 $CLIENT_PID -kill -2 $SERVER_PID +kill -2 $PID1 $PID2 wait diff --git a/test/cpp/qps/timer.cc b/test/cpp/qps/timer.cc index 5a5be97071b..3c1342041cf 100644 --- a/test/cpp/qps/timer.cc +++ b/test/cpp/qps/timer.cc @@ -35,9 +35,15 @@ #include #include +#include Timer::Timer() : start_(Sample()) {} +double Timer::Now() { + auto ts = gpr_now(); + return ts.tv_sec + 1e-9 * ts.tv_nsec; +} + static double time_double(struct timeval* tv) { return tv->tv_sec + 1e-6 * tv->tv_usec; } diff --git a/test/cpp/qps/timer.h b/test/cpp/qps/timer.h index 8a229cbd305..1c9a006b937 100644 --- a/test/cpp/qps/timer.h +++ b/test/cpp/qps/timer.h @@ -46,6 +46,8 @@ class Timer { Result Mark(); + static double Now(); + private: static Result Sample(); diff --git a/test/cpp/qps/worker.cc b/test/cpp/qps/worker.cc index 749420bd694..741dfc000d3 100644 --- a/test/cpp/qps/worker.cc +++ b/test/cpp/qps/worker.cc @@ -78,7 +78,7 @@ namespace testing { std::unique_ptr CreateClient(const ClientConfig& config) { switch (config.client_type()) { case ClientType::SYNCHRONOUS_CLIENT: return CreateSynchronousClient(config); - case ClientType::ASYNC_CLIENT: return CreateAsyncClient(config); + case ClientType::ASYNC_CLIENT: abort(); //return CreateAsyncClient(config); } abort(); } @@ -86,7 +86,7 @@ std::unique_ptr CreateClient(const ClientConfig& config) { std::unique_ptr CreateServer(const ServerConfig& config) { switch (config.server_type()) { case ServerType::SYNCHRONOUS_SERVER: return CreateSynchronousServer(config, FLAGS_server_port); - case ServerType::ASYNC_SERVER: return CreateAsyncServer(config, FLAGS_server_port); + case ServerType::ASYNC_SERVER: abort(); //return CreateAsyncServer(config, FLAGS_server_port); } abort(); } @@ -112,6 +112,17 @@ class WorkerImpl final : public Worker::Service { if (!client) { return Status(INVALID_ARGUMENT); } + ClientStatus status; + if (!stream->Write(status)) { + return Status(UNKNOWN); + } + while (stream->Read(&args)) { + if (!args.has_mark()) { + return Status(INVALID_ARGUMENT); + } + *status.mutable_stats() = client->Mark(); + stream->Write(status); + } return Status::OK; } @@ -126,13 +137,25 @@ class WorkerImpl final : public Worker::Service { if (!stream->Read(&args)) { return Status(INVALID_ARGUMENT); } - if (!args.has_config()) { + if (!args.has_setup()) { return Status(INVALID_ARGUMENT); } - auto server = CreateServer(args.config()); + auto server = CreateServer(args.setup()); if (!server) { return Status(INVALID_ARGUMENT); } + ServerStatus status; + status.set_port(FLAGS_server_port); + if (!stream->Write(status)) { + return Status(UNKNOWN); + } + while (stream->Read(&args)) { + if (!args.has_mark()) { + return Status(INVALID_ARGUMENT); + } + *status.mutable_stats() = server->Mark(); + stream->Write(status); + } return Status::OK; } From 093a4ebd3e0bb307af0738ba4e53d5aed28b15f4 Mon Sep 17 00:00:00 2001 From: Stephen Thorne Date: Tue, 3 Mar 2015 16:13:56 +0000 Subject: [PATCH 030/120] Fix backslash line endings for grpc_python/Dockerfile. Without the correct line endings docker had errors interpreting '&&' as a command. --- tools/dockerfile/grpc_python/Dockerfile | 28 ++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/tools/dockerfile/grpc_python/Dockerfile b/tools/dockerfile/grpc_python/Dockerfile index 2e72752cdd7..58a3d8c14f1 100644 --- a/tools/dockerfile/grpc_python/Dockerfile +++ b/tools/dockerfile/grpc_python/Dockerfile @@ -44,21 +44,21 @@ RUN cd /var/local/git/grpc \ && pip install src/python/interop # Run Python GRPC's tests +# TODO(nathaniel): It would be nice for these to be auto-discoverable? RUN cd /var/local/git/grpc \ - # TODO(nathaniel): It would be nice for these to be auto-discoverable? - && python2.7 -B -m grpc._adapter._blocking_invocation_inline_service_test - && python2.7 -B -m grpc._adapter._c_test - && python2.7 -B -m grpc._adapter._event_invocation_synchronous_event_service_test - && python2.7 -B -m grpc._adapter._future_invocation_asynchronous_event_service_test - && python2.7 -B -m grpc._adapter._links_test - && python2.7 -B -m grpc._adapter._lonely_rear_link_test - && python2.7 -B -m grpc._adapter._low_test - && python2.7 -B -m grpc.framework.assembly.implementations_test - && python2.7 -B -m grpc.framework.base.packets.implementations_test - && python2.7 -B -m grpc.framework.face.blocking_invocation_inline_service_test - && python2.7 -B -m grpc.framework.face.event_invocation_synchronous_event_service_test - && python2.7 -B -m grpc.framework.face.future_invocation_asynchronous_event_service_test - && python2.7 -B -m grpc.framework.foundation._later_test + && python2.7 -B -m grpc._adapter._blocking_invocation_inline_service_test \ + && python2.7 -B -m grpc._adapter._c_test \ + && python2.7 -B -m grpc._adapter._event_invocation_synchronous_event_service_test \ + && python2.7 -B -m grpc._adapter._future_invocation_asynchronous_event_service_test \ + && python2.7 -B -m grpc._adapter._links_test \ + && python2.7 -B -m grpc._adapter._lonely_rear_link_test \ + && python2.7 -B -m grpc._adapter._low_test \ + && python2.7 -B -m grpc.framework.assembly.implementations_test \ + && python2.7 -B -m grpc.framework.base.packets.implementations_test \ + && python2.7 -B -m grpc.framework.face.blocking_invocation_inline_service_test \ + && python2.7 -B -m grpc.framework.face.event_invocation_synchronous_event_service_test \ + && python2.7 -B -m grpc.framework.face.future_invocation_asynchronous_event_service_test \ + && python2.7 -B -m grpc.framework.foundation._later_test \ && python2.7 -B -m grpc.framework.foundation._logging_pool_test # Add a cacerts directory containing the Google root pem file, allowing the interop client to access the production test instance From 4e233a1a4653699bda751ef38923c7d755093d2c Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Tue, 3 Mar 2015 09:17:41 -0800 Subject: [PATCH 031/120] Add macros --- include/grpc++/config.h | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/include/grpc++/config.h b/include/grpc++/config.h index cfa8d3be9f1..e753e4f9761 100644 --- a/include/grpc++/config.h +++ b/include/grpc++/config.h @@ -34,7 +34,6 @@ #ifndef GRPCXX_CONFIG_H #define GRPCXX_CONFIG_H -#include #ifdef GRPC_OLD_CXX #define GRPC_FINAL @@ -44,9 +43,23 @@ #define GRPC_OVERRIDE override #endif +#ifndef GRPC_CUSTOM_STRING +#include +#define GRPC_CUSTOM_STRING std::string +#endif + +#ifndef GRPC_CUSTOM_MESSAGE +#include +#define GRPC_CUSTOM_MESSAGE ::google::protobuf::Message +#endif + namespace grpc { -typedef std::string string; +typedef GRPC_CUSTOM_STRING string; + +namespace protobuf { +typedef GRPC_CUSTOM_MESSAGE Message; +} // namespace protobuf } // namespace grpc From 7694c35d5f9c85ea844755d35f7d78d76e38348c Mon Sep 17 00:00:00 2001 From: Yang Gao Date: Tue, 3 Mar 2015 09:48:06 -0800 Subject: [PATCH 032/120] Global replace google::protobuf::Message with grpc::protobuf::Message, all tests passed --- include/grpc++/async_unary_call.h | 2 +- include/grpc++/channel_interface.h | 6 ------ include/grpc++/client_context.h | 6 ------ include/grpc++/completion_queue.h | 4 ++-- include/grpc++/impl/call.h | 14 ++++---------- include/grpc++/impl/client_unary_call.h | 11 ++++------- include/grpc++/impl/rpc_method.h | 6 ------ include/grpc++/impl/rpc_service_method.h | 20 ++++++++++---------- include/grpc++/impl/service_type.h | 12 ++++-------- include/grpc++/server.h | 8 +------- include/grpc++/stream.h | 12 ++++++------ src/cpp/client/client_unary_call.cc | 4 ++-- src/cpp/common/call.cc | 4 ++-- src/cpp/proto/proto_utils.cc | 4 ++-- src/cpp/proto/proto_utils.h | 11 ++++------- src/cpp/server/async_server_context.cc | 4 ++-- src/cpp/server/server.cc | 10 +++++----- 17 files changed, 49 insertions(+), 89 deletions(-) diff --git a/include/grpc++/async_unary_call.h b/include/grpc++/async_unary_call.h index 71b7d3ff858..f81cd7605d2 100644 --- a/include/grpc++/async_unary_call.h +++ b/include/grpc++/async_unary_call.h @@ -49,7 +49,7 @@ class ClientAsyncResponseReader GRPC_FINAL { public: ClientAsyncResponseReader(ChannelInterface* channel, CompletionQueue* cq, const RpcMethod& method, ClientContext* context, - const google::protobuf::Message& request, void* tag) + const grpc::protobuf::Message& request, void* tag) : context_(context), call_(channel->CreateCall(method, context, cq)) { init_buf_.Reset(tag); diff --git a/include/grpc++/channel_interface.h b/include/grpc++/channel_interface.h index 77d13636184..51260aed3d7 100644 --- a/include/grpc++/channel_interface.h +++ b/include/grpc++/channel_interface.h @@ -37,12 +37,6 @@ #include #include -namespace google { -namespace protobuf { -class Message; -} // namespace protobuf -} // namespace google - struct grpc_call; namespace grpc { diff --git a/include/grpc++/client_context.h b/include/grpc++/client_context.h index 87e5e9ad6c4..c55d7c2d586 100644 --- a/include/grpc++/client_context.h +++ b/include/grpc++/client_context.h @@ -47,12 +47,6 @@ using std::chrono::system_clock; struct grpc_call; struct grpc_completion_queue; -namespace google { -namespace protobuf { -class Message; -} // namespace protobuf -} // namespace google - namespace grpc { class CallOpBuffer; diff --git a/include/grpc++/completion_queue.h b/include/grpc++/completion_queue.h index 0ca12604038..f741e3c36bb 100644 --- a/include/grpc++/completion_queue.h +++ b/include/grpc++/completion_queue.h @@ -106,8 +106,8 @@ class CompletionQueue { friend Status BlockingUnaryCall(ChannelInterface *channel, const RpcMethod &method, ClientContext *context, - const google::protobuf::Message &request, - google::protobuf::Message *result); + const grpc::protobuf::Message &request, + grpc::protobuf::Message *result); // Wraps grpc_completion_queue_pluck. // Cannot be mixed with calls to Next(). diff --git a/include/grpc++/impl/call.h b/include/grpc++/impl/call.h index 3e199e3eaef..5de56629735 100644 --- a/include/grpc++/impl/call.h +++ b/include/grpc++/impl/call.h @@ -42,12 +42,6 @@ #include #include -namespace google { -namespace protobuf { -class Message; -} // namespace protobuf -} // namespace google - struct grpc_call; struct grpc_op; @@ -67,8 +61,8 @@ class CallOpBuffer : public CompletionQueueTag { std::multimap *metadata); void AddSendInitialMetadata(ClientContext *ctx); void AddRecvInitialMetadata(ClientContext *ctx); - void AddSendMessage(const google::protobuf::Message &message); - void AddRecvMessage(google::protobuf::Message *message); + void AddSendMessage(const grpc::protobuf::Message &message); + void AddRecvMessage(grpc::protobuf::Message *message); void AddClientSendClose(); void AddClientRecvStatus(ClientContext *ctx, Status *status); void AddServerSendStatus(std::multimap *metadata, @@ -95,10 +89,10 @@ class CallOpBuffer : public CompletionQueueTag { std::multimap *recv_initial_metadata_; grpc_metadata_array recv_initial_metadata_arr_; // Send message - const google::protobuf::Message *send_message_; + const grpc::protobuf::Message *send_message_; grpc_byte_buffer *send_message_buf_; // Recv message - google::protobuf::Message *recv_message_; + grpc::protobuf::Message *recv_message_; grpc_byte_buffer *recv_message_buf_; // Client send close bool client_send_close_; diff --git a/include/grpc++/impl/client_unary_call.h b/include/grpc++/impl/client_unary_call.h index d8703264e60..23cf3a66df8 100644 --- a/include/grpc++/impl/client_unary_call.h +++ b/include/grpc++/impl/client_unary_call.h @@ -34,11 +34,8 @@ #ifndef GRPCXX_IMPL_CLIENT_UNARY_CALL_H #define GRPCXX_IMPL_CLIENT_UNARY_CALL_H -namespace google { -namespace protobuf { -class Message; -} // namespace protobuf -} // namespace google + +#include namespace grpc { @@ -51,8 +48,8 @@ class Status; // Wrapper that performs a blocking unary call Status BlockingUnaryCall(ChannelInterface *channel, const RpcMethod &method, ClientContext *context, - const google::protobuf::Message &request, - google::protobuf::Message *result); + const grpc::protobuf::Message &request, + grpc::protobuf::Message *result); } // namespace grpc diff --git a/include/grpc++/impl/rpc_method.h b/include/grpc++/impl/rpc_method.h index ab407f5c468..e8909ac1846 100644 --- a/include/grpc++/impl/rpc_method.h +++ b/include/grpc++/impl/rpc_method.h @@ -34,12 +34,6 @@ #ifndef GRPCXX_IMPL_RPC_METHOD_H #define GRPCXX_IMPL_RPC_METHOD_H -namespace google { -namespace protobuf { -class Message; -} // namespace protobuf -} // namespace google - namespace grpc { class RpcMethod { diff --git a/include/grpc++/impl/rpc_service_method.h b/include/grpc++/impl/rpc_service_method.h index ff94c7e6c00..325c8812caf 100644 --- a/include/grpc++/impl/rpc_service_method.h +++ b/include/grpc++/impl/rpc_service_method.h @@ -56,13 +56,13 @@ class MethodHandler { virtual ~MethodHandler() {} struct HandlerParameter { HandlerParameter(Call* c, ServerContext* context, - const google::protobuf::Message* req, - google::protobuf::Message* resp) + const grpc::protobuf::Message* req, + grpc::protobuf::Message* resp) : call(c), server_context(context), request(req), response(resp) {} Call* call; ServerContext* server_context; - const google::protobuf::Message* request; - google::protobuf::Message* response; + const grpc::protobuf::Message* request; + grpc::protobuf::Message* response; }; virtual Status RunHandler(const HandlerParameter& param) = 0; }; @@ -165,8 +165,8 @@ class RpcServiceMethod : public RpcMethod { // Takes ownership of the handler and two prototype objects. RpcServiceMethod(const char* name, RpcMethod::RpcType type, MethodHandler* handler, - google::protobuf::Message* request_prototype, - google::protobuf::Message* response_prototype) + grpc::protobuf::Message* request_prototype, + grpc::protobuf::Message* response_prototype) : RpcMethod(name, type), handler_(handler), request_prototype_(request_prototype), @@ -174,17 +174,17 @@ class RpcServiceMethod : public RpcMethod { MethodHandler* handler() { return handler_.get(); } - google::protobuf::Message* AllocateRequestProto() { + grpc::protobuf::Message* AllocateRequestProto() { return request_prototype_->New(); } - google::protobuf::Message* AllocateResponseProto() { + grpc::protobuf::Message* AllocateResponseProto() { return response_prototype_->New(); } private: std::unique_ptr handler_; - std::unique_ptr request_prototype_; - std::unique_ptr response_prototype_; + std::unique_ptr request_prototype_; + std::unique_ptr response_prototype_; }; // This class contains all the method information for an rpc service. It is diff --git a/include/grpc++/impl/service_type.h b/include/grpc++/impl/service_type.h index 7481d64d6af..7cd3ddad6b7 100644 --- a/include/grpc++/impl/service_type.h +++ b/include/grpc++/impl/service_type.h @@ -34,11 +34,7 @@ #ifndef GRPCXX_IMPL_SERVICE_TYPE_H #define GRPCXX_IMPL_SERVICE_TYPE_H -namespace google { -namespace protobuf { -class Message; -} // namespace protobuf -} // namespace google +#include namespace grpc { @@ -72,7 +68,7 @@ class AsynchronousService { public: virtual void RequestAsyncCall(void* registered_method, ServerContext* context, - ::google::protobuf::Message* request, + ::grpc::protobuf::Message* request, ServerAsyncStreamingInterface* stream, CompletionQueue* cq, void* tag) = 0; }; @@ -91,7 +87,7 @@ class AsynchronousService { protected: void RequestAsyncUnary(int index, ServerContext* context, - ::google::protobuf::Message* request, + grpc::protobuf::Message* request, ServerAsyncStreamingInterface* stream, CompletionQueue* cq, void* tag) { dispatch_impl_->RequestAsyncCall(request_args_[index], context, request, @@ -104,7 +100,7 @@ class AsynchronousService { stream, cq, tag); } void RequestServerStreaming(int index, ServerContext* context, - ::google::protobuf::Message* request, + grpc::protobuf::Message* request, ServerAsyncStreamingInterface* stream, CompletionQueue* cq, void* tag) { dispatch_impl_->RequestAsyncCall(request_args_[index], context, request, diff --git a/include/grpc++/server.h b/include/grpc++/server.h index 3282b82d04e..e3ba93e4877 100644 --- a/include/grpc++/server.h +++ b/include/grpc++/server.h @@ -47,12 +47,6 @@ struct grpc_server; -namespace google { -namespace protobuf { -class Message; -} // namespace protobuf -} // namespace google - namespace grpc { class AsynchronousService; class RpcService; @@ -101,7 +95,7 @@ class Server GRPC_FINAL : private CallHook, // DispatchImpl void RequestAsyncCall(void* registered_method, ServerContext* context, - ::google::protobuf::Message* request, + grpc::protobuf::Message* request, ServerAsyncStreamingInterface* stream, CompletionQueue* cq, void* tag); diff --git a/include/grpc++/stream.h b/include/grpc++/stream.h index d95a379757e..7625bcc38d3 100644 --- a/include/grpc++/stream.h +++ b/include/grpc++/stream.h @@ -88,7 +88,7 @@ class ClientReader GRPC_FINAL : public ClientStreamingInterface, public: // Blocking create a stream and write the first request out. ClientReader(ChannelInterface* channel, const RpcMethod& method, - ClientContext* context, const google::protobuf::Message& request) + ClientContext* context, const grpc::protobuf::Message& request) : context_(context), call_(channel->CreateCall(method, context, &cq_)) { CallOpBuffer buf; buf.AddSendInitialMetadata(&context->send_initial_metadata_); @@ -142,7 +142,7 @@ class ClientWriter GRPC_FINAL : public ClientStreamingInterface, public: // Blocking create a stream. ClientWriter(ChannelInterface* channel, const RpcMethod& method, - ClientContext* context, google::protobuf::Message* response) + ClientContext* context, grpc::protobuf::Message* response) : context_(context), response_(response), call_(channel->CreateCall(method, context, &cq_)) { @@ -179,7 +179,7 @@ class ClientWriter GRPC_FINAL : public ClientStreamingInterface, private: ClientContext* context_; - google::protobuf::Message* const response_; + grpc::protobuf::Message* const response_; CompletionQueue cq_; Call call_; }; @@ -386,7 +386,7 @@ class ClientAsyncReader GRPC_FINAL : public ClientAsyncStreamingInterface, // Create a stream and write the first request out. ClientAsyncReader(ChannelInterface* channel, CompletionQueue* cq, const RpcMethod& method, ClientContext* context, - const google::protobuf::Message& request, void* tag) + const grpc::protobuf::Message& request, void* tag) : context_(context), call_(channel->CreateCall(method, context, cq)) { init_buf_.Reset(tag); init_buf_.AddSendInitialMetadata(&context->send_initial_metadata_); @@ -436,7 +436,7 @@ class ClientAsyncWriter GRPC_FINAL : public ClientAsyncStreamingInterface, public: ClientAsyncWriter(ChannelInterface* channel, CompletionQueue* cq, const RpcMethod& method, ClientContext* context, - google::protobuf::Message* response, void* tag) + grpc::protobuf::Message* response, void* tag) : context_(context), response_(response), call_(channel->CreateCall(method, context, cq)) { @@ -477,7 +477,7 @@ class ClientAsyncWriter GRPC_FINAL : public ClientAsyncStreamingInterface, private: ClientContext* context_; - google::protobuf::Message* const response_; + grpc::protobuf::Message* const response_; Call call_; CallOpBuffer init_buf_; CallOpBuffer meta_buf_; diff --git a/src/cpp/client/client_unary_call.cc b/src/cpp/client/client_unary_call.cc index 684b3cbadb4..5c179de9d8f 100644 --- a/src/cpp/client/client_unary_call.cc +++ b/src/cpp/client/client_unary_call.cc @@ -44,8 +44,8 @@ namespace grpc { // Wrapper that performs a blocking unary call Status BlockingUnaryCall(ChannelInterface *channel, const RpcMethod &method, ClientContext *context, - const google::protobuf::Message &request, - google::protobuf::Message *result) { + const grpc::protobuf::Message &request, + grpc::protobuf::Message *result) { CompletionQueue cq; Call call(channel->CreateCall(method, context, &cq)); CallOpBuffer buf; diff --git a/src/cpp/common/call.cc b/src/cpp/common/call.cc index f3a691114d2..b2b6c627857 100644 --- a/src/cpp/common/call.cc +++ b/src/cpp/common/call.cc @@ -163,11 +163,11 @@ void CallOpBuffer::AddSendInitialMetadata(ClientContext* ctx) { AddSendInitialMetadata(&ctx->send_initial_metadata_); } -void CallOpBuffer::AddSendMessage(const google::protobuf::Message& message) { +void CallOpBuffer::AddSendMessage(const grpc::protobuf::Message& message) { send_message_ = &message; } -void CallOpBuffer::AddRecvMessage(google::protobuf::Message* message) { +void CallOpBuffer::AddRecvMessage(grpc::protobuf::Message* message) { recv_message_ = message; recv_message_->Clear(); } diff --git a/src/cpp/proto/proto_utils.cc b/src/cpp/proto/proto_utils.cc index 69a6bb080e0..e6badd5d6e7 100644 --- a/src/cpp/proto/proto_utils.cc +++ b/src/cpp/proto/proto_utils.cc @@ -40,7 +40,7 @@ namespace grpc { -bool SerializeProto(const google::protobuf::Message &msg, +bool SerializeProto(const grpc::protobuf::Message &msg, grpc_byte_buffer **bp) { grpc::string msg_str; bool success = msg.SerializeToString(&msg_str); @@ -54,7 +54,7 @@ bool SerializeProto(const google::protobuf::Message &msg, } bool DeserializeProto(grpc_byte_buffer *buffer, - google::protobuf::Message *msg) { + grpc::protobuf::Message *msg) { grpc::string msg_string; grpc_byte_buffer_reader *reader = grpc_byte_buffer_reader_create(buffer); gpr_slice slice; diff --git a/src/cpp/proto/proto_utils.h b/src/cpp/proto/proto_utils.h index a0af4d6465d..7a1b1f8b7cb 100644 --- a/src/cpp/proto/proto_utils.h +++ b/src/cpp/proto/proto_utils.h @@ -34,23 +34,20 @@ #ifndef GRPC_INTERNAL_CPP_PROTO_PROTO_UTILS_H #define GRPC_INTERNAL_CPP_PROTO_PROTO_UTILS_H +#include + struct grpc_byte_buffer; -namespace google { -namespace protobuf { -class Message; -} -} namespace grpc { // Serialize the msg into a buffer created inside the function. The caller // should destroy the returned buffer when done with it. If serialization fails, // false is returned and buffer is left unchanged. -bool SerializeProto(const google::protobuf::Message &msg, +bool SerializeProto(const grpc::protobuf::Message &msg, grpc_byte_buffer **buffer); // The caller keeps ownership of buffer and msg. -bool DeserializeProto(grpc_byte_buffer *buffer, google::protobuf::Message *msg); +bool DeserializeProto(grpc_byte_buffer *buffer, grpc::protobuf::Message *msg); } // namespace grpc diff --git a/src/cpp/server/async_server_context.cc b/src/cpp/server/async_server_context.cc index 5f8c2ba10f4..bee75497b8c 100644 --- a/src/cpp/server/async_server_context.cc +++ b/src/cpp/server/async_server_context.cc @@ -58,14 +58,14 @@ void AsyncServerContext::Accept(grpc_completion_queue *cq) { call_, GRPC_WRITE_BUFFER_HINT) == GRPC_CALL_OK); } -bool AsyncServerContext::StartRead(google::protobuf::Message *request) { +bool AsyncServerContext::StartRead(grpc::protobuf::Message *request) { GPR_ASSERT(request); request_ = request; grpc_call_error err = grpc_call_start_read_old(call_, this); return err == GRPC_CALL_OK; } -bool AsyncServerContext::StartWrite(const google::protobuf::Message &response, +bool AsyncServerContext::StartWrite(const grpc::protobuf::Message &response, int flags) { grpc_byte_buffer *buffer = nullptr; if (!SerializeProto(response, &buffer)) { diff --git a/src/cpp/server/server.cc b/src/cpp/server/server.cc index 97bf0f1a6ea..17b97f6ecff 100644 --- a/src/cpp/server/server.cc +++ b/src/cpp/server/server.cc @@ -117,8 +117,8 @@ class Server::SyncRequest GRPC_FINAL : public CompletionQueueTag { } void Run() { - std::unique_ptr req; - std::unique_ptr res; + std::unique_ptr req; + std::unique_ptr res; if (has_request_payload_) { req.reset(method_->AllocateRequestProto()); if (!DeserializeProto(request_payload_, req.get())) { @@ -298,7 +298,7 @@ void Server::PerformOpsOnCall(CallOpBuffer* buf, Call* call) { class Server::AsyncRequest GRPC_FINAL : public CompletionQueueTag { public: AsyncRequest(Server* server, void* registered_method, ServerContext* ctx, - ::google::protobuf::Message* request, + grpc::protobuf::Message* request, ServerAsyncStreamingInterface* stream, CompletionQueue* cq, void* tag) : tag_(tag), @@ -352,7 +352,7 @@ class Server::AsyncRequest GRPC_FINAL : public CompletionQueueTag { private: void* const tag_; - ::google::protobuf::Message* const request_; + grpc::protobuf::Message* const request_; ServerAsyncStreamingInterface* const stream_; CompletionQueue* const cq_; ServerContext* const ctx_; @@ -364,7 +364,7 @@ class Server::AsyncRequest GRPC_FINAL : public CompletionQueueTag { }; void Server::RequestAsyncCall(void* registered_method, ServerContext* context, - ::google::protobuf::Message* request, + grpc::protobuf::Message* request, ServerAsyncStreamingInterface* stream, CompletionQueue* cq, void* tag) { new AsyncRequest(this, registered_method, context, request, stream, cq, tag); From 1532923d65684ddd006914f82af18d26a6a91659 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Mon, 2 Mar 2015 15:32:47 -0800 Subject: [PATCH 033/120] client side support for TLS --- src/csharp/Grpc.Core/Channel.cs | 55 +++++++-- src/csharp/Grpc.Core/ChannelArgs.cs | 112 ++++++++++++++++++ src/csharp/Grpc.Core/Credentials.cs | 77 ++++++++++++ src/csharp/Grpc.Core/Grpc.Core.csproj | 4 + .../Internal/ChannelArgsSafeHandle.cs | 77 ++++++++++++ .../Grpc.Core/Internal/ChannelSafeHandle.cs | 35 +++--- .../Internal/CredentialsSafeHandle.cs | 64 ++++++++++ .../Grpc.IntegrationTesting.csproj | 13 ++ .../Grpc.IntegrationTesting/InteropClient.cs | 25 +++- .../Grpc.IntegrationTesting/data/README | 1 + .../Grpc.IntegrationTesting/data/ca.pem | 15 +++ .../Grpc.IntegrationTesting/data/server1.key | 16 +++ .../Grpc.IntegrationTesting/data/server1.pem | 16 +++ src/csharp/ext/grpc_csharp_ext.c | 68 +++++++++++ 14 files changed, 545 insertions(+), 33 deletions(-) create mode 100644 src/csharp/Grpc.Core/ChannelArgs.cs create mode 100644 src/csharp/Grpc.Core/Credentials.cs create mode 100644 src/csharp/Grpc.Core/Internal/ChannelArgsSafeHandle.cs create mode 100644 src/csharp/Grpc.Core/Internal/CredentialsSafeHandle.cs create mode 100644 src/csharp/Grpc.IntegrationTesting/data/README create mode 100644 src/csharp/Grpc.IntegrationTesting/data/ca.pem create mode 100644 src/csharp/Grpc.IntegrationTesting/data/server1.key create mode 100644 src/csharp/Grpc.IntegrationTesting/data/server1.pem diff --git a/src/csharp/Grpc.Core/Channel.cs b/src/csharp/Grpc.Core/Channel.cs index 942651cf393..83d965debf1 100644 --- a/src/csharp/Grpc.Core/Channel.cs +++ b/src/csharp/Grpc.Core/Channel.cs @@ -1,5 +1,4 @@ #region Copyright notice and license - // Copyright 2015, Google Inc. // All rights reserved. // @@ -28,9 +27,7 @@ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - #endregion - using System; using System.Runtime.InteropServices; using System.Threading; @@ -39,18 +36,32 @@ using Grpc.Core.Internal; namespace Grpc.Core { - public class Channel : IDisposable - { + public class Channel : IDisposable + { readonly ChannelSafeHandle handle; readonly String target; - // TODO: add way how to create grpc_secure_channel.... - // TODO: add support for channel args... - public Channel(string target) - { - this.handle = ChannelSafeHandle.Create(target, IntPtr.Zero); - this.target = target; - } + /// + /// Creates a channel. + /// + public Channel(string target, Credentials credentials = null, ChannelArgs channelArgs = null) + { + using (ChannelArgsSafeHandle nativeChannelArgs = CreateNativeChannelArgs(channelArgs)) + { + if (credentials != null) + { + using (CredentialsSafeHandle nativeCredentials = credentials.ToNativeCredentials()) + { + this.handle = ChannelSafeHandle.CreateSecure(nativeCredentials, target, nativeChannelArgs); + } + } + else + { + this.handle = ChannelSafeHandle.Create(target, nativeChannelArgs); + } + } + this.target = GetOverridenTarget(target, channelArgs); + } internal ChannelSafeHandle Handle { @@ -81,5 +92,23 @@ namespace Grpc.Core handle.Dispose(); } } - } + + private static string GetOverridenTarget(string target, ChannelArgs args) + { + if (args != null && !string.IsNullOrEmpty(args.GetSslTargetNameOverride())) + { + return args.GetSslTargetNameOverride(); + } + return target; + } + + private static ChannelArgsSafeHandle CreateNativeChannelArgs(ChannelArgs args) + { + if (args == null) + { + return ChannelArgsSafeHandle.CreateNull(); + } + return args.ToNativeChannelArgs(); + } + } } diff --git a/src/csharp/Grpc.Core/ChannelArgs.cs b/src/csharp/Grpc.Core/ChannelArgs.cs new file mode 100644 index 00000000000..653a5780a33 --- /dev/null +++ b/src/csharp/Grpc.Core/ChannelArgs.cs @@ -0,0 +1,112 @@ +#region Copyright notice and license +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#endregion +using System; +using System.Collections.Generic; +using System.Runtime.InteropServices; +using System.Threading; +using System.Threading.Tasks; +using Grpc.Core.Internal; + +namespace Grpc.Core +{ + // TODO: should we be using the builder pattern? + public class ChannelArgs + { + public const string SslTargetNameOverrideKey = "grpc.ssl_target_name_override"; + + public class Builder + { + Dictionary stringArgs = new Dictionary(); + // TODO: AddInteger not supported yet. + public Builder AddString(string key, string value) + { + stringArgs.Add(key, value); + return this; + } + + public ChannelArgs Build() + { + return new ChannelArgs(stringArgs); + } + } + + Dictionary stringArgs; + + private ChannelArgs(Dictionary stringArgs) + { + // TODO: use immutable dict? + this.stringArgs = new Dictionary(stringArgs); + } + + public string GetSslTargetNameOverride() + { + string result; + if (stringArgs.TryGetValue(SslTargetNameOverrideKey, out result)) + { + return result; + } + return null; + } + + public static Builder NewBuilder() + { + return new Builder(); + } + + /// + /// Creates native object for the channel arguments. + /// + /// The native channel arguments. + internal ChannelArgsSafeHandle ToNativeChannelArgs() + { + ChannelArgsSafeHandle nativeArgs = null; + try + { + nativeArgs = ChannelArgsSafeHandle.Create(stringArgs.Count); + int i = 0; + foreach (var entry in stringArgs) + { + nativeArgs.SetString(i, entry.Key, entry.Value); + i++; + } + return nativeArgs; + } + catch (Exception e) + { + if (nativeArgs != null) + { + nativeArgs.Dispose(); + } + throw; + } + } + } +} diff --git a/src/csharp/Grpc.Core/Credentials.cs b/src/csharp/Grpc.Core/Credentials.cs new file mode 100644 index 00000000000..5116c277f72 --- /dev/null +++ b/src/csharp/Grpc.Core/Credentials.cs @@ -0,0 +1,77 @@ +#region Copyright notice and license + +// Copyright 2015, Google Inc. +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#endregion + +using System; +using Grpc.Core.Internal; + +namespace Grpc.Core +{ + public abstract class Credentials + { + /// + /// Creates native object for the credentials. + /// + /// The native credentials. + internal abstract CredentialsSafeHandle ToNativeCredentials(); + } + + /// + /// Client-side SSL credentials. + /// + public class SslCredentials : Credentials + { + string pemRootCerts; + + public SslCredentials(string pemRootCerts) + { + this.pemRootCerts = pemRootCerts; + } + + /// + /// PEM encoding of the server root certificates. + /// + public string RootCerts + { + get + { + return this.pemRootCerts; + } + } + + internal override CredentialsSafeHandle ToNativeCredentials() + { + return CredentialsSafeHandle.CreateSslCredentials(pemRootCerts); + } + } +} + diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj index 05d40d45a6e..93d5430591b 100644 --- a/src/csharp/Grpc.Core/Grpc.Core.csproj +++ b/src/csharp/Grpc.Core/Grpc.Core.csproj @@ -65,6 +65,10 @@ + + + + GRPC_OVERRIDE --- test/cpp/qps/server_sync.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/cpp/qps/server_sync.cc b/test/cpp/qps/server_sync.cc index 8a75b73af3d..beee688608e 100644 --- a/test/cpp/qps/server_sync.cc +++ b/test/cpp/qps/server_sync.cc @@ -60,7 +60,7 @@ namespace testing { class TestServiceImpl GRPC_FINAL : public TestService::Service { public: Status UnaryCall(ServerContext* context, const SimpleRequest* request, - SimpleResponse* response) override { + SimpleResponse* response) GRPC_OVERRIDE { if (request->has_response_size() && request->response_size() > 0) { if (!Server::SetPayload(request->response_type(), request->response_size(), From 461be402a94903eab2d8947f91ec3f6e16a07d66 Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 5 Mar 2015 04:59:18 +0000 Subject: [PATCH 078/120] Fix ref counting --- src/core/surface/call.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/surface/call.c b/src/core/surface/call.c index b2033f3dc0e..cfce9437940 100644 --- a/src/core/surface/call.c +++ b/src/core/surface/call.c @@ -375,6 +375,7 @@ static void unlock(grpc_call *call) { sizeof(completed_requests)); call->num_completed_requests = 0; call->completing = 1; + grpc_call_internal_ref(call); } if (!call->sending) { @@ -403,6 +404,7 @@ static void unlock(grpc_call *call) { lock(call); call->completing = 0; unlock(call); + grpc_call_internal_unref(call, 0); } } From 49f61320539be82aa4e8f55491637c692098c0bf Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Tue, 3 Mar 2015 13:02:11 -0800 Subject: [PATCH 079/120] Teach run_tests about individual Python tests Allows: - running python tests in parallel - clearer Travis output - subjects each python test to the five minute run_tests timeout, instead of ALL the tests to the five minute timeout - easier benchmarking of which tests are slow --- tools/run_tests/python_tests.json | 18 ++++++++++++++++ tools/run_tests/run_python.sh | 22 +------------------- tools/run_tests/run_tests.py | 34 +++++++++++++++++++++++-------- 3 files changed, 44 insertions(+), 30 deletions(-) create mode 100755 tools/run_tests/python_tests.json diff --git a/tools/run_tests/python_tests.json b/tools/run_tests/python_tests.json new file mode 100755 index 00000000000..9e5b1365e6a --- /dev/null +++ b/tools/run_tests/python_tests.json @@ -0,0 +1,18 @@ +[ + "grpc._adapter._blocking_invocation_inline_service_test", + "grpc._adapter._c_test", + "grpc._adapter._event_invocation_synchronous_event_service_test", + "grpc._adapter._future_invocation_asynchronous_event_service_test", + "grpc._adapter._links_test", + "grpc._adapter._lonely_rear_link_test", + "grpc._adapter._low_test", + "grpc.early_adopter.implementations_test", + "grpc.framework.assembly.implementations_test", + "grpc.framework.base.packets.implementations_test", + "grpc.framework.face.blocking_invocation_inline_service_test", + "grpc.framework.face.event_invocation_synchronous_event_service_test", + "grpc.framework.face.future_invocation_asynchronous_event_service_test", + "grpc.framework.foundation._later_test", + "grpc.framework.foundation._logging_pool_test" +] + diff --git a/tools/run_tests/run_python.sh b/tools/run_tests/run_python.sh index 9c7dea008db..403862b0a05 100755 --- a/tools/run_tests/run_python.sh +++ b/tools/run_tests/run_python.sh @@ -36,24 +36,4 @@ cd $(dirname $0)/../.. root=`pwd` export LD_LIBRARY_PATH=$root/libs/opt source python2.7_virtual_environment/bin/activate -# TODO(issue 215): Properly itemize these in run_tests.py so that they can be parallelized. -# TODO(atash): Enable dynamic unused port discovery for this test. -# TODO(mlumish): Re-enable this test when we can install protoc -# python2.7 -B test/compiler/python_plugin_test.py --build_mode=opt -python2.7 -B -m grpc._adapter._blocking_invocation_inline_service_test -python2.7 -B -m grpc._adapter._c_test -python2.7 -B -m grpc._adapter._event_invocation_synchronous_event_service_test -python2.7 -B -m grpc._adapter._future_invocation_asynchronous_event_service_test -python2.7 -B -m grpc._adapter._links_test -python2.7 -B -m grpc._adapter._lonely_rear_link_test -python2.7 -B -m grpc._adapter._low_test -python2.7 -B -m grpc.early_adopter.implementations_test -python2.7 -B -m grpc.framework.assembly.implementations_test -python2.7 -B -m grpc.framework.base.packets.implementations_test -python2.7 -B -m grpc.framework.face.blocking_invocation_inline_service_test -python2.7 -B -m grpc.framework.face.event_invocation_synchronous_event_service_test -python2.7 -B -m grpc.framework.face.future_invocation_asynchronous_event_service_test -python2.7 -B -m grpc.framework.foundation._later_test -python2.7 -B -m grpc.framework.foundation._logging_pool_test -# TODO(nathaniel): Get tests working under 3.4 (requires 3.X-friendly protobuf) -# python3.4 -B -m unittest discover -s src/python -p '*.py' +python2.7 -B -m $* diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index e1e4a4ba204..9d45693cd4a 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -57,8 +57,19 @@ class SimpleConfig(object): self.allow_hashing = (config != 'gcov') self.environ = environ - def job_spec(self, binary, hash_targets): - return jobset.JobSpec(cmdline=[binary], + def job_spec(self, cmdline, hash_targets): + """Construct a jobset.JobSpec for a test under this config + + Args: + cmdline: a list of strings specifying the command line the test + would like to run + hash_targets: either None (don't do caching of test results), or + a list of strings specifying files to include in a + binary hash to check if a test has changed + -- if used, all artifacts needed to run the test must + be listed + """ + return jobset.JobSpec(cmdline=cmdline, environ=self.environ, hash_targets=hash_targets if self.allow_hashing else None) @@ -74,9 +85,9 @@ class ValgrindConfig(object): self.maxjobs = 2 * multiprocessing.cpu_count() self.allow_hashing = False - def job_spec(self, binary, hash_targets): + def job_spec(self, cmdline, hash_targets): return jobset.JobSpec(cmdline=['valgrind', '--tool=%s' % self.tool] + - self.args + [binary], + self.args + cmdline, shortname='valgrind %s' % binary, hash_targets=None) @@ -95,7 +106,7 @@ class CLanguage(object): if travis and target['flaky']: continue binary = 'bins/%s/%s' % (config.build_config, target['name']) - out.append(config.job_spec(binary, [binary])) + out.append(config.job_spec([binary], [binary])) return out def make_targets(self): @@ -108,7 +119,7 @@ class CLanguage(object): class NodeLanguage(object): def test_specs(self, config, travis): - return [config.job_spec('tools/run_tests/run_node.sh', None)] + return [config.job_spec(['tools/run_tests/run_node.sh'], None)] def make_targets(self): return ['static_c'] @@ -120,7 +131,7 @@ class NodeLanguage(object): class PhpLanguage(object): def test_specs(self, config, travis): - return [config.job_spec('src/php/bin/run_tests.sh', None)] + return [config.job_spec(['src/php/bin/run_tests.sh'], None)] def make_targets(self): return ['static_c'] @@ -131,8 +142,13 @@ class PhpLanguage(object): class PythonLanguage(object): + def __init__(self): + with open('tools/run_tests/python_tests.json') as f: + self._tests = json.load(f) + def test_specs(self, config, travis): - return [config.job_spec('tools/run_tests/run_python.sh', None)] + return [config.job_spec(['tools/run_tests/run_python.sh', test], None) + for test in self._tests] def make_targets(self): return ['static_c'] @@ -143,7 +159,7 @@ class PythonLanguage(object): class RubyLanguage(object): def test_specs(self, config, travis): - return [config.job_spec('tools/run_tests/run_ruby.sh', None)] + return [config.job_spec(['tools/run_tests/run_ruby.sh'], None)] def make_targets(self): return ['static_c'] From 3a0d9768d3f167c9d54110ca08882d6c556658ca Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Thu, 5 Mar 2015 12:43:24 -0800 Subject: [PATCH 080/120] Updates the ruby C extension to match the new secure C server API --- src/ruby/ext/grpc/rb_server.c | 41 ++++++++++++----------------------- 1 file changed, 14 insertions(+), 27 deletions(-) diff --git a/src/ruby/ext/grpc/rb_server.c b/src/ruby/ext/grpc/rb_server.c index 5954e27d024..c54f02e87af 100644 --- a/src/ruby/ext/grpc/rb_server.c +++ b/src/ruby/ext/grpc/rb_server.c @@ -97,35 +97,19 @@ static VALUE grpc_rb_server_alloc(VALUE cls) { /* call-seq: cq = CompletionQueue.new - insecure_server = Server.new(cq, {'arg1': 'value1'}) - server_creds = ... - secure_server = Server.new(cq, {'arg1': 'value1'}, server_creds) + server = Server.new(cq, {'arg1': 'value1'}) Initializes server instances. */ -static VALUE grpc_rb_server_init(int argc, VALUE *argv, VALUE self) { - VALUE cqueue = Qnil; - VALUE credentials = Qnil; - VALUE channel_args = Qnil; +static VALUE grpc_rb_server_init(VALUE self, VALUE cqueue, VALUE channel_args) { grpc_completion_queue *cq = NULL; - grpc_server_credentials *creds = NULL; grpc_rb_server *wrapper = NULL; grpc_server *srv = NULL; grpc_channel_args args; MEMZERO(&args, grpc_channel_args, 1); - - /* "21" == 2 mandatory args, 1 (credentials) is optional */ - rb_scan_args(argc, argv, "21", &cqueue, &channel_args, &credentials); cq = grpc_rb_get_wrapped_completion_queue(cqueue); - Data_Get_Struct(self, grpc_rb_server, wrapper); grpc_rb_hash_convert_to_channel_args(channel_args, &args); srv = grpc_server_create(cq, &args); - if (credentials == Qnil) { - srv = grpc_server_create(cq, &args); - } else { - creds = grpc_rb_get_wrapped_server_credentials(credentials); - srv = grpc_secure_server_create(creds, cq, &args); - } if (args.args != NULL) { xfree(args.args); /* Allocated by grpc_rb_hash_convert_to_channel_args */ @@ -215,33 +199,36 @@ static VALUE grpc_rb_server_destroy(VALUE self) { // secure port server_creds = ... - secure_server = Server.new(cq, {'arg1': 'value1'}, creds) - secure_server.add_http_port('mydomain:7575', True) + secure_server = Server.new(cq, {'arg1': 'value1'}) + secure_server.add_http_port('mydomain:7575', server_creds) Adds a http2 port to server */ static VALUE grpc_rb_server_add_http2_port(int argc, VALUE *argv, VALUE self) { VALUE port = Qnil; - VALUE is_secure = Qnil; + VALUE rb_creds = Qnil; grpc_rb_server *s = NULL; + grpc_server_credentials *creds = NULL; int recvd_port = 0; - /* "11" == 1 mandatory args, 1 (is_secure) is optional */ - rb_scan_args(argc, argv, "11", &port, &is_secure); + /* "11" == 1 mandatory args, 1 (rb_creds) is optional */ + rb_scan_args(argc, argv, "11", &port, &rb_creds); Data_Get_Struct(self, grpc_rb_server, s); if (s->wrapped == NULL) { rb_raise(rb_eRuntimeError, "closed!"); return Qnil; - } else if (is_secure == Qnil || TYPE(is_secure) != T_TRUE) { + } else if (rb_creds == Qnil) { recvd_port = grpc_server_add_http2_port(s->wrapped, StringValueCStr(port)); if (recvd_port == 0) { rb_raise(rb_eRuntimeError, "could not add port %s to server, not sure why", StringValueCStr(port)); } - } else if (TYPE(is_secure) != T_FALSE) { + } else { + creds = grpc_rb_get_wrapped_server_credentials(rb_creds); recvd_port = - grpc_server_add_secure_http2_port(s->wrapped, StringValueCStr(port)); + grpc_server_add_secure_http2_port(s->wrapped, StringValueCStr(port), + creds); if (recvd_port == 0) { rb_raise(rb_eRuntimeError, "could not add secure port %s to server, not sure why", @@ -258,7 +245,7 @@ void Init_grpc_server() { rb_define_alloc_func(rb_cServer, grpc_rb_server_alloc); /* Provides a ruby constructor and support for dup/clone. */ - rb_define_method(rb_cServer, "initialize", grpc_rb_server_init, -1); + rb_define_method(rb_cServer, "initialize", grpc_rb_server_init, 2); rb_define_method(rb_cServer, "initialize_copy", grpc_rb_server_init_copy, 1); /* Add the server methods. */ From ea85c2c30eccbd3a3abb94b1b233e0defdd92122 Mon Sep 17 00:00:00 2001 From: Donna Dionne Date: Thu, 5 Mar 2015 13:38:52 -0800 Subject: [PATCH 081/120] Adding csharp to test suite temp remove timing out test to investigate --- tools/gce_setup/cloud_prod_runner.sh | 2 +- tools/gce_setup/interop_test_runner.sh | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/tools/gce_setup/cloud_prod_runner.sh b/tools/gce_setup/cloud_prod_runner.sh index 3760ae49795..520dfcd998a 100755 --- a/tools/gce_setup/cloud_prod_runner.sh +++ b/tools/gce_setup/cloud_prod_runner.sh @@ -34,7 +34,7 @@ main() { # temporarily remove ping_pong and cancel_after_first_response while investigating timeout test_cases=(large_unary empty_unary client_streaming server_streaming cancel_after_begin) auth_test_cases=(service_account_creds compute_engine_creds) - clients=(cxx java go ruby node) + clients=(cxx java go ruby node csharp_mono) for test_case in "${test_cases[@]}" do for client in "${clients[@]}" diff --git a/tools/gce_setup/interop_test_runner.sh b/tools/gce_setup/interop_test_runner.sh index 5f8c0e70645..ebc631c1fd5 100755 --- a/tools/gce_setup/interop_test_runner.sh +++ b/tools/gce_setup/interop_test_runner.sh @@ -35,8 +35,9 @@ echo $result_file_name main() { source grpc_docker.sh - test_cases=(large_unary empty_unary ping_pong client_streaming server_streaming cancel_after_begin cancel_after_first_response) - clients=(cxx java go ruby node) + # temporarily remove ping_pong and cancel_after_first_response while investigating timeout + test_cases=(large_unary empty_unary client_streaming server_streaming cancel_after_begin) + clients=(cxx java go ruby node csharp_mono) servers=(cxx java go ruby node python) for test_case in "${test_cases[@]}" do From fd5d8ffee56c2c9c048fc88218d1d912acca529d Mon Sep 17 00:00:00 2001 From: David Klempner Date: Thu, 5 Mar 2015 14:17:38 -0800 Subject: [PATCH 082/120] Don't call grpc_create_chttp2_transport after destroying the server Add synchronization in server_secure_chttp2.c to avoid propagating a completed handshake past that layer to a potentially already destroyed server. --- src/core/security/server_secure_chttp2.c | 73 +++++++++++++++++++----- src/core/surface/server_chttp2.c | 7 +++ 2 files changed, 66 insertions(+), 14 deletions(-) diff --git a/src/core/security/server_secure_chttp2.c b/src/core/security/server_secure_chttp2.c index c88f0726bb7..bd6f8473cb7 100644 --- a/src/core/security/server_secure_chttp2.c +++ b/src/core/security/server_secure_chttp2.c @@ -35,6 +35,7 @@ #include "src/core/channel/http_filter.h" #include "src/core/channel/http_server_filter.h" +#include "src/core/iomgr/endpoint.h" #include "src/core/iomgr/resolve_address.h" #include "src/core/iomgr/tcp_server.h" #include "src/core/security/security_context.h" @@ -43,8 +44,27 @@ #include "src/core/transport/chttp2_transport.h" #include #include +#include #include +typedef struct grpc_server_secure_state { + grpc_server *server; + grpc_tcp_server *tcp; + int is_shutdown; + gpr_mu mu; + gpr_refcount refcount; +} grpc_server_secure_state; + +static void state_ref(grpc_server_secure_state *state) { + gpr_ref(&state->refcount); +} + +static void state_unref(grpc_server_secure_state *state) { + if (gpr_unref(&state->refcount)) { + gpr_free(state); + } +} + static grpc_transport_setup_result setup_transport(void *server, grpc_transport *transport, grpc_mdctx *mdctx) { @@ -54,44 +74,62 @@ static grpc_transport_setup_result setup_transport(void *server, GPR_ARRAY_SIZE(extra_filters), mdctx); } -static void on_secure_transport_setup_done(void *server, +static void on_secure_transport_setup_done(void *statep, grpc_security_status status, grpc_endpoint *secure_endpoint) { + grpc_server_secure_state *state = statep; if (status == GRPC_SECURITY_OK) { - grpc_create_chttp2_transport( - setup_transport, server, grpc_server_get_channel_args(server), - secure_endpoint, NULL, 0, grpc_mdctx_create(), 0); + gpr_mu_lock(&state->mu); + if (!state->is_shutdown) { + grpc_create_chttp2_transport( + setup_transport, state->server, + grpc_server_get_channel_args(state->server), + secure_endpoint, NULL, 0, grpc_mdctx_create(), 0); + } else { + /* We need to consume this here, because the server may already have gone + * away. */ + grpc_endpoint_destroy(secure_endpoint); + } + gpr_mu_unlock(&state->mu); } else { gpr_log(GPR_ERROR, "Secure transport failed with error %d", status); } + state_unref(state); } -static void on_accept(void *server, grpc_endpoint *tcp) { - const grpc_channel_args *args = grpc_server_get_channel_args(server); +static void on_accept(void *statep, grpc_endpoint *tcp) { + grpc_server_secure_state *state = statep; + const grpc_channel_args *args = grpc_server_get_channel_args(state->server); grpc_security_context *ctx = grpc_find_security_context_in_args(args); GPR_ASSERT(ctx); - grpc_setup_secure_transport(ctx, tcp, on_secure_transport_setup_done, server); + state_ref(state); + grpc_setup_secure_transport(ctx, tcp, on_secure_transport_setup_done, state); } /* Note: the following code is the same with server_chttp2.c */ /* Server callback: start listening on our ports */ -static void start(grpc_server *server, void *tcpp, grpc_pollset **pollsets, +static void start(grpc_server *server, void *statep, grpc_pollset **pollsets, size_t pollset_count) { - grpc_tcp_server *tcp = tcpp; - grpc_tcp_server_start(tcp, pollsets, pollset_count, on_accept, server); + grpc_server_secure_state *state = statep; + grpc_tcp_server_start(state->tcp, pollsets, pollset_count, on_accept, state); } /* Server callback: destroy the tcp listener (so we don't generate further callbacks) */ -static void destroy(grpc_server *server, void *tcpp) { - grpc_tcp_server *tcp = tcpp; - grpc_tcp_server_destroy(tcp); +static void destroy(grpc_server *server, void *statep) { + grpc_server_secure_state *state = statep; + gpr_mu_lock(&state->mu); + state->is_shutdown = 1; + grpc_tcp_server_destroy(state->tcp); + gpr_mu_unlock(&state->mu); + state_unref(state); } int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr) { grpc_resolved_addresses *resolved = NULL; grpc_tcp_server *tcp = NULL; + grpc_server_secure_state *state = NULL; size_t i; unsigned count = 0; int port_num = -1; @@ -132,8 +170,15 @@ int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr) { } grpc_resolved_addresses_destroy(resolved); + state = gpr_malloc(sizeof(*state)); + state->server = server; + state->tcp = tcp; + state->is_shutdown = 0; + gpr_mu_init(&state->mu); + gpr_ref_init(&state->refcount, 1); + /* Register with the server only upon success */ - grpc_server_add_listener(server, tcp, start, destroy); + grpc_server_add_listener(server, state, start, destroy); return port_num; diff --git a/src/core/surface/server_chttp2.c b/src/core/surface/server_chttp2.c index fd702593b89..27434b39e2d 100644 --- a/src/core/surface/server_chttp2.c +++ b/src/core/surface/server_chttp2.c @@ -53,6 +53,13 @@ static grpc_transport_setup_result setup_transport(void *server, } static void new_transport(void *server, grpc_endpoint *tcp) { + /* + * Beware that the call to grpc_create_chttp2_transport() has to happen before + * grpc_tcp_server_destroy(). This is fine here, but similar code + * asynchronously doing a handshake instead of calling grpc_tcp_server_start() + * (as in server_secure_chttp2.c) needs to add synchronization to avoid this + * case. + */ grpc_create_chttp2_transport(setup_transport, server, grpc_server_get_channel_args(server), tcp, NULL, 0, grpc_mdctx_create(), 0); From 0ce8edc49ef4390deac36594bcc6f83b716466be Mon Sep 17 00:00:00 2001 From: Tim Emiola Date: Thu, 5 Mar 2015 15:17:30 -0800 Subject: [PATCH 083/120] Updates ruby code affected by the secure server API change --- src/ruby/bin/interop/interop_server.rb | 5 ++--- src/ruby/bin/math_server.rb | 5 ++--- src/ruby/bin/noproto_server.rb | 5 ++--- src/ruby/lib/grpc/generic/rpc_server.rb | 9 +-------- src/ruby/spec/client_server_spec.rb | 18 ++++++++---------- src/ruby/spec/generic/rpc_server_spec.rb | 13 ------------- src/ruby/spec/server_spec.rb | 15 ++++----------- 7 files changed, 19 insertions(+), 51 deletions(-) diff --git a/src/ruby/bin/interop/interop_server.rb b/src/ruby/bin/interop/interop_server.rb index b3b7d0c5a3a..0819ba9bbcc 100755 --- a/src/ruby/bin/interop/interop_server.rb +++ b/src/ruby/bin/interop/interop_server.rb @@ -176,12 +176,11 @@ end def main opts = parse_options host = "0.0.0.0:#{opts['port']}" + s = GRPC::RpcServer.new if opts['secure'] - s = GRPC::RpcServer.new(creds: test_server_creds) - s.add_http2_port(host, true) + s.add_http2_port(host, test_server_creds) logger.info("... running securely on #{host}") else - s = GRPC::RpcServer.new s.add_http2_port(host) logger.info("... running insecurely on #{host}") end diff --git a/src/ruby/bin/math_server.rb b/src/ruby/bin/math_server.rb index 93277e39320..5cc76134893 100755 --- a/src/ruby/bin/math_server.rb +++ b/src/ruby/bin/math_server.rb @@ -173,12 +173,11 @@ def main end end.parse! + s = GRPC::RpcServer.new if options['secure'] - s = GRPC::RpcServer.new(creds: test_server_creds) - s.add_http2_port(options['host'], true) + s.add_http2_port(options['host'], test_server_creds) logger.info("... running securely on #{options['host']}") else - s = GRPC::RpcServer.new s.add_http2_port(options['host']) logger.info("... running insecurely on #{options['host']}") end diff --git a/src/ruby/bin/noproto_server.rb b/src/ruby/bin/noproto_server.rb index 435f8f4ebf4..9979cb7ebbd 100755 --- a/src/ruby/bin/noproto_server.rb +++ b/src/ruby/bin/noproto_server.rb @@ -95,12 +95,11 @@ def main end end.parse! + s = GRPC::RpcServer.new if options['secure'] - s = GRPC::RpcServer.new(creds: test_server_creds) - s.add_http2_port(options['host'], true) + s.add_http2_port(options['host'], test_server_creds) logger.info("... running securely on #{options['host']}") else - s = GRPC::RpcServer.new s.add_http2_port(options['host']) logger.info("... running insecurely on #{options['host']}") end diff --git a/src/ruby/lib/grpc/generic/rpc_server.rb b/src/ruby/lib/grpc/generic/rpc_server.rb index 6938f718922..35e84023be9 100644 --- a/src/ruby/lib/grpc/generic/rpc_server.rb +++ b/src/ruby/lib/grpc/generic/rpc_server.rb @@ -81,7 +81,6 @@ module GRPC max_waiting_requests:DEFAULT_MAX_WAITING_REQUESTS, poll_period:INFINITE_FUTURE, completion_queue_override:nil, - creds:nil, server_override:nil, **kw) if completion_queue_override.nil? @@ -95,13 +94,7 @@ module GRPC @cq = cq if server_override.nil? - if creds.nil? - srv = Core::Server.new(@cq, kw) - elsif !creds.is_a? Core::ServerCredentials - fail(ArgumentError, 'not a ServerCredentials') - else - srv = Core::Server.new(@cq, kw, creds) - end + srv = Core::Server.new(@cq, kw) else srv = server_override fail(ArgumentError, 'not a Server') unless srv.is_a? Core::Server diff --git a/src/ruby/spec/client_server_spec.rb b/src/ruby/spec/client_server_spec.rb index 030ff328f21..49a2d3bb4df 100644 --- a/src/ruby/spec/client_server_spec.rb +++ b/src/ruby/spec/client_server_spec.rb @@ -95,7 +95,7 @@ shared_context 'setup: tags' do end def new_client_call - @ch.create_call('/method', 'localhost', deadline) + @ch.create_call('/method', 'foo.test.google.fr', deadline) end end @@ -346,12 +346,12 @@ end describe 'the secure http client/server' do before(:example) do certs = load_test_certs - server_host = 'localhost:0' + server_host = '0.0.0.0:0' @client_queue = GRPC::Core::CompletionQueue.new @server_queue = GRPC::Core::CompletionQueue.new server_creds = GRPC::Core::ServerCredentials.new(nil, certs[1], certs[2]) - @server = GRPC::Core::Server.new(@server_queue, nil, server_creds) - server_port = @server.add_http2_port(server_host, true) + @server = GRPC::Core::Server.new(@server_queue, nil) + server_port = @server.add_http2_port(server_host, server_creds) @server.start args = { Channel::SSL_TARGET => 'foo.test.google.fr' } @ch = Channel.new("0.0.0.0:#{server_port}", args, @@ -362,11 +362,9 @@ describe 'the secure http client/server' do @server.close end - # TODO: uncomment after updating the to the new c api - # it_behaves_like 'basic GRPC message delivery is OK' do - # end + it_behaves_like 'basic GRPC message delivery is OK' do + end - # TODO: uncomment after updating the to the new c api - # it_behaves_like 'GRPC metadata delivery works OK' do - # end + it_behaves_like 'GRPC metadata delivery works OK' do + end end diff --git a/src/ruby/spec/generic/rpc_server_spec.rb b/src/ruby/spec/generic/rpc_server_spec.rb index e8c70604461..d5421d400c9 100644 --- a/src/ruby/spec/generic/rpc_server_spec.rb +++ b/src/ruby/spec/generic/rpc_server_spec.rb @@ -164,19 +164,6 @@ describe GRPC::RpcServer do expect(&blk).to raise_error end - it 'can be created with the creds as valid ServerCedentials' do - certs = load_test_certs - server_creds = GRPC::Core::ServerCredentials.new(nil, certs[1], certs[2]) - blk = proc do - opts = { - a_channel_arg: 'an_arg', - creds: server_creds - } - RpcServer.new(**opts) - end - expect(&blk).to_not raise_error - end - it 'can be created with a server override' do opts = { a_channel_arg: 'an_arg', server_override: @server } blk = proc do diff --git a/src/ruby/spec/server_spec.rb b/src/ruby/spec/server_spec.rb index 5b81f195371..a47e484f971 100644 --- a/src/ruby/spec/server_spec.rb +++ b/src/ruby/spec/server_spec.rb @@ -118,10 +118,11 @@ describe Server do end describe 'for secure servers' do + let(:cert) { create_test_cert } it 'runs without failing' do blk = proc do s = Server.new(@cq, nil) - s.add_http2_port('localhost:0', true) + s.add_http2_port('localhost:0', cert) s.close end expect(&blk).to_not raise_error @@ -130,7 +131,7 @@ describe Server do it 'fails if the server is closed' do s = Server.new(@cq, nil) s.close - blk = proc { s.add_http2_port('localhost:0', true) } + blk = proc { s.add_http2_port('localhost:0', cert) } expect(&blk).to raise_error(RuntimeError) end end @@ -138,7 +139,7 @@ describe Server do shared_examples '#new' do it 'takes a completion queue with nil channel args' do - expect { Server.new(@cq, nil, create_test_cert) }.to_not raise_error + expect { Server.new(@cq, nil) }.to_not raise_error end it 'does not take a hash with bad keys as channel args' do @@ -195,14 +196,6 @@ describe Server do it_behaves_like '#new' end - describe '#new with a secure channel' do - def construct_with_args(a) - proc { Server.new(@cq, a, create_test_cert) } - end - - it_behaves_like '#new' - end - def start_a_server s = Server.new(@cq, nil) s.add_http2_port('0.0.0.0:0') From 60fd3614807703218300a410bd437a5e950efbed Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 5 Mar 2015 16:24:22 -0800 Subject: [PATCH 084/120] Crash in channel/server creation if grpc_init not called --- src/core/surface/channel.c | 2 ++ src/core/surface/init.c | 10 ++++++++++ src/core/surface/init.h | 1 + src/core/surface/server.c | 4 ++++ 4 files changed, 17 insertions(+) diff --git a/src/core/surface/channel.c b/src/core/surface/channel.c index e38734c6a49..e764a3b9af0 100644 --- a/src/core/surface/channel.c +++ b/src/core/surface/channel.c @@ -39,6 +39,7 @@ #include "src/core/iomgr/iomgr.h" #include "src/core/surface/call.h" #include "src/core/surface/client.h" +#include "src/core/surface/init.h" #include #include @@ -63,6 +64,7 @@ grpc_channel *grpc_channel_create_from_filters( size_t size = sizeof(grpc_channel) + grpc_channel_stack_size(filters, num_filters); grpc_channel *channel = gpr_malloc(size); + GPR_ASSERT(grpc_is_initialized() && "call grpc_init()"); channel->is_client = is_client; /* decremented by grpc_channel_destroy, and grpc_client_channel_closed if is_client */ gpr_ref_init(&channel->refs, 1 + is_client); diff --git a/src/core/surface/init.c b/src/core/surface/init.c index 4db66fb66eb..1f5c8d1b5d9 100644 --- a/src/core/surface/init.c +++ b/src/core/surface/init.c @@ -73,3 +73,13 @@ void grpc_shutdown(void) { } gpr_mu_unlock(&g_init_mu); } + +int grpc_is_initialized(void) { + int r; + gpr_once_init(&g_init, do_init); + gpr_mu_lock(&g_init_mu); + r = g_initializations > 0; + gpr_mu_unlock(&g_init_mu); + return r; +} + diff --git a/src/core/surface/init.h b/src/core/surface/init.h index ab40bedf875..416874020d7 100644 --- a/src/core/surface/init.h +++ b/src/core/surface/init.h @@ -35,5 +35,6 @@ #define GRPC_INTERNAL_CORE_SURFACE_INIT_H void grpc_security_pre_init(void); +int grpc_is_initialized(void); #endif /* GRPC_INTERNAL_CORE_SURFACE_INIT_H */ diff --git a/src/core/surface/server.c b/src/core/surface/server.c index c99a1b4cc9c..424734c54ce 100644 --- a/src/core/surface/server.c +++ b/src/core/surface/server.c @@ -44,6 +44,7 @@ #include "src/core/surface/call.h" #include "src/core/surface/channel.h" #include "src/core/surface/completion_queue.h" +#include "src/core/surface/init.h" #include "src/core/transport/metadata.h" #include #include @@ -612,6 +613,9 @@ grpc_server *grpc_server_create_from_filters(grpc_completion_queue *cq, int census_enabled = grpc_channel_args_is_census_enabled(args); grpc_server *server = gpr_malloc(sizeof(grpc_server)); + + GPR_ASSERT(grpc_is_initialized() && "call grpc_init()"); + memset(server, 0, sizeof(grpc_server)); if (cq) addcq(server, cq); From 53f8fea5df167fadf01113cde643c99b2a212c66 Mon Sep 17 00:00:00 2001 From: Masood Malekghassemi Date: Thu, 5 Mar 2015 17:03:07 -0800 Subject: [PATCH 085/120] Move protoc output to temporary directory Moves the Python protoc plugin output directory to an auto-generated temporary directory. Has the build configuration set by environment variable (consistent with `tools/run-tests/run_tests.py`'s set envvars). --- test/compiler/python_plugin_test.py | 50 +++++++++++++++++------------ 1 file changed, 29 insertions(+), 21 deletions(-) diff --git a/test/compiler/python_plugin_test.py b/test/compiler/python_plugin_test.py index f16682862c3..9cf3c624c05 100644 --- a/test/compiler/python_plugin_test.py +++ b/test/compiler/python_plugin_test.py @@ -32,8 +32,10 @@ import contextlib import errno import itertools import os +import shutil import subprocess import sys +import tempfile import time import unittest @@ -55,8 +57,8 @@ DOES_NOT_MATTER_DELAY = 0 NO_DELAY = 0 LONG_DELAY = 1 -# Assigned in __main__. -_build_mode = None +# Build mode environment variable set by tools/run_tests/run_tests.py. +_build_mode = os.environ['CONFIG'] class _ServicerMethods(object): @@ -227,24 +229,26 @@ class PythonPluginTest(unittest.TestCase): protoc_command = 'protoc' # Ensure that the output directory exists. - outdir = '../../gens/test/compiler/python' - try: - os.makedirs(outdir) - except OSError as exception: - if exception.errno != errno.EEXIST: - raise + self.outdir = tempfile.mkdtemp() # Invoke protoc with the plugin. cmd = [ protoc_command, '--plugin=protoc-gen-python-grpc=%s' % protoc_plugin_filename, '-I %s' % os.path.dirname(test_proto_filename), - '--python_out=%s' % outdir, - '--python-grpc_out=%s' % outdir, + '--python_out=%s' % self.outdir, + '--python-grpc_out=%s' % self.outdir, os.path.basename(test_proto_filename), ] subprocess.call(' '.join(cmd), shell=True) - sys.path.append(outdir) + sys.path.append(self.outdir) + + def tearDown(self): + try: + shutil.rmtree(self.outdir) + except OSError as exc: + if exc.errno != errno.ENOENT: + raise # TODO(atash): Figure out which of theses tests is hanging flakily with small # probability. @@ -296,6 +300,8 @@ class PythonPluginTest(unittest.TestCase): with self.assertRaises(exceptions.ExpirationError): response_future.result() + @unittest.skip('TODO(atash,nathaniel): figure out why this flakily hangs ' + 'forever and fix.') def testUnaryCallAsyncCancelled(self): import test_pb2 # pylint: disable=g-import-not-at-top request = test_pb2.SimpleRequest(response_size=13) @@ -325,6 +331,8 @@ class PythonPluginTest(unittest.TestCase): expected_response, response = check self.assertEqual(expected_response, response) + @unittest.skip('TODO(atash,nathaniel): figure out why this flakily hangs ' + 'forever and fix.') def testStreamingOutputCallExpired(self): import test_pb2 # pylint: disable=g-import-not-at-top request = StreamingOutputRequest(test_pb2) @@ -335,6 +343,8 @@ class PythonPluginTest(unittest.TestCase): with self.assertRaises(exceptions.ExpirationError): list(responses) + @unittest.skip('TODO(atash,nathaniel): figure out why this flakily hangs ' + 'forever and fix.') def testStreamingOutputCallCancelled(self): import test_pb2 # pylint: disable=g-import-not-at-top request = StreamingOutputRequest(test_pb2) @@ -359,6 +369,8 @@ class PythonPluginTest(unittest.TestCase): with self.assertRaises(exceptions.ServicerError): next(responses) + @unittest.skip('TODO(atash,nathaniel): figure out why this flakily hangs ' + 'forever and fix.') def testStreamingInputCall(self): import test_pb2 # pylint: disable=g-import-not-at-top with _CreateService(test_pb2, NO_DELAY) as (servicer, stub, unused_server): @@ -426,6 +438,8 @@ class PythonPluginTest(unittest.TestCase): expected_response, response = check self.assertEqual(expected_response, response) + @unittest.skip('TODO(atash,nathaniel): figure out why this flakily hangs ' + 'forever and fix.') def testFullDuplexCallExpired(self): import test_pb2 # pylint: disable=g-import-not-at-top request = FullDuplexRequest(test_pb2) @@ -436,6 +450,8 @@ class PythonPluginTest(unittest.TestCase): with self.assertRaises(exceptions.ExpirationError): list(responses) + @unittest.skip('TODO(atash,nathaniel): figure out why this flakily hangs ' + 'forever and fix.') def testFullDuplexCallCancelled(self): import test_pb2 # pylint: disable=g-import-not-at-top with _CreateService(test_pb2, NO_DELAY) as (servicer, stub, unused_server): @@ -459,6 +475,8 @@ class PythonPluginTest(unittest.TestCase): with self.assertRaises(exceptions.ServicerError): next(responses) + @unittest.skip('TODO(atash,nathaniel): figure out why this flakily hangs ' + 'forever and fix.') def testHalfDuplexCall(self): import test_pb2 # pylint: disable=g-import-not-at-top with _CreateService(test_pb2, DOES_NOT_MATTER_DELAY) as ( @@ -502,14 +520,4 @@ class PythonPluginTest(unittest.TestCase): if __name__ == '__main__': os.chdir(os.path.dirname(sys.argv[0])) - parser = argparse.ArgumentParser( - description='Run Python compiler plugin test.') - parser.add_argument( - '--build_mode', dest='build_mode', type=str, default='dbg', - help='The build mode of the targets to test, e.g. "dbg", "opt", "asan", ' - 'etc.') - parser.add_argument('--port', dest='port', type=int, default=0) - args, remainder = parser.parse_known_args() - _build_mode = args.build_mode - sys.argv[1:] = remainder unittest.main() From 8ace0bc987696aa1d28ef60cc468bcf02a2e689e Mon Sep 17 00:00:00 2001 From: Craig Tiller Date: Thu, 5 Mar 2015 17:16:09 -0800 Subject: [PATCH 086/120] Rename to save confusion --- src/core/surface/init.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/surface/init.c b/src/core/surface/init.c index 1f5c8d1b5d9..e48c4202e58 100644 --- a/src/core/surface/init.c +++ b/src/core/surface/init.c @@ -40,17 +40,17 @@ #include "src/core/surface/surface_trace.h" #include "src/core/transport/chttp2_transport.h" -static gpr_once g_init = GPR_ONCE_INIT; +static gpr_once g_basic_init = GPR_ONCE_INIT; static gpr_mu g_init_mu; static int g_initializations; -static void do_init(void) { +static void do_basic_init(void) { gpr_mu_init(&g_init_mu); g_initializations = 0; } void grpc_init(void) { - gpr_once_init(&g_init, do_init); + gpr_once_init(&g_basic_init, do_basic_init); gpr_mu_lock(&g_init_mu); if (++g_initializations == 1) { @@ -76,7 +76,7 @@ void grpc_shutdown(void) { int grpc_is_initialized(void) { int r; - gpr_once_init(&g_init, do_init); + gpr_once_init(&g_basic_init, do_basic_init); gpr_mu_lock(&g_init_mu); r = g_initializations > 0; gpr_mu_unlock(&g_init_mu); From b2d4a8de95c160d42c6f1e3edf582d7321226dbb Mon Sep 17 00:00:00 2001 From: Masood Malekghassemi Date: Thu, 5 Mar 2015 17:04:18 -0800 Subject: [PATCH 087/120] Have Python protoc plugin test run with other tests --- tools/run_tests/python_tests.json | 64 +++++++++++++++++++++++-------- tools/run_tests/run_python.sh | 2 +- tools/run_tests/run_tests.py | 11 ++++-- 3 files changed, 57 insertions(+), 20 deletions(-) diff --git a/tools/run_tests/python_tests.json b/tools/run_tests/python_tests.json index 9e5b1365e6a..4b43ee8357c 100755 --- a/tools/run_tests/python_tests.json +++ b/tools/run_tests/python_tests.json @@ -1,18 +1,50 @@ [ - "grpc._adapter._blocking_invocation_inline_service_test", - "grpc._adapter._c_test", - "grpc._adapter._event_invocation_synchronous_event_service_test", - "grpc._adapter._future_invocation_asynchronous_event_service_test", - "grpc._adapter._links_test", - "grpc._adapter._lonely_rear_link_test", - "grpc._adapter._low_test", - "grpc.early_adopter.implementations_test", - "grpc.framework.assembly.implementations_test", - "grpc.framework.base.packets.implementations_test", - "grpc.framework.face.blocking_invocation_inline_service_test", - "grpc.framework.face.event_invocation_synchronous_event_service_test", - "grpc.framework.face.future_invocation_asynchronous_event_service_test", - "grpc.framework.foundation._later_test", - "grpc.framework.foundation._logging_pool_test" + { + "file": "test/compiler/python_plugin_test.py" + }, + { + "module": "grpc._adapter._blocking_invocation_inline_service_test" + }, + { + "module": "grpc._adapter._c_test" + }, + { + "module": "grpc._adapter._event_invocation_synchronous_event_service_test" + }, + { + "module": "grpc._adapter._future_invocation_asynchronous_event_service_test" + }, + { + "module": "grpc._adapter._links_test" + }, + { + "module": "grpc._adapter._lonely_rear_link_test" + }, + { + "module": "grpc._adapter._low_test" + }, + { + "module": "grpc.early_adopter.implementations_test" + }, + { + "module": "grpc.framework.assembly.implementations_test" + }, + { + "module": "grpc.framework.base.packets.implementations_test" + }, + { + "module": "grpc.framework.face.blocking_invocation_inline_service_test" + }, + { + "module": "grpc.framework.face.event_invocation_synchronous_event_service_test" + }, + { + "module": "grpc.framework.face.future_invocation_asynchronous_event_service_test" + }, + { + "module": "grpc.framework.foundation._later_test" + }, + { + "module": "grpc.framework.foundation._logging_pool_test" + } ] - diff --git a/tools/run_tests/run_python.sh b/tools/run_tests/run_python.sh index 403862b0a05..fa1497aee47 100755 --- a/tools/run_tests/run_python.sh +++ b/tools/run_tests/run_python.sh @@ -36,4 +36,4 @@ cd $(dirname $0)/../.. root=`pwd` export LD_LIBRARY_PATH=$root/libs/opt source python2.7_virtual_environment/bin/activate -python2.7 -B -m $* +python2.7 -B $* diff --git a/tools/run_tests/run_tests.py b/tools/run_tests/run_tests.py index 0f4544a5c6c..12a45f3ad9a 100755 --- a/tools/run_tests/run_tests.py +++ b/tools/run_tests/run_tests.py @@ -170,11 +170,16 @@ class PythonLanguage(object): self._tests = json.load(f) def test_specs(self, config, travis): - return [config.job_spec(['tools/run_tests/run_python.sh', test], None) - for test in self._tests] + modules = [config.job_spec(['tools/run_tests/run_python.sh', '-m', + test['module']], None) + for test in self._tests if 'module' in test] + files = [config.job_spec(['tools/run_tests/run_python.sh', + test['file']], None) + for test in self._tests if 'file' in test] + return files + modules def make_targets(self): - return ['static_c'] + return ['static_c', 'grpc_python_plugin'] def build_steps(self): return [['tools/run_tests/build_python.sh']] From a29d0f3fbcfbffb04cff4bf1e34429307b58ae09 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Wed, 4 Mar 2015 17:54:56 -0800 Subject: [PATCH 088/120] Split async call into server and client classes sharing the same base. --- src/csharp/Grpc.Core/Grpc.Core.csproj | 7 +- src/csharp/Grpc.Core/Internal/AsyncCall.cs | 577 ++++-------------- .../Grpc.Core/Internal/AsyncCallBase.cs | 407 ++++++++++++ .../Grpc.Core/Internal/AsyncCallServer.cs | 125 ++++ .../Grpc.Core/Internal/AsyncCompletion.cs | 95 +++ .../Grpc.Core/Internal/CallSafeHandle.cs | 1 - .../Internal/ClientStreamingInputObserver.cs | 9 +- .../Internal/ServerStreamingOutputObserver.cs | 16 +- .../Grpc.Core/OperationFailedException.cs | 48 ++ src/csharp/Grpc.Core/ServerCallHandler.cs | 34 +- src/csharp/Grpc.Core/Status.cs | 6 + src/csharp/Grpc.Core/Utils/Preconditions.cs | 113 ++++ 12 files changed, 949 insertions(+), 489 deletions(-) create mode 100644 src/csharp/Grpc.Core/Internal/AsyncCallBase.cs create mode 100644 src/csharp/Grpc.Core/Internal/AsyncCallServer.cs create mode 100644 src/csharp/Grpc.Core/Internal/AsyncCompletion.cs create mode 100644 src/csharp/Grpc.Core/OperationFailedException.cs create mode 100644 src/csharp/Grpc.Core/Utils/Preconditions.cs diff --git a/src/csharp/Grpc.Core/Grpc.Core.csproj b/src/csharp/Grpc.Core/Grpc.Core.csproj index 93d5430591b..78b6cdde59b 100644 --- a/src/csharp/Grpc.Core/Grpc.Core.csproj +++ b/src/csharp/Grpc.Core/Grpc.Core.csproj @@ -51,7 +51,6 @@ - @@ -69,6 +68,12 @@ + + + + + +