diff options
author | Mark D. Roth <roth@google.com> | 2017-11-27 10:17:44 -0800 |
---|---|---|
committer | Mark D. Roth <roth@google.com> | 2017-11-27 10:17:44 -0800 |
commit | 5491eb7c5b0c01418b6bb28e2e704b7854962708 (patch) | |
tree | 2cde234dd2cd96348a6f67a77365befb9c705cdc | |
parent | dc8be882f7489d38c9fe1ea61cf70a349b4a9357 (diff) | |
parent | de93112a3f70afa39d3e9aa87da165f9f737fdef (diff) |
Merge remote-tracking branch 'upstream/master' into server_connection_timeout
112 files changed, 3116 insertions, 823 deletions
@@ -480,6 +480,7 @@ grpc_cc_library( ], hdrs = [ "src/core/lib/profiling/timers.h", + "src/core/lib/support/abstract.h", "src/core/lib/support/arena.h", "src/core/lib/support/atomic.h", "src/core/lib/support/atomic_with_atm.h", diff --git a/CMakeLists.txt b/CMakeLists.txt index bae6bb29b4..387f29c133 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -430,6 +430,7 @@ add_dependencies(buildtests_c gpr_env_test) add_dependencies(buildtests_c gpr_histogram_test) add_dependencies(buildtests_c gpr_host_port_test) add_dependencies(buildtests_c gpr_log_test) +add_dependencies(buildtests_c gpr_manual_constructor_test) add_dependencies(buildtests_c gpr_mpscq_test) add_dependencies(buildtests_c gpr_spinlock_test) add_dependencies(buildtests_c gpr_stack_lockfree_test) @@ -6391,6 +6392,34 @@ target_link_libraries(gpr_log_test endif (gRPC_BUILD_TESTS) if (gRPC_BUILD_TESTS) +add_executable(gpr_manual_constructor_test + test/core/support/manual_constructor_test.cc +) + + +target_include_directories(gpr_manual_constructor_test + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/include + PRIVATE ${BORINGSSL_ROOT_DIR}/include + PRIVATE ${PROTOBUF_ROOT_DIR}/src + PRIVATE ${BENCHMARK_ROOT_DIR}/include + PRIVATE ${ZLIB_ROOT_DIR} + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/zlib + PRIVATE ${CARES_INCLUDE_DIR} + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/cares/cares + PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/third_party/gflags/include + PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/third_party/abseil-cpp +) + +target_link_libraries(gpr_manual_constructor_test + ${_gRPC_ALLTARGETS_LIBRARIES} + gpr_test_util + gpr +) + +endif (gRPC_BUILD_TESTS) +if (gRPC_BUILD_TESTS) + add_executable(gpr_mpscq_test test/core/support/mpscq_test.cc ) @@ -114,7 +114,7 @@ CC_msan = clang CXX_msan = clang++ LD_msan = clang++ LDXX_msan = clang++ -CPPFLAGS_msan = -O0 -fsanitize-coverage=edge -fsanitize=memory -fsanitize-memory-track-origins -fno-omit-frame-pointer -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_USE_OWN_TR1_TUPLE=1 -Wno-unused-command-line-argument -fPIE -pie -DGPR_NO_DIRECT_SYSCALLS +CPPFLAGS_msan = -O0 -fsanitize-coverage=edge -fsanitize=memory -fsanitize-memory-track-origins -fsanitize-memory-use-after-dtor -fno-omit-frame-pointer -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_USE_OWN_TR1_TUPLE=1 -Wno-unused-command-line-argument -fPIE -pie -DGPR_NO_DIRECT_SYSCALLS LDFLAGS_msan = -fsanitize=memory -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_USE_OWN_TR1_TUPLE=1 -fPIE -pie $(if $(JENKINS_BUILD),-Wl$(comma)-Ttext-segment=0x7e0000000000,) DEFINES_msan = NDEBUG @@ -328,6 +328,7 @@ ifeq ($(SYSTEM),Darwin) CXXFLAGS += -stdlib=libc++ endif CPPFLAGS += -g -Wall -Wextra -Werror -Wno-long-long -Wno-unused-parameter -DOSATOMIC_USE_INLINED=1 -Ithird_party/abseil-cpp +COREFLAGS += -fno-rtti -fno-exceptions LDFLAGS += -g CPPFLAGS += $(CPPFLAGS_$(CONFIG)) @@ -990,6 +991,7 @@ gpr_env_test: $(BINDIR)/$(CONFIG)/gpr_env_test gpr_histogram_test: $(BINDIR)/$(CONFIG)/gpr_histogram_test gpr_host_port_test: $(BINDIR)/$(CONFIG)/gpr_host_port_test gpr_log_test: $(BINDIR)/$(CONFIG)/gpr_log_test +gpr_manual_constructor_test: $(BINDIR)/$(CONFIG)/gpr_manual_constructor_test gpr_mpscq_test: $(BINDIR)/$(CONFIG)/gpr_mpscq_test gpr_spinlock_test: $(BINDIR)/$(CONFIG)/gpr_spinlock_test gpr_stack_lockfree_test: $(BINDIR)/$(CONFIG)/gpr_stack_lockfree_test @@ -1385,6 +1387,7 @@ buildtests_c: privatelibs_c \ $(BINDIR)/$(CONFIG)/gpr_histogram_test \ $(BINDIR)/$(CONFIG)/gpr_host_port_test \ $(BINDIR)/$(CONFIG)/gpr_log_test \ + $(BINDIR)/$(CONFIG)/gpr_manual_constructor_test \ $(BINDIR)/$(CONFIG)/gpr_mpscq_test \ $(BINDIR)/$(CONFIG)/gpr_spinlock_test \ $(BINDIR)/$(CONFIG)/gpr_stack_lockfree_test \ @@ -1834,6 +1837,8 @@ test_c: buildtests_c $(Q) $(BINDIR)/$(CONFIG)/gpr_host_port_test || ( echo test gpr_host_port_test failed ; exit 1 ) $(E) "[RUN] Testing gpr_log_test" $(Q) $(BINDIR)/$(CONFIG)/gpr_log_test || ( echo test gpr_log_test failed ; exit 1 ) + $(E) "[RUN] Testing gpr_manual_constructor_test" + $(Q) $(BINDIR)/$(CONFIG)/gpr_manual_constructor_test || ( echo test gpr_manual_constructor_test failed ; exit 1 ) $(E) "[RUN] Testing gpr_mpscq_test" $(Q) $(BINDIR)/$(CONFIG)/gpr_mpscq_test || ( echo test gpr_mpscq_test failed ; exit 1 ) $(E) "[RUN] Testing gpr_spinlock_test" @@ -2584,6 +2589,16 @@ $(OBJDIR)/$(CONFIG)/src/compiler/%.o : src/compiler/%.cc $(Q) mkdir -p `dirname $@` $(Q) $(HOST_CXX) $(HOST_CXXFLAGS) $(HOST_CPPFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $< +$(OBJDIR)/$(CONFIG)/src/core/%.o : src/core/%.cc + $(E) "[CXX] Compiling $<" + $(Q) mkdir -p `dirname $@` + $(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(COREFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $< + +$(OBJDIR)/$(CONFIG)/test/core/%.o : test/core/%.cc + $(E) "[CXX] Compiling $<" + $(Q) mkdir -p `dirname $@` + $(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(COREFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $< + $(OBJDIR)/$(CONFIG)/%.o : %.cc $(E) "[CXX] Compiling $<" $(Q) mkdir -p `dirname $@` @@ -10152,6 +10167,38 @@ endif endif +GPR_MANUAL_CONSTRUCTOR_TEST_SRC = \ + test/core/support/manual_constructor_test.cc \ + +GPR_MANUAL_CONSTRUCTOR_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(GPR_MANUAL_CONSTRUCTOR_TEST_SRC)))) +ifeq ($(NO_SECURE),true) + +# You can't build secure targets if you don't have OpenSSL. + +$(BINDIR)/$(CONFIG)/gpr_manual_constructor_test: openssl_dep_error + +else + + + +$(BINDIR)/$(CONFIG)/gpr_manual_constructor_test: $(GPR_MANUAL_CONSTRUCTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + $(E) "[LD] Linking $@" + $(Q) mkdir -p `dirname $@` + $(Q) $(LD) $(LDFLAGS) $(GPR_MANUAL_CONSTRUCTOR_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/gpr_manual_constructor_test + +endif + +$(OBJDIR)/$(CONFIG)/test/core/support/manual_constructor_test.o: $(LIBDIR)/$(CONFIG)/libgpr_test_util.a $(LIBDIR)/$(CONFIG)/libgpr.a + +deps_gpr_manual_constructor_test: $(GPR_MANUAL_CONSTRUCTOR_TEST_OBJS:.o=.dep) + +ifneq ($(NO_SECURE),true) +ifneq ($(NO_DEPS),true) +-include $(GPR_MANUAL_CONSTRUCTOR_TEST_OBJS:.o=.dep) +endif +endif + + GPR_MPSCQ_TEST_SRC = \ test/core/support/mpscq_test.cc \ @@ -10,7 +10,7 @@ bind( bind( name = "zlib", - actual = "@submodule_zlib//:z", + actual = "@com_github_madler_zlib//:z", ) bind( @@ -35,22 +35,22 @@ bind( bind( name = "cares", - actual = "@submodule_cares//:ares", + actual = "@com_github_cares_cares//:ares", ) bind( name = "gtest", - actual = "@submodule_gtest//:gtest", + actual = "@com_github_google_googletest//:gtest", ) bind( name = "gmock", - actual = "@submodule_gtest//:gmock", + actual = "@com_github_google_googletest//:gmock", ) bind( name = "benchmark", - actual = "@submodule_benchmark//:benchmark", + actual = "@com_github_google_benchmark//:benchmark", ) bind( @@ -58,47 +58,60 @@ bind( actual = "@com_github_gflags_gflags//:gflags", ) -local_repository( +http_archive( name = "boringssl", - path = "third_party/boringssl-with-bazel", + # on the master-with-bazel branch + url = "https://boringssl.googlesource.com/boringssl/+archive/886e7d75368e3f4fab3f4d0d3584e4abfc557755.tar.gz", ) -new_local_repository( - name = "submodule_zlib", +new_http_archive( + name = "com_github_madler_zlib", build_file = "third_party/zlib.BUILD", - path = "third_party/zlib", + strip_prefix = "zlib-cacf7f1d4e3d44d871b605da3b647f07d718623f", + url = "https://github.com/madler/zlib/archive/cacf7f1d4e3d44d871b605da3b647f07d718623f.tar.gz", ) -new_local_repository( +http_archive( name = "com_google_protobuf", - build_file = "third_party/protobuf/BUILD", - path = "third_party/protobuf", + strip_prefix = "protobuf-2761122b810fe8861004ae785cc3ab39f384d342", + url = "https://github.com/google/protobuf/archive/2761122b810fe8861004ae785cc3ab39f384d342.tar.gz", ) -new_local_repository( - name = "submodule_gtest", +new_http_archive( + name = "com_github_google_googletest", build_file = "third_party/gtest.BUILD", - path = "third_party/googletest", + strip_prefix = "googletest-ec44c6c1675c25b9827aacd08c02433cccde7780", + url = "https://github.com/google/googletest/archive/ec44c6c1675c25b9827aacd08c02433cccde7780.tar.gz", ) -local_repository( +http_archive( name = "com_github_gflags_gflags", - path = "third_party/gflags", + strip_prefix = "gflags-30dbc81fb5ffdc98ea9b14b1918bfe4e8779b26e", + url = "https://github.com/gflags/gflags/archive/30dbc81fb5ffdc98ea9b14b1918bfe4e8779b26e.tar.gz", ) -new_local_repository( - name = "submodule_benchmark", - path = "third_party/benchmark", +new_http_archive( + name = "com_github_google_benchmark", build_file = "third_party/benchmark.BUILD", + strip_prefix = "benchmark-5b7683f49e1e9223cf9927b24f6fd3d6bd82e3f8", + url = "https://github.com/google/benchmark/archive/5b7683f49e1e9223cf9927b24f6fd3d6bd82e3f8.tar.gz", ) new_local_repository( - name = "submodule_cares", + name = "cares_local_files", + build_file = "third_party/cares/cares_local_files.BUILD", path = "third_party/cares", +) + +new_http_archive( + name = "com_github_cares_cares", build_file = "third_party/cares/cares.BUILD", + strip_prefix = "c-ares-3be1924221e1326df520f8498d704a5c4c8d0cce", + url = "https://github.com/c-ares/c-ares/archive/3be1924221e1326df520f8498d704a5c4c8d0cce.tar.gz", ) -local_repository( +http_archive( name = "com_google_absl", - path = "third_party/abseil-cpp", + strip_prefix = "abseil-cpp-cc4bed2d74f7c8717e31f9579214ab52a9c9c610", + url = "https://github.com/abseil/abseil-cpp/archive/cc4bed2d74f7c8717e31f9579214ab52a9c9c610.tar.gz", ) diff --git a/build.yaml b/build.yaml index 4437aec860..b440411d76 100644 --- a/build.yaml +++ b/build.yaml @@ -104,6 +104,7 @@ filegroups: - include/grpc/support/useful.h headers: - src/core/lib/profiling/timers.h + - src/core/lib/support/abstract.h - src/core/lib/support/arena.h - src/core/lib/support/atomic.h - src/core/lib/support/atomic_with_atm.h @@ -2215,6 +2216,16 @@ targets: - gpr_test_util - gpr uses_polling: false +- name: gpr_manual_constructor_test + cpu_cost: 3 + build: test + language: c + src: + - test/core/support/manual_constructor_test.cc + deps: + - gpr_test_util + - gpr + uses_polling: false - name: gpr_mpscq_test cpu_cost: 30 build: test @@ -4916,8 +4927,8 @@ configs: msan: CC: clang CPPFLAGS: -O0 -fsanitize-coverage=edge -fsanitize=memory -fsanitize-memory-track-origins - -fno-omit-frame-pointer -DGTEST_HAS_TR1_TUPLE=0 -DGTEST_USE_OWN_TR1_TUPLE=1 - -Wno-unused-command-line-argument -fPIE -pie -DGPR_NO_DIRECT_SYSCALLS + -fsanitize-memory-use-after-dtor -fno-omit-frame-pointer -DGTEST_HAS_TR1_TUPLE=0 + -DGTEST_USE_OWN_TR1_TUPLE=1 -Wno-unused-command-line-argument -fPIE -pie -DGPR_NO_DIRECT_SYSCALLS CXX: clang++ DEFINES: NDEBUG LD: clang++ @@ -4925,6 +4936,8 @@ configs: -fPIE -pie $(if $(JENKINS_BUILD),-Wl$(comma)-Ttext-segment=0x7e0000000000,) LDXX: clang++ compile_the_world: true + test_environ: + MSAN_OPTIONS: poison_in_dtor=1 mutrace: CPPFLAGS: -O3 -fno-omit-frame-pointer DEFINES: NDEBUG @@ -4977,6 +4990,7 @@ defaults: CPPFLAGS: -Ithird_party/boringssl/include -fvisibility=hidden -DOPENSSL_NO_ASM -D_GNU_SOURCE -DWIN32_LEAN_AND_MEAN -D_HAS_EXCEPTIONS=0 -DNOMINMAX global: + COREFLAGS: -fno-rtti -fno-exceptions CPPFLAGS: -g -Wall -Wextra -Werror -Wno-long-long -Wno-unused-parameter -DOSATOMIC_USE_INLINED=1 -Ithird_party/abseil-cpp LDFLAGS: -g diff --git a/examples/python/route_guide/route_guide_client.py b/examples/python/route_guide/route_guide_client.py index 653f0d02c6..a0e32fb6f5 100644 --- a/examples/python/route_guide/route_guide_client.py +++ b/examples/python/route_guide/route_guide_client.py @@ -17,7 +17,6 @@ from __future__ import print_function import random -import time import grpc @@ -66,7 +65,6 @@ def generate_route(feature_list): random_feature = feature_list[random.randint(0, len(feature_list) - 1)] print("Visiting point %s" % random_feature.location) yield random_feature.location - time.sleep(random.uniform(0.5, 1.5)) def guide_record_route(stub): @@ -91,7 +89,6 @@ def generate_messages(): for msg in messages: print("Sending %s at %s" % (msg.message, msg.location)) yield msg - time.sleep(random.uniform(0.5, 1.0)) def guide_route_chat(stub): diff --git a/gRPC-Core.podspec b/gRPC-Core.podspec index 02c6a64515..2f97565f1b 100644 --- a/gRPC-Core.podspec +++ b/gRPC-Core.podspec @@ -187,6 +187,7 @@ Pod::Spec.new do |s| # To save you from scrolling, this is the last part of the podspec. ss.source_files = 'src/core/lib/profiling/timers.h', + 'src/core/lib/support/abstract.h', 'src/core/lib/support/arena.h', 'src/core/lib/support/atomic.h', 'src/core/lib/support/atomic_with_atm.h', @@ -706,6 +707,7 @@ Pod::Spec.new do |s| 'src/core/plugin_registry/grpc_plugin_registry.cc' ss.private_header_files = 'src/core/lib/profiling/timers.h', + 'src/core/lib/support/abstract.h', 'src/core/lib/support/arena.h', 'src/core/lib/support/atomic.h', 'src/core/lib/support/atomic_with_atm.h', diff --git a/grpc.gemspec b/grpc.gemspec index d674c09005..0dd7ceb350 100644 --- a/grpc.gemspec +++ b/grpc.gemspec @@ -84,6 +84,7 @@ Gem::Specification.new do |s| s.files += %w( include/grpc/impl/codegen/sync_posix.h ) s.files += %w( include/grpc/impl/codegen/sync_windows.h ) s.files += %w( src/core/lib/profiling/timers.h ) + s.files += %w( src/core/lib/support/abstract.h ) s.files += %w( src/core/lib/support/arena.h ) s.files += %w( src/core/lib/support/atomic.h ) s.files += %w( src/core/lib/support/atomic_with_atm.h ) diff --git a/include/grpc++/impl/codegen/call.h b/include/grpc++/impl/codegen/call.h index 1a988297dc..41e95866cf 100644 --- a/include/grpc++/impl/codegen/call.h +++ b/include/grpc++/impl/codegen/call.h @@ -579,6 +579,7 @@ class CallOpClientRecvStatus { op->data.recv_status_on_client.trailing_metadata = metadata_map_->arr(); op->data.recv_status_on_client.status = &status_code_; op->data.recv_status_on_client.status_details = &error_message_; + op->data.recv_status_on_client.error_string = nullptr; op->flags = 0; op->reserved = NULL; } diff --git a/include/grpc/impl/codegen/grpc_types.h b/include/grpc/impl/codegen/grpc_types.h index 5cd04b3d03..73669d9e84 100644 --- a/include/grpc/impl/codegen/grpc_types.h +++ b/include/grpc/impl/codegen/grpc_types.h @@ -561,6 +561,10 @@ typedef struct grpc_op { grpc_metadata_array* trailing_metadata; grpc_status_code* status; grpc_slice* status_details; + /** If this is not nullptr, it will be populated with the full fidelity + * error string for debugging purposes. The application is responsible + * for freeing the data. */ + const char** error_string; } recv_status_on_client; struct grpc_op_recv_close_on_server { /** out argument, set to 1 if the call failed in any way (seen as a diff --git a/package.xml b/package.xml index 3356c271d8..59d49dd165 100644 --- a/package.xml +++ b/package.xml @@ -96,6 +96,7 @@ <file baseinstalldir="/" name="include/grpc/impl/codegen/sync_posix.h" role="src" /> <file baseinstalldir="/" name="include/grpc/impl/codegen/sync_windows.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/profiling/timers.h" role="src" /> + <file baseinstalldir="/" name="src/core/lib/support/abstract.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/support/arena.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/support/atomic.h" role="src" /> <file baseinstalldir="/" name="src/core/lib/support/atomic_with_atm.h" role="src" /> diff --git a/src/compiler/cpp_generator.cc b/src/compiler/cpp_generator.cc index 3adf0fa451..dec8cd0f25 100644 --- a/src/compiler/cpp_generator.cc +++ b/src/compiler/cpp_generator.cc @@ -104,7 +104,7 @@ grpc::string GetHeaderPrologue(grpc_generator::File* file, grpc::string leading_comments = file->GetLeadingComments("//"); if (!leading_comments.empty()) { printer->Print(vars, "// Original file comments:\n"); - printer->Print(leading_comments.c_str()); + printer->PrintRaw(leading_comments.c_str()); } printer->Print(vars, "#ifndef GRPC_$filename_identifier$__INCLUDED\n"); printer->Print(vars, "#define GRPC_$filename_identifier$__INCLUDED\n"); diff --git a/src/compiler/csharp_generator.cc b/src/compiler/csharp_generator.cc index e0957bf9bb..40fe0b054a 100644 --- a/src/compiler/csharp_generator.cc +++ b/src/compiler/csharp_generator.cc @@ -666,7 +666,7 @@ grpc::string GetServices(const FileDescriptor* file, bool generate_client, grpc::string leading_comments = GetCsharpComments(file, true); if (!leading_comments.empty()) { out.Print("// Original file comments:\n"); - out.Print(leading_comments.c_str()); + out.PrintRaw(leading_comments.c_str()); } out.Print("#pragma warning disable 1591\n"); diff --git a/src/compiler/node_generator.cc b/src/compiler/node_generator.cc index ed835b4445..661587cbd6 100644 --- a/src/compiler/node_generator.cc +++ b/src/compiler/node_generator.cc @@ -250,7 +250,7 @@ grpc::string GenerateFile(const FileDescriptor* file) { grpc::string leading_comments = GetNodeComments(file, true); if (!leading_comments.empty()) { out.Print("// Original file comments:\n"); - out.Print(leading_comments.c_str()); + out.PrintRaw(leading_comments.c_str()); } out.Print("'use strict';\n"); diff --git a/src/compiler/objective_c_generator.cc b/src/compiler/objective_c_generator.cc index 349f1dc281..8fe30e97e9 100644 --- a/src/compiler/objective_c_generator.cc +++ b/src/compiler/objective_c_generator.cc @@ -65,7 +65,7 @@ static void PrintAllComments(const DescriptorType* desc, Printer* printer) { printer->Print(" * "); size_t start_pos = it->find_first_not_of(' '); if (start_pos != grpc::string::npos) { - printer->Print(it->c_str() + start_pos); + printer->PrintRaw(it->c_str() + start_pos); } printer->Print("\n"); } diff --git a/src/compiler/php_generator.cc b/src/compiler/php_generator.cc index 1ff9520d7f..d9705e8077 100644 --- a/src/compiler/php_generator.cc +++ b/src/compiler/php_generator.cc @@ -164,7 +164,7 @@ grpc::string GenerateFile(const FileDescriptor* file, grpc::string leading_comments = GetPHPComments(file, "//"); if (!leading_comments.empty()) { out.Print("// Original file comments:\n"); - out.Print(leading_comments.c_str()); + out.PrintRaw(leading_comments.c_str()); } map<grpc::string, grpc::string> vars; diff --git a/src/compiler/protobuf_plugin.h b/src/compiler/protobuf_plugin.h index 1551908156..b971af1310 100644 --- a/src/compiler/protobuf_plugin.h +++ b/src/compiler/protobuf_plugin.h @@ -141,6 +141,7 @@ class ProtoBufPrinter : public grpc_generator::Printer { } void Print(const char* string) { printer_.Print(string); } + void PrintRaw(const char* string) { printer_.PrintRaw(string); } void Indent() { printer_.Indent(); } void Outdent() { printer_.Outdent(); } diff --git a/src/compiler/python_generator.cc b/src/compiler/python_generator.cc index c1ae7d31ad..8a0b889454 100644 --- a/src/compiler/python_generator.cc +++ b/src/compiler/python_generator.cc @@ -101,7 +101,7 @@ void PrivateGenerator::PrintAllComments(StringVector comments, ++it) { size_t start_pos = it->find_first_not_of(' '); if (start_pos != grpc::string::npos) { - out->Print(it->c_str() + start_pos); + out->PrintRaw(it->c_str() + start_pos); } out->Print("\n"); } diff --git a/src/compiler/ruby_generator.cc b/src/compiler/ruby_generator.cc index ed7e074b47..e81dea603b 100644 --- a/src/compiler/ruby_generator.cc +++ b/src/compiler/ruby_generator.cc @@ -174,7 +174,7 @@ grpc::string GetServices(const FileDescriptor* file) { grpc::string leading_comments = GetRubyComments(file, true); if (!leading_comments.empty()) { out.Print("# Original file comments:\n"); - out.Print(leading_comments.c_str()); + out.PrintRaw(leading_comments.c_str()); } out.Print("\n"); diff --git a/src/compiler/schema_interface.h b/src/compiler/schema_interface.h index b2021f2926..c000478e68 100644 --- a/src/compiler/schema_interface.h +++ b/src/compiler/schema_interface.h @@ -86,6 +86,7 @@ struct Printer { virtual void Print(const std::map<grpc::string, grpc::string>& vars, const char* template_string) = 0; virtual void Print(const char* string) = 0; + virtual void PrintRaw(const char* string) = 0; virtual void Indent() = 0; virtual void Outdent() = 0; }; diff --git a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc index 635034db61..607fbf306a 100644 --- a/src/core/ext/transport/chttp2/transport/chttp2_transport.cc +++ b/src/core/ext/transport/chttp2/transport/chttp2_transport.cc @@ -1758,7 +1758,7 @@ static void send_goaway(grpc_exec_ctx* exec_ctx, grpc_chttp2_transport* t, grpc_http2_error_code http_error; grpc_slice slice; grpc_error_get_status(exec_ctx, error, GRPC_MILLIS_INF_FUTURE, nullptr, - &slice, &http_error); + &slice, &http_error, nullptr); grpc_chttp2_goaway_append(t->last_new_stream_id, (uint32_t)http_error, grpc_slice_ref_internal(slice), &t->qbuf); grpc_chttp2_initiate_write(exec_ctx, t, @@ -2065,7 +2065,7 @@ void grpc_chttp2_cancel_stream(grpc_exec_ctx* exec_ctx, if (s->id != 0) { grpc_http2_error_code http_error; grpc_error_get_status(exec_ctx, due_to_error, s->deadline, nullptr, - nullptr, &http_error); + nullptr, &http_error, nullptr); grpc_slice_buffer_add( &t->qbuf, grpc_chttp2_rst_stream_create(s->id, (uint32_t)http_error, &s->stats.outgoing)); @@ -2083,7 +2083,8 @@ void grpc_chttp2_fake_status(grpc_exec_ctx* exec_ctx, grpc_chttp2_transport* t, grpc_chttp2_stream* s, grpc_error* error) { grpc_status_code status; grpc_slice slice; - grpc_error_get_status(exec_ctx, error, s->deadline, &status, &slice, nullptr); + grpc_error_get_status(exec_ctx, error, s->deadline, &status, &slice, nullptr, + nullptr); if (status != GRPC_STATUS_OK) { s->seen_error = true; } @@ -2248,7 +2249,7 @@ static void close_from_api(grpc_exec_ctx* exec_ctx, grpc_chttp2_transport* t, grpc_status_code grpc_status; grpc_slice slice; grpc_error_get_status(exec_ctx, error, s->deadline, &grpc_status, &slice, - nullptr); + nullptr, nullptr); GPR_ASSERT(grpc_status >= 0 && (int)grpc_status < 100); diff --git a/src/core/ext/transport/chttp2/transport/flow_control.h b/src/core/ext/transport/chttp2/transport/flow_control.h index bb710fef83..2515c94309 100644 --- a/src/core/ext/transport/chttp2/transport/flow_control.h +++ b/src/core/ext/transport/chttp2/transport/flow_control.h @@ -19,6 +19,7 @@ #ifndef GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FLOW_CONTROL_H #define GRPC_CORE_EXT_TRANSPORT_CHTTP2_TRANSPORT_FLOW_CONTROL_H +#include <grpc/support/port_platform.h> #include <stdint.h> #include <grpc/support/useful.h> diff --git a/src/core/lib/channel/channel_stack.h b/src/core/lib/channel/channel_stack.h index 6b41ad105a..830c1123d0 100644 --- a/src/core/lib/channel/channel_stack.h +++ b/src/core/lib/channel/channel_stack.h @@ -84,6 +84,7 @@ typedef struct { typedef struct { grpc_call_stats stats; grpc_status_code final_status; + const char** error_string; } grpc_call_final_info; /* Channel filters specify: diff --git a/src/core/lib/iomgr/ev_epoll1_linux.cc b/src/core/lib/iomgr/ev_epoll1_linux.cc index 60446f7dd5..0dda1d924c 100644 --- a/src/core/lib/iomgr/ev_epoll1_linux.cc +++ b/src/core/lib/iomgr/ev_epoll1_linux.cc @@ -263,11 +263,13 @@ static grpc_fd* fd_create(int fd, const char* name) { if (new_fd == nullptr) { new_fd = (grpc_fd*)gpr_malloc(sizeof(grpc_fd)); + new_fd->read_closure.Init(); + new_fd->write_closure.Init(); } new_fd->fd = fd; - new_fd->read_closure.Init(); - new_fd->write_closure.Init(); + new_fd->read_closure->InitEvent(); + new_fd->write_closure->InitEvent(); gpr_atm_no_barrier_store(&new_fd->read_notifier_pollset, (gpr_atm)NULL); new_fd->freelist_next = nullptr; @@ -336,8 +338,8 @@ static void fd_orphan(grpc_exec_ctx* exec_ctx, grpc_fd* fd, GRPC_CLOSURE_SCHED(exec_ctx, on_done, GRPC_ERROR_REF(error)); grpc_iomgr_unregister_object(&fd->iomgr_object); - fd->read_closure.Destroy(); - fd->write_closure.Destroy(); + fd->read_closure->DestroyEvent(); + fd->write_closure->DestroyEvent(); gpr_mu_lock(&fd_freelist_mu); fd->freelist_next = fd_freelist; diff --git a/src/core/lib/iomgr/ev_epollex_linux.cc b/src/core/lib/iomgr/ev_epollex_linux.cc index 10b84401fa..62643df697 100644 --- a/src/core/lib/iomgr/ev_epollex_linux.cc +++ b/src/core/lib/iomgr/ev_epollex_linux.cc @@ -286,8 +286,8 @@ static void fd_destroy(grpc_exec_ctx* exec_ctx, void* arg, grpc_error* error) { fd->freelist_next = fd_freelist; fd_freelist = fd; - fd->read_closure.Destroy(); - fd->write_closure.Destroy(); + fd->read_closure->DestroyEvent(); + fd->write_closure->DestroyEvent(); gpr_mu_unlock(&fd_freelist_mu); } @@ -340,6 +340,8 @@ static grpc_fd* fd_create(int fd, const char* name) { if (new_fd == nullptr) { new_fd = (grpc_fd*)gpr_malloc(sizeof(grpc_fd)); + new_fd->read_closure.Init(); + new_fd->write_closure.Init(); } gpr_mu_init(&new_fd->pollable_mu); @@ -347,8 +349,8 @@ static grpc_fd* fd_create(int fd, const char* name) { new_fd->pollable_obj = nullptr; gpr_atm_rel_store(&new_fd->refst, (gpr_atm)1); new_fd->fd = fd; - new_fd->read_closure.Init(); - new_fd->write_closure.Init(); + new_fd->read_closure->InitEvent(); + new_fd->write_closure->InitEvent(); gpr_atm_no_barrier_store(&new_fd->read_notifier_pollset, (gpr_atm)NULL); new_fd->freelist_next = nullptr; diff --git a/src/core/lib/iomgr/ev_epollsig_linux.cc b/src/core/lib/iomgr/ev_epollsig_linux.cc index 689c0d4573..12c8483b8e 100644 --- a/src/core/lib/iomgr/ev_epollsig_linux.cc +++ b/src/core/lib/iomgr/ev_epollsig_linux.cc @@ -767,8 +767,8 @@ static void unref_by(grpc_fd* fd, int n) { fd_freelist = fd; grpc_iomgr_unregister_object(&fd->iomgr_object); - fd->read_closure.Destroy(); - fd->write_closure.Destroy(); + fd->read_closure->DestroyEvent(); + fd->write_closure->DestroyEvent(); gpr_mu_unlock(&fd_freelist_mu); } else { @@ -819,6 +819,8 @@ static grpc_fd* fd_create(int fd, const char* name) { if (new_fd == nullptr) { new_fd = (grpc_fd*)gpr_malloc(sizeof(grpc_fd)); gpr_mu_init(&new_fd->po.mu); + new_fd->read_closure.Init(); + new_fd->write_closure.Init(); } /* Note: It is not really needed to get the new_fd->po.mu lock here. If this @@ -833,8 +835,8 @@ static grpc_fd* fd_create(int fd, const char* name) { gpr_atm_rel_store(&new_fd->refst, (gpr_atm)1); new_fd->fd = fd; new_fd->orphaned = false; - new_fd->read_closure.Init(); - new_fd->write_closure.Init(); + new_fd->read_closure->InitEvent(); + new_fd->write_closure->InitEvent(); gpr_atm_no_barrier_store(&new_fd->read_notifier_pollset, (gpr_atm)NULL); new_fd->freelist_next = nullptr; diff --git a/src/core/lib/iomgr/lockfree_event.cc b/src/core/lib/iomgr/lockfree_event.cc index d477f64ba5..f0e798e8d8 100644 --- a/src/core/lib/iomgr/lockfree_event.cc +++ b/src/core/lib/iomgr/lockfree_event.cc @@ -57,7 +57,9 @@ extern grpc_core::TraceFlag grpc_polling_trace; namespace grpc_core { -LockfreeEvent::LockfreeEvent() { +LockfreeEvent::LockfreeEvent() { InitEvent(); } + +void LockfreeEvent::InitEvent() { /* Perform an atomic store to start the state machine. Note carefully that LockfreeEvent *MAY* be used whilst in a destroyed @@ -67,7 +69,7 @@ LockfreeEvent::LockfreeEvent() { gpr_atm_no_barrier_store(&state_, kClosureNotReady); } -LockfreeEvent::~LockfreeEvent() { +void LockfreeEvent::DestroyEvent() { gpr_atm curr; do { curr = gpr_atm_no_barrier_load(&state_); diff --git a/src/core/lib/iomgr/lockfree_event.h b/src/core/lib/iomgr/lockfree_event.h index c667dcd3bc..aec67a3399 100644 --- a/src/core/lib/iomgr/lockfree_event.h +++ b/src/core/lib/iomgr/lockfree_event.h @@ -30,11 +30,16 @@ namespace grpc_core { class LockfreeEvent { public: LockfreeEvent(); - ~LockfreeEvent(); LockfreeEvent(const LockfreeEvent&) = delete; LockfreeEvent& operator=(const LockfreeEvent&) = delete; + // These methods are used to initialize and destroy the internal state. These + // cannot be done in constructor and destructor because SetReady may be called + // when the event is destroyed and put in a freelist. + void InitEvent(); + void DestroyEvent(); + bool IsShutdown() const { return (gpr_atm_no_barrier_load(&state_) & kShutdownBit) != 0; } diff --git a/src/core/lib/iomgr/sockaddr_utils.cc b/src/core/lib/iomgr/sockaddr_utils.cc index 3477fb52cd..0c0a2fe5b2 100644 --- a/src/core/lib/iomgr/sockaddr_utils.cc +++ b/src/core/lib/iomgr/sockaddr_utils.cc @@ -148,7 +148,7 @@ int grpc_sockaddr_to_string(char** out, grpc_resolved_address addr_normalized; char ntop_buf[INET6_ADDRSTRLEN]; const void* ip = nullptr; - int port; + int port = 0; uint32_t sin6_scope_id = 0; int ret; diff --git a/src/core/lib/support/abstract.h b/src/core/lib/support/abstract.h new file mode 100644 index 0000000000..5498769a7d --- /dev/null +++ b/src/core/lib/support/abstract.h @@ -0,0 +1,29 @@ +/* + * + * Copyright 2017 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef GRPC_CORE_LIB_SUPPORT_ABSTRACT_H +#define GRPC_CORE_LIB_SUPPORT_ABSTRACT_H + +// This is needed to support abstract base classes in the c core. Since gRPC +// doesn't have a c++ runtime, it will hit a linker error on delete unless +// we define a virtual operator delete. See this blog for more info: +// https://eli.thegreenplace.net/2015/c-deleting-destructors-and-virtual-operator-delete/ +#define GRPC_ABSTRACT_BASE_CLASS \ + static void operator delete(void* p) { abort(); } + +#endif /* GRPC_CORE_LIB_SUPPORT_ABSTRACT_H */ diff --git a/src/core/lib/support/manual_constructor.h b/src/core/lib/support/manual_constructor.h index d753cf98a0..fda7653dbc 100644 --- a/src/core/lib/support/manual_constructor.h +++ b/src/core/lib/support/manual_constructor.h @@ -22,12 +22,147 @@ // manually construct a region of memory with some type #include <stddef.h> +#include <stdlib.h> #include <new> #include <type_traits> #include <utility> +#include <grpc/support/log.h> + namespace grpc_core { +// this contains templated helpers needed to implement the ManualConstructors +// in this file. +namespace manual_ctor_impl { + +// is_one_of returns true it a class, Member, is present in a variadic list of +// classes, List. +template <class Member, class... List> +class is_one_of; + +template <class Member, class... List> +class is_one_of<Member, Member, List...> { + public: + static constexpr const bool value = true; +}; + +template <class Member, class A, class... List> +class is_one_of<Member, A, List...> { + public: + static constexpr const bool value = is_one_of<Member, List...>::value; +}; + +template <class Member> +class is_one_of<Member> { + public: + static constexpr const bool value = false; +}; + +// max_size_of returns sizeof(Type) for the largest type in the variadic list +// of classes, Types. +template <class... Types> +class max_size_of; + +template <class A> +class max_size_of<A> { + public: + static constexpr const size_t value = sizeof(A); +}; + +template <class A, class... B> +class max_size_of<A, B...> { + public: + static constexpr const size_t value = sizeof(A) > max_size_of<B...>::value + ? sizeof(A) + : max_size_of<B...>::value; +}; + +// max_size_of returns alignof(Type) for the largest type in the variadic list +// of classes, Types. +template <class... Types> +class max_align_of; + +template <class A> +class max_align_of<A> { + public: + static constexpr const size_t value = alignof(A); +}; + +template <class A, class... B> +class max_align_of<A, B...> { + public: + static constexpr const size_t value = alignof(A) > max_align_of<B...>::value + ? alignof(A) + : max_align_of<B...>::value; +}; + +} // namespace manual_ctor_impl + +template <class BaseType, class... DerivedTypes> +class PolymorphicManualConstructor { + public: + // No constructor or destructor because one of the most useful uses of + // this class is as part of a union, and members of a union could not have + // constructors or destructors till C++11. And, anyway, the whole point of + // this class is to bypass constructor and destructor. + + BaseType* get() { return reinterpret_cast<BaseType*>(&space_); } + const BaseType* get() const { + return reinterpret_cast<const BaseType*>(&space_); + } + + BaseType* operator->() { return get(); } + const BaseType* operator->() const { return get(); } + + BaseType& operator*() { return *get(); } + const BaseType& operator*() const { return *get(); } + + template <class DerivedType> + void Init() { + FinishInit(new (&space_) DerivedType); + } + + // Init() constructs the Type instance using the given arguments + // (which are forwarded to Type's constructor). + // + // Note that Init() with no arguments performs default-initialization, + // not zero-initialization (i.e it behaves the same as "new Type;", not + // "new Type();"), so it will leave non-class types uninitialized. + template <class DerivedType, typename... Ts> + void Init(Ts&&... args) { + FinishInit(new (&space_) DerivedType(std::forward<Ts>(args)...)); + } + + // Init() that is equivalent to copy and move construction. + // Enables usage like this: + // ManualConstructor<std::vector<int>> v; + // v.Init({1, 2, 3}); + template <class DerivedType> + void Init(const DerivedType& x) { + FinishInit(new (&space_) DerivedType(x)); + } + template <class DerivedType> + void Init(DerivedType&& x) { + FinishInit(new (&space_) DerivedType(std::move(x))); + } + + void Destroy() { get()->~BaseType(); } + + private: + template <class DerivedType> + void FinishInit(DerivedType* p) { + static_assert( + manual_ctor_impl::is_one_of<DerivedType, DerivedTypes...>::value, + "DerivedType must be one of the predeclared DerivedTypes"); + GPR_ASSERT(reinterpret_cast<BaseType*>(static_cast<DerivedType*>(p)) == p); + } + + typename std::aligned_storage< + grpc_core::manual_ctor_impl::max_size_of<DerivedTypes...>::value, + grpc_core::manual_ctor_impl::max_align_of<DerivedTypes...>::value>::type + space_; +}; + template <typename Type> class ManualConstructor { public: diff --git a/src/core/lib/surface/call.cc b/src/core/lib/surface/call.cc index a83c95c8dc..a2eb02bd85 100644 --- a/src/core/lib/surface/call.cc +++ b/src/core/lib/surface/call.cc @@ -234,6 +234,7 @@ struct grpc_call { struct { grpc_status_code* status; grpc_slice* status_details; + const char** error_string; } client; struct { int* cancelled; @@ -284,7 +285,8 @@ static void receiving_slice_ready(grpc_exec_ctx* exec_ctx, void* bctlp, static void get_final_status(grpc_exec_ctx* exec_ctx, grpc_call* call, void (*set_value)(grpc_status_code code, void* user_data), - void* set_value_user_data, grpc_slice* details); + void* set_value_user_data, grpc_slice* details, + const char** error_string); static void set_status_value_directly(grpc_status_code status, void* dest); static void set_status_from_error(grpc_exec_ctx* exec_ctx, grpc_call* call, status_source source, grpc_error* error); @@ -546,7 +548,8 @@ static void destroy_call(grpc_exec_ctx* exec_ctx, void* call, } get_final_status(exec_ctx, c, set_status_value_directly, - &c->final_info.final_status, nullptr); + &c->final_info.final_status, nullptr, + c->final_info.error_string); c->final_info.stats.latency = gpr_time_sub(gpr_now(GPR_CLOCK_MONOTONIC), c->start_time); @@ -733,16 +736,15 @@ static void cancel_with_status(grpc_exec_ctx* exec_ctx, grpc_call* c, * FINAL STATUS CODE MANIPULATION */ -static bool get_final_status_from(grpc_exec_ctx* exec_ctx, grpc_call* call, - grpc_error* error, bool allow_ok_status, - void (*set_value)(grpc_status_code code, - void* user_data), - void* set_value_user_data, - grpc_slice* details) { +static bool get_final_status_from( + grpc_exec_ctx* exec_ctx, grpc_call* call, grpc_error* error, + bool allow_ok_status, + void (*set_value)(grpc_status_code code, void* user_data), + void* set_value_user_data, grpc_slice* details, const char** error_string) { grpc_status_code code; grpc_slice slice = grpc_empty_slice(); grpc_error_get_status(exec_ctx, error, call->send_deadline, &code, &slice, - nullptr); + nullptr, error_string); if (code == GRPC_STATUS_OK && !allow_ok_status) { return false; } @@ -757,7 +759,8 @@ static bool get_final_status_from(grpc_exec_ctx* exec_ctx, grpc_call* call, static void get_final_status(grpc_exec_ctx* exec_ctx, grpc_call* call, void (*set_value)(grpc_status_code code, void* user_data), - void* set_value_user_data, grpc_slice* details) { + void* set_value_user_data, grpc_slice* details, + const char** error_string) { int i; received_status status[STATUS_SOURCE_COUNT]; for (i = 0; i < STATUS_SOURCE_COUNT; i++) { @@ -781,7 +784,7 @@ static void get_final_status(grpc_exec_ctx* exec_ctx, grpc_call* call, grpc_error_has_clear_grpc_status(status[i].error)) { if (get_final_status_from(exec_ctx, call, status[i].error, allow_ok_status != 0, set_value, - set_value_user_data, details)) { + set_value_user_data, details, error_string)) { return; } } @@ -791,7 +794,7 @@ static void get_final_status(grpc_exec_ctx* exec_ctx, grpc_call* call, if (status[i].is_set) { if (get_final_status_from(exec_ctx, call, status[i].error, allow_ok_status != 0, set_value, - set_value_user_data, details)) { + set_value_user_data, details, error_string)) { return; } } @@ -1332,10 +1335,11 @@ static void post_batch_completion(grpc_exec_ctx* exec_ctx, if (call->is_client) { get_final_status(exec_ctx, call, set_status_value_directly, call->final_op.client.status, - call->final_op.client.status_details); + call->final_op.client.status_details, + call->final_op.client.error_string); } else { get_final_status(exec_ctx, call, set_cancelled_value, - call->final_op.server.cancelled, nullptr); + call->final_op.server.cancelled, nullptr, nullptr); } GRPC_ERROR_UNREF(error); @@ -1992,6 +1996,8 @@ static grpc_call_error call_start_batch(grpc_exec_ctx* exec_ctx, call->final_op.client.status = op->data.recv_status_on_client.status; call->final_op.client.status_details = op->data.recv_status_on_client.status_details; + call->final_op.client.error_string = + op->data.recv_status_on_client.error_string; stream_op->recv_trailing_metadata = true; stream_op->collect_stats = true; stream_op_payload->recv_trailing_metadata.recv_trailing_metadata = diff --git a/src/core/lib/transport/error_utils.cc b/src/core/lib/transport/error_utils.cc index 19510b4c8d..69c8ae6de3 100644 --- a/src/core/lib/transport/error_utils.cc +++ b/src/core/lib/transport/error_utils.cc @@ -18,6 +18,7 @@ #include "src/core/lib/transport/error_utils.h" +#include <grpc/support/string_util.h> #include "src/core/lib/iomgr/error_internal.h" #include "src/core/lib/transport/status_conversion.h" @@ -41,8 +42,8 @@ static grpc_error* recursively_find_error_with_field(grpc_error* error, void grpc_error_get_status(grpc_exec_ctx* exec_ctx, grpc_error* error, grpc_millis deadline, grpc_status_code* code, - grpc_slice* slice, - grpc_http2_error_code* http_error) { + grpc_slice* slice, grpc_http2_error_code* http_error, + const char** error_string) { // Start with the parent error and recurse through the tree of children // until we find the first one that has a status code. grpc_error* found_error = @@ -69,6 +70,10 @@ void grpc_error_get_status(grpc_exec_ctx* exec_ctx, grpc_error* error, } if (code != nullptr) *code = status; + if (error_string != NULL && status != GRPC_STATUS_OK) { + *error_string = gpr_strdup(grpc_error_string(error)); + } + if (http_error != nullptr) { if (grpc_error_get_int(found_error, GRPC_ERROR_INT_HTTP2_ERROR, &integer)) { *http_error = (grpc_http2_error_code)integer; diff --git a/src/core/lib/transport/error_utils.h b/src/core/lib/transport/error_utils.h index 690e42058a..6f21f484e5 100644 --- a/src/core/lib/transport/error_utils.h +++ b/src/core/lib/transport/error_utils.h @@ -30,13 +30,15 @@ extern "C" { /// A utility function to get the status code and message to be returned /// to the application. If not set in the top-level message, looks /// through child errors until it finds the first one with these attributes. -/// All attributes are pulled from the same child error. If any of the -/// attributes (code, msg, http_status) are unneeded, they can be passed as +/// All attributes are pulled from the same child error. error_string will +/// be populated with the entire error string. If any of the attributes (code, +/// msg, http_status, error_string) are unneeded, they can be passed as /// NULL. void grpc_error_get_status(grpc_exec_ctx* exec_ctx, grpc_error* error, grpc_millis deadline, grpc_status_code* code, grpc_slice* slice, - grpc_http2_error_code* http_status); + grpc_http2_error_code* http_status, + const char** error_string); /// A utility function to check whether there is a clear status code that /// doesn't need to be guessed in \a error. This means that \a error or some diff --git a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs index 9488ce29e9..e7d8939978 100644 --- a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs +++ b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallServerTest.cs @@ -64,7 +64,7 @@ namespace Grpc.Core.Internal.Tests public void CancelNotificationAfterStartDisposes() { var finishedTask = asyncCallServer.ServerSideCallAsync(); - fakeCall.ReceivedCloseOnServerHandler(true, cancelled: true); + fakeCall.ReceivedCloseOnServerCallback.OnReceivedCloseOnServer(true, cancelled: true); AssertFinished(asyncCallServer, fakeCall, finishedTask); } @@ -76,8 +76,8 @@ namespace Grpc.Core.Internal.Tests var moveNextTask = requestStream.MoveNext(); - fakeCall.ReceivedCloseOnServerHandler(true, cancelled: true); - fakeCall.ReceivedMessageHandler(true, null); + fakeCall.ReceivedCloseOnServerCallback.OnReceivedCloseOnServer(true, cancelled: true); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null); Assert.IsFalse(moveNextTask.Result); AssertFinished(asyncCallServer, fakeCall, finishedTask); @@ -89,7 +89,7 @@ namespace Grpc.Core.Internal.Tests var finishedTask = asyncCallServer.ServerSideCallAsync(); var requestStream = new ServerRequestStream<string, string>(asyncCallServer); - fakeCall.ReceivedCloseOnServerHandler(true, cancelled: true); + fakeCall.ReceivedCloseOnServerCallback.OnReceivedCloseOnServer(true, cancelled: true); // Check that starting a read after cancel notification has been processed is legal. var moveNextTask = requestStream.MoveNext(); @@ -107,10 +107,10 @@ namespace Grpc.Core.Internal.Tests // if a read completion's success==false, the request stream will silently finish // and we rely on C core cancelling the call. var moveNextTask = requestStream.MoveNext(); - fakeCall.ReceivedMessageHandler(false, null); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(false, null); Assert.IsFalse(moveNextTask.Result); - fakeCall.ReceivedCloseOnServerHandler(true, cancelled: true); + fakeCall.ReceivedCloseOnServerCallback.OnReceivedCloseOnServer(true, cancelled: true); AssertFinished(asyncCallServer, fakeCall, finishedTask); } @@ -120,7 +120,7 @@ namespace Grpc.Core.Internal.Tests var finishedTask = asyncCallServer.ServerSideCallAsync(); var responseStream = new ServerResponseStream<string, string>(asyncCallServer); - fakeCall.ReceivedCloseOnServerHandler(true, cancelled: true); + fakeCall.ReceivedCloseOnServerCallback.OnReceivedCloseOnServer(true, cancelled: true); // TODO(jtattermusch): should we throw a different exception type instead? Assert.Throws(typeof(InvalidOperationException), () => responseStream.WriteAsync("request1")); @@ -134,10 +134,10 @@ namespace Grpc.Core.Internal.Tests var responseStream = new ServerResponseStream<string, string>(asyncCallServer); var writeTask = responseStream.WriteAsync("request1"); - fakeCall.SendCompletionHandler(false); + fakeCall.SendCompletionCallback.OnSendCompletion(false); Assert.ThrowsAsync(typeof(IOException), async () => await writeTask); - fakeCall.ReceivedCloseOnServerHandler(true, cancelled: true); + fakeCall.ReceivedCloseOnServerCallback.OnReceivedCloseOnServer(true, cancelled: true); AssertFinished(asyncCallServer, fakeCall, finishedTask); } @@ -150,13 +150,13 @@ namespace Grpc.Core.Internal.Tests var writeTask = responseStream.WriteAsync("request1"); var writeStatusTask = asyncCallServer.SendStatusFromServerAsync(Status.DefaultSuccess, new Metadata(), null); - fakeCall.SendCompletionHandler(true); - fakeCall.SendStatusFromServerHandler(true); + fakeCall.SendCompletionCallback.OnSendCompletion(true); + fakeCall.SendStatusFromServerCallback.OnSendStatusFromServerCompletion(true); Assert.DoesNotThrowAsync(async () => await writeTask); Assert.DoesNotThrowAsync(async () => await writeStatusTask); - fakeCall.ReceivedCloseOnServerHandler(true, cancelled: true); + fakeCall.ReceivedCloseOnServerCallback.OnReceivedCloseOnServer(true, cancelled: true); AssertFinished(asyncCallServer, fakeCall, finishedTask); } @@ -170,8 +170,8 @@ namespace Grpc.Core.Internal.Tests asyncCallServer.SendStatusFromServerAsync(Status.DefaultSuccess, new Metadata(), null); Assert.ThrowsAsync(typeof(InvalidOperationException), async () => await responseStream.WriteAsync("request1")); - fakeCall.SendStatusFromServerHandler(true); - fakeCall.ReceivedCloseOnServerHandler(true, cancelled: true); + fakeCall.SendStatusFromServerCallback.OnSendStatusFromServerCompletion(true); + fakeCall.ReceivedCloseOnServerCallback.OnReceivedCloseOnServer(true, cancelled: true); AssertFinished(asyncCallServer, fakeCall, finishedTask); } diff --git a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs index b2b49f3a48..9aab54d2d0 100644 --- a/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs +++ b/src/csharp/Grpc.Core.Tests/Internal/AsyncCallTest.cs @@ -73,7 +73,7 @@ namespace Grpc.Core.Internal.Tests public void AsyncUnary_Success() { var resultTask = asyncCall.UnaryCallAsync("request1"); - fakeCall.UnaryResponseClientHandler(true, + fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata()), CreateResponsePayload(), new Metadata()); @@ -85,7 +85,7 @@ namespace Grpc.Core.Internal.Tests public void AsyncUnary_NonSuccessStatusCode() { var resultTask = asyncCall.UnaryCallAsync("request1"); - fakeCall.UnaryResponseClientHandler(true, + fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true, CreateClientSideStatus(StatusCode.InvalidArgument), null, new Metadata()); @@ -97,7 +97,7 @@ namespace Grpc.Core.Internal.Tests public void AsyncUnary_NullResponsePayload() { var resultTask = asyncCall.UnaryCallAsync("request1"); - fakeCall.UnaryResponseClientHandler(true, + fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata()), null, new Metadata()); @@ -118,7 +118,7 @@ namespace Grpc.Core.Internal.Tests public void ClientStreaming_NoRequest_Success() { var resultTask = asyncCall.ClientStreamingCallAsync(); - fakeCall.UnaryResponseClientHandler(true, + fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata()), CreateResponsePayload(), new Metadata()); @@ -130,7 +130,7 @@ namespace Grpc.Core.Internal.Tests public void ClientStreaming_NoRequest_NonSuccessStatusCode() { var resultTask = asyncCall.ClientStreamingCallAsync(); - fakeCall.UnaryResponseClientHandler(true, + fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true, CreateClientSideStatus(StatusCode.InvalidArgument), null, new Metadata()); @@ -145,18 +145,18 @@ namespace Grpc.Core.Internal.Tests var requestStream = new ClientRequestStream<string, string>(asyncCall); var writeTask = requestStream.WriteAsync("request1"); - fakeCall.SendCompletionHandler(true); + fakeCall.SendCompletionCallback.OnSendCompletion(true); writeTask.Wait(); var writeTask2 = requestStream.WriteAsync("request2"); - fakeCall.SendCompletionHandler(true); + fakeCall.SendCompletionCallback.OnSendCompletion(true); writeTask2.Wait(); var completeTask = requestStream.CompleteAsync(); - fakeCall.SendCompletionHandler(true); + fakeCall.SendCompletionCallback.OnSendCompletion(true); completeTask.Wait(); - fakeCall.UnaryResponseClientHandler(true, + fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata()), CreateResponsePayload(), new Metadata()); @@ -171,12 +171,12 @@ namespace Grpc.Core.Internal.Tests var requestStream = new ClientRequestStream<string, string>(asyncCall); var writeTask = requestStream.WriteAsync("request1"); - fakeCall.SendCompletionHandler(false); + fakeCall.SendCompletionCallback.OnSendCompletion(false); // The write will wait for call to finish to receive the status code. Assert.IsFalse(writeTask.IsCompleted); - fakeCall.UnaryResponseClientHandler(true, + fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true, CreateClientSideStatus(StatusCode.Internal), null, new Metadata()); @@ -195,12 +195,12 @@ namespace Grpc.Core.Internal.Tests var writeTask = requestStream.WriteAsync("request1"); - fakeCall.UnaryResponseClientHandler(true, + fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true, CreateClientSideStatus(StatusCode.Internal), null, new Metadata()); - fakeCall.SendCompletionHandler(false); + fakeCall.SendCompletionCallback.OnSendCompletion(false); var ex = Assert.ThrowsAsync<RpcException>(async () => await writeTask); Assert.AreEqual(StatusCode.Internal, ex.Status.StatusCode); @@ -215,13 +215,13 @@ namespace Grpc.Core.Internal.Tests var requestStream = new ClientRequestStream<string, string>(asyncCall); var writeTask = requestStream.WriteAsync("request1"); - fakeCall.SendCompletionHandler(false); + fakeCall.SendCompletionCallback.OnSendCompletion(false); // Until the delayed write completion has been triggered, // we still act as if there was an active write. Assert.Throws(typeof(InvalidOperationException), () => requestStream.WriteAsync("request2")); - fakeCall.UnaryResponseClientHandler(true, + fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true, CreateClientSideStatus(StatusCode.Internal), null, new Metadata()); @@ -242,7 +242,7 @@ namespace Grpc.Core.Internal.Tests var resultTask = asyncCall.ClientStreamingCallAsync(); var requestStream = new ClientRequestStream<string, string>(asyncCall); - fakeCall.UnaryResponseClientHandler(true, + fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata()), CreateResponsePayload(), new Metadata()); @@ -260,7 +260,7 @@ namespace Grpc.Core.Internal.Tests var resultTask = asyncCall.ClientStreamingCallAsync(); var requestStream = new ClientRequestStream<string, string>(asyncCall); - fakeCall.UnaryResponseClientHandler(true, + fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true, new ClientSideStatus(new Status(StatusCode.OutOfRange, ""), new Metadata()), CreateResponsePayload(), new Metadata()); @@ -282,9 +282,9 @@ namespace Grpc.Core.Internal.Tests Assert.Throws(typeof(InvalidOperationException), () => requestStream.WriteAsync("request1")); - fakeCall.SendCompletionHandler(true); + fakeCall.SendCompletionCallback.OnSendCompletion(true); - fakeCall.UnaryResponseClientHandler(true, + fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata()), CreateResponsePayload(), new Metadata()); @@ -298,7 +298,7 @@ namespace Grpc.Core.Internal.Tests var resultTask = asyncCall.ClientStreamingCallAsync(); var requestStream = new ClientRequestStream<string, string>(asyncCall); - fakeCall.UnaryResponseClientHandler(true, + fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata()), CreateResponsePayload(), new Metadata()); @@ -319,7 +319,7 @@ namespace Grpc.Core.Internal.Tests var writeTask = requestStream.WriteAsync("request1"); Assert.ThrowsAsync(typeof(TaskCanceledException), async () => await writeTask); - fakeCall.UnaryResponseClientHandler(true, + fakeCall.UnaryResponseClientCallback.OnUnaryResponseClient(true, CreateClientSideStatus(StatusCode.Cancelled), null, new Metadata()); @@ -342,11 +342,11 @@ namespace Grpc.Core.Internal.Tests var responseStream = new ClientResponseStream<string, string>(asyncCall); var readTask = responseStream.MoveNext(); - fakeCall.ReceivedResponseHeadersHandler(true, new Metadata()); + fakeCall.ReceivedResponseHeadersCallback.OnReceivedResponseHeaders(true, new Metadata()); Assert.AreEqual(0, asyncCall.ResponseHeadersAsync.Result.Count); - fakeCall.ReceivedMessageHandler(true, null); - fakeCall.ReceivedStatusOnClientHandler(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata())); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null); + fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata())); AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask); } @@ -359,8 +359,8 @@ namespace Grpc.Core.Internal.Tests var readTask = responseStream.MoveNext(); // try alternative order of completions - fakeCall.ReceivedStatusOnClientHandler(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata())); - fakeCall.ReceivedMessageHandler(true, null); + fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata())); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null); AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask); } @@ -372,8 +372,8 @@ namespace Grpc.Core.Internal.Tests var responseStream = new ClientResponseStream<string, string>(asyncCall); var readTask = responseStream.MoveNext(); - fakeCall.ReceivedMessageHandler(false, null); // after a failed read, we rely on C core to deliver appropriate status code. - fakeCall.ReceivedStatusOnClientHandler(true, CreateClientSideStatus(StatusCode.Internal)); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(false, null); // after a failed read, we rely on C core to deliver appropriate status code. + fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, CreateClientSideStatus(StatusCode.Internal)); AssertStreamingResponseError(asyncCall, fakeCall, readTask, StatusCode.Internal); } @@ -385,18 +385,18 @@ namespace Grpc.Core.Internal.Tests var responseStream = new ClientResponseStream<string, string>(asyncCall); var readTask1 = responseStream.MoveNext(); - fakeCall.ReceivedMessageHandler(true, CreateResponsePayload()); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateResponsePayload()); Assert.IsTrue(readTask1.Result); Assert.AreEqual("response1", responseStream.Current); var readTask2 = responseStream.MoveNext(); - fakeCall.ReceivedMessageHandler(true, CreateResponsePayload()); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateResponsePayload()); Assert.IsTrue(readTask2.Result); Assert.AreEqual("response1", responseStream.Current); var readTask3 = responseStream.MoveNext(); - fakeCall.ReceivedStatusOnClientHandler(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata())); - fakeCall.ReceivedMessageHandler(true, null); + fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata())); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null); AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask3); } @@ -409,12 +409,12 @@ namespace Grpc.Core.Internal.Tests var responseStream = new ClientResponseStream<string, string>(asyncCall); var writeTask1 = requestStream.CompleteAsync(); - fakeCall.SendCompletionHandler(true); + fakeCall.SendCompletionCallback.OnSendCompletion(true); Assert.DoesNotThrowAsync(async () => await writeTask1); var readTask = responseStream.MoveNext(); - fakeCall.ReceivedMessageHandler(true, null); - fakeCall.ReceivedStatusOnClientHandler(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata())); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null); + fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata())); AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask); } @@ -427,8 +427,8 @@ namespace Grpc.Core.Internal.Tests var responseStream = new ClientResponseStream<string, string>(asyncCall); var readTask = responseStream.MoveNext(); - fakeCall.ReceivedMessageHandler(true, null); - fakeCall.ReceivedStatusOnClientHandler(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata())); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null); + fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata())); AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask); @@ -445,8 +445,8 @@ namespace Grpc.Core.Internal.Tests var responseStream = new ClientResponseStream<string, string>(asyncCall); var readTask = responseStream.MoveNext(); - fakeCall.ReceivedMessageHandler(true, null); - fakeCall.ReceivedStatusOnClientHandler(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata())); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null); + fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, new ClientSideStatus(Status.DefaultSuccess, new Metadata())); AssertStreamingResponseSuccess(asyncCall, fakeCall, readTask); @@ -461,14 +461,14 @@ namespace Grpc.Core.Internal.Tests var responseStream = new ClientResponseStream<string, string>(asyncCall); var writeTask = requestStream.WriteAsync("request1"); - fakeCall.SendCompletionHandler(false); + fakeCall.SendCompletionCallback.OnSendCompletion(false); // The write will wait for call to finish to receive the status code. Assert.IsFalse(writeTask.IsCompleted); var readTask = responseStream.MoveNext(); - fakeCall.ReceivedMessageHandler(true, null); - fakeCall.ReceivedStatusOnClientHandler(true, CreateClientSideStatus(StatusCode.PermissionDenied)); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null); + fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, CreateClientSideStatus(StatusCode.PermissionDenied)); var ex = Assert.ThrowsAsync<RpcException>(async () => await writeTask); Assert.AreEqual(StatusCode.PermissionDenied, ex.Status.StatusCode); @@ -486,9 +486,9 @@ namespace Grpc.Core.Internal.Tests var writeTask = requestStream.WriteAsync("request1"); var readTask = responseStream.MoveNext(); - fakeCall.ReceivedMessageHandler(true, null); - fakeCall.ReceivedStatusOnClientHandler(true, CreateClientSideStatus(StatusCode.PermissionDenied)); - fakeCall.SendCompletionHandler(false); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null); + fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, CreateClientSideStatus(StatusCode.PermissionDenied)); + fakeCall.SendCompletionCallback.OnSendCompletion(false); var ex = Assert.ThrowsAsync<RpcException>(async () => await writeTask); Assert.AreEqual(StatusCode.PermissionDenied, ex.Status.StatusCode); @@ -510,8 +510,8 @@ namespace Grpc.Core.Internal.Tests Assert.ThrowsAsync(typeof(TaskCanceledException), async () => await writeTask); var readTask = responseStream.MoveNext(); - fakeCall.ReceivedMessageHandler(true, null); - fakeCall.ReceivedStatusOnClientHandler(true, CreateClientSideStatus(StatusCode.Cancelled)); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null); + fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, CreateClientSideStatus(StatusCode.Cancelled)); AssertStreamingResponseError(asyncCall, fakeCall, readTask, StatusCode.Cancelled); } @@ -526,13 +526,13 @@ namespace Grpc.Core.Internal.Tests Assert.IsTrue(fakeCall.IsCancelled); var readTask1 = responseStream.MoveNext(); - fakeCall.ReceivedMessageHandler(true, CreateResponsePayload()); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateResponsePayload()); Assert.IsTrue(readTask1.Result); Assert.AreEqual("response1", responseStream.Current); var readTask2 = responseStream.MoveNext(); - fakeCall.ReceivedMessageHandler(true, null); - fakeCall.ReceivedStatusOnClientHandler(true, CreateClientSideStatus(StatusCode.Cancelled)); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null); + fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, CreateClientSideStatus(StatusCode.Cancelled)); AssertStreamingResponseError(asyncCall, fakeCall, readTask2, StatusCode.Cancelled); } @@ -547,13 +547,13 @@ namespace Grpc.Core.Internal.Tests asyncCall.Cancel(); Assert.IsTrue(fakeCall.IsCancelled); - fakeCall.ReceivedMessageHandler(true, CreateResponsePayload()); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, CreateResponsePayload()); Assert.IsTrue(readTask1.Result); Assert.AreEqual("response1", responseStream.Current); var readTask2 = responseStream.MoveNext(); - fakeCall.ReceivedMessageHandler(true, null); - fakeCall.ReceivedStatusOnClientHandler(true, CreateClientSideStatus(StatusCode.Cancelled)); + fakeCall.ReceivedMessageCallback.OnReceivedMessage(true, null); + fakeCall.ReceivedStatusOnClientCallback.OnReceivedStatusOnClient(true, CreateClientSideStatus(StatusCode.Cancelled)); AssertStreamingResponseError(asyncCall, fakeCall, readTask2, StatusCode.Cancelled); } diff --git a/src/csharp/Grpc.Core.Tests/Internal/FakeNativeCall.cs b/src/csharp/Grpc.Core.Tests/Internal/FakeNativeCall.cs index c3a27167f9..581ac3384b 100644 --- a/src/csharp/Grpc.Core.Tests/Internal/FakeNativeCall.cs +++ b/src/csharp/Grpc.Core.Tests/Internal/FakeNativeCall.cs @@ -31,43 +31,43 @@ namespace Grpc.Core.Internal.Tests /// </summary> internal class FakeNativeCall : INativeCall { - public UnaryResponseClientHandler UnaryResponseClientHandler + public IUnaryResponseClientCallback UnaryResponseClientCallback { get; set; } - public ReceivedStatusOnClientHandler ReceivedStatusOnClientHandler + public IReceivedStatusOnClientCallback ReceivedStatusOnClientCallback { get; set; } - public ReceivedMessageHandler ReceivedMessageHandler + public IReceivedMessageCallback ReceivedMessageCallback { get; set; } - public ReceivedResponseHeadersHandler ReceivedResponseHeadersHandler + public IReceivedResponseHeadersCallback ReceivedResponseHeadersCallback { get; set; } - public SendCompletionHandler SendCompletionHandler + public ISendCompletionCallback SendCompletionCallback { get; set; } - public SendCompletionHandler SendStatusFromServerHandler + public ISendStatusFromServerCompletionCallback SendStatusFromServerCallback { get; set; } - public ReceivedCloseOnServerHandler ReceivedCloseOnServerHandler + public IReceivedCloseOnServerCallback ReceivedCloseOnServerCallback { get; set; @@ -100,9 +100,9 @@ namespace Grpc.Core.Internal.Tests return "PEER"; } - public void StartUnary(UnaryResponseClientHandler callback, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags) + public void StartUnary(IUnaryResponseClientCallback callback, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags) { - UnaryResponseClientHandler = callback; + UnaryResponseClientCallback = callback; } public void StartUnary(BatchContextSafeHandle ctx, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags) @@ -110,55 +110,55 @@ namespace Grpc.Core.Internal.Tests throw new NotImplementedException(); } - public void StartClientStreaming(UnaryResponseClientHandler callback, MetadataArraySafeHandle metadataArray, CallFlags callFlags) + public void StartClientStreaming(IUnaryResponseClientCallback callback, MetadataArraySafeHandle metadataArray, CallFlags callFlags) { - UnaryResponseClientHandler = callback; + UnaryResponseClientCallback = callback; } - public void StartServerStreaming(ReceivedStatusOnClientHandler callback, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags) + public void StartServerStreaming(IReceivedStatusOnClientCallback callback, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags) { - ReceivedStatusOnClientHandler = callback; + ReceivedStatusOnClientCallback = callback; } - public void StartDuplexStreaming(ReceivedStatusOnClientHandler callback, MetadataArraySafeHandle metadataArray, CallFlags callFlags) + public void StartDuplexStreaming(IReceivedStatusOnClientCallback callback, MetadataArraySafeHandle metadataArray, CallFlags callFlags) { - ReceivedStatusOnClientHandler = callback; + ReceivedStatusOnClientCallback = callback; } - public void StartReceiveMessage(ReceivedMessageHandler callback) + public void StartReceiveMessage(IReceivedMessageCallback callback) { - ReceivedMessageHandler = callback; + ReceivedMessageCallback = callback; } - public void StartReceiveInitialMetadata(ReceivedResponseHeadersHandler callback) + public void StartReceiveInitialMetadata(IReceivedResponseHeadersCallback callback) { - ReceivedResponseHeadersHandler = callback; + ReceivedResponseHeadersCallback = callback; } - public void StartSendInitialMetadata(SendCompletionHandler callback, MetadataArraySafeHandle metadataArray) + public void StartSendInitialMetadata(ISendCompletionCallback callback, MetadataArraySafeHandle metadataArray) { - SendCompletionHandler = callback; + SendCompletionCallback = callback; } - public void StartSendMessage(SendCompletionHandler callback, byte[] payload, WriteFlags writeFlags, bool sendEmptyInitialMetadata) + public void StartSendMessage(ISendCompletionCallback callback, byte[] payload, WriteFlags writeFlags, bool sendEmptyInitialMetadata) { - SendCompletionHandler = callback; + SendCompletionCallback = callback; } - public void StartSendCloseFromClient(SendCompletionHandler callback) + public void StartSendCloseFromClient(ISendCompletionCallback callback) { - SendCompletionHandler = callback; + SendCompletionCallback = callback; } - public void StartSendStatusFromServer(SendCompletionHandler callback, Status status, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata, + public void StartSendStatusFromServer(ISendStatusFromServerCompletionCallback callback, Status status, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata, byte[] optionalPayload, WriteFlags writeFlags) { - SendStatusFromServerHandler = callback; + SendStatusFromServerCallback = callback; } - public void StartServerSide(ReceivedCloseOnServerHandler callback) + public void StartServerSide(IReceivedCloseOnServerCallback callback) { - ReceivedCloseOnServerHandler = callback; + ReceivedCloseOnServerCallback = callback; } public void Dispose() diff --git a/src/csharp/Grpc.Core.Tests/PInvokeTest.cs b/src/csharp/Grpc.Core.Tests/PInvokeTest.cs index 7529c44c4e..43f816bb1c 100644 --- a/src/csharp/Grpc.Core.Tests/PInvokeTest.cs +++ b/src/csharp/Grpc.Core.Tests/PInvokeTest.cs @@ -63,7 +63,7 @@ namespace Grpc.Core.Tests [Ignore("Prevent running on Jenkins")] public void NativeCallbackBenchmark() { - OpCompletionDelegate handler = Handler; + NativeCallbackTestDelegate handler = Handler; counter = 0; BenchmarkUtil.RunBenchmark( @@ -91,7 +91,7 @@ namespace Grpc.Core.Tests 10000, 10000, () => { - Native.grpcsharp_test_callback(new OpCompletionDelegate(Handler)); + Native.grpcsharp_test_callback(new NativeCallbackTestDelegate(Handler)); }); Assert.AreNotEqual(0, counter); } diff --git a/src/csharp/Grpc.Core/Channel.cs b/src/csharp/Grpc.Core/Channel.cs index 1803920662..f9925a8a76 100644 --- a/src/csharp/Grpc.Core/Channel.cs +++ b/src/csharp/Grpc.Core/Channel.cs @@ -127,6 +127,20 @@ namespace Grpc.Core } } + // cached handler for watch connectivity state + static readonly BatchCompletionDelegate WatchConnectivityStateHandler = (success, ctx, state) => + { + var tcs = (TaskCompletionSource<object>) state; + if (success) + { + tcs.SetResult(null); + } + else + { + tcs.SetCanceled(); + } + }; + /// <summary> /// Returned tasks completes once channel state has become different from /// given lastObservedState. @@ -138,18 +152,8 @@ namespace Grpc.Core "Shutdown is a terminal state. No further state changes can occur."); var tcs = new TaskCompletionSource<object>(); var deadlineTimespec = deadline.HasValue ? Timespec.FromDateTime(deadline.Value) : Timespec.InfFuture; - var handler = new BatchCompletionDelegate((success, ctx) => - { - if (success) - { - tcs.SetResult(null); - } - else - { - tcs.SetCanceled(); - } - }); - handle.WatchConnectivityState(lastObservedState, deadlineTimespec, completionQueue, handler); + // pass "tcs" as "state" for WatchConnectivityStateHandler. + handle.WatchConnectivityState(lastObservedState, deadlineTimespec, completionQueue, WatchConnectivityStateHandler, tcs); return tcs.Task; } diff --git a/src/csharp/Grpc.Core/Internal/AsyncCall.cs b/src/csharp/Grpc.Core/Internal/AsyncCall.cs index 09fb722c81..aa2161267a 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCall.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCall.cs @@ -27,7 +27,7 @@ namespace Grpc.Core.Internal /// <summary> /// Manages client side native call lifecycle. /// </summary> - internal class AsyncCall<TRequest, TResponse> : AsyncCallBase<TRequest, TResponse> + internal class AsyncCall<TRequest, TResponse> : AsyncCallBase<TRequest, TResponse>, IUnaryResponseClientCallback, IReceivedStatusOnClientCallback, IReceivedResponseHeadersCallback { static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<AsyncCall<TRequest, TResponse>>(); @@ -138,7 +138,7 @@ namespace Grpc.Core.Internal unaryResponseTcs = new TaskCompletionSource<TResponse>(); using (var metadataArray = MetadataArraySafeHandle.Create(details.Options.Headers)) { - call.StartUnary(HandleUnaryResponse, payload, GetWriteFlagsForCall(), metadataArray, details.Options.Flags); + call.StartUnary(UnaryResponseClientCallback, payload, GetWriteFlagsForCall(), metadataArray, details.Options.Flags); } return unaryResponseTcs.Task; } @@ -162,7 +162,7 @@ namespace Grpc.Core.Internal unaryResponseTcs = new TaskCompletionSource<TResponse>(); using (var metadataArray = MetadataArraySafeHandle.Create(details.Options.Headers)) { - call.StartClientStreaming(HandleUnaryResponse, metadataArray, details.Options.Flags); + call.StartClientStreaming(UnaryResponseClientCallback, metadataArray, details.Options.Flags); } return unaryResponseTcs.Task; @@ -188,9 +188,9 @@ namespace Grpc.Core.Internal streamingResponseCallFinishedTcs = new TaskCompletionSource<object>(); using (var metadataArray = MetadataArraySafeHandle.Create(details.Options.Headers)) { - call.StartServerStreaming(HandleFinished, payload, GetWriteFlagsForCall(), metadataArray, details.Options.Flags); + call.StartServerStreaming(ReceivedStatusOnClientCallback, payload, GetWriteFlagsForCall(), metadataArray, details.Options.Flags); } - call.StartReceiveInitialMetadata(HandleReceivedResponseHeaders); + call.StartReceiveInitialMetadata(ReceivedResponseHeadersCallback); } } @@ -210,9 +210,9 @@ namespace Grpc.Core.Internal streamingResponseCallFinishedTcs = new TaskCompletionSource<object>(); using (var metadataArray = MetadataArraySafeHandle.Create(details.Options.Headers)) { - call.StartDuplexStreaming(HandleFinished, metadataArray, details.Options.Flags); + call.StartDuplexStreaming(ReceivedStatusOnClientCallback, metadataArray, details.Options.Flags); } - call.StartReceiveInitialMetadata(HandleReceivedResponseHeaders); + call.StartReceiveInitialMetadata(ReceivedResponseHeadersCallback); } } @@ -256,7 +256,7 @@ namespace Grpc.Core.Internal halfcloseRequested = true; return TaskUtils.CompletedTask; } - call.StartSendCloseFromClient(HandleSendFinished); + call.StartSendCloseFromClient(SendCompletionCallback); halfcloseRequested = true; streamingWriteTcs = new TaskCompletionSource<object>(); @@ -516,5 +516,26 @@ namespace Grpc.Core.Internal streamingResponseCallFinishedTcs.SetResult(null); } + + IUnaryResponseClientCallback UnaryResponseClientCallback => this; + + void IUnaryResponseClientCallback.OnUnaryResponseClient(bool success, ClientSideStatus receivedStatus, byte[] receivedMessage, Metadata responseHeaders) + { + HandleUnaryResponse(success, receivedStatus, receivedMessage, responseHeaders); + } + + IReceivedStatusOnClientCallback ReceivedStatusOnClientCallback => this; + + void IReceivedStatusOnClientCallback.OnReceivedStatusOnClient(bool success, ClientSideStatus receivedStatus) + { + HandleFinished(success, receivedStatus); + } + + IReceivedResponseHeadersCallback ReceivedResponseHeadersCallback => this; + + void IReceivedResponseHeadersCallback.OnReceivedResponseHeaders(bool success, Metadata responseHeaders) + { + HandleReceivedResponseHeaders(success, responseHeaders); + } } } diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs index f379c85e00..3273c26b88 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCallBase.cs @@ -35,7 +35,7 @@ namespace Grpc.Core.Internal /// Base for handling both client side and server side calls. /// Manages native call lifecycle and provides convenience methods. /// </summary> - internal abstract class AsyncCallBase<TWrite, TRead> + internal abstract class AsyncCallBase<TWrite, TRead> : IReceivedMessageCallback, ISendCompletionCallback { static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<AsyncCallBase<TWrite, TRead>>(); protected static readonly Status DeserializeResponseFailureStatus = new Status(StatusCode.Internal, "Failed to deserialize response message."); @@ -126,7 +126,7 @@ namespace Grpc.Core.Internal return earlyResult; } - call.StartSendMessage(HandleSendFinished, payload, writeFlags, !initialMetadataSent); + call.StartSendMessage(SendCompletionCallback, payload, writeFlags, !initialMetadataSent); initialMetadataSent = true; streamingWritesCounter++; @@ -154,7 +154,7 @@ namespace Grpc.Core.Internal GrpcPreconditions.CheckState(streamingReadTcs == null, "Only one read can be pending at a time"); GrpcPreconditions.CheckState(!disposed); - call.StartReceiveMessage(HandleReadFinished); + call.StartReceiveMessage(ReceivedMessageCallback); streamingReadTcs = new TaskCompletionSource<TRead>(); return streamingReadTcs.Task; } @@ -342,5 +342,19 @@ namespace Grpc.Core.Internal } origTcs.SetResult(msg); } + + protected ISendCompletionCallback SendCompletionCallback => this; + + void ISendCompletionCallback.OnSendCompletion(bool success) + { + HandleSendFinished(success); + } + + IReceivedMessageCallback ReceivedMessageCallback => this; + + void IReceivedMessageCallback.OnReceivedMessage(bool success, byte[] receivedMessage) + { + HandleReadFinished(success, receivedMessage); + } } } diff --git a/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs b/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs index 271a6ffadf..11acb27533 100644 --- a/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs +++ b/src/csharp/Grpc.Core/Internal/AsyncCallServer.cs @@ -31,7 +31,7 @@ namespace Grpc.Core.Internal /// <summary> /// Manages server side native call lifecycle. /// </summary> - internal class AsyncCallServer<TRequest, TResponse> : AsyncCallBase<TResponse, TRequest> + internal class AsyncCallServer<TRequest, TResponse> : AsyncCallBase<TResponse, TRequest>, IReceivedCloseOnServerCallback, ISendStatusFromServerCompletionCallback { readonly TaskCompletionSource<object> finishedServersideTcs = new TaskCompletionSource<object>(); readonly CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); @@ -70,7 +70,7 @@ namespace Grpc.Core.Internal started = true; - call.StartServerSide(HandleFinishedServerside); + call.StartServerSide(ReceiveCloseOnServerCallback); return finishedServersideTcs.Task; } } @@ -114,7 +114,7 @@ namespace Grpc.Core.Internal using (var metadataArray = MetadataArraySafeHandle.Create(headers)) { - call.StartSendInitialMetadata(HandleSendFinished, metadataArray); + call.StartSendInitialMetadata(SendCompletionCallback, metadataArray); } this.initialMetadataSent = true; @@ -127,10 +127,10 @@ namespace Grpc.Core.Internal /// Sends call result status, indicating we are done with writes. /// Sending a status different from StatusCode.OK will also implicitly cancel the call. /// </summary> - public Task SendStatusFromServerAsync(Status status, Metadata trailers, Tuple<TResponse, WriteFlags> optionalWrite) + public Task SendStatusFromServerAsync(Status status, Metadata trailers, ResponseWithFlags? optionalWrite) { - byte[] payload = optionalWrite != null ? UnsafeSerialize(optionalWrite.Item1) : null; - var writeFlags = optionalWrite != null ? optionalWrite.Item2 : default(WriteFlags); + byte[] payload = optionalWrite.HasValue ? UnsafeSerialize(optionalWrite.Value.Response) : null; + var writeFlags = optionalWrite.HasValue ? optionalWrite.Value.WriteFlags : default(WriteFlags); lock (myLock) { @@ -140,13 +140,13 @@ namespace Grpc.Core.Internal using (var metadataArray = MetadataArraySafeHandle.Create(trailers)) { - call.StartSendStatusFromServer(HandleSendStatusFromServerFinished, status, metadataArray, !initialMetadataSent, + call.StartSendStatusFromServer(SendStatusFromServerCompletionCallback, status, metadataArray, !initialMetadataSent, payload, writeFlags); } halfcloseRequested = true; initialMetadataSent = true; sendStatusFromServerTcs = new TaskCompletionSource<object>(); - if (optionalWrite != null) + if (optionalWrite.HasValue) { streamingWritesCounter++; } @@ -227,5 +227,31 @@ namespace Grpc.Core.Internal finishedServersideTcs.SetResult(null); } + + IReceivedCloseOnServerCallback ReceiveCloseOnServerCallback => this; + + void IReceivedCloseOnServerCallback.OnReceivedCloseOnServer(bool success, bool cancelled) + { + HandleFinishedServerside(success, cancelled); + } + + ISendStatusFromServerCompletionCallback SendStatusFromServerCompletionCallback => this; + + void ISendStatusFromServerCompletionCallback.OnSendStatusFromServerCompletion(bool success) + { + HandleSendStatusFromServerFinished(success); + } + + public struct ResponseWithFlags + { + public ResponseWithFlags(TResponse response, WriteFlags writeFlags) + { + this.Response = response; + this.WriteFlags = writeFlags; + } + + public TResponse Response { get; } + public WriteFlags WriteFlags { get; } + } } } diff --git a/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs b/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs index cd5e3d8911..1e6f1fba37 100644 --- a/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/BatchContextSafeHandle.cs @@ -20,15 +20,25 @@ using System; using System.Runtime.InteropServices; using System.Text; using Grpc.Core; +using Grpc.Core.Logging; +using Grpc.Core.Utils; namespace Grpc.Core.Internal { + internal interface IOpCompletionCallback + { + void OnComplete(bool success); + } + /// <summary> /// grpcsharp_batch_context /// </summary> - internal class BatchContextSafeHandle : SafeHandleZeroIsInvalid + internal class BatchContextSafeHandle : SafeHandleZeroIsInvalid, IOpCompletionCallback { static readonly NativeMethods Native = NativeMethods.Get(); + static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<BatchContextSafeHandle>(); + + CompletionCallbackData completionCallbackData; private BatchContextSafeHandle() { @@ -47,19 +57,26 @@ namespace Grpc.Core.Internal } } + public void SetCompletionCallback(BatchCompletionDelegate callback, object state) + { + GrpcPreconditions.CheckState(completionCallbackData.Callback == null); + GrpcPreconditions.CheckNotNull(callback, nameof(callback)); + completionCallbackData = new CompletionCallbackData(callback, state); + } + // Gets data of recv_initial_metadata completion. public Metadata GetReceivedInitialMetadata() { IntPtr metadataArrayPtr = Native.grpcsharp_batch_context_recv_initial_metadata(this); return MetadataArraySafeHandle.ReadMetadataFromPtrUnsafe(metadataArrayPtr); } - + // Gets data of recv_status_on_client completion. public ClientSideStatus GetReceivedStatusOnClient() { UIntPtr detailsLength; IntPtr detailsPtr = Native.grpcsharp_batch_context_recv_status_on_client_details(this, out detailsLength); - string details = MarshalUtils.PtrToStringUTF8(detailsPtr, (int) detailsLength.ToUInt32()); + string details = MarshalUtils.PtrToStringUTF8(detailsPtr, (int)detailsLength.ToUInt32()); var status = new Status(Native.grpcsharp_batch_context_recv_status_on_client_status(this), details); IntPtr metadataArrayPtr = Native.grpcsharp_batch_context_recv_status_on_client_trailing_metadata(this); @@ -86,11 +103,40 @@ namespace Grpc.Core.Internal { return Native.grpcsharp_batch_context_recv_close_on_server_cancelled(this) != 0; } - + protected override bool ReleaseHandle() { Native.grpcsharp_batch_context_destroy(handle); return true; } + + void IOpCompletionCallback.OnComplete(bool success) + { + try + { + completionCallbackData.Callback(success, this, completionCallbackData.State); + } + catch (Exception e) + { + Logger.Error(e, "Exception occured while invoking batch completion delegate."); + } + finally + { + completionCallbackData = default(CompletionCallbackData); + Dispose(); + } + } + + struct CompletionCallbackData + { + public CompletionCallbackData(BatchCompletionDelegate callback, object state) + { + this.Callback = callback; + this.State = state; + } + + public BatchCompletionDelegate Callback { get; } + public object State { get; } + } } } diff --git a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs index 3a7f97707b..d6a5ba586b 100644 --- a/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/CallSafeHandle.cs @@ -32,6 +32,23 @@ namespace Grpc.Core.Internal public static readonly CallSafeHandle NullInstance = new CallSafeHandle(); static readonly NativeMethods Native = NativeMethods.Get(); + // Completion handlers are pre-allocated to avoid unneccessary delegate allocations. + // The "state" field is used to store the actual callback to invoke. + static readonly BatchCompletionDelegate CompletionHandler_IUnaryResponseClientCallback = + (success, context, state) => ((IUnaryResponseClientCallback)state).OnUnaryResponseClient(success, context.GetReceivedStatusOnClient(), context.GetReceivedMessage(), context.GetReceivedInitialMetadata()); + static readonly BatchCompletionDelegate CompletionHandler_IReceivedStatusOnClientCallback = + (success, context, state) => ((IReceivedStatusOnClientCallback)state).OnReceivedStatusOnClient(success, context.GetReceivedStatusOnClient()); + static readonly BatchCompletionDelegate CompletionHandler_IReceivedMessageCallback = + (success, context, state) => ((IReceivedMessageCallback)state).OnReceivedMessage(success, context.GetReceivedMessage()); + static readonly BatchCompletionDelegate CompletionHandler_IReceivedResponseHeadersCallback = + (success, context, state) => ((IReceivedResponseHeadersCallback)state).OnReceivedResponseHeaders(success, context.GetReceivedInitialMetadata()); + static readonly BatchCompletionDelegate CompletionHandler_ISendCompletionCallback = + (success, context, state) => ((ISendCompletionCallback)state).OnSendCompletion(success); + static readonly BatchCompletionDelegate CompletionHandler_ISendStatusFromServerCompletionCallback = + (success, context, state) => ((ISendStatusFromServerCompletionCallback)state).OnSendStatusFromServerCompletion(success); + static readonly BatchCompletionDelegate CompletionHandler_IReceivedCloseOnServerCallback = + (success, context, state) => ((IReceivedCloseOnServerCallback)state).OnReceivedCloseOnServer(success, context.GetReceivedCloseOnServerCancelled()); + const uint GRPC_WRITE_BUFFER_HINT = 1; CompletionQueueSafeHandle completionQueue; @@ -49,12 +66,12 @@ namespace Grpc.Core.Internal Native.grpcsharp_call_set_credentials(this, credentials).CheckOk(); } - public void StartUnary(UnaryResponseClientHandler callback, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags) + public void StartUnary(IUnaryResponseClientCallback callback, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags) { using (completionQueue.NewScope()) { var ctx = BatchContextSafeHandle.Create(); - completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedStatusOnClient(), context.GetReceivedMessage(), context.GetReceivedInitialMetadata())); + completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, CompletionHandler_IUnaryResponseClientCallback, callback); Native.grpcsharp_call_start_unary(this, ctx, payload, new UIntPtr((ulong)payload.Length), writeFlags, metadataArray, callFlags) .CheckOk(); } @@ -66,106 +83,106 @@ namespace Grpc.Core.Internal .CheckOk(); } - public void StartClientStreaming(UnaryResponseClientHandler callback, MetadataArraySafeHandle metadataArray, CallFlags callFlags) + public void StartClientStreaming(IUnaryResponseClientCallback callback, MetadataArraySafeHandle metadataArray, CallFlags callFlags) { using (completionQueue.NewScope()) { var ctx = BatchContextSafeHandle.Create(); - completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedStatusOnClient(), context.GetReceivedMessage(), context.GetReceivedInitialMetadata())); + completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, CompletionHandler_IUnaryResponseClientCallback, callback); Native.grpcsharp_call_start_client_streaming(this, ctx, metadataArray, callFlags).CheckOk(); } } - public void StartServerStreaming(ReceivedStatusOnClientHandler callback, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags) + public void StartServerStreaming(IReceivedStatusOnClientCallback callback, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags) { using (completionQueue.NewScope()) { var ctx = BatchContextSafeHandle.Create(); - completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedStatusOnClient())); + completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, CompletionHandler_IReceivedStatusOnClientCallback, callback); Native.grpcsharp_call_start_server_streaming(this, ctx, payload, new UIntPtr((ulong)payload.Length), writeFlags, metadataArray, callFlags).CheckOk(); } } - public void StartDuplexStreaming(ReceivedStatusOnClientHandler callback, MetadataArraySafeHandle metadataArray, CallFlags callFlags) + public void StartDuplexStreaming(IReceivedStatusOnClientCallback callback, MetadataArraySafeHandle metadataArray, CallFlags callFlags) { using (completionQueue.NewScope()) { var ctx = BatchContextSafeHandle.Create(); - completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedStatusOnClient())); + completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, CompletionHandler_IReceivedStatusOnClientCallback, callback); Native.grpcsharp_call_start_duplex_streaming(this, ctx, metadataArray, callFlags).CheckOk(); } } - public void StartSendMessage(SendCompletionHandler callback, byte[] payload, WriteFlags writeFlags, bool sendEmptyInitialMetadata) + public void StartSendMessage(ISendCompletionCallback callback, byte[] payload, WriteFlags writeFlags, bool sendEmptyInitialMetadata) { using (completionQueue.NewScope()) { var ctx = BatchContextSafeHandle.Create(); - completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success)); + completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, CompletionHandler_ISendCompletionCallback, callback); Native.grpcsharp_call_send_message(this, ctx, payload, new UIntPtr((ulong)payload.Length), writeFlags, sendEmptyInitialMetadata ? 1 : 0).CheckOk(); } } - public void StartSendCloseFromClient(SendCompletionHandler callback) + public void StartSendCloseFromClient(ISendCompletionCallback callback) { using (completionQueue.NewScope()) { var ctx = BatchContextSafeHandle.Create(); - completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success)); + completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, CompletionHandler_ISendCompletionCallback, callback); Native.grpcsharp_call_send_close_from_client(this, ctx).CheckOk(); } } - public void StartSendStatusFromServer(SendCompletionHandler callback, Status status, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata, + public void StartSendStatusFromServer(ISendStatusFromServerCompletionCallback callback, Status status, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata, byte[] optionalPayload, WriteFlags writeFlags) { using (completionQueue.NewScope()) { var ctx = BatchContextSafeHandle.Create(); var optionalPayloadLength = optionalPayload != null ? new UIntPtr((ulong)optionalPayload.Length) : UIntPtr.Zero; - completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success)); + completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, CompletionHandler_ISendStatusFromServerCompletionCallback, callback); var statusDetailBytes = MarshalUtils.GetBytesUTF8(status.Detail); Native.grpcsharp_call_send_status_from_server(this, ctx, status.StatusCode, statusDetailBytes, new UIntPtr((ulong)statusDetailBytes.Length), metadataArray, sendEmptyInitialMetadata ? 1 : 0, optionalPayload, optionalPayloadLength, writeFlags).CheckOk(); } } - public void StartReceiveMessage(ReceivedMessageHandler callback) + public void StartReceiveMessage(IReceivedMessageCallback callback) { using (completionQueue.NewScope()) { var ctx = BatchContextSafeHandle.Create(); - completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedMessage())); + completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, CompletionHandler_IReceivedMessageCallback, callback); Native.grpcsharp_call_recv_message(this, ctx).CheckOk(); } } - public void StartReceiveInitialMetadata(ReceivedResponseHeadersHandler callback) + public void StartReceiveInitialMetadata(IReceivedResponseHeadersCallback callback) { using (completionQueue.NewScope()) { var ctx = BatchContextSafeHandle.Create(); - completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedInitialMetadata())); + completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, CompletionHandler_IReceivedResponseHeadersCallback, callback); Native.grpcsharp_call_recv_initial_metadata(this, ctx).CheckOk(); } } - public void StartServerSide(ReceivedCloseOnServerHandler callback) + public void StartServerSide(IReceivedCloseOnServerCallback callback) { using (completionQueue.NewScope()) { var ctx = BatchContextSafeHandle.Create(); - completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success, context.GetReceivedCloseOnServerCancelled())); + completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, CompletionHandler_IReceivedCloseOnServerCallback, callback); Native.grpcsharp_call_start_serverside(this, ctx).CheckOk(); } } - public void StartSendInitialMetadata(SendCompletionHandler callback, MetadataArraySafeHandle metadataArray) + public void StartSendInitialMetadata(ISendCompletionCallback callback, MetadataArraySafeHandle metadataArray) { using (completionQueue.NewScope()) { var ctx = BatchContextSafeHandle.Create(); - completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, (success, context) => callback(success)); + completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, CompletionHandler_ISendCompletionCallback, callback); Native.grpcsharp_call_send_initial_metadata(this, ctx, metadataArray).CheckOk(); } } diff --git a/src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs b/src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs index f826a17bad..1eeb0e3d97 100644 --- a/src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/ChannelSafeHandle.cs @@ -64,10 +64,10 @@ namespace Grpc.Core.Internal return Native.grpcsharp_channel_check_connectivity_state(this, tryToConnect ? 1 : 0); } - public void WatchConnectivityState(ChannelState lastObservedState, Timespec deadline, CompletionQueueSafeHandle cq, BatchCompletionDelegate callback) + public void WatchConnectivityState(ChannelState lastObservedState, Timespec deadline, CompletionQueueSafeHandle cq, BatchCompletionDelegate callback, object callbackState) { var ctx = BatchContextSafeHandle.Create(); - cq.CompletionRegistry.RegisterBatchCompletion(ctx, callback); + cq.CompletionRegistry.RegisterBatchCompletion(ctx, callback, callbackState); Native.grpcsharp_channel_watch_connectivity_state(this, lastObservedState, deadline, cq, ctx); } diff --git a/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs b/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs index 1102c8d14f..b68655b33c 100644 --- a/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs +++ b/src/csharp/Grpc.Core/Internal/CompletionRegistry.cs @@ -19,15 +19,15 @@ using System; using System.Collections.Concurrent; using System.Collections.Generic; +using System.Diagnostics; using System.Runtime.InteropServices; +using System.Threading; using Grpc.Core.Logging; using Grpc.Core.Utils; namespace Grpc.Core.Internal { - internal delegate void OpCompletionDelegate(bool success); - - internal delegate void BatchCompletionDelegate(bool success, BatchContextSafeHandle ctx); + internal delegate void BatchCompletionDelegate(bool success, BatchContextSafeHandle ctx, object state); internal delegate void RequestCallCompletionDelegate(bool success, RequestCallContextSafeHandle ctx); @@ -36,8 +36,8 @@ namespace Grpc.Core.Internal static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<CompletionRegistry>(); readonly GrpcEnvironment environment; - readonly Dictionary<IntPtr, OpCompletionDelegate> dict = new Dictionary<IntPtr, OpCompletionDelegate>(new IntPtrComparer()); - readonly object myLock = new object(); + readonly Dictionary<IntPtr, IOpCompletionCallback> dict = new Dictionary<IntPtr, IOpCompletionCallback>(new IntPtrComparer()); + SpinLock spinLock = new SpinLock(Debugger.IsAttached); IntPtr lastRegisteredKey; // only for testing public CompletionRegistry(GrpcEnvironment environment) @@ -45,38 +45,51 @@ namespace Grpc.Core.Internal this.environment = environment; } - public void Register(IntPtr key, OpCompletionDelegate callback) + public void Register(IntPtr key, IOpCompletionCallback callback) { environment.DebugStats.PendingBatchCompletions.Increment(); - lock (myLock) + + bool lockTaken = false; + try { + spinLock.Enter(ref lockTaken); + dict.Add(key, callback); this.lastRegisteredKey = key; } + finally + { + if (lockTaken) spinLock.Exit(); + } } - public void RegisterBatchCompletion(BatchContextSafeHandle ctx, BatchCompletionDelegate callback) + public void RegisterBatchCompletion(BatchContextSafeHandle ctx, BatchCompletionDelegate callback, object state) { - // TODO(jtattermusch): get rid of new delegate creation here - OpCompletionDelegate opCallback = ((success) => HandleBatchCompletion(success, ctx, callback)); - Register(ctx.Handle, opCallback); + ctx.SetCompletionCallback(callback, state); + Register(ctx.Handle, ctx); } public void RegisterRequestCallCompletion(RequestCallContextSafeHandle ctx, RequestCallCompletionDelegate callback) { - // TODO(jtattermusch): get rid of new delegate creation here - OpCompletionDelegate opCallback = ((success) => HandleRequestCallCompletion(success, ctx, callback)); - Register(ctx.Handle, opCallback); + ctx.CompletionCallback = callback; + Register(ctx.Handle, ctx); } - public OpCompletionDelegate Extract(IntPtr key) + public IOpCompletionCallback Extract(IntPtr key) { - OpCompletionDelegate value = null; - lock (myLock) + IOpCompletionCallback value = null; + bool lockTaken = false; + try { + spinLock.Enter(ref lockTaken); + value = dict[key]; dict.Remove(key); } + finally + { + if (lockTaken) spinLock.Exit(); + } environment.DebugStats.PendingBatchCompletions.Decrement(); return value; } @@ -89,44 +102,6 @@ namespace Grpc.Core.Internal get { return this.lastRegisteredKey; } } - private static void HandleBatchCompletion(bool success, BatchContextSafeHandle ctx, BatchCompletionDelegate callback) - { - try - { - callback(success, ctx); - } - catch (Exception e) - { - Logger.Error(e, "Exception occured while invoking batch completion delegate."); - } - finally - { - if (ctx != null) - { - ctx.Dispose(); - } - } - } - - private static void HandleRequestCallCompletion(bool success, RequestCallContextSafeHandle ctx, RequestCallCompletionDelegate callback) - { - try - { - callback(success, ctx); - } - catch (Exception e) - { - Logger.Error(e, "Exception occured while invoking request call completion delegate."); - } - finally - { - if (ctx != null) - { - ctx.Dispose(); - } - } - } - /// <summary> /// IntPtr doesn't implement <c>IEquatable{IntPtr}</c> so we need to use custom comparer to avoid boxing. /// </summary> diff --git a/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs b/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs index f7f723c00b..bd0229a9dd 100644 --- a/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs +++ b/src/csharp/Grpc.Core/Internal/GrpcThreadPool.cs @@ -68,8 +68,8 @@ namespace Grpc.Core.Internal GrpcPreconditions.CheckArgument(poolSize >= completionQueueCount, "Thread pool size cannot be smaller than the number of completion queues used."); - this.runCompletionQueueEventCallbackSuccess = new WaitCallback((callback) => RunCompletionQueueEventCallback((OpCompletionDelegate) callback, true)); - this.runCompletionQueueEventCallbackFailure = new WaitCallback((callback) => RunCompletionQueueEventCallback((OpCompletionDelegate) callback, false)); + this.runCompletionQueueEventCallbackSuccess = new WaitCallback((callback) => RunCompletionQueueEventCallback((IOpCompletionCallback) callback, true)); + this.runCompletionQueueEventCallbackFailure = new WaitCallback((callback) => RunCompletionQueueEventCallback((IOpCompletionCallback) callback, false)); } public void Start() @@ -225,11 +225,11 @@ namespace Grpc.Core.Internal return list.AsReadOnly(); } - private void RunCompletionQueueEventCallback(OpCompletionDelegate callback, bool success) + private void RunCompletionQueueEventCallback(IOpCompletionCallback callback, bool success) { try { - callback(success); + callback.OnComplete(success); } catch (Exception e) { diff --git a/src/csharp/Grpc.Core/Internal/INativeCall.cs b/src/csharp/Grpc.Core/Internal/INativeCall.cs index f9c06583c8..5c35b2ba46 100644 --- a/src/csharp/Grpc.Core/Internal/INativeCall.cs +++ b/src/csharp/Grpc.Core/Internal/INativeCall.cs @@ -20,18 +20,41 @@ using Grpc.Core; namespace Grpc.Core.Internal { - internal delegate void UnaryResponseClientHandler(bool success, ClientSideStatus receivedStatus, byte[] receivedMessage, Metadata responseHeaders); + internal interface IUnaryResponseClientCallback + { + void OnUnaryResponseClient(bool success, ClientSideStatus receivedStatus, byte[] receivedMessage, Metadata responseHeaders); + } // Received status for streaming response calls. - internal delegate void ReceivedStatusOnClientHandler(bool success, ClientSideStatus receivedStatus); + internal interface IReceivedStatusOnClientCallback + { + void OnReceivedStatusOnClient(bool success, ClientSideStatus receivedStatus); + } - internal delegate void ReceivedMessageHandler(bool success, byte[] receivedMessage); + internal interface IReceivedMessageCallback + { + void OnReceivedMessage(bool success, byte[] receivedMessage); + } - internal delegate void ReceivedResponseHeadersHandler(bool success, Metadata responseHeaders); + internal interface IReceivedResponseHeadersCallback + { + void OnReceivedResponseHeaders(bool success, Metadata responseHeaders); + } - internal delegate void SendCompletionHandler(bool success); + internal interface ISendCompletionCallback + { + void OnSendCompletion(bool success); + } - internal delegate void ReceivedCloseOnServerHandler(bool success, bool cancelled); + internal interface ISendStatusFromServerCompletionCallback + { + void OnSendStatusFromServerCompletion(bool success); + } + + internal interface IReceivedCloseOnServerCallback + { + void OnReceivedCloseOnServer(bool success, bool cancelled); + } /// <summary> /// Abstraction of a native call object. @@ -44,28 +67,28 @@ namespace Grpc.Core.Internal string GetPeer(); - void StartUnary(UnaryResponseClientHandler callback, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags); + void StartUnary(IUnaryResponseClientCallback callback, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags); void StartUnary(BatchContextSafeHandle ctx, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags); - void StartClientStreaming(UnaryResponseClientHandler callback, MetadataArraySafeHandle metadataArray, CallFlags callFlags); + void StartClientStreaming(IUnaryResponseClientCallback callback, MetadataArraySafeHandle metadataArray, CallFlags callFlags); - void StartServerStreaming(ReceivedStatusOnClientHandler callback, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags); + void StartServerStreaming(IReceivedStatusOnClientCallback callback, byte[] payload, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags callFlags); - void StartDuplexStreaming(ReceivedStatusOnClientHandler callback, MetadataArraySafeHandle metadataArray, CallFlags callFlags); + void StartDuplexStreaming(IReceivedStatusOnClientCallback callback, MetadataArraySafeHandle metadataArray, CallFlags callFlags); - void StartReceiveMessage(ReceivedMessageHandler callback); + void StartReceiveMessage(IReceivedMessageCallback callback); - void StartReceiveInitialMetadata(ReceivedResponseHeadersHandler callback); + void StartReceiveInitialMetadata(IReceivedResponseHeadersCallback callback); - void StartSendInitialMetadata(SendCompletionHandler callback, MetadataArraySafeHandle metadataArray); + void StartSendInitialMetadata(ISendCompletionCallback callback, MetadataArraySafeHandle metadataArray); - void StartSendMessage(SendCompletionHandler callback, byte[] payload, WriteFlags writeFlags, bool sendEmptyInitialMetadata); + void StartSendMessage(ISendCompletionCallback callback, byte[] payload, WriteFlags writeFlags, bool sendEmptyInitialMetadata); - void StartSendCloseFromClient(SendCompletionHandler callback); + void StartSendCloseFromClient(ISendCompletionCallback callback); - void StartSendStatusFromServer(SendCompletionHandler callback, Status status, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata, byte[] optionalPayload, WriteFlags writeFlags); + void StartSendStatusFromServer(ISendStatusFromServerCompletionCallback callback, Status status, MetadataArraySafeHandle metadataArray, bool sendEmptyInitialMetadata, byte[] optionalPayload, WriteFlags writeFlags); - void StartServerSide(ReceivedCloseOnServerHandler callback); + void StartServerSide(IReceivedCloseOnServerCallback callback); } } diff --git a/src/csharp/Grpc.Core/Internal/NativeMethods.cs b/src/csharp/Grpc.Core/Internal/NativeMethods.cs index 22faa19d9b..d517252cfe 100644 --- a/src/csharp/Grpc.Core/Internal/NativeMethods.cs +++ b/src/csharp/Grpc.Core/Internal/NativeMethods.cs @@ -29,6 +29,8 @@ using Grpc.Core.Utils; namespace Grpc.Core.Internal { + internal delegate void NativeCallbackTestDelegate(bool success); + /// <summary> /// Provides access to all native methods provided by <c>NativeExtension</c>. /// An extra level of indirection is added to P/Invoke calls to allow intelligent loading @@ -420,7 +422,7 @@ namespace Grpc.Core.Internal public delegate Timespec gprsharp_convert_clock_type_delegate(Timespec t, ClockType targetClock); public delegate int gprsharp_sizeof_timespec_delegate(); - public delegate CallError grpcsharp_test_callback_delegate([MarshalAs(UnmanagedType.FunctionPtr)] OpCompletionDelegate callback); + public delegate CallError grpcsharp_test_callback_delegate([MarshalAs(UnmanagedType.FunctionPtr)] NativeCallbackTestDelegate callback); public delegate IntPtr grpcsharp_test_nop_delegate(IntPtr ptr); public delegate void grpcsharp_test_override_method_delegate(string methodName, string variant); } diff --git a/src/csharp/Grpc.Core/Internal/RequestCallContextSafeHandle.cs b/src/csharp/Grpc.Core/Internal/RequestCallContextSafeHandle.cs index b7af0c102d..09f5c3e452 100644 --- a/src/csharp/Grpc.Core/Internal/RequestCallContextSafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/RequestCallContextSafeHandle.cs @@ -19,15 +19,17 @@ using System; using System.Runtime.InteropServices; using Grpc.Core; +using Grpc.Core.Logging; namespace Grpc.Core.Internal { /// <summary> /// grpcsharp_request_call_context /// </summary> - internal class RequestCallContextSafeHandle : SafeHandleZeroIsInvalid + internal class RequestCallContextSafeHandle : SafeHandleZeroIsInvalid, IOpCompletionCallback { static readonly NativeMethods Native = NativeMethods.Get(); + static readonly ILogger Logger = GrpcEnvironment.Logger.ForType<RequestCallContextSafeHandle>(); private RequestCallContextSafeHandle() { @@ -46,6 +48,8 @@ namespace Grpc.Core.Internal } } + public RequestCallCompletionDelegate CompletionCallback { get; set; } + // Gets data of server_rpc_new completion. public ServerRpcNew GetServerRpcNew(Server server) { @@ -72,5 +76,22 @@ namespace Grpc.Core.Internal Native.grpcsharp_request_call_context_destroy(handle); return true; } + + void IOpCompletionCallback.OnComplete(bool success) + { + try + { + CompletionCallback(success, this); + } + catch (Exception e) + { + Logger.Error(e, "Exception occured while invoking request call completion delegate."); + } + finally + { + CompletionCallback = null; + Dispose(); + } + } } } diff --git a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs index 6019f8e793..98995a0862 100644 --- a/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs +++ b/src/csharp/Grpc.Core/Internal/ServerCallHandler.cs @@ -60,7 +60,7 @@ namespace Grpc.Core.Internal var responseStream = new ServerResponseStream<TRequest, TResponse>(asyncCall); Status status; - Tuple<TResponse,WriteFlags> responseTuple = null; + AsyncCallServer<TRequest,TResponse>.ResponseWithFlags? responseWithFlags = null; var context = HandlerUtils.NewContext(newRpc, responseStream, asyncCall.CancellationToken); try { @@ -68,7 +68,7 @@ namespace Grpc.Core.Internal var request = requestStream.Current; var response = await handler(request, context).ConfigureAwait(false); status = context.Status; - responseTuple = Tuple.Create(response, HandlerUtils.GetWriteFlags(context.WriteOptions)); + responseWithFlags = new AsyncCallServer<TRequest, TResponse>.ResponseWithFlags(response, HandlerUtils.GetWriteFlags(context.WriteOptions)); } catch (Exception e) { @@ -80,7 +80,7 @@ namespace Grpc.Core.Internal } try { - await asyncCall.SendStatusFromServerAsync(status, context.ResponseTrailers, responseTuple).ConfigureAwait(false); + await asyncCall.SendStatusFromServerAsync(status, context.ResponseTrailers, responseWithFlags).ConfigureAwait(false); } catch (Exception) { @@ -177,13 +177,13 @@ namespace Grpc.Core.Internal var responseStream = new ServerResponseStream<TRequest, TResponse>(asyncCall); Status status; - Tuple<TResponse,WriteFlags> responseTuple = null; + AsyncCallServer<TRequest, TResponse>.ResponseWithFlags? responseWithFlags = null; var context = HandlerUtils.NewContext(newRpc, responseStream, asyncCall.CancellationToken); try { var response = await handler(requestStream, context).ConfigureAwait(false); status = context.Status; - responseTuple = Tuple.Create(response, HandlerUtils.GetWriteFlags(context.WriteOptions)); + responseWithFlags = new AsyncCallServer<TRequest, TResponse>.ResponseWithFlags(response, HandlerUtils.GetWriteFlags(context.WriteOptions)); } catch (Exception e) { @@ -196,7 +196,7 @@ namespace Grpc.Core.Internal try { - await asyncCall.SendStatusFromServerAsync(status, context.ResponseTrailers, responseTuple).ConfigureAwait(false); + await asyncCall.SendStatusFromServerAsync(status, context.ResponseTrailers, responseWithFlags).ConfigureAwait(false); } catch (Exception) { diff --git a/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs b/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs index 63000e9a22..a308890cde 100644 --- a/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs +++ b/src/csharp/Grpc.Core/Internal/ServerSafeHandle.cs @@ -59,13 +59,15 @@ namespace Grpc.Core.Internal { Native.grpcsharp_server_start(this); } - + public void ShutdownAndNotify(BatchCompletionDelegate callback, CompletionQueueSafeHandle completionQueue) { using (completionQueue.NewScope()) { var ctx = BatchContextSafeHandle.Create(); - completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, callback); + // TODO(jtattermusch): delegate allocation by caller can be avoided by utilizing the "state" object, + // but server shutdown isn't worth optimizing right now. + completionQueue.CompletionRegistry.RegisterBatchCompletion(ctx, callback, null); Native.grpcsharp_server_shutdown_and_notify_callback(this, completionQueue, ctx); } } diff --git a/src/csharp/Grpc.Core/Server.cs b/src/csharp/Grpc.Core/Server.cs index 77ad876bdf..71c7f108f3 100644 --- a/src/csharp/Grpc.Core/Server.cs +++ b/src/csharp/Grpc.Core/Server.cs @@ -387,7 +387,7 @@ namespace Grpc.Core /// <summary> /// Handles native callback. /// </summary> - private void HandleServerShutdown(bool success, BatchContextSafeHandle ctx) + private void HandleServerShutdown(bool success, BatchContextSafeHandle ctx, object state) { shutdownTcs.SetResult(null); } diff --git a/src/csharp/Grpc.Microbenchmarks/CompletionRegistryBenchmark.cs b/src/csharp/Grpc.Microbenchmarks/CompletionRegistryBenchmark.cs new file mode 100644 index 0000000000..2d1c33e9a0 --- /dev/null +++ b/src/csharp/Grpc.Microbenchmarks/CompletionRegistryBenchmark.cs @@ -0,0 +1,78 @@ +#region Copyright notice and license + +// Copyright 2015 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#endregion + +using System; +using System.Runtime.InteropServices; +using System.Threading; +using Grpc.Core; +using Grpc.Core.Internal; +using System.Collections.Generic; +using System.Diagnostics; + +namespace Grpc.Microbenchmarks +{ + public class CompletionRegistryBenchmark + { + GrpcEnvironment environment; + + public void Init() + { + environment = GrpcEnvironment.AddRef(); + } + + public void Cleanup() + { + GrpcEnvironment.ReleaseAsync().Wait(); + } + + public void Run(int threadCount, int iterations, bool useSharedRegistry) + { + Console.WriteLine(string.Format("CompletionRegistryBenchmark: threads={0}, iterations={1}, useSharedRegistry={2}", threadCount, iterations, useSharedRegistry)); + CompletionRegistry sharedRegistry = useSharedRegistry ? new CompletionRegistry(environment) : null; + var threadedBenchmark = new ThreadedBenchmark(threadCount, () => ThreadBody(iterations, sharedRegistry)); + threadedBenchmark.Run(); + // TODO: parametrize by number of pending completions + } + + private void ThreadBody(int iterations, CompletionRegistry optionalSharedRegistry) + { + var completionRegistry = optionalSharedRegistry ?? new CompletionRegistry(environment); + var ctx = BatchContextSafeHandle.Create(); + + var stopwatch = Stopwatch.StartNew(); + for (int i = 0; i < iterations; i++) + { + completionRegistry.Register(ctx.Handle, ctx); + var callback = completionRegistry.Extract(ctx.Handle); + // NOTE: we are not calling the callback to avoid disposing ctx. + } + stopwatch.Stop(); + Console.WriteLine("Elapsed millis: " + stopwatch.ElapsedMilliseconds); + + ctx.Dispose(); + } + + private class NopCompletionCallback : IOpCompletionCallback + { + public void OnComplete(bool success) + { + + } + } + } +} diff --git a/src/csharp/Grpc.Microbenchmarks/GCStats.cs b/src/csharp/Grpc.Microbenchmarks/GCStats.cs new file mode 100644 index 0000000000..ca7051ec4e --- /dev/null +++ b/src/csharp/Grpc.Microbenchmarks/GCStats.cs @@ -0,0 +1,69 @@ +#region Copyright notice and license + +// Copyright 2015 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#endregion + +using System; +using Grpc.Core; +using Grpc.Core.Internal; + +namespace Grpc.Microbenchmarks +{ + internal class GCStats + { + readonly object myLock = new object(); + GCStatsSnapshot lastSnapshot; + + public GCStats() + { + lastSnapshot = new GCStatsSnapshot(GC.CollectionCount(0), GC.CollectionCount(1), GC.CollectionCount(2)); + } + + public GCStatsSnapshot GetSnapshot(bool reset = false) + { + lock (myLock) + { + var newSnapshot = new GCStatsSnapshot(GC.CollectionCount(0) - lastSnapshot.Gen0, + GC.CollectionCount(1) - lastSnapshot.Gen1, + GC.CollectionCount(2) - lastSnapshot.Gen2); + if (reset) + { + lastSnapshot = newSnapshot; + } + return newSnapshot; + } + } + } + + public class GCStatsSnapshot + { + public GCStatsSnapshot(int gen0, int gen1, int gen2) + { + this.Gen0 = gen0; + this.Gen1 = gen1; + this.Gen2 = gen2; + } + + public int Gen0 { get; } + public int Gen1 { get; } + public int Gen2 { get; } + + public override string ToString() + { + return string.Format("[GCCollectionCount: gen0 {0}, gen1 {1}, gen2 {2}]", Gen0, Gen1, Gen2); + } + } +} diff --git a/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj b/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj index 108357e4eb..8a629f9748 100644 --- a/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj +++ b/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj @@ -15,6 +15,10 @@ <ProjectReference Include="../Grpc.Core/Grpc.Core.csproj" /> </ItemGroup> + <ItemGroup> + <PackageReference Include="CommandLineParser" Version="2.1.1-beta" /> + </ItemGroup> + <ItemGroup Condition=" '$(TargetFramework)' == 'net45' "> <Reference Include="System" /> <Reference Include="Microsoft.CSharp" /> diff --git a/src/csharp/Grpc.Microbenchmarks/PInvokeByteArrayBenchmark.cs b/src/csharp/Grpc.Microbenchmarks/PInvokeByteArrayBenchmark.cs new file mode 100644 index 0000000000..787b5508fb --- /dev/null +++ b/src/csharp/Grpc.Microbenchmarks/PInvokeByteArrayBenchmark.cs @@ -0,0 +1,64 @@ +#region Copyright notice and license + +// Copyright 2015 gRPC authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#endregion + +using System; +using System.Runtime.InteropServices; +using System.Threading; +using Grpc.Core; +using Grpc.Core.Internal; +using System.Collections.Generic; +using System.Diagnostics; + +namespace Grpc.Microbenchmarks +{ + public class PInvokeByteArrayBenchmark + { + static readonly NativeMethods Native = NativeMethods.Get(); + + public void Init() + { + } + + public void Cleanup() + { + } + + public void Run(int threadCount, int iterations, int payloadSize) + { + Console.WriteLine(string.Format("PInvokeByteArrayBenchmark: threads={0}, iterations={1}, payloadSize={2}", threadCount, iterations, payloadSize)); + var threadedBenchmark = new ThreadedBenchmark(threadCount, () => ThreadBody(iterations, payloadSize)); + threadedBenchmark.Run(); + } + + private void ThreadBody(int iterations, int payloadSize) + { + var payload = new byte[payloadSize]; + + var stopwatch = Stopwatch.StartNew(); + for (int i = 0; i < iterations; i++) + { + var gcHandle = GCHandle.Alloc(payload, GCHandleType.Pinned); + var payloadPtr = gcHandle.AddrOfPinnedObject(); + Native.grpcsharp_test_nop(payloadPtr); + gcHandle.Free(); + } + stopwatch.Stop(); + Console.WriteLine("Elapsed millis: " + stopwatch.ElapsedMilliseconds); + } + } +} diff --git a/src/csharp/Grpc.Microbenchmarks/Program.cs b/src/csharp/Grpc.Microbenchmarks/Program.cs index d07d4187c4..a64c2979ab 100644 --- a/src/csharp/Grpc.Microbenchmarks/Program.cs +++ b/src/csharp/Grpc.Microbenchmarks/Program.cs @@ -20,14 +20,84 @@ using System; using Grpc.Core; using Grpc.Core.Internal; using Grpc.Core.Logging; +using CommandLine; +using CommandLine.Text; namespace Grpc.Microbenchmarks { class Program { + public enum MicrobenchmarkType + { + CompletionRegistry, + PInvokeByteArray, + SendMessage + } + + private class BenchmarkOptions + { + [Option("benchmark", Required = true, HelpText = "Benchmark to run")] + public MicrobenchmarkType Benchmark { get; set; } + } + public static void Main(string[] args) { GrpcEnvironment.SetLogger(new ConsoleLogger()); + var parserResult = Parser.Default.ParseArguments<BenchmarkOptions>(args) + .WithNotParsed(errors => { + Console.WriteLine("Supported benchmarks:"); + foreach (var enumValue in Enum.GetValues(typeof(MicrobenchmarkType))) + { + Console.WriteLine(" " + enumValue); + } + Environment.Exit(1); + }) + .WithParsed(options => + { + switch (options.Benchmark) + { + case MicrobenchmarkType.CompletionRegistry: + RunCompletionRegistryBenchmark(); + break; + case MicrobenchmarkType.PInvokeByteArray: + RunPInvokeByteArrayBenchmark(); + break; + case MicrobenchmarkType.SendMessage: + RunSendMessageBenchmark(); + break; + default: + throw new ArgumentException("Unsupported benchmark."); + } + }); + } + + static void RunCompletionRegistryBenchmark() + { + var benchmark = new CompletionRegistryBenchmark(); + benchmark.Init(); + foreach (int threadCount in new int[] {1, 1, 2, 4, 8, 12}) + { + foreach (bool useSharedRegistry in new bool[] {false, true}) + { + benchmark.Run(threadCount, 4 * 1000 * 1000, useSharedRegistry); + } + } + benchmark.Cleanup(); + } + + static void RunPInvokeByteArrayBenchmark() + { + var benchmark = new PInvokeByteArrayBenchmark(); + benchmark.Init(); + foreach (int threadCount in new int[] {1, 1, 2, 4, 8, 12}) + { + benchmark.Run(threadCount, 4 * 1000 * 1000, 0); + } + benchmark.Cleanup(); + } + + static void RunSendMessageBenchmark() + { var benchmark = new SendMessageBenchmark(); benchmark.Init(); foreach (int threadCount in new int[] {1, 1, 2, 4, 8, 12}) diff --git a/src/csharp/Grpc.Microbenchmarks/SendMessageBenchmark.cs b/src/csharp/Grpc.Microbenchmarks/SendMessageBenchmark.cs index de67874580..9cff97eb88 100644 --- a/src/csharp/Grpc.Microbenchmarks/SendMessageBenchmark.cs +++ b/src/csharp/Grpc.Microbenchmarks/SendMessageBenchmark.cs @@ -59,16 +59,16 @@ namespace Grpc.Microbenchmarks var cq = CompletionQueueSafeHandle.CreateAsync(completionRegistry); var call = CreateFakeCall(cq); - var sendCompletionHandler = new SendCompletionHandler((success) => { }); + var sendCompletionCallback = new NopSendCompletionCallback(); var payload = new byte[payloadSize]; var writeFlags = default(WriteFlags); var stopwatch = Stopwatch.StartNew(); for (int i = 0; i < iterations; i++) { - call.StartSendMessage(sendCompletionHandler, payload, writeFlags, false); + call.StartSendMessage(sendCompletionCallback, payload, writeFlags, false); var callback = completionRegistry.Extract(completionRegistry.LastRegisteredKey); - callback(true); + callback.OnComplete(true); } stopwatch.Stop(); Console.WriteLine("Elapsed millis: " + stopwatch.ElapsedMilliseconds); @@ -87,5 +87,13 @@ namespace Grpc.Microbenchmarks } return call; } + + private class NopSendCompletionCallback : ISendCompletionCallback + { + public void OnSendCompletion(bool success) + { + // NOP + } + } } } diff --git a/src/csharp/Grpc.Microbenchmarks/ThreadedBenchmark.cs b/src/csharp/Grpc.Microbenchmarks/ThreadedBenchmark.cs index feac8d1690..95b9aaaf3f 100644 --- a/src/csharp/Grpc.Microbenchmarks/ThreadedBenchmark.cs +++ b/src/csharp/Grpc.Microbenchmarks/ThreadedBenchmark.cs @@ -46,6 +46,7 @@ namespace Grpc.Microbenchmarks public void Run() { Console.WriteLine("Running threads."); + var gcStats = new GCStats(); var threads = new List<Thread>(); for (int i = 0; i < runners.Count; i++) { @@ -58,7 +59,7 @@ namespace Grpc.Microbenchmarks { thread.Join(); } - Console.WriteLine("All threads finished."); + Console.WriteLine("All threads finished (GC Stats Delta: " + gcStats.GetSnapshot() + ")"); } } } diff --git a/src/python/grpcio/grpc/__init__.py b/src/python/grpcio/grpc/__init__.py index c9f9ac27d9..558ce42129 100644 --- a/src/python/grpcio/grpc/__init__.py +++ b/src/python/grpcio/grpc/__init__.py @@ -424,6 +424,21 @@ class ServerCredentials(object): self._credentials = credentials +class ServerCertificateConfiguration(object): + """A certificate configuration for use with an SSL-enabled Server. + + Instances of this class can be returned in the certificate configuration + fetching callback. + + This class has no supported interface -- it exists to define the + type of its instances and its instances exist to be passed to + other functions. + """ + + def __init__(self, certificate_configuration): + self._certificate_configuration = certificate_configuration + + ######################## Multi-Callable Interfaces ########################### @@ -1252,6 +1267,61 @@ def ssl_server_credentials(private_key_certificate_chain_pairs, ], require_client_auth)) +def ssl_server_certificate_configuration(private_key_certificate_chain_pairs, + root_certificates=None): + """Creates a ServerCertificateConfiguration for use with a Server. + + Args: + private_key_certificate_chain_pairs: A collection of pairs of + the form [PEM-encoded private key, PEM-encoded certificate + chain]. + root_certificates: An optional byte string of PEM-encoded client root + certificates that the server will use to verify client authentication. + + Returns: + A ServerCertificateConfiguration that can be returned in the certificate + configuration fetching callback. + """ + if len(private_key_certificate_chain_pairs) == 0: + raise ValueError( + 'At least one private key-certificate chain pair is required!') + else: + return ServerCertificateConfiguration( + _cygrpc.server_certificate_config_ssl(root_certificates, [ + _cygrpc.SslPemKeyCertPair(key, pem) + for key, pem in private_key_certificate_chain_pairs + ])) + + +def dynamic_ssl_server_credentials(initial_certificate_configuration, + certificate_configuration_fetcher, + require_client_authentication=False): + """Creates a ServerCredentials for use with an SSL-enabled Server. + + Args: + initial_certificate_configuration (ServerCertificateConfiguration): The + certificate configuration with which the server will be initialized. + certificate_configuration_fetcher (callable): A callable that takes no + arguments and should return a ServerCertificateConfiguration to + replace the server's current certificate, or None for no change + (i.e., the server will continue its current certificate + config). The library will call this callback on *every* new + client connection before starting the TLS handshake with the + client, thus allowing the user application to optionally + return a new ServerCertificateConfiguration that the server will then + use for the handshake. + require_client_authentication: A boolean indicating whether or not to + require clients to be authenticated. + + Returns: + A ServerCredentials. + """ + return ServerCredentials( + _cygrpc.server_credentials_ssl_dynamic_cert_config( + initial_certificate_configuration, + certificate_configuration_fetcher, require_client_authentication)) + + def channel_ready_future(channel): """Creates a Future that tracks when a Channel is ready. @@ -1334,7 +1404,8 @@ __all__ = ('FutureTimeoutError', 'FutureCancelledError', 'Future', 'ChannelConnectivity', 'StatusCode', 'RpcError', 'RpcContext', 'Call', 'ChannelCredentials', 'CallCredentials', 'AuthMetadataContext', 'AuthMetadataPluginCallback', - 'AuthMetadataPlugin', 'ServerCredentials', 'UnaryUnaryMultiCallable', + 'AuthMetadataPlugin', 'ServerCertificateConfiguration', + 'ServerCredentials', 'UnaryUnaryMultiCallable', 'UnaryStreamMultiCallable', 'StreamUnaryMultiCallable', 'StreamStreamMultiCallable', 'Channel', 'ServicerContext', 'RpcMethodHandler', 'HandlerCallDetails', 'GenericRpcHandler', @@ -1344,8 +1415,9 @@ __all__ = ('FutureTimeoutError', 'FutureCancelledError', 'Future', 'method_handlers_generic_handler', 'ssl_channel_credentials', 'metadata_call_credentials', 'access_token_call_credentials', 'composite_call_credentials', 'composite_channel_credentials', - 'ssl_server_credentials', 'channel_ready_future', 'insecure_channel', - 'secure_channel', 'server',) + 'ssl_server_credentials', 'ssl_server_certificate_configuration', + 'dynamic_ssl_server_credentials', 'channel_ready_future', + 'insecure_channel', 'secure_channel', 'server',) ############################### Extension Shims ################################ diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi index 41975cbe9e..bc0f185c77 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pxd.pxi @@ -28,12 +28,27 @@ cdef class CallCredentials: cdef list references +cdef class ServerCertificateConfig: + + cdef grpc_ssl_server_certificate_config *c_cert_config + cdef const char *c_pem_root_certs + cdef grpc_ssl_pem_key_cert_pair *c_ssl_pem_key_cert_pairs + cdef size_t c_ssl_pem_key_cert_pairs_count + cdef list references + + cdef class ServerCredentials: cdef grpc_server_credentials *c_credentials cdef grpc_ssl_pem_key_cert_pair *c_ssl_pem_key_cert_pairs cdef size_t c_ssl_pem_key_cert_pairs_count cdef list references + # the cert config related state is used only if this credentials is + # created with cert config/fetcher + cdef object initial_cert_config + cdef object cert_config_fetcher + # whether C-core has asked for the initial_cert_config + cdef bint initial_cert_config_fetched cdef class CredentialsMetadataPlugin: diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi index 0fabda19ce..ee1328d2e9 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/credentials.pyx.pxi @@ -14,6 +14,7 @@ cimport cpython +import grpc import threading import traceback @@ -58,12 +59,30 @@ cdef class CallCredentials: grpc_shutdown() +cdef class ServerCertificateConfig: + + def __cinit__(self): + grpc_init() + self.c_cert_config = NULL + self.c_pem_root_certs = NULL + self.c_ssl_pem_key_cert_pairs = NULL + self.references = [] + + def __dealloc__(self): + grpc_ssl_server_certificate_config_destroy(self.c_cert_config) + gpr_free(self.c_ssl_pem_key_cert_pairs) + grpc_shutdown() + + cdef class ServerCredentials: def __cinit__(self): grpc_init() self.c_credentials = NULL self.references = [] + self.initial_cert_config = None + self.cert_config_fetcher = None + self.initial_cert_config_fetched = False def __dealloc__(self): if self.c_credentials != NULL: @@ -254,34 +273,86 @@ def call_credentials_metadata_plugin(CredentialsMetadataPlugin plugin): credentials.references.append(plugin) return credentials -def server_credentials_ssl(pem_root_certs, pem_key_cert_pairs, - bint force_client_auth): - pem_root_certs = str_to_bytes(pem_root_certs) - cdef char *c_pem_root_certs = NULL - if pem_root_certs is not None: - c_pem_root_certs = pem_root_certs - pem_key_cert_pairs = list(pem_key_cert_pairs) +cdef const char* _get_c_pem_root_certs(pem_root_certs): + if pem_root_certs is None: + return NULL + else: + return pem_root_certs + +cdef grpc_ssl_pem_key_cert_pair* _create_c_ssl_pem_key_cert_pairs(pem_key_cert_pairs): + # return a malloc'ed grpc_ssl_pem_key_cert_pair from a _list_ of SslPemKeyCertPair for pair in pem_key_cert_pairs: if not isinstance(pair, SslPemKeyCertPair): raise TypeError("expected pem_key_cert_pairs to be sequence of " "SslPemKeyCertPair") + cdef size_t c_ssl_pem_key_cert_pairs_count = len(pem_key_cert_pairs) + cdef grpc_ssl_pem_key_cert_pair* c_ssl_pem_key_cert_pairs = NULL + with nogil: + c_ssl_pem_key_cert_pairs = ( + <grpc_ssl_pem_key_cert_pair *>gpr_malloc( + sizeof(grpc_ssl_pem_key_cert_pair) * c_ssl_pem_key_cert_pairs_count)) + for i in range(c_ssl_pem_key_cert_pairs_count): + c_ssl_pem_key_cert_pairs[i] = ( + (<SslPemKeyCertPair>pem_key_cert_pairs[i]).c_pair) + return c_ssl_pem_key_cert_pairs + +def server_credentials_ssl(pem_root_certs, pem_key_cert_pairs, + bint force_client_auth): + pem_root_certs = str_to_bytes(pem_root_certs) + pem_key_cert_pairs = list(pem_key_cert_pairs) cdef ServerCredentials credentials = ServerCredentials() - credentials.references.append(pem_key_cert_pairs) credentials.references.append(pem_root_certs) + credentials.references.append(pem_key_cert_pairs) + cdef const char * c_pem_root_certs = _get_c_pem_root_certs(pem_root_certs) credentials.c_ssl_pem_key_cert_pairs_count = len(pem_key_cert_pairs) - with nogil: - credentials.c_ssl_pem_key_cert_pairs = ( - <grpc_ssl_pem_key_cert_pair *>gpr_malloc( - sizeof(grpc_ssl_pem_key_cert_pair) * - credentials.c_ssl_pem_key_cert_pairs_count - )) - for i in range(credentials.c_ssl_pem_key_cert_pairs_count): - credentials.c_ssl_pem_key_cert_pairs[i] = ( - (<SslPemKeyCertPair>pem_key_cert_pairs[i]).c_pair) - credentials.c_credentials = grpc_ssl_server_credentials_create( - c_pem_root_certs, credentials.c_ssl_pem_key_cert_pairs, - credentials.c_ssl_pem_key_cert_pairs_count, - GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY if force_client_auth else GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE, - NULL) + credentials.c_ssl_pem_key_cert_pairs = _create_c_ssl_pem_key_cert_pairs(pem_key_cert_pairs) + cdef grpc_ssl_server_certificate_config *c_cert_config = NULL + c_cert_config = grpc_ssl_server_certificate_config_create( + c_pem_root_certs, credentials.c_ssl_pem_key_cert_pairs, + credentials.c_ssl_pem_key_cert_pairs_count) + cdef grpc_ssl_server_credentials_options* c_options = NULL + # C-core assumes ownership of c_cert_config + c_options = grpc_ssl_server_credentials_create_options_using_config( + GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY + if force_client_auth else + GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE, + c_cert_config) + # C-core assumes ownership of c_options + credentials.c_credentials = grpc_ssl_server_credentials_create_with_options(c_options) return credentials +def server_certificate_config_ssl(pem_root_certs, pem_key_cert_pairs): + pem_root_certs = str_to_bytes(pem_root_certs) + pem_key_cert_pairs = list(pem_key_cert_pairs) + cdef ServerCertificateConfig cert_config = ServerCertificateConfig() + cert_config.references.append(pem_root_certs) + cert_config.references.append(pem_key_cert_pairs) + cert_config.c_pem_root_certs = _get_c_pem_root_certs(pem_root_certs) + cert_config.c_ssl_pem_key_cert_pairs_count = len(pem_key_cert_pairs) + cert_config.c_ssl_pem_key_cert_pairs = _create_c_ssl_pem_key_cert_pairs(pem_key_cert_pairs) + cert_config.c_cert_config = grpc_ssl_server_certificate_config_create( + cert_config.c_pem_root_certs, cert_config.c_ssl_pem_key_cert_pairs, + cert_config.c_ssl_pem_key_cert_pairs_count) + return cert_config + +def server_credentials_ssl_dynamic_cert_config(initial_cert_config, + cert_config_fetcher, + bint force_client_auth): + if not isinstance(initial_cert_config, grpc.ServerCertificateConfiguration): + raise TypeError( + 'initial_cert_config must be a grpc.ServerCertificateConfiguration') + if not callable(cert_config_fetcher): + raise TypeError('cert_config_fetcher must be callable') + cdef ServerCredentials credentials = ServerCredentials() + credentials.initial_cert_config = initial_cert_config + credentials.cert_config_fetcher = cert_config_fetcher + cdef grpc_ssl_server_credentials_options* c_options = NULL + c_options = grpc_ssl_server_credentials_create_options_using_config_fetcher( + GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY + if force_client_auth else + GRPC_SSL_DONT_REQUEST_CLIENT_CERTIFICATE, + _server_cert_config_fetcher_wrapper, + <void*>credentials) + # C-core assumes ownership of c_options + credentials.c_credentials = grpc_ssl_server_credentials_create_with_options(c_options) + return credentials diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi index f115106e60..660263fc09 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/grpc.pxi @@ -391,6 +391,42 @@ cdef extern from "grpc/grpc_security.h": GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_BUT_DONT_VERIFY GRPC_SSL_REQUEST_AND_REQUIRE_CLIENT_CERTIFICATE_AND_VERIFY + ctypedef enum grpc_ssl_certificate_config_reload_status: + GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED + GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW + GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL + + ctypedef struct grpc_ssl_server_certificate_config: + # We don't care about the internals + pass + + ctypedef struct grpc_ssl_server_credentials_options: + # We don't care about the internals + pass + + grpc_ssl_server_certificate_config * grpc_ssl_server_certificate_config_create( + const char *pem_root_certs, + const grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs, + size_t num_key_cert_pairs) + + void grpc_ssl_server_certificate_config_destroy(grpc_ssl_server_certificate_config *config) + + ctypedef grpc_ssl_certificate_config_reload_status (*grpc_ssl_server_certificate_config_callback)( + void *user_data, + grpc_ssl_server_certificate_config **config) + + grpc_ssl_server_credentials_options *grpc_ssl_server_credentials_create_options_using_config( + grpc_ssl_client_certificate_request_type client_certificate_request, + grpc_ssl_server_certificate_config *certificate_config) + + grpc_ssl_server_credentials_options* grpc_ssl_server_credentials_create_options_using_config_fetcher( + grpc_ssl_client_certificate_request_type client_certificate_request, + grpc_ssl_server_certificate_config_callback cb, + void *user_data) + + grpc_server_credentials *grpc_ssl_server_credentials_create_with_options( + grpc_ssl_server_credentials_options *options) + ctypedef struct grpc_ssl_pem_key_cert_pair: const char *private_key const char *certificate_chain "cert_chain" @@ -440,10 +476,6 @@ cdef extern from "grpc/grpc_security.h": # We don't care about the internals (and in fact don't know them) pass - grpc_server_credentials *grpc_ssl_server_credentials_create( - const char *pem_root_certs, - grpc_ssl_pem_key_cert_pair *pem_key_cert_pairs, - size_t num_key_cert_pairs, int force_client_auth, void *reserved) void grpc_server_credentials_release(grpc_server_credentials *creds) nogil int grpc_server_add_secure_http2_port(grpc_server *server, const char *addr, diff --git a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi index b8db27469f..5f3405936c 100644 --- a/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi +++ b/src/python/grpcio/grpc/_cython/_cygrpc/server.pyx.pxi @@ -14,8 +14,46 @@ cimport cpython +import logging import time +import grpc +cdef grpc_ssl_certificate_config_reload_status _server_cert_config_fetcher_wrapper( + void* user_data, grpc_ssl_server_certificate_config **config) with gil: + # This is a credentials.ServerCertificateConfig + cdef ServerCertificateConfig cert_config = None + if not user_data: + raise ValueError('internal error: user_data must be specified') + credentials = <ServerCredentials>user_data + if not credentials.initial_cert_config_fetched: + # C-core is asking for the initial cert config + credentials.initial_cert_config_fetched = True + cert_config = credentials.initial_cert_config._certificate_configuration + else: + user_cb = credentials.cert_config_fetcher + try: + cert_config_wrapper = user_cb() + except Exception: + logging.exception('Error fetching certificate config') + return GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL + if cert_config_wrapper is None: + return GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED + elif not isinstance( + cert_config_wrapper, grpc.ServerCertificateConfiguration): + logging.error( + 'Error fetching certificate configuration: certificate ' + 'configuration must be of type grpc.ServerCertificateConfiguration, ' + 'not %s' % type(cert_config_wrapper).__name__) + return GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL + else: + cert_config = cert_config_wrapper._certificate_configuration + config[0] = <grpc_ssl_server_certificate_config*>cert_config.c_cert_config + # our caller will assume ownership of memory, so we have to recreate + # a copy of c_cert_config here + cert_config.c_cert_config = grpc_ssl_server_certificate_config_create( + cert_config.c_pem_root_certs, cert_config.c_ssl_pem_key_cert_pairs, + cert_config.c_ssl_pem_key_cert_pairs_count) + return GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_NEW cdef class Server: diff --git a/src/python/grpcio_health_checking/setup.py b/src/python/grpcio_health_checking/setup.py index 01d796f4e6..7a2e6f5027 100644 --- a/src/python/grpcio_health_checking/setup.py +++ b/src/python/grpcio_health_checking/setup.py @@ -60,17 +60,8 @@ INSTALL_REQUIRES = ('protobuf>=3.3.0', 'grpcio>={version}'.format(version=grpc_version.VERSION),) try: - # ensure we can load the _pb2_grpc module: - from grpc_health.v1 import health_pb2_grpc as _pb2_grpc - # if we can find the _pb2_grpc module, the package has already been built. - SETUP_REQUIRES = () - COMMAND_CLASS = { - # wire up commands to no-op not to break the external dependencies - 'preprocess': _NoOpCommand, - 'build_package_protos': _NoOpCommand, - } -except ImportError: # we are in the build environment import health_commands as _health_commands + # we are in the build environment, otherwise the above import fails SETUP_REQUIRES = ( 'grpcio-tools=={version}'.format(version=grpc_version.VERSION),) COMMAND_CLASS = { @@ -78,6 +69,13 @@ except ImportError: # we are in the build environment 'preprocess': _health_commands.CopyProtoModules, 'build_package_protos': _health_commands.BuildPackageProtos, } +except ImportError: + SETUP_REQUIRES = () + COMMAND_CLASS = { + # wire up commands to no-op not to break the external dependencies + 'preprocess': _NoOpCommand, + 'build_package_protos': _NoOpCommand, + } setuptools.setup( name='grpcio-health-checking', diff --git a/src/python/grpcio_reflection/setup.py b/src/python/grpcio_reflection/setup.py index ad9e86990f..25312c7c0a 100644 --- a/src/python/grpcio_reflection/setup.py +++ b/src/python/grpcio_reflection/setup.py @@ -61,17 +61,8 @@ INSTALL_REQUIRES = ('protobuf>=3.3.0', 'grpcio>={version}'.format(version=grpc_version.VERSION),) try: - # ensure we can load the _pb2_grpc module: - from grpc_reflection.v1alpha import reflection_pb2_grpc as _pb2_grpc - # if we can find the _pb2_grpc module, the package has already been built. - SETUP_REQUIRES = () - COMMAND_CLASS = { - # wire up commands to no-op not to break the external dependencies - 'preprocess': _NoOpCommand, - 'build_package_protos': _NoOpCommand, - } -except ImportError: # we are in the build environment import reflection_commands as _reflection_commands + # we are in the build environment, otherwise the above import fails SETUP_REQUIRES = ( 'grpcio-tools=={version}'.format(version=grpc_version.VERSION),) COMMAND_CLASS = { @@ -79,6 +70,13 @@ except ImportError: # we are in the build environment 'preprocess': _reflection_commands.CopyProtoModules, 'build_package_protos': _reflection_commands.BuildPackageProtos, } +except ImportError: + SETUP_REQUIRES = () + COMMAND_CLASS = { + # wire up commands to no-op not to break the external dependencies + 'preprocess': _NoOpCommand, + 'build_package_protos': _NoOpCommand, + } setuptools.setup( name='grpcio-reflection', diff --git a/src/python/grpcio_tests/tests/interop/client.py b/src/python/grpcio_tests/tests/interop/client.py index e520c08290..383b5f033d 100644 --- a/src/python/grpcio_tests/tests/interop/client.py +++ b/src/python/grpcio_tests/tests/interop/client.py @@ -29,37 +29,40 @@ def _args(): parser = argparse.ArgumentParser() parser.add_argument( '--server_host', - help='the host to which to connect', + default="localhost", type=str, - default="localhost") + help='the host to which to connect') parser.add_argument( - '--server_port', help='the port to which to connect', type=int) + '--server_port', + type=int, + required=True, + help='the port to which to connect') parser.add_argument( '--test_case', - help='the test case to execute', + default='large_unary', type=str, - default="large_unary") + help='the test case to execute') parser.add_argument( '--use_tls', - help='require a secure connection', default=False, - type=resources.parse_bool) + type=resources.parse_bool, + help='require a secure connection') parser.add_argument( '--use_test_ca', - help='replace platform root CAs with ca.pem', default=False, - type=resources.parse_bool) + type=resources.parse_bool, + help='replace platform root CAs with ca.pem') parser.add_argument( '--server_host_override', default="foo.test.google.fr", - help='the server host to which to claim to connect', - type=str) + type=str, + help='the server host to which to claim to connect') parser.add_argument( - '--oauth_scope', help='scope for OAuth tokens', type=str) + '--oauth_scope', type=str, help='scope for OAuth tokens') parser.add_argument( '--default_service_account', - help='email address of the default service account', - type=str) + type=str, + help='email address of the default service account') return parser.parse_args() diff --git a/src/python/grpcio_tests/tests/interop/server.py b/src/python/grpcio_tests/tests/interop/server.py index 8ad1f5f7cd..eeb41a21d2 100644 --- a/src/python/grpcio_tests/tests/interop/server.py +++ b/src/python/grpcio_tests/tests/interop/server.py @@ -29,12 +29,13 @@ _ONE_DAY_IN_SECONDS = 60 * 60 * 24 def serve(): parser = argparse.ArgumentParser() - parser.add_argument('--port', help='the port on which to serve', type=int) + parser.add_argument( + '--port', type=int, required=True, help='the port on which to serve') parser.add_argument( '--use_tls', - help='require a secure connection', default=False, - type=resources.parse_bool) + type=resources.parse_bool, + help='require a secure connection') args = parser.parse_args() server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) diff --git a/src/python/grpcio_tests/tests/tests.json b/src/python/grpcio_tests/tests/tests.json index 8512d5b96f..e277a3ea1d 100644 --- a/src/python/grpcio_tests/tests/tests.json +++ b/src/python/grpcio_tests/tests/tests.json @@ -46,6 +46,10 @@ "unit._reconnect_test.ReconnectTest", "unit._resource_exhausted_test.ResourceExhaustedTest", "unit._rpc_test.RPCTest", + "unit._server_ssl_cert_config_test.ServerSSLCertConfigFetcherParamsChecks", + "unit._server_ssl_cert_config_test.ServerSSLCertReloadTestCertConfigReuse", + "unit._server_ssl_cert_config_test.ServerSSLCertReloadTestWithClientAuth", + "unit._server_ssl_cert_config_test.ServerSSLCertReloadTestWithoutClientAuth", "unit._thread_cleanup_test.CleanupThreadTest", "unit.beta._beta_features_test.BetaFeaturesTest", "unit.beta._beta_features_test.ContextManagementAndLifecycleTest", diff --git a/src/python/grpcio_tests/tests/unit/_api_test.py b/src/python/grpcio_tests/tests/unit/_api_test.py index a3351aab50..b14e8d5c75 100644 --- a/src/python/grpcio_tests/tests/unit/_api_test.py +++ b/src/python/grpcio_tests/tests/unit/_api_test.py @@ -30,18 +30,20 @@ class AllTest(unittest.TestCase): 'ChannelConnectivity', 'StatusCode', 'RpcError', 'RpcContext', 'Call', 'ChannelCredentials', 'CallCredentials', 'AuthMetadataContext', 'AuthMetadataPluginCallback', - 'AuthMetadataPlugin', 'ServerCredentials', - 'UnaryUnaryMultiCallable', 'UnaryStreamMultiCallable', - 'StreamUnaryMultiCallable', 'StreamStreamMultiCallable', 'Channel', - 'ServicerContext', 'RpcMethodHandler', 'HandlerCallDetails', - 'GenericRpcHandler', 'ServiceRpcHandler', 'Server', - 'unary_unary_rpc_method_handler', 'unary_stream_rpc_method_handler', + 'AuthMetadataPlugin', 'ServerCertificateConfiguration', + 'ServerCredentials', 'UnaryUnaryMultiCallable', + 'UnaryStreamMultiCallable', 'StreamUnaryMultiCallable', + 'StreamStreamMultiCallable', 'Channel', 'ServicerContext', + 'RpcMethodHandler', 'HandlerCallDetails', 'GenericRpcHandler', + 'ServiceRpcHandler', 'Server', 'unary_unary_rpc_method_handler', + 'unary_stream_rpc_method_handler', 'stream_unary_rpc_method_handler', 'stream_stream_rpc_method_handler', 'method_handlers_generic_handler', 'ssl_channel_credentials', 'metadata_call_credentials', 'access_token_call_credentials', 'composite_call_credentials', 'composite_channel_credentials', - 'ssl_server_credentials', 'channel_ready_future', + 'ssl_server_credentials', 'ssl_server_certificate_configuration', + 'dynamic_ssl_server_credentials', 'channel_ready_future', 'insecure_channel', 'secure_channel', 'server',) six.assertCountEqual(self, expected_grpc_code_elements, diff --git a/src/python/grpcio_tests/tests/unit/_server_ssl_cert_config_test.py b/src/python/grpcio_tests/tests/unit/_server_ssl_cert_config_test.py new file mode 100644 index 0000000000..005d16ea75 --- /dev/null +++ b/src/python/grpcio_tests/tests/unit/_server_ssl_cert_config_test.py @@ -0,0 +1,519 @@ +# Copyright 2017 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tests server certificate rotation. + +Here we test various aspects of gRPC Python, and in some cases gRPC +Core by extension, support for server certificate rotation. + +* ServerSSLCertReloadTestWithClientAuth: test ability to rotate + server's SSL cert for use in future channels with clients while not + affecting any existing channel. The server requires client + authentication. + +* ServerSSLCertReloadTestWithoutClientAuth: like + ServerSSLCertReloadTestWithClientAuth except that the server does + not authenticate the client. + +* ServerSSLCertReloadTestCertConfigReuse: tests gRPC Python's ability + to deal with user's reuse of ServerCertificateConfiguration instances. +""" + +import abc +import collections +import os +import six +import threading +import unittest + +from concurrent import futures + +import grpc +from tests.unit import resources +from tests.testing import _application_common +from tests.testing import _server_application +from tests.testing.proto import services_pb2_grpc + +CA_1_PEM = resources.cert_hier_1_root_ca_cert() +CA_2_PEM = resources.cert_hier_2_root_ca_cert() + +CLIENT_KEY_1_PEM = resources.cert_hier_1_client_1_key() +CLIENT_CERT_CHAIN_1_PEM = (resources.cert_hier_1_client_1_cert() + + resources.cert_hier_1_intermediate_ca_cert()) + +CLIENT_KEY_2_PEM = resources.cert_hier_2_client_1_key() +CLIENT_CERT_CHAIN_2_PEM = (resources.cert_hier_2_client_1_cert() + + resources.cert_hier_2_intermediate_ca_cert()) + +SERVER_KEY_1_PEM = resources.cert_hier_1_server_1_key() +SERVER_CERT_CHAIN_1_PEM = (resources.cert_hier_1_server_1_cert() + + resources.cert_hier_1_intermediate_ca_cert()) + +SERVER_KEY_2_PEM = resources.cert_hier_2_server_1_key() +SERVER_CERT_CHAIN_2_PEM = (resources.cert_hier_2_server_1_cert() + + resources.cert_hier_2_intermediate_ca_cert()) + +# for use with the CertConfigFetcher. Roughly a simple custom mock +# implementation +Call = collections.namedtuple('Call', ['did_raise', 'returned_cert_config']) + + +def _create_client_stub( + port, + expect_success, + root_certificates=None, + private_key=None, + certificate_chain=None,): + channel = grpc.secure_channel('localhost:{}'.format(port), + grpc.ssl_channel_credentials( + root_certificates=root_certificates, + private_key=private_key, + certificate_chain=certificate_chain)) + if expect_success: + # per Nathaniel: there's some robustness issue if we start + # using a channel without waiting for it to be actually ready + grpc.channel_ready_future(channel).result(timeout=10) + return services_pb2_grpc.FirstServiceStub(channel) + + +class CertConfigFetcher(object): + + def __init__(self): + self._lock = threading.Lock() + self._calls = [] + self._should_raise = False + self._cert_config = None + + def reset(self): + with self._lock: + self._calls = [] + self._should_raise = False + self._cert_config = None + + def configure(self, should_raise, cert_config): + assert not (should_raise and cert_config), ( + "should not specify both should_raise and a cert_config at the same time" + ) + with self._lock: + self._should_raise = should_raise + self._cert_config = cert_config + + def getCalls(self): + with self._lock: + return self._calls + + def __call__(self): + with self._lock: + if self._should_raise: + self._calls.append(Call(True, None)) + raise ValueError('just for fun, should not affect the test') + else: + self._calls.append(Call(False, self._cert_config)) + return self._cert_config + + +class _ServerSSLCertReloadTest( + six.with_metaclass(abc.ABCMeta, unittest.TestCase)): + + def __init__(self, *args, **kwargs): + super(_ServerSSLCertReloadTest, self).__init__(*args, **kwargs) + self.server = None + self.port = None + + @abc.abstractmethod + def require_client_auth(self): + raise NotImplementedError() + + def setUp(self): + self.server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) + services_pb2_grpc.add_FirstServiceServicer_to_server( + _server_application.FirstServiceServicer(), self.server) + switch_cert_on_client_num = 10 + initial_cert_config = grpc.ssl_server_certificate_configuration( + [(SERVER_KEY_1_PEM, SERVER_CERT_CHAIN_1_PEM)], + root_certificates=CA_2_PEM) + self.cert_config_fetcher = CertConfigFetcher() + server_credentials = grpc.dynamic_ssl_server_credentials( + initial_cert_config, + self.cert_config_fetcher, + require_client_authentication=self.require_client_auth()) + self.port = self.server.add_secure_port('[::]:0', server_credentials) + self.server.start() + + def tearDown(self): + if self.server: + self.server.stop(None) + + def _perform_rpc(self, client_stub, expect_success): + # we don't care about the actual response of the rpc; only + # whether we can perform it or not, and if not, the status + # code must be UNAVAILABLE + request = _application_common.UNARY_UNARY_REQUEST + if expect_success: + response = client_stub.UnUn(request) + self.assertEqual(response, _application_common.UNARY_UNARY_RESPONSE) + else: + with self.assertRaises(grpc.RpcError) as exception_context: + client_stub.UnUn(request) + self.assertEqual(exception_context.exception.code(), + grpc.StatusCode.UNAVAILABLE) + + def _do_one_shot_client_rpc(self, + expect_success, + root_certificates=None, + private_key=None, + certificate_chain=None): + client_stub = _create_client_stub( + self.port, + expect_success, + root_certificates=root_certificates, + private_key=private_key, + certificate_chain=certificate_chain) + self._perform_rpc(client_stub, expect_success) + del client_stub + + def _test(self): + # things should work... + self.cert_config_fetcher.configure(False, None) + self._do_one_shot_client_rpc( + True, + root_certificates=CA_1_PEM, + private_key=CLIENT_KEY_2_PEM, + certificate_chain=CLIENT_CERT_CHAIN_2_PEM) + actual_calls = self.cert_config_fetcher.getCalls() + self.assertEqual(len(actual_calls), 1) + self.assertFalse(actual_calls[0].did_raise) + self.assertIsNone(actual_calls[0].returned_cert_config) + + # client should reject server... + # fails because client trusts ca2 and so will reject server + self.cert_config_fetcher.reset() + self.cert_config_fetcher.configure(False, None) + self._do_one_shot_client_rpc( + False, + root_certificates=CA_2_PEM, + private_key=CLIENT_KEY_2_PEM, + certificate_chain=CLIENT_CERT_CHAIN_2_PEM) + actual_calls = self.cert_config_fetcher.getCalls() + self.assertGreaterEqual(len(actual_calls), 1) + self.assertFalse(actual_calls[0].did_raise) + for i, call in enumerate(actual_calls): + self.assertFalse(call.did_raise, 'i= {}'.format(i)) + self.assertIsNone(call.returned_cert_config, 'i= {}'.format(i)) + + # should work again... + self.cert_config_fetcher.reset() + self.cert_config_fetcher.configure(True, None) + self._do_one_shot_client_rpc( + True, + root_certificates=CA_1_PEM, + private_key=CLIENT_KEY_2_PEM, + certificate_chain=CLIENT_CERT_CHAIN_2_PEM) + actual_calls = self.cert_config_fetcher.getCalls() + self.assertEqual(len(actual_calls), 1) + self.assertTrue(actual_calls[0].did_raise) + self.assertIsNone(actual_calls[0].returned_cert_config) + + # if with_client_auth, then client should be rejected by + # server because client uses key/cert1, but server trusts ca2, + # so server will reject + self.cert_config_fetcher.reset() + self.cert_config_fetcher.configure(False, None) + self._do_one_shot_client_rpc( + not self.require_client_auth(), + root_certificates=CA_1_PEM, + private_key=CLIENT_KEY_1_PEM, + certificate_chain=CLIENT_CERT_CHAIN_1_PEM) + actual_calls = self.cert_config_fetcher.getCalls() + self.assertGreaterEqual(len(actual_calls), 1) + for i, call in enumerate(actual_calls): + self.assertFalse(call.did_raise, 'i= {}'.format(i)) + self.assertIsNone(call.returned_cert_config, 'i= {}'.format(i)) + + # should work again... + self.cert_config_fetcher.reset() + self.cert_config_fetcher.configure(False, None) + self._do_one_shot_client_rpc( + True, + root_certificates=CA_1_PEM, + private_key=CLIENT_KEY_2_PEM, + certificate_chain=CLIENT_CERT_CHAIN_2_PEM) + actual_calls = self.cert_config_fetcher.getCalls() + self.assertEqual(len(actual_calls), 1) + self.assertFalse(actual_calls[0].did_raise) + self.assertIsNone(actual_calls[0].returned_cert_config) + + # now create the "persistent" clients + self.cert_config_fetcher.reset() + self.cert_config_fetcher.configure(False, None) + persistent_client_stub_A = _create_client_stub( + self.port, + True, + root_certificates=CA_1_PEM, + private_key=CLIENT_KEY_2_PEM, + certificate_chain=CLIENT_CERT_CHAIN_2_PEM) + self._perform_rpc(persistent_client_stub_A, True) + actual_calls = self.cert_config_fetcher.getCalls() + self.assertEqual(len(actual_calls), 1) + self.assertFalse(actual_calls[0].did_raise) + self.assertIsNone(actual_calls[0].returned_cert_config) + + self.cert_config_fetcher.reset() + self.cert_config_fetcher.configure(False, None) + persistent_client_stub_B = _create_client_stub( + self.port, + True, + root_certificates=CA_1_PEM, + private_key=CLIENT_KEY_2_PEM, + certificate_chain=CLIENT_CERT_CHAIN_2_PEM) + self._perform_rpc(persistent_client_stub_B, True) + actual_calls = self.cert_config_fetcher.getCalls() + self.assertEqual(len(actual_calls), 1) + self.assertFalse(actual_calls[0].did_raise) + self.assertIsNone(actual_calls[0].returned_cert_config) + + # moment of truth!! client should reject server because the + # server switch cert... + cert_config = grpc.ssl_server_certificate_configuration( + [(SERVER_KEY_2_PEM, SERVER_CERT_CHAIN_2_PEM)], + root_certificates=CA_1_PEM) + self.cert_config_fetcher.reset() + self.cert_config_fetcher.configure(False, cert_config) + self._do_one_shot_client_rpc( + False, + root_certificates=CA_1_PEM, + private_key=CLIENT_KEY_2_PEM, + certificate_chain=CLIENT_CERT_CHAIN_2_PEM) + actual_calls = self.cert_config_fetcher.getCalls() + self.assertGreaterEqual(len(actual_calls), 1) + self.assertFalse(actual_calls[0].did_raise) + for i, call in enumerate(actual_calls): + self.assertFalse(call.did_raise, 'i= {}'.format(i)) + self.assertEqual(call.returned_cert_config, cert_config, + 'i= {}'.format(i)) + + # now should work again... + self.cert_config_fetcher.reset() + self.cert_config_fetcher.configure(False, None) + self._do_one_shot_client_rpc( + True, + root_certificates=CA_2_PEM, + private_key=CLIENT_KEY_1_PEM, + certificate_chain=CLIENT_CERT_CHAIN_1_PEM) + actual_calls = self.cert_config_fetcher.getCalls() + self.assertEqual(len(actual_calls), 1) + self.assertFalse(actual_calls[0].did_raise) + self.assertIsNone(actual_calls[0].returned_cert_config) + + # client should be rejected by server if with_client_auth + self.cert_config_fetcher.reset() + self.cert_config_fetcher.configure(False, None) + self._do_one_shot_client_rpc( + not self.require_client_auth(), + root_certificates=CA_2_PEM, + private_key=CLIENT_KEY_2_PEM, + certificate_chain=CLIENT_CERT_CHAIN_2_PEM) + actual_calls = self.cert_config_fetcher.getCalls() + self.assertGreaterEqual(len(actual_calls), 1) + for i, call in enumerate(actual_calls): + self.assertFalse(call.did_raise, 'i= {}'.format(i)) + self.assertIsNone(call.returned_cert_config, 'i= {}'.format(i)) + + # here client should reject server... + self.cert_config_fetcher.reset() + self.cert_config_fetcher.configure(False, None) + self._do_one_shot_client_rpc( + False, + root_certificates=CA_1_PEM, + private_key=CLIENT_KEY_2_PEM, + certificate_chain=CLIENT_CERT_CHAIN_2_PEM) + actual_calls = self.cert_config_fetcher.getCalls() + self.assertGreaterEqual(len(actual_calls), 1) + for i, call in enumerate(actual_calls): + self.assertFalse(call.did_raise, 'i= {}'.format(i)) + self.assertIsNone(call.returned_cert_config, 'i= {}'.format(i)) + + # persistent clients should continue to work + self.cert_config_fetcher.reset() + self.cert_config_fetcher.configure(False, None) + self._perform_rpc(persistent_client_stub_A, True) + actual_calls = self.cert_config_fetcher.getCalls() + self.assertEqual(len(actual_calls), 0) + + self.cert_config_fetcher.reset() + self.cert_config_fetcher.configure(False, None) + self._perform_rpc(persistent_client_stub_B, True) + actual_calls = self.cert_config_fetcher.getCalls() + self.assertEqual(len(actual_calls), 0) + + +class ServerSSLCertConfigFetcherParamsChecks(unittest.TestCase): + + def test_check_on_initial_config(self): + with self.assertRaises(TypeError): + grpc.dynamic_ssl_server_credentials(None, str) + with self.assertRaises(TypeError): + grpc.dynamic_ssl_server_credentials(1, str) + + def test_check_on_config_fetcher(self): + cert_config = grpc.ssl_server_certificate_configuration( + [(SERVER_KEY_2_PEM, SERVER_CERT_CHAIN_2_PEM)], + root_certificates=CA_1_PEM) + with self.assertRaises(TypeError): + grpc.dynamic_ssl_server_credentials(cert_config, None) + with self.assertRaises(TypeError): + grpc.dynamic_ssl_server_credentials(cert_config, 1) + + +class ServerSSLCertReloadTestWithClientAuth(_ServerSSLCertReloadTest): + + def require_client_auth(self): + return True + + test = _ServerSSLCertReloadTest._test + + +class ServerSSLCertReloadTestWithoutClientAuth(_ServerSSLCertReloadTest): + + def require_client_auth(self): + return False + + test = _ServerSSLCertReloadTest._test + + +class ServerSSLCertReloadTestCertConfigReuse(_ServerSSLCertReloadTest): + """Ensures that `ServerCertificateConfiguration` instances can be reused. + + Because gRPC Core takes ownership of the + `grpc_ssl_server_certificate_config` encapsulated by + `ServerCertificateConfiguration`, this test reuses the same + `ServerCertificateConfiguration` instances multiple times to make sure + gRPC Python takes care of maintaining the validity of + `ServerCertificateConfiguration` instances, so that such instances can be + re-used by user application. + """ + + def require_client_auth(self): + return True + + def setUp(self): + self.server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) + services_pb2_grpc.add_FirstServiceServicer_to_server( + _server_application.FirstServiceServicer(), self.server) + self.cert_config_A = grpc.ssl_server_certificate_configuration( + [(SERVER_KEY_1_PEM, SERVER_CERT_CHAIN_1_PEM)], + root_certificates=CA_2_PEM) + self.cert_config_B = grpc.ssl_server_certificate_configuration( + [(SERVER_KEY_2_PEM, SERVER_CERT_CHAIN_2_PEM)], + root_certificates=CA_1_PEM) + self.cert_config_fetcher = CertConfigFetcher() + server_credentials = grpc.dynamic_ssl_server_credentials( + self.cert_config_A, + self.cert_config_fetcher, + require_client_authentication=True) + self.port = self.server.add_secure_port('[::]:0', server_credentials) + self.server.start() + + def test_cert_config_reuse(self): + + # succeed with A + self.cert_config_fetcher.reset() + self.cert_config_fetcher.configure(False, self.cert_config_A) + self._do_one_shot_client_rpc( + True, + root_certificates=CA_1_PEM, + private_key=CLIENT_KEY_2_PEM, + certificate_chain=CLIENT_CERT_CHAIN_2_PEM) + actual_calls = self.cert_config_fetcher.getCalls() + self.assertEqual(len(actual_calls), 1) + self.assertFalse(actual_calls[0].did_raise) + self.assertEqual(actual_calls[0].returned_cert_config, + self.cert_config_A) + + # fail with A + self.cert_config_fetcher.reset() + self.cert_config_fetcher.configure(False, self.cert_config_A) + self._do_one_shot_client_rpc( + False, + root_certificates=CA_2_PEM, + private_key=CLIENT_KEY_1_PEM, + certificate_chain=CLIENT_CERT_CHAIN_1_PEM) + actual_calls = self.cert_config_fetcher.getCalls() + self.assertGreaterEqual(len(actual_calls), 1) + self.assertFalse(actual_calls[0].did_raise) + for i, call in enumerate(actual_calls): + self.assertFalse(call.did_raise, 'i= {}'.format(i)) + self.assertEqual(call.returned_cert_config, self.cert_config_A, + 'i= {}'.format(i)) + + # succeed again with A + self.cert_config_fetcher.reset() + self.cert_config_fetcher.configure(False, self.cert_config_A) + self._do_one_shot_client_rpc( + True, + root_certificates=CA_1_PEM, + private_key=CLIENT_KEY_2_PEM, + certificate_chain=CLIENT_CERT_CHAIN_2_PEM) + actual_calls = self.cert_config_fetcher.getCalls() + self.assertEqual(len(actual_calls), 1) + self.assertFalse(actual_calls[0].did_raise) + self.assertEqual(actual_calls[0].returned_cert_config, + self.cert_config_A) + + # succeed with B + self.cert_config_fetcher.reset() + self.cert_config_fetcher.configure(False, self.cert_config_B) + self._do_one_shot_client_rpc( + True, + root_certificates=CA_2_PEM, + private_key=CLIENT_KEY_1_PEM, + certificate_chain=CLIENT_CERT_CHAIN_1_PEM) + actual_calls = self.cert_config_fetcher.getCalls() + self.assertEqual(len(actual_calls), 1) + self.assertFalse(actual_calls[0].did_raise) + self.assertEqual(actual_calls[0].returned_cert_config, + self.cert_config_B) + + # fail with B + self.cert_config_fetcher.reset() + self.cert_config_fetcher.configure(False, self.cert_config_B) + self._do_one_shot_client_rpc( + False, + root_certificates=CA_1_PEM, + private_key=CLIENT_KEY_2_PEM, + certificate_chain=CLIENT_CERT_CHAIN_2_PEM) + actual_calls = self.cert_config_fetcher.getCalls() + self.assertGreaterEqual(len(actual_calls), 1) + self.assertFalse(actual_calls[0].did_raise) + for i, call in enumerate(actual_calls): + self.assertFalse(call.did_raise, 'i= {}'.format(i)) + self.assertEqual(call.returned_cert_config, self.cert_config_B, + 'i= {}'.format(i)) + + # succeed again with B + self.cert_config_fetcher.reset() + self.cert_config_fetcher.configure(False, self.cert_config_B) + self._do_one_shot_client_rpc( + True, + root_certificates=CA_2_PEM, + private_key=CLIENT_KEY_1_PEM, + certificate_chain=CLIENT_CERT_CHAIN_1_PEM) + actual_calls = self.cert_config_fetcher.getCalls() + self.assertEqual(len(actual_calls), 1) + self.assertFalse(actual_calls[0].did_raise) + self.assertEqual(actual_calls[0].returned_cert_config, + self.cert_config_B) + + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/src/python/grpcio_tests/tests/unit/credentials/README b/src/python/grpcio_tests/tests/unit/credentials/README deleted file mode 100644 index cb20dcb49f..0000000000 --- a/src/python/grpcio_tests/tests/unit/credentials/README +++ /dev/null @@ -1 +0,0 @@ -These are test keys *NOT* to be used in production. diff --git a/src/python/grpcio_tests/tests/unit/credentials/README.md b/src/python/grpcio_tests/tests/unit/credentials/README.md new file mode 100644 index 0000000000..100b43c1aa --- /dev/null +++ b/src/python/grpcio_tests/tests/unit/credentials/README.md @@ -0,0 +1,15 @@ +These are test keys *NOT* to be used in production. + +The `certificate_hierarchy_1` and `certificate_hierarchy_2` contain +two disjoint but similarly organized certificate hierarchies. Each +contains: + +* The respective root CA cert in `certs/ca.cert.pem` + +* The intermediate CA cert in + `intermediate/certs/intermediate.cert.pem`, signed by the root CA + +* A client cert and a server cert--both signed by the intermediate + CA--in `intermediate/certs/client.cert.pem` and + `intermediate/certs/localhost-1.cert.pem`; the corresponding keys + are in `intermediate/private` diff --git a/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/certs/ca.cert.pem b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/certs/ca.cert.pem new file mode 100644 index 0000000000..604b86fdff --- /dev/null +++ b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/certs/ca.cert.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFZDCCA0ygAwIBAgIJAKfkDFZ6+Ly/MA0GCSqGSIb3DQEBCwUAMD8xCzAJBgNV +BAYTAnVzMQ4wDAYDVQQIDAVkdW1teTEOMAwGA1UECgwFZHVtbXkxEDAOBgNVBAMM +B3Jvb3QgY2EwHhcNMTcxMTAyMDAzNzA1WhcNMzcxMDI4MDAzNzA1WjA/MQswCQYD +VQQGEwJ1czEOMAwGA1UECAwFZHVtbXkxDjAMBgNVBAoMBWR1bW15MRAwDgYDVQQD +DAdyb290IGNhMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxlSUuSbi +o66tT2ZCqu9wNqSX8VhAJkmrAT5y6m2V0VlQ8Gz7ddynW5UVSmtvDNTebZ15FrvO +6Ng7QnwXXNs/dEzl6oMe6AKDZpuWScVkiqH1UYWBkMLRygWCTEYpSTWTpZWk1zxj +DJ2LlIoO1X/ufLyLOfy2a2XEz8ICzJePmqVca6fmfEtCTj1/8FcwCBF6YlUWVzlR +wewjanQo/lorTYbub+Q6LGxPXZ8W0qoKZzLDSD9cnj4pcJzGGFeu9KkNaW4rldZG +t7mTGQqIRc98dDRc9Jb7PqL8tMPLidw1KErUi05ofxggc5vqNnj4xBl6aX6b/EYN +rBLzO2e0FazX6TwNKwwg68vbOanpDq5LVmIUH8bY1zNZ+JPBGO9pXlAA0YwLx86r +R7YhQ431ZpJ2KGnYjVhYnZ2L3NjV3UYX3x5Z3OrDj9hybhucJB48DMQ1+loEabwK +fSUJtcSPc8dCIibxVKidBFgaTPXtHy2MPXuhMhR7PCtMpE7RPUoYmdZLr9FNN1ty +/RAbwBfuhGLbRI2qqJgbOzHJHaOY/FtShfooLz7lt4LIjPTARaNsulG2rbv+m3z9 +mhNjL+peV8gni/xyOYYTbdzZagLrtSHeTWsITvmVt0flMHkjHyv35rw23+hBlSjp +6+S+0MmwuwxqBBccBSlZ9t3Xh1N+vFkb2UkCAwEAAaNjMGEwHQYDVR0OBBYEFJWE +tQwTbTCgZWNN08VSxjdNA0oaMB8GA1UdIwQYMBaAFJWEtQwTbTCgZWNN08VSxjdN +A0oaMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB +CwUAA4ICAQCNjPv/e3ozX1PuN5Tluf0yOmKCxKVCK3Pp98WkDzH4Rp1urEeYrGJL +vBNcl17avOJ0e+zTVYPXFviFbsBsU/zaf+TqEujXabsdL+nvvCJ2mMqYn4wyDFjS +zDNbGH6O0ENZz5NSY0/UGSOHYrYnYB94QRFLbbf0Y3PmBS2eRNjIUnv7ytPZNMi/ +piM+QhPb0Ebyk0rHQZ0RAJaC/wsEtqP8TGV/fx+AzG7zW/zxgPTrgIThy138tLQ+ +xCVDP9H2c17nVP6vjYzKnMZ94uGrGqUzV9vU7EqYl0uZflIf98pLfdKHnQ3heqds +8KQPNKRxVvcc92qv2pQY951wb1fkhLutjHn7TUvrenyAngz+Vs19NxbqLPys1CTw +iaL7vZ8VE/aEDm1tjt5SLM474tpATjk1+qMRaWnii8J5rTodYHP+Zu2GxyIrMiGq +tfNZMYI0tETK1XmEo75E/3s9pmIeQNGKLFp+qL7xrVyN/2ffNv0at8kkqXluunK9 +/Ki0gKYlGFm4Eu8t/nHMqhBx/njYg6pLDuarLW6ftUV7aHd7qKcCWOWqK6gnH/vX +3Apv31eltZBBVN69p3CFy2oMnjrom2Yn/DUXFwrJLBiNJ1dd1JyDxpqpJ74ZQy+/ +pSRWMTRM5SuC7lYARx5rYPmp6cZJWyWRH/3r7bwS699/W965pa5nug== +-----END CERTIFICATE----- diff --git a/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/intermediate/certs/client.cert.pem b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/intermediate/certs/client.cert.pem new file mode 100644 index 0000000000..44bc562599 --- /dev/null +++ b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/intermediate/certs/client.cert.pem @@ -0,0 +1,28 @@ +-----BEGIN CERTIFICATE----- +MIIExzCCAq+gAwIBAgICEAMwDQYJKoZIhvcNAQELBQAwRzELMAkGA1UEBhMCdXMx +DjAMBgNVBAgMBWR1bW15MQ4wDAYDVQQKDAVkdW1teTEYMBYGA1UEAwwPaW50ZXJt +ZWRpYXRlIGNhMB4XDTE3MTEwMjAwMzcwNloXDTI3MTAzMTAwMzcwNlowPjELMAkG +A1UEBhMCdXMxDjAMBgNVBAgMBWR1bW15MQ4wDAYDVQQKDAVkdW1teTEPMA0GA1UE +AwwGY2xpZW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwquL6gtP +R7P9xJK76FTj8fI5TSJa3cAMt1p6CmessjHQq7nQ6DWLGVi4XIt9Sc/1C3rXupOe +90Ok4L0tsuVZH78Wn0EBmBH7S4IbhU9P+aJ9mcigepj1lnxWqoVblgeJYKMOOwAf +pAKUNMWDSm+nCfwE+R5d8d8cfA41Awq1jTRjOVpiJq6aoKfs791a1ZkZde3kFrNV +AVjC06GgA1lZd3sHf94hmLeC+xJztRXVE9e+7dcc7nFDH0t5DIKYBAklsHg77mZa +3IK4aOZew7Lm6diPoMnAzXh2rWpJU6RrEE29gIkJBsF8CL1Ndg9MzssCg6KBjoai +Vt5dJ+4TSEGCOwIDAQABo4HFMIHCMAkGA1UdEwQCMAAwEQYJYIZIAYb4QgEBBAQD +AgWgMDMGCWCGSAGG+EIBDQQmFiRPcGVuU1NMIEdlbmVyYXRlZCBDbGllbnQgQ2Vy +dGlmaWNhdGUwHQYDVR0OBBYEFPeuKDCswk8jaH9tl6X+uXjo+WM1MB8GA1UdIwQY +MBaAFCoqYgmKh3CUafVp+paXxfz+He+FMA4GA1UdDwEB/wQEAwIF4DAdBgNVHSUE +FjAUBggrBgEFBQcDAgYIKwYBBQUHAwQwDQYJKoZIhvcNAQELBQADggIBADYAp8XS +UjMEpX/zVjRWpAAT4HNEJylCV1QNyhBIAyx38A6xJYuFIx966Htd6W9/Rw4sUY6y +F4pOmnLCRxIPqFzzMYcBHSpynlcu5G7zqIod3wYIk7BNlB0AzkZn6yD8bM1y5Plf +myzQVDEGggrDtaW2EehhNIB+wOmbRGITjIcZUEr8V4BlLXkCqOuxauxl82d5/k2w +LAhjOb9d1VW6RT8+Lcn6drhHZdvtSCe8Z27BcXhaQLL8366mhbigKYJt5adD0KOx +pl0MQcoL1Rth5cJEj+1/lgUaxcnvh7TaIIGEx0h3olQXsTxSTypU/nww2Ic41xdG +xl3xvHsxe20IvOOAMRfS/LPW7MCtQ3k0BqB/rAQvmB0r5YITLlMJuBqg+zjYrG/j +s5szSGAz9r0leFuPraeuZA41d9UBTAJMoVrrQZ4xVHMXQi1oz9E9KlIdbO9+spvC +ulfO+D+Z4a9trYSWhnQL2dSHT0+kHqJ/8GipiUNP/yAC76dRpDVR3xtYNr73iw0j +hyDsVjihTD8JBebs3axnt+Bc+FwoCCd6CVcsggfGUNhu/N5LS78b13PcaRzrUNjU +Eh+8cJvMLst+UQzePlyazzpn7jjN3KsBzWUkbnXCtUs2qRMn8f2gZqliDo7JSFvy +WtBSCYpikOivuJSQUlrHQ8NaXeddyWQzLY79 +-----END CERTIFICATE----- diff --git a/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/intermediate/certs/intermediate.cert.pem b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/intermediate/certs/intermediate.cert.pem new file mode 100644 index 0000000000..98e13669c0 --- /dev/null +++ b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/intermediate/certs/intermediate.cert.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFaDCCA1CgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwPzELMAkGA1UEBhMCdXMx +DjAMBgNVBAgMBWR1bW15MQ4wDAYDVQQKDAVkdW1teTEQMA4GA1UEAwwHcm9vdCBj +YTAeFw0xNzExMDIwMDM3MDZaFw0yNzEwMzEwMDM3MDZaMEcxCzAJBgNVBAYTAnVz +MQ4wDAYDVQQIDAVkdW1teTEOMAwGA1UECgwFZHVtbXkxGDAWBgNVBAMMD2ludGVy +bWVkaWF0ZSBjYTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAOOxzve7 +CG2P9SvKfXkJVTXkj4y79JSZ77Kud/TiPfDbHTqZWKuLTXkOCkCCxfpuJvWXnnj5 +1AeLCdKx9hEwJQeU23EXDt1K+RsRyl09SXtPNnJnqHD1mUHRQR28vGX5ctrQzK8J +Sa6/mHW4bX8ol100npbgVMDnM4IDfLYcsv4BXMICGkSHOW6Gn0zJaeHzRVPpmnK/ +0k/GQAcIrU2sZ39kVlVQkWq3HJC28cNL/P04hjh4gAf0evo/k9VrEtxPWYMfiPDt +kOAKueoPv/VTA/zL5t8lyzfhrhxvsJxFg/klapPXK0gLLbhsHyOhnkbrzvmSR4Rw +xubYJ2dDK0DKx+BIZqlFznjP9BvOtvtuVVMyqg9cfgc7J/OjvAguO0f93MLSfIWP +uISqv7Llt/Blvy/xI5owvOKVc/hm3d+5pqjWBC1HkVwo4qugpWmM49dFWl4kc4c7 +ayYUjTmcgoj1ZR89w4Off/bPd1A6gXqSkw2VQfgFF+uOos84fP1V+zPWhp3UDY3P +bFeJtuTdv1gR5w1jCIq6xVJ+UsyDZBaYP7yBBRiNzS1/yXJpnXrvHmDfUeQHLBPR +N0nbMjqXJ1dVpZwydiI0Qx9DnJtOaq/spUreXr8+PU2jeQdCCAN21MB1umr2gZBJ +8MZBStTgE7SDByfGmGfp7B5/s/r4O/rNc4WzAgMBAAGjZjBkMB0GA1UdDgQWBBQq +KmIJiodwlGn1afqWl8X8/h3vhTAfBgNVHSMEGDAWgBSVhLUME20woGVjTdPFUsY3 +TQNKGjASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG +9w0BAQsFAAOCAgEAvzLu/Jc8DlfCltVufC54UZ8DVwUfxdGapNBGv4icrs1wMV3S +xqdaLO+vSp9NeEufi724+/hj4URapW9kSt2TMD7BNJ61QSATZFJajxTFgGa0Zz95 +RBDw8/b5Arz/2pOF4VX+FJ+wqHvoH/2A0T+fwz8hLORhxZHv/cUN6kif4FKCwryQ +s89e694kXkEiJfquvu7DR9hYCLOJwzMOOJiTnjz3hlQg4WGu7Z8ZvqzCM+how1hr +nYbUx6a+HfoUf79AHJB0N1EsEEetJ+omvTdrrayCvy1bHA3QgHlJ28QZIJ7MzX9E +n11/xQ95iTuSp8iWurzjTjbrm7eHnGUh+5QubYLXOzbqKzNZu72w0uvWv6ptIudU +usttltiwW8H9kP0ArWTcZDPhhPfS9impFlhiPDk1wUv2/7g+Zz1OaOb7IiSH0s8y +FG72AB8ucJ5dNa/2q5dJiM8Gm5CbiVw5RXTBjlfTTkNeM6LBI3dRghpPdU7Kbfhn +xYs9vnRZeRMJHrcodLuwVcpY/gyeJ0k5LD6eIPCJmatkYZ122isYyMX8lL2P5aR+ +7d2hhqcOCproOrtThjp6nW2jWTB+R/O2+s6mhKSPgfbY2cdky1Y9FSJxSNayb9B8 +eQ+A29iOHrGVAA0R/rvw119rLAYxjXzToM28owx7IyXKrBaU4RMv5yokgag= +-----END CERTIFICATE----- diff --git a/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/intermediate/certs/localhost-1.cert.pem b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/intermediate/certs/localhost-1.cert.pem new file mode 100644 index 0000000000..f15f1cf5c2 --- /dev/null +++ b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/intermediate/certs/localhost-1.cert.pem @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE----- +MIIFFzCCAv+gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwRzELMAkGA1UEBhMCdXMx +DjAMBgNVBAgMBWR1bW15MQ4wDAYDVQQKDAVkdW1teTEYMBYGA1UEAwwPaW50ZXJt +ZWRpYXRlIGNhMB4XDTE3MTEwMjAwMzcwNloXDTI3MTAzMTAwMzcwNlowTTELMAkG +A1UEBhMCdXMxDjAMBgNVBAgMBWR1bW15MQ4wDAYDVQQKDAVkdW1teTEKMAgGA1UE +CwwBMTESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEArRAy0Nim9P883BAisXdFoKmgHGTtcLH/SzwkkPWTFHz0rHU1Klwz +w8u3OkRyvgoQp7DqkohboNMDwg5VrOOcfKwtM2GZ5jixo+YKvJ25oj8Jfr+40baz +nyWTmOcfoviKrb7u2T9BPEEz5og+lXRDAsTFATGaQDX2LN3Dd9KIw+7sWY+gc3Zi +13HHaWYhtmfJjzFbH1vDxHKCdSdgtPyEhqcJ4OC6wbgp/mQ01VlPAr08kRfkC8mT +TS7atqc410irKViF3sWi4YNPf7LuBrjo75FIIOp+sQgZE6xwOuZ/9bT2Zx/IUtCC +TqzVgZI0s5NVlINtWR6eyyxQ1uDKTs4xrQIDAQABo4IBBTCCAQEwCQYDVR0TBAIw +ADARBglghkgBhvhCAQEEBAMCBkAwMwYJYIZIAYb4QgENBCYWJE9wZW5TU0wgR2Vu +ZXJhdGVkIFNlcnZlciBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUDE8pwi7aELJjvyNT +ed81/KIgGfowaAYDVR0jBGEwX4AUKipiCYqHcJRp9Wn6lpfF/P4d74WhQ6RBMD8x +CzAJBgNVBAYTAnVzMQ4wDAYDVQQIDAVkdW1teTEOMAwGA1UECgwFZHVtbXkxEDAO +BgNVBAMMB3Jvb3QgY2GCAhAAMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggr +BgEFBQcDATANBgkqhkiG9w0BAQsFAAOCAgEA2cvXxJw120Z9oWXyGwR6CH7TcXoy +1i77B1M5j0Krvkjh2/MkEU+JxpZcrhAgZODK9wMPeIUIpJNw2t6Hg+vigpInu7pY +MXR4IA5XLnhGV/hueXa0JLia5FG1TISxr4piW6Jd9P2pOt3ECm3Url/F0OeFF/74 +jGaAlWkbhqWJ9M7Gd4QP2wUNm0P4CwAqS9DC6dnMz+JXTakEUirOpmq7U8UKT+5N +QS1K4WuH671n4MiYye3+UoRYt4zPjOzN+QxzvAMtkUBspPmWD6txmD5tKUYDECqn +0sSbY6ytD30OTHIbICFp40arOffmEEJSriL+uQNPPmvqMxX1G2kUFGm15NLPs8Xa +J7ChrAaJzssN5J3myZUbDfCuxmTkWg+hGvGmxLraVNWc3fzKFmdszSkXrGIdf2HR +gZeFI3w6M4Ktx3KctXlsjwqQTYZI/WwLOEpsrHQBPBLQhISyNw4xjZ4MxK8SFZuQ +IiGps/do0eEgeQ+o3gD1dIXt8YxFIxrgk0pzJONpXGgv/cZrukbLNTBdkTSkIwtx +TXKdiJbO17H24MvW+UxFdsIoJXmfQZWdQC3p+Dl0iP+K80aI6WbaysmToHuOi216 +e49nmiM72Izul2zmBi7Cq2nRQbHAETsFfqC34FzJlx0aP8WS953IBD0jNi1BB+AX +BxwiZ1rPjeMvekI= +-----END CERTIFICATE----- diff --git a/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/intermediate/private/client.key.pem b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/intermediate/private/client.key.pem new file mode 100644 index 0000000000..d8a21632ab --- /dev/null +++ b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/intermediate/private/client.key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEAwquL6gtPR7P9xJK76FTj8fI5TSJa3cAMt1p6CmessjHQq7nQ +6DWLGVi4XIt9Sc/1C3rXupOe90Ok4L0tsuVZH78Wn0EBmBH7S4IbhU9P+aJ9mcig +epj1lnxWqoVblgeJYKMOOwAfpAKUNMWDSm+nCfwE+R5d8d8cfA41Awq1jTRjOVpi +Jq6aoKfs791a1ZkZde3kFrNVAVjC06GgA1lZd3sHf94hmLeC+xJztRXVE9e+7dcc +7nFDH0t5DIKYBAklsHg77mZa3IK4aOZew7Lm6diPoMnAzXh2rWpJU6RrEE29gIkJ +BsF8CL1Ndg9MzssCg6KBjoaiVt5dJ+4TSEGCOwIDAQABAoIBABECKAFU56JeKYfp +Qh20fQ4Amd0RaVsCkpnaf9s037PaAl9eptADDZozVDhRv6qZTtGn8/1LNJJqCJfS +L5H30+egLHvRlDATMh+QyJLHMTegaNTs4IiVoK97QZ84c54SHoCg/ndNNXaA+y35 +K9VvF+sZZ93UN2UQl06Hdz5Cy0YA7L5HIIH3Ezk0ArAw4AarLil5mv4yEz2ApZhm +Tw4I4yNfxB7tZeP+ekNg0XXRL1quA0tGblp+A5fAFfVMDplqqB2d3/KxPR9FSEOi +4PzBZ5Mq2wQBPIaNog5um9qkw6VKxjl5sQGhP1GGTA8iZqR9iM2+xh57xdCZm3g3 +jcr+aPECgYEA42mXTsF/4oBQtU6hh/sOCMWHhxAPstKpQHFMKGYLHKEJ/V1qq0Sd +d0kswAYCmH5G9ookzu5p7pNf0hUUHO5EwelpSZ3FEmtIM+oBwSnDk3vGuadYXN5X +fPuVUla65B1F9SSwapYNBUAiRgrY69Knca2rkTSdcZQaBuWmo684UQcCgYEA2yRE +P23I/9N6AVhKB/zTRtil1AxnTW8o+j7AE4q1o+xly7DS7DT34INaLKLiuG6ylV1F +UoTiqmWqH3A7m3o3Id2AnVf/oDoKV78LCXRF3dJJWvzrPdob2fLlwyjgqXYvmD3O +UH/OFY2blYcAHOYib1Y1AAhHPlXiHA52BYZtnC0CgYAVjjitWmII0ijURrPA8+cM +pcyG3NrgFF++n/6cBbAf8pPD1Er8GPDkEaeQPAGa+r03OTjr9GVOG+IFQ8I4S81w +o/M66x129XxOj2vDJ3ZGUIExr88MXnbkfeRVfasRXET5S5T9RWPOj5mwEe8lyz3b +5J5SkS4rSeJ9rN7yvPUVmQKBgAvrrB67LRzldxSNpfFLSn7nGBYx2oi2zEbYlQA7 +ImhZWqw64S5iLz2yR3x4G9cmhmZjnXrAqcfVIez14PgzLL6V2wI0ID6qCZf+V25b +OdW4M69UZMOHks5HTUJRfe8Z87rXWdq9KQu5GUaIAnSP/D2MNfPbf2yfpV4bV0Yz +qtC9AoGAD3/XXaeGCdV5DPomEmehp84JXU2q/YECRvph46tr4jArG67PCvx2m84B ++W6my4Yi7QJcW4gC0gsdAuxbJl4Y7MCZBnTtNIRCRnHEIciKITJ/+brFln5QUgyn +WnXEPN8q7VjSVXGrljFuLWkzi2Vh8iZDgourNfW+iYDGCJjx1H0= +-----END RSA PRIVATE KEY----- diff --git a/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/intermediate/private/localhost-1.key.pem b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/intermediate/private/localhost-1.key.pem new file mode 100644 index 0000000000..aa83f1a4a2 --- /dev/null +++ b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_1/intermediate/private/localhost-1.key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEogIBAAKCAQEArRAy0Nim9P883BAisXdFoKmgHGTtcLH/SzwkkPWTFHz0rHU1 +Klwzw8u3OkRyvgoQp7DqkohboNMDwg5VrOOcfKwtM2GZ5jixo+YKvJ25oj8Jfr+4 +0baznyWTmOcfoviKrb7u2T9BPEEz5og+lXRDAsTFATGaQDX2LN3Dd9KIw+7sWY+g +c3Zi13HHaWYhtmfJjzFbH1vDxHKCdSdgtPyEhqcJ4OC6wbgp/mQ01VlPAr08kRfk +C8mTTS7atqc410irKViF3sWi4YNPf7LuBrjo75FIIOp+sQgZE6xwOuZ/9bT2Zx/I +UtCCTqzVgZI0s5NVlINtWR6eyyxQ1uDKTs4xrQIDAQABAoIBAC56mDswxH4uAmlT +yA2Da+a/R6n4jTBkDZ1mFKf93Dd3a7rZa6Lpylk+YAI9GdfiGiD/SbB7AKjLo0m9 +0dKx+ngdQbJ39v42obbT9HQ9o/poFaO91+QyvkDytZYuFHgPaidJjRo5e8qz9D1o +v+4hoFGhCQvOB5BRLcFU+cc3etWr5t61sNL/kKCWEDd+MWWsOCHpdhEoWC+o25pC +bhD3FG5xoz+8zL7WdNfke/4twfKoBJ/kq89bfIkl8eKpg387WBQY44RJF7/zVr7a +9dsUuW2y/wVXslCHChjSrxhRlOyy5ssv3EgKh8gPkZ+oeKuONqAGw27nyKyvpjxS +i62K+WECgYEA4oKpIS2D77RCC6rpYIK6KYfbUcNSOtHFvcbf0RH9Oi8vSRYum2ZA +/ITdWSFgWkhT6iOSPuvZlu/EvueWDgNgW1ZVsTMFeapz1+Jwk7JRoBKF1dUEwELh +jdAswdh0MLbgBYs6NXtVVkeK2ocgZtosmt1PUktl566NlyIyhOjH6vkCgYEAw5g0 +cteTpz+noKsfWcbnjyesuQy0caICfZIE01nKv9rKTF8BtCO6Qxj10iM2o00jW7Vl +tZa/igjuqvozXAHBI3xegtrWV05urkjj3FB/Pyuqsx3wxhAdSNchQjdTjwUBQEzp +3ztGSlDTRPpijnpW28lg8Kkr3weryaHvl0xM1VUCgYBqnTN8QU8rgT3g/gYw/fcf +2ylY98V5mAkqBTSN1JjLTTBFh2JSlLOb5/HDpRkUBZ0xxKJuaVaWW67QaHLRj7dH +5oAZErnOBXPXNmbkrfcLkAxclJJS6Gf/9u9KIla2Iy2YjmrMh4uoO65Yo2eV4bVD +A031nzWM8jUE4PzEYEjRCQKBgHDdTj6KiQg0Yg0DUabjcNEZasCpRSJhAyDkdmZi +5OzKWnuxQvFowF1hdM/aQ/f9Vg7gYJ1lLIeBWf9NOv+3f3RzmrHVh2N/vbxSETIb +PSH9l5WeDEauG8fhY66q8EuR7sPk3ftTX98YPqEJ/n8Ktz5COO8GH2umKInEKNXc +UGW1AoGAfENy7vInNv0tzFWPSYdFgesvzo7e8mXyVO8hCyWvY3rxW2on7qfLF3Z9 +fHjd7P9gULja0n1kvmxwUC3u20RrvpY59F4hfi+ji2EiubS9Yhszd2e1CLeRMkln +ojDjnflN32ZbWVHX/i6g3Dabq9JOD0FsOaOlriLMuofdA6jTUFE= +-----END RSA PRIVATE KEY----- diff --git a/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/certs/ca.cert.pem b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/certs/ca.cert.pem new file mode 100644 index 0000000000..212b5862cb --- /dev/null +++ b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/certs/ca.cert.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFZDCCA0ygAwIBAgIJALhSfZ8i0rWTMA0GCSqGSIb3DQEBCwUAMD8xCzAJBgNV +BAYTAnVzMQ4wDAYDVQQIDAVkdW1teTEOMAwGA1UECgwFZHVtbXkxEDAOBgNVBAMM +B3Jvb3QgY2EwHhcNMTcxMTAyMDAzNzU4WhcNMzcxMDI4MDAzNzU4WjA/MQswCQYD +VQQGEwJ1czEOMAwGA1UECAwFZHVtbXkxDjAMBgNVBAoMBWR1bW15MRAwDgYDVQQD +DAdyb290IGNhMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEArHaQ3uyp +wVaVPZDYvy/EJbnP7KbZNPBvKpQCDEqg9B2TPaC8WVjiqT6I88c+KcGuB8nADJdk +o10iZC5AwbrXK4ELSCOvBpxYI5sjoFcv3lZ/oe4e650QO2L/ADmtwLaLYK6rZkwW +Sd90yCGF7ZOTZTJZDwmWEl+ohi+2ow6sRMHKcSKUNfx9G5BB7TOzoqUxqH+moEds +YpjVMEcKzQi2FmbRd+8Dlg2eGqA2V4faprGQwoYz8NqJZGa/KPpRvXE2VjSTDN6b +rJ7mmui6eYN53mZEBRYogyoQHdFXhK02FgyoPEgR/wQlLLbQ+xxOcv02YsOljtza +hl5LjeNUYPMjyhef0QpONp+5NcFhZf38DsSq5EWZLLxPScxwl0lBQkJTjo5ARuFl +Mrv50RYrLwv4ImsiO2ftE7gAX4vNsgcixnCHd6rNzoGimf1+DSvDVJ9ujWo7HPN3 +7ONuoyjsU4mUJJpYXs8zHx5WSxaYiPJRcmG3LjcU5/A+Fs7bkqSrlEjJsG29xDrO +vKR7hH+m6MwcIcXSh9wjjAIvHxAALdU9xaYE3hmVkoxew1mRBsYq34h2vpwGOY5r +0njRQyGGZnVa8qkQd6P3U5fcvLOM8v9QImZqRDS2jAGZXYruo/RIgJpklVX7ZY0+ +CnGdz4YxgLyOBJCDu3aEgL1oON3mg2SsrVMCAwEAAaNjMGEwHQYDVR0OBBYEFOBO +9R6yEY6KOE+aSClwD2BQtWXKMB8GA1UdIwQYMBaAFOBO9R6yEY6KOE+aSClwD2BQ +tWXKMA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEB +CwUAA4ICAQBElio7lLZ2eNt0tDPVSkChksc0IJ2/DpjYjqJzqxF/jZ2oToaAn2Er +9iHl8ggTLB5WrTQxO1ev7qOwQsk9hrgvZ+EQCBTbyDyfNwVjgftH5jdQGdbyrnuJ +yaks1mnd8is5ZZQmmQSd7GVOMTYi/7yH0xI4DHQ386dwnf5eKdoOI7yrVufEMxRx +tB3Wv8KrX4z47zsIO28H/O0T26oUkrd4PEqFwDa5HQr6iG7QQgoGD/DPLgbBudlO +kEos9fmXxiX60RLziKCE/DAxI3YWPvG3WhIWnVj22Oz6apz2pYWpOKwlaihNYrhq +8xc02vIFwKh+t7D+wF4KHfduyMJ/wKVc5dzpNbTgkZePPKSB7QgbsMeRqbdPoXQF +pMuzfj8VCWzpqBeHqE/adSCZhzeTrnyiYavF4T2vkSC5KJu+MHmbZ3nU9bcnnEy+ +24oEv9cEAiYNkvftbD+5ByEtkcBB2uT47sbiGrAeco+GxFGUVqi1IjObqrkIrPzV +OjQhTZV6qgYCOuniJiGfoiMeHqdaDybpqo1bIrxSlvGRNcVoOsKt2/KP1DzW4ARZ +hoRvayU2apHz/T5TAailqAW2MsrjGRaVHQTmeZKag8CKtAcjWzui0J2DnfXxUMn8 +R3ruFu3xJduOT1VghT9L9udvX9YhPCIKVL9+B5eFX9eMV6N7hUnVug== +-----END CERTIFICATE----- diff --git a/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/intermediate/certs/client.cert.pem b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/intermediate/certs/client.cert.pem new file mode 100644 index 0000000000..b6f4280168 --- /dev/null +++ b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/intermediate/certs/client.cert.pem @@ -0,0 +1,28 @@ +-----BEGIN CERTIFICATE----- +MIIExzCCAq+gAwIBAgICEAMwDQYJKoZIhvcNAQELBQAwRzELMAkGA1UEBhMCdXMx +DjAMBgNVBAgMBWR1bW15MQ4wDAYDVQQKDAVkdW1teTEYMBYGA1UEAwwPaW50ZXJt +ZWRpYXRlIGNhMB4XDTE3MTEwMjAwMzgwMFoXDTI3MTAzMTAwMzgwMFowPjELMAkG +A1UEBhMCdXMxDjAMBgNVBAgMBWR1bW15MQ4wDAYDVQQKDAVkdW1teTEPMA0GA1UE +AwwGY2xpZW50MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAyxZFTLqv +Gd9SpFAykyRyLQgHcR5hgD55mz+9fl1OfnMoAc7yTdPVLksDLmeFUlxcvCtLHysJ +klIBX62c6LzbsVcfLg/DPJlQxFnkhJCRKen4fp7x9h62qqJkDFVXsiEFza9L1lsN +4OwqU8i4RRgZ/xggM/s/wVBtynioeW9QADNmKZ1n6HVKkYwdOynbFSggYfFrL3HL +54bC9roZUETin0G5wZ9QU+srgivT0a/KC3ourBYHXAI40iHuuOBf3syDVJ6xId/r +3UO3qkiQ5q7pwglg+8Nx7Q3CFtGZY3ewxSSSDo6BOyweGYMsBaxMO3EyTqecyfXn +3n4XPqwmDalWYQIDAQABo4HFMIHCMAkGA1UdEwQCMAAwEQYJYIZIAYb4QgEBBAQD +AgWgMDMGCWCGSAGG+EIBDQQmFiRPcGVuU1NMIEdlbmVyYXRlZCBDbGllbnQgQ2Vy +dGlmaWNhdGUwHQYDVR0OBBYEFP2bodoNQ1tCNEOALPnygGMUfNI+MB8GA1UdIwQY +MBaAFOWzLd7eBJwSNbzRqNsD7MQDCHg/MA4GA1UdDwEB/wQEAwIF4DAdBgNVHSUE +FjAUBggrBgEFBQcDAgYIKwYBBQUHAwQwDQYJKoZIhvcNAQELBQADggIBAHqUuCLt +olOdR9p/g+KgGPnKuVgMn15Wc2VLCrbbl2P0fuCcNWmnBKqHHgQ1EJEpgnQ2N8m6 +tOGucX7IAzlZj36RP4lN3gZqFRSO/OiTOUYpE6Uv1hYRxeMzAYo5sBdCiiypjV9z +H0Ew5NuWRf2/0nFWoywB9ktHcfD8lRFI3o8zUFXmE2JSUPQtKhW3tBkPPjYBlgzD +RD8cq8dVK9P7i3tUENP+MNHJToNLFBqfA9De6bKnhCWHhZkfB0VeeSm4Ja9HkCg/ +DB+PAKMfbLCH5T8gCpEWxNlvj09r9mn37fNjtJPO/goAcNZNO2AURmb/ZQ4ggdry +xb6lm832qplMUMWx//Ore0faEodlEc5d2kEtmcjj79gAypcLmm74q7CPt7xmniyd +XvNT33S2tkh4dSirpCVwq0xyqOP3ZqTsTjudTveTBaTZNhTbCjDbaV7ga47TcH9/ ++OZ3fQKjt2LAC6162wgEFZf10nUgaAXvSlI74gru93vEwWd8Pd3sWfGwuAFX3oKI +JuwL2kxEuoZQmeRiVJu6KQb+Im7d5CIoWViDmfxcSDJfdtSePTqmDURIx87fw14Z +XBWJP4PiK5PRmG/L0cGiDckmDKm/MuD13Z2I/NMl81GNY/q3WY2O7BmddPpAG5dr +sc5hOqA9+jX08XbxKnfBPYllK5skYMkFH5tN +-----END CERTIFICATE----- diff --git a/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/intermediate/certs/intermediate.cert.pem b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/intermediate/certs/intermediate.cert.pem new file mode 100644 index 0000000000..4305e5333f --- /dev/null +++ b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/intermediate/certs/intermediate.cert.pem @@ -0,0 +1,31 @@ +-----BEGIN CERTIFICATE----- +MIIFaDCCA1CgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwPzELMAkGA1UEBhMCdXMx +DjAMBgNVBAgMBWR1bW15MQ4wDAYDVQQKDAVkdW1teTEQMA4GA1UEAwwHcm9vdCBj +YTAeFw0xNzExMDIwMDM3NTlaFw0yNzEwMzEwMDM3NTlaMEcxCzAJBgNVBAYTAnVz +MQ4wDAYDVQQIDAVkdW1teTEOMAwGA1UECgwFZHVtbXkxGDAWBgNVBAMMD2ludGVy +bWVkaWF0ZSBjYTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKuM2iFz +CCKmbs4uLj/8wjtxf+jFmkwzN4Pps4hqJ3NJqWB326LhzWyqM4WiTAJWE02wSJbS +16RPfbjkVC77OI4+PUdwqxU9vNAP/95w0h6hBSFtkysuT5VVUt5jiY7wnUKgqTCi +MYhYOl+HEP32O4cnxAazkUKKvtyrd4/PvejJ9zz+iYexRnaaGfOFR3co7jQ5QKar +oK4UgJC3mVDZQEMBV0oljkpgVQMAVb4XQU7e+o25JOUkOoK6LdK/b/95khR0jTyD +OBLqd4mCEzxNi+jZ0jLTLPk0c+DnGmRfoNUxnFb40R8QnEIEKwf+JKyl6p89oqOl +pvIZFLZlUWIS4qL+993l1SCqPkWJOAdTg+s/Zh6DeAOhrUn9/wk0aQwZrK7wQQLJ +4GGhxC/FfuUGsLqZszAVkP8jDEWnzhN2rw3V+C7v6lj4qHhUwqGHuYzCx2Hxl+B8 +UyBmZb9gXKVUtAvaZjaL2PDj1ZAxT0KVMlw1ZVrZu45OsHNQuBx/4uIAt6Rga8yt +av1lsq+hFqwI4bU/oZC/oPMacOsB4qEkAA1101WjMc5bg6JOPWobwIqmUXQR1WJE +j30e99HCpk1Cc2+9sUCzNu8KvU5kUY2K90zwqProvj5IfMuDetAVXsEjgW+ZqSho +UMIpJ2M/hzAFl8Z5IRlG+YNfZNXl0FqJ5LzLAgMBAAGjZjBkMB0GA1UdDgQWBBTl +sy3e3gScEjW80ajbA+zEAwh4PzAfBgNVHSMEGDAWgBTgTvUeshGOijhPmkgpcA9g +ULVlyjASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjANBgkqhkiG +9w0BAQsFAAOCAgEAOS7DtliOUPcVosRfyx9dHcSUc3O+uY8uKjSHhdIrxDJm4lwP +Q6lKg5j8CdMVb+sDQmyBkqQIA/6E13corP6R283jO6W8D4A8kjOiQWpXfjW6OcP3 +4rrDEWhCdeLFSNJIYOFkr2qWJpI/k0VpyDnmY0YluS5WbNjg6zTzGelzhFbV7/S1 +cteNAZD0vHD8NmbLVDJjjIY3E/iwzoUzBncLYbDwqyVS1g6utWdSy8LEJxzzqqWJ +pBKlNYILAdh8efBgvotafaxsn2nfjmVmekPn3KcQZuE4Kzv1EQ2PrHpGeJKwh6up +YBL2tav5cAki8bWoGPr2oGmWUf9L2tB57SdWdaY60ifzmQaeGiWPZBSmAz7PRSrz +sR9SMIkBfYVRxXgWwlvr8JYnd2h/Ef5K9fI32nGfje+7/0kPEjNyjehri7sV4Sjt +zzkDiFO+JklrRuLBPMFYOokq6Pcko32FKlE82pe8QkMDS8Sk//9PqCTK9ceB7y6E +NYLNBW/X9SAw/TR5kdRinHHgHyEug7N4+DCU3lU1wl72ZjoiGE7V6c2AssFC2VcE +E+WYxJT1ROJ1/5+U6BKdaIpTwMtRIFRomOEI66iOwOSEwqLIztkqxwpQ7THraWKm +2W5e54u/efapIDcQFnP3E8r7TD0PdIeU6mD28o0+WiK3uL/OZpvyKaHPeFU= +-----END CERTIFICATE----- diff --git a/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/intermediate/certs/localhost-1.cert.pem b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/intermediate/certs/localhost-1.cert.pem new file mode 100644 index 0000000000..2850e42fe9 --- /dev/null +++ b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/intermediate/certs/localhost-1.cert.pem @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE----- +MIIFFzCCAv+gAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwRzELMAkGA1UEBhMCdXMx +DjAMBgNVBAgMBWR1bW15MQ4wDAYDVQQKDAVkdW1teTEYMBYGA1UEAwwPaW50ZXJt +ZWRpYXRlIGNhMB4XDTE3MTEwMjAwMzc1OVoXDTI3MTAzMTAwMzc1OVowTTELMAkG +A1UEBhMCdXMxDjAMBgNVBAgMBWR1bW15MQ4wDAYDVQQKDAVkdW1teTEKMAgGA1UE +CwwBMTESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A +MIIBCgKCAQEAycY/7H1xk3/XHZRopULV7YsOzPIrMG25zoACbpDZxjS0I+2r1c7V +wnvE8TszAkloLi+Skku5CYC7IvVEEEuKuIuV+8M48FJEwlCPge8LPiy18C+npCEd +fgDzCV/O9DfJj6UaiCUayVE7UujXoke7AlKQEJcqvnD/CoTv2Y8jV1A6mPf6CTEI +Sl1BMeFSmeFyvZll+xJ8Up1KfQZxKhtpP1s/rp6ZNlqSs1LM5+vcDHHZ6COTbq7t +2vvcmGDTqeCLsqicBg1kJyMPRtqa0bNPj2bcVtcK0Ndfn6eL2hi+EoBy2nIXi6aG +PpXf85b9bCLd5pZI80nHzFlhdvV+SxqrfwIDAQABo4IBBTCCAQEwCQYDVR0TBAIw +ADARBglghkgBhvhCAQEEBAMCBkAwMwYJYIZIAYb4QgENBCYWJE9wZW5TU0wgR2Vu +ZXJhdGVkIFNlcnZlciBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUoYjECaDz/ZELru/r +jfTB1ShlVrAwaAYDVR0jBGEwX4AU5bMt3t4EnBI1vNGo2wPsxAMIeD+hQ6RBMD8x +CzAJBgNVBAYTAnVzMQ4wDAYDVQQIDAVkdW1teTEOMAwGA1UECgwFZHVtbXkxEDAO +BgNVBAMMB3Jvb3QgY2GCAhAAMA4GA1UdDwEB/wQEAwIFoDATBgNVHSUEDDAKBggr +BgEFBQcDATANBgkqhkiG9w0BAQsFAAOCAgEAiiR2knMMym4O+3fD1KlYSnc2UR3v +0FlRVAsr8wvTlVjJhx7DbRusBNJHWX66mUgK9x5OLnhyvyqlFVhR9AwlnxgfLWz9 +nnACeXzcjQZnKWFQWu8bJSC6Ene6rd1g2acK6SOjxavVbj7JVFnmlHF/naZUzvMl +mJivYta4k7ob8UcX0I5TlJpzglU3UHyyJd5d9zhbF8wqbBq63zR2ovWci4pYCg+F +jYcTGYVZJti3SHO+9/EqTC9x2KDNs3o0+rreJ3GuoonkInKZMQQZJQ6qILvkxlhT +jyU5xlcaJ+0tSaiFK3eF0nXIpFYdZbIHYPCdLjh9AZ2dkFcAgSa/L8+tsVt60k8D +HTO0Hz6dW5D2ckeebZvz5LACMN89gVzrc/rVkeg7QmpSbjkTSLC2KJS53hJzWcEI +3KB73B9iY+ZYytcYBTYLizsAxd5g7j9z8UXrmVQ4mWbh2+xKiG+9aVOzCZ09AYi6 +WVK2aRcMQshgkkqPOloN9OeQNCE8Exf7N/zHsBhygorJXoD/PFgnV1VZm8xkOdiJ +zTb3bpGdmL5+bzzS6wP8Q7pGZGYdlnB7JNO8oMYPPtzX8OOx92BTkPnqJnnRWTpR +SjMEEdQe8K7iXxejQkjaAq5BlwaAOjCjPTqYomECcYjC0WaXsmrPcnZwSqpnHZZ2 +OiINYJub5cvBLNo= +-----END CERTIFICATE----- diff --git a/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/intermediate/private/client.key.pem b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/intermediate/private/client.key.pem new file mode 100644 index 0000000000..a4c5fd4a56 --- /dev/null +++ b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/intermediate/private/client.key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAyxZFTLqvGd9SpFAykyRyLQgHcR5hgD55mz+9fl1OfnMoAc7y +TdPVLksDLmeFUlxcvCtLHysJklIBX62c6LzbsVcfLg/DPJlQxFnkhJCRKen4fp7x +9h62qqJkDFVXsiEFza9L1lsN4OwqU8i4RRgZ/xggM/s/wVBtynioeW9QADNmKZ1n +6HVKkYwdOynbFSggYfFrL3HL54bC9roZUETin0G5wZ9QU+srgivT0a/KC3ourBYH +XAI40iHuuOBf3syDVJ6xId/r3UO3qkiQ5q7pwglg+8Nx7Q3CFtGZY3ewxSSSDo6B +OyweGYMsBaxMO3EyTqecyfXn3n4XPqwmDalWYQIDAQABAoIBAFhIOR3OtVlw3BLz +jdiq6jsrF1kUFNxTzDcxsSUiWIHde1G17Vzpre0uzJY6iBkyb1mZFFHbOpDxtwkp +hmEh3/qqXbJ/RaatGxAP56e81G28+LnKTHJqDYwFhapa2wFjG4u7HSN0d4cEAq5j +Pb9DZ+GdUjpmiON3HBL8+ne3bLZ42uI+DSVe8d3irbqg2rqsiANf0gdimMW4nuI4 +rVxf8HrY43PdQn/Vby+7qLRE3tmIlpbTqJGRtWRjdeBBI91APCrRljjXrKqT6Zpa +E6Daz3YIQvXkIT0q+WkeN1VmQbtRnk7kRsPNp15kSwpHfmv6o/vkO9OUb1n71P2F +wnB0WDECgYEA8iltnKxXnjqwZ/vzIWzcd94j+mdZg/K2/JCOqjwMvpSGCvx2zUmq +Y2nxO2K85AVeOm/Yt87SMODB6AQ9CsrVGEUAzzacvCJDb8oUhaOL5gypnyvZiGCy +snzXfgB+v/xuGekIjs2y7E8h3GG40j0aNQnUY1Fuc6iaeJG4BtjkuQUCgYEA1rE4 +DrTSsUh3hLYQusIHZR8Lecrrd4QUZSMKLkWjobiSTw3m4mglx1s2G4eZ3WuzOyFq +Dp3/b3yfT8prdPBGA6shHNFf+1TO1q1/pIt15dc3sFwxMkuunai8N4QZJRqZLbYq +FkNFkZ20hFHcH/NHDsAsRL/0tJdEmJ2ruP+Qdq0CgYBsdPGKwgVb8J0hdU4nIkJ7 +zRoABFmrJwGdjIDY7Zwnnw2JzhjHSL7vV3ubRVWkKmNReNZvPEoXahJuf7d3JfDa +tczvAV6hRBc/8hnO4Li/h9xQVatP0T83gYJiBIbAJaaKJDyY+Lex7p8TvRCx2Hvs +VUKyWL5HPrQwW9M3/dwyoQKBgQCNQoPA4Wcz8Jt7PZQaXaoh9eBGHab6t3P366s6 +MOXudZQG4f3FgINC/ZfHW1x43PFL+btfrMOyJkxoYqZ7hdB7f3DFFlpR80Y46GVw +7bYAKbBhoPdZwYQ+BhT5bjhhOnQJKK/egBrZKevpmDb+6sIZSYaXIbovzMv8otmn +WrhB7QKBgAdl+KYBQULCUBp8qCQH5sAQoWErpyuD2FNN6LGknpPqn4DdujvwEP0Z +OSvbauLkI0Qc9/MezKPTeYXlFqdbpItwyySJsUkiI3HhVYlBgDkZ7xb6uHIH5E6I +bKgIW5JEf5I7Eu1iurORkXxCCGMkiQmEs4X5kSXXRYgXfNgAD0FX +-----END RSA PRIVATE KEY----- diff --git a/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/intermediate/private/localhost-1.key.pem b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/intermediate/private/localhost-1.key.pem new file mode 100644 index 0000000000..8cba174841 --- /dev/null +++ b/src/python/grpcio_tests/tests/unit/credentials/certificate_hierarchy_2/intermediate/private/localhost-1.key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAycY/7H1xk3/XHZRopULV7YsOzPIrMG25zoACbpDZxjS0I+2r +1c7VwnvE8TszAkloLi+Skku5CYC7IvVEEEuKuIuV+8M48FJEwlCPge8LPiy18C+n +pCEdfgDzCV/O9DfJj6UaiCUayVE7UujXoke7AlKQEJcqvnD/CoTv2Y8jV1A6mPf6 +CTEISl1BMeFSmeFyvZll+xJ8Up1KfQZxKhtpP1s/rp6ZNlqSs1LM5+vcDHHZ6COT +bq7t2vvcmGDTqeCLsqicBg1kJyMPRtqa0bNPj2bcVtcK0Ndfn6eL2hi+EoBy2nIX +i6aGPpXf85b9bCLd5pZI80nHzFlhdvV+SxqrfwIDAQABAoIBAQC022161aoTEtjH +m7n8v56vUCCRFVQfEYsljFohrtZ0sdLyDVwjxkSWEYiizXRYTWIDXALd/N+7o9aZ +bAx5Kq0J45wpUYBc8PDO15T6W0DRlxPxWVXDaSddRQ6TTXxcLREPH2dbtx5+asBo +/Woi/Haki0q0hDr8/p2sWSH/+SwtWpOezGVlrWrkMeIhlBwHZfdHVoZvSx65Uv7x +WU07vsjrbXNDwf+2fmklAQrzhedCeh8loGyjtN3cfrTjrE1zqpEsHnlZcJxe6sRB +1nOqpoUnpZXklDDIYC8EmeubmDJ0jnXOQCDDep3MzVcnZGyF5E/+szaa1NL70Ayj +rbKk1Y3ZAoGBAPy/1ym7Cjl4OGHN2fdkR6iL68ebJozpr+eTSxDNLuBSi5IJxJyG +1+B4+v1u0RwZ3DjrSQsO5DCbZ+DHU6O/DAJK2CxUED+M+G2kRyffailRQmNzjpRG +75dIhSkSRYH8vdvEOnGpeQBZwBcCRH/2YUMlZeSfx9fHJhk1nyUxJeHjAoGBAMxe +k+cBb0zYok+Ww1xTwOdq0PwKj0oDsEg8hOdWc8pH0SlOAB4BI5kmfd1JDMHfRc49 +7tpNqjsPrnlb9xd8l0281Lj2NoVSE5KX1JtsOsKecQsvHH5zRk4eJ3h/mNixpjfe +79Zc/O40T4rWpQRqhat+WHveJC0/ON4AH4uT0BK1AoGBAPcTioCu6YXYsjVaCJPB +IhPwBGOylfL2lxDoel9IVWTRDMOMbPkfEHXNjn6lECJKXW//Af6fZg7mPJwN/wN5 +xYGQLNbYrrGRW2HDUBP4YU1WtHGIC3+EAL+BEztdMzmpGuh1YTSvmSvwkMltXA1D +iz0amArw72lOsz29n3+6FfBFAoGAIpRqMC8k9vq80/yth6TAQifnvo3G2v4uyLo8 +vqv5IaPvNy70hB8rN9G0gEnI99Dgjdoa3SNBB4dKvUwbTgUN0OB/meBHL13I5Af+ +uGGiu6V1eS/6gUbeAX/Gq/PjF99PQareKAZJ4cBGKTbSayHfBjp1nFflBSbqZ13b ++JEFJvUCgYBOs2J2XXamPbI7gu7B2TE9j/62v0SJyoHq2LHMmYUDRuPdPk3eKCt3 +283w+E8XUIFbctaxsbo8msNjjvV22D/Nci3d87aPe8bn1SVto3GnTuwnOpRq3E+3 +wAarqrhiZbGZSCcAkEOk7FlxAwYnCM6paqMxDEMCJ4qChMM42E9ZyQ== +-----END RSA PRIVATE KEY----- diff --git a/src/python/grpcio_tests/tests/unit/resources.py b/src/python/grpcio_tests/tests/unit/resources.py index 823d2307d3..11ef9e8565 100644 --- a/src/python/grpcio_tests/tests/unit/resources.py +++ b/src/python/grpcio_tests/tests/unit/resources.py @@ -11,7 +11,7 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -"""Constants and functions for data used in interoperability testing.""" +"""Constants and functions for data used in testing.""" import os @@ -34,3 +34,81 @@ def private_key(): def certificate_chain(): return pkg_resources.resource_string(__name__, _CERTIFICATE_CHAIN_RESOURCE_PATH) + + +def cert_hier_1_root_ca_cert(): + return pkg_resources.resource_string( + __name__, 'credentials/certificate_hierarchy_1/certs/ca.cert.pem') + + +def cert_hier_1_intermediate_ca_cert(): + return pkg_resources.resource_string( + __name__, + 'credentials/certificate_hierarchy_1/intermediate/certs/intermediate.cert.pem' + ) + + +def cert_hier_1_client_1_key(): + return pkg_resources.resource_string( + __name__, + 'credentials/certificate_hierarchy_1/intermediate/private/client.key.pem' + ) + + +def cert_hier_1_client_1_cert(): + return pkg_resources.resource_string( + __name__, + 'credentials/certificate_hierarchy_1/intermediate/certs/client.cert.pem') + + +def cert_hier_1_server_1_key(): + return pkg_resources.resource_string( + __name__, + 'credentials/certificate_hierarchy_1/intermediate/private/localhost-1.key.pem' + ) + + +def cert_hier_1_server_1_cert(): + return pkg_resources.resource_string( + __name__, + 'credentials/certificate_hierarchy_1/intermediate/certs/localhost-1.cert.pem' + ) + + +def cert_hier_2_root_ca_cert(): + return pkg_resources.resource_string( + __name__, 'credentials/certificate_hierarchy_2/certs/ca.cert.pem') + + +def cert_hier_2_intermediate_ca_cert(): + return pkg_resources.resource_string( + __name__, + 'credentials/certificate_hierarchy_2/intermediate/certs/intermediate.cert.pem' + ) + + +def cert_hier_2_client_1_key(): + return pkg_resources.resource_string( + __name__, + 'credentials/certificate_hierarchy_2/intermediate/private/client.key.pem' + ) + + +def cert_hier_2_client_1_cert(): + return pkg_resources.resource_string( + __name__, + 'credentials/certificate_hierarchy_2/intermediate/certs/client.cert.pem') + + +def cert_hier_2_server_1_key(): + return pkg_resources.resource_string( + __name__, + 'credentials/certificate_hierarchy_2/intermediate/private/localhost-1.key.pem' + ) + + +def cert_hier_2_server_1_cert(): + return pkg_resources.resource_string( + __name__, + 'credentials/certificate_hierarchy_2/intermediate/certs/localhost-1.cert.pem' + ) diff --git a/templates/Makefile.template b/templates/Makefile.template index 0588787910..3eb838857a 100644 --- a/templates/Makefile.template +++ b/templates/Makefile.template @@ -215,7 +215,7 @@ ifeq ($(SYSTEM),Darwin) CXXFLAGS += -stdlib=libc++ endif - % for arg in ['CFLAGS', 'CXXFLAGS', 'CPPFLAGS', 'LDFLAGS', 'DEFINES']: + % for arg in ['CFLAGS', 'CXXFLAGS', 'CPPFLAGS', 'COREFLAGS', 'LDFLAGS', 'DEFINES']: % if defaults.get('global', []).get(arg, None) is not None: ${arg} += ${defaults.get('global').get(arg)} % endif @@ -1268,6 +1268,16 @@ $(Q) mkdir -p `dirname $@` $(Q) $(HOST_CXX) $(HOST_CXXFLAGS) $(HOST_CPPFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $< + $(OBJDIR)/$(CONFIG)/src/core/%.o : src/core/%.cc + $(E) "[CXX] Compiling $<" + $(Q) mkdir -p `dirname $@` + $(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(COREFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $< + + $(OBJDIR)/$(CONFIG)/test/core/%.o : test/core/%.cc + $(E) "[CXX] Compiling $<" + $(Q) mkdir -p `dirname $@` + $(Q) $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(COREFLAGS) -MMD -MF $(addsuffix .dep, $(basename $@)) -c -o $@ $< + $(OBJDIR)/$(CONFIG)/%.o : %.cc $(E) "[CXX] Compiling $<" $(Q) mkdir -p `dirname $@` diff --git a/templates/test/core/surface/public_headers_must_be_c89.c.template b/templates/test/core/surface/public_headers_must_be_c89.c.template index e2d3b1810a..6e4a83666e 100644 --- a/templates/test/core/surface/public_headers_must_be_c89.c.template +++ b/templates/test/core/surface/public_headers_must_be_c89.c.template @@ -48,10 +48,8 @@ #include <stdio.h> int main(int argc, char **argv) { - if(argc == 12345678) { - % for fn in fns: - printf("%lx", (unsigned long) ${fn}); - % endfor - } + % for fn in fns: + printf("%lx", (unsigned long) ${fn}); + % endfor return 0; } diff --git a/test/core/support/BUILD b/test/core/support/BUILD index 9d042fdc9f..69512cd9a9 100644 --- a/test/core/support/BUILD +++ b/test/core/support/BUILD @@ -139,6 +139,16 @@ grpc_cc_test( ) grpc_cc_test( + name = "manual_constructor_test", + srcs = ["manual_constructor_test.cc"], + language = "C++", + deps = [ + "//:gpr", + "//test/core/util:gpr_test_util", + ], +) + +grpc_cc_test( name = "spinlock_test", srcs = ["spinlock_test.cc"], language = "C++", diff --git a/test/core/support/manual_constructor_test.cc b/test/core/support/manual_constructor_test.cc new file mode 100644 index 0000000000..714f8b21a0 --- /dev/null +++ b/test/core/support/manual_constructor_test.cc @@ -0,0 +1,99 @@ +/* + * + * Copyright 2017 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +/* Test of gpr synchronization support. */ + +#include "src/core/lib/support/manual_constructor.h" +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/sync.h> +#include <grpc/support/thd.h> +#include <stdio.h> +#include <stdlib.h> +#include <cstring> +#include "src/core/lib/support/abstract.h" +#include "test/core/util/test_config.h" + +class A { + public: + A() {} + virtual ~A() {} + virtual const char* foo() { return "A_foo"; } + virtual const char* bar() { return "A_bar"; } + GRPC_ABSTRACT_BASE_CLASS +}; + +class B : public A { + public: + B() {} + ~B() {} + const char* foo() override { return "B_foo"; } + char get_junk() { return junk[0]; } + + private: + char junk[1000]; +}; + +class C : public B { + public: + C() {} + ~C() {} + virtual const char* bar() { return "C_bar"; } + char get_more_junk() { return more_junk[0]; } + + private: + char more_junk[1000]; +}; + +class D : public A { + public: + virtual const char* bar() { return "D_bar"; } +}; + +static void basic_test() { + grpc_core::PolymorphicManualConstructor<A, B> poly; + poly.Init<B>(); + GPR_ASSERT(!strcmp(poly->foo(), "B_foo")); + GPR_ASSERT(!strcmp(poly->bar(), "A_bar")); +} + +static void complex_test() { + grpc_core::PolymorphicManualConstructor<A, B, C, D> polyB; + polyB.Init<B>(); + GPR_ASSERT(!strcmp(polyB->foo(), "B_foo")); + GPR_ASSERT(!strcmp(polyB->bar(), "A_bar")); + + grpc_core::PolymorphicManualConstructor<A, B, C, D> polyC; + polyC.Init<C>(); + GPR_ASSERT(!strcmp(polyC->foo(), "B_foo")); + GPR_ASSERT(!strcmp(polyC->bar(), "C_bar")); + + grpc_core::PolymorphicManualConstructor<A, B, C, D> polyD; + polyD.Init<D>(); + GPR_ASSERT(!strcmp(polyD->foo(), "A_foo")); + GPR_ASSERT(!strcmp(polyD->bar(), "D_bar")); +} + +/* ------------------------------------------------- */ + +int main(int argc, char* argv[]) { + grpc_test_init(argc, argv); + basic_test(); + complex_test(); + return 0; +} diff --git a/test/core/surface/public_headers_must_be_c89.c b/test/core/surface/public_headers_must_be_c89.c index db9f902dbf..b5a83c8eed 100644 --- a/test/core/surface/public_headers_must_be_c89.c +++ b/test/core/surface/public_headers_must_be_c89.c @@ -66,288 +66,286 @@ #include <stdio.h> int main(int argc, char **argv) { - if(argc == 12345678) { - printf("%lx", (unsigned long) grpc_compression_algorithm_parse); - printf("%lx", (unsigned long) grpc_compression_algorithm_name); - printf("%lx", (unsigned long) grpc_stream_compression_algorithm_name); - printf("%lx", (unsigned long) grpc_compression_algorithm_for_level); - printf("%lx", (unsigned long) grpc_stream_compression_algorithm_for_level); - printf("%lx", (unsigned long) grpc_compression_options_init); - printf("%lx", (unsigned long) grpc_compression_options_enable_algorithm); - printf("%lx", (unsigned long) grpc_compression_options_disable_algorithm); - printf("%lx", (unsigned long) grpc_compression_options_is_algorithm_enabled); - printf("%lx", (unsigned long) grpc_compression_options_is_stream_compression_algorithm_enabled); - printf("%lx", (unsigned long) grpc_metadata_array_init); - printf("%lx", (unsigned long) grpc_metadata_array_destroy); - printf("%lx", (unsigned long) grpc_call_details_init); - printf("%lx", (unsigned long) grpc_call_details_destroy); - printf("%lx", (unsigned long) grpc_register_plugin); - printf("%lx", (unsigned long) grpc_init); - printf("%lx", (unsigned long) grpc_shutdown); - printf("%lx", (unsigned long) grpc_version_string); - printf("%lx", (unsigned long) grpc_g_stands_for); - printf("%lx", (unsigned long) grpc_completion_queue_factory_lookup); - printf("%lx", (unsigned long) grpc_completion_queue_create_for_next); - printf("%lx", (unsigned long) grpc_completion_queue_create_for_pluck); - printf("%lx", (unsigned long) grpc_completion_queue_create); - printf("%lx", (unsigned long) grpc_completion_queue_next); - printf("%lx", (unsigned long) grpc_completion_queue_pluck); - printf("%lx", (unsigned long) grpc_completion_queue_shutdown); - printf("%lx", (unsigned long) grpc_completion_queue_destroy); - printf("%lx", (unsigned long) grpc_completion_queue_thread_local_cache_init); - printf("%lx", (unsigned long) grpc_completion_queue_thread_local_cache_flush); - printf("%lx", (unsigned long) grpc_alarm_create); - printf("%lx", (unsigned long) grpc_alarm_set); - printf("%lx", (unsigned long) grpc_alarm_cancel); - printf("%lx", (unsigned long) grpc_alarm_destroy); - printf("%lx", (unsigned long) grpc_channel_check_connectivity_state); - printf("%lx", (unsigned long) grpc_channel_num_external_connectivity_watchers); - printf("%lx", (unsigned long) grpc_channel_watch_connectivity_state); - printf("%lx", (unsigned long) grpc_channel_support_connectivity_watcher); - printf("%lx", (unsigned long) grpc_channel_create_call); - printf("%lx", (unsigned long) grpc_channel_ping); - printf("%lx", (unsigned long) grpc_channel_register_call); - printf("%lx", (unsigned long) grpc_channel_create_registered_call); - printf("%lx", (unsigned long) grpc_call_arena_alloc); - printf("%lx", (unsigned long) grpc_call_start_batch); - printf("%lx", (unsigned long) grpc_call_get_peer); - printf("%lx", (unsigned long) grpc_census_call_set_context); - printf("%lx", (unsigned long) grpc_census_call_get_context); - printf("%lx", (unsigned long) grpc_channel_get_target); - printf("%lx", (unsigned long) grpc_channel_get_info); - printf("%lx", (unsigned long) grpc_insecure_channel_create); - printf("%lx", (unsigned long) grpc_lame_client_channel_create); - printf("%lx", (unsigned long) grpc_channel_destroy); - printf("%lx", (unsigned long) grpc_call_cancel); - printf("%lx", (unsigned long) grpc_call_cancel_with_status); - printf("%lx", (unsigned long) grpc_call_ref); - printf("%lx", (unsigned long) grpc_call_unref); - printf("%lx", (unsigned long) grpc_server_request_call); - printf("%lx", (unsigned long) grpc_server_register_method); - printf("%lx", (unsigned long) grpc_server_request_registered_call); - printf("%lx", (unsigned long) grpc_server_create); - printf("%lx", (unsigned long) grpc_server_register_completion_queue); - printf("%lx", (unsigned long) grpc_server_add_insecure_http2_port); - printf("%lx", (unsigned long) grpc_server_start); - printf("%lx", (unsigned long) grpc_server_shutdown_and_notify); - printf("%lx", (unsigned long) grpc_server_cancel_all_calls); - printf("%lx", (unsigned long) grpc_server_destroy); - printf("%lx", (unsigned long) grpc_tracer_set_enabled); - printf("%lx", (unsigned long) grpc_header_key_is_legal); - printf("%lx", (unsigned long) grpc_header_nonbin_value_is_legal); - printf("%lx", (unsigned long) grpc_is_binary_header); - printf("%lx", (unsigned long) grpc_call_error_to_string); - printf("%lx", (unsigned long) grpc_resource_quota_create); - printf("%lx", (unsigned long) grpc_resource_quota_ref); - printf("%lx", (unsigned long) grpc_resource_quota_unref); - printf("%lx", (unsigned long) grpc_resource_quota_resize); - printf("%lx", (unsigned long) grpc_resource_quota_arg_vtable); - printf("%lx", (unsigned long) grpc_auth_property_iterator_next); - printf("%lx", (unsigned long) grpc_auth_context_property_iterator); - printf("%lx", (unsigned long) grpc_auth_context_peer_identity); - printf("%lx", (unsigned long) grpc_auth_context_find_properties_by_name); - printf("%lx", (unsigned long) grpc_auth_context_peer_identity_property_name); - printf("%lx", (unsigned long) grpc_auth_context_peer_is_authenticated); - printf("%lx", (unsigned long) grpc_call_auth_context); - printf("%lx", (unsigned long) grpc_auth_context_release); - printf("%lx", (unsigned long) grpc_auth_context_add_property); - printf("%lx", (unsigned long) grpc_auth_context_add_cstring_property); - printf("%lx", (unsigned long) grpc_auth_context_set_peer_identity_property_name); - printf("%lx", (unsigned long) grpc_channel_credentials_release); - printf("%lx", (unsigned long) grpc_google_default_credentials_create); - printf("%lx", (unsigned long) grpc_set_ssl_roots_override_callback); - printf("%lx", (unsigned long) grpc_ssl_credentials_create); - printf("%lx", (unsigned long) grpc_call_credentials_release); - printf("%lx", (unsigned long) grpc_composite_channel_credentials_create); - printf("%lx", (unsigned long) grpc_composite_call_credentials_create); - printf("%lx", (unsigned long) grpc_google_compute_engine_credentials_create); - printf("%lx", (unsigned long) grpc_max_auth_token_lifetime); - printf("%lx", (unsigned long) grpc_service_account_jwt_access_credentials_create); - printf("%lx", (unsigned long) grpc_google_refresh_token_credentials_create); - printf("%lx", (unsigned long) grpc_access_token_credentials_create); - printf("%lx", (unsigned long) grpc_google_iam_credentials_create); - printf("%lx", (unsigned long) grpc_metadata_credentials_create_from_plugin); - printf("%lx", (unsigned long) grpc_secure_channel_create); - printf("%lx", (unsigned long) grpc_server_credentials_release); - printf("%lx", (unsigned long) grpc_ssl_server_certificate_config_create); - printf("%lx", (unsigned long) grpc_ssl_server_certificate_config_destroy); - printf("%lx", (unsigned long) grpc_ssl_server_credentials_create); - printf("%lx", (unsigned long) grpc_ssl_server_credentials_create_ex); - printf("%lx", (unsigned long) grpc_ssl_server_credentials_create_options_using_config); - printf("%lx", (unsigned long) grpc_ssl_server_credentials_create_options_using_config_fetcher); - printf("%lx", (unsigned long) grpc_ssl_server_credentials_options_destroy); - printf("%lx", (unsigned long) grpc_ssl_server_credentials_create_with_options); - printf("%lx", (unsigned long) grpc_server_add_secure_http2_port); - printf("%lx", (unsigned long) grpc_call_set_credentials); - printf("%lx", (unsigned long) grpc_server_credentials_set_auth_metadata_processor); - printf("%lx", (unsigned long) grpc_raw_byte_buffer_create); - printf("%lx", (unsigned long) grpc_raw_compressed_byte_buffer_create); - printf("%lx", (unsigned long) grpc_byte_buffer_copy); - printf("%lx", (unsigned long) grpc_byte_buffer_length); - printf("%lx", (unsigned long) grpc_byte_buffer_destroy); - printf("%lx", (unsigned long) grpc_byte_buffer_reader_init); - printf("%lx", (unsigned long) grpc_byte_buffer_reader_destroy); - printf("%lx", (unsigned long) grpc_byte_buffer_reader_next); - printf("%lx", (unsigned long) grpc_byte_buffer_reader_readall); - printf("%lx", (unsigned long) grpc_raw_byte_buffer_from_reader); - printf("%lx", (unsigned long) grpc_slice_ref); - printf("%lx", (unsigned long) grpc_slice_unref); - printf("%lx", (unsigned long) grpc_slice_copy); - printf("%lx", (unsigned long) grpc_slice_new); - printf("%lx", (unsigned long) grpc_slice_new_with_user_data); - printf("%lx", (unsigned long) grpc_slice_new_with_len); - printf("%lx", (unsigned long) grpc_slice_malloc); - printf("%lx", (unsigned long) grpc_slice_malloc_large); - printf("%lx", (unsigned long) grpc_slice_intern); - printf("%lx", (unsigned long) grpc_slice_from_copied_string); - printf("%lx", (unsigned long) grpc_slice_from_copied_buffer); - printf("%lx", (unsigned long) grpc_slice_from_static_string); - printf("%lx", (unsigned long) grpc_slice_from_static_buffer); - printf("%lx", (unsigned long) grpc_slice_sub); - printf("%lx", (unsigned long) grpc_slice_sub_no_ref); - printf("%lx", (unsigned long) grpc_slice_split_tail); - printf("%lx", (unsigned long) grpc_slice_split_tail_maybe_ref); - printf("%lx", (unsigned long) grpc_slice_split_head); - printf("%lx", (unsigned long) grpc_empty_slice); - printf("%lx", (unsigned long) grpc_slice_default_hash_impl); - printf("%lx", (unsigned long) grpc_slice_default_eq_impl); - printf("%lx", (unsigned long) grpc_slice_eq); - printf("%lx", (unsigned long) grpc_slice_cmp); - printf("%lx", (unsigned long) grpc_slice_str_cmp); - printf("%lx", (unsigned long) grpc_slice_buf_start_eq); - printf("%lx", (unsigned long) grpc_slice_rchr); - printf("%lx", (unsigned long) grpc_slice_chr); - printf("%lx", (unsigned long) grpc_slice_slice); - printf("%lx", (unsigned long) grpc_slice_hash); - printf("%lx", (unsigned long) grpc_slice_is_equivalent); - printf("%lx", (unsigned long) grpc_slice_dup); - printf("%lx", (unsigned long) grpc_slice_to_c_string); - printf("%lx", (unsigned long) grpc_slice_buffer_init); - printf("%lx", (unsigned long) grpc_slice_buffer_destroy); - printf("%lx", (unsigned long) grpc_slice_buffer_add); - printf("%lx", (unsigned long) grpc_slice_buffer_add_indexed); - printf("%lx", (unsigned long) grpc_slice_buffer_addn); - printf("%lx", (unsigned long) grpc_slice_buffer_tiny_add); - printf("%lx", (unsigned long) grpc_slice_buffer_pop); - printf("%lx", (unsigned long) grpc_slice_buffer_reset_and_unref); - printf("%lx", (unsigned long) grpc_slice_buffer_swap); - printf("%lx", (unsigned long) grpc_slice_buffer_move_into); - printf("%lx", (unsigned long) grpc_slice_buffer_trim_end); - printf("%lx", (unsigned long) grpc_slice_buffer_move_first); - printf("%lx", (unsigned long) grpc_slice_buffer_move_first_no_ref); - printf("%lx", (unsigned long) grpc_slice_buffer_move_first_into_buffer); - printf("%lx", (unsigned long) grpc_slice_buffer_take_first); - printf("%lx", (unsigned long) grpc_slice_buffer_undo_take_first); - printf("%lx", (unsigned long) gpr_malloc); - printf("%lx", (unsigned long) gpr_zalloc); - printf("%lx", (unsigned long) gpr_free); - printf("%lx", (unsigned long) gpr_realloc); - printf("%lx", (unsigned long) gpr_malloc_aligned); - printf("%lx", (unsigned long) gpr_free_aligned); - printf("%lx", (unsigned long) gpr_set_allocation_functions); - printf("%lx", (unsigned long) gpr_get_allocation_functions); - printf("%lx", (unsigned long) gpr_avl_create); - printf("%lx", (unsigned long) gpr_avl_ref); - printf("%lx", (unsigned long) gpr_avl_unref); - printf("%lx", (unsigned long) gpr_avl_add); - printf("%lx", (unsigned long) gpr_avl_remove); - printf("%lx", (unsigned long) gpr_avl_get); - printf("%lx", (unsigned long) gpr_avl_maybe_get); - printf("%lx", (unsigned long) gpr_avl_is_empty); - printf("%lx", (unsigned long) gpr_cmdline_create); - printf("%lx", (unsigned long) gpr_cmdline_add_int); - printf("%lx", (unsigned long) gpr_cmdline_add_flag); - printf("%lx", (unsigned long) gpr_cmdline_add_string); - printf("%lx", (unsigned long) gpr_cmdline_on_extra_arg); - printf("%lx", (unsigned long) gpr_cmdline_set_survive_failure); - printf("%lx", (unsigned long) gpr_cmdline_parse); - printf("%lx", (unsigned long) gpr_cmdline_destroy); - printf("%lx", (unsigned long) gpr_cmdline_usage_string); - printf("%lx", (unsigned long) gpr_cpu_num_cores); - printf("%lx", (unsigned long) gpr_cpu_current_cpu); - printf("%lx", (unsigned long) gpr_histogram_create); - printf("%lx", (unsigned long) gpr_histogram_destroy); - printf("%lx", (unsigned long) gpr_histogram_add); - printf("%lx", (unsigned long) gpr_histogram_merge); - printf("%lx", (unsigned long) gpr_histogram_percentile); - printf("%lx", (unsigned long) gpr_histogram_mean); - printf("%lx", (unsigned long) gpr_histogram_stddev); - printf("%lx", (unsigned long) gpr_histogram_variance); - printf("%lx", (unsigned long) gpr_histogram_maximum); - printf("%lx", (unsigned long) gpr_histogram_minimum); - printf("%lx", (unsigned long) gpr_histogram_count); - printf("%lx", (unsigned long) gpr_histogram_sum); - printf("%lx", (unsigned long) gpr_histogram_sum_of_squares); - printf("%lx", (unsigned long) gpr_histogram_get_contents); - printf("%lx", (unsigned long) gpr_histogram_merge_contents); - printf("%lx", (unsigned long) gpr_join_host_port); - printf("%lx", (unsigned long) gpr_split_host_port); - printf("%lx", (unsigned long) gpr_log_severity_string); - printf("%lx", (unsigned long) gpr_log); - printf("%lx", (unsigned long) gpr_log_message); - printf("%lx", (unsigned long) gpr_set_log_verbosity); - printf("%lx", (unsigned long) gpr_log_verbosity_init); - printf("%lx", (unsigned long) gpr_set_log_function); - printf("%lx", (unsigned long) gpr_strdup); - printf("%lx", (unsigned long) gpr_asprintf); - printf("%lx", (unsigned long) gpr_subprocess_binary_extension); - printf("%lx", (unsigned long) gpr_subprocess_create); - printf("%lx", (unsigned long) gpr_subprocess_destroy); - printf("%lx", (unsigned long) gpr_subprocess_join); - printf("%lx", (unsigned long) gpr_subprocess_interrupt); - printf("%lx", (unsigned long) gpr_mu_init); - printf("%lx", (unsigned long) gpr_mu_destroy); - printf("%lx", (unsigned long) gpr_mu_lock); - printf("%lx", (unsigned long) gpr_mu_unlock); - printf("%lx", (unsigned long) gpr_mu_trylock); - printf("%lx", (unsigned long) gpr_cv_init); - printf("%lx", (unsigned long) gpr_cv_destroy); - printf("%lx", (unsigned long) gpr_cv_wait); - printf("%lx", (unsigned long) gpr_cv_signal); - printf("%lx", (unsigned long) gpr_cv_broadcast); - printf("%lx", (unsigned long) gpr_once_init); - printf("%lx", (unsigned long) gpr_event_init); - printf("%lx", (unsigned long) gpr_event_set); - printf("%lx", (unsigned long) gpr_event_get); - printf("%lx", (unsigned long) gpr_event_wait); - printf("%lx", (unsigned long) gpr_ref_init); - printf("%lx", (unsigned long) gpr_ref); - printf("%lx", (unsigned long) gpr_ref_non_zero); - printf("%lx", (unsigned long) gpr_refn); - printf("%lx", (unsigned long) gpr_unref); - printf("%lx", (unsigned long) gpr_ref_is_unique); - printf("%lx", (unsigned long) gpr_stats_init); - printf("%lx", (unsigned long) gpr_stats_inc); - printf("%lx", (unsigned long) gpr_stats_read); - printf("%lx", (unsigned long) gpr_thd_new); - printf("%lx", (unsigned long) gpr_thd_options_default); - printf("%lx", (unsigned long) gpr_thd_options_set_detached); - printf("%lx", (unsigned long) gpr_thd_options_set_joinable); - printf("%lx", (unsigned long) gpr_thd_options_is_detached); - printf("%lx", (unsigned long) gpr_thd_options_is_joinable); - printf("%lx", (unsigned long) gpr_thd_currentid); - printf("%lx", (unsigned long) gpr_thd_join); - printf("%lx", (unsigned long) gpr_time_0); - printf("%lx", (unsigned long) gpr_inf_future); - printf("%lx", (unsigned long) gpr_inf_past); - printf("%lx", (unsigned long) gpr_time_init); - printf("%lx", (unsigned long) gpr_now); - printf("%lx", (unsigned long) gpr_convert_clock_type); - printf("%lx", (unsigned long) gpr_time_cmp); - printf("%lx", (unsigned long) gpr_time_max); - printf("%lx", (unsigned long) gpr_time_min); - printf("%lx", (unsigned long) gpr_time_add); - printf("%lx", (unsigned long) gpr_time_sub); - printf("%lx", (unsigned long) gpr_time_from_micros); - printf("%lx", (unsigned long) gpr_time_from_nanos); - printf("%lx", (unsigned long) gpr_time_from_millis); - printf("%lx", (unsigned long) gpr_time_from_seconds); - printf("%lx", (unsigned long) gpr_time_from_minutes); - printf("%lx", (unsigned long) gpr_time_from_hours); - printf("%lx", (unsigned long) gpr_time_to_millis); - printf("%lx", (unsigned long) gpr_time_similar); - printf("%lx", (unsigned long) gpr_sleep_until); - printf("%lx", (unsigned long) gpr_timespec_to_micros); - } + printf("%lx", (unsigned long) grpc_compression_algorithm_parse); + printf("%lx", (unsigned long) grpc_compression_algorithm_name); + printf("%lx", (unsigned long) grpc_stream_compression_algorithm_name); + printf("%lx", (unsigned long) grpc_compression_algorithm_for_level); + printf("%lx", (unsigned long) grpc_stream_compression_algorithm_for_level); + printf("%lx", (unsigned long) grpc_compression_options_init); + printf("%lx", (unsigned long) grpc_compression_options_enable_algorithm); + printf("%lx", (unsigned long) grpc_compression_options_disable_algorithm); + printf("%lx", (unsigned long) grpc_compression_options_is_algorithm_enabled); + printf("%lx", (unsigned long) grpc_compression_options_is_stream_compression_algorithm_enabled); + printf("%lx", (unsigned long) grpc_metadata_array_init); + printf("%lx", (unsigned long) grpc_metadata_array_destroy); + printf("%lx", (unsigned long) grpc_call_details_init); + printf("%lx", (unsigned long) grpc_call_details_destroy); + printf("%lx", (unsigned long) grpc_register_plugin); + printf("%lx", (unsigned long) grpc_init); + printf("%lx", (unsigned long) grpc_shutdown); + printf("%lx", (unsigned long) grpc_version_string); + printf("%lx", (unsigned long) grpc_g_stands_for); + printf("%lx", (unsigned long) grpc_completion_queue_factory_lookup); + printf("%lx", (unsigned long) grpc_completion_queue_create_for_next); + printf("%lx", (unsigned long) grpc_completion_queue_create_for_pluck); + printf("%lx", (unsigned long) grpc_completion_queue_create); + printf("%lx", (unsigned long) grpc_completion_queue_next); + printf("%lx", (unsigned long) grpc_completion_queue_pluck); + printf("%lx", (unsigned long) grpc_completion_queue_shutdown); + printf("%lx", (unsigned long) grpc_completion_queue_destroy); + printf("%lx", (unsigned long) grpc_completion_queue_thread_local_cache_init); + printf("%lx", (unsigned long) grpc_completion_queue_thread_local_cache_flush); + printf("%lx", (unsigned long) grpc_alarm_create); + printf("%lx", (unsigned long) grpc_alarm_set); + printf("%lx", (unsigned long) grpc_alarm_cancel); + printf("%lx", (unsigned long) grpc_alarm_destroy); + printf("%lx", (unsigned long) grpc_channel_check_connectivity_state); + printf("%lx", (unsigned long) grpc_channel_num_external_connectivity_watchers); + printf("%lx", (unsigned long) grpc_channel_watch_connectivity_state); + printf("%lx", (unsigned long) grpc_channel_support_connectivity_watcher); + printf("%lx", (unsigned long) grpc_channel_create_call); + printf("%lx", (unsigned long) grpc_channel_ping); + printf("%lx", (unsigned long) grpc_channel_register_call); + printf("%lx", (unsigned long) grpc_channel_create_registered_call); + printf("%lx", (unsigned long) grpc_call_arena_alloc); + printf("%lx", (unsigned long) grpc_call_start_batch); + printf("%lx", (unsigned long) grpc_call_get_peer); + printf("%lx", (unsigned long) grpc_census_call_set_context); + printf("%lx", (unsigned long) grpc_census_call_get_context); + printf("%lx", (unsigned long) grpc_channel_get_target); + printf("%lx", (unsigned long) grpc_channel_get_info); + printf("%lx", (unsigned long) grpc_insecure_channel_create); + printf("%lx", (unsigned long) grpc_lame_client_channel_create); + printf("%lx", (unsigned long) grpc_channel_destroy); + printf("%lx", (unsigned long) grpc_call_cancel); + printf("%lx", (unsigned long) grpc_call_cancel_with_status); + printf("%lx", (unsigned long) grpc_call_ref); + printf("%lx", (unsigned long) grpc_call_unref); + printf("%lx", (unsigned long) grpc_server_request_call); + printf("%lx", (unsigned long) grpc_server_register_method); + printf("%lx", (unsigned long) grpc_server_request_registered_call); + printf("%lx", (unsigned long) grpc_server_create); + printf("%lx", (unsigned long) grpc_server_register_completion_queue); + printf("%lx", (unsigned long) grpc_server_add_insecure_http2_port); + printf("%lx", (unsigned long) grpc_server_start); + printf("%lx", (unsigned long) grpc_server_shutdown_and_notify); + printf("%lx", (unsigned long) grpc_server_cancel_all_calls); + printf("%lx", (unsigned long) grpc_server_destroy); + printf("%lx", (unsigned long) grpc_tracer_set_enabled); + printf("%lx", (unsigned long) grpc_header_key_is_legal); + printf("%lx", (unsigned long) grpc_header_nonbin_value_is_legal); + printf("%lx", (unsigned long) grpc_is_binary_header); + printf("%lx", (unsigned long) grpc_call_error_to_string); + printf("%lx", (unsigned long) grpc_resource_quota_create); + printf("%lx", (unsigned long) grpc_resource_quota_ref); + printf("%lx", (unsigned long) grpc_resource_quota_unref); + printf("%lx", (unsigned long) grpc_resource_quota_resize); + printf("%lx", (unsigned long) grpc_resource_quota_arg_vtable); + printf("%lx", (unsigned long) grpc_auth_property_iterator_next); + printf("%lx", (unsigned long) grpc_auth_context_property_iterator); + printf("%lx", (unsigned long) grpc_auth_context_peer_identity); + printf("%lx", (unsigned long) grpc_auth_context_find_properties_by_name); + printf("%lx", (unsigned long) grpc_auth_context_peer_identity_property_name); + printf("%lx", (unsigned long) grpc_auth_context_peer_is_authenticated); + printf("%lx", (unsigned long) grpc_call_auth_context); + printf("%lx", (unsigned long) grpc_auth_context_release); + printf("%lx", (unsigned long) grpc_auth_context_add_property); + printf("%lx", (unsigned long) grpc_auth_context_add_cstring_property); + printf("%lx", (unsigned long) grpc_auth_context_set_peer_identity_property_name); + printf("%lx", (unsigned long) grpc_channel_credentials_release); + printf("%lx", (unsigned long) grpc_google_default_credentials_create); + printf("%lx", (unsigned long) grpc_set_ssl_roots_override_callback); + printf("%lx", (unsigned long) grpc_ssl_credentials_create); + printf("%lx", (unsigned long) grpc_call_credentials_release); + printf("%lx", (unsigned long) grpc_composite_channel_credentials_create); + printf("%lx", (unsigned long) grpc_composite_call_credentials_create); + printf("%lx", (unsigned long) grpc_google_compute_engine_credentials_create); + printf("%lx", (unsigned long) grpc_max_auth_token_lifetime); + printf("%lx", (unsigned long) grpc_service_account_jwt_access_credentials_create); + printf("%lx", (unsigned long) grpc_google_refresh_token_credentials_create); + printf("%lx", (unsigned long) grpc_access_token_credentials_create); + printf("%lx", (unsigned long) grpc_google_iam_credentials_create); + printf("%lx", (unsigned long) grpc_metadata_credentials_create_from_plugin); + printf("%lx", (unsigned long) grpc_secure_channel_create); + printf("%lx", (unsigned long) grpc_server_credentials_release); + printf("%lx", (unsigned long) grpc_ssl_server_certificate_config_create); + printf("%lx", (unsigned long) grpc_ssl_server_certificate_config_destroy); + printf("%lx", (unsigned long) grpc_ssl_server_credentials_create); + printf("%lx", (unsigned long) grpc_ssl_server_credentials_create_ex); + printf("%lx", (unsigned long) grpc_ssl_server_credentials_create_options_using_config); + printf("%lx", (unsigned long) grpc_ssl_server_credentials_create_options_using_config_fetcher); + printf("%lx", (unsigned long) grpc_ssl_server_credentials_options_destroy); + printf("%lx", (unsigned long) grpc_ssl_server_credentials_create_with_options); + printf("%lx", (unsigned long) grpc_server_add_secure_http2_port); + printf("%lx", (unsigned long) grpc_call_set_credentials); + printf("%lx", (unsigned long) grpc_server_credentials_set_auth_metadata_processor); + printf("%lx", (unsigned long) grpc_raw_byte_buffer_create); + printf("%lx", (unsigned long) grpc_raw_compressed_byte_buffer_create); + printf("%lx", (unsigned long) grpc_byte_buffer_copy); + printf("%lx", (unsigned long) grpc_byte_buffer_length); + printf("%lx", (unsigned long) grpc_byte_buffer_destroy); + printf("%lx", (unsigned long) grpc_byte_buffer_reader_init); + printf("%lx", (unsigned long) grpc_byte_buffer_reader_destroy); + printf("%lx", (unsigned long) grpc_byte_buffer_reader_next); + printf("%lx", (unsigned long) grpc_byte_buffer_reader_readall); + printf("%lx", (unsigned long) grpc_raw_byte_buffer_from_reader); + printf("%lx", (unsigned long) grpc_slice_ref); + printf("%lx", (unsigned long) grpc_slice_unref); + printf("%lx", (unsigned long) grpc_slice_copy); + printf("%lx", (unsigned long) grpc_slice_new); + printf("%lx", (unsigned long) grpc_slice_new_with_user_data); + printf("%lx", (unsigned long) grpc_slice_new_with_len); + printf("%lx", (unsigned long) grpc_slice_malloc); + printf("%lx", (unsigned long) grpc_slice_malloc_large); + printf("%lx", (unsigned long) grpc_slice_intern); + printf("%lx", (unsigned long) grpc_slice_from_copied_string); + printf("%lx", (unsigned long) grpc_slice_from_copied_buffer); + printf("%lx", (unsigned long) grpc_slice_from_static_string); + printf("%lx", (unsigned long) grpc_slice_from_static_buffer); + printf("%lx", (unsigned long) grpc_slice_sub); + printf("%lx", (unsigned long) grpc_slice_sub_no_ref); + printf("%lx", (unsigned long) grpc_slice_split_tail); + printf("%lx", (unsigned long) grpc_slice_split_tail_maybe_ref); + printf("%lx", (unsigned long) grpc_slice_split_head); + printf("%lx", (unsigned long) grpc_empty_slice); + printf("%lx", (unsigned long) grpc_slice_default_hash_impl); + printf("%lx", (unsigned long) grpc_slice_default_eq_impl); + printf("%lx", (unsigned long) grpc_slice_eq); + printf("%lx", (unsigned long) grpc_slice_cmp); + printf("%lx", (unsigned long) grpc_slice_str_cmp); + printf("%lx", (unsigned long) grpc_slice_buf_start_eq); + printf("%lx", (unsigned long) grpc_slice_rchr); + printf("%lx", (unsigned long) grpc_slice_chr); + printf("%lx", (unsigned long) grpc_slice_slice); + printf("%lx", (unsigned long) grpc_slice_hash); + printf("%lx", (unsigned long) grpc_slice_is_equivalent); + printf("%lx", (unsigned long) grpc_slice_dup); + printf("%lx", (unsigned long) grpc_slice_to_c_string); + printf("%lx", (unsigned long) grpc_slice_buffer_init); + printf("%lx", (unsigned long) grpc_slice_buffer_destroy); + printf("%lx", (unsigned long) grpc_slice_buffer_add); + printf("%lx", (unsigned long) grpc_slice_buffer_add_indexed); + printf("%lx", (unsigned long) grpc_slice_buffer_addn); + printf("%lx", (unsigned long) grpc_slice_buffer_tiny_add); + printf("%lx", (unsigned long) grpc_slice_buffer_pop); + printf("%lx", (unsigned long) grpc_slice_buffer_reset_and_unref); + printf("%lx", (unsigned long) grpc_slice_buffer_swap); + printf("%lx", (unsigned long) grpc_slice_buffer_move_into); + printf("%lx", (unsigned long) grpc_slice_buffer_trim_end); + printf("%lx", (unsigned long) grpc_slice_buffer_move_first); + printf("%lx", (unsigned long) grpc_slice_buffer_move_first_no_ref); + printf("%lx", (unsigned long) grpc_slice_buffer_move_first_into_buffer); + printf("%lx", (unsigned long) grpc_slice_buffer_take_first); + printf("%lx", (unsigned long) grpc_slice_buffer_undo_take_first); + printf("%lx", (unsigned long) gpr_malloc); + printf("%lx", (unsigned long) gpr_zalloc); + printf("%lx", (unsigned long) gpr_free); + printf("%lx", (unsigned long) gpr_realloc); + printf("%lx", (unsigned long) gpr_malloc_aligned); + printf("%lx", (unsigned long) gpr_free_aligned); + printf("%lx", (unsigned long) gpr_set_allocation_functions); + printf("%lx", (unsigned long) gpr_get_allocation_functions); + printf("%lx", (unsigned long) gpr_avl_create); + printf("%lx", (unsigned long) gpr_avl_ref); + printf("%lx", (unsigned long) gpr_avl_unref); + printf("%lx", (unsigned long) gpr_avl_add); + printf("%lx", (unsigned long) gpr_avl_remove); + printf("%lx", (unsigned long) gpr_avl_get); + printf("%lx", (unsigned long) gpr_avl_maybe_get); + printf("%lx", (unsigned long) gpr_avl_is_empty); + printf("%lx", (unsigned long) gpr_cmdline_create); + printf("%lx", (unsigned long) gpr_cmdline_add_int); + printf("%lx", (unsigned long) gpr_cmdline_add_flag); + printf("%lx", (unsigned long) gpr_cmdline_add_string); + printf("%lx", (unsigned long) gpr_cmdline_on_extra_arg); + printf("%lx", (unsigned long) gpr_cmdline_set_survive_failure); + printf("%lx", (unsigned long) gpr_cmdline_parse); + printf("%lx", (unsigned long) gpr_cmdline_destroy); + printf("%lx", (unsigned long) gpr_cmdline_usage_string); + printf("%lx", (unsigned long) gpr_cpu_num_cores); + printf("%lx", (unsigned long) gpr_cpu_current_cpu); + printf("%lx", (unsigned long) gpr_histogram_create); + printf("%lx", (unsigned long) gpr_histogram_destroy); + printf("%lx", (unsigned long) gpr_histogram_add); + printf("%lx", (unsigned long) gpr_histogram_merge); + printf("%lx", (unsigned long) gpr_histogram_percentile); + printf("%lx", (unsigned long) gpr_histogram_mean); + printf("%lx", (unsigned long) gpr_histogram_stddev); + printf("%lx", (unsigned long) gpr_histogram_variance); + printf("%lx", (unsigned long) gpr_histogram_maximum); + printf("%lx", (unsigned long) gpr_histogram_minimum); + printf("%lx", (unsigned long) gpr_histogram_count); + printf("%lx", (unsigned long) gpr_histogram_sum); + printf("%lx", (unsigned long) gpr_histogram_sum_of_squares); + printf("%lx", (unsigned long) gpr_histogram_get_contents); + printf("%lx", (unsigned long) gpr_histogram_merge_contents); + printf("%lx", (unsigned long) gpr_join_host_port); + printf("%lx", (unsigned long) gpr_split_host_port); + printf("%lx", (unsigned long) gpr_log_severity_string); + printf("%lx", (unsigned long) gpr_log); + printf("%lx", (unsigned long) gpr_log_message); + printf("%lx", (unsigned long) gpr_set_log_verbosity); + printf("%lx", (unsigned long) gpr_log_verbosity_init); + printf("%lx", (unsigned long) gpr_set_log_function); + printf("%lx", (unsigned long) gpr_strdup); + printf("%lx", (unsigned long) gpr_asprintf); + printf("%lx", (unsigned long) gpr_subprocess_binary_extension); + printf("%lx", (unsigned long) gpr_subprocess_create); + printf("%lx", (unsigned long) gpr_subprocess_destroy); + printf("%lx", (unsigned long) gpr_subprocess_join); + printf("%lx", (unsigned long) gpr_subprocess_interrupt); + printf("%lx", (unsigned long) gpr_mu_init); + printf("%lx", (unsigned long) gpr_mu_destroy); + printf("%lx", (unsigned long) gpr_mu_lock); + printf("%lx", (unsigned long) gpr_mu_unlock); + printf("%lx", (unsigned long) gpr_mu_trylock); + printf("%lx", (unsigned long) gpr_cv_init); + printf("%lx", (unsigned long) gpr_cv_destroy); + printf("%lx", (unsigned long) gpr_cv_wait); + printf("%lx", (unsigned long) gpr_cv_signal); + printf("%lx", (unsigned long) gpr_cv_broadcast); + printf("%lx", (unsigned long) gpr_once_init); + printf("%lx", (unsigned long) gpr_event_init); + printf("%lx", (unsigned long) gpr_event_set); + printf("%lx", (unsigned long) gpr_event_get); + printf("%lx", (unsigned long) gpr_event_wait); + printf("%lx", (unsigned long) gpr_ref_init); + printf("%lx", (unsigned long) gpr_ref); + printf("%lx", (unsigned long) gpr_ref_non_zero); + printf("%lx", (unsigned long) gpr_refn); + printf("%lx", (unsigned long) gpr_unref); + printf("%lx", (unsigned long) gpr_ref_is_unique); + printf("%lx", (unsigned long) gpr_stats_init); + printf("%lx", (unsigned long) gpr_stats_inc); + printf("%lx", (unsigned long) gpr_stats_read); + printf("%lx", (unsigned long) gpr_thd_new); + printf("%lx", (unsigned long) gpr_thd_options_default); + printf("%lx", (unsigned long) gpr_thd_options_set_detached); + printf("%lx", (unsigned long) gpr_thd_options_set_joinable); + printf("%lx", (unsigned long) gpr_thd_options_is_detached); + printf("%lx", (unsigned long) gpr_thd_options_is_joinable); + printf("%lx", (unsigned long) gpr_thd_currentid); + printf("%lx", (unsigned long) gpr_thd_join); + printf("%lx", (unsigned long) gpr_time_0); + printf("%lx", (unsigned long) gpr_inf_future); + printf("%lx", (unsigned long) gpr_inf_past); + printf("%lx", (unsigned long) gpr_time_init); + printf("%lx", (unsigned long) gpr_now); + printf("%lx", (unsigned long) gpr_convert_clock_type); + printf("%lx", (unsigned long) gpr_time_cmp); + printf("%lx", (unsigned long) gpr_time_max); + printf("%lx", (unsigned long) gpr_time_min); + printf("%lx", (unsigned long) gpr_time_add); + printf("%lx", (unsigned long) gpr_time_sub); + printf("%lx", (unsigned long) gpr_time_from_micros); + printf("%lx", (unsigned long) gpr_time_from_nanos); + printf("%lx", (unsigned long) gpr_time_from_millis); + printf("%lx", (unsigned long) gpr_time_from_seconds); + printf("%lx", (unsigned long) gpr_time_from_minutes); + printf("%lx", (unsigned long) gpr_time_from_hours); + printf("%lx", (unsigned long) gpr_time_to_millis); + printf("%lx", (unsigned long) gpr_time_similar); + printf("%lx", (unsigned long) gpr_sleep_until); + printf("%lx", (unsigned long) gpr_timespec_to_micros); return 0; } diff --git a/test/cpp/microbenchmarks/bm_error.cc b/test/cpp/microbenchmarks/bm_error.cc index 02a93e90cc..bbd8b3c339 100644 --- a/test/cpp/microbenchmarks/bm_error.cc +++ b/test/cpp/microbenchmarks/bm_error.cc @@ -251,7 +251,7 @@ static void BM_ErrorGetStatus(benchmark::State& state) { grpc_status_code status; grpc_slice slice; grpc_error_get_status(&exec_ctx, fixture.error(), fixture.deadline(), - &status, &slice, nullptr); + &status, &slice, nullptr, nullptr); } grpc_exec_ctx_finish(&exec_ctx); track_counters.Finish(state); @@ -265,7 +265,7 @@ static void BM_ErrorGetStatusCode(benchmark::State& state) { while (state.KeepRunning()) { grpc_status_code status; grpc_error_get_status(&exec_ctx, fixture.error(), fixture.deadline(), - &status, nullptr, nullptr); + &status, nullptr, nullptr, nullptr); } grpc_exec_ctx_finish(&exec_ctx); track_counters.Finish(state); @@ -279,7 +279,7 @@ static void BM_ErrorHttpError(benchmark::State& state) { while (state.KeepRunning()) { grpc_http2_error_code error; grpc_error_get_status(&exec_ctx, fixture.error(), fixture.deadline(), - nullptr, nullptr, &error); + nullptr, nullptr, &error, nullptr); } grpc_exec_ctx_finish(&exec_ctx); track_counters.Finish(state); diff --git a/third_party/cares/cares.BUILD b/third_party/cares/cares.BUILD index 8cc01b64c4..85ca506ab0 100644 --- a/third_party/cares/cares.BUILD +++ b/third_party/cares/cares.BUILD @@ -8,7 +8,7 @@ config_setting( config_setting( name = "android", values = { - "crosstool_top": "//external:android/crosstool", + "crosstool_top": "//external:android/crosstool", }, ) @@ -18,120 +18,128 @@ config_setting( name = "ios_x86_64", values = {"cpu": "ios_x86_64"}, ) + config_setting( name = "ios_armv7", values = {"cpu": "ios_armv7"}, ) + config_setting( name = "ios_armv7s", values = {"cpu": "ios_armv7s"}, ) + config_setting( name = "ios_arm64", values = {"cpu": "ios_arm64"}, ) +genrule( + name = "ares_build", + srcs = ["@cares_local_files//:ares_build_h"], + outs = ["ares_build.h"], + cmd = "cat $(location @cares_local_files//:ares_build_h) > $@", +) + +# cc_library( +# name = "ares_build_h", +# hdrs = ["ares_build.h"], +# data = [":ares_build"], +# includes = ["."], +# ) + +genrule( + name = "ares_config", + srcs = ["@cares_local_files//:ares_config_h"], + outs = ["ares_config.h"], + cmd = "cat $(location @cares_local_files//:ares_config_h) > $@", +) + +# cc_library( +# name = "ares_config_h", +# hdrs = ["ares_config.h"], +# data = [":ares_config"], +# includes = ["."], +# ) + cc_library( name = "ares", srcs = [ - "cares/ares__close_sockets.c", - "cares/ares__get_hostent.c", - "cares/ares__read_line.c", - "cares/ares__timeval.c", - "cares/ares_cancel.c", - "cares/ares_create_query.c", - "cares/ares_data.c", - "cares/ares_destroy.c", - "cares/ares_expand_name.c", - "cares/ares_expand_string.c", - "cares/ares_fds.c", - "cares/ares_free_hostent.c", - "cares/ares_free_string.c", - "cares/ares_getenv.c", - "cares/ares_gethostbyaddr.c", - "cares/ares_gethostbyname.c", - "cares/ares_getnameinfo.c", - "cares/ares_getopt.c", - "cares/ares_getsock.c", - "cares/ares_init.c", - "cares/ares_library_init.c", - "cares/ares_llist.c", - "cares/ares_mkquery.c", - "cares/ares_nowarn.c", - "cares/ares_options.c", - "cares/ares_parse_a_reply.c", - "cares/ares_parse_aaaa_reply.c", - "cares/ares_parse_mx_reply.c", - "cares/ares_parse_naptr_reply.c", - "cares/ares_parse_ns_reply.c", - "cares/ares_parse_ptr_reply.c", - "cares/ares_parse_soa_reply.c", - "cares/ares_parse_srv_reply.c", - "cares/ares_parse_txt_reply.c", - "cares/ares_platform.c", - "cares/ares_process.c", - "cares/ares_query.c", - "cares/ares_search.c", - "cares/ares_send.c", - "cares/ares_strcasecmp.c", - "cares/ares_strdup.c", - "cares/ares_strerror.c", - "cares/ares_timeout.c", - "cares/ares_version.c", - "cares/ares_writev.c", - "cares/bitncmp.c", - "cares/inet_net_pton.c", - "cares/inet_ntop.c", - "cares/windows_port.c", + "ares__close_sockets.c", + "ares__get_hostent.c", + "ares__read_line.c", + "ares__timeval.c", + "ares_cancel.c", + "ares_create_query.c", + "ares_data.c", + "ares_destroy.c", + "ares_expand_name.c", + "ares_expand_string.c", + "ares_fds.c", + "ares_free_hostent.c", + "ares_free_string.c", + "ares_getenv.c", + "ares_gethostbyaddr.c", + "ares_gethostbyname.c", + "ares_getnameinfo.c", + "ares_getopt.c", + "ares_getsock.c", + "ares_init.c", + "ares_library_init.c", + "ares_llist.c", + "ares_mkquery.c", + "ares_nowarn.c", + "ares_options.c", + "ares_parse_a_reply.c", + "ares_parse_aaaa_reply.c", + "ares_parse_mx_reply.c", + "ares_parse_naptr_reply.c", + "ares_parse_ns_reply.c", + "ares_parse_ptr_reply.c", + "ares_parse_soa_reply.c", + "ares_parse_srv_reply.c", + "ares_parse_txt_reply.c", + "ares_platform.c", + "ares_process.c", + "ares_query.c", + "ares_search.c", + "ares_send.c", + "ares_strcasecmp.c", + "ares_strdup.c", + "ares_strerror.c", + "ares_timeout.c", + "ares_version.c", + "ares_writev.c", + "bitncmp.c", + "inet_net_pton.c", + "inet_ntop.c", + "windows_port.c", ], hdrs = [ + "ares.h", "ares_build.h", - "cares/ares.h", - "cares/ares_data.h", - "cares/ares_dns.h", - "cares/ares_getenv.h", - "cares/ares_getopt.h", - "cares/ares_inet_net_pton.h", - "cares/ares_iphlpapi.h", - "cares/ares_ipv6.h", - "cares/ares_library_init.h", - "cares/ares_llist.h", - "cares/ares_nowarn.h", - "cares/ares_platform.h", - "cares/ares_private.h", - "cares/ares_rules.h", - "cares/ares_setup.h", - "cares/ares_strcasecmp.h", - "cares/ares_strdup.h", - "cares/ares_version.h", - "cares/bitncmp.h", - "cares/config-win32.h", - "cares/nameser.h", - "cares/setup_once.h", - ] + select({ - ":ios_x86_64": ["config_darwin/ares_config.h"], - ":ios_armv7": ["config_darwin/ares_config.h"], - ":ios_armv7s": ["config_darwin/ares_config.h"], - ":ios_arm64": ["config_darwin/ares_config.h"], - ":darwin": ["config_darwin/ares_config.h"], - ":android": ["config_android/ares_config.h"], - "//conditions:default": ["config_linux/ares_config.h"], - }), - includes = [ - ".", - "cares" - ] + select({ - ":ios_x86_64": ["config_darwin"], - ":ios_armv7": ["config_darwin"], - ":ios_armv7s": ["config_darwin"], - ":ios_arm64": ["config_darwin"], - ":darwin": ["config_darwin"], - ":android": ["config_android"], - "//conditions:default": ["config_linux"], - }), - linkstatic = 1, - visibility = [ - "//visibility:public", + "ares_config.h", + "ares_data.h", + "ares_dns.h", + "ares_getenv.h", + "ares_getopt.h", + "ares_inet_net_pton.h", + "ares_iphlpapi.h", + "ares_ipv6.h", + "ares_library_init.h", + "ares_llist.h", + "ares_nowarn.h", + "ares_platform.h", + "ares_private.h", + "ares_rules.h", + "ares_setup.h", + "ares_strcasecmp.h", + "ares_strdup.h", + "ares_version.h", + "bitncmp.h", + "config-win32.h", + "nameser.h", + "setup_once.h", ], copts = [ "-D_GNU_SOURCE", @@ -139,4 +147,13 @@ cc_library( "-DNOMINMAX", "-DHAVE_CONFIG_H", ], + data = [ + ":ares_build", + ":ares_config", + ], + includes = ["."], + linkstatic = 1, + visibility = [ + "//visibility:public", + ], ) diff --git a/third_party/cares/cares_local_files.BUILD b/third_party/cares/cares_local_files.BUILD new file mode 100644 index 0000000000..fe59447beb --- /dev/null +++ b/third_party/cares/cares_local_files.BUILD @@ -0,0 +1,57 @@ +package( + default_visibility = ["//visibility:public"], +) + +config_setting( + name = "darwin", + values = {"cpu": "darwin"}, +) + +# Android is not officially supported through C++. +# This just helps with the build for now. +config_setting( + name = "android", + values = { + "crosstool_top": "//external:android/crosstool", + }, +) + +# iOS is not officially supported through C++. +# This just helps with the build for now. +config_setting( + name = "ios_x86_64", + values = {"cpu": "ios_x86_64"}, +) + +config_setting( + name = "ios_armv7", + values = {"cpu": "ios_armv7"}, +) + +config_setting( + name = "ios_armv7s", + values = {"cpu": "ios_armv7s"}, +) + +config_setting( + name = "ios_arm64", + values = {"cpu": "ios_arm64"}, +) + +filegroup( + name = "ares_build_h", + srcs = ["ares_build.h"], +) + +filegroup( + name = "ares_config_h", + srcs = select({ + ":ios_x86_64": ["config_darwin/ares_config.h"], + ":ios_armv7": ["config_darwin/ares_config.h"], + ":ios_armv7s": ["config_darwin/ares_config.h"], + ":ios_arm64": ["config_darwin/ares_config.h"], + ":darwin": ["config_darwin/ares_config.h"], + ":android": ["config_android/ares_config.h"], + "//conditions:default": ["config_linux/ares_config.h"], + }), +) diff --git a/third_party/protobuf b/third_party/protobuf -Subproject 80a37e0782d2d702d52234b62dd4b9ec74fd2c9 +Subproject 2761122b810fe8861004ae785cc3ab39f384d34 diff --git a/tools/codegen/core/gen_nano_proto.sh b/tools/codegen/core/gen_nano_proto.sh index db00bd937f..4246840173 100755 --- a/tools/codegen/core/gen_nano_proto.sh +++ b/tools/codegen/core/gen_nano_proto.sh @@ -68,7 +68,7 @@ popd # this should be the same version as the submodule we compile against # ideally we'd update this as a template to ensure that -pip install protobuf==3.2.0 +pip install protobuf==3.5.0.post1 pushd "$(dirname $INPUT_PROTO)" > /dev/null diff --git a/tools/distrib/python/check_grpcio_tools.py b/tools/distrib/python/check_grpcio_tools.py index c5afa713e6..b56ccaea7a 100755 --- a/tools/distrib/python/check_grpcio_tools.py +++ b/tools/distrib/python/check_grpcio_tools.py @@ -14,17 +14,21 @@ # See the License for the specific language governing permissions and # limitations under the License. -import cStringIO - -import make_grpcio_tools as make +import make_grpcio_tools as _make OUT_OF_DATE_MESSAGE = """file {} is out of date Have you called tools/distrib/python/make_grpcio_tools.py since upgrading protobuf?""" -check_protoc_lib_deps_content = make.get_deps() +submodule_commit_hash = _make.protobuf_submodule_commit_hash() + +with open(_make.GRPC_PYTHON_PROTOC_LIB_DEPS, 'r') as _protoc_lib_deps_file: + content = _protoc_lib_deps_file.read().splitlines() + +testString = (_make.COMMIT_HASH_PREFIX + + submodule_commit_hash + + _make.COMMIT_HASH_SUFFIX) -with open(make.GRPC_PYTHON_PROTOC_LIB_DEPS, 'r') as protoc_lib_deps_file: - if protoc_lib_deps_file.read() != check_protoc_lib_deps_content: - print(OUT_OF_DATE_MESSAGE.format(make.GRPC_PYTHON_PROTOC_LIB_DEPS)) - raise SystemExit(1) +if testString not in content: + print(OUT_OF_DATE_MESSAGE.format(_make.GRPC_PYTHON_PROTOC_LIB_DEPS)) + raise SystemExit(1) diff --git a/tools/distrib/python/grpcio_tools/protoc_lib_deps.py b/tools/distrib/python/grpcio_tools/protoc_lib_deps.py index 18470d59d5..2c65fca628 100644 --- a/tools/distrib/python/grpcio_tools/protoc_lib_deps.py +++ b/tools/distrib/python/grpcio_tools/protoc_lib_deps.py @@ -1,5 +1,5 @@ -# Copyright 2016 gRPC authors. +# Copyright 2017 gRPC authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -14,8 +14,10 @@ # limitations under the License. # AUTO-GENERATED BY make_grpcio_tools.py! -CC_FILES=['google/protobuf/compiler/zip_writer.cc', 'google/protobuf/compiler/subprocess.cc', 'google/protobuf/compiler/ruby/ruby_generator.cc', 'google/protobuf/compiler/python/python_generator.cc', 'google/protobuf/compiler/plugin.pb.cc', 'google/protobuf/compiler/plugin.cc', 'google/protobuf/compiler/php/php_generator.cc', 'google/protobuf/compiler/objectivec/objectivec_primitive_field.cc', 'google/protobuf/compiler/objectivec/objectivec_oneof.cc', 'google/protobuf/compiler/objectivec/objectivec_message_field.cc', 'google/protobuf/compiler/objectivec/objectivec_message.cc', 'google/protobuf/compiler/objectivec/objectivec_map_field.cc', 'google/protobuf/compiler/objectivec/objectivec_helpers.cc', 'google/protobuf/compiler/objectivec/objectivec_generator.cc', 'google/protobuf/compiler/objectivec/objectivec_file.cc', 'google/protobuf/compiler/objectivec/objectivec_field.cc', 'google/protobuf/compiler/objectivec/objectivec_extension.cc', 'google/protobuf/compiler/objectivec/objectivec_enum_field.cc', 'google/protobuf/compiler/objectivec/objectivec_enum.cc', 'google/protobuf/compiler/js/well_known_types_embed.cc', 'google/protobuf/compiler/js/js_generator.cc', 'google/protobuf/compiler/javanano/javanano_primitive_field.cc', 'google/protobuf/compiler/javanano/javanano_message_field.cc', 'google/protobuf/compiler/javanano/javanano_message.cc', 'google/protobuf/compiler/javanano/javanano_map_field.cc', 'google/protobuf/compiler/javanano/javanano_helpers.cc', 'google/protobuf/compiler/javanano/javanano_generator.cc', 'google/protobuf/compiler/javanano/javanano_file.cc', 'google/protobuf/compiler/javanano/javanano_field.cc', 'google/protobuf/compiler/javanano/javanano_extension.cc', 'google/protobuf/compiler/javanano/javanano_enum_field.cc', 'google/protobuf/compiler/javanano/javanano_enum.cc', 'google/protobuf/compiler/java/java_string_field_lite.cc', 'google/protobuf/compiler/java/java_string_field.cc', 'google/protobuf/compiler/java/java_shared_code_generator.cc', 'google/protobuf/compiler/java/java_service.cc', 'google/protobuf/compiler/java/java_primitive_field_lite.cc', 'google/protobuf/compiler/java/java_primitive_field.cc', 'google/protobuf/compiler/java/java_name_resolver.cc', 'google/protobuf/compiler/java/java_message_lite.cc', 'google/protobuf/compiler/java/java_message_field_lite.cc', 'google/protobuf/compiler/java/java_message_field.cc', 'google/protobuf/compiler/java/java_message_builder_lite.cc', 'google/protobuf/compiler/java/java_message_builder.cc', 'google/protobuf/compiler/java/java_message.cc', 'google/protobuf/compiler/java/java_map_field_lite.cc', 'google/protobuf/compiler/java/java_map_field.cc', 'google/protobuf/compiler/java/java_lazy_message_field_lite.cc', 'google/protobuf/compiler/java/java_lazy_message_field.cc', 'google/protobuf/compiler/java/java_helpers.cc', 'google/protobuf/compiler/java/java_generator_factory.cc', 'google/protobuf/compiler/java/java_generator.cc', 'google/protobuf/compiler/java/java_file.cc', 'google/protobuf/compiler/java/java_field.cc', 'google/protobuf/compiler/java/java_extension_lite.cc', 'google/protobuf/compiler/java/java_extension.cc', 'google/protobuf/compiler/java/java_enum_lite.cc', 'google/protobuf/compiler/java/java_enum_field_lite.cc', 'google/protobuf/compiler/java/java_enum_field.cc', 'google/protobuf/compiler/java/java_enum.cc', 'google/protobuf/compiler/java/java_doc_comment.cc', 'google/protobuf/compiler/java/java_context.cc', 'google/protobuf/compiler/csharp/csharp_wrapper_field.cc', 'google/protobuf/compiler/csharp/csharp_source_generator_base.cc', 'google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc', 'google/protobuf/compiler/csharp/csharp_repeated_message_field.cc', 'google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc', 'google/protobuf/compiler/csharp/csharp_reflection_class.cc', 'google/protobuf/compiler/csharp/csharp_primitive_field.cc', 'google/protobuf/compiler/csharp/csharp_message_field.cc', 'google/protobuf/compiler/csharp/csharp_message.cc', 'google/protobuf/compiler/csharp/csharp_map_field.cc', 'google/protobuf/compiler/csharp/csharp_helpers.cc', 'google/protobuf/compiler/csharp/csharp_generator.cc', 'google/protobuf/compiler/csharp/csharp_field_base.cc', 'google/protobuf/compiler/csharp/csharp_enum_field.cc', 'google/protobuf/compiler/csharp/csharp_enum.cc', 'google/protobuf/compiler/csharp/csharp_doc_comment.cc', 'google/protobuf/compiler/cpp/cpp_string_field.cc', 'google/protobuf/compiler/cpp/cpp_service.cc', 'google/protobuf/compiler/cpp/cpp_primitive_field.cc', 'google/protobuf/compiler/cpp/cpp_message_field.cc', 'google/protobuf/compiler/cpp/cpp_message.cc', 'google/protobuf/compiler/cpp/cpp_map_field.cc', 'google/protobuf/compiler/cpp/cpp_helpers.cc', 'google/protobuf/compiler/cpp/cpp_generator.cc', 'google/protobuf/compiler/cpp/cpp_file.cc', 'google/protobuf/compiler/cpp/cpp_field.cc', 'google/protobuf/compiler/cpp/cpp_extension.cc', 'google/protobuf/compiler/cpp/cpp_enum_field.cc', 'google/protobuf/compiler/cpp/cpp_enum.cc', 'google/protobuf/compiler/command_line_interface.cc', 'google/protobuf/compiler/code_generator.cc', 'google/protobuf/wrappers.pb.cc', 'google/protobuf/wire_format.cc', 'google/protobuf/util/type_resolver_util.cc', 'google/protobuf/util/time_util.cc', 'google/protobuf/util/message_differencer.cc', 'google/protobuf/util/json_util.cc', 'google/protobuf/util/internal/utility.cc', 'google/protobuf/util/internal/type_info_test_helper.cc', 'google/protobuf/util/internal/type_info.cc', 'google/protobuf/util/internal/protostream_objectwriter.cc', 'google/protobuf/util/internal/protostream_objectsource.cc', 'google/protobuf/util/internal/proto_writer.cc', 'google/protobuf/util/internal/object_writer.cc', 'google/protobuf/util/internal/json_stream_parser.cc', 'google/protobuf/util/internal/json_objectwriter.cc', 'google/protobuf/util/internal/json_escaping.cc', 'google/protobuf/util/internal/field_mask_utility.cc', 'google/protobuf/util/internal/error_listener.cc', 'google/protobuf/util/internal/default_value_objectwriter.cc', 'google/protobuf/util/internal/datapiece.cc', 'google/protobuf/util/field_mask_util.cc', 'google/protobuf/util/field_comparator.cc', 'google/protobuf/util/delimited_message_util.cc', 'google/protobuf/unknown_field_set.cc', 'google/protobuf/type.pb.cc', 'google/protobuf/timestamp.pb.cc', 'google/protobuf/text_format.cc', 'google/protobuf/stubs/substitute.cc', 'google/protobuf/stubs/mathlimits.cc', 'google/protobuf/struct.pb.cc', 'google/protobuf/source_context.pb.cc', 'google/protobuf/service.cc', 'google/protobuf/reflection_ops.cc', 'google/protobuf/message.cc', 'google/protobuf/map_field.cc', 'google/protobuf/io/zero_copy_stream_impl.cc', 'google/protobuf/io/tokenizer.cc', 'google/protobuf/io/strtod.cc', 'google/protobuf/io/printer.cc', 'google/protobuf/io/gzip_stream.cc', 'google/protobuf/generated_message_table_driven.cc', 'google/protobuf/generated_message_reflection.cc', 'google/protobuf/field_mask.pb.cc', 'google/protobuf/extension_set_heavy.cc', 'google/protobuf/empty.pb.cc', 'google/protobuf/dynamic_message.cc', 'google/protobuf/duration.pb.cc', 'google/protobuf/descriptor_database.cc', 'google/protobuf/descriptor.pb.cc', 'google/protobuf/descriptor.cc', 'google/protobuf/compiler/parser.cc', 'google/protobuf/compiler/importer.cc', 'google/protobuf/api.pb.cc', 'google/protobuf/any.pb.cc', 'google/protobuf/any.cc', 'google/protobuf/wire_format_lite.cc', 'google/protobuf/stubs/time.cc', 'google/protobuf/stubs/strutil.cc', 'google/protobuf/stubs/structurally_valid.cc', 'google/protobuf/stubs/stringprintf.cc', 'google/protobuf/stubs/stringpiece.cc', 'google/protobuf/stubs/statusor.cc', 'google/protobuf/stubs/status.cc', 'google/protobuf/stubs/once.cc', 'google/protobuf/stubs/io_win32.cc', 'google/protobuf/stubs/int128.cc', 'google/protobuf/stubs/common.cc', 'google/protobuf/stubs/bytestream.cc', 'google/protobuf/stubs/atomicops_internals_x86_msvc.cc', 'google/protobuf/stubs/atomicops_internals_x86_gcc.cc', 'google/protobuf/repeated_field.cc', 'google/protobuf/message_lite.cc', 'google/protobuf/io/zero_copy_stream_impl_lite.cc', 'google/protobuf/io/zero_copy_stream.cc', 'google/protobuf/io/coded_stream.cc', 'google/protobuf/generated_message_util.cc', 'google/protobuf/generated_message_table_driven_lite.cc', 'google/protobuf/extension_set.cc', 'google/protobuf/arenastring.cc', 'google/protobuf/arena.cc', 'google/protobuf/compiler/js/embed.cc'] +CC_FILES=['google/protobuf/compiler/zip_writer.cc', 'google/protobuf/compiler/subprocess.cc', 'google/protobuf/compiler/ruby/ruby_generator.cc', 'google/protobuf/compiler/python/python_generator.cc', 'google/protobuf/compiler/plugin.pb.cc', 'google/protobuf/compiler/plugin.cc', 'google/protobuf/compiler/php/php_generator.cc', 'google/protobuf/compiler/objectivec/objectivec_primitive_field.cc', 'google/protobuf/compiler/objectivec/objectivec_oneof.cc', 'google/protobuf/compiler/objectivec/objectivec_message_field.cc', 'google/protobuf/compiler/objectivec/objectivec_message.cc', 'google/protobuf/compiler/objectivec/objectivec_map_field.cc', 'google/protobuf/compiler/objectivec/objectivec_helpers.cc', 'google/protobuf/compiler/objectivec/objectivec_generator.cc', 'google/protobuf/compiler/objectivec/objectivec_file.cc', 'google/protobuf/compiler/objectivec/objectivec_field.cc', 'google/protobuf/compiler/objectivec/objectivec_extension.cc', 'google/protobuf/compiler/objectivec/objectivec_enum_field.cc', 'google/protobuf/compiler/objectivec/objectivec_enum.cc', 'google/protobuf/compiler/js/well_known_types_embed.cc', 'google/protobuf/compiler/js/js_generator.cc', 'google/protobuf/compiler/javanano/javanano_primitive_field.cc', 'google/protobuf/compiler/javanano/javanano_message_field.cc', 'google/protobuf/compiler/javanano/javanano_message.cc', 'google/protobuf/compiler/javanano/javanano_map_field.cc', 'google/protobuf/compiler/javanano/javanano_helpers.cc', 'google/protobuf/compiler/javanano/javanano_generator.cc', 'google/protobuf/compiler/javanano/javanano_file.cc', 'google/protobuf/compiler/javanano/javanano_field.cc', 'google/protobuf/compiler/javanano/javanano_extension.cc', 'google/protobuf/compiler/javanano/javanano_enum_field.cc', 'google/protobuf/compiler/javanano/javanano_enum.cc', 'google/protobuf/compiler/java/java_string_field_lite.cc', 'google/protobuf/compiler/java/java_string_field.cc', 'google/protobuf/compiler/java/java_shared_code_generator.cc', 'google/protobuf/compiler/java/java_service.cc', 'google/protobuf/compiler/java/java_primitive_field_lite.cc', 'google/protobuf/compiler/java/java_primitive_field.cc', 'google/protobuf/compiler/java/java_name_resolver.cc', 'google/protobuf/compiler/java/java_message_lite.cc', 'google/protobuf/compiler/java/java_message_field_lite.cc', 'google/protobuf/compiler/java/java_message_field.cc', 'google/protobuf/compiler/java/java_message_builder_lite.cc', 'google/protobuf/compiler/java/java_message_builder.cc', 'google/protobuf/compiler/java/java_message.cc', 'google/protobuf/compiler/java/java_map_field_lite.cc', 'google/protobuf/compiler/java/java_map_field.cc', 'google/protobuf/compiler/java/java_lazy_message_field_lite.cc', 'google/protobuf/compiler/java/java_lazy_message_field.cc', 'google/protobuf/compiler/java/java_helpers.cc', 'google/protobuf/compiler/java/java_generator_factory.cc', 'google/protobuf/compiler/java/java_generator.cc', 'google/protobuf/compiler/java/java_file.cc', 'google/protobuf/compiler/java/java_field.cc', 'google/protobuf/compiler/java/java_extension_lite.cc', 'google/protobuf/compiler/java/java_extension.cc', 'google/protobuf/compiler/java/java_enum_lite.cc', 'google/protobuf/compiler/java/java_enum_field_lite.cc', 'google/protobuf/compiler/java/java_enum_field.cc', 'google/protobuf/compiler/java/java_enum.cc', 'google/protobuf/compiler/java/java_doc_comment.cc', 'google/protobuf/compiler/java/java_context.cc', 'google/protobuf/compiler/csharp/csharp_wrapper_field.cc', 'google/protobuf/compiler/csharp/csharp_source_generator_base.cc', 'google/protobuf/compiler/csharp/csharp_repeated_primitive_field.cc', 'google/protobuf/compiler/csharp/csharp_repeated_message_field.cc', 'google/protobuf/compiler/csharp/csharp_repeated_enum_field.cc', 'google/protobuf/compiler/csharp/csharp_reflection_class.cc', 'google/protobuf/compiler/csharp/csharp_primitive_field.cc', 'google/protobuf/compiler/csharp/csharp_message_field.cc', 'google/protobuf/compiler/csharp/csharp_message.cc', 'google/protobuf/compiler/csharp/csharp_map_field.cc', 'google/protobuf/compiler/csharp/csharp_helpers.cc', 'google/protobuf/compiler/csharp/csharp_generator.cc', 'google/protobuf/compiler/csharp/csharp_field_base.cc', 'google/protobuf/compiler/csharp/csharp_enum_field.cc', 'google/protobuf/compiler/csharp/csharp_enum.cc', 'google/protobuf/compiler/csharp/csharp_doc_comment.cc', 'google/protobuf/compiler/cpp/cpp_string_field.cc', 'google/protobuf/compiler/cpp/cpp_service.cc', 'google/protobuf/compiler/cpp/cpp_primitive_field.cc', 'google/protobuf/compiler/cpp/cpp_padding_optimizer.cc', 'google/protobuf/compiler/cpp/cpp_message_field.cc', 'google/protobuf/compiler/cpp/cpp_message.cc', 'google/protobuf/compiler/cpp/cpp_map_field.cc', 'google/protobuf/compiler/cpp/cpp_helpers.cc', 'google/protobuf/compiler/cpp/cpp_generator.cc', 'google/protobuf/compiler/cpp/cpp_file.cc', 'google/protobuf/compiler/cpp/cpp_field.cc', 'google/protobuf/compiler/cpp/cpp_extension.cc', 'google/protobuf/compiler/cpp/cpp_enum_field.cc', 'google/protobuf/compiler/cpp/cpp_enum.cc', 'google/protobuf/compiler/command_line_interface.cc', 'google/protobuf/compiler/code_generator.cc', 'google/protobuf/wrappers.pb.cc', 'google/protobuf/wire_format.cc', 'google/protobuf/util/type_resolver_util.cc', 'google/protobuf/util/time_util.cc', 'google/protobuf/util/message_differencer.cc', 'google/protobuf/util/json_util.cc', 'google/protobuf/util/internal/utility.cc', 'google/protobuf/util/internal/type_info_test_helper.cc', 'google/protobuf/util/internal/type_info.cc', 'google/protobuf/util/internal/protostream_objectwriter.cc', 'google/protobuf/util/internal/protostream_objectsource.cc', 'google/protobuf/util/internal/proto_writer.cc', 'google/protobuf/util/internal/object_writer.cc', 'google/protobuf/util/internal/json_stream_parser.cc', 'google/protobuf/util/internal/json_objectwriter.cc', 'google/protobuf/util/internal/json_escaping.cc', 'google/protobuf/util/internal/field_mask_utility.cc', 'google/protobuf/util/internal/error_listener.cc', 'google/protobuf/util/internal/default_value_objectwriter.cc', 'google/protobuf/util/internal/datapiece.cc', 'google/protobuf/util/field_mask_util.cc', 'google/protobuf/util/field_comparator.cc', 'google/protobuf/util/delimited_message_util.cc', 'google/protobuf/unknown_field_set.cc', 'google/protobuf/type.pb.cc', 'google/protobuf/timestamp.pb.cc', 'google/protobuf/text_format.cc', 'google/protobuf/stubs/substitute.cc', 'google/protobuf/stubs/mathlimits.cc', 'google/protobuf/struct.pb.cc', 'google/protobuf/source_context.pb.cc', 'google/protobuf/service.cc', 'google/protobuf/reflection_ops.cc', 'google/protobuf/message.cc', 'google/protobuf/map_field.cc', 'google/protobuf/io/zero_copy_stream_impl.cc', 'google/protobuf/io/tokenizer.cc', 'google/protobuf/io/strtod.cc', 'google/protobuf/io/printer.cc', 'google/protobuf/io/gzip_stream.cc', 'google/protobuf/generated_message_table_driven.cc', 'google/protobuf/generated_message_reflection.cc', 'google/protobuf/field_mask.pb.cc', 'google/protobuf/extension_set_heavy.cc', 'google/protobuf/empty.pb.cc', 'google/protobuf/dynamic_message.cc', 'google/protobuf/duration.pb.cc', 'google/protobuf/descriptor_database.cc', 'google/protobuf/descriptor.pb.cc', 'google/protobuf/descriptor.cc', 'google/protobuf/compiler/parser.cc', 'google/protobuf/compiler/importer.cc', 'google/protobuf/api.pb.cc', 'google/protobuf/any.pb.cc', 'google/protobuf/any.cc', 'google/protobuf/wire_format_lite.cc', 'google/protobuf/stubs/time.cc', 'google/protobuf/stubs/strutil.cc', 'google/protobuf/stubs/structurally_valid.cc', 'google/protobuf/stubs/stringprintf.cc', 'google/protobuf/stubs/stringpiece.cc', 'google/protobuf/stubs/statusor.cc', 'google/protobuf/stubs/status.cc', 'google/protobuf/stubs/once.cc', 'google/protobuf/stubs/io_win32.cc', 'google/protobuf/stubs/int128.cc', 'google/protobuf/stubs/common.cc', 'google/protobuf/stubs/bytestream.cc', 'google/protobuf/stubs/atomicops_internals_x86_msvc.cc', 'google/protobuf/stubs/atomicops_internals_x86_gcc.cc', 'google/protobuf/repeated_field.cc', 'google/protobuf/message_lite.cc', 'google/protobuf/io/zero_copy_stream_impl_lite.cc', 'google/protobuf/io/zero_copy_stream.cc', 'google/protobuf/io/coded_stream.cc', 'google/protobuf/generated_message_util.cc', 'google/protobuf/generated_message_table_driven_lite.cc', 'google/protobuf/extension_set.cc', 'google/protobuf/arenastring.cc', 'google/protobuf/arena.cc', 'google/protobuf/compiler/js/embed.cc'] PROTO_FILES=['google/protobuf/wrappers.proto', 'google/protobuf/type.proto', 'google/protobuf/timestamp.proto', 'google/protobuf/struct.proto', 'google/protobuf/source_context.proto', 'google/protobuf/field_mask.proto', 'google/protobuf/empty.proto', 'google/protobuf/duration.proto', 'google/protobuf/descriptor.proto', 'google/protobuf/compiler/plugin.proto', 'google/protobuf/api.proto', 'google/protobuf/any.proto'] CC_INCLUDE='third_party/protobuf/src' PROTO_INCLUDE='third_party/protobuf/src' + +PROTOBUF_SUBMODULE_VERSION="2761122b810fe8861004ae785cc3ab39f384d342" diff --git a/tools/distrib/python/make_grpcio_tools.py b/tools/distrib/python/make_grpcio_tools.py index 5bc07ff360..c865f0bcc0 100755 --- a/tools/distrib/python/make_grpcio_tools.py +++ b/tools/distrib/python/make_grpcio_tools.py @@ -28,7 +28,7 @@ import traceback import uuid DEPS_FILE_CONTENT=""" -# Copyright 2016 gRPC authors. +# Copyright 2017 gRPC authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -48,8 +48,13 @@ PROTO_FILES={proto_files} CC_INCLUDE={cc_include} PROTO_INCLUDE={proto_include} + +{commit_hash} """ +COMMIT_HASH_PREFIX = 'PROTOBUF_SUBMODULE_VERSION="' +COMMIT_HASH_SUFFIX = '"' + # Bazel query result prefix for expected source files in protobuf. PROTOBUF_CC_PREFIX = '//:src/' PROTOBUF_PROTO_PREFIX = '//:src/' @@ -63,6 +68,7 @@ GRPC_PYTHON_ROOT = os.path.join(GRPC_ROOT, 'tools', 'distrib', GRPC_PYTHON_PROTOBUF_RELATIVE_ROOT = os.path.join('third_party', 'protobuf', 'src') GRPC_PROTOBUF = os.path.join(GRPC_ROOT, GRPC_PYTHON_PROTOBUF_RELATIVE_ROOT) +GRPC_PROTOBUF_SUBMODULE_ROOT = os.path.join(GRPC_ROOT, 'third_party', 'protobuf') GRPC_PROTOC_PLUGINS = os.path.join(GRPC_ROOT, 'src', 'compiler') GRPC_PYTHON_PROTOBUF = os.path.join(GRPC_PYTHON_ROOT, 'third_party', 'protobuf', 'src') @@ -78,6 +84,14 @@ BAZEL_DEPS = os.path.join(GRPC_ROOT, 'tools', 'distrib', 'python', 'bazel_deps.s BAZEL_DEPS_PROTOC_LIB_QUERY = '//:protoc_lib' BAZEL_DEPS_COMMON_PROTOS_QUERY = '//:well_known_protos' +def protobuf_submodule_commit_hash(): + """Gets the commit hash for the HEAD of the protobuf submodule currently + checked out.""" + cwd = os.getcwd() + os.chdir(GRPC_PROTOBUF_SUBMODULE_ROOT) + output = subprocess.check_output(['git', 'rev-parse', 'HEAD']) + os.chdir(cwd) + return output.splitlines()[0].strip() def bazel_query(query): output = subprocess.check_output([BAZEL_DEPS, query]) @@ -94,11 +108,13 @@ def get_deps(): proto_files = [ name[len(PROTOBUF_PROTO_PREFIX):] for name in proto_files_output if name.endswith('.proto') and name.startswith(PROTOBUF_PROTO_PREFIX)] + commit_hash = protobuf_submodule_commit_hash() deps_file_content = DEPS_FILE_CONTENT.format( cc_files=cc_files, proto_files=proto_files, cc_include=repr(GRPC_PYTHON_PROTOBUF_RELATIVE_ROOT), - proto_include=repr(GRPC_PYTHON_PROTOBUF_RELATIVE_ROOT)) + proto_include=repr(GRPC_PYTHON_PROTOBUF_RELATIVE_ROOT), + commit_hash=COMMIT_HASH_PREFIX + commit_hash + COMMIT_HASH_SUFFIX) return deps_file_content def long_path(path): diff --git a/tools/doxygen/Doxyfile.c++.internal b/tools/doxygen/Doxyfile.c++.internal index c9c64399f7..3c564e203a 100644 --- a/tools/doxygen/Doxyfile.c++.internal +++ b/tools/doxygen/Doxyfile.c++.internal @@ -1026,6 +1026,7 @@ src/core/lib/slice/percent_encoding.h \ src/core/lib/slice/slice_hash_table.h \ src/core/lib/slice/slice_internal.h \ src/core/lib/slice/slice_string_helpers.h \ +src/core/lib/support/abstract.h \ src/core/lib/support/arena.h \ src/core/lib/support/atomic.h \ src/core/lib/support/atomic_with_atm.h \ diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index b8434bb819..5674124f44 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1267,6 +1267,7 @@ src/core/lib/slice/slice_intern.cc \ src/core/lib/slice/slice_internal.h \ src/core/lib/slice/slice_string_helpers.cc \ src/core/lib/slice/slice_string_helpers.h \ +src/core/lib/support/abstract.h \ src/core/lib/support/alloc.cc \ src/core/lib/support/arena.cc \ src/core/lib/support/arena.h \ diff --git a/tools/interop_matrix/README.md b/tools/interop_matrix/README.md index 588afe4fd4..40c02a1bc7 100644 --- a/tools/interop_matrix/README.md +++ b/tools/interop_matrix/README.md @@ -8,8 +8,8 @@ from specific releases/tag, are used to test version compatiblity between gRPC r ## Step-by-step instructions for adding a GCR image for a new release for compatibility test We have continuous nightly test setup to test gRPC backward compatibility between old clients and latest server. When a gRPC developer creates a new gRPC release, s/he is also responsible to add the just-released gRPC client to the nightly test. The steps are: - Add (or update) an entry in `./client_matrix.py` file to reference the github tag for the release. -- Build new client docker image(s). For example, for java release `v1.9.9`, do - - `tools/interop_matrix/create_matrix_images.py --git_checkout --release=v1.9.9 --language=java` +- Build new client docker image(s). For example, for C and wrapper languages release `v1.9.9`, do + - `tools/interop_matrix/create_matrix_images.py --git_checkout --release=v1.9.9 --language cxx csharp python ruby php` - Verify that the new docker image was built successfully and uploaded to GCR. For example, - `gcloud beta container images list --repository gcr.io/grpc-testing` shows image repos. - `gcloud beta container images list-tags gcr.io/grpc-testing/grpc_interop_java_oracle8` should show an image entry with tag `v1.9.9`. diff --git a/tools/interop_matrix/client_matrix.py b/tools/interop_matrix/client_matrix.py index c8dbb3ae66..c7860f3fcc 100644 --- a/tools/interop_matrix/client_matrix.py +++ b/tools/interop_matrix/client_matrix.py @@ -19,6 +19,7 @@ def get_github_repo(lang): return { 'go': 'git@github.com:grpc/grpc-go.git', 'java': 'git@github.com:grpc/grpc-java.git', + 'node': 'git@github.com:grpc/grpc-node.git', # all other languages use the grpc.git repo. }.get(lang, 'git@github.com:grpc/grpc.git') @@ -44,6 +45,7 @@ LANG_RELEASE_MATRIX = { 'v1.3.9', 'v1.4.2', 'v1.6.6', + 'v1.7.2', ], 'go': [ 'v1.0.5', @@ -53,6 +55,10 @@ LANG_RELEASE_MATRIX = { 'v1.5.2', 'v1.6.0', 'v1.7.0', + 'v1.7.1', + 'v1.7.2', + 'v1.7.3', + 'v1.8.0', ], 'java': [ 'v1.0.3', @@ -63,6 +69,7 @@ LANG_RELEASE_MATRIX = { 'v1.5.0', 'v1.6.1', 'v1.7.0', + 'v1.8.0', ], 'python': [ 'v1.0.x', @@ -72,6 +79,24 @@ LANG_RELEASE_MATRIX = { 'v1.4.2', 'v1.6.6', ], + 'python': [ + 'v1.0.x', + 'v1.1.4', + 'v1.2.5', + 'v1.3.9', + 'v1.4.2', + 'v1.6.6', + 'v1.7.2', + ], + 'python': [ + 'v1.0.x', + 'v1.1.4', + 'v1.2.5', + 'v1.3.9', + 'v1.4.2', + 'v1.6.6', + 'v1.7.2', + ], 'node': [ 'v1.0.1', 'v1.1.4', @@ -79,6 +104,7 @@ LANG_RELEASE_MATRIX = { 'v1.3.9', 'v1.4.2', 'v1.6.6', + 'v1.7.1', ], 'ruby': [ # Ruby v1.0.x doesn't have the fix #8914, therefore not supported. @@ -87,6 +113,7 @@ LANG_RELEASE_MATRIX = { 'v1.3.9', 'v1.4.2', 'v1.6.6', + 'v1.7.2', ], 'php': [ 'v1.0.1', @@ -95,6 +122,7 @@ LANG_RELEASE_MATRIX = { 'v1.3.9', 'v1.4.2', 'v1.6.6', + 'v1.7.2', ], 'csharp': [ #'v1.0.1', @@ -103,5 +131,6 @@ LANG_RELEASE_MATRIX = { 'v1.3.9', 'v1.4.2', 'v1.6.6', + 'v1.7.2', ], } diff --git a/tools/interop_matrix/create_matrix_images.py b/tools/interop_matrix/create_matrix_images.py index 21040eadf2..493a7d5364 100755 --- a/tools/interop_matrix/create_matrix_images.py +++ b/tools/interop_matrix/create_matrix_images.py @@ -77,6 +77,15 @@ argp.add_argument('--keep', action='store_true', help='keep the created local images after uploading to GCR') +argp.add_argument('--reuse_git_root', + default=False, + action='store_const', + const=True, + help='reuse the repo dir. If False, the existing git root ' + 'directory will removed before a clean checkout, because ' + 'reusing the repo can cause git checkout error if you switch ' + 'between releases.') + args = argp.parse_args() @@ -133,7 +142,7 @@ def build_image_jobspec(runtime, env, gcr_tag, stack_base): } build_env.update(env) build_job = jobset.JobSpec( - cmdline=[os.path.join(stack_base, _IMAGE_BUILDER)], + cmdline=[_IMAGE_BUILDER], environ=build_env, shortname='build_docker_%s' % runtime, timeout_seconds=30*60) @@ -227,6 +236,11 @@ def checkout_grpc_stack(lang, release): repo_dir = os.path.splitext(os.path.basename(repo))[0] stack_base = os.path.join(args.git_checkout_root, repo_dir) + # Clean up leftover repo dir if necessary. + if not args.reuse_git_root and os.path.exists(stack_base): + jobset.message('START', 'Removing git checkout root.', do_newline=True) + shutil.rmtree(stack_base) + if not os.path.exists(stack_base): subprocess.check_call(['git', 'clone', '--recursive', repo], cwd=os.path.dirname(stack_base)) diff --git a/tools/interop_matrix/testcases/node__v1.0.1 b/tools/interop_matrix/testcases/node__v1.0.1 index fca9821544..6faf321391 100644 --- a/tools/interop_matrix/testcases/node__v1.0.1 +++ b/tools/interop_matrix/testcases/node__v1.0.1 @@ -1,21 +1,21 @@ #!/bin/bash echo "Testing ${docker_image:=grpc_interop_node:a53aa5e3-b548-4566-b5a8-6d15c1315b32}" -docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_00c688f2-57da-4023-89f3-46b1f7b5869f $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" -docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_d86705d8-14ea-4024-90b6-de74d6e8d19c $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" -docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_ebaafacd-1d82-4a75-bea1-a5c64e01fcaf $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" -docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_5125241a-fbf6-4c1c-895b-026a5a41f02f $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" -docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_3d5e5b82-7205-4eba-b775-8122f05a4760 $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" -docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_16fa0b49-2083-4932-8f26-79cfdffec940 $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" -docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_23cee670-2d8d-4f5c-8893-c3c43da8b03a $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" -docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_7b6a9454-e3b6-4993-b542-468e268930aa $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" -docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_5a7109ed-c065-4b62-98f4-b3ed8f385762 $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=grpc-test.sandbox.googleapis.com --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" -docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_1e0ba8dd-4dc1-431b-b202-529e7ace5d1d $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" -docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_649de56a-e722-4a59-b265-e9c0e871f068 $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" -docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_8be512a2-5e1c-4858-8cfc-82f99b678b76 $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" -docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_d19b6333-e528-48b5-8421-2ae3f7ce9dab $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" -docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_4749c80a-21c5-4d81-9df5-3c46ba6480cd $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" -docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_b7bee545-4857-4269-a1f2-9553dfc7e4b8 $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" -docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_4e96db87-6f48-426d-a7f0-97f3a5b6b3f4 $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" -docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_31a1d58c-f8bf-460a-af60-28969ecaaf80 $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" -docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_ce64b147-bcfa-44b2-a2f7-4a485380ce30 $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=grpc-test4.sandbox.googleapis.com --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" +docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_00c688f2-57da-4023-89f3-46b1f7b5869f $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" +docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_d86705d8-14ea-4024-90b6-de74d6e8d19c $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" +docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_ebaafacd-1d82-4a75-bea1-a5c64e01fcaf $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" +docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_5125241a-fbf6-4c1c-895b-026a5a41f02f $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" +docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_3d5e5b82-7205-4eba-b775-8122f05a4760 $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" +docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_16fa0b49-2083-4932-8f26-79cfdffec940 $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" +docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_23cee670-2d8d-4f5c-8893-c3c43da8b03a $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" +docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_7b6a9454-e3b6-4993-b542-468e268930aa $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" +docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_5a7109ed-c065-4b62-98f4-b3ed8f385762 $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" +docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_1e0ba8dd-4dc1-431b-b202-529e7ace5d1d $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=large_unary" +docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_649de56a-e722-4a59-b265-e9c0e871f068 $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_unary" +docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_8be512a2-5e1c-4858-8cfc-82f99b678b76 $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=ping_pong" +docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_d19b6333-e528-48b5-8421-2ae3f7ce9dab $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=empty_stream" +docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_4749c80a-21c5-4d81-9df5-3c46ba6480cd $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=client_streaming" +docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_b7bee545-4857-4269-a1f2-9553dfc7e4b8 $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=server_streaming" +docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_4e96db87-6f48-426d-a7f0-97f3a5b6b3f4 $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_begin" +docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_31a1d58c-f8bf-460a-af60-28969ecaaf80 $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=cancel_after_first_response" +docker run -i --rm=true -w /var/local/git/grpc --net=host --name interop_client_node_ce64b147-bcfa-44b2-a2f7-4a485380ce30 $docker_image bash -l -c "node src/node/interop/interop_client.js --server_host=216.239.32.254 --server_host_override=grpc-test4.sandbox.googleapis.com --server_port=443 --use_tls=true --test_case=timeout_on_sleeping_server" diff --git a/tools/run_tests/generated/configs.json b/tools/run_tests/generated/configs.json index abbe76d60c..fee8290efe 100644 --- a/tools/run_tests/generated/configs.json +++ b/tools/run_tests/generated/configs.json @@ -20,7 +20,10 @@ } }, { - "config": "msan" + "config": "msan", + "environ": { + "MSAN_OPTIONS": "poison_in_dtor=1" + } }, { "config": "basicprof" diff --git a/tools/run_tests/generated/sources_and_headers.json b/tools/run_tests/generated/sources_and_headers.json index 153909d1e1..8a7d54e9e3 100644 --- a/tools/run_tests/generated/sources_and_headers.json +++ b/tools/run_tests/generated/sources_and_headers.json @@ -756,6 +756,21 @@ "headers": [], "is_filegroup": false, "language": "c", + "name": "gpr_manual_constructor_test", + "src": [ + "test/core/support/manual_constructor_test.cc" + ], + "third_party": false, + "type": "target" + }, + { + "deps": [ + "gpr", + "gpr_test_util" + ], + "headers": [], + "is_filegroup": false, + "language": "c", "name": "gpr_mpscq_test", "src": [ "test/core/support/mpscq_test.cc" @@ -7831,6 +7846,7 @@ "include/grpc/support/tls_pthread.h", "include/grpc/support/useful.h", "src/core/lib/profiling/timers.h", + "src/core/lib/support/abstract.h", "src/core/lib/support/arena.h", "src/core/lib/support/atomic.h", "src/core/lib/support/atomic_with_atm.h", @@ -7879,6 +7895,7 @@ "include/grpc/support/tls_pthread.h", "include/grpc/support/useful.h", "src/core/lib/profiling/timers.h", + "src/core/lib/support/abstract.h", "src/core/lib/support/arena.h", "src/core/lib/support/atomic.h", "src/core/lib/support/atomic_with_atm.h", diff --git a/tools/run_tests/generated/tests.json b/tools/run_tests/generated/tests.json index 78db31e378..5b9e3099b6 100644 --- a/tools/run_tests/generated/tests.json +++ b/tools/run_tests/generated/tests.json @@ -920,6 +920,30 @@ "posix", "windows" ], + "cpu_cost": 3, + "exclude_configs": [], + "exclude_iomgrs": [], + "flaky": false, + "gtest": false, + "language": "c", + "name": "gpr_manual_constructor_test", + "platforms": [ + "linux", + "mac", + "posix", + "windows" + ], + "uses_polling": false + }, + { + "args": [], + "benchmark": false, + "ci_platforms": [ + "linux", + "mac", + "posix", + "windows" + ], "cpu_cost": 30, "exclude_configs": [], "exclude_iomgrs": [], diff --git a/tools/run_tests/sanity/check_bazel_workspace.py b/tools/run_tests/sanity/check_bazel_workspace.py new file mode 100755 index 0000000000..776c78b03f --- /dev/null +++ b/tools/run_tests/sanity/check_bazel_workspace.py @@ -0,0 +1,49 @@ +#!/usr/bin/env python + +# Copyright 2016 gRPC authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from __future__ import print_function + +import ast +import os +import re +import subprocess +import sys + +os.chdir(os.path.join(os.path.dirname(sys.argv[0]), '../../..')) + +git_hash_pattern = re.compile('[0-9a-f]{40}') + +# Parse git hashes from submodules +git_submodules = subprocess.check_output('git submodule', shell=True).strip().split('\n') +git_submodule_hashes = {re.search(git_hash_pattern, s).group() for s in git_submodules} + +# Parse git hashes from Bazel WORKSPACE {new_}http_archive rules +with open('WORKSPACE', 'r') as f: + workspace_rules = [expr.value for expr in ast.parse(f.read()).body] + +http_archive_rules = [rule for rule in workspace_rules if rule.func.id.endswith('http_archive')] +archive_urls = [kw.value.s for rule in http_archive_rules for kw in rule.keywords if kw.arg == 'url'] +workspace_git_hashes = {re.search(git_hash_pattern, url).group() for url in archive_urls} + +# Validate the equivalence of the git submodules and Bazel git dependencies. The +# condition we impose is that there is a git submodule for every dependency in +# the workspace, but not necessarily conversely. E.g. Bloaty is a dependency +# not used by any of the targets built by Bazel. +if len(workspace_git_hashes - git_submodule_hashes) > 0: + print("Found discrepancies between git submodules and Bazel WORKSPACE dependencies") + sys.exit(1) + +sys.exit(0) diff --git a/tools/run_tests/sanity/check_submodules.sh b/tools/run_tests/sanity/check_submodules.sh index 1f7b078ff7..b573d21f4f 100755 --- a/tools/run_tests/sanity/check_submodules.sh +++ b/tools/run_tests/sanity/check_submodules.sh @@ -31,7 +31,7 @@ cat << EOF | awk '{ print $1 }' | sort > $want_submodules 886e7d75368e3f4fab3f4d0d3584e4abfc557755 third_party/boringssl-with-bazel (version_for_cocoapods_7.0-857-g886e7d7) 30dbc81fb5ffdc98ea9b14b1918bfe4e8779b26e third_party/gflags (v2.2.0) ec44c6c1675c25b9827aacd08c02433cccde7780 third_party/googletest (release-1.8.0) - 80a37e0782d2d702d52234b62dd4b9ec74fd2c95 third_party/protobuf (v3.4.0) + 2761122b810fe8861004ae785cc3ab39f384d342 third_party/protobuf (v3.5.0) cacf7f1d4e3d44d871b605da3b647f07d718623f third_party/zlib (v1.2.11) 3be1924221e1326df520f8498d704a5c4c8d0cce third_party/cares/cares (cares-1_13_0) 73594cde8c9a52a102c4341c244c833aa61b9c06 third_party/bloaty diff --git a/tools/run_tests/sanity/sanity_tests.yaml b/tools/run_tests/sanity/sanity_tests.yaml index 3ca5c1b6c0..81eec4d149 100644 --- a/tools/run_tests/sanity/sanity_tests.yaml +++ b/tools/run_tests/sanity/sanity_tests.yaml @@ -1,4 +1,5 @@ # a set of tests that are run in parallel for sanity tests +- script: tools/run_tests/sanity/check_bazel_workspace.py - script: tools/run_tests/sanity/check_cache_mk.sh - script: tools/run_tests/sanity/check_owners.sh - script: tools/run_tests/sanity/check_sources_and_headers.py |